[7659] Added several security checks to prevent cheating using facked packets

This commit is contained in:
arrai 2009-04-13 01:39:14 +02:00
parent bd56140537
commit a0ef77af5b
6 changed files with 68 additions and 19 deletions

View file

@ -905,7 +905,7 @@ void WorldSession::HandleGuildBankQuery( WorldPacket & recv_data )
uint8 unk;
recv_data >> GoGuid >> unk;
if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
if (uint32 GuildId = GetPlayer()->GetGuildId())
@ -929,7 +929,7 @@ void WorldSession::HandleGuildBankTabColon( WorldPacket & recv_data )
uint8 TabId,unk1;
recv_data >> GoGuid >> TabId >> unk1;
if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@ -958,7 +958,7 @@ void WorldSession::HandleGuildBankDeposit( WorldPacket & recv_data )
if (!money)
return;
if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@ -1006,7 +1006,7 @@ void WorldSession::HandleGuildBankWithdraw( WorldPacket & recv_data )
if (!money)
return;
if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@ -1107,7 +1107,7 @@ void WorldSession::HandleGuildBankDepositItem( WorldPacket & recv_data )
return;
}
if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@ -1562,7 +1562,7 @@ void WorldSession::HandleGuildBankBuyTab( WorldPacket & recv_data )
recv_data >> GoGuid;
recv_data >> TabId;
if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();
@ -1619,7 +1619,7 @@ void WorldSession::HandleGuildBankModifyTab( WorldPacket & recv_data )
if(IconIndex.empty())
return;
if (!objmgr.IsGuildVaultGameObject(_player, GoGuid))
if (!objmgr.IsGameObjectOfTypeInRange(_player, GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
return;
uint32 GuildId = GetPlayer()->GetGuildId();

View file

@ -825,10 +825,23 @@ void WorldSession::HandleAutoStoreBagItemOpcode( WorldPacket & recv_data )
_player->StoreItem( dest, pItem, true );
}
void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/)
void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket)
{
CHECK_PACKET_SIZE(recvPacket, 8);
sLog.outDebug("WORLD: CMSG_BUY_BANK_SLOT");
uint64 guid;
recvPacket >> guid;
// cheating protection
Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_BANKER);
if(!pCreature)
{
sLog.outDebug( "WORLD: HandleBuyBankSlotOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) );
return;
}
uint32 slot = _player->GetByteValue(PLAYER_BYTES_2, 2);
// next slot

View file

@ -52,6 +52,9 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
recv_data >> mailbox;
recv_data >> receiver;
if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
return;
// recheck
CHECK_PACKET_SIZE(recv_data, 8+(receiver.size()+1)+1+1+4+4+1+4+4+8+1);
@ -274,6 +277,10 @@ void WorldSession::HandleMarkAsRead(WorldPacket & recv_data )
uint64 mailbox;
uint32 mailId;
recv_data >> mailbox;
if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
return;
recv_data >> mailId;
Player *pl = _player;
Mail *m = pl->GetMail(mailId);
@ -297,6 +304,10 @@ void WorldSession::HandleMailDelete(WorldPacket & recv_data )
uint32 mailId;
recv_data >> mailbox;
recv_data >> mailId;
if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
return;
Player* pl = _player;
pl->m_mailsUpdated = true;
Mail *m = pl->GetMail(mailId);
@ -312,6 +323,10 @@ void WorldSession::HandleReturnToSender(WorldPacket & recv_data )
uint64 mailbox;
uint32 mailId;
recv_data >> mailbox;
if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
return;
recv_data >> mailId;
Player *pl = _player;
Mail *m = pl->GetMail(mailId);
@ -409,6 +424,10 @@ void WorldSession::HandleTakeItem(WorldPacket & recv_data )
uint32 mailId;
uint32 itemId;
recv_data >> mailbox;
if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
return;
recv_data >> mailId;
recv_data >> itemId; // item guid low?
Player* pl = _player;
@ -500,6 +519,10 @@ void WorldSession::HandleTakeMoney(WorldPacket & recv_data )
uint32 mailId;
recv_data >> mailbox;
recv_data >> mailId;
if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
return;
Player *pl = _player;
Mail* m = pl->GetMail(mailId);
@ -531,9 +554,8 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )
uint64 mailbox;
recv_data >> mailbox;
//GameObject* obj = ObjectAccessor::GetGameObject(_player, mailbox);
//if(!obj || !obj->IsMailBox())
// return;
if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
return;
Player* pl = _player;
@ -669,6 +691,9 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
recv_data >> mailbox >> mailId;
if (!objmgr.IsGameObjectOfTypeInRange(_player, mailbox, GAMEOBJECT_TYPE_MAILBOX))
return;
Player *pl = _player;
Mail* m = pl->GetMail(mailId);

View file

@ -4154,6 +4154,23 @@ void ObjectMgr::LoadInstanceTemplate()
sLog.outString();
}
bool ObjectMgr::IsGameObjectOfTypeInRange(Player *player, uint64 guid, GameobjectTypes type) const
{
if(GameObject *go = ObjectAccessor::GetGameObject(*player, guid))
{
if(go->GetGoType() == type)
{
// TODO: find out how the client calculates the maximal usage distance to spellless working
// gameobjects like guildbanks and mailboxes - 10.0 is a just an abitrary choosen number
if (go->IsWithinDistInMap(player, 10.0f))
return true;
sLog.outError("IsGameObjectOfTypeInRange: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal 10 is allowed)", go->GetGOInfo()->name,
go->GetGUIDLow(), player->GetName(), player->GetGUIDLow(), go->GetDistance(player));
}
}
return false;
}
GossipText const *ObjectMgr::GetGossipText(uint32 Text_ID) const
{
GossipTextMap::const_iterator itr = mGossipText.find(Text_ID);

View file

@ -417,13 +417,7 @@ class ObjectMgr
return mGameObjectForQuestSet.find(entry) != mGameObjectForQuestSet.end();
}
bool IsGuildVaultGameObject(Player *player, uint64 guid) const
{
if(GameObject *go = ObjectAccessor::GetGameObject(*player, guid))
if(go->GetGoType() == GAMEOBJECT_TYPE_GUILD_BANK)
return true;
return false;
}
bool IsGameObjectOfTypeInRange(Player *player, uint64 guid, GameobjectTypes type) const;
GossipText const* GetGossipText(uint32 Text_ID) const;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "7658"
#define REVISION_NR "7659"
#endif // __REVISION_NR_H__