[8121] Cleanup and more safe code in Player::BuyItemFromVendor use.

* Move bag search by bag guid code to WorldSession::HandleBuyItemInSlotOpcode
* Really reject unexisted bag cases.
This commit is contained in:
VladimirMangos 2009-07-05 17:43:39 +04:00
parent c853c2e261
commit b4302d61e5
4 changed files with 55 additions and 55 deletions

View file

@ -672,7 +672,31 @@ void WorldSession::HandleBuyItemInSlotOpcode( WorldPacket & recv_data )
recv_data >> vendorguid >> item >> slot >> bagguid >> bagslot >> count; recv_data >> vendorguid >> item >> slot >> bagguid >> bagslot >> count;
GetPlayer()->BuyItemFromVendor(vendorguid,item,count,bagguid,bagslot); uint8 bag = NULL_BAG; // init for case invalid bagGUID
// find bag slot by bag guid
if (bagguid == _player->GetGUID())
bag = INVENTORY_SLOT_BAG_0;
else
{
for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END;++i)
{
if (Bag *pBag = (Bag*)_player->GetItemByPos(INVENTORY_SLOT_BAG_0,i))
{
if (bagguid == pBag->GetGUID())
{
bag = i;
break;
}
}
}
}
// bag not found, cheating?
if (bag == NULL_BAG)
return;
GetPlayer()->BuyItemFromVendor(vendorguid,item,count,bag,bagslot);
} }
void WorldSession::HandleBuyItemOpcode( WorldPacket & recv_data ) void WorldSession::HandleBuyItemOpcode( WorldPacket & recv_data )

View file

