diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 4f8c6aaa1..5d39afeb7 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -95,7 +95,9 @@ set(client_SRCS renderSDL/ScreenHandler.cpp renderSDL/SDL_Extensions.cpp - serverLobby/LobbyWindow.cpp + globalLobby/GlobalLobbyClient.cpp + globalLobby/GlobalLobbyWidget.cpp + globalLobby/GlobalLobbyWindow.cpp widgets/Buttons.cpp widgets/CArtifactHolder.cpp @@ -272,7 +274,9 @@ set(client_HEADERS renderSDL/SDL_Extensions.h renderSDL/SDL_PixelAccess.h - serverLobby/LobbyWindow.h + globalLobby/GlobalLobbyClient.h + globalLobby/GlobalLobbyWidget.h + globalLobby/GlobalLobbyWindow.h widgets/Buttons.h widgets/CArtifactHolder.h diff --git a/client/serverLobby/LobbyWindow.cpp b/client/globalLobby/GlobalLobbyClient.cpp similarity index 63% rename from client/serverLobby/LobbyWindow.cpp rename to client/globalLobby/GlobalLobbyClient.cpp index b67152942..eb2d558fa 100644 --- a/client/serverLobby/LobbyWindow.cpp +++ b/client/globalLobby/GlobalLobbyClient.cpp @@ -1,5 +1,5 @@ /* - * LobbyWindow.cpp, part of VCMI engine + * GlobalLobbyClient.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * @@ -9,17 +9,20 @@ */ #include "StdInc.h" -#include "LobbyWindow.h" +#include "GlobalLobbyClient.h" + +#include "GlobalLobbyWindow.h" #include "../gui/CGuiHandler.h" #include "../gui/WindowHandler.h" -#include "../widgets/TextControls.h" #include "../windows/InfoWindows.h" #include "../../lib/MetaString.h" #include "../../lib/CConfigHandler.h" #include "../../lib/network/NetworkClient.h" +GlobalLobbyClient::~GlobalLobbyClient() = default; + GlobalLobbyClient::GlobalLobbyClient(GlobalLobbyWindow * window) : networkClient(std::make_unique(*this)) , window(window) @@ -122,74 +125,3 @@ void GlobalLobbyClient::poll() { networkClient->poll(); } - -GlobalLobbyWidget::GlobalLobbyWidget(GlobalLobbyWindow * window) - : window(window) -{ - addCallback("closeWindow", [](int) { GH.windows().popWindows(1); }); - addCallback("sendMessage", [this](int) { this->window->doSendChatMessage(); }); - - const JsonNode config(JsonPath::builtin("config/widgets/lobbyWindow.json")); - build(config); -} - -std::shared_ptr GlobalLobbyWidget::getAccountNameLabel() -{ - return widget("accountNameLabel"); -} - -std::shared_ptr GlobalLobbyWidget::getMessageInput() -{ - return widget("messageInput"); -} - -std::shared_ptr GlobalLobbyWidget::getGameChat() -{ - return widget("gameChat"); -} - -GlobalLobbyWindow::GlobalLobbyWindow(): - CWindowObject(BORDERED) -{ - OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - widget = std::make_shared(this); - pos = widget->pos; - center(); - connection = std::make_shared(this); - - connection->start("127.0.0.1", 30303); - widget->getAccountNameLabel()->setText(settings["general"]["playerName"].String()); - - addUsedEvents(TIME); -} - -void GlobalLobbyWindow::tick(uint32_t msPassed) -{ - connection->poll(); -} - -void GlobalLobbyWindow::doSendChatMessage() -{ - std::string messageText = widget->getMessageInput()->getText(); - - JsonNode toSend; - toSend["type"].String() = "sendChatMessage"; - toSend["messageText"].String() = messageText; - - connection->sendMessage(toSend); - - widget->getMessageInput()->setText(""); -} - -void GlobalLobbyWindow::onGameChatMessage(const std::string & sender, const std::string & message, const std::string & when) -{ - MetaString chatMessageFormatted; - chatMessageFormatted.appendRawString("[%s] {%s}: %s\n"); - chatMessageFormatted.replaceRawString(when); - chatMessageFormatted.replaceRawString(sender); - chatMessageFormatted.replaceRawString(message); - - chatHistory += chatMessageFormatted.toString(); - - widget->getGameChat()->setText(chatHistory); -} diff --git a/client/serverLobby/LobbyWindow.h b/client/globalLobby/GlobalLobbyClient.h similarity index 55% rename from client/serverLobby/LobbyWindow.h rename to client/globalLobby/GlobalLobbyClient.h index eaa0f0396..c018792ff 100644 --- a/client/serverLobby/LobbyWindow.h +++ b/client/globalLobby/GlobalLobbyClient.h @@ -1,5 +1,5 @@ /* - * LobbyWindow.h, part of VCMI engine + * GlobalLobbyClient.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * @@ -9,24 +9,14 @@ */ #pragma once -#include "../gui/InterfaceObjectConfigurable.h" -#include "../windows/CWindowObject.h" - #include "../../lib/network/NetworkListener.h" +VCMI_LIB_NAMESPACE_BEGIN +class JsonNode; +VCMI_LIB_NAMESPACE_END + class GlobalLobbyWindow; -class GlobalLobbyWidget : public InterfaceObjectConfigurable -{ - GlobalLobbyWindow * window; -public: - GlobalLobbyWidget(GlobalLobbyWindow * window); - - std::shared_ptr getAccountNameLabel(); - std::shared_ptr getMessageInput(); - std::shared_ptr getGameChat(); -}; - class GlobalLobbyClient : public INetworkClientListener { std::unique_ptr networkClient; @@ -40,6 +30,7 @@ class GlobalLobbyClient : public INetworkClientListener public: explicit GlobalLobbyClient(GlobalLobbyWindow * window); + ~GlobalLobbyClient(); void sendMessage(const JsonNode & data); void start(const std::string & host, uint16_t port); @@ -47,20 +38,3 @@ public: void poll(); }; - -class GlobalLobbyWindow : public CWindowObject -{ - std::string chatHistory; - - std::shared_ptr widget; - std::shared_ptr connection; - - void tick(uint32_t msPassed); - -public: - GlobalLobbyWindow(); - - void doSendChatMessage(); - - void onGameChatMessage(const std::string & sender, const std::string & message, const std::string & when); -}; diff --git a/client/globalLobby/GlobalLobbyWidget.cpp b/client/globalLobby/GlobalLobbyWidget.cpp new file mode 100644 index 000000000..6491d1a24 --- /dev/null +++ b/client/globalLobby/GlobalLobbyWidget.cpp @@ -0,0 +1,42 @@ +/* + * GlobalLobbyWidget.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ + +#include "StdInc.h" +#include "GlobalLobbyWidget.h" +#include "GlobalLobbyWindow.h" + +#include "../gui/CGuiHandler.h" +#include "../gui/WindowHandler.h" +#include "../widgets/TextControls.h" + +GlobalLobbyWidget::GlobalLobbyWidget(GlobalLobbyWindow * window) + : window(window) +{ + addCallback("closeWindow", [](int) { GH.windows().popWindows(1); }); + addCallback("sendMessage", [this](int) { this->window->doSendChatMessage(); }); + + const JsonNode config(JsonPath::builtin("config/widgets/lobbyWindow.json")); + build(config); +} + +std::shared_ptr GlobalLobbyWidget::getAccountNameLabel() +{ + return widget("accountNameLabel"); +} + +std::shared_ptr GlobalLobbyWidget::getMessageInput() +{ + return widget("messageInput"); +} + +std::shared_ptr GlobalLobbyWidget::getGameChat() +{ + return widget("gameChat"); +} diff --git a/client/globalLobby/GlobalLobbyWidget.h b/client/globalLobby/GlobalLobbyWidget.h new file mode 100644 index 000000000..c22c0deae --- /dev/null +++ b/client/globalLobby/GlobalLobbyWidget.h @@ -0,0 +1,25 @@ +/* + * GlobalLobbyWidget.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#pragma once + +#include "../gui/InterfaceObjectConfigurable.h" + +class GlobalLobbyWindow; + +class GlobalLobbyWidget : public InterfaceObjectConfigurable +{ + GlobalLobbyWindow * window; +public: + GlobalLobbyWidget(GlobalLobbyWindow * window); + + std::shared_ptr getAccountNameLabel(); + std::shared_ptr getMessageInput(); + std::shared_ptr getGameChat(); +}; diff --git a/client/globalLobby/GlobalLobbyWindow.cpp b/client/globalLobby/GlobalLobbyWindow.cpp new file mode 100644 index 000000000..8ea9dad64 --- /dev/null +++ b/client/globalLobby/GlobalLobbyWindow.cpp @@ -0,0 +1,67 @@ +/* + * GlobalLobbyWindow.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ + +#include "StdInc.h" +#include "GlobalLobbyWindow.h" + +#include "GlobalLobbyWidget.h" +#include "GlobalLobbyClient.h" + +#include "../gui/CGuiHandler.h" +#include "../widgets/TextControls.h" + +#include "../../lib/MetaString.h" +#include "../../lib/CConfigHandler.h" + +GlobalLobbyWindow::GlobalLobbyWindow(): + CWindowObject(BORDERED) +{ + OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; + widget = std::make_shared(this); + pos = widget->pos; + center(); + connection = std::make_shared(this); + + connection->start("127.0.0.1", 30303); + widget->getAccountNameLabel()->setText(settings["general"]["playerName"].String()); + + addUsedEvents(TIME); +} + +void GlobalLobbyWindow::tick(uint32_t msPassed) +{ + connection->poll(); +} + +void GlobalLobbyWindow::doSendChatMessage() +{ + std::string messageText = widget->getMessageInput()->getText(); + + JsonNode toSend; + toSend["type"].String() = "sendChatMessage"; + toSend["messageText"].String() = messageText; + + connection->sendMessage(toSend); + + widget->getMessageInput()->setText(""); +} + +void GlobalLobbyWindow::onGameChatMessage(const std::string & sender, const std::string & message, const std::string & when) +{ + MetaString chatMessageFormatted; + chatMessageFormatted.appendRawString("[%s] {%s}: %s\n"); + chatMessageFormatted.replaceRawString(when); + chatMessageFormatted.replaceRawString(sender); + chatMessageFormatted.replaceRawString(message); + + chatHistory += chatMessageFormatted.toString(); + + widget->getGameChat()->setText(chatHistory); +} diff --git a/client/globalLobby/GlobalLobbyWindow.h b/client/globalLobby/GlobalLobbyWindow.h new file mode 100644 index 000000000..9856d96cb --- /dev/null +++ b/client/globalLobby/GlobalLobbyWindow.h @@ -0,0 +1,32 @@ +/* + * GlobalLobbyWindow.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#pragma once + +#include "../windows/CWindowObject.h" + +class GlobalLobbyWidget; +class GlobalLobbyClient; + +class GlobalLobbyWindow : public CWindowObject +{ + std::string chatHistory; + + std::shared_ptr widget; + std::shared_ptr connection; + + void tick(uint32_t msPassed); + +public: + GlobalLobbyWindow(); + + void doSendChatMessage(); + + void onGameChatMessage(const std::string & sender, const std::string & message, const std::string & when); +}; diff --git a/client/mainmenu/CMainMenu.cpp b/client/mainmenu/CMainMenu.cpp index 255b6444b..6938666cf 100644 --- a/client/mainmenu/CMainMenu.cpp +++ b/client/mainmenu/CMainMenu.cpp @@ -24,7 +24,7 @@ #include "../gui/Shortcut.h" #include "../gui/WindowHandler.h" #include "../render/Canvas.h" -#include "../serverLobby/LobbyWindow.h" +#include "../globalLobby/GlobalLobbyWindow.h" #include "../widgets/CComponent.h" #include "../widgets/Buttons.h" #include "../widgets/MiscWidgets.h" diff --git a/lobby/LobbyServer.cpp b/lobby/LobbyServer.cpp index 29cdce371..3ad7393f5 100644 --- a/lobby/LobbyServer.cpp +++ b/lobby/LobbyServer.cpp @@ -78,6 +78,11 @@ void LobbyDatabase::insertChatMessage(const std::string & sender, const std::str insertChatMessageStatement->reset(); } +bool LobbyDatabase::isPlayerInGameRoom(const std::string & accountName) +{ + return false; //TODO +} + std::vector LobbyDatabase::getRecentMessageHistory() { std::vector result; @@ -132,6 +137,9 @@ void LobbyServer::onPacketReceived(const std::shared_ptr & co if (json["type"].String() == "authentication") return receiveAuthentication(connection, json); + + if (json["type"].String() == "joinGameRoom") + return receiveJoinGameRoom(connection, json); } void LobbyServer::receiveSendChatMessage(const std::shared_ptr & connection, const JsonNode & json) @@ -157,6 +165,12 @@ void LobbyServer::receiveAuthentication(const std::shared_ptr { std::string accountName = json["accountName"].String(); + // TODO: account cookie check + // TODO: account password check + // TODO: protocol version number + // TODO: client/server mode flag + // TODO: client language + activeAccounts[connection].accountName = accountName; auto history = database->getRecentMessageHistory(); @@ -178,6 +192,21 @@ void LobbyServer::receiveAuthentication(const std::shared_ptr sendMessage(connection, reply); } +void LobbyServer::receiveJoinGameRoom(const std::shared_ptr & connection, const JsonNode & json) +{ + if (activeAccounts.count(connection) == 0) + return; // unauthenticated + + std::string senderName = activeAccounts[connection].accountName; + + if (database->isPlayerInGameRoom(senderName)) + return; // only 1 room per player allowed + + // TODO: roomType: private, public + // TODO: additional flags, e.g. allowCheats + // TODO: connection mode: direct or proxy +} + LobbyServer::LobbyServer() : database(new LobbyDatabase()) , networkServer(new NetworkServer(*this)) diff --git a/lobby/LobbyServer.h b/lobby/LobbyServer.h index da334ee7f..3c79a6b78 100644 --- a/lobby/LobbyServer.h +++ b/lobby/LobbyServer.h @@ -39,6 +39,7 @@ public: void insertChatMessage(const std::string & sender, const std::string & messageText); std::vector getRecentMessageHistory(); + bool isPlayerInGameRoom(const std::string & accountName); }; class LobbyServer : public INetworkServerListener @@ -62,6 +63,7 @@ class LobbyServer : public INetworkServerListener void receiveSendChatMessage(const std::shared_ptr & connection, const JsonNode & json); void receiveAuthentication(const std::shared_ptr & connection, const JsonNode & json); + void receiveJoinGameRoom(const std::shared_ptr & connection, const JsonNode & json); public: LobbyServer();