diff options
Diffstat (limited to 'src/server/game/Handlers/SpellHandler.cpp')
-rw-r--r-- | src/server/game/Handlers/SpellHandler.cpp | 91 |
1 files changed, 56 insertions, 35 deletions
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index 554aee1dc37..32ace07d9ec 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -31,6 +31,7 @@ #include "SpellAuraEffects.h" #include "Player.h" #include "Config.h" +#include "QueryCallback.h" void WorldSession::HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlags, SpellCastTargets& targets) { @@ -169,38 +170,44 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) { TC_LOG_DEBUG("network", "WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size()); - Player* pUser = _player; + Player* player = GetPlayer(); // ignore for remote control state - if (pUser->m_unitMovedByMe != pUser) + if (player->m_unitMovedByMe != player) return; - uint8 bagIndex, slot; + // additional check, client outputs message on its own + if (!player->IsAlive()) + { + player->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, nullptr, nullptr); + return; + } + uint8 bagIndex, slot; recvPacket >> bagIndex >> slot; TC_LOG_INFO("network", "bagIndex: %u, slot: %u", bagIndex, slot); - Item* item = pUser->GetItemByPos(bagIndex, slot); + Item* item = player->GetItemByPos(bagIndex, slot); if (!item) { - pUser->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) { - pUser->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->Flags & ITEM_FLAG_HAS_LOOT) && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) { - pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL); + player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL); TC_LOG_ERROR("entities.player.cheat", "Possible hacking attempt: Player %s [guid: %u] tried to open item [guid: %u, entry: %u] which is not openable!", - pUser->GetName().c_str(), pUser->GetGUID().GetCounter(), item->GetGUID().GetCounter(), proto->ItemId); + player->GetName().c_str(), player->GetGUID().GetCounter(), item->GetGUID().GetCounter(), proto->ItemId); return; } @@ -212,7 +219,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) if (!lockInfo) { - pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr); TC_LOG_ERROR("network", "WORLD::OpenItem: item [guid = %u] has an unknown lockId: %u!", item->GetGUID().GetCounter(), lockId); return; } @@ -220,7 +227,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) // was not unlocked yet if (item->IsLocked()) { - pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, nullptr); return; } } @@ -228,37 +235,51 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED))// wrapped? { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM); - stmt->setUInt32(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->SetGuidValue(ITEM_FIELD_GIFTCREATOR, ObjectGuid::Empty); - item->SetEntry(entry); - item->SetUInt32Value(ITEM_FIELD_FLAGS, flags); - item->SetState(ITEM_CHANGED, pUser); - } - else - { - TC_LOG_ERROR("network", "Wrapped item %u don't have record in character_gifts table and will deleted", item->GetGUID().GetCounter()); - pUser->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->setUInt32(0, item->GetGUID().GetCounter()); + if (item->GetGUID() != itemGuid || !item->HasFlag(ITEM_FIELD_FLAGS, 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 %u don't have record in character_gifts table and will deleted", itemGuid.GetCounter()); + GetPlayer()->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); + return; } - else - pUser->SendLoot(item->GetGUID(), LOOT_CORPSE); + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + Field* fields = result->Fetch(); + uint32 entry = fields[0].GetUInt32(); + uint32 flags = fields[1].GetUInt32(); + + item->SetGuidValue(ITEM_FIELD_GIFTCREATOR, ObjectGuid::Empty); + item->SetEntry(entry); + item->SetUInt32Value(ITEM_FIELD_FLAGS, flags); + item->SetState(ITEM_CHANGED, GetPlayer()); + + GetPlayer()->SaveInventoryAndGoldToDB(trans); + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); + stmt->setUInt32(0, itemGuid.GetCounter()); + trans->Append(stmt); + + CharacterDatabase.CommitTransaction(trans); } void WorldSession::HandleGameObjectUseOpcode(WorldPacket& recvData) |