mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-27 22:49:25 +02:00
Client-side update, adapted and fixed login and chat
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "../../lib/MetaString.h"
|
#include "../../lib/MetaString.h"
|
||||||
#include "../../lib/CConfigHandler.h"
|
#include "../../lib/CConfigHandler.h"
|
||||||
|
#include "../../lib/TextOperations.h"
|
||||||
#include "../../lib/network/NetworkClient.h"
|
#include "../../lib/network/NetworkClient.h"
|
||||||
|
|
||||||
GlobalLobbyClient::~GlobalLobbyClient()
|
GlobalLobbyClient::~GlobalLobbyClient()
|
||||||
@@ -42,15 +43,7 @@ static std::string getCurrentTimeFormatted(int timeOffsetSeconds = 0)
|
|||||||
auto timeNowChrono = std::chrono::system_clock::now();
|
auto timeNowChrono = std::chrono::system_clock::now();
|
||||||
timeNowChrono += std::chrono::seconds(timeOffsetSeconds);
|
timeNowChrono += std::chrono::seconds(timeOffsetSeconds);
|
||||||
|
|
||||||
std::time_t timeNowC = std::chrono::system_clock::to_time_t(timeNowChrono);
|
return TextOperations::getFormattedTimeLocal(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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalLobbyClient::onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message)
|
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());
|
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();
|
auto loginWindowPtr = loginWindow.lock();
|
||||||
|
|
||||||
|
if (!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
|
||||||
|
throw std::runtime_error("lobby connection finished without active login window!");
|
||||||
|
|
||||||
|
{
|
||||||
|
Settings configID = settings.write["lobby"]["accountID"];
|
||||||
|
configID->String() = json["accountID"].String();
|
||||||
|
|
||||||
|
Settings configName = settings.write["lobby"]["displayName"];
|
||||||
|
configName->String() = json["displayName"].String();
|
||||||
|
|
||||||
|
Settings configCookie = settings.write["lobby"]["accountCookie"];
|
||||||
|
configCookie->String() = json["accountCookie"].String();
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Settings configCookie = settings.write["lobby"]["accountCookie"];
|
||||||
|
configCookie->String() = json["accountCookie"].String();
|
||||||
|
|
||||||
|
Settings configName = settings.write["lobby"]["displayName"];
|
||||||
|
configName->String() = json["displayName"].String();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto loginWindowPtr = loginWindow.lock();
|
||||||
|
|
||||||
if (!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
|
if (!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
|
||||||
throw std::runtime_error("lobby connection finished without active login window!");
|
throw std::runtime_error("lobby connection finished without active login window!");
|
||||||
|
|
||||||
loginWindowPtr->onConnectionSuccess();
|
loginWindowPtr->onConnectionSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json["type"].String() == "chatHistory")
|
void GlobalLobbyClient::receiveChatHistory(const JsonNode & json)
|
||||||
{
|
{
|
||||||
for (auto const & entry : json["messages"].Vector())
|
for (auto const & entry : json["messages"].Vector())
|
||||||
{
|
{
|
||||||
std::string senderName = entry["senderName"].String();
|
std::string accountID = entry["accountID"].String();
|
||||||
|
std::string displayName = entry["displayName"].String();
|
||||||
std::string messageText = entry["messageText"].String();
|
std::string messageText = entry["messageText"].String();
|
||||||
int ageSeconds = entry["ageSeconds"].Integer();
|
int ageSeconds = entry["ageSeconds"].Integer();
|
||||||
std::string timeFormatted = getCurrentTimeFormatted(-ageSeconds);
|
std::string timeFormatted = getCurrentTimeFormatted(-ageSeconds);
|
||||||
|
|
||||||
auto lobbyWindowPtr = lobbyWindow.lock();
|
auto lobbyWindowPtr = lobbyWindow.lock();
|
||||||
if(lobbyWindowPtr)
|
if(lobbyWindowPtr)
|
||||||
lobbyWindowPtr->onGameChatMessage(senderName, messageText, timeFormatted);
|
lobbyWindowPtr->onGameChatMessage(displayName, messageText, timeFormatted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json["type"].String() == "chatMessage")
|
void GlobalLobbyClient::receiveChatMessage(const JsonNode & json)
|
||||||
{
|
{
|
||||||
std::string senderName = json["senderName"].String();
|
std::string accountID = json["accountID"].String();
|
||||||
|
std::string displayName = json["displayName"].String();
|
||||||
std::string messageText = json["messageText"].String();
|
std::string messageText = json["messageText"].String();
|
||||||
std::string timeFormatted = getCurrentTimeFormatted();
|
std::string timeFormatted = getCurrentTimeFormatted();
|
||||||
auto lobbyWindowPtr = lobbyWindow.lock();
|
auto lobbyWindowPtr = lobbyWindow.lock();
|
||||||
if(lobbyWindowPtr)
|
if(lobbyWindowPtr)
|
||||||
lobbyWindowPtr->onGameChatMessage(senderName, messageText, timeFormatted);
|
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> &)
|
void GlobalLobbyClient::onConnectionEstablished(const std::shared_ptr<NetworkConnection> &)
|
||||||
{
|
{
|
||||||
JsonNode toSend;
|
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);
|
sendMessage(toSend);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +224,9 @@ void GlobalLobbyClient::sendMessage(const JsonNode & data)
|
|||||||
|
|
||||||
void GlobalLobbyClient::connect()
|
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()
|
bool GlobalLobbyClient::isConnected()
|
||||||
|
|||||||
@@ -33,6 +33,15 @@ class GlobalLobbyClient : public INetworkClientListener, boost::noncopyable
|
|||||||
void onDisconnected(const std::shared_ptr<NetworkConnection> &) override;
|
void onDisconnected(const std::shared_ptr<NetworkConnection> &) override;
|
||||||
void onTimer() 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:
|
public:
|
||||||
explicit GlobalLobbyClient();
|
explicit GlobalLobbyClient();
|
||||||
~GlobalLobbyClient();
|
~GlobalLobbyClient();
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "../../lib/CGeneralTextHandler.h"
|
#include "../../lib/CGeneralTextHandler.h"
|
||||||
#include "../../lib/MetaString.h"
|
#include "../../lib/MetaString.h"
|
||||||
|
#include "../../lib/CConfigHandler.h"
|
||||||
|
|
||||||
GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
|
GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
|
||||||
: CWindowObject(BORDERED)
|
: CWindowObject(BORDERED)
|
||||||
@@ -41,9 +42,14 @@ GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
|
|||||||
inputUsername = std::make_shared<CTextInput>(Rect(15, 73, 176, 16), FONT_SMALL, nullptr, ETextAlignment::TOPLEFT, true);
|
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(); });
|
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(); });
|
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));
|
background->playerColored(PlayerColor(1));
|
||||||
|
inputUsername->setText(settings["lobby"]["displayName"].String());
|
||||||
|
inputUsername->cb += [this](const std::string & text)
|
||||||
|
{
|
||||||
|
buttonLogin->block(text.empty());
|
||||||
|
};
|
||||||
|
|
||||||
center();
|
center();
|
||||||
}
|
}
|
||||||
@@ -56,8 +62,12 @@ void GlobalLobbyLoginWindow::onClose()
|
|||||||
|
|
||||||
void GlobalLobbyLoginWindow::onLogin()
|
void GlobalLobbyLoginWindow::onLogin()
|
||||||
{
|
{
|
||||||
|
Settings config = settings.write["lobby"]["displayName"];
|
||||||
|
config->String() = inputUsername->getText();
|
||||||
|
|
||||||
labelStatus->setText(CGI->generaltexth->translate("vcmi.lobby.login.connecting"));
|
labelStatus->setText(CGI->generaltexth->translate("vcmi.lobby.login.connecting"));
|
||||||
CSH->getGlobalLobby().connect();
|
CSH->getGlobalLobby().connect();
|
||||||
|
buttonClose->block(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalLobbyLoginWindow::onConnectionSuccess()
|
void GlobalLobbyLoginWindow::onConnectionSuccess()
|
||||||
@@ -73,4 +83,5 @@ void GlobalLobbyLoginWindow::onConnectionFailed(const std::string & reason)
|
|||||||
formatter.replaceRawString(reason);
|
formatter.replaceRawString(reason);
|
||||||
|
|
||||||
labelStatus->setText(formatter.toString());
|
labelStatus->setText(formatter.toString());
|
||||||
|
buttonClose->block(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ GlobalLobbyWindow::GlobalLobbyWindow():
|
|||||||
pos = widget->pos;
|
pos = widget->pos;
|
||||||
center();
|
center();
|
||||||
|
|
||||||
widget->getAccountNameLabel()->setText(settings["general"]["playerName"].String());
|
widget->getAccountNameLabel()->setText(settings["lobby"]["displayName"].String());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalLobbyWindow::doSendChatMessage()
|
void GlobalLobbyWindow::doSendChatMessage()
|
||||||
|
|||||||
@@ -553,12 +553,36 @@
|
|||||||
"type" : "object",
|
"type" : "object",
|
||||||
"additionalProperties" : false,
|
"additionalProperties" : false,
|
||||||
"default" : {},
|
"default" : {},
|
||||||
"required" : [ "mapPreview" ],
|
"required" : [ "mapPreview", "accountID", "accountCookie", "displayName", "hostname", "port" ],
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"mapPreview" : {
|
"mapPreview" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"default" : true
|
"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" : {
|
"gameTweaks" : {
|
||||||
|
|||||||
@@ -219,4 +219,10 @@ std::string TextOperations::getFormattedDateTimeLocal(std::time_t dt)
|
|||||||
return vstd::getFormattedDateTime(dt, Languages::getLanguageOptions(settings["general"]["language"].String()).dateTimeFormat);
|
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
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ namespace TextOperations
|
|||||||
|
|
||||||
/// get formatted DateTime depending on the language selected
|
/// get formatted DateTime depending on the language selected
|
||||||
DLL_LINKAGE std::string getFormattedDateTimeLocal(std::time_t dt);
|
DLL_LINKAGE std::string getFormattedDateTimeLocal(std::time_t dt);
|
||||||
|
|
||||||
|
/// get formatted time (without date)
|
||||||
|
DLL_LINKAGE std::string getFormattedTimeLocal(std::time_t dt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ void LobbyDatabase::createTables()
|
|||||||
accountID TEXT,
|
accountID TEXT,
|
||||||
displayName TEXT,
|
displayName TEXT,
|
||||||
online INTEGER NOT NULL,
|
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
|
creationTime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||||
);
|
);
|
||||||
)";
|
)";
|
||||||
@@ -110,11 +110,11 @@ void LobbyDatabase::prepareStatements()
|
|||||||
// DELETE FROM
|
// DELETE FROM
|
||||||
|
|
||||||
static const std::string deleteGameRoomPlayersText = R"(
|
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"(
|
static const std::string deleteGameRoomInvitesText = R"(
|
||||||
DELETE FROM gameRoomInvites WHERE gameRoomID = ? AND accountID = ?
|
DELETE FROM gameRoomInvites WHERE roomID = ? AND accountID = ?
|
||||||
)";
|
)";
|
||||||
|
|
||||||
// UPDATE
|
// UPDATE
|
||||||
@@ -134,10 +134,11 @@ void LobbyDatabase::prepareStatements()
|
|||||||
// SELECT FROM
|
// SELECT FROM
|
||||||
|
|
||||||
static const std::string getRecentMessageHistoryText = R"(
|
static const std::string getRecentMessageHistoryText = R"(
|
||||||
SELECT senderName, messageText, strftime('%s',CURRENT_TIMESTAMP)- strftime('%s',creationTime) AS secondsElapsed
|
SELECT senderName, displayName, messageText, strftime('%s',CURRENT_TIMESTAMP)- strftime('%s',cm.creationTime) AS secondsElapsed
|
||||||
FROM chatMessages
|
FROM chatMessages cm
|
||||||
|
LEFT JOIN accounts on accountID = senderName
|
||||||
WHERE secondsElapsed < 60*60*18
|
WHERE secondsElapsed < 60*60*18
|
||||||
ORDER BY creationTime DESC
|
ORDER BY cm.creationTime DESC
|
||||||
LIMIT 100
|
LIMIT 100
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@@ -149,7 +150,7 @@ void LobbyDatabase::prepareStatements()
|
|||||||
)";
|
)";
|
||||||
|
|
||||||
static const std::string getAccountGameRoomText = R"(
|
static const std::string getAccountGameRoomText = R"(
|
||||||
SELECT roomID
|
SELECT grp.roomID
|
||||||
FROM gameRoomPlayers grp
|
FROM gameRoomPlayers grp
|
||||||
LEFT JOIN gameRooms gr ON gr.roomID = grp.roomID
|
LEFT JOIN gameRooms gr ON gr.roomID = grp.roomID
|
||||||
WHERE accountID = ? AND status IN ('public', 'private', 'busy')
|
WHERE accountID = ? AND status IN ('public', 'private', 'busy')
|
||||||
@@ -159,7 +160,13 @@ void LobbyDatabase::prepareStatements()
|
|||||||
static const std::string getActiveAccountsText = R"(
|
static const std::string getActiveAccountsText = R"(
|
||||||
SELECT accountID, displayName
|
SELECT accountID, displayName
|
||||||
FROM accounts
|
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"(
|
static const std::string isAccountCookieValidText = R"(
|
||||||
@@ -187,12 +194,18 @@ void LobbyDatabase::prepareStatements()
|
|||||||
WHERE accountID = ?
|
WHERE accountID = ?
|
||||||
)";
|
)";
|
||||||
|
|
||||||
static const std::string isAccountExistsText = R"(
|
static const std::string isAccountIDExistsText = R"(
|
||||||
SELECT COUNT(accountID)
|
SELECT COUNT(accountID)
|
||||||
FROM accounts
|
FROM accounts
|
||||||
WHERE accountID = ?
|
WHERE accountID = ?
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
static const std::string isAccountNameExistsText = R"(
|
||||||
|
SELECT COUNT(displayName)
|
||||||
|
FROM accounts
|
||||||
|
WHERE displayName = ?
|
||||||
|
)";
|
||||||
|
|
||||||
insertChatMessageStatement = database->prepare(insertChatMessageText);
|
insertChatMessageStatement = database->prepare(insertChatMessageText);
|
||||||
insertAccountStatement = database->prepare(insertAccountText);
|
insertAccountStatement = database->prepare(insertAccountText);
|
||||||
insertAccessCookieStatement = database->prepare(insertAccessCookieText);
|
insertAccessCookieStatement = database->prepare(insertAccessCookieText);
|
||||||
@@ -210,11 +223,13 @@ void LobbyDatabase::prepareStatements()
|
|||||||
getIdleGameRoomStatement = database->prepare(getIdleGameRoomText);
|
getIdleGameRoomStatement = database->prepare(getIdleGameRoomText);
|
||||||
getAccountGameRoomStatement = database->prepare(getAccountGameRoomText);
|
getAccountGameRoomStatement = database->prepare(getAccountGameRoomText);
|
||||||
getActiveAccountsStatement = database->prepare(getActiveAccountsText);
|
getActiveAccountsStatement = database->prepare(getActiveAccountsText);
|
||||||
|
getAccountDisplayNameStatement = database->prepare(getAccountDisplayNameText);
|
||||||
|
|
||||||
isAccountCookieValidStatement = database->prepare(isAccountCookieValidText);
|
isAccountCookieValidStatement = database->prepare(isAccountCookieValidText);
|
||||||
isPlayerInGameRoomStatement = database->prepare(isPlayerInGameRoomText);
|
isPlayerInGameRoomStatement = database->prepare(isPlayerInGameRoomText);
|
||||||
isPlayerInAnyGameRoomStatement = database->prepare(isPlayerInAnyGameRoomText);
|
isPlayerInAnyGameRoomStatement = database->prepare(isPlayerInAnyGameRoomText);
|
||||||
isAccountExistsStatement = database->prepare(isAccountExistsText);
|
isAccountIDExistsStatement = database->prepare(isAccountIDExistsText);
|
||||||
|
isAccountNameExistsStatement = database->prepare(isAccountNameExistsText);
|
||||||
}
|
}
|
||||||
|
|
||||||
LobbyDatabase::~LobbyDatabase() = default;
|
LobbyDatabase::~LobbyDatabase() = default;
|
||||||
@@ -262,7 +277,7 @@ std::vector<LobbyChatMessage> LobbyDatabase::getRecentMessageHistory()
|
|||||||
while(getRecentMessageHistoryStatement->execute())
|
while(getRecentMessageHistoryStatement->execute())
|
||||||
{
|
{
|
||||||
LobbyChatMessage message;
|
LobbyChatMessage message;
|
||||||
getRecentMessageHistoryStatement->getColumns(message.sender, message.messageText, message.age);
|
getRecentMessageHistoryStatement->getColumns(message.accountID, message.displayName, message.messageText, message.age);
|
||||||
result.push_back(message);
|
result.push_back(message);
|
||||||
}
|
}
|
||||||
getRecentMessageHistoryStatement->reset();
|
getRecentMessageHistoryStatement->reset();
|
||||||
@@ -332,7 +347,14 @@ void LobbyDatabase::updateActiveAccount(const std::string & accountID, bool isAc
|
|||||||
|
|
||||||
std::string LobbyDatabase::getAccountDisplayName(const std::string & accountID)
|
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)
|
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)
|
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)
|
isAccountCookieValidStatement->setBinds(accountID, accessCookieUUID, cookieLifetime.count());
|
||||||
{
|
if (isAccountCookieValidStatement->execute())
|
||||||
return {};
|
isAccountCookieValidStatement->getColumns(result);
|
||||||
|
isAccountCookieValidStatement->reset();
|
||||||
|
|
||||||
|
return result ? LobbyCookieStatus::VALID : LobbyCookieStatus::INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
LobbyInviteStatus LobbyDatabase::getAccountInviteStatus(const std::string & accountID, const std::string & roomID)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LobbyDatabase::isAccountExists(const std::string & accountID)
|
bool LobbyDatabase::isAccountNameExists(const std::string & displayName)
|
||||||
{
|
{
|
||||||
return false;
|
bool result = false;
|
||||||
|
|
||||||
|
isAccountNameExistsStatement->setBinds(displayName);
|
||||||
|
if (isAccountNameExistsStatement->execute())
|
||||||
|
isAccountNameExistsStatement->getColumns(result);
|
||||||
|
isAccountNameExistsStatement->reset();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LobbyDatabase::isAccountIDExists(const std::string & accountID)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
isAccountIDExistsStatement->setBinds(accountID);
|
||||||
|
if (isAccountIDExistsStatement->execute())
|
||||||
|
isAccountIDExistsStatement->getColumns(result);
|
||||||
|
isAccountIDExistsStatement->reset();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<LobbyGameRoom> LobbyDatabase::getActiveGameRooms()
|
std::vector<LobbyGameRoom> LobbyDatabase::getActiveGameRooms()
|
||||||
|
|||||||
@@ -38,12 +38,14 @@ class LobbyDatabase
|
|||||||
SQLiteStatementPtr getIdleGameRoomStatement;
|
SQLiteStatementPtr getIdleGameRoomStatement;
|
||||||
SQLiteStatementPtr getAccountGameRoomStatement;
|
SQLiteStatementPtr getAccountGameRoomStatement;
|
||||||
SQLiteStatementPtr getActiveAccountsStatement;
|
SQLiteStatementPtr getActiveAccountsStatement;
|
||||||
|
SQLiteStatementPtr getAccountDisplayNameStatement;
|
||||||
|
|
||||||
SQLiteStatementPtr isAccountCookieValidStatement;
|
SQLiteStatementPtr isAccountCookieValidStatement;
|
||||||
SQLiteStatementPtr isGameRoomCookieValidStatement;
|
SQLiteStatementPtr isGameRoomCookieValidStatement;
|
||||||
SQLiteStatementPtr isPlayerInGameRoomStatement;
|
SQLiteStatementPtr isPlayerInGameRoomStatement;
|
||||||
SQLiteStatementPtr isPlayerInAnyGameRoomStatement;
|
SQLiteStatementPtr isPlayerInAnyGameRoomStatement;
|
||||||
SQLiteStatementPtr isAccountExistsStatement;
|
SQLiteStatementPtr isAccountIDExistsStatement;
|
||||||
|
SQLiteStatementPtr isAccountNameExistsStatement;
|
||||||
|
|
||||||
void prepareStatements();
|
void prepareStatements();
|
||||||
void createTables();
|
void createTables();
|
||||||
@@ -81,12 +83,12 @@ public:
|
|||||||
|
|
||||||
LobbyCookieStatus getGameRoomCookieStatus(const std::string & accountID, const std::string & accessCookieUUID, std::chrono::seconds cookieLifetime);
|
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, 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);
|
LobbyInviteStatus getAccountInviteStatus(const std::string & accountID, const std::string & roomID);
|
||||||
LobbyRoomState getGameRoomStatus(const std::string & roomID);
|
LobbyRoomState getGameRoomStatus(const std::string & roomID);
|
||||||
uint32_t getGameRoomFreeSlots(const std::string & roomID);
|
uint32_t getGameRoomFreeSlots(const std::string & roomID);
|
||||||
|
|
||||||
bool isPlayerInGameRoom(const std::string & accountID);
|
bool isPlayerInGameRoom(const std::string & accountID);
|
||||||
bool isPlayerInGameRoom(const std::string & accountID, const std::string & roomID);
|
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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ struct LobbyGameRoom
|
|||||||
|
|
||||||
struct LobbyChatMessage
|
struct LobbyChatMessage
|
||||||
{
|
{
|
||||||
std::string sender;
|
std::string accountID;
|
||||||
|
std::string displayName;
|
||||||
std::string messageText;
|
std::string messageText;
|
||||||
std::chrono::seconds age;
|
std::chrono::seconds age;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -100,11 +100,13 @@ void LobbyServer::sendLoginFailed(const NetworkConnectionPtr & target, const std
|
|||||||
sendMessage(target, reply);
|
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;
|
JsonNode reply;
|
||||||
reply["type"].String() = "loginSuccess";
|
reply["type"].String() = "loginSuccess";
|
||||||
reply["accountCookie"].String() = accountCookie;
|
reply["accountCookie"].String() = accountCookie;
|
||||||
|
if (!displayName.empty())
|
||||||
|
reply["displayName"].String() = displayName;
|
||||||
sendMessage(target, reply);
|
sendMessage(target, reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,8 +119,9 @@ void LobbyServer::sendChatHistory(const NetworkConnectionPtr & target, const std
|
|||||||
{
|
{
|
||||||
JsonNode jsonEntry;
|
JsonNode jsonEntry;
|
||||||
|
|
||||||
|
jsonEntry["accountID"].String() = message.accountID;
|
||||||
|
jsonEntry["displayName"].String() = message.displayName;
|
||||||
jsonEntry["messageText"].String() = message.messageText;
|
jsonEntry["messageText"].String() = message.messageText;
|
||||||
jsonEntry["senderName"].String() = message.sender;
|
|
||||||
jsonEntry["ageSeconds"].Integer() = message.age.count();
|
jsonEntry["ageSeconds"].Integer() = message.age.count();
|
||||||
|
|
||||||
reply["messages"].Vector().push_back(jsonEntry);
|
reply["messages"].Vector().push_back(jsonEntry);
|
||||||
@@ -183,12 +186,13 @@ void LobbyServer::sendJoinRoomSuccess(const NetworkConnectionPtr & target, const
|
|||||||
sendMessage(target, reply);
|
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;
|
JsonNode reply;
|
||||||
reply["type"].String() = "chatMessage";
|
reply["type"].String() = "chatMessage";
|
||||||
reply["messageText"].String() = messageText;
|
reply["messageText"].String() = messageText;
|
||||||
reply["senderName"].String() = senderName;
|
reply["accountID"].String() = accountID;
|
||||||
|
reply["displayName"].String() = displayName;
|
||||||
reply["roomMode"].String() = roomMode;
|
reply["roomMode"].String() = roomMode;
|
||||||
reply["roomName"].String() = roomName;
|
reply["roomName"].String() = roomName;
|
||||||
|
|
||||||
@@ -285,32 +289,33 @@ void LobbyServer::onPacketReceived(const NetworkConnectionPtr & connection, cons
|
|||||||
|
|
||||||
void LobbyServer::receiveSendChatMessage(const NetworkConnectionPtr & connection, const JsonNode & json)
|
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 messageText = json["messageText"].String();
|
||||||
std::string messageTextClean = sanitizeChatMessage(messageText);
|
std::string messageTextClean = sanitizeChatMessage(messageText);
|
||||||
|
std::string displayName = database->getAccountDisplayName(accountID);
|
||||||
|
|
||||||
if (messageTextClean.empty())
|
if (messageTextClean.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
database->insertChatMessage(senderName, "global", "english", messageText);
|
database->insertChatMessage(accountID, "global", "english", messageText);
|
||||||
|
|
||||||
for(const auto & connection : activeAccounts)
|
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)
|
void LobbyServer::receiveClientRegister(const NetworkConnectionPtr & connection, const JsonNode & json)
|
||||||
{
|
{
|
||||||
std::string accountID = json["accountID"].String();
|
|
||||||
std::string displayName = json["displayName"].String();
|
std::string displayName = json["displayName"].String();
|
||||||
std::string language = json["language"].String();
|
std::string language = json["language"].String();
|
||||||
|
|
||||||
if (database->isAccountExists(accountID))
|
if (isAccountNameValid(displayName))
|
||||||
return sendLoginFailed(connection, "Account name already in use");
|
|
||||||
|
|
||||||
if (isAccountNameValid(accountID))
|
|
||||||
return sendLoginFailed(connection, "Illegal account name");
|
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 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->insertAccount(accountID, displayName);
|
||||||
database->insertAccessCookie(accountID, accountCookie);
|
database->insertAccessCookie(accountID, accountCookie);
|
||||||
@@ -325,7 +330,7 @@ void LobbyServer::receiveClientLogin(const NetworkConnectionPtr & connection, co
|
|||||||
std::string language = json["language"].String();
|
std::string language = json["language"].String();
|
||||||
std::string version = json["version"].String();
|
std::string version = json["version"].String();
|
||||||
|
|
||||||
if (!database->isAccountExists(accountID))
|
if (!database->isAccountIDExists(accountID))
|
||||||
return sendLoginFailed(connection, "Account not found");
|
return sendLoginFailed(connection, "Account not found");
|
||||||
|
|
||||||
auto clientCookieStatus = database->getAccountCookieStatus(accountID, accountCookie, accountCookieLifetime);
|
auto clientCookieStatus = database->getAccountCookieStatus(accountID, accountCookie, accountCookieLifetime);
|
||||||
@@ -344,7 +349,7 @@ void LobbyServer::receiveClientLogin(const NetworkConnectionPtr & connection, co
|
|||||||
activeAccounts[connection].version = version;
|
activeAccounts[connection].version = version;
|
||||||
activeAccounts[connection].language = language;
|
activeAccounts[connection].language = language;
|
||||||
|
|
||||||
sendLoginSuccess(connection, accountCookie);
|
sendLoginSuccess(connection, accountCookie, displayName);
|
||||||
sendChatHistory(connection, database->getRecentMessageHistory());
|
sendChatHistory(connection, database->getRecentMessageHistory());
|
||||||
|
|
||||||
// send active accounts list to new account
|
// send active accounts list to new account
|
||||||
@@ -369,7 +374,7 @@ void LobbyServer::receiveServerLogin(const NetworkConnectionPtr & connection, co
|
|||||||
{
|
{
|
||||||
database->insertGameRoom(gameRoomID, accountID);
|
database->insertGameRoom(gameRoomID, accountID);
|
||||||
activeGameRooms[connection].roomID = gameRoomID;
|
activeGameRooms[connection].roomID = gameRoomID;
|
||||||
sendLoginSuccess(connection, accountCookie);
|
sendLoginSuccess(connection, accountCookie, {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,10 +70,10 @@ class LobbyServer : public INetworkServerListener
|
|||||||
void broadcastActiveAccounts();
|
void broadcastActiveAccounts();
|
||||||
void broadcastActiveGameRooms();
|
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 sendAccountCreated(const NetworkConnectionPtr & target, const std::string & accountID, const std::string & accountCookie);
|
||||||
void sendLoginFailed(const NetworkConnectionPtr & target, const std::string & reason);
|
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 sendChatHistory(const NetworkConnectionPtr & target, const std::vector<LobbyChatMessage> &);
|
||||||
void sendAccountJoinsRoom(const NetworkConnectionPtr & target, const std::string & accountID);
|
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user