diff --git a/Server/Components/Vehicles/vehicle.cpp b/Server/Components/Vehicles/vehicle.cpp index c960b9473..b39c7f74d 100644 --- a/Server/Components/Vehicles/vehicle.cpp +++ b/Server/Components/Vehicles/vehicle.cpp @@ -810,6 +810,15 @@ void Vehicle::destream() vehicleData->setVehicle(nullptr, 0); } + // Related issue: https://github.com/openmultiplayer/open.mp/issues/735 + // Disable spectator's spectating state when spectated vehicle is removed + // This also makes spectateData values to be accurate and not remain with old data + auto spectateData = player->getSpectateData(); + if (spectateData.type == PlayerSpectateData::ESpectateType::Vehicle && spectateData.spectateID == poolID) + { + player->setSpectating(false); + } + if (isStreamedInForPlayer(*player)) { streamOutForClient(*player); diff --git a/Server/Source/player_impl.hpp b/Server/Source/player_impl.hpp index 01e85ad82..4fe6808ee 100644 --- a/Server/Source/player_impl.hpp +++ b/Server/Source/player_impl.hpp @@ -606,13 +606,19 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy void setSpectating(bool spectating) override { + NetCode::RPC::TogglePlayerSpectating togglePlayerSpectatingRPC; + // Reset internal player spectating data if ID is already set to a player // Related issue: https://github.com/openmultiplayer/open.mp/issues/735 - if (!spectating && spectateData_.spectateID != INVALID_PLAYER_ID) + // UPD: Also send player spectating RPC to disable it first in client internally + if (spectating && spectateData_.type == PlayerSpectateData::ESpectateType::Player && spectateData_.spectateID != INVALID_PLAYER_ID) { spectateData_.type = PlayerSpectateData::ESpectateType::None; spectateData_.spectateID = INVALID_PLAYER_ID; spectateData_.spectating = false; + + togglePlayerSpectatingRPC.Enable = spectateData_.spectating; + PacketHelper::send(togglePlayerSpectatingRPC, *this); } if (spectating == spectateData_.spectating) @@ -641,7 +647,6 @@ struct Player final : public IPlayer, public PoolIDProvider, public NoCopy } spectateData_.spectating = spectating; - NetCode::RPC::TogglePlayerSpectating togglePlayerSpectatingRPC; togglePlayerSpectatingRPC.Enable = spectating; PacketHelper::send(togglePlayerSpectatingRPC, *this); } diff --git a/Server/Source/player_pool.hpp b/Server/Source/player_pool.hpp index 9fa39d9c3..78f26dab2 100644 --- a/Server/Source/player_pool.hpp +++ b/Server/Source/player_pool.hpp @@ -1722,7 +1722,17 @@ struct PlayerPool final : public IPlayerPool, public NetworkEventHandler, public { continue; } + Player* other = static_cast(p); + + // Related issue: https://github.com/openmultiplayer/open.mp/issues/735 + // Disable spectator's spectating state when spectated player is disconnected + // This also makes spectateData values to be accurate and not remain with old data + if (other->spectateData_.type == PlayerSpectateData::ESpectateType::Player && other->spectateData_.spectateID == player.getID()) + { + other->setSpectating(false); + } + if (player.streamedFor_.valid(other->poolID)) { --other->numStreamed_;