From ffa58152aca63d3a9a2419dbc7224de6937b5694 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 10 Jan 2024 15:31:11 +0200 Subject: [PATCH] Client-side support for hosting game server via lobby --- Mods/vcmi/config/vcmi/english.json | 14 ++ client/CMT.cpp | 42 ----- client/CMakeLists.txt | 2 + client/CServerHandler.cpp | 32 ++-- client/CServerHandler.h | 4 +- client/NetPacksLobbyClient.cpp | 9 ++ client/globalLobby/GlobalLobbyLoginWindow.cpp | 3 +- client/globalLobby/GlobalLobbyServerSetup.cpp | 144 ++++++++++++++++++ client/globalLobby/GlobalLobbyServerSetup.h | 49 ++++++ client/globalLobby/GlobalLobbyWindow.cpp | 3 + client/mainmenu/CMainMenu.cpp | 11 +- config/schemas/settings.json | 17 ++- config/widgets/lobbyWindow.json | 42 ++--- server/CVCMIServer.cpp | 19 +-- 14 files changed, 283 insertions(+), 108 deletions(-) create mode 100644 client/globalLobby/GlobalLobbyServerSetup.cpp create mode 100644 client/globalLobby/GlobalLobbyServerSetup.h diff --git a/Mods/vcmi/config/vcmi/english.json b/Mods/vcmi/config/vcmi/english.json index 1431dab4d..5d88ee8ad 100644 --- a/Mods/vcmi/config/vcmi/english.json +++ b/Mods/vcmi/config/vcmi/english.json @@ -77,6 +77,20 @@ "vcmi.lobby.login.connecting" : "Connecting...", "vcmi.lobby.login.error" : "Connection error: %s", + "vcmi.lobby.room.create" : "Create Room", + "vcmi.lobby.room.players.limit" : "Players Limit", + "vcmi.lobby.room.public" : "Public", + "vcmi.lobby.room.private" : "Private", + "vcmi.lobby.room.description.public" : "Any player can join public room.", + "vcmi.lobby.room.description.private" : "Only invited players can join private room.", + "vcmi.lobby.room.description.new" : "To start the game, select a scenario or set up a random map.", + "vcmi.lobby.room.description.load" : "To start the game, use one of your saved games.", + "vcmi.lobby.room.description.limit" : "Up to %d players can enter your room, including you.", + "vcmi.lobby.room.new" : "New Game", + "vcmi.lobby.room.load" : "Load Game", + "vcmi.lobby.room.type" : "Room Type", + "vcmi.lobby.room.mode" : "Game Mode", + "vcmi.client.errors.missingCampaigns" : "{Missing data files}\n\nCampaigns data files were not found! You may be using incomplete or corrupted Heroes 3 data files. Please reinstall game data.", "vcmi.server.errors.existingProcess" : "Another VCMI server process is running. Please terminate it before starting a new game.", "vcmi.server.errors.modsToEnable" : "{Following mods are required}", diff --git a/client/CMT.cpp b/client/CMT.cpp index 05cab7883..32f5b3f35 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -139,14 +139,6 @@ int main(int argc, char * argv[]) ("donotstartserver,d","do not attempt to start server and just connect to it instead server") ("serverport", po::value(), "override port specified in config file") ("savefrequency", po::value(), "limit auto save creation to each N days") - ("lobby", "parameters address, port, uuid to connect ro remote lobby session") - ("lobby-address", po::value(), "address to remote lobby") - ("lobby-port", po::value(), "port to remote lobby") - ("lobby-host", "if this client hosts session") - ("lobby-uuid", po::value(), "uuid to the server") - ("lobby-connections", po::value(), "connections of server") - ("lobby-username", po::value(), "player name") - ("lobby-gamemode", po::value(), "use 0 for new game and 1 for load game") ("uuid", po::value(), "uuid for the client"); if(argc > 1) @@ -371,40 +363,6 @@ int main(int argc, char * argv[]) } std::vector names; - session["lobby"].Bool() = false; - if(vm.count("lobby")) - { - session["lobby"].Bool() = true; - session["host"].Bool() = false; - session["address"].String() = vm["lobby-address"].as(); - if(vm.count("lobby-username")) - session["username"].String() = vm["lobby-username"].as(); - else - session["username"].String() = settings["launcher"]["lobbyUsername"].String(); - if(vm.count("lobby-gamemode")) - session["gamemode"].Integer() = vm["lobby-gamemode"].as(); - else - session["gamemode"].Integer() = 0; - CSH->uuid = vm["uuid"].as(); - session["port"].Integer() = vm["lobby-port"].as(); - logGlobal->info("Remote lobby mode at %s:%d, uuid is %s", session["address"].String(), session["port"].Integer(), CSH->uuid); - if(vm.count("lobby-host")) - { - session["host"].Bool() = true; - session["hostConnections"].String() = std::to_string(vm["lobby-connections"].as()); - session["hostUuid"].String() = vm["lobby-uuid"].as(); - logGlobal->info("This client will host session, server uuid is %s", session["hostUuid"].String()); - } - - //we should not reconnect to previous game in online mode - Settings saveSession = settings.write["server"]["reconnect"]; - saveSession->Bool() = false; - - //start lobby immediately - names.push_back(session["username"].String()); - ESelectionScreen sscreen = session["gamemode"].Integer() == 0 ? ESelectionScreen::newGame : ESelectionScreen::loadGame; - CMM->openLobby(sscreen, session["host"].Bool(), &names, ELoadMode::MULTI); - } if(!settings["session"]["headless"].Bool()) { diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 7d00fee8c..507f6012b 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -97,6 +97,7 @@ set(client_SRCS globalLobby/GlobalLobbyClient.cpp globalLobby/GlobalLobbyLoginWindow.cpp + globalLobby/GlobalLobbyServerSetup.cpp globalLobby/GlobalLobbyWidget.cpp globalLobby/GlobalLobbyWindow.cpp @@ -277,6 +278,7 @@ set(client_HEADERS globalLobby/GlobalLobbyClient.h globalLobby/GlobalLobbyLoginWindow.h + globalLobby/GlobalLobbyServerSetup.h globalLobby/GlobalLobbyWidget.h globalLobby/GlobalLobbyWindow.h diff --git a/client/CServerHandler.cpp b/client/CServerHandler.cpp index 165c6f902..8983c9db1 100644 --- a/client/CServerHandler.cpp +++ b/client/CServerHandler.cpp @@ -182,7 +182,7 @@ GlobalLobbyClient & CServerHandler::getGlobalLobby() return *lobbyClient; } -void CServerHandler::startLocalServerAndConnect() +void CServerHandler::startLocalServerAndConnect(bool connectToLobby) { if(threadRunLocalServer) threadRunLocalServer->join(); @@ -191,14 +191,10 @@ void CServerHandler::startLocalServerAndConnect() #if defined(SINGLE_PROCESS_APP) boost::condition_variable cond; - std::vector args{"--uuid=" + uuid, "--port=" + std::to_string(getLocalPort())}; - if(settings["session"]["lobby"].Bool() && settings["session"]["host"].Bool()) - { - args.push_back("--lobby=" + settings["session"]["address"].String()); - args.push_back("--connections=" + settings["session"]["hostConnections"].String()); - args.push_back("--lobby-port=" + std::to_string(settings["session"]["port"].Integer())); - args.push_back("--lobby-uuid=" + settings["session"]["hostUuid"].String()); - } + std::vector args{"--port=" + std::to_string(getLocalPort())}; + if(connectToLobby) + args.push_back("--lobby"); + threadRunLocalServer = std::make_unique([&cond, args, this] { setThreadName("CVCMIServer"); CVCMIServer::create(&cond, args); @@ -211,7 +207,7 @@ void CServerHandler::startLocalServerAndConnect() envHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "startServer", true); } #else - threadRunLocalServer = std::make_unique(&CServerHandler::threadRunServer, this); //runs server executable; + threadRunLocalServer = std::make_unique(&CServerHandler::threadRunServer, this, connectToLobby); //runs server executable; #endif logNetwork->trace("Setting up thread calling server: %d ms", th->getDiff()); @@ -800,7 +796,7 @@ void CServerHandler::debugStartTest(std::string filename, bool save) if(settings["session"]["donotstartserver"].Bool()) connectToServer(getLocalHostname(), getLocalPort()); else - startLocalServerAndConnect(); + startLocalServerAndConnect(false); boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); @@ -916,22 +912,16 @@ void CServerHandler::visitForClient(CPackForClient & clientPack) client->handlePack(&clientPack); } -void CServerHandler::threadRunServer() +void CServerHandler::threadRunServer(bool connectToLobby) { #if !defined(VCMI_MOBILE) setThreadName("runServer"); const std::string logName = (VCMIDirs::get().userLogsPath() / "server_log.txt").string(); std::string comm = VCMIDirs::get().serverPath().string() + " --port=" + std::to_string(getLocalPort()) - + " --run-by-client" - + " --uuid=" + uuid; - if(settings["session"]["lobby"].Bool() && settings["session"]["host"].Bool()) - { - comm += " --lobby=" + settings["session"]["address"].String(); - comm += " --connections=" + settings["session"]["hostConnections"].String(); - comm += " --lobby-port=" + std::to_string(settings["session"]["port"].Integer()); - comm += " --lobby-uuid=" + settings["session"]["hostUuid"].String(); - } + + " --run-by-client"; + if(connectToLobby) + comm += " --lobby"; comm += " > \"" + logName + '\"'; logGlobal->info("Server command line: %s", comm); diff --git a/client/CServerHandler.h b/client/CServerHandler.h index bca2f4608..2d0ea27b3 100644 --- a/client/CServerHandler.h +++ b/client/CServerHandler.h @@ -94,7 +94,7 @@ class CServerHandler : public IServerAPI, public LobbyInfo, public INetworkClien std::shared_ptr highScoreCalc; void threadRunNetwork(); - void threadRunServer(); + void threadRunServer(bool connectToLobby); void onServerFinished(); void sendLobbyPack(const CPackForLobby & pack) const override; @@ -137,7 +137,7 @@ public: ~CServerHandler(); void resetStateForLobby(const StartInfo::EMode mode, const std::vector * names = nullptr); - void startLocalServerAndConnect(); + void startLocalServerAndConnect(bool connectToLobby); void connectToServer(const std::string & addr, const ui16 port); GlobalLobbyClient & getGlobalLobby(); diff --git a/client/NetPacksLobbyClient.cpp b/client/NetPacksLobbyClient.cpp index e28fb4682..578e28a1c 100644 --- a/client/NetPacksLobbyClient.cpp +++ b/client/NetPacksLobbyClient.cpp @@ -19,6 +19,7 @@ #include "lobby/ExtraOptionsTab.h" #include "lobby/SelectionTab.h" #include "lobby/CBonusSelection.h" +#include "globalLobby/GlobalLobbyWindow.h" #include "CServerHandler.h" #include "CGameInfo.h" @@ -40,12 +41,20 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon { handler.c->connectionID = pack.clientId; if(handler.mapToStart) + { handler.setMapInfo(handler.mapToStart); + } else if(!settings["session"]["headless"].Bool()) { if (GH.windows().topWindow()) GH.windows().popWindows(1); + while (!GH.windows().findWindows().empty()) + { + // if global lobby is open, pop all dialogs on top of it as well as lobby itself + GH.windows().popWindows(1); + } + GH.windows().createAndPushWindow(static_cast(handler.screenType)); } handler.state = EClientState::LOBBY; diff --git a/client/globalLobby/GlobalLobbyLoginWindow.cpp b/client/globalLobby/GlobalLobbyLoginWindow.cpp index 783cdb9ba..dce37c03a 100644 --- a/client/globalLobby/GlobalLobbyLoginWindow.cpp +++ b/client/globalLobby/GlobalLobbyLoginWindow.cpp @@ -66,7 +66,8 @@ void GlobalLobbyLoginWindow::onLogin() config->String() = inputUsername->getText(); labelStatus->setText(CGI->generaltexth->translate("vcmi.lobby.login.connecting")); - CSH->getGlobalLobby().connect(); + if (!CSH->getGlobalLobby().isConnected()) + CSH->getGlobalLobby().connect(); buttonClose->block(true); } diff --git a/client/globalLobby/GlobalLobbyServerSetup.cpp b/client/globalLobby/GlobalLobbyServerSetup.cpp new file mode 100644 index 000000000..d2f0f2ffd --- /dev/null +++ b/client/globalLobby/GlobalLobbyServerSetup.cpp @@ -0,0 +1,144 @@ +/* + * GlobalLobbyServerSetup.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 "GlobalLobbyServerSetup.h" + +#include "../gui/CGuiHandler.h" +#include "../widgets/TextControls.h" +#include "../widgets/Images.h" +#include "../widgets/Buttons.h" +#include "../CGameInfo.h" +#include "../CServerHandler.h" +#include "../mainmenu/CMainMenu.h" + +#include "../../lib/CGeneralTextHandler.h" +#include "../../lib/MetaString.h" +#include "../../lib/CConfigHandler.h" + +GlobalLobbyServerSetup::GlobalLobbyServerSetup() + : CWindowObject(BORDERED) +{ + OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; + + pos.w = 284; + pos.h = 340; + + background = std::make_shared(ImagePath::builtin("DiBoxBck"), Rect(0, 0, pos.w, pos.h)); + labelTitle = std::make_shared( pos.w / 2, 20, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.create")); + labelPlayerLimit = std::make_shared( pos.w / 2, 48, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.players.limit")); + labelRoomType = std::make_shared( pos.w / 2, 108, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.type")); + labelGameMode = std::make_shared( pos.w / 2, 158, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.mode")); + + togglePlayerLimit = std::make_shared(nullptr); + togglePlayerLimit->addToggle(2, std::make_shared(Point(10 + 39*0, 60), AnimationPath::builtin("RanNum2"), CButton::tooltip(), 0)); + togglePlayerLimit->addToggle(3, std::make_shared(Point(10 + 39*1, 60), AnimationPath::builtin("RanNum3"), CButton::tooltip(), 0)); + togglePlayerLimit->addToggle(4, std::make_shared(Point(10 + 39*2, 60), AnimationPath::builtin("RanNum4"), CButton::tooltip(), 0)); + togglePlayerLimit->addToggle(5, std::make_shared(Point(10 + 39*3, 60), AnimationPath::builtin("RanNum5"), CButton::tooltip(), 0)); + togglePlayerLimit->addToggle(6, std::make_shared(Point(10 + 39*4, 60), AnimationPath::builtin("RanNum6"), CButton::tooltip(), 0)); + togglePlayerLimit->addToggle(7, std::make_shared(Point(10 + 39*5, 60), AnimationPath::builtin("RanNum7"), CButton::tooltip(), 0)); + togglePlayerLimit->addToggle(8, std::make_shared(Point(10 + 39*6, 60), AnimationPath::builtin("RanNum8"), CButton::tooltip(), 0)); + togglePlayerLimit->setSelected(settings["lobby"]["roomPlayerLimit"].Integer()); + togglePlayerLimit->addCallback([this](int index){onPlayerLimitChanged(index);}); + + auto buttonPublic = std::make_shared(Point(10, 120), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0); + auto buttonPrivate = std::make_shared(Point(146, 120), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0); + buttonPublic->addTextOverlay(CGI->generaltexth->translate("vcmi.lobby.room.public"), EFonts::FONT_SMALL, Colors::YELLOW); + buttonPrivate->addTextOverlay(CGI->generaltexth->translate("vcmi.lobby.room.private"), EFonts::FONT_SMALL, Colors::YELLOW); + + toggleRoomType = std::make_shared(nullptr); + toggleRoomType->addToggle(0, buttonPublic); + toggleRoomType->addToggle(1, buttonPrivate); + toggleRoomType->setSelected(settings["lobby"]["roomType"].Integer()); + toggleRoomType->addCallback([this](int index){onRoomTypeChanged(index);}); + + auto buttonNewGame = std::make_shared(Point(10, 170), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0); + auto buttonLoadGame = std::make_shared(Point(146, 170), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0); + buttonNewGame->addTextOverlay(CGI->generaltexth->translate("vcmi.lobby.room.new"), EFonts::FONT_SMALL, Colors::YELLOW); + buttonLoadGame->addTextOverlay(CGI->generaltexth->translate("vcmi.lobby.room.load"), EFonts::FONT_SMALL, Colors::YELLOW); + + toggleGameMode = std::make_shared(nullptr); + toggleGameMode->addToggle(0, buttonNewGame); + toggleGameMode->addToggle(1, buttonLoadGame); + toggleGameMode->setSelected(settings["lobby"]["roomMode"].Integer()); + toggleGameMode->addCallback([this](int index){onGameModeChanged(index);}); + + labelDescription = std::make_shared("", Rect(10, 195, pos.w - 20, 80), 1, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE); + + buttonCreate = std::make_shared(Point(10, 300), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this](){ onCreate(); }); + buttonClose = std::make_shared(Point(210, 300), AnimationPath::builtin("MuBcanc"), CButton::tooltip(), [this](){ onClose(); }); + + background->playerColored(PlayerColor(1)); + + updateDescription(); + center(); +} + +void GlobalLobbyServerSetup::updateDescription() +{ + MetaString description; + description.appendRawString("%s %s %s"); + if (toggleRoomType->getSelected() == 0) + description.replaceTextID("vcmi.lobby.room.description.public"); + else + description.replaceTextID("vcmi.lobby.room.description.private"); + + if (toggleGameMode->getSelected() == 0) + description.replaceTextID("vcmi.lobby.room.description.new"); + else + description.replaceTextID("vcmi.lobby.room.description.load"); + + description.replaceTextID("vcmi.lobby.room.description.limit"); + description.replaceNumber(togglePlayerLimit->getSelected()); + + labelDescription->setText(description.toString()); +} + +void GlobalLobbyServerSetup::onPlayerLimitChanged(int value) +{ + Settings config = settings.write["lobby"]["roomPlayerLimit"]; + config->Integer() = value; + updateDescription(); +} + +void GlobalLobbyServerSetup::onRoomTypeChanged(int value) +{ + Settings config = settings.write["lobby"]["roomType"]; + config->Integer() = value; + updateDescription(); +} + +void GlobalLobbyServerSetup::onGameModeChanged(int value) +{ + Settings config = settings.write["lobby"]["roomMode"]; + config->Integer() = value; + updateDescription(); +} + +void GlobalLobbyServerSetup::onCreate() +{ + if (toggleGameMode->getSelected() == 0) + { + CSH->resetStateForLobby(StartInfo::NEW_GAME, nullptr); + CSH->screenType = ESelectionScreen::newGame; + } + else + { + CSH->resetStateForLobby(StartInfo::LOAD_GAME, nullptr); + CSH->screenType = ESelectionScreen::loadGame; + } + CSH->loadMode = ELoadMode::MULTI; + CSH->startLocalServerAndConnect(true); +} + +void GlobalLobbyServerSetup::onClose() +{ + close(); +} diff --git a/client/globalLobby/GlobalLobbyServerSetup.h b/client/globalLobby/GlobalLobbyServerSetup.h new file mode 100644 index 000000000..7f49bb130 --- /dev/null +++ b/client/globalLobby/GlobalLobbyServerSetup.h @@ -0,0 +1,49 @@ +/* + * GlobalLobbyServerSetup.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 CLabel; +class CTextBox; +class FilledTexturePlayerColored; +class CButton; +class CToggleGroup; + +class GlobalLobbyServerSetup : public CWindowObject +{ + std::shared_ptr background; + std::shared_ptr labelTitle; + + std::shared_ptr labelPlayerLimit; + std::shared_ptr labelRoomType; + std::shared_ptr labelGameMode; + + std::shared_ptr togglePlayerLimit; // 2-8 + std::shared_ptr toggleRoomType; // public or private + std::shared_ptr toggleGameMode; // new game or load game + + std::shared_ptr labelDescription; + std::shared_ptr labelStatus; + + std::shared_ptr buttonCreate; + std::shared_ptr buttonClose; + + void updateDescription(); + void onPlayerLimitChanged(int value); + void onRoomTypeChanged(int value); + void onGameModeChanged(int value); + + void onCreate(); + void onClose(); + +public: + GlobalLobbyServerSetup(); +}; diff --git a/client/globalLobby/GlobalLobbyWindow.cpp b/client/globalLobby/GlobalLobbyWindow.cpp index c4b5f7fb0..9f91d0ccc 100644 --- a/client/globalLobby/GlobalLobbyWindow.cpp +++ b/client/globalLobby/GlobalLobbyWindow.cpp @@ -13,8 +13,10 @@ #include "GlobalLobbyWidget.h" #include "GlobalLobbyClient.h" +#include "GlobalLobbyServerSetup.h" #include "../gui/CGuiHandler.h" +#include "../gui/WindowHandler.h" #include "../widgets/TextControls.h" #include "../CServerHandler.h" @@ -47,6 +49,7 @@ void GlobalLobbyWindow::doSendChatMessage() void GlobalLobbyWindow::doCreateGameRoom() { + GH.windows().createAndPushWindow(); // TODO: // start local server and supply our UUID / client credentials to it // server logs into lobby ( uuid = client, mode = server ). This creates 'room' in mode 'empty' diff --git a/client/mainmenu/CMainMenu.cpp b/client/mainmenu/CMainMenu.cpp index c7e3fdcb5..911fe7f25 100644 --- a/client/mainmenu/CMainMenu.cpp +++ b/client/mainmenu/CMainMenu.cpp @@ -458,10 +458,11 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType) playerName->setText(getPlayerName()); playerName->cb += std::bind(&CMultiMode::onNameChange, this, _1); - buttonHotseat = std::make_shared(Point(373, 78), AnimationPath::builtin("MUBHOT.DEF"), CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this)); - buttonHost = std::make_shared(Point(373, 78 + 57 * 1), AnimationPath::builtin("MUBHOST.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.hostTCP"), ""), std::bind(&CMultiMode::hostTCP, this)); - buttonJoin = std::make_shared(Point(373, 78 + 57 * 2), AnimationPath::builtin("MUBJOIN.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.joinTCP"), ""), std::bind(&CMultiMode::joinTCP, this)); - buttonLobby = std::make_shared(Point(373, 78 + 57 * 4), AnimationPath::builtin("MUBONL.DEF"), CGI->generaltexth->zelp[265], std::bind(&CMultiMode::openLobby, this)); + buttonHotseat = std::make_shared(Point(373, 78 + 57 * 0), AnimationPath::builtin("MUBHOT.DEF"), CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this)); + buttonLobby = std::make_shared(Point(373, 78 + 57 * 1), AnimationPath::builtin("MUBONL.DEF"), CGI->generaltexth->zelp[265], std::bind(&CMultiMode::openLobby, this)); + + buttonHost = std::make_shared(Point(373, 78 + 57 * 3), AnimationPath::builtin("MUBHOST.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.hostTCP"), ""), std::bind(&CMultiMode::hostTCP, this)); + buttonJoin = std::make_shared(Point(373, 78 + 57 * 4), AnimationPath::builtin("MUBJOIN.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.joinTCP"), ""), std::bind(&CMultiMode::joinTCP, this)); buttonCancel = std::make_shared(Point(373, 424), AnimationPath::builtin("MUBCANC.DEF"), CGI->generaltexth->zelp[288], [=](){ close();}, EShortcut::GLOBAL_CANCEL); } @@ -617,7 +618,7 @@ void CSimpleJoinScreen::startConnection(const std::string & addr, ui16 port) #endif if(addr.empty()) - CSH->startLocalServerAndConnect(); + CSH->startLocalServerAndConnect(false); else CSH->connectToServer(addr, port); } diff --git a/config/schemas/settings.json b/config/schemas/settings.json index 73d7b6df6..daf7cb301 100644 --- a/config/schemas/settings.json +++ b/config/schemas/settings.json @@ -553,7 +553,7 @@ "type" : "object", "additionalProperties" : false, "default" : {}, - "required" : [ "mapPreview", "accountID", "accountCookie", "displayName", "hostname", "port" ], + "required" : [ "mapPreview", "accountID", "accountCookie", "displayName", "hostname", "port", "roomPlayerLimit", "roomType", "roomMode" ], "properties" : { "mapPreview" : { "type" : "boolean", @@ -583,6 +583,21 @@ "type" : "number", "default" : 30303 }, + + "roomPlayerLimit" : { + "type" : "number", + "default" : 2 + }, + + "roomType" : { + "type" : "number", + "default" : 0 + }, + + "roomMode" : { + "type" : "number", + "default" : 0 + }, } }, "gameTweaks" : { diff --git a/config/widgets/lobbyWindow.json b/config/widgets/lobbyWindow.json index 2b81f3dbe..dfbf90d00 100644 --- a/config/widgets/lobbyWindow.json +++ b/config/widgets/lobbyWindow.json @@ -58,7 +58,7 @@ { "type": "areaFilled", - "rect": {"x": 5, "y": 210, "w": 250, "h": 310} + "rect": {"x": 5, "y": 210, "w": 250, "h": 340} }, { "type": "labelTitle", @@ -115,6 +115,24 @@ "text" : "Player List" }, + { + "type": "button", + "position": {"x": 840, "y": 10}, + "image": "settingsWindow/button80", + "help": "core.help.288", + "callback": "closeWindow", + "items": + [ + { + "type": "label", + "font": "medium", + "alignment": "center", + "color": "yellow", + "text": "Leave" + } + ] + }, + { "type": "button", "position": {"x": 940, "y": 10}, @@ -129,7 +147,7 @@ "font": "medium", "alignment": "center", "color": "yellow", - "text": "Exit" + "text": "Close" } ] }, @@ -153,24 +171,6 @@ ] }, - { - "type": "button", - "position": {"x": 10, "y": 520}, - "image": "settingsWindow/button190", - "help": "core.help.288", - "callback": "createGameRoom", - "items": - [ - { - "type": "label", - "font": "medium", - "alignment": "center", - "color": "yellow", - "text": "Start Public Game" - } - ] - }, - { "type": "button", "position": {"x": 10, "y": 555}, @@ -184,7 +184,7 @@ "font": "medium", "alignment": "center", "color": "yellow", - "text": "Start Private Game" + "text": "Create Room" } ] }, diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index 2f22b4c80..bb677deae 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -266,17 +266,11 @@ void CVCMIServer::establishOutgoingConnection() if(!cmdLineOptions.count("lobby")) return; - uuid = cmdLineOptions["lobby-uuid"].as(); - auto address = cmdLineOptions["lobby"].as(); - int port = cmdLineOptions["lobby-port"].as(); - logNetwork->info("Establishing connection to remote at %s:%d with uuid %s", address, port, uuid); + std::string hostname = settings["lobby"]["hostname"].String(); + int16_t port = settings["lobby"]["port"].Integer(); outgoingConnection = std::make_unique(*this); - - outgoingConnection->start(address, port);//, SERVER_NAME, uuid); - -// connections.insert(c); -// remoteConnections.insert(c); + outgoingConnection->start(hostname, port); } void CVCMIServer::prepareToRestart() @@ -1004,12 +998,7 @@ static void handleCommandOptions(int argc, const char * argv[], boost::program_o ("help,h", "display help and exit") ("version,v", "display version information and exit") ("run-by-client", "indicate that server launched by client on same machine") - ("uuid", po::value(), "") - ("port", po::value(), "port at which server will listen to connections from client") - ("lobby", po::value(), "address to remote lobby") - ("lobby-port", po::value(), "port at which server connect to remote lobby") - ("lobby-uuid", po::value(), "") - ("connections", po::value(), "amount of connections to remote lobby"); + ("port", po::value(), "port at which server will listen to connections from client"); if(argc > 1) {