From 0817d5d7154a56295bd52c3d54710023ac26b1be Mon Sep 17 00:00:00 2001 From: elexis Date: Thu, 26 Sep 2019 11:36:03 +0000 Subject: [PATCH] Always inform clients why the server chose to disconnect them, i.e. stop using NDR_UNKNOWN as a disconnect reason when the reason is known and add a LOGWARNING for future authors. Differential Revision: https://code.wildfiregames.com/D1561 Tested on: clang 8.0.1, Jenkins This was SVN commit r22996. --- .../data/mods/public/gui/common/network.js | 3 +++ source/network/NetHost.h | 9 ++++++-- source/network/NetServer.cpp | 2 +- source/network/NetServerTurnManager.cpp | 6 ++--- source/network/NetSession.cpp | 23 +++++++++++++------ source/network/NetSession.h | 8 +++---- 6 files changed, 34 insertions(+), 17 deletions(-) diff --git a/binaries/data/mods/public/gui/common/network.js b/binaries/data/mods/public/gui/common/network.js index 3bb6f60039..eec29453f8 100644 --- a/binaries/data/mods/public/gui/common/network.js +++ b/binaries/data/mods/public/gui/common/network.js @@ -73,6 +73,9 @@ function getDisconnectReason(id, wasConnected) case 7: return translate("Playername in use. If you were disconnected, retry in few seconds."); case 8: return translate("Server full."); case 9: return translate("Secure lobby authentication failed. Join via lobby."); + case 10: return translate("Error: Server failed to allocate a unique client identifier."); + case 11: return translate("Error: Client commands were ready for an unexpected game turn."); + case 12: return translate("Error: Client simulated an unexpected game turn."); default: warn("Unknown disconnect-reason ID received: " + id); return sprintf(translate("\\[Invalid value %(id)s]"), { "id": id }); diff --git a/source/network/NetHost.h b/source/network/NetHost.h index 3710c0f41f..00198a9f7a 100644 --- a/source/network/NetHost.h +++ b/source/network/NetHost.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -56,6 +56,8 @@ typedef std::map PlayerAssignmentMap; // map from GUID - /** * Reasons sent by server to clients in disconnection messages. * Must be kept in sync with binaries/data/mods/public/gui/common/network.js + * To avoid ambiguity, use a distinct reason for each callstack leading to a disconnect. + * NDR_UNKNOWN should remain reserved to the case where it is actually not a known disconnect by the server. */ enum NetDisconnectReason { @@ -68,7 +70,10 @@ enum NetDisconnectReason NDR_BANNED, NDR_PLAYERNAME_IN_USE, NDR_SERVER_FULL, - NDR_LOBBY_AUTH_FAILED + NDR_LOBBY_AUTH_FAILED, + NDR_GUID_FAILED, + NDR_INCORRECT_READY_TURN_COMMANDS, + NDR_INCORRECT_READY_TURN_SIMULATED }; class CNetHost diff --git a/source/network/NetServer.cpp b/source/network/NetServer.cpp index c4943bf0b3..0045d46a75 100644 --- a/source/network/NetServer.cpp +++ b/source/network/NetServer.cpp @@ -923,7 +923,7 @@ bool CNetServerWorker::OnClientHandshake(void* context, CFsmEvent* event) { if (++count > 100) { - session->Disconnect(NDR_UNKNOWN); + session->Disconnect(NDR_GUID_FAILED); return true; } guid = ps_generate_guid(); diff --git a/source/network/NetServerTurnManager.cpp b/source/network/NetServerTurnManager.cpp index 11130b29a3..f16e749931 100644 --- a/source/network/NetServerTurnManager.cpp +++ b/source/network/NetServerTurnManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -58,7 +58,7 @@ void CNetServerTurnManager::NotifyFinishedClientCommands(CNetServerSession& sess turn, m_ClientsReady[client] + 1); - session.Disconnect(NDR_UNKNOWN); + session.Disconnect(NDR_INCORRECT_READY_TURN_COMMANDS); } m_ClientsReady[client] = turn; @@ -106,7 +106,7 @@ void CNetServerTurnManager::NotifyFinishedClientUpdate(CNetServerSession& sessio turn, m_ClientsReady[client] + 1); - session.Disconnect(NDR_UNKNOWN); + session.Disconnect(NDR_INCORRECT_READY_TURN_SIMULATED); } m_ClientsSimulated[client] = turn; diff --git a/source/network/NetSession.cpp b/source/network/NetSession.cpp index f0a5bbf2af..457714b125 100644 --- a/source/network/NetSession.cpp +++ b/source/network/NetSession.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -115,12 +115,15 @@ bool CNetClientSession::Connect(const CStr& server, const u16 port, const bool i return true; } -void CNetClientSession::Disconnect(u32 reason) +void CNetClientSession::Disconnect(NetDisconnectReason reason) { + if (reason == NDR_UNKNOWN) + LOGWARNING("Disconnecting from the server without communicating the disconnect reason!"); + ENSURE(m_Host && m_Server); // TODO: ought to do reliable async disconnects, probably - enet_peer_disconnect_now(m_Server, reason); + enet_peer_disconnect_now(m_Server, static_cast(reason)); enet_host_destroy(m_Host); m_Host = NULL; @@ -252,16 +255,22 @@ u32 CNetServerSession::GetMeanRTT() const return m_Peer->roundTripTime; } -void CNetServerSession::Disconnect(u32 reason) +void CNetServerSession::Disconnect(NetDisconnectReason reason) { + if (reason == NDR_UNKNOWN) + LOGWARNING("Disconnecting client without communicating the disconnect reason!"); + Update((uint)NMT_CONNECTION_LOST, NULL); - enet_peer_disconnect(m_Peer, reason); + enet_peer_disconnect(m_Peer, static_cast(reason)); } -void CNetServerSession::DisconnectNow(u32 reason) +void CNetServerSession::DisconnectNow(NetDisconnectReason reason) { - enet_peer_disconnect_now(m_Peer, reason); + if (reason == NDR_UNKNOWN) + LOGWARNING("Disconnecting client without communicating the disconnect reason!"); + + enet_peer_disconnect_now(m_Peer, static_cast(reason)); } bool CNetServerSession::SendMessage(const CNetMessage* message) diff --git a/source/network/NetSession.h b/source/network/NetSession.h index 298d99c75f..53bad9ebb4 100644 --- a/source/network/NetSession.h +++ b/source/network/NetSession.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -88,7 +88,7 @@ public: * Disconnect from the server. * Sends a disconnection notification to the server. */ - void Disconnect(u32 reason); + void Disconnect(NetDisconnectReason reason); /** * Send a message to the server. @@ -175,14 +175,14 @@ public: * The server will receive a disconnection notification after a while. * The server will not receive any further messages sent via this session. */ - void Disconnect(u32 reason); + void Disconnect(NetDisconnectReason reason); /** * Sends an unreliable disconnection notification to the client. * The server will not receive any disconnection notification. * The server will not receive any further messages sent via this session. */ - void DisconnectNow(u32 reason); + void DisconnectNow(NetDisconnectReason reason); /** * Prevent timeouts for the client running in the same process as the server.