From db5a52a0f857b482b07e0c1e1a3f4fad3e162968 Mon Sep 17 00:00:00 2001 From: Arseniy Shestakov Date: Sun, 30 Oct 2016 02:43:06 +0300 Subject: [PATCH] Multiplayer: gracefully handle player loss unless it's a host We don't want server to shutdown after just one of players lost the game. --- client/Client.cpp | 5 +++-- lib/serializer/Connection.cpp | 5 +++++ lib/serializer/Connection.h | 1 + server/CGameHandler.cpp | 6 +++++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/client/Client.cpp b/client/Client.cpp index 7779aabe8..d07726690 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -391,7 +391,7 @@ void CClient::newGame( CConnection *con, StartInfo *si ) else { serv = con; - networkMode = (con->connectionID == 1) ? HOST : GUEST; + networkMode = con->isHost() ? HOST : GUEST; } CConnection &c = *serv; @@ -693,7 +693,7 @@ void CClient::stopConnection() { terminate = true; - if (serv) //request closing connection + if (serv && serv->isHost()) //request closing connection { logNetwork->infoStream() << "Connection has been requested to be closed."; boost::unique_lock(*serv->wmx); @@ -1075,6 +1075,7 @@ CConnection * CServerHandler::justConnectToServer(const std::string &host, const ret = new CConnection( host.size() ? host : settings["server"]["server"].String(), realPort, NAME); + ret->connectionID = 1; // TODO: Refactoring for the server so IDs set outside of CConnection } catch(...) { diff --git a/lib/serializer/Connection.cpp b/lib/serializer/Connection.cpp index 6a664edc8..6cc13643b 100644 --- a/lib/serializer/Connection.cpp +++ b/lib/serializer/Connection.cpp @@ -201,6 +201,11 @@ bool CConnection::isOpen() const return socket && connected; } +bool CConnection::isHost() const +{ + return connectionID == 1; +} + void CConnection::reportState(CLogger * out) { out->debugStream() << "CConnection"; diff --git a/lib/serializer/Connection.h b/lib/serializer/Connection.h index de53215e2..2402d4db3 100644 --- a/lib/serializer/Connection.h +++ b/lib/serializer/Connection.h @@ -74,6 +74,7 @@ public: void close(); bool isOpen() const; + bool isHost() const; template CConnection &operator&(const T&); virtual ~CConnection(void); diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 8b190f338..d14538573 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1097,7 +1097,7 @@ void CGameHandler::handleConnection(std::set players, CConnection & { assert(!c.connected); //make sure that connection has been marked as broken logGlobal->error(e.what()); - end2 = true; + conns -= &c; } catch(...) { @@ -2631,6 +2631,9 @@ void CGameHandler::sendToAllClients(CPackForClient * info) logNetwork->trace("Sending to all clients a package of type %s", typeid(*info).name()); for (auto & elem : conns) { + if(!elem->isOpen()) + continue; + boost::unique_lock lock(*(elem)->wmx); *elem << info; } @@ -2703,6 +2706,7 @@ void CGameHandler::close() { exit(0); } + end2 = true; //for (CConnection *cc : conns) // if (cc && cc->socket && cc->socket->is_open())