[10059] Cleanup in Player::m_mover uses

* Also fix triggered by related checks unread packet tail spam cases.
* Fix one case when expected death at fall controlled player
  under ground has been possible avoided
This commit is contained in:
VladimirMangos 2010-06-15 03:46:51 +04:00
parent e82f4fbd29
commit 2326292981
5 changed files with 67 additions and 51 deletions

View file

@ -181,7 +181,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data)
DEBUG_LOG("Guid: %s", guid.GetString().c_str()); DEBUG_LOG("Guid: %s", guid.GetString().c_str());
DEBUG_LOG("Flags %u, time %u", flags, time/IN_MILLISECONDS); DEBUG_LOG("Flags %u, time %u", flags, time/IN_MILLISECONDS);
Unit *mover = _player->m_mover; Unit *mover = _player->GetMover();
Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;
if(!plMover || !plMover->IsBeingTeleportedNear()) if(!plMover || !plMover->IsBeingTeleportedNear())
@ -223,7 +223,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
DEBUG_LOG("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode); DEBUG_LOG("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
recv_data.hexlike(); recv_data.hexlike();
Unit *mover = _player->m_mover; Unit *mover = _player->GetMover();
Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;
// ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
@ -335,7 +335,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
// TODO: discard movement packets after the player is rooted // TODO: discard movement packets after the player is rooted
if(plMover->isAlive()) if(plMover->isAlive())
{ {
plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth()); plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, plMover->GetMaxHealth());
// pl can be alive if GM/etc // pl can be alive if GM/etc
if(!plMover->isAlive()) if(!plMover->isAlive())
{ {
@ -434,12 +434,13 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
DEBUG_LOG("WORLD: Recvd CMSG_SET_ACTIVE_MOVER"); DEBUG_LOG("WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
recv_data.hexlike(); recv_data.hexlike();
uint64 guid; ObjectGuid guid;
recv_data >> guid; recv_data >> guid;
if(_player->m_mover->GetGUID() != guid) if(_player->GetMover()->GetObjectGuid() != guid)
{ {
sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " I64FMT " and should be " I64FMT, _player->m_mover->GetGUID(), guid); sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is %s and should be %s",
_player->GetMover()->GetObjectGuid().GetString().c_str(), guid.GetString().c_str());
return; return;
} }
} }
@ -455,9 +456,12 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
recv_data >> old_mover_guid.ReadAsPacked(); recv_data >> old_mover_guid.ReadAsPacked();
recv_data >> mi; recv_data >> mi;
if(_player->m_mover->GetObjectGuid() == old_mover_guid) if(_player->GetMover()->GetObjectGuid() == old_mover_guid)
{ {
sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is " I64FMT " and should be " I64FMT " instead of " UI64FMTD, _player->m_mover->GetGUID(), _player->GetGUID(), old_mover_guid.GetRawValue()); sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is %s and should be %s instead of %s",
_player->GetMover()->GetObjectGuid().GetString().c_str(),
_player->GetObjectGuid().GetString().c_str(),
old_mover_guid.GetString().c_str());
recv_data.rpos(recv_data.wpos()); // prevent warnings spam recv_data.rpos(recv_data.wpos()); // prevent warnings spam
return; return;
} }

View file

@ -405,7 +405,7 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/)
UpdateMask Player::updateVisualBits; UpdateMask Player::updateVisualBits;
Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this), m_camera(this) Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputationMgr(this), m_mover(this), m_camera(this)
{ {
m_transport = 0; m_transport = 0;
@ -584,8 +584,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa
m_summon_y = 0.0f; m_summon_y = 0.0f;
m_summon_z = 0.0f; m_summon_z = 0.0f;
m_mover = this;
m_miniPet = 0; m_miniPet = 0;
m_contestedPvPTimer = 0; m_contestedPvPTimer = 0;
@ -19442,7 +19440,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
if(HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) || HasAuraType(SPELL_AURA_FLY) || isInFlight()) if(HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED) || HasAuraType(SPELL_AURA_FLY) || isInFlight())
m_movementInfo.AddMovementFlag(MOVEFLAG_FLYING); m_movementInfo.AddMovementFlag(MOVEFLAG_FLYING);
m_mover = this; SetMover(this);
} }
void Player::SendInitialPacketsAfterAddToMap() void Player::SendInitialPacketsAfterAddToMap()

View file

@ -2189,7 +2189,6 @@ class MANGOS_DLL_SPEC Player : public Unit
/*********************************************************/ /*********************************************************/
bool HasMovementFlag(MovementFlags f) const; // for script access to m_movementInfo.HasMovementFlag bool HasMovementFlag(MovementFlags f) const; // for script access to m_movementInfo.HasMovementFlag
void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode); void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode);
Unit *m_mover;
void SetFallInformation(uint32 time, float z) void SetFallInformation(uint32 time, float z)
{ {
m_lastFallTime = time; m_lastFallTime = time;
@ -2208,6 +2207,8 @@ class MANGOS_DLL_SPEC Player : public Unit
void SetClientControl(Unit* target, uint8 allowMove); void SetClientControl(Unit* target, uint8 allowMove);
void SetMover(Unit* target) { m_mover = target ? target : this; } void SetMover(Unit* target) { m_mover = target ? target : this; }
Unit* GetMover() const { return m_mover; }
bool IsSelfMover() const { return m_mover == this; }// normal case for player not controlling other unit
void EnterVehicle(Vehicle *vehicle); void EnterVehicle(Vehicle *vehicle);
void ExitVehicle(Vehicle *vehicle); void ExitVehicle(Vehicle *vehicle);
@ -2602,6 +2603,7 @@ class MANGOS_DLL_SPEC Player : public Unit
m_DelayedOperations |= operation; m_DelayedOperations |= operation;
} }
Unit *m_mover;
Camera m_camera; Camera m_camera;
GridReference<Player> m_gridRef; GridReference<Player> m_gridRef;

View file

@ -31,13 +31,6 @@
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{ {
// TODO: add targets.read() check
Player* pUser = _player;
// ignore for remote control state
if(pUser->m_mover != pUser)
return;
uint8 bagIndex, slot; uint8 bagIndex, slot;
uint8 unk_flags; // flags (if 0x02 - some additional data are received) uint8 unk_flags; // flags (if 0x02 - some additional data are received)
uint8 cast_count; // next cast if exists (single or not) uint8 cast_count; // next cast if exists (single or not)
@ -47,9 +40,20 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags; recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags;
// TODO: add targets.read() check
Player* pUser = _player;
// ignore for remote control state
if (!pUser->IsSelfMover())
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
return;
}
// reject fake data // reject fake data
if (glyphIndex >= MAX_GLYPH_SLOT_INDEX) if (glyphIndex >= MAX_GLYPH_SLOT_INDEX)
{ {
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
return; return;
} }
@ -57,12 +61,14 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
Item *pItem = pUser->GetItemByPos(bagIndex, slot); Item *pItem = pUser->GetItemByPos(bagIndex, slot);
if (!pItem) if (!pItem)
{ {
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
return; return;
} }
if (pItem->GetGUID() != item_guid) if (pItem->GetGUID() != item_guid)
{ {
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
return; return;
} }
@ -72,6 +78,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
ItemPrototype const *proto = pItem->GetProto(); ItemPrototype const *proto = pItem->GetProto();
if (!proto) if (!proto)
{ {
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL );
return; return;
} }
@ -79,6 +86,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
// some item classes can be used only in equipped state // some item classes can be used only in equipped state
if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped()) if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
{ {
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL ); pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL );
return; return;
} }
@ -86,6 +94,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
uint8 msg = pUser->CanUseItem(pItem); uint8 msg = pUser->CanUseItem(pItem);
if (msg != EQUIP_ERR_OK) if (msg != EQUIP_ERR_OK)
{ {
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError( msg, pItem, NULL ); pUser->SendEquipError( msg, pItem, NULL );
return; return;
} }
@ -95,6 +104,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
!(proto->Flags & ITEM_FLAGS_USEABLE_IN_ARENA) && !(proto->Flags & ITEM_FLAGS_USEABLE_IN_ARENA) &&
pUser->InArena()) pUser->InArena())
{ {
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH,pItem,NULL); pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH,pItem,NULL);
return; return;
} }
@ -107,6 +117,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{ {
if (IsNonCombatSpell(spellInfo)) if (IsNonCombatSpell(spellInfo))
{ {
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT,pItem,NULL); pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT,pItem,NULL);
return; return;
} }
@ -116,6 +127,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
// Prevent potion drink if another potion in processing (client have potions disabled in like case) // Prevent potion drink if another potion in processing (client have potions disabled in like case)
if (pItem->IsPotion() && pUser->GetLastPotionId()) if (pItem->IsPotion() && pUser->GetLastPotionId())
{ {
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_OBJECT_IS_BUSY,pItem,NULL); pUser->SendEquipError(EQUIP_ERR_OBJECT_IS_BUSY,pItem,NULL);
return; return;
} }
@ -174,18 +186,18 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
{ {
DETAIL_LOG("WORLD: CMSG_OPEN_ITEM packet, data length = %i",(uint32)recvPacket.size()); DETAIL_LOG("WORLD: CMSG_OPEN_ITEM packet, data length = %i",(uint32)recvPacket.size());
Player* pUser = _player;
// ignore for remote control state
if(pUser->m_mover != pUser)
return;
uint8 bagIndex, slot; uint8 bagIndex, slot;
recvPacket >> bagIndex >> slot; recvPacket >> bagIndex >> slot;
DETAIL_LOG("bagIndex: %u, slot: %u",bagIndex,slot); DETAIL_LOG("bagIndex: %u, slot: %u",bagIndex,slot);
Player* pUser = _player;
// ignore for remote control state
if (!pUser->IsSelfMover())
return;
Item *pItem = pUser->GetItemByPos(bagIndex, slot); Item *pItem = pUser->GetItemByPos(bagIndex, slot);
if(!pItem) if(!pItem)
{ {
@ -257,7 +269,7 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
DEBUG_LOG( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid)); DEBUG_LOG( "WORLD: Recvd CMSG_GAMEOBJ_USE Message [guid=%u]", GUID_LOPART(guid));
// ignore for remote control state // ignore for remote control state
if(_player->m_mover != _player) if (!_player->IsSelfMover())
return; return;
GameObject *obj = GetPlayer()->GetMap()->GetGameObject(guid); GameObject *obj = GetPlayer()->GetMap()->GetGameObject(guid);
@ -276,7 +288,7 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket)
DEBUG_LOG( "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [in game guid: %u]", GUID_LOPART(guid)); DEBUG_LOG( "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [in game guid: %u]", GUID_LOPART(guid));
// ignore for remote control state // ignore for remote control state
if(_player->m_mover != _player) if (!_player->IsSelfMover())
return; return;
GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid);
@ -298,8 +310,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received) recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received)
// ignore for remote control state (for player case) // ignore for remote control state (for player case)
Unit* mover = _player->m_mover; Unit* mover = _player->GetMover();
if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER) if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
{ {
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return; return;
@ -317,7 +329,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
return; return;
} }
if(mover->GetTypeId()==TYPEID_PLAYER) if (mover->GetTypeId()==TYPEID_PLAYER)
{ {
// not have spell in spellbook or spell passive and not casted by client // not have spell in spellbook or spell passive and not casted by client
if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(spellId) ) if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(spellId) )
@ -364,7 +376,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
} }
// auto-selection buff level base at target level (in spellInfo) // auto-selection buff level base at target level (in spellInfo)
if(targets.getUnitTarget()) if (targets.getUnitTarget())
{ {
SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(spellInfo,targets.getUnitTarget()->getLevel()); SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForPlayerLevel(spellInfo,targets.getUnitTarget()->getLevel());
@ -380,16 +392,16 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket) void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket)
{ {
// ignore for remote control state (for player case)
Unit* mover = _player->m_mover;
if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
return;
uint32 spellId; uint32 spellId;
recvPacket.read_skip<uint8>(); // counter, increments with every CANCEL packet, don't use for now recvPacket.read_skip<uint8>(); // counter, increments with every CANCEL packet, don't use for now
recvPacket >> spellId; recvPacket >> spellId;
// ignore for remote control state (for player case)
Unit* mover = _player->GetMover();
if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
return;
//FIXME: hack, ignore unexpected client cancel Deadly Throw cast //FIXME: hack, ignore unexpected client cancel Deadly Throw cast
if(spellId==26679) if(spellId==26679)
return; return;
@ -410,10 +422,10 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
if (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL) if (spellInfo->Attributes & SPELL_ATTR_CANT_CANCEL)
return; return;
if(!IsPositiveSpell(spellId)) if (!IsPositiveSpell(spellId))
{ {
// ignore for remote control state // ignore for remote control state
if (_player->m_mover != _player) if (!_player->IsSelfMover())
{ {
// except own aura spells // except own aura spells
bool allow = false; bool allow = false;
@ -450,16 +462,16 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket) void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
{ {
// ignore for remote control state
if(_player->m_mover != _player)
return;
uint64 guid; uint64 guid;
uint32 spellId; uint32 spellId;
recvPacket >> guid; recvPacket >> guid;
recvPacket >> spellId; recvPacket >> spellId;
// ignore for remote control state
if (!_player->IsSelfMover())
return;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
if(!spellInfo) if(!spellInfo)
{ {
@ -501,7 +513,7 @@ void WorldSession::HandleCancelAutoRepeatSpellOpcode( WorldPacket& /*recvPacket*
{ {
// cancel and prepare for deleting // cancel and prepare for deleting
// do not send SMSG_CANCEL_AUTO_REPEAT! client will send this Opcode again (loop) // do not send SMSG_CANCEL_AUTO_REPEAT! client will send this Opcode again (loop)
_player->m_mover->InterruptSpell(CURRENT_AUTOREPEAT_SPELL, true, false); _player->GetMover()->InterruptSpell(CURRENT_AUTOREPEAT_SPELL, true, false);
} }
void WorldSession::HandleCancelChanneling( WorldPacket & recv_data) void WorldSession::HandleCancelChanneling( WorldPacket & recv_data)
@ -509,8 +521,8 @@ void WorldSession::HandleCancelChanneling( WorldPacket & recv_data)
recv_data.read_skip<uint32>(); // spellid, not used recv_data.read_skip<uint32>(); // spellid, not used
// ignore for remote control state (for player case) // ignore for remote control state (for player case)
Unit* mover = _player->m_mover; Unit* mover = _player->GetMover();
if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER) if (mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
return; return;
mover->InterruptSpell(CURRENT_CHANNELED_SPELL); mover->InterruptSpell(CURRENT_CHANNELED_SPELL);
@ -518,14 +530,14 @@ void WorldSession::HandleCancelChanneling( WorldPacket & recv_data)
void WorldSession::HandleTotemDestroyed( WorldPacket& recvPacket) void WorldSession::HandleTotemDestroyed( WorldPacket& recvPacket)
{ {
// ignore for remote control state
if(_player->m_mover != _player)
return;
uint8 slotId; uint8 slotId;
recvPacket >> slotId; recvPacket >> slotId;
// ignore for remote control state
if (!_player->IsSelfMover())
return;
if (int(slotId) >= MAX_TOTEM_SLOT) if (int(slotId) >= MAX_TOTEM_SLOT)
return; return;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "10058" #define REVISION_NR "10059"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__