// Arat
int CInputMain::MyShop(LPCHARACTER ch, const char * c_pData, size_t uiBytes)
{
TPacketCGMyShop * p = (TPacketCGMyShop *) c_pData;
int iExtraLen = p->bCount * sizeof(TShopItemTable);
[..]
sys_log(0, "MyShop count %d", p->bCount);
ch->OpenMyShop(p->szSign, (TShopItemTable *) (c_pData + sizeof(TPacketCGMyShop)), p->bCount);
return (iExtraLen);
}
// Ekle
#ifdef ENABLE_SHOW_CHEST_DROP
void CInputMain::ChestDropInfo(LPCHARACTER ch, const char* c_pData)
{
// FIXME@2: Güvenlik / stabilite
// ch veya c_pData geçersizse (NULL) dereference edilip çökme oluşmasın diye
// önce doğrulama yapılıyor, sonra packet parse ve item erişimi geliyor.
if (!ch || !c_pData)
return;
TPacketCGChestDropInfo* p = (TPacketCGChestDropInfo*) c_pData;
if (p->wInventoryCell >= INVENTORY_AND_EQUIP_SLOT_MAX)
return;
LPITEM pkItem = ch->GetInventoryItem(p->wInventoryCell);
if (!pkItem)
return;
LPDESC pkDesc = ch->GetDesc();
if (!pkDesc)
return;
std::vector<TChestDropInfoTable> vec_ItemList;
ITEM_MANAGER::instance().GetChestItemList(pkItem->GetVnum(), vec_ItemList);
TPacketGCChestDropInfo packet;
packet.bHeader = HEADER_GC_CHEST_DROP_INFO;
packet.wSize = sizeof(packet) + sizeof(TChestDropInfoTable) * vec_ItemList.size();
packet.dwChestVnum = pkItem->GetVnum();
pkDesc->BufferedPacket(&packet, sizeof(packet));
// FIXME@3: Crash önleme
// Drop listesi boşken vec_ItemList[0] erişimi geçersizdir ve server/client crash’e gider.
// empty() kontrolü ile güvenli çıkış eklendi.
if (!vec_ItemList.empty())
pkDesc->Packet(&vec_ItemList[0], sizeof(TChestDropInfoTable) * vec_ItemList.size());
}
#endif
// Arat
case HEADER_CG_MYSHOP:
if ((iExtraLen = MyShop(ch, c_pData, m_iBufferLeft)) < 0)
return -1;
break;
case HEADER_CG_REFINE:
Refine(ch, c_pData);
break;
// Ekle
#ifdef ENABLE_SHOW_CHEST_DROP
case HEADER_CG_CHEST_DROP_INFO:
ChestDropInfo(ch, c_pData);
break;
#endif