mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
[10077] Add delayed far teleports for opcode handlers
Some opcode handlers have many code with possible deep calling far teleports by some reason (death, quest script, etc). This can be triggering unexpected lost Map context and crashs result. Note: player login opcode still have disbled delayed teleports (old way work) just becase Player object created in it and not have flag set. Calling point look not 100% safe but at this commit this way not chnages for while.
This commit is contained in:
parent
3e210228f9
commit
d6138f01a6
4 changed files with 35 additions and 19 deletions
|
|
@ -184,11 +184,8 @@ bool WorldSession::Update(uint32 /*diff*/)
|
|||
LogUnexpectedOpcode(packet, "the player has not logged in yet");
|
||||
}
|
||||
else if(_player->IsInWorld())
|
||||
{
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
ExecuteOpcode(opHandle, packet);
|
||||
|
||||
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
|
||||
break;
|
||||
case STATUS_LOGGEDIN_OR_RECENTLY_LOGGEDOUT:
|
||||
|
|
@ -197,12 +194,8 @@ bool WorldSession::Update(uint32 /*diff*/)
|
|||
LogUnexpectedOpcode(packet, "the player has not logged in yet and not recently logout");
|
||||
}
|
||||
else
|
||||
{
|
||||
// not expected _player or must checked in packet hanlder
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
ExecuteOpcode(opHandle, packet);
|
||||
break;
|
||||
case STATUS_TRANSFER:
|
||||
if(!_player)
|
||||
|
|
@ -210,11 +203,7 @@ bool WorldSession::Update(uint32 /*diff*/)
|
|||
else if(_player->IsInWorld())
|
||||
LogUnexpectedOpcode(packet, "the player is still in world");
|
||||
else
|
||||
{
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
ExecuteOpcode(opHandle, packet);
|
||||
break;
|
||||
case STATUS_AUTHED:
|
||||
// prevent cheating with skip queue wait
|
||||
|
|
@ -229,9 +218,7 @@ bool WorldSession::Update(uint32 /*diff*/)
|
|||
if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
|
||||
m_playerRecentlyLogout = false;
|
||||
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
||||
LogUnprocessedTail(packet);
|
||||
ExecuteOpcode(opHandle, packet);
|
||||
break;
|
||||
case STATUS_NEVER:
|
||||
sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)",
|
||||
|
|
@ -872,3 +859,27 @@ void WorldSession::SendRedirectClient(std::string& ip, uint16 port)
|
|||
|
||||
SendPacket(&pkt);
|
||||
}
|
||||
|
||||
void WorldSession::ExecuteOpcode( OpcodeHandler& opHandle, WorldPacket* packet )
|
||||
{
|
||||
// need prevent do internal far teleports in handlers because some handlers do lot steps
|
||||
// or call code that can do far teleports in some conditions unexpectedly for generic way work code
|
||||
if (_player)
|
||||
_player->SetCanDelayTeleport(true);
|
||||
|
||||
(this->*opHandle.handler)(*packet);
|
||||
|
||||
if (_player)
|
||||
{
|
||||
// can be not set in fact for login opcode, but this not create porblems.
|
||||
_player->SetCanDelayTeleport(false);
|
||||
|
||||
//we should execute delayed teleports only for alive(!) players
|
||||
//because we don't want player's ghost teleported from graveyard
|
||||
if (_player->IsHasDelayedTeleport() && _player->isAlive())
|
||||
_player->TeleportTo(_player->m_teleport_dest, _player->m_teleport_options);
|
||||
}
|
||||
|
||||
if (packet->rpos() < packet->wpos() && sLog.HasLogLevelOrHigher(LOG_LVL_DEBUG))
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue