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 // Check if server owner has left
updateServerOwner(); updateServerOwner();
if (ServerConfig::m_ranked && m_state.load() == WAITING_FOR_START_GAME)
clearDisconnectedRankedPlayer();
if (allowJoinedPlayersWaiting() || (m_game_setup->isGrandPrix() && if (allowJoinedPlayersWaiting() || (m_game_setup->isGrandPrix() &&
m_state.load() == WAITING_FOR_START_GAME)) m_state.load() == WAITING_FOR_START_GAME))
{ {
updateWaitingPlayers(); updateWaitingPlayers();
clearDisconnectedRankedPlayer();
// Only poll the STK server if this is a WAN server. // Only poll the STK server if this is a WAN server.
if (NetworkConfig::get()->isWAN()) if (NetworkConfig::get()->isWAN())
checkIncomingConnectionRequests(); checkIncomingConnectionRequests();
@ -1460,13 +1462,17 @@ void ServerLobby::connectionRequested(Event* event)
// Reject non-valiated player joinning if WAN server and not disabled // Reject non-valiated player joinning if WAN server and not disabled
// encforement of validation, unless it's player from localhost or lan // encforement of validation, unless it's player from localhost or lan
// And no duplicated online id or split screen players in ranked server // 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) && if (((encrypted_size == 0 || online_id == 0) &&
!(peer->getAddress().isPublicAddressLocalhost() || !(peer->getAddress().isPublicAddressLocalhost() ||
peer->getAddress().isLAN()) && peer->getAddress().isLAN()) &&
NetworkConfig::get()->isWAN() && NetworkConfig::get()->isWAN() &&
ServerConfig::m_validating_player) || ServerConfig::m_validating_player) ||
((player_count != 1 || online_id == 0 || (ServerConfig::m_ranked &&
m_scores.find(online_id) != m_scores.end()) && ServerConfig::m_ranked)) (player_count != 1 || online_id == 0 || duplicated_ranked_player)))
{ {
NetworkString* message = getNetworkString(2); NetworkString* message = getNetworkString(2);
message->setSynchronous(true); message->setSynchronous(true);
@ -1516,9 +1522,11 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr<STKPeer> peer,
return; return;
} }
// Check again for duplicated online id in ranked server // Check again for duplicated player in ranked server
if (m_scores.find(online_id) != m_scores.end() && bool duplicated_ranked_player =
ServerConfig::m_ranked) 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); NetworkString* message = getNetworkString(2);
message->setSynchronous(true); message->setSynchronous(true);
@ -2321,13 +2329,16 @@ void ServerLobby::addWaitingPlayersToGame()
uint32_t online_id = npp->getOnlineId(); uint32_t online_id = npp->getOnlineId();
if (ServerConfig::m_ranked) 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); NetworkString* message = getNetworkString(2);
message->setSynchronous(true); message->setSynchronous(true);
message->addUInt8(LE_CONNECTION_REFUSED) message->addUInt8(LE_CONNECTION_REFUSED)
.addUInt8(RR_INVALID_PLAYER); .addUInt8(RR_INVALID_PLAYER);
peer->sendPacket(message, true/*reliable*/, false/*encrypted*/); peer->sendPacket(message, true/*reliable*/);
peer->reset(); peer->reset();
delete message; delete message;
Log::verbose("ServerLobby", "Player refused: invalid player"); 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); std::unique_lock<std::mutex> lock(m_peers_mutex);
for (auto peer : m_peers) for (auto peer : m_peers)
{ {
if (peer.second->isDisconnected())
continue;
auto peer_profile = peer.second->getPlayerProfiles(); auto peer_profile = peer.second->getPlayerProfiles();
p.insert(p.end(), peer_profile.begin(), peer_profile.end()); 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_validated.store(false);
m_average_ping.store(0); m_average_ping.store(0);
m_waiting_for_game.store(true); m_waiting_for_game.store(true);
m_disconnected.store(false);
} // STKPeer } // STKPeer
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -55,6 +56,7 @@ void STKPeer::disconnect()
if (m_enet_peer->state != ENET_PEER_STATE_CONNECTED || if (m_enet_peer->state != ENET_PEER_STATE_CONNECTED ||
a != m_peer_address) a != m_peer_address)
return; return;
m_disconnected.store(true);
m_host->addEnetCommand(m_enet_peer, NULL, PDI_NORMAL, ECT_DISCONNECT); m_host->addEnetCommand(m_enet_peer, NULL, PDI_NORMAL, ECT_DISCONNECT);
} // disconnect } // disconnect
@ -67,6 +69,7 @@ void STKPeer::kick()
if (m_enet_peer->state != ENET_PEER_STATE_CONNECTED || if (m_enet_peer->state != ENET_PEER_STATE_CONNECTED ||
a != m_peer_address) a != m_peer_address)
return; return;
m_disconnected.store(true);
m_host->addEnetCommand(m_enet_peer, NULL, PDI_KICK, ECT_DISCONNECT); m_host->addEnetCommand(m_enet_peer, NULL, PDI_KICK, ECT_DISCONNECT);
} // kick } // kick
@ -79,6 +82,7 @@ void STKPeer::reset()
if (m_enet_peer->state != ENET_PEER_STATE_CONNECTED || if (m_enet_peer->state != ENET_PEER_STATE_CONNECTED ||
a != m_peer_address) a != m_peer_address)
return; return;
m_disconnected.store(true);
m_host->addEnetCommand(m_enet_peer, NULL, 0, ECT_RESET); m_host->addEnetCommand(m_enet_peer, NULL, 0, ECT_RESET);
} // reset } // reset

View File

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