From 9cb972d5ef7965cdd285cd7e4cfce2562d8e2bfc Mon Sep 17 00:00:00 2001 From: ratkosrb Date: Thu, 16 Nov 2023 16:18:45 +0200 Subject: [PATCH] Fix item dupe when trading to bots. Closes https://github.com/vmangos/core/issues/2290 --- src/game/Handlers/TradeHandler.cpp | 16 +++++++++ src/game/Objects/Item.cpp | 55 ++++++++++++++++-------------- src/game/Objects/Item.h | 1 + 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/game/Handlers/TradeHandler.cpp b/src/game/Handlers/TradeHandler.cpp index 0b4d5ca170f..b6bfc38e208 100644 --- a/src/game/Handlers/TradeHandler.cpp +++ b/src/game/Handlers/TradeHandler.cpp @@ -156,6 +156,14 @@ void WorldSession::MoveItems(Item* myItems[], Item* hisItems[]) // store trader->MoveItemToInventory(traderDst, myItems[i], true, true); + + // If saving is disabled for player who receives the item, it must be deleted from db, or it enables duping. + if (trader->IsSavingDisabled()) + { + sLog.Out(LOG_BASIC, LOG_LVL_DETAIL, "Item guid %u traded to character %u with disabled saving. Deleting from DB.", myItems[i]->GetGUIDLow(), trader->GetGUIDLow()); + myItems[i]->DeleteFromInventoryDB(); + myItems[i]->DeleteAllFromDB(); + } } if (hisItems[i]) @@ -173,6 +181,14 @@ void WorldSession::MoveItems(Item* myItems[], Item* hisItems[]) // store _player->MoveItemToInventory(playerDst, hisItems[i], true, true); + + // If saving is disabled for player who receives the item, it must be deleted from db, or it enables duping. + if (_player->IsSavingDisabled()) + { + sLog.Out(LOG_BASIC, LOG_LVL_DETAIL, "Item guid %u traded to character %u with disabled saving. Deleting from DB.", hisItems[i]->GetGUIDLow(), _player->GetGUIDLow()); + hisItems[i]->DeleteFromInventoryDB(); + hisItems[i]->DeleteAllFromDB(); + } } } else diff --git a/src/game/Objects/Item.cpp b/src/game/Objects/Item.cpp index 3dbf887173a..07a62bd8f3e 100644 --- a/src/game/Objects/Item.cpp +++ b/src/game/Objects/Item.cpp @@ -307,31 +307,7 @@ void Item::SaveToDB() break; case ITEM_REMOVED: { - static SqlStatementID delItemText; - static SqlStatementID delInst ; - static SqlStatementID delGifts ; - static SqlStatementID delLoot ; - - if (uint32 item_text_id = GetUInt32Value(ITEM_FIELD_ITEM_TEXT_ID)) - { - SqlStatement stmt = CharacterDatabase.CreateStatement(delItemText, "DELETE FROM `item_text` WHERE `id` = ?"); - stmt.PExecute(item_text_id); - } - - SqlStatement stmt = CharacterDatabase.CreateStatement(delInst, "DELETE FROM `item_instance` WHERE `guid` = ?"); - stmt.PExecute(guid); - - if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)) - { - stmt = CharacterDatabase.CreateStatement(delGifts, "DELETE FROM `character_gifts` WHERE `item_guid` = ?"); - stmt.PExecute(GetGUIDLow()); - } - - if (HasSavedLoot()) - { - stmt = CharacterDatabase.CreateStatement(delLoot, "DELETE FROM `item_loot` WHERE `guid` = ?"); - stmt.PExecute(GetGUIDLow()); - } + DeleteAllFromDB(); if (IsInWorld()) RemoveFromWorld(); @@ -493,6 +469,35 @@ bool Item::LoadFromDB(uint32 guidLow, ObjectGuid ownerGuid, Field* fields, uint3 return true; } +void Item::DeleteAllFromDB() +{ + static SqlStatementID delItemText; + static SqlStatementID delInst; + static SqlStatementID delGifts; + static SqlStatementID delLoot; + + if (uint32 item_text_id = GetUInt32Value(ITEM_FIELD_ITEM_TEXT_ID)) + { + SqlStatement stmt = CharacterDatabase.CreateStatement(delItemText, "DELETE FROM `item_text` WHERE `id` = ?"); + stmt.PExecute(item_text_id); + } + + SqlStatement stmt = CharacterDatabase.CreateStatement(delInst, "DELETE FROM `item_instance` WHERE `guid` = ?"); + stmt.PExecute(GetGUIDLow()); + + if (HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED)) + { + stmt = CharacterDatabase.CreateStatement(delGifts, "DELETE FROM `character_gifts` WHERE `item_guid` = ?"); + stmt.PExecute(GetGUIDLow()); + } + + if (HasSavedLoot()) + { + stmt = CharacterDatabase.CreateStatement(delLoot, "DELETE FROM `item_loot` WHERE `guid` = ?"); + stmt.PExecute(GetGUIDLow()); + } +} + void Item::DeleteAllFromDB(uint32 guidLow) { CharacterDatabase.PExecute("DELETE FROM `item_instance` WHERE `guid` = '%u'", guidLow); diff --git a/src/game/Objects/Item.h b/src/game/Objects/Item.h index 8c2279d132b..fb8e8c18195 100644 --- a/src/game/Objects/Item.h +++ b/src/game/Objects/Item.h @@ -271,6 +271,7 @@ class Item : public Object void DeleteFromInventoryDB(); void LoadLootFromDB(Field* fields); + void DeleteAllFromDB(); static void DeleteAllFromDB(uint32 guidLow); bool isWeapon() const{ return GetProto()->Class == ITEM_CLASS_WEAPON; }