@ -17144,16 +17144,16 @@ void Player::InitDataForForm(bool reapplyMods)
} }
// Return true is the bought item has a max count to force refresh of window by caller // Return true is the bought item has a max count to force refresh of window by caller
bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot) bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint8 bag, uint8 slot)
{ {
// cheating attempt // cheating attempt
if(count < 1) count = 1; if (count < 1) count = 1;
if(!isAlive()) if (!isAlive())
return false; return false;
ItemPrototype const *pProto = objmgr.GetItemPrototype( item ); ItemPrototype const *pProto = objmgr.GetItemPrototype( item );
if( !pProto ) if (!pProto)
{ {
SendBuyError( BUY_ERR_CANT_FIND_ITEM, NULL, item, 0); SendBuyError( BUY_ERR_CANT_FIND_ITEM, NULL, item, 0);
return false; return false;
@ -17175,7 +17175,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
} }
size_t vendor_slot = vItems->FindItemSlot(item); size_t vendor_slot = vItems->FindItemSlot(item);
if(vendor_slot >= vItems->GetItemCount()) if (vendor_slot >= vItems->GetItemCount())
{ {
SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0);
return false; return false;
@ -17184,39 +17184,39 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
VendorItem const* crItem = vItems->m_items[vendor_slot]; VendorItem const* crItem = vItems->m_items[vendor_slot];
// check current item amount if it limited // check current item amount if it limited
if( crItem->maxcount != 0 ) if (crItem->maxcount != 0)
{ {
if(pCreature->GetVendorItemCurrentCount(crItem) < pProto->BuyCount * count ) if (pCreature->GetVendorItemCurrentCount(crItem) < pProto->BuyCount * count )
{ {
SendBuyError( BUY_ERR_ITEM_ALREADY_SOLD, pCreature, item, 0); SendBuyError( BUY_ERR_ITEM_ALREADY_SOLD, pCreature, item, 0);
return false; return false;
} }
} }
if( uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank) if (uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank)
{ {
SendBuyError( BUY_ERR_REPUTATION_REQUIRE, pCreature, item, 0); SendBuyError( BUY_ERR_REPUTATION_REQUIRE, pCreature, item, 0);
return false; return false;
} }
if(crItem->ExtendedCost) if (crItem->ExtendedCost)
{ {
ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
if(!iece) if (!iece)
{ {
sLog.outError("Item %u have wrong ExtendedCost field value %u", pProto->ItemId, crItem->ExtendedCost); sLog.outError("Item %u have wrong ExtendedCost field value %u", pProto->ItemId, crItem->ExtendedCost);
return false; return false;
} }
// honor points price // honor points price
if(GetHonorPoints() < (iece->reqhonorpoints * count)) if (GetHonorPoints() < (iece->reqhonorpoints * count))
{ {
SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL); SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL);
return false; return false;
} }
// arena points price // arena points price
if(GetArenaPoints() < (iece->reqarenapoints * count)) if (GetArenaPoints() < (iece->reqarenapoints * count))
{ {
SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL); SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL);
return false; return false;
@ -17246,62 +17246,38 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
// reputation discount // reputation discount
price = uint32(floor(price * GetReputationPriceDiscount(pCreature))); price = uint32(floor(price * GetReputationPriceDiscount(pCreature)));
if( GetMoney() < price ) if (GetMoney() < price)
{ {
SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, item, 0); SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, item, 0);
return false; return false;
} }
uint8 bag = 0; // init for case invalid bagGUID if ((bag == NULL_BAG && slot == NULL_SLOT) || IsInventoryPos(bag, slot))
if (bagguid != NULL_BAG && slot != NULL_SLOT)
{
if( bagguid == GetGUID() )
{
bag = INVENTORY_SLOT_BAG_0;
}
else
{
for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END;++i)
{
if( Bag *pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0,i) )
{
if( bagguid == pBag->GetGUID() )
{
bag = i;
break;
}
}
}
}
}
if( IsInventoryPos( bag, slot ) || (bagguid == NULL_BAG && slot == NULL_SLOT) )
{ {
ItemPosCountVec dest; ItemPosCountVec dest;
uint8 msg = CanStoreNewItem( bag, slot, dest, item, pProto->BuyCount * count ); uint8 msg = CanStoreNewItem( bag, slot, dest, item, pProto->BuyCount * count );
if( msg != EQUIP_ERR_OK ) if (msg != EQUIP_ERR_OK)
{ {
SendEquipError( msg, NULL, NULL ); SendEquipError( msg, NULL, NULL );
return false; return false;
} }
ModifyMoney( -(int32)price ); ModifyMoney( -(int32)price );
if(crItem->ExtendedCost) // case for new honor system if (crItem->ExtendedCost) // case for new honor system
{ {
ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
if(iece->reqhonorpoints) if (iece->reqhonorpoints)
ModifyHonorPoints( - int32(iece->reqhonorpoints * count)); ModifyHonorPoints( - int32(iece->reqhonorpoints * count));
if(iece->reqarenapoints) if (iece->reqarenapoints)
ModifyArenaPoints( - int32(iece->reqarenapoints * count)); ModifyArenaPoints( - int32(iece->reqarenapoints * count));
for (uint8 i = 0; i < 5; ++i) for (uint8 i = 0; i < 5; ++i)
{ {
if(iece->reqitem[i]) if (iece->reqitem[i])
DestroyItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count), true); DestroyItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count), true);
} }
} }
if(Item *it = StoreNewItem( dest, item, true )) if (Item *it = StoreNewItem( dest, item, true ))
{ {
uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count); uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count);
@ -17315,9 +17291,9 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
SendNewItem(it, pProto->BuyCount*count, true, false, false); SendNewItem(it, pProto->BuyCount*count, true, false, false);
} }
} }
else if( IsEquipmentPos( bag, slot ) ) else if (IsEquipmentPos(bag, slot))
{ {
if(pProto->BuyCount * count != 1) if (pProto->BuyCount * count != 1)
{ {
SendEquipError( EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, NULL, NULL ); SendEquipError( EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, NULL, NULL );
return false; return false;
@ -17325,19 +17301,19 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
uint16 dest; uint16 dest;
uint8 msg = CanEquipNewItem( slot, dest, item, false ); uint8 msg = CanEquipNewItem( slot, dest, item, false );
if( msg != EQUIP_ERR_OK ) if (msg != EQUIP_ERR_OK)
{ {
SendEquipError( msg, NULL, NULL ); SendEquipError( msg, NULL, NULL );
return false; return false;
} }
ModifyMoney( -(int32)price ); ModifyMoney( -(int32)price );
if(crItem->ExtendedCost) // case for new honor system if (crItem->ExtendedCost) // case for new honor system
{ {
ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost); ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
if(iece->reqhonorpoints) if (iece->reqhonorpoints)
ModifyHonorPoints( - int32(iece->reqhonorpoints)); ModifyHonorPoints( - int32(iece->reqhonorpoints));
if(iece->reqarenapoints) if (iece->reqarenapoints)
ModifyArenaPoints( - int32(iece->reqarenapoints)); ModifyArenaPoints( - int32(iece->reqarenapoints));
for (uint8 i = 0; i < 5; ++i) for (uint8 i = 0; i < 5; ++i)
{ {
@ -17346,7 +17322,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
} }
} }
if(Item *it = EquipNewItem( dest, item, true )) if (Item *it = EquipNewItem( dest, item, true ))
{ {
uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count); uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count);
@ -17368,7 +17344,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
return false; return false;
} }
return crItem->maxcount!=0; return crItem->maxcount != 0;
} }
uint32 Player::GetMaxPersonalArenaRatingRequirement() uint32 Player::GetMaxPersonalArenaRatingRequirement()

View file

@ -1186,7 +1186,7 @@ class MANGOS_DLL_SPEC Player : public Unit
return mainItem && mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(); return mainItem && mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip();
} }
void SendNewItem( Item *item, uint32 count, bool received, bool created, bool broadcast = false ); void SendNewItem( Item *item, uint32 count, bool received, bool created, bool broadcast = false );
bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot); bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint8 bag, uint8 slot);
float GetReputationPriceDiscount( Creature const* pCreature ) const; float GetReputationPriceDiscount( Creature const* pCreature ) const;
Player* GetTrader() const { return pTrader; } Player* GetTrader() const { return pTrader; }

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "8120" #define REVISION_NR "8121"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__