Fix ranked server player reconnection handling

This commit is contained in:
Benau 2018-09-13 10:46:37 +08:00
parent 323af45fbd
commit 3b070cdaad
4 changed files with 29 additions and 9 deletions

View File

@ -369,11 +369,13 @@ void ServerLobby::asynchronousUpdate()
// Check if server owner has left
updateServerOwner();
if (ServerConfig::m_ranked && m_state.load() == WAITING_FOR_START_GAME)
clearDisconnectedRankedPlayer();
if (allowJoinedPlayersWaiting() || (m_game_setup->isGrandPrix() &&
m_state.load() == WAITING_FOR_START_GAME))
{
updateWaitingPlayers();
clearDisconnectedRankedPlayer();
// Only poll the STK server if this is a WAN server.
if (NetworkConfig::get()->isWAN())
checkIncomingConnectionRequests();
@ -1460,13 +1462,17 @@ void ServerLobby::connectionRequested(Event* event)
// Reject non-valiated player joinning if WAN server and not disabled
// encforement of validation, unless it's player from localhost or lan
// And no duplicated online id or split screen players in ranked server
bool duplicated_ranked_player =
m_ranked_players.find(online_id) != m_ranked_players.end() &&
!m_ranked_players.at(online_id).expired();
if (((encrypted_size == 0 || online_id == 0) &&
!(peer->getAddress().isPublicAddressLocalhost() ||
peer->getAddress().isLAN()) &&
NetworkConfig::get()->isWAN() &&
ServerConfig::m_validating_player) ||
((player_count != 1 || online_id == 0 ||
m_scores.find(online_id) != m_scores.end()) && ServerConfig::m_ranked))
(ServerConfig::m_ranked &&
(player_count != 1 || online_id == 0 || duplicated_ranked_player)))
{
NetworkString* message = getNetworkString(2);
message->setSynchronous(true);
@ -1516,9 +1522,11 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr<STKPeer> peer,
return;
}
// Check again for duplicated online id in ranked server
if (m_scores.find(online_id) != m_scores.end() &&
ServerConfig::m_ranked)
// Check again for duplicated player in ranked server
bool duplicated_ranked_player =
m_ranked_players.find(online_id) != m_ranked_players.end() &&
!m_ranked_players.at(online_id).expired();
if (ServerConfig::m_ranked && duplicated_ranked_player)
{
NetworkString* message = getNetworkString(2);
message->setSynchronous(true);
@ -2321,13 +2329,16 @@ void ServerLobby::addWaitingPlayersToGame()
uint32_t online_id = npp->getOnlineId();
if (ServerConfig::m_ranked)
{
if (m_scores.find(online_id) != m_scores.end())
bool duplicated_ranked_player =
m_ranked_players.find(online_id) != m_ranked_players.end() &&
!m_ranked_players.at(online_id).expired();
if (duplicated_ranked_player)
{
NetworkString* message = getNetworkString(2);
message->setSynchronous(true);
message->addUInt8(LE_CONNECTION_REFUSED)
.addUInt8(RR_INVALID_PLAYER);
peer->sendPacket(message, true/*reliable*/, false/*encrypted*/);
peer->sendPacket(message, true/*reliable*/);
peer->reset();
delete message;
Log::verbose("ServerLobby", "Player refused: invalid player");

View File

@ -1221,6 +1221,8 @@ std::vector<std::shared_ptr<NetworkPlayerProfile> >
std::unique_lock<std::mutex> lock(m_peers_mutex);
for (auto peer : m_peers)
{
if (peer.second->isDisconnected())
continue;
auto peer_profile = peer.second->getPlayerProfiles();
p.insert(p.end(), peer_profile.begin(), peer_profile.end());
}

View File

@ -41,6 +41,7 @@ STKPeer::STKPeer(ENetPeer *enet_peer, STKHost* host, uint32_t host_id)
m_validated.store(false);
m_average_ping.store(0);
m_waiting_for_game.store(true);
m_disconnected.store(false);
} // STKPeer
//-----------------------------------------------------------------------------
@ -55,6 +56,7 @@ void STKPeer::disconnect()
if (m_enet_peer->state != ENET_PEER_STATE_CONNECTED ||
a != m_peer_address)
return;
m_disconnected.store(true);
m_host->addEnetCommand(m_enet_peer, NULL, PDI_NORMAL, ECT_DISCONNECT);
} // disconnect
@ -67,6 +69,7 @@ void STKPeer::kick()
if (m_enet_peer->state != ENET_PEER_STATE_CONNECTED ||
a != m_peer_address)
return;
m_disconnected.store(true);
m_host->addEnetCommand(m_enet_peer, NULL, PDI_KICK, ECT_DISCONNECT);
} // kick
@ -79,6 +82,7 @@ void STKPeer::reset()
if (m_enet_peer->state != ENET_PEER_STATE_CONNECTED ||
a != m_peer_address)
return;
m_disconnected.store(true);
m_host->addEnetCommand(m_enet_peer, NULL, 0, ECT_RESET);
} // reset

View File

@ -67,6 +67,8 @@ protected:
/** True if this peer is waiting for game. */
std::atomic_bool m_waiting_for_game;
std::atomic_bool m_disconnected;
/** Host id of this peer. */
uint32_t m_host_id;
@ -177,7 +179,8 @@ public:
void setWaitingForGame(bool val) { m_waiting_for_game.store(val); }
// ------------------------------------------------------------------------
bool isWaitingForGame() const { return m_waiting_for_game.load(); }
// ------------------------------------------------------------------------
bool isDisconnected() const { return m_disconnected.load(); }
}; // STKPeer
#endif // STK_PEER_HPP