fix(Core/Transports): Exclude out of world players from receiving transport creations/removes. (#26680)

Co-authored-by: Claude <claude@users.noreply.github.com>
This commit is contained in:
Benjamin Jackson
2026-07-19 06:27:43 -04:00
committed by GitHub
parent 92bc564d88
commit 11747f6a50
2 changed files with 16 additions and 2 deletions

View File

@@ -35,6 +35,7 @@
#include "ScriptMgr.h"
#include "SpellAuras.h"
#include "Transport.h"
#include "UpdateData.h"
#include "Vehicle.h"
#include "WaypointMovementGenerator.h"
#include "WorldPacket.h"
@@ -129,6 +130,14 @@ void WorldSession::HandleMoveWorldportAck()
if (Transport* t = _player->GetTransport())
if (!t->IsInMap(_player))
{
// Client was never told to destroy its own transport
// Destroy it now or it keeps a phantom copy of the transport on the new map
UpdateData transData;
t->BuildOutOfRangeUpdateBlock(&transData);
WorldPacket packet;
transData.BuildPacket(packet);
_player->SendDirectMessage(&packet);
t->RemovePassenger(_player);
_player->m_transport = nullptr;
_player->m_movementInfo.transport.Reset();

View File

@@ -376,9 +376,12 @@ bool Map::AddToMap(Transport* obj, bool /*checkTransport*/)
_transports.insert(obj);
// Broadcast creation to players
// Skip players that are not in world. Sending the create to their loading client
// could materialize a lingering transport on whatever map they are teleporting to.
// They get the correct transport list from SendInitTransports when added to their new map
for (Map::PlayerList::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
{
if (itr->GetSource()->GetTransport() != obj)
if (itr->GetSource()->IsInWorld() && itr->GetSource()->GetTransport() != obj)
{
UpdateData data;
obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
@@ -761,8 +764,10 @@ void Map::RemoveFromMap(Transport* obj, bool remove)
obj->BuildOutOfRangeUpdateBlock(&data);
WorldPacket packet;
data.BuildPacket(packet);
// Skip players that are not in world
// Their client already received the destroy from SendRemoveTransports when leaving this map
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (itr->GetSource()->GetTransport() != obj)
if (itr->GetSource()->IsInWorld() && itr->GetSource()->GetTransport() != obj)
itr->GetSource()->SendDirectMessage(&packet);
}