Browse Source

Client-side update, adapted and fixed login and chat

Ivan Savenko 1 year ago
parent
commit
47f72af556

+ 119 - 34
client/globalLobby/GlobalLobbyClient.cpp

@@ -20,6 +20,7 @@
 
 #include "../../lib/MetaString.h"
 #include "../../lib/CConfigHandler.h"
+#include "../../lib/TextOperations.h"
 #include "../../lib/network/NetworkClient.h"
 
 GlobalLobbyClient::~GlobalLobbyClient()
@@ -42,15 +43,7 @@ static std::string getCurrentTimeFormatted(int timeOffsetSeconds = 0)
 	auto timeNowChrono = std::chrono::system_clock::now();
 	timeNowChrono += std::chrono::seconds(timeOffsetSeconds);
 
-	std::time_t timeNowC = std::chrono::system_clock::to_time_t(timeNowChrono);
-	std::tm timeNowTm = *std::localtime(&timeNowC);
-
-	MetaString timeFormatted;
-	timeFormatted.appendRawString("%d:%d");
-	timeFormatted.replaceNumber(timeNowTm.tm_hour);
-	timeFormatted.replaceNumber(timeNowTm.tm_min);
-
-	return timeFormatted.toString();
+	return TextOperations::getFormattedTimeLocal(std::chrono::system_clock::to_time_t(timeNowChrono));
 }
 
 void GlobalLobbyClient::onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message)
@@ -59,48 +52,138 @@ void GlobalLobbyClient::onPacketReceived(const std::shared_ptr<NetworkConnection
 
 	JsonNode json(message.data(), message.size());
 
-	if (json["type"].String() == "authentication")
+	if (json["type"].String() == "accountCreated")
+		return receiveAccountCreated(json);
+
+	if (json["type"].String() == "loginFailed")
+		return receiveLoginFailed(json);
+
+	if (json["type"].String() == "loginSuccess")
+		return receiveLoginSuccess(json);
+
+	if (json["type"].String() == "chatHistory")
+		return receiveChatHistory(json);
+
+	if (json["type"].String() == "chatMessage")
+		return receiveChatMessage(json);
+
+	if (json["type"].String() == "activeAccounts")
+		return receiveActiveAccounts(json);
+
+	throw std::runtime_error("Received unexpected message from lobby server: " + json["type"].String() );
+}
+
+void GlobalLobbyClient::receiveAccountCreated(const JsonNode & json)
+{
+	auto loginWindowPtr = loginWindow.lock();
+
+	if (!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
+		throw std::runtime_error("lobby connection finished without active login window!");
+
 	{
-		auto loginWindowPtr = loginWindow.lock();
+		Settings configID = settings.write["lobby"]["accountID"];
+		configID->String() = json["accountID"].String();
 
-		if (!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
-			throw std::runtime_error("lobby connection finished without active login window!");
+		Settings configName = settings.write["lobby"]["displayName"];
+		configName->String() = json["displayName"].String();
 
-		loginWindowPtr->onConnectionSuccess();
+		Settings configCookie = settings.write["lobby"]["accountCookie"];
+		configCookie->String() = json["accountCookie"].String();
 	}
 
-	if (json["type"].String() == "chatHistory")
+	sendClientLogin();
+}
+
+void GlobalLobbyClient::receiveLoginFailed(const JsonNode & json)
+{
+	auto loginWindowPtr = loginWindow.lock();
+
+	if (!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
+		throw std::runtime_error("lobby connection finished without active login window!");
+
+	loginWindowPtr->onConnectionFailed(json["reason"].String());
+}
+
+void GlobalLobbyClient::receiveLoginSuccess(const JsonNode & json)
+{
 	{
-		for (auto const & entry : json["messages"].Vector())
-		{
-			std::string senderName = entry["senderName"].String();
-			std::string messageText = entry["messageText"].String();
-			int ageSeconds = entry["ageSeconds"].Integer();
-			std::string timeFormatted = getCurrentTimeFormatted(-ageSeconds);
-
-			auto lobbyWindowPtr = lobbyWindow.lock();
-			if(lobbyWindowPtr)
-				lobbyWindowPtr->onGameChatMessage(senderName, messageText, timeFormatted);
-		}
+		Settings configCookie = settings.write["lobby"]["accountCookie"];
+		configCookie->String() = json["accountCookie"].String();
+
+		Settings configName = settings.write["lobby"]["displayName"];
+		configName->String() = json["displayName"].String();
 	}
 
-	if (json["type"].String() == "chatMessage")
+	auto loginWindowPtr = loginWindow.lock();
+
+	if (!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
+		throw std::runtime_error("lobby connection finished without active login window!");
+
+	loginWindowPtr->onConnectionSuccess();
+}
+
+void GlobalLobbyClient::receiveChatHistory(const JsonNode & json)
+{
+	for (auto const & entry : json["messages"].Vector())
 	{
-		std::string senderName = json["senderName"].String();
-		std::string messageText = json["messageText"].String();
-		std::string timeFormatted = getCurrentTimeFormatted();
+		std::string accountID = entry["accountID"].String();
+		std::string displayName = entry["displayName"].String();
+		std::string messageText = entry["messageText"].String();
+		int ageSeconds = entry["ageSeconds"].Integer();
+		std::string timeFormatted = getCurrentTimeFormatted(-ageSeconds);
+
 		auto lobbyWindowPtr = lobbyWindow.lock();
 		if(lobbyWindowPtr)
-			lobbyWindowPtr->onGameChatMessage(senderName, messageText, timeFormatted);
+			lobbyWindowPtr->onGameChatMessage(displayName, messageText, timeFormatted);
 	}
 }
 
+void GlobalLobbyClient::receiveChatMessage(const JsonNode & json)
+{
+	std::string accountID = json["accountID"].String();
+	std::string displayName = json["displayName"].String();
+	std::string messageText = json["messageText"].String();
+	std::string timeFormatted = getCurrentTimeFormatted();
+	auto lobbyWindowPtr = lobbyWindow.lock();
+	if(lobbyWindowPtr)
+		lobbyWindowPtr->onGameChatMessage(displayName, messageText, timeFormatted);
+}
+
+void GlobalLobbyClient::receiveActiveAccounts(const JsonNode & json)
+{
+	//for (auto const & jsonEntry : json["messages"].Vector())
+	//{
+	//	std::string accountID = jsonEntry["accountID"].String();
+	//	std::string displayName = jsonEntry["displayName"].String();
+	//}
+}
+
 void GlobalLobbyClient::onConnectionEstablished(const std::shared_ptr<NetworkConnection> &)
 {
 	JsonNode toSend;
-	toSend["type"].String() = "authentication";
-	toSend["accountName"].String() = settings["general"]["playerName"].String();
 
+	std::string accountID = settings["lobby"]["accountID"].String();
+
+	if (accountID.empty())
+		sendClientRegister();
+	else
+		sendClientLogin();
+}
+
+void GlobalLobbyClient::sendClientRegister()
+{
+	JsonNode toSend;
+	toSend["type"].String() = "clientRegister";
+	toSend["displayName"] = settings["lobby"]["displayName"];
+	sendMessage(toSend);
+}
+
+void GlobalLobbyClient::sendClientLogin()
+{
+	JsonNode toSend;
+	toSend["type"].String() = "clientLogin";
+	toSend["accountID"] = settings["lobby"]["accountID"];
+	toSend["accountCookie"] = settings["lobby"]["accountCookie"];
 	sendMessage(toSend);
 }
 
@@ -141,7 +224,9 @@ void GlobalLobbyClient::sendMessage(const JsonNode & data)
 
 void GlobalLobbyClient::connect()
 {
-	networkClient->start("127.0.0.1", 30303);
+	std::string hostname = settings["lobby"]["hostname"].String();
+	int16_t port = settings["lobby"]["port"].Integer();
+	networkClient->start(hostname, port);
 }
 
 bool GlobalLobbyClient::isConnected()

+ 9 - 0
client/globalLobby/GlobalLobbyClient.h

@@ -33,6 +33,15 @@ class GlobalLobbyClient : public INetworkClientListener, boost::noncopyable
 	void onDisconnected(const std::shared_ptr<NetworkConnection> &) override;
 	void onTimer() override;
 
+	void sendClientRegister();
+	void sendClientLogin();
+
+	void receiveAccountCreated(const JsonNode & json);
+	void receiveLoginFailed(const JsonNode & json);
+	void receiveLoginSuccess(const JsonNode & json);
+	void receiveChatHistory(const JsonNode & json);
+	void receiveChatMessage(const JsonNode & json);
+	void receiveActiveAccounts(const JsonNode & json);
 public:
 	explicit GlobalLobbyClient();
 	~GlobalLobbyClient();

+ 12 - 1
client/globalLobby/GlobalLobbyLoginWindow.cpp

@@ -25,6 +25,7 @@
 
 #include "../../lib/CGeneralTextHandler.h"
 #include "../../lib/MetaString.h"
+#include "../../lib/CConfigHandler.h"
 
 GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
 	: CWindowObject(BORDERED)
@@ -41,9 +42,14 @@ GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
 	inputUsername = std::make_shared<CTextInput>(Rect(15, 73, 176, 16), FONT_SMALL, nullptr, ETextAlignment::TOPLEFT, true);
 	buttonLogin = std::make_shared<CButton>(Point(10, 160), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this](){ onLogin(); });
 	buttonClose = std::make_shared<CButton>(Point(126, 160), AnimationPath::builtin("MuBcanc"), CButton::tooltip(), [this](){ onClose(); });
-	labelStatus = std::make_shared<CTextBox>( "", Rect(15, 95, 175, 60), 1, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE);
+	labelStatus = std::make_shared<CTextBox>( "", Rect(15, 95, 175, 60), 1, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE);
 
 	background->playerColored(PlayerColor(1));
+	inputUsername->setText(settings["lobby"]["displayName"].String());
+	inputUsername->cb += [this](const std::string & text)
+	{
+		buttonLogin->block(text.empty());
+	};
 
 	center();
 }
@@ -56,8 +62,12 @@ void GlobalLobbyLoginWindow::onClose()
 
 void GlobalLobbyLoginWindow::onLogin()
 {
+	Settings config = settings.write["lobby"]["displayName"];
+	config->String() = inputUsername->getText();
+
 	labelStatus->setText(CGI->generaltexth->translate("vcmi.lobby.login.connecting"));
 	CSH->getGlobalLobby().connect();
+	buttonClose->block(true);
 }
 
 void GlobalLobbyLoginWindow::onConnectionSuccess()
@@ -73,4 +83,5 @@ void GlobalLobbyLoginWindow::onConnectionFailed(const std::string & reason)
 	formatter.replaceRawString(reason);
 
 	labelStatus->setText(formatter.toString());
+	buttonClose->block(false);
 }

+ 1 - 1
client/globalLobby/GlobalLobbyWindow.cpp

@@ -29,7 +29,7 @@ GlobalLobbyWindow::GlobalLobbyWindow():
 	pos = widget->pos;
 	center();
 
-	widget->getAccountNameLabel()->setText(settings["general"]["playerName"].String());
+	widget->getAccountNameLabel()->setText(settings["lobby"]["displayName"].String());
 }
 
 void GlobalLobbyWindow::doSendChatMessage()

+ 26 - 2
config/schemas/settings.json

@@ -553,12 +553,36 @@
 			"type" : "object",
 			"additionalProperties" : false,
 			"default" : {},
-			"required" : [ "mapPreview" ],
+			"required" : [ "mapPreview", "accountID", "accountCookie", "displayName", "hostname", "port" ],
 			"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"
+				},
+				"port" : {
+					"type" : "number",
+					"default" : 30303
+				},
 			}
 		},
 		"gameTweaks" : {

+ 6 - 0
lib/TextOperations.cpp

@@ -219,4 +219,10 @@ std::string TextOperations::getFormattedDateTimeLocal(std::time_t dt)
 	return vstd::getFormattedDateTime(dt, Languages::getLanguageOptions(settings["general"]["language"].String()).dateTimeFormat);
 }
 
+std::string TextOperations::getFormattedTimeLocal(std::time_t dt)
+{
+	return vstd::getFormattedDateTime(dt, "%H:%M");
+}
+
+
 VCMI_LIB_NAMESPACE_END

+ 3 - 0
lib/TextOperations.h

@@ -59,6 +59,9 @@ namespace TextOperations
 
 	/// get formatted DateTime depending on the language selected
 	DLL_LINKAGE std::string getFormattedDateTimeLocal(std::time_t dt);
+
+	/// get formatted time (without date)
+	DLL_LINKAGE std::string getFormattedTimeLocal(std::time_t dt);
 };
 
 

+ 60 - 19
lobby/LobbyDatabase.cpp

@@ -49,7 +49,7 @@ void LobbyDatabase::createTables()
 			accountID TEXT,
 			displayName TEXT,
 			online INTEGER NOT NULL,
-			lastLoginTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
+			lastLoginTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
 			creationTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
 		);
 	)";
@@ -110,11 +110,11 @@ void LobbyDatabase::prepareStatements()
 	// DELETE FROM
 
 	static const std::string deleteGameRoomPlayersText = R"(
-		 DELETE FROM gameRoomPlayers WHERE gameRoomID = ? AND accountID = ?
+		 DELETE FROM gameRoomPlayers WHERE roomID = ? AND accountID = ?
 	)";
 
 	static const std::string deleteGameRoomInvitesText = R"(
-		DELETE FROM gameRoomInvites WHERE gameRoomID = ? AND accountID = ?
+		DELETE FROM gameRoomInvites WHERE roomID = ? AND accountID = ?
 	)";
 
 	// UPDATE
@@ -134,10 +134,11 @@ void LobbyDatabase::prepareStatements()
 	// SELECT FROM
 
 	static const std::string getRecentMessageHistoryText = R"(
-		SELECT senderName, messageText, strftime('%s',CURRENT_TIMESTAMP)- strftime('%s',creationTime)  AS secondsElapsed
-		FROM chatMessages
+		SELECT senderName, displayName, messageText, strftime('%s',CURRENT_TIMESTAMP)- strftime('%s',cm.creationTime)  AS secondsElapsed
+		FROM chatMessages cm
+		LEFT JOIN accounts on accountID = senderName
 		WHERE secondsElapsed < 60*60*18
-		ORDER BY creationTime DESC
+		ORDER BY cm.creationTime DESC
 		LIMIT 100
 	)";
 
@@ -149,7 +150,7 @@ void LobbyDatabase::prepareStatements()
 	)";
 
 	static const std::string getAccountGameRoomText = R"(
-		SELECT roomID
+		SELECT grp.roomID
 		FROM gameRoomPlayers grp
 		LEFT JOIN gameRooms gr ON gr.roomID = grp.roomID
 		WHERE accountID = ? AND status IN ('public', 'private', 'busy')
@@ -159,7 +160,13 @@ void LobbyDatabase::prepareStatements()
 	static const std::string getActiveAccountsText = R"(
 		SELECT accountID, displayName
 		FROM accounts
-		WHERE online <> 1
+		WHERE online = 1
+	)";
+
+	static const std::string getAccountDisplayNameText = R"(
+		SELECT displayName
+		FROM accounts
+		WHERE accountID = ?
 	)";
 
 	static const std::string isAccountCookieValidText = R"(
@@ -187,12 +194,18 @@ void LobbyDatabase::prepareStatements()
 		WHERE accountID = ?
 	)";
 
-	static const std::string isAccountExistsText = R"(
+	static const std::string isAccountIDExistsText = R"(
 		SELECT COUNT(accountID)
 		FROM accounts
 		WHERE accountID = ?
 	)";
 
+	static const std::string isAccountNameExistsText = R"(
+		SELECT COUNT(displayName)
+		FROM accounts
+		WHERE displayName = ?
+	)";
+
 	insertChatMessageStatement = database->prepare(insertChatMessageText);
 	insertAccountStatement = database->prepare(insertAccountText);
 	insertAccessCookieStatement = database->prepare(insertAccessCookieText);
@@ -210,11 +223,13 @@ void LobbyDatabase::prepareStatements()
 	getIdleGameRoomStatement = database->prepare(getIdleGameRoomText);
 	getAccountGameRoomStatement = database->prepare(getAccountGameRoomText);
 	getActiveAccountsStatement = database->prepare(getActiveAccountsText);
+	getAccountDisplayNameStatement = database->prepare(getAccountDisplayNameText);
 
 	isAccountCookieValidStatement = database->prepare(isAccountCookieValidText);
 	isPlayerInGameRoomStatement = database->prepare(isPlayerInGameRoomText);
 	isPlayerInAnyGameRoomStatement = database->prepare(isPlayerInAnyGameRoomText);
-	isAccountExistsStatement = database->prepare(isAccountExistsText);
+	isAccountIDExistsStatement = database->prepare(isAccountIDExistsText);
+	isAccountNameExistsStatement = database->prepare(isAccountNameExistsText);
 }
 
 LobbyDatabase::~LobbyDatabase() = default;
@@ -262,7 +277,7 @@ std::vector<LobbyChatMessage> LobbyDatabase::getRecentMessageHistory()
 	while(getRecentMessageHistoryStatement->execute())
 	{
 		LobbyChatMessage message;
-		getRecentMessageHistoryStatement->getColumns(message.sender, message.messageText, message.age);
+		getRecentMessageHistoryStatement->getColumns(message.accountID, message.displayName, message.messageText, message.age);
 		result.push_back(message);
 	}
 	getRecentMessageHistoryStatement->reset();
@@ -332,7 +347,14 @@ void LobbyDatabase::updateActiveAccount(const std::string & accountID, bool isAc
 
 std::string LobbyDatabase::getAccountDisplayName(const std::string & accountID)
 {
-	return {};
+	std::string result;
+
+	getAccountDisplayNameStatement->setBinds(accountID);
+	if (getAccountDisplayNameStatement->execute())
+		getAccountDisplayNameStatement->getColumns(result);
+	getAccountDisplayNameStatement->reset();
+
+	return result;
 }
 
 LobbyCookieStatus LobbyDatabase::getGameRoomCookieStatus(const std::string & accountID, const std::string & accessCookieUUID, std::chrono::seconds cookieLifetime)
@@ -342,12 +364,14 @@ LobbyCookieStatus LobbyDatabase::getGameRoomCookieStatus(const std::string & acc
 
 LobbyCookieStatus LobbyDatabase::getAccountCookieStatus(const std::string & accountID, const std::string & accessCookieUUID, std::chrono::seconds cookieLifetime)
 {
-	return {};
-}
+	bool result = false;
 
-LobbyCookieStatus LobbyDatabase::getAccountCookieStatus(const std::string & accountID, std::chrono::seconds cookieLifetime)
-{
-	return {};
+	isAccountCookieValidStatement->setBinds(accountID, accessCookieUUID, cookieLifetime.count());
+	if (isAccountCookieValidStatement->execute())
+		isAccountCookieValidStatement->getColumns(result);
+	isAccountCookieValidStatement->reset();
+
+	return result ? LobbyCookieStatus::VALID : LobbyCookieStatus::INVALID;
 }
 
 LobbyInviteStatus LobbyDatabase::getAccountInviteStatus(const std::string & accountID, const std::string & roomID)
@@ -365,9 +389,26 @@ uint32_t LobbyDatabase::getGameRoomFreeSlots(const std::string & roomID)
 	return 0;
 }
 
-bool LobbyDatabase::isAccountExists(const std::string & accountID)
+bool LobbyDatabase::isAccountNameExists(const std::string & displayName)
+{
+	bool result = false;
+
+	isAccountNameExistsStatement->setBinds(displayName);
+	if (isAccountNameExistsStatement->execute())
+		isAccountNameExistsStatement->getColumns(result);
+	isAccountNameExistsStatement->reset();
+	return result;
+}
+
+bool LobbyDatabase::isAccountIDExists(const std::string & accountID)
 {
-	return false;
+	bool result = false;
+
+	isAccountIDExistsStatement->setBinds(accountID);
+	if (isAccountIDExistsStatement->execute())
+		isAccountIDExistsStatement->getColumns(result);
+	isAccountIDExistsStatement->reset();
+	return result;
 }
 
 std::vector<LobbyGameRoom> LobbyDatabase::getActiveGameRooms()

+ 5 - 3
lobby/LobbyDatabase.h

@@ -38,12 +38,14 @@ class LobbyDatabase
 	SQLiteStatementPtr getIdleGameRoomStatement;
 	SQLiteStatementPtr getAccountGameRoomStatement;
 	SQLiteStatementPtr getActiveAccountsStatement;
+	SQLiteStatementPtr getAccountDisplayNameStatement;
 
 	SQLiteStatementPtr isAccountCookieValidStatement;
 	SQLiteStatementPtr isGameRoomCookieValidStatement;
 	SQLiteStatementPtr isPlayerInGameRoomStatement;
 	SQLiteStatementPtr isPlayerInAnyGameRoomStatement;
-	SQLiteStatementPtr isAccountExistsStatement;
+	SQLiteStatementPtr isAccountIDExistsStatement;
+	SQLiteStatementPtr isAccountNameExistsStatement;
 
 	void prepareStatements();
 	void createTables();
@@ -81,12 +83,12 @@ public:
 
 	LobbyCookieStatus getGameRoomCookieStatus(const std::string & accountID, const std::string & accessCookieUUID, std::chrono::seconds cookieLifetime);
 	LobbyCookieStatus getAccountCookieStatus(const std::string & accountID, const std::string & accessCookieUUID, std::chrono::seconds cookieLifetime);
-	LobbyCookieStatus getAccountCookieStatus(const std::string & accountID, std::chrono::seconds cookieLifetime);
 	LobbyInviteStatus getAccountInviteStatus(const std::string & accountID, const std::string & roomID);
 	LobbyRoomState getGameRoomStatus(const std::string & roomID);
 	uint32_t getGameRoomFreeSlots(const std::string & roomID);
 
 	bool isPlayerInGameRoom(const std::string & accountID);
 	bool isPlayerInGameRoom(const std::string & accountID, const std::string & roomID);
-	bool isAccountExists(const std::string & accountID);
+	bool isAccountNameExists(const std::string & displayName);
+	bool isAccountIDExists(const std::string & accountID);
 };

+ 2 - 1
lobby/LobbyDefines.h

@@ -26,7 +26,8 @@ struct LobbyGameRoom
 
 struct LobbyChatMessage
 {
-	std::string sender;
+	std::string accountID;
+	std::string displayName;
 	std::string messageText;
 	std::chrono::seconds age;
 };

+ 20 - 15
lobby/LobbyServer.cpp

@@ -100,11 +100,13 @@ void LobbyServer::sendLoginFailed(const NetworkConnectionPtr & target, const std
 	sendMessage(target, reply);
 }
 
-void LobbyServer::sendLoginSuccess(const NetworkConnectionPtr & target, const std::string & accountCookie)
+void LobbyServer::sendLoginSuccess(const NetworkConnectionPtr & target, const std::string & accountCookie, const std::string & displayName)
 {
 	JsonNode reply;
 	reply["type"].String() = "loginSuccess";
 	reply["accountCookie"].String() = accountCookie;
+	if (!displayName.empty())
+		reply["displayName"].String() = displayName;
 	sendMessage(target, reply);
 }
 
@@ -117,8 +119,9 @@ void LobbyServer::sendChatHistory(const NetworkConnectionPtr & target, const std
 	{
 		JsonNode jsonEntry;
 
+		jsonEntry["accountID"].String() = message.accountID;
+		jsonEntry["displayName"].String() = message.displayName;
 		jsonEntry["messageText"].String() = message.messageText;
-		jsonEntry["senderName"].String() = message.sender;
 		jsonEntry["ageSeconds"].Integer() = message.age.count();
 
 		reply["messages"].Vector().push_back(jsonEntry);
@@ -183,12 +186,13 @@ void LobbyServer::sendJoinRoomSuccess(const NetworkConnectionPtr & target, const
 	sendMessage(target, reply);
 }
 
-void LobbyServer::sendChatMessage(const NetworkConnectionPtr & target, const std::string & roomMode, const std::string & roomName, const std::string & senderName, const std::string & messageText)
+void LobbyServer::sendChatMessage(const NetworkConnectionPtr & target, const std::string & roomMode, const std::string & roomName, const std::string & accountID, std::string & displayName, const std::string & messageText)
 {
 	JsonNode reply;
 	reply["type"].String() = "chatMessage";
 	reply["messageText"].String() = messageText;
-	reply["senderName"].String() = senderName;
+	reply["accountID"].String() = accountID;
+	reply["displayName"].String() = displayName;
 	reply["roomMode"].String() = roomMode;
 	reply["roomName"].String() = roomName;
 
@@ -285,32 +289,33 @@ void LobbyServer::onPacketReceived(const NetworkConnectionPtr & connection, cons
 
 void LobbyServer::receiveSendChatMessage(const NetworkConnectionPtr & connection, const JsonNode & json)
 {
-	std::string senderName = activeAccounts[connection].accountID;
+	std::string accountID = activeAccounts[connection].accountID;
 	std::string messageText = json["messageText"].String();
 	std::string messageTextClean = sanitizeChatMessage(messageText);
+	std::string displayName = database->getAccountDisplayName(accountID);
 
 	if (messageTextClean.empty())
 		return;
 
-	database->insertChatMessage(senderName, "global", "english", messageText);
+	database->insertChatMessage(accountID, "global", "english", messageText);
 
 	for(const auto & connection : activeAccounts)
-		sendChatMessage(connection.first, "global", "english", senderName, messageText);
+		sendChatMessage(connection.first, "global", "english", accountID, displayName, messageText);
 }
 
 void LobbyServer::receiveClientRegister(const NetworkConnectionPtr & connection, const JsonNode & json)
 {
-	std::string accountID = json["accountID"].String();
 	std::string displayName = json["displayName"].String();
 	std::string language = json["language"].String();
 
-	if (database->isAccountExists(accountID))
-		return sendLoginFailed(connection, "Account name already in use");
-
-	if (isAccountNameValid(accountID))
+	if (isAccountNameValid(displayName))
 		return sendLoginFailed(connection, "Illegal account name");
 
+	if (database->isAccountNameExists(displayName))
+		return sendLoginFailed(connection, "Account name already in use");
+
 	std::string accountCookie = boost::uuids::to_string(boost::uuids::random_generator()());
+	std::string accountID = boost::uuids::to_string(boost::uuids::random_generator()());
 
 	database->insertAccount(accountID, displayName);
 	database->insertAccessCookie(accountID, accountCookie);
@@ -325,7 +330,7 @@ void LobbyServer::receiveClientLogin(const NetworkConnectionPtr & connection, co
 	std::string language = json["language"].String();
 	std::string version = json["version"].String();
 
-	if (!database->isAccountExists(accountID))
+	if (!database->isAccountIDExists(accountID))
 		return sendLoginFailed(connection, "Account not found");
 
 	auto clientCookieStatus = database->getAccountCookieStatus(accountID, accountCookie, accountCookieLifetime);
@@ -344,7 +349,7 @@ void LobbyServer::receiveClientLogin(const NetworkConnectionPtr & connection, co
 	activeAccounts[connection].version = version;
 	activeAccounts[connection].language = language;
 
-	sendLoginSuccess(connection, accountCookie);
+	sendLoginSuccess(connection, accountCookie, displayName);
 	sendChatHistory(connection, database->getRecentMessageHistory());
 
 	// send active accounts list to new account
@@ -369,7 +374,7 @@ void LobbyServer::receiveServerLogin(const NetworkConnectionPtr & connection, co
 	{
 		database->insertGameRoom(gameRoomID, accountID);
 		activeGameRooms[connection].roomID = gameRoomID;
-		sendLoginSuccess(connection, accountCookie);
+		sendLoginSuccess(connection, accountCookie, {});
 	}
 }
 

+ 2 - 2
lobby/LobbyServer.h

@@ -70,10 +70,10 @@ class LobbyServer : public INetworkServerListener
 	void broadcastActiveAccounts();
 	void broadcastActiveGameRooms();
 
-	void sendChatMessage(const NetworkConnectionPtr & target, const std::string & roomMode, const std::string & roomName, const std::string & senderName, const std::string & messageText);
+	void sendChatMessage(const NetworkConnectionPtr & target, const std::string & roomMode, const std::string & roomName, const std::string & accountID, 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);
+	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);