Bläddra i källkod

Implemented connecting to server via proxy

Ivan Savenko 1 år sedan
förälder
incheckning
c5c46a7c9a

+ 13 - 4
client/CServerHandler.cpp

@@ -139,6 +139,7 @@ CServerHandler::CServerHandler()
 	, state(EClientState::NONE)
 	, campaignStateToSend(nullptr)
 	, screenType(ESelectionScreen::unknown)
+	, serverMode(EServerMode::NONE)
 	, loadMode(ELoadMode::NONE)
 	, client(nullptr)
 	, campaignServerRestartLock(false)
@@ -156,10 +157,11 @@ void CServerHandler::threadRunNetwork()
 	logGlobal->info("Ending network thread");
 }
 
-void CServerHandler::resetStateForLobby(EStartMode mode, ESelectionScreen screen, const std::vector<std::string> & names)
+void CServerHandler::resetStateForLobby(EStartMode mode, ESelectionScreen screen, EServerMode newServerMode, const std::vector<std::string> & names)
 {
 	hostClientId = -1;
 	state = EClientState::NONE;
+	serverMode = newServerMode;
 	mapToStart = nullptr;
 	th = std::make_unique<CStopWatch>();
 	c.reset();
@@ -297,11 +299,18 @@ void CServerHandler::onTimer()
 	networkHandler->connectToRemote(*this, getLocalHostname(), getLocalPort());
 }
 
-void CServerHandler::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & netConnection)
+void CServerHandler::onConnectionEstablished(const NetworkConnectionPtr & netConnection)
 {
 	networkConnection = netConnection;
 
 	logNetwork->info("Connection established");
+
+	if (serverMode == EServerMode::LOBBY_GUEST)
+	{
+		// say hello to lobby to switch connection to proxy mode
+		getGlobalLobby().sendProxyConnectionLogin(netConnection);
+	}
+
 	c = std::make_shared<CConnection>(netConnection);
 	nextClient = std::make_unique<CClient>();
 	c->uuid = uuid;
@@ -791,12 +800,12 @@ void CServerHandler::debugStartTest(std::string filename, bool save)
 	auto mapInfo = std::make_shared<CMapInfo>();
 	if(save)
 	{
-		resetStateForLobby(EStartMode::LOAD_GAME, ESelectionScreen::loadGame, {});
+		resetStateForLobby(EStartMode::LOAD_GAME, ESelectionScreen::loadGame, EServerMode::LOCAL, {});
 		mapInfo->saveInit(ResourcePath(filename, EResType::SAVEGAME));
 	}
 	else
 	{
-		resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, {});
+		resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOCAL, {});
 		mapInfo->mapInit(filename);
 	}
 	if(settings["session"]["donotstartserver"].Bool())

+ 13 - 4
client/CServerHandler.h

@@ -57,6 +57,14 @@ enum class EClientState : ui8
 	CONNECTION_FAILED // We could not connect to server
 };
 
+enum class EServerMode : uint8_t
+{
+	NONE = 0,
+	LOCAL, // no global lobby
+	LOBBY_HOST, // We are hosting global server available via global lobby
+	LOBBY_GUEST // Connecting to a remote server via proxy provided by global lobby
+};
+
 class IServerAPI
 {
 protected:
@@ -106,10 +114,10 @@ class CServerHandler final : public IServerAPI, public LobbyInfo, public INetwor
 	void onServerFinished();
 	void sendLobbyPack(const CPackForLobby & pack) const override;
 
-	void onPacketReceived(const std::shared_ptr<INetworkConnection> &, const std::vector<uint8_t> & message) override;
+	void onPacketReceived(const NetworkConnectionPtr &, const std::vector<uint8_t> & message) override;
 	void onConnectionFailed(const std::string & errorMessage) override;
-	void onConnectionEstablished(const std::shared_ptr<INetworkConnection> &) override;
-	void onDisconnected(const std::shared_ptr<INetworkConnection> &) override;
+	void onConnectionEstablished(const NetworkConnectionPtr &) override;
+	void onDisconnected(const NetworkConnectionPtr &) override;
 	void onTimer() override;
 
 	void applyPackOnLobbyScreen(CPackForLobby & pack);
@@ -132,6 +140,7 @@ public:
 	std::shared_ptr<CampaignState> campaignStateToSend;
 
 	ESelectionScreen screenType; // To create lobby UI only after server is setup
+	EServerMode serverMode;
 	ELoadMode loadMode; // For saves filtering in SelectionTab
 	////////////////////
 
@@ -146,7 +155,7 @@ public:
 	CServerHandler();
 	~CServerHandler();
 	
-	void resetStateForLobby(EStartMode mode, ESelectionScreen screen, const std::vector<std::string> & names);
+	void resetStateForLobby(EStartMode mode, ESelectionScreen screen, EServerMode serverMode, const std::vector<std::string> & names);
 	void startLocalServerAndConnect(bool connectToLobby);
 	void connectToServer(const std::string & addr, const ui16 port);
 

+ 1 - 0
client/NetPacksLobbyClient.cpp

@@ -53,6 +53,7 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon
 
 			if (!GH.windows().findWindows<GlobalLobbyServerSetup>().empty())
 			{
+				assert(handler.serverMode == EServerMode::LOBBY_HOST);
 				// announce opened game room
 				// TODO: find better approach?
 				int roomType = settings["lobby"]["roomType"].Integer();

+ 32 - 1
client/globalLobby/GlobalLobbyClient.cpp

@@ -18,6 +18,7 @@
 #include "../gui/WindowHandler.h"
 #include "../windows/InfoWindows.h"
 #include "../CServerHandler.h"
+#include "../mainmenu/CMainMenu.h"
 
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/MetaString.h"
@@ -190,7 +191,18 @@ void GlobalLobbyClient::receiveActiveGameRooms(const JsonNode & json)
 
 void GlobalLobbyClient::receiveJoinRoomSuccess(const JsonNode & json)
 {
-	// TODO: store "gameRoomID" field and use it for future queries
+	Settings configRoom = settings.write["lobby"]["roomID"];
+	configRoom->String() = json["gameRoomID"].String();
+
+	if (json["proxyMode"].Bool())
+	{
+		CSH->resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOBBY_GUEST, {});
+		CSH->loadMode = ELoadMode::MULTI;
+
+		std::string hostname = settings["lobby"]["hostname"].String();
+		int16_t port = settings["lobby"]["port"].Integer();
+		CSH->connectToServer(hostname, port);
+	}
 }
 
 void GlobalLobbyClient::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & connection)
@@ -334,3 +346,22 @@ void GlobalLobbyClient::activateInterface()
 	else
 		GH.windows().pushWindow(createLoginWindow());
 }
+
+void GlobalLobbyClient::sendProxyConnectionLogin(const NetworkConnectionPtr & netConnection)
+{
+	JsonNode toSend;
+	toSend["type"].String() = "clientProxyLogin";
+	toSend["accountID"] = settings["lobby"]["accountID"];
+	toSend["accountCookie"] = settings["lobby"]["accountCookie"];
+	toSend["gameRoomID"] = settings["lobby"]["roomID"];
+
+	std::string payloadString = toSend.toJson(true);
+
+	// FIXME: find better approach
+	uint8_t * payloadBegin = reinterpret_cast<uint8_t *>(payloadString.data());
+	uint8_t * payloadEnd = payloadBegin + payloadString.size();
+
+	std::vector<uint8_t> payloadBuffer(payloadBegin, payloadEnd);
+
+	netConnection->sendPacket(payloadBuffer);
+}

+ 2 - 0
client/globalLobby/GlobalLobbyClient.h

@@ -63,6 +63,8 @@ public:
 	void sendOpenPublicRoom();
 	void sendOpenPrivateRoom();
 
+	void sendProxyConnectionLogin(const NetworkConnectionPtr & netConnection);
+
 	void connect();
 	bool isConnected();
 };

+ 2 - 2
client/globalLobby/GlobalLobbyServerSetup.cpp

@@ -125,9 +125,9 @@ void GlobalLobbyServerSetup::onGameModeChanged(int value)
 void GlobalLobbyServerSetup::onCreate()
 {
 	if(toggleGameMode->getSelected() == 0)
-		CSH->resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, {});
+		CSH->resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOBBY_HOST, {});
 	else
-		CSH->resetStateForLobby(EStartMode::LOAD_GAME, ESelectionScreen::loadGame, {});
+		CSH->resetStateForLobby(EStartMode::LOAD_GAME, ESelectionScreen::loadGame, EServerMode::LOBBY_HOST, {});
 
 	CSH->loadMode = ELoadMode::MULTI;
 	CSH->startLocalServerAndConnect(true);

+ 2 - 2
client/mainmenu/CMainMenu.cpp

@@ -361,7 +361,7 @@ void CMainMenu::update()
 
 void CMainMenu::openLobby(ESelectionScreen screenType, bool host, const std::vector<std::string> & names, ELoadMode loadMode)
 {
-	CSH->resetStateForLobby(screenType == ESelectionScreen::newGame ? EStartMode::NEW_GAME : EStartMode::LOAD_GAME, screenType, names);
+	CSH->resetStateForLobby(screenType == ESelectionScreen::newGame ? EStartMode::NEW_GAME : EStartMode::LOAD_GAME, screenType, EServerMode::LOCAL, names);
 	CSH->loadMode = loadMode;
 
 	GH.windows().createAndPushWindow<CSimpleJoinScreen>(host);
@@ -376,7 +376,7 @@ void CMainMenu::openCampaignLobby(const std::string & campaignFileName, std::str
 
 void CMainMenu::openCampaignLobby(std::shared_ptr<CampaignState> campaign)
 {
-	CSH->resetStateForLobby(EStartMode::CAMPAIGN, ESelectionScreen::campaignList, {});
+	CSH->resetStateForLobby(EStartMode::CAMPAIGN, ESelectionScreen::campaignList, EServerMode::LOCAL, {});
 	CSH->campaignStateToSend = campaign;
 	GH.windows().createAndPushWindow<CSimpleJoinScreen>();
 }

+ 5 - 8
config/schemas/settings.json

@@ -553,28 +553,24 @@
 			"type" : "object",
 			"additionalProperties" : false,
 			"default" : {},
-			"required" : [ "mapPreview", "accountID", "accountCookie", "displayName", "hostname", "port", "roomPlayerLimit", "roomType", "roomMode" ],
+			"required" : [ "mapPreview", "accountID", "accountCookie", "displayName", "hostname", "port", "roomPlayerLimit", "roomType", "roomMode", "roomID" ],
 			"properties" : {
 				"mapPreview" : {
 					"type" : "boolean",
 					"default" : true
 				},
-				
 				"accountID" : {
 					"type" : "string",
 					"default" : ""
 				},
-				
 				"accountCookie" : {
 					"type" : "string",
 					"default" : ""
 				},
-				
 				"displayName" : {
 					"type" : "string",
 					"default" : ""
 				},
-
 				"hostname" : {
 					"type" : "string",
 					"default" : "127.0.0.1"
@@ -583,21 +579,22 @@
 					"type" : "number",
 					"default" : 30303
 				},
-				
 				"roomPlayerLimit" : {
 					"type" : "number",
 					"default" : 2
 				},
-				
 				"roomType" : {
 					"type" : "number",
 					"default" : 0
 				},
-				
 				"roomMode" : {
 					"type" : "number",
 					"default" : 0
 				},
+				"roomID" : {
+					"type" : "string",
+					"default" : ""
+				}
 			}
 		},
 		"gameTweaks" : {

+ 7 - 2
lib/network/NetworkServer.cpp

@@ -53,15 +53,20 @@ void NetworkServer::sendPacket(const std::shared_ptr<INetworkConnection> & conne
 
 void NetworkServer::closeConnection(const std::shared_ptr<INetworkConnection> & connection)
 {
+	logNetwork->info("Closing connection!");
 	assert(connections.count(connection));
 	connections.erase(connection);
 }
 
 void NetworkServer::onDisconnected(const std::shared_ptr<INetworkConnection> & connection)
 {
+	logNetwork->info("Connection lost!");
 	assert(connections.count(connection));
-	connections.erase(connection);
-	listener.onDisconnected(connection);
+	if (connections.count(connection)) // how? Connection was explicitly closed before?
+	{
+		connections.erase(connection);
+		listener.onDisconnected(connection);
+	}
 }
 
 void NetworkServer::onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message)

+ 23 - 5
lobby/LobbyDatabase.cpp

@@ -155,6 +155,12 @@ void LobbyDatabase::prepareStatements()
 		LIMIT 1
 	)";
 
+	static const std::string getGameRoomStatusText = R"(
+		SELECT status
+		FROM gameRooms
+		WHERE roomID = ?
+	)";
+
 	static const std::string getAccountGameRoomText = R"(
 		SELECT grp.roomID
 		FROM gameRoomPlayers grp
@@ -209,14 +215,16 @@ void LobbyDatabase::prepareStatements()
 
 	static const std::string isPlayerInGameRoomText = R"(
 		SELECT COUNT(accountID)
-		FROM gameRoomPlayers
-		WHERE accountID = ? AND roomID = ?
+		FROM gameRoomPlayers grp
+		LEFT JOIN gameRooms gr ON gr.roomID = grp.roomID
+		WHERE accountID = ? AND grp.roomID = ? AND status IN (1, 2)
 	)";
 
 	static const std::string isPlayerInAnyGameRoomText = R"(
 		SELECT COUNT(accountID)
-		FROM gameRoomPlayers
-		WHERE accountID = ?
+		FROM gameRoomPlayers grp
+		LEFT JOIN gameRooms gr ON gr.roomID = grp.roomID
+		WHERE accountID = ? AND status IN (1, 2)
 	)";
 
 	static const std::string isAccountIDExistsText = R"(
@@ -247,6 +255,7 @@ void LobbyDatabase::prepareStatements()
 
 	getRecentMessageHistoryStatement = database->prepare(getRecentMessageHistoryText);
 	getIdleGameRoomStatement = database->prepare(getIdleGameRoomText);
+	getGameRoomStatusStatement = database->prepare(getGameRoomStatusText);
 	getAccountGameRoomStatement = database->prepare(getAccountGameRoomText);
 	getActiveAccountsStatement = database->prepare(getActiveAccountsText);
 	getActiveGameRoomsStatement = database->prepare(getActiveGameRoomsText);
@@ -406,7 +415,16 @@ LobbyInviteStatus LobbyDatabase::getAccountInviteStatus(const std::string & acco
 
 LobbyRoomState LobbyDatabase::getGameRoomStatus(const std::string & roomID)
 {
-	return {};
+	int result = -1;
+
+	getGameRoomStatusStatement->setBinds(roomID);
+	if(getGameRoomStatusStatement->execute())
+		getGameRoomStatusStatement->getColumns(result);
+	getGameRoomStatusStatement->reset();
+
+	if (result != -1)
+		return static_cast<LobbyRoomState>(result);
+	return LobbyRoomState::CLOSED;
 }
 
 uint32_t LobbyDatabase::getGameRoomFreeSlots(const std::string & roomID)

+ 1 - 0
lobby/LobbyDatabase.h

@@ -37,6 +37,7 @@ class LobbyDatabase
 
 	SQLiteStatementPtr getRecentMessageHistoryStatement;
 	SQLiteStatementPtr getIdleGameRoomStatement;
+	SQLiteStatementPtr getGameRoomStatusStatement;
 	SQLiteStatementPtr getActiveGameRoomsStatement;
 	SQLiteStatementPtr getActiveAccountsStatement;
 	SQLiteStatementPtr getAccountGameRoomStatement;

+ 25 - 12
lobby/LobbyServer.cpp

@@ -148,7 +148,7 @@ void LobbyServer::broadcastActiveAccounts()
 		sendMessage(connection.first, reply);
 }
 
-void LobbyServer::broadcastActiveGameRooms()
+JsonNode LobbyServer::prepareActiveGameRooms()
 {
 	auto activeGameRoomStats = database->getActiveGameRooms();
 	JsonNode reply;
@@ -167,6 +167,13 @@ void LobbyServer::broadcastActiveGameRooms()
 		reply["gameRooms"].Vector().push_back(jsonEntry);
 	}
 
+	return reply;
+}
+
+void LobbyServer::broadcastActiveGameRooms()
+{
+	auto reply = prepareActiveGameRooms();
+
 	for(const auto & connection : activeAccounts)
 		sendMessage(connection.first, reply);
 }
@@ -179,11 +186,12 @@ void LobbyServer::sendAccountJoinsRoom(const NetworkConnectionPtr & target, cons
 	sendMessage(target, reply);
 }
 
-void LobbyServer::sendJoinRoomSuccess(const NetworkConnectionPtr & target, const std::string & gameRoomID)
+void LobbyServer::sendJoinRoomSuccess(const NetworkConnectionPtr & target, const std::string & gameRoomID, bool proxyMode)
 {
 	JsonNode reply;
 	reply["type"].String() = "joinRoomSuccess";
 	reply["gameRoomID"].String() = gameRoomID;
+	reply["proxyMode"].Bool() = proxyMode;
 	sendMessage(target, reply);
 }
 
@@ -230,8 +238,9 @@ void LobbyServer::onPacketReceived(const NetworkConnectionPtr & connection, cons
 	{
 		auto lockedPtr = activeProxies.at(connection).lock();
 		if(lockedPtr)
-			lockedPtr->sendPacket(message);
-		return;
+			return lockedPtr->sendPacket(message);
+
+		throw std::runtime_error("Received unexpected message for inactive proxy!");
 	}
 
 	JsonNode json(message.data(), message.size());
@@ -257,7 +266,7 @@ void LobbyServer::onPacketReceived(const NetworkConnectionPtr & connection, cons
 		if(json["type"].String() == "declineInvite")
 			return receiveDeclineInvite(connection, json);
 
-		return;
+		throw std::runtime_error("Received unexpected message of type " + json["type"].String());
 	}
 
 	// communication messages from vcmiserver
@@ -266,7 +275,7 @@ void LobbyServer::onPacketReceived(const NetworkConnectionPtr & connection, cons
 		if(json["type"].String() == "leaveGameRoom")
 			return receiveLeaveGameRoom(connection, json);
 
-		return;
+		throw std::runtime_error("Received unexpected message of type " + json["type"].String());
 	}
 
 	// unauthorized connections - permit only login or register attempts
@@ -287,6 +296,8 @@ void LobbyServer::onPacketReceived(const NetworkConnectionPtr & connection, cons
 
 	// TODO: add logging of suspicious connections.
 	networkServer->closeConnection(connection);
+
+	throw std::runtime_error("Received unexpected message of type " + json["type"].String());
 }
 
 void LobbyServer::receiveSendChatMessage(const NetworkConnectionPtr & connection, const JsonNode & json)
@@ -358,6 +369,7 @@ void LobbyServer::receiveClientLogin(const NetworkConnectionPtr & connection, co
 	// send active accounts list to new account
 	// and update acount list to everybody else
 	broadcastActiveAccounts();
+	sendMessage(connection, prepareActiveGameRooms());
 }
 
 void LobbyServer::receiveServerLogin(const NetworkConnectionPtr & connection, const JsonNode & json)
@@ -420,18 +432,19 @@ void LobbyServer::receiveServerProxyLogin(const NetworkConnectionPtr & connectio
 {
 	std::string gameRoomID = json["gameRoomID"].String();
 	std::string guestAccountID = json["guestAccountID"].String();
-	std::string hostCookie = json["hostCookie"].String();
+	std::string accountCookie = json["accountCookie"].String();
 
-	auto clientCookieStatus = database->getGameRoomCookieStatus(gameRoomID, hostCookie, accountCookieLifetime);
+	// FIXME: find host account ID and validate his cookie
+	//auto clientCookieStatus = database->getAccountCookieStatus(hostAccountID, accountCookie, accountCookieLifetime);
 
-	if(clientCookieStatus != LobbyCookieStatus::INVALID)
+	//if(clientCookieStatus != LobbyCookieStatus::INVALID)
 	{
 		NetworkConnectionPtr targetAccount = findAccount(guestAccountID);
 
 		if(targetAccount == nullptr)
 			return; // unknown / disconnected account
 
-		sendJoinRoomSuccess(targetAccount, gameRoomID);
+		sendJoinRoomSuccess(targetAccount, gameRoomID, true);
 
 		AwaitingProxyState proxy;
 		proxy.accountID = guestAccountID;
@@ -441,7 +454,7 @@ void LobbyServer::receiveServerProxyLogin(const NetworkConnectionPtr & connectio
 		return;
 	}
 
-	networkServer->closeConnection(connection);
+	//networkServer->closeConnection(connection);
 }
 
 void LobbyServer::receiveOpenGameRoom(const NetworkConnectionPtr & connection, const JsonNode & json)
@@ -467,7 +480,7 @@ void LobbyServer::receiveOpenGameRoom(const NetworkConnectionPtr & connection, c
 
 	database->insertPlayerIntoGameRoom(accountID, gameRoomID);
 	broadcastActiveGameRooms();
-	sendJoinRoomSuccess(connection, gameRoomID);
+	sendJoinRoomSuccess(connection, gameRoomID, false);
 }
 
 void LobbyServer::receiveJoinGameRoom(const NetworkConnectionPtr & connection, const JsonNode & json)

+ 3 - 1
lobby/LobbyServer.h

@@ -70,13 +70,15 @@ class LobbyServer : public INetworkServerListener
 	void broadcastActiveAccounts();
 	void broadcastActiveGameRooms();
 
+	JsonNode prepareActiveGameRooms();
+
 	void sendChatMessage(const NetworkConnectionPtr & target, const std::string & roomMode, const std::string & roomName, const std::string & accountID, const std::string & displayName, const std::string & messageText);
 	void sendAccountCreated(const NetworkConnectionPtr & target, const std::string & accountID, const std::string & accountCookie);
 	void sendLoginFailed(const NetworkConnectionPtr & target, const std::string & reason);
 	void sendLoginSuccess(const NetworkConnectionPtr & target, const std::string & accountCookie, const std::string & displayName);
 	void sendChatHistory(const NetworkConnectionPtr & target, const std::vector<LobbyChatMessage> &);
 	void sendAccountJoinsRoom(const NetworkConnectionPtr & target, const std::string & accountID);
-	void sendJoinRoomSuccess(const NetworkConnectionPtr & target, const std::string & gameRoomID);
+	void sendJoinRoomSuccess(const NetworkConnectionPtr & target, const std::string & gameRoomID, bool proxyMode);
 	void sendInviteReceived(const NetworkConnectionPtr & target, const std::string & accountID, const std::string & gameRoomID);
 
 	void receiveClientRegister(const NetworkConnectionPtr & connection, const JsonNode & json);

+ 28 - 17
server/GlobalLobbyProcessor.cpp

@@ -34,29 +34,39 @@ void GlobalLobbyProcessor::onDisconnected(const std::shared_ptr<INetworkConnecti
 
 void GlobalLobbyProcessor::onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message)
 {
-	JsonNode json(message.data(), message.size());
+	if (connection == controlConnection)
+	{
+		JsonNode json(message.data(), message.size());
 
-	if(json["type"].String() == "loginFailed")
-		return receiveLoginFailed(json);
+		if(json["type"].String() == "loginFailed")
+			return receiveLoginFailed(json);
 
-	if(json["type"].String() == "loginSuccess")
-		return receiveLoginSuccess(json);
+		if(json["type"].String() == "loginSuccess")
+			return receiveLoginSuccess(json);
 
-	if(json["type"].String() == "accountJoinsRoom")
-		return receiveAccountJoinsRoom(json);
+		if(json["type"].String() == "accountJoinsRoom")
+			return receiveAccountJoinsRoom(json);
 
-	throw std::runtime_error("Received unexpected message from lobby server: " + json["type"].String());
+		throw std::runtime_error("Received unexpected message from lobby server: " + json["type"].String());
+	}
+	else
+	{
+		// received game message via proxy connection
+		owner.onPacketReceived(connection, message);
+	}
 }
 
 void GlobalLobbyProcessor::receiveLoginFailed(const JsonNode & json)
 {
+	logGlobal->info("Lobby: Failed to login into a lobby server!");
+
 	throw std::runtime_error("Failed to login into a lobby server!");
 }
 
 void GlobalLobbyProcessor::receiveLoginSuccess(const JsonNode & json)
 {
 	// no-op, wait just for any new commands from lobby
-	logGlobal->info("Succesfully connected to lobby server");
+	logGlobal->info("Lobby: Succesfully connected to lobby server");
 	owner.startAcceptingIncomingConnections();
 }
 
@@ -64,6 +74,7 @@ void GlobalLobbyProcessor::receiveAccountJoinsRoom(const JsonNode & json)
 {
 	std::string accountID = json["accountID"].String();
 
+	logGlobal->info("Lobby: Account %s will join our room!", accountID);
 	assert(proxyConnections.count(accountID) == 0);
 
 	proxyConnections[accountID] = nullptr;
@@ -87,29 +98,29 @@ void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr<INetwor
 		toSend["gameRoomID"].String() = owner.uuid;
 		toSend["accountID"] = settings["lobby"]["accountID"];
 		toSend["accountCookie"] = settings["lobby"]["accountCookie"];
-		sendMessage(toSend);
+		sendMessage(connection, toSend);
 	}
 	else
 	{
 		// Proxy connection for a player
-		std::string accountID;
+		std::string guestAccountID;
 		for (auto const & proxies : proxyConnections)
 			if (proxies.second == nullptr)
-				accountID = proxies.first;
+				guestAccountID = proxies.first;
 
 		JsonNode toSend;
 		toSend["type"].String() = "serverProxyLogin";
 		toSend["gameRoomID"].String() = owner.uuid;
-		toSend["accountID"].String() = accountID;
+		toSend["guestAccountID"].String() = guestAccountID;
 		toSend["accountCookie"] = settings["lobby"]["accountCookie"];
-		sendMessage(toSend);
+		sendMessage(connection, toSend);
 
-		proxyConnections[accountID] = connection;
+		proxyConnections[guestAccountID] = connection;
 		owner.onNewConnection(connection);
 	}
 }
 
-void GlobalLobbyProcessor::sendMessage(const JsonNode & data)
+void GlobalLobbyProcessor::sendMessage(const NetworkConnectionPtr & target, const JsonNode & data)
 {
 	std::string payloadString = data.toJson(true);
 
@@ -119,5 +130,5 @@ void GlobalLobbyProcessor::sendMessage(const JsonNode & data)
 
 	std::vector<uint8_t> payloadBuffer(payloadBegin, payloadEnd);
 
-	controlConnection->sendPacket(payloadBuffer);
+	target->sendPacket(payloadBuffer);
 }

+ 3 - 3
server/GlobalLobbyProcessor.h

@@ -21,15 +21,15 @@ class GlobalLobbyProcessor : public INetworkClientListener
 {
 	CVCMIServer & owner;
 
-	std::shared_ptr<INetworkConnection> controlConnection;
-	std::map<std::string, std::shared_ptr<INetworkConnection>> proxyConnections;
+	NetworkConnectionPtr controlConnection;
+	std::map<std::string, NetworkConnectionPtr> proxyConnections;
 
 	void onDisconnected(const std::shared_ptr<INetworkConnection> & connection) override;
 	void onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message) override;
 	void onConnectionFailed(const std::string & errorMessage) override;
 	void onConnectionEstablished(const std::shared_ptr<INetworkConnection> &) override;
 
-	void sendMessage(const JsonNode & data);
+	void sendMessage(const NetworkConnectionPtr & target, const JsonNode & data);
 
 	void receiveLoginFailed(const JsonNode & json);
 	void receiveLoginSuccess(const JsonNode & json);