diff --git a/launcher/icons/menu-lobby.png b/launcher/icons/menu-lobby.png deleted file mode 100644 index 6385fc3b5..000000000 Binary files a/launcher/icons/menu-lobby.png and /dev/null differ diff --git a/launcher/icons/room-private.png b/launcher/icons/room-private.png deleted file mode 100644 index 33896d9b9..000000000 Binary files a/launcher/icons/room-private.png and /dev/null differ diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 0263fef96..5eb40861f 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -16,6 +16,7 @@ set(server_SRCS processors/TurnOrderProcessor.cpp CGameHandler.cpp + GlobalLobbyProcessor.cpp ServerSpellCastEnvironment.cpp CVCMIServer.cpp NetPacksServer.cpp @@ -41,6 +42,7 @@ set(server_HEADERS processors/TurnOrderProcessor.h CGameHandler.h + GlobalLobbyProcessor.h ServerSpellCastEnvironment.h CVCMIServer.h LobbyNetPackVisitors.h diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index b9e3ee66d..f6643a803 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -8,7 +8,7 @@ * */ #include "StdInc.h" -#include +#include "CVCMIServer.h" #include "../lib/filesystem/Filesystem.h" #include "../lib/campaign/CampaignState.h" @@ -21,7 +21,6 @@ #include "../lib/spells/CSpellHandler.h" #include "../lib/CCreatureHandler.h" #include "zlib.h" -#include "CVCMIServer.h" #include "../lib/StartInfo.h" #include "../lib/mapping/CMapHeader.h" #include "../lib/rmg/CMapGenOptions.h" @@ -34,6 +33,7 @@ #include "../lib/VCMI_Lib.h" #include "../lib/VCMIDirs.h" #include "CGameHandler.h" +#include "GlobalLobbyProcessor.h" #include "processors/PlayerMessageProcessor.h" #include "../lib/mapping/CMapInfo.h" #include "../lib/GameConstants.h" @@ -53,6 +53,7 @@ #include #include #include +#include #include "../lib/gameState/CGameState.h" @@ -165,6 +166,7 @@ CVCMIServer::CVCMIServer(boost::program_options::variables_map & opts) networkHandler = INetworkHandler::createHandler(); networkServer = networkHandler->createServerTCP(*this); networkServer->start(port); + establishOutgoingConnection(); logNetwork->info("Listening for connections at port %d", port); } @@ -172,9 +174,6 @@ CVCMIServer::~CVCMIServer() = default; void CVCMIServer::onNewConnection(const std::shared_ptr & connection) { - if (activeConnections.empty()) - establishOutgoingConnection(); - if(state == EServerState::LOBBY) { activeConnections.push_back(std::make_shared(connection)); @@ -195,16 +194,6 @@ void CVCMIServer::onPacketReceived(const std::shared_ptr & c pack->visit(visitor); } -void CVCMIServer::onConnectionFailed(const std::string & errorMessage) -{ - //TODO: handle failure to connect to lobby -} - -void CVCMIServer::onConnectionEstablished(const std::shared_ptr &) -{ - //TODO: handle connection to lobby - login? -} - void CVCMIServer::setState(EServerState value) { state = value; @@ -262,14 +251,8 @@ void CVCMIServer::onTimer() void CVCMIServer::establishOutgoingConnection() { - if(!cmdLineOptions.count("lobby")) - return; - - std::string hostname = settings["lobby"]["hostname"].String(); - int16_t port = settings["lobby"]["port"].Integer(); - - outgoingConnection = networkHandler->createClientTCP(*this); - outgoingConnection->start(hostname, port); + if(cmdLineOptions.count("lobby")) + lobbyProcessor = std::make_unique(*this); } void CVCMIServer::prepareToRestart() diff --git a/server/CVCMIServer.h b/server/CVCMIServer.h index 346d135d7..91d1c3553 100644 --- a/server/CVCMIServer.h +++ b/server/CVCMIServer.h @@ -37,6 +37,7 @@ VCMI_LIB_NAMESPACE_END class CGameHandler; class CBaseForServerApply; class CBaseForGHApply; +class GlobalLobbyProcessor; enum class EServerState : ui8 { @@ -47,15 +48,11 @@ enum class EServerState : ui8 SHUTDOWN }; -class CVCMIServer : public LobbyInfo, public INetworkServerListener, public INetworkClientListener, public INetworkTimerListener +class CVCMIServer : public LobbyInfo, public INetworkServerListener, public INetworkTimerListener { - std::unique_ptr networkHandler; - /// Network server instance that receives and processes incoming connections on active socket std::unique_ptr networkServer; - - /// Outgoing connection established by this server to game lobby for proxy mode (only in lobby game) - std::unique_ptr outgoingConnection; + std::unique_ptr lobbyProcessor; std::chrono::steady_clock::time_point gameplayStartTime; std::chrono::steady_clock::time_point lastTimerUpdateTime; @@ -64,6 +61,8 @@ public: /// List of all active connections std::vector> activeConnections; + std::unique_ptr networkHandler; + private: bool restartGameplay; // FIXME: this is just a hack @@ -75,8 +74,6 @@ private: void onDisconnected(const std::shared_ptr & connection) override; void onPacketReceived(const std::shared_ptr & connection, const std::vector & message) override; void onNewConnection(const std::shared_ptr &) override; - void onConnectionFailed(const std::string & errorMessage) override; - void onConnectionEstablished(const std::shared_ptr &) override; void onTimer() override; void establishOutgoingConnection(); diff --git a/server/GlobalLobbyProcessor.cpp b/server/GlobalLobbyProcessor.cpp new file mode 100644 index 000000000..5138f1b61 --- /dev/null +++ b/server/GlobalLobbyProcessor.cpp @@ -0,0 +1,82 @@ +/* + * GlobalLobbyProcessor.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 "GlobalLobbyProcessor.h" + +#include "CVCMIServer.h" +#include "../lib/CConfigHandler.h" + +GlobalLobbyProcessor::GlobalLobbyProcessor(CVCMIServer & owner) + : owner(owner) + , networkClient(owner.networkHandler->createClientTCP(*this)) +{ + std::string hostname = settings["lobby"]["hostname"].String(); + int16_t port = settings["lobby"]["port"].Integer(); + networkClient->start(hostname, port); + logGlobal->info("Connecting to lobby server"); +} + +void GlobalLobbyProcessor::onDisconnected(const std::shared_ptr & connection) +{ + throw std::runtime_error("Lost connection to a lobby server!"); +} + +void GlobalLobbyProcessor::onPacketReceived(const std::shared_ptr & connection, const std::vector & message) +{ + JsonNode json(message.data(), message.size()); + + if(json["type"].String() == "loginFailed") + return receiveLoginFailed(json); + + if(json["type"].String() == "loginSuccess") + return receiveLoginSuccess(json); + + throw std::runtime_error("Received unexpected message from lobby server: " + json["type"].String()); +} + +void GlobalLobbyProcessor::receiveLoginFailed(const JsonNode & json) +{ + 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"); +} + +void GlobalLobbyProcessor::onConnectionFailed(const std::string & errorMessage) +{ + throw std::runtime_error("Failed to connect to a lobby server!"); +} + +void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr &) +{ + logGlobal->info("Connection to lobby server established"); + + JsonNode toSend; + toSend["type"].String() = "serverLogin"; + toSend["accountID"] = settings["lobby"]["accountID"]; + toSend["accountCookie"] = settings["lobby"]["accountCookie"]; + sendMessage(toSend); +} + +void GlobalLobbyProcessor::sendMessage(const JsonNode & data) +{ + std::string payloadString = data.toJson(true); + + // FIXME: find better approach + uint8_t * payloadBegin = reinterpret_cast(payloadString.data()); + uint8_t * payloadEnd = payloadBegin + payloadString.size(); + + std::vector payloadBuffer(payloadBegin, payloadEnd); + + networkClient->sendPacket(payloadBuffer); +} diff --git a/server/GlobalLobbyProcessor.h b/server/GlobalLobbyProcessor.h new file mode 100644 index 000000000..530e59161 --- /dev/null +++ b/server/GlobalLobbyProcessor.h @@ -0,0 +1,39 @@ +/* + * GlobalLobbyProcessor.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 "../lib/network/NetworkInterface.h" + +VCMI_LIB_NAMESPACE_BEGIN +class JsonNode; +VCMI_LIB_NAMESPACE_END + +class CVCMIServer; + +class GlobalLobbyProcessor : public INetworkClientListener +{ + CVCMIServer & owner; + + std::shared_ptr controlConnection; +// std::set> proxyConnections; + std::unique_ptr networkClient; + + void onDisconnected(const std::shared_ptr & connection) override; + void onPacketReceived(const std::shared_ptr & connection, const std::vector & message) override; + void onConnectionFailed(const std::string & errorMessage) override; + void onConnectionEstablished(const std::shared_ptr &) override; + + void sendMessage(const JsonNode & data); + + void receiveLoginFailed(const JsonNode & json); + void receiveLoginSuccess(const JsonNode & json); +public: + GlobalLobbyProcessor(CVCMIServer & owner); +};