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.cpp83
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)