aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <none@none>2010-10-09 17:36:53 +0200
committerShauren <none@none>2010-10-09 17:36:53 +0200
commit324de6fb4c6f56ac08a487d24e47e457bf11b5c3 (patch)
treef73297b924190f1b95a8905ec3ba3efa569d6f30 /src
parenta20dd32de0a0eaea8a7e869b0b0aedf3f6920b5a (diff)
Core: Added some anti-WPE filter checks to prevent putting non-empty bags into other bags/gbank/mail/auction, original patch from mythcore
Core: Changed inventory saving - will no longer abort operation at single item fail Closes issue #1994. --HG-- branch : trunk
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp74
-rwxr-xr-xsrc/server/game/Guilds/Guild.cpp7
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp6
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/MailHandler.cpp6
4 files changed, 61 insertions, 32 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 2dfccde8017..5926589ef76 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -10039,6 +10039,9 @@ uint8 Player::_CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemPosCountVe
uint32 need_space;
+ if (pSrcItem && pSrcItem->IsBag() && !((Bag*)pSrcItem)->IsEmpty() && !IsBagPos(uint16(bag) << 8 | slot))
+ return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
+
// empty specific slot - check item fit to slot
if (!pItem2 || swap)
{
@@ -10111,6 +10114,9 @@ uint8 Player::_CanStoreItem_InBag(uint8 bag, ItemPosCountVec &dest, ItemPrototyp
if (!pBag || pBag == pSrcItem)
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ if (pSrcItem && pSrcItem->IsBag() && !((Bag*)pSrcItem)->IsEmpty())
+ return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
+
ItemPrototype const* pBagProto = pBag->GetProto();
if (!pBagProto)
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
@@ -10169,6 +10175,10 @@ uint8 Player::_CanStoreItem_InBag(uint8 bag, ItemPosCountVec &dest, ItemPrototyp
uint8 Player::_CanStoreItem_InInventorySlots(uint8 slot_begin, uint8 slot_end, ItemPosCountVec &dest, ItemPrototype const *pProto, uint32& count, bool merge, Item* pSrcItem, uint8 skip_bag, uint8 skip_slot) const
{
+ //this is never called for non-bag slots so we can do this
+ if (pSrcItem && pSrcItem->IsBag() && !((Bag*)pSrcItem)->IsEmpty())
+ return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
+
for (uint32 j = slot_begin; j < slot_end; j++)
{
// skip specific slot already processed in first called _CanStoreItem_InSpecificSlot
@@ -18056,52 +18066,52 @@ void Player::_SaveInventory(SQLTransaction& trans)
if (m_itemUpdateQueue.empty())
return;
- // do not save if the update queue is corrupt
- bool error = false;
+ uint32 lowGuid = GetGUIDLow();
for (size_t i = 0; i < m_itemUpdateQueue.size(); ++i)
{
Item *item = m_itemUpdateQueue[i];
- if (!item || item->GetState() == ITEM_REMOVED)
+ if (!item)
continue;
- Item *test = GetItemByPos(item->GetBagSlot(), item->GetSlot());
-
- if (test == NULL)
- {
- sLog.outCrash("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%d) and slot(%d) values for the item with guid %d (state %d) are incorrect, the player doesn't have an item at that position!", GetGUIDLow(), GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), (int32)item->GetState());
- //error = true;
- //Should the above line really be commented out?
- }
- else if (test != item)
- {
- sLog.outError("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the item with guid %d is there instead!", GetGUIDLow(), GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow());
- error = true;
- }
- }
-
- if (error)
- {
- sLog.outError("Player::_SaveInventory - one or more errors occurred save aborted!");
- ChatHandler(this).SendSysMessage(LANG_ITEM_SAVE_FAILED);
- return;
- }
-
- for (size_t i = 0; i < m_itemUpdateQueue.size(); i++)
- {
- Item *item = m_itemUpdateQueue[i];
- if (!item) continue;
-
Bag *container = item->GetContainer();
uint32 bag_guid = container ? container->GetGUIDLow() : 0;
+ if (item->GetState() != ITEM_REMOVED)
+ {
+ Item *test = GetItemByPos(item->GetBagSlot(), item->GetSlot());
+ if (test == NULL)
+ {
+ uint32 bagTestGUID = 0;
+ if (Item* test2 = GetItemByPos(INVENTORY_SLOT_BAG_0, item->GetBagSlot()))
+ bagTestGUID = test2->GetGUIDLow();
+ sLog.outError("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u (state %d) are incorrect, the player doesn't have an item at that position!", lowGuid, GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), (int32)item->GetState());
+ // according to the test that was just performed nothing should be in this slot, delete
+ trans->PAppend("DELETE FROM character_inventory WHERE bag=%u AND slot=%u", bagTestGUID, item->GetSlot());
+ // also THIS item should be somewhere else, cheat attempt
+ item->FSetState(ITEM_REMOVED); // we are IN updateQueue right now, can't use SetState which modifies the queue
+ DeleteRefundReference(item->GetGUIDLow());
+ // don't skip, let the switch delete it
+ //continue;
+ }
+ else if (test != item)
+ {
+ sLog.outError("Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u are incorrect, the item with guid %u is there instead!", lowGuid, GetName(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow());
+ // save all changes to the item...
+ if (item->GetState() != ITEM_NEW) // only for existing items, no dupes
+ item->SaveToDB(trans);
+ // ...but do not save position in invntory
+ continue;
+ }
+ }
+
switch (item->GetState())
{
case ITEM_NEW:
- trans->PAppend("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
+ trans->PAppend("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", lowGuid, bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
break;
case ITEM_CHANGED:
trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
- trans->PAppend("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
+ trans->PAppend("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", lowGuid, bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
break;
case ITEM_REMOVED:
trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index eab64fd0731..3ed1a6a9d7a 100755
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -1977,6 +1977,13 @@ void Guild::MoveFromCharToBank(Player * pl, uint8 PlayerBag, uint8 PlayerSlot, u
if (!pItemChar) // Problem to get item from player
return;
+ // prevent storing non-empty bags
+ if (pItemChar && pItemChar->IsBag() && !((Bag*)pItemChar)->IsEmpty())
+ {
+ pl->SendEquipError(EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS, pItemChar, NULL);
+ return;
+ }
+
if (!pItemChar->CanBeTraded())
{
pl->SendEquipError(EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pItemChar, NULL);
diff --git a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp b/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp
index 677e879a8f2..3fbfbfe6980 100755
--- a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp
@@ -192,6 +192,12 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
return;
}
+ if (it->IsBag() && !((Bag*)it)->IsEmpty())
+ {
+ SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
+ return;
+ }
+
AuctionHouseObject* auctionHouse = sAuctionMgr.GetAuctionsMap(pCreature->getFaction());
//we have to take deposit :
diff --git a/src/server/game/Server/Protocol/Handlers/MailHandler.cpp b/src/server/game/Server/Protocol/Handlers/MailHandler.cpp
index dbc4134d90f..f1ffd691b22 100755
--- a/src/server/game/Server/Protocol/Handlers/MailHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/MailHandler.cpp
@@ -219,6 +219,12 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data)
return;
}
+ if (item->IsBag() && !((Bag*)item)->IsEmpty())
+ {
+ pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS);
+ return;
+ }
+
items[i] = item;
}