diff options
Diffstat (limited to 'src/server/game/Handlers/SpellHandler.cpp')
-rw-r--r-- | src/server/game/Handlers/SpellHandler.cpp | 83 |
1 files changed, 52 insertions, 31 deletions
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index c91231df279..a3ae9f579fd 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -132,31 +132,38 @@ void WorldSession::HandleUseItemOpcode(WorldPackets::Spells::UseItem& packet) void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet) { - Player* player = _player; + Player* player = GetPlayer(); // ignore for remote control state if (player->m_unitMovedByMe != player) return; TC_LOG_INFO("network", "bagIndex: %u, slot: %u", packet.Slot, packet.PackSlot); + // additional check, client outputs message on its own + if (!player->IsAlive()) + { + player->SendEquipError(EQUIP_ERR_PLAYER_DEAD, nullptr, nullptr); + return; + } + Item* item = player->GetItemByPos(packet.Slot, packet.PackSlot); if (!item) { - player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } ItemTemplate const* proto = item->GetTemplate(); if (!proto) { - player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, nullptr); return; } // Verify that the bag is an actual bag or wrapped item that can be used "normally" if (!(proto->GetFlags() & ITEM_FLAG_HAS_LOOT) && !item->HasItemFlag(ITEM_FIELD_FLAG_WRAPPED)) { - player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL); + player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, nullptr); TC_LOG_ERROR("entities.player.cheat", "Possible hacking attempt: Player %s [%s] tried to open item [%s, entry: %u] which is not openable!", player->GetName().c_str(), player->GetGUID().ToString().c_str(), item->GetGUID().ToString().c_str(), proto->GetId()); return; @@ -170,7 +177,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet) if (!lockInfo) { - player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr); TC_LOG_ERROR("network", "WORLD::OpenItem: item [%s] has an unknown lockId: %u!", item->GetGUID().ToString().c_str(), lockId); return; } @@ -178,7 +185,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet) // was not unlocked yet if (item->IsLocked()) { - player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr); return; } } @@ -186,37 +193,51 @@ void WorldSession::HandleOpenItemOpcode(WorldPackets::Spells::OpenItem& packet) if (item->HasItemFlag(ITEM_FIELD_FLAG_WRAPPED))// wrapped? { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM); - stmt->setUInt64(0, item->GetGUID().GetCounter()); + _queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt) + .WithPreparedCallback(std::bind(&WorldSession::HandleOpenWrappedItemCallback, this, item->GetPos(), item->GetGUID(), std::placeholders::_1))); + } + else + player->SendLoot(item->GetGUID(), LOOT_CORPSE); +} - PreparedQueryResult result = CharacterDatabase.Query(stmt); - - if (result) - { - Field* fields = result->Fetch(); - uint32 entry = fields[0].GetUInt32(); - uint32 flags = fields[1].GetUInt32(); - - item->SetGiftCreator(ObjectGuid::Empty); - item->SetEntry(entry); - item->SetItemFlags(ItemFieldFlags(flags)); - item->SetState(ITEM_CHANGED, player); - } - else - { - TC_LOG_ERROR("network", "Wrapped item %s don't have record in character_gifts table and will deleted", item->GetGUID().ToString().c_str()); - player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); - return; - } +void WorldSession::HandleOpenWrappedItemCallback(uint16 pos, ObjectGuid itemGuid, PreparedQueryResult result) +{ + if (!GetPlayer()) + return; - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); + Item* item = GetPlayer()->GetItemByPos(pos); + if (!item) + return; - stmt->setUInt64(0, item->GetGUID().GetCounter()); + if (item->GetGUID() != itemGuid || !item->HasItemFlag(ITEM_FIELD_FLAG_WRAPPED)) // during getting result, gift was swapped with another item + return; - CharacterDatabase.Execute(stmt); + if (!result) + { + TC_LOG_ERROR("network", "Wrapped item %s don't have record in character_gifts table and will deleted", item->GetGUID().ToString().c_str()); + GetPlayer()->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); + return; } - else - player->SendLoot(item->GetGUID(), LOOT_CORPSE); + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + Field* fields = result->Fetch(); + uint32 entry = fields[0].GetUInt32(); + uint32 flags = fields[1].GetUInt32(); + + item->SetGiftCreator(ObjectGuid::Empty); + item->SetEntry(entry); + item->SetItemFlags(ItemFieldFlags(flags)); + item->SetState(ITEM_CHANGED, GetPlayer()); + + GetPlayer()->SaveInventoryAndGoldToDB(trans); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); + stmt->setUInt64(0, itemGuid.GetCounter()); + trans->Append(stmt); + + CharacterDatabase.CommitTransaction(trans); } void WorldSession::HandleGameObjectUseOpcode(WorldPackets::GameObject::GameObjUse& packet) |