Skip to content

Commit

Permalink
Fix item dupe when trading to bots.
Browse files Browse the repository at this point in the history
Closes #2290
  • Loading branch information
ratkosrb committed Nov 16, 2023
1 parent 6126528 commit 9cb972d
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 25 deletions.
16 changes: 16 additions & 0 deletions src/game/Handlers/TradeHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand All @@ -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
Expand Down
55 changes: 30 additions & 25 deletions src/game/Objects/Item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/game/Objects/Item.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down

0 comments on commit 9cb972d

Please sign in to comment.