Prevent undefined behaviour if too many players joined battle or soccer
This commit is contained in:
parent
f99e13cb78
commit
875c2b8eb8
@ -2456,7 +2456,7 @@ void ServerLobby::startSelection(const Event *event)
|
|||||||
if (!has_peer_plays_game)
|
if (!has_peer_plays_game)
|
||||||
{
|
{
|
||||||
for (STKPeer* peer : always_spectate_peers)
|
for (STKPeer* peer : always_spectate_peers)
|
||||||
peer->setAlwaysSpectate(false);
|
peer->setAlwaysSpectate(ASM_NONE);
|
||||||
always_spectate_peers.clear();
|
always_spectate_peers.clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2469,6 +2469,40 @@ void ServerLobby::startSelection(const Event *event)
|
|||||||
peer->setWaitingForGame(true);
|
peer->setWaitingForGame(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned max_player = 0;
|
||||||
|
STKHost::get()->updatePlayers(&max_player);
|
||||||
|
|
||||||
|
if (max_player > 10 && (RaceManager::get()->isBattleMode() ||
|
||||||
|
RaceManager::get()->isSoccerMode()))
|
||||||
|
{
|
||||||
|
// Set late coming player to spectate if too many players in battle or
|
||||||
|
// soccer
|
||||||
|
std::sort(peers.begin(), peers.end(),
|
||||||
|
[](const std::shared_ptr<STKPeer>& a,
|
||||||
|
const std::shared_ptr<STKPeer>& b)
|
||||||
|
{ return a->getHostId() > b->getHostId(); });
|
||||||
|
int remove_player = max_player - 10;
|
||||||
|
for (unsigned i = 0; i < peers.size(); i++)
|
||||||
|
{
|
||||||
|
auto& peer = peers[i];
|
||||||
|
if (!peer->isValidated() || peer->isWaitingForGame())
|
||||||
|
continue;
|
||||||
|
peer->setAlwaysSpectate(ASM_FULL);
|
||||||
|
peer->setWaitingForGame(true);
|
||||||
|
always_spectate_peers.insert(peer.get());
|
||||||
|
remove_player -= (int)peer->getPlayerProfiles().size();
|
||||||
|
if (remove_player <= 0)
|
||||||
|
break;
|
||||||
|
// In case something goes wrong (all players need spectate)
|
||||||
|
if (i == peers.size() - 1)
|
||||||
|
{
|
||||||
|
Log::error("ServerLobby", "Too many players and cannot set "
|
||||||
|
"spectate for late coming players!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const std::string& kart_erase : karts_erase)
|
for (const std::string& kart_erase : karts_erase)
|
||||||
{
|
{
|
||||||
m_available_kts.first.erase(kart_erase);
|
m_available_kts.first.erase(kart_erase);
|
||||||
@ -2478,7 +2512,7 @@ void ServerLobby::startSelection(const Event *event)
|
|||||||
m_available_kts.second.erase(track_erase);
|
m_available_kts.second.erase(track_erase);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned max_player = 0;
|
max_player = 0;
|
||||||
STKHost::get()->updatePlayers(&max_player);
|
STKHost::get()->updatePlayers(&max_player);
|
||||||
if (auto ai = m_ai_peer.lock())
|
if (auto ai = m_ai_peer.lock())
|
||||||
{
|
{
|
||||||
@ -4684,6 +4718,7 @@ void ServerLobby::addWaitingPlayersToGame()
|
|||||||
if (!peer || !peer->isValidated())
|
if (!peer || !peer->isValidated())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
peer->resetAlwaysSpectateFull();
|
||||||
peer->setWaitingForGame(false);
|
peer->setWaitingForGame(false);
|
||||||
peer->setSpectator(false);
|
peer->setSpectator(false);
|
||||||
if (m_peers_ready.find(peer) == m_peers_ready.end())
|
if (m_peers_ready.find(peer) == m_peers_ready.end())
|
||||||
@ -5522,10 +5557,10 @@ void ServerLobby::handleServerCommand(Event* event,
|
|||||||
delete chat;
|
delete chat;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
peer->setAlwaysSpectate(true);
|
peer->setAlwaysSpectate(ASM_COMMAND);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
peer->setAlwaysSpectate(false);
|
peer->setAlwaysSpectate(ASM_NONE);
|
||||||
updatePlayerList();
|
updatePlayerList();
|
||||||
}
|
}
|
||||||
else if (argv[0] == "listserveraddon")
|
else if (argv[0] == "listserveraddon")
|
||||||
|
@ -44,7 +44,7 @@ STKPeer::STKPeer(ENetPeer *enet_peer, STKHost* host, uint32_t host_id)
|
|||||||
m_host_id = host_id;
|
m_host_id = host_id;
|
||||||
m_connected_time = StkTime::getMonoTimeMs();
|
m_connected_time = StkTime::getMonoTimeMs();
|
||||||
m_validated.store(false);
|
m_validated.store(false);
|
||||||
m_always_spectate.store(false);
|
m_always_spectate.store(ASM_NONE);
|
||||||
m_average_ping.store(0);
|
m_average_ping.store(0);
|
||||||
m_packet_loss.store(0);
|
m_packet_loss.store(0);
|
||||||
m_waiting_for_game.store(true);
|
m_waiting_for_game.store(true);
|
||||||
|
@ -61,6 +61,13 @@ enum AddonScore : int
|
|||||||
AS_TOTAL = 4,
|
AS_TOTAL = 4,
|
||||||
}; // AddonScore
|
}; // AddonScore
|
||||||
|
|
||||||
|
enum AlwaysSpectateMode : uint8_t
|
||||||
|
{
|
||||||
|
ASM_NONE = 0, //!< Default, not spectating at all
|
||||||
|
ASM_COMMAND = 1, //!< Set by player through command
|
||||||
|
ASM_FULL = 2, //!< Set by server because too many players joined
|
||||||
|
}; // AlwaysSpectateMode
|
||||||
|
|
||||||
/*! \class STKPeer
|
/*! \class STKPeer
|
||||||
* \brief Represents a peer.
|
* \brief Represents a peer.
|
||||||
* This class is used to interface the ENetPeer structure.
|
* This class is used to interface the ENetPeer structure.
|
||||||
@ -85,7 +92,7 @@ protected:
|
|||||||
|
|
||||||
std::atomic_bool m_warned_for_high_ping;
|
std::atomic_bool m_warned_for_high_ping;
|
||||||
|
|
||||||
std::atomic_bool m_always_spectate;
|
std::atomic<uint8_t> m_always_spectate;
|
||||||
|
|
||||||
/** Host id of this peer. */
|
/** Host id of this peer. */
|
||||||
uint32_t m_host_id;
|
uint32_t m_host_id;
|
||||||
@ -292,10 +299,17 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
const SocketAddress& getAddress() const { return *m_socket_address.get(); }
|
const SocketAddress& getAddress() const { return *m_socket_address.get(); }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setAlwaysSpectate(bool val) { m_always_spectate.store(val); }
|
void setAlwaysSpectate(AlwaysSpectateMode mode)
|
||||||
|
{ m_always_spectate.store(mode); }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
bool alwaysSpectate() const { return m_always_spectate.load(); }
|
bool alwaysSpectate() const
|
||||||
|
{ return m_always_spectate.load() != ASM_NONE; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void resetAlwaysSpectateFull()
|
||||||
|
{
|
||||||
|
if (m_always_spectate.load() == ASM_FULL)
|
||||||
|
m_always_spectate.store(ASM_NONE);
|
||||||
|
}
|
||||||
}; // STKPeer
|
}; // STKPeer
|
||||||
|
|
||||||
#endif // STK_PEER_HPP
|
#endif // STK_PEER_HPP
|
||||||
|
Loading…
x
Reference in New Issue
Block a user