Skip to content

Commit

Permalink
Merge pull request #740 from openmultiplayer/amir/spec
Browse files Browse the repository at this point in the history
Properly handle spectating when a player disconnects
  • Loading branch information
AmyrAhmady authored Oct 15, 2023
2 parents e2fdba7 + da79040 commit a32e732
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
9 changes: 9 additions & 0 deletions Server/Components/Vehicles/vehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 7 additions & 2 deletions Server/Source/player_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
Expand Down
10 changes: 10 additions & 0 deletions Server/Source/player_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1722,7 +1722,17 @@ struct PlayerPool final : public IPlayerPool, public NetworkEventHandler, public
{
continue;
}

Player* other = static_cast<Player*>(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_;
Expand Down

0 comments on commit a32e732

Please sign in to comment.