aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/SpellHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Handlers/SpellHandler.cpp')
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp91
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)