1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Client-side support for hosting game server via lobby

This commit is contained in:
Ivan Savenko
2024-01-10 15:31:11 +02:00
parent 47f72af556
commit ffa58152ac
14 changed files with 283 additions and 108 deletions

View File

@@ -77,6 +77,20 @@
"vcmi.lobby.login.connecting" : "Connecting...", "vcmi.lobby.login.connecting" : "Connecting...",
"vcmi.lobby.login.error" : "Connection error: %s", "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.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.existingProcess" : "Another VCMI server process is running. Please terminate it before starting a new game.",
"vcmi.server.errors.modsToEnable" : "{Following mods are required}", "vcmi.server.errors.modsToEnable" : "{Following mods are required}",

View File

@@ -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") ("donotstartserver,d","do not attempt to start server and just connect to it instead server")
("serverport", po::value<si64>(), "override port specified in config file") ("serverport", po::value<si64>(), "override port specified in config file")
("savefrequency", po::value<si64>(), "limit auto save creation to each N days") ("savefrequency", po::value<si64>(), "limit auto save creation to each N days")
("lobby", "parameters address, port, uuid to connect ro remote lobby session")
("lobby-address", po::value<std::string>(), "address to remote lobby")
("lobby-port", po::value<ui16>(), "port to remote lobby")
("lobby-host", "if this client hosts session")
("lobby-uuid", po::value<std::string>(), "uuid to the server")
("lobby-connections", po::value<ui16>(), "connections of server")
("lobby-username", po::value<std::string>(), "player name")
("lobby-gamemode", po::value<ui16>(), "use 0 for new game and 1 for load game")
("uuid", po::value<std::string>(), "uuid for the client"); ("uuid", po::value<std::string>(), "uuid for the client");
if(argc > 1) if(argc > 1)
@@ -371,40 +363,6 @@ int main(int argc, char * argv[])
} }
std::vector<std::string> names; std::vector<std::string> names;
session["lobby"].Bool() = false;
if(vm.count("lobby"))
{
session["lobby"].Bool() = true;
session["host"].Bool() = false;
session["address"].String() = vm["lobby-address"].as<std::string>();
if(vm.count("lobby-username"))
session["username"].String() = vm["lobby-username"].as<std::string>();
else
session["username"].String() = settings["launcher"]["lobbyUsername"].String();
if(vm.count("lobby-gamemode"))
session["gamemode"].Integer() = vm["lobby-gamemode"].as<ui16>();
else
session["gamemode"].Integer() = 0;
CSH->uuid = vm["uuid"].as<std::string>();
session["port"].Integer() = vm["lobby-port"].as<ui16>();
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<ui16>());
session["hostUuid"].String() = vm["lobby-uuid"].as<std::string>();
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()) if(!settings["session"]["headless"].Bool())
{ {

View File

@@ -97,6 +97,7 @@ set(client_SRCS
globalLobby/GlobalLobbyClient.cpp globalLobby/GlobalLobbyClient.cpp
globalLobby/GlobalLobbyLoginWindow.cpp globalLobby/GlobalLobbyLoginWindow.cpp
globalLobby/GlobalLobbyServerSetup.cpp
globalLobby/GlobalLobbyWidget.cpp globalLobby/GlobalLobbyWidget.cpp
globalLobby/GlobalLobbyWindow.cpp globalLobby/GlobalLobbyWindow.cpp
@@ -277,6 +278,7 @@ set(client_HEADERS
globalLobby/GlobalLobbyClient.h globalLobby/GlobalLobbyClient.h
globalLobby/GlobalLobbyLoginWindow.h globalLobby/GlobalLobbyLoginWindow.h
globalLobby/GlobalLobbyServerSetup.h
globalLobby/GlobalLobbyWidget.h globalLobby/GlobalLobbyWidget.h
globalLobby/GlobalLobbyWindow.h globalLobby/GlobalLobbyWindow.h

View File

@@ -182,7 +182,7 @@ GlobalLobbyClient & CServerHandler::getGlobalLobby()
return *lobbyClient; return *lobbyClient;
} }
void CServerHandler::startLocalServerAndConnect() void CServerHandler::startLocalServerAndConnect(bool connectToLobby)
{ {
if(threadRunLocalServer) if(threadRunLocalServer)
threadRunLocalServer->join(); threadRunLocalServer->join();
@@ -191,14 +191,10 @@ void CServerHandler::startLocalServerAndConnect()
#if defined(SINGLE_PROCESS_APP) #if defined(SINGLE_PROCESS_APP)
boost::condition_variable cond; boost::condition_variable cond;
std::vector<std::string> args{"--uuid=" + uuid, "--port=" + std::to_string(getLocalPort())}; std::vector<std::string> args{"--port=" + std::to_string(getLocalPort())};
if(settings["session"]["lobby"].Bool() && settings["session"]["host"].Bool()) if(connectToLobby)
{ args.push_back("--lobby");
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());
}
threadRunLocalServer = std::make_unique<boost::thread>([&cond, args, this] { threadRunLocalServer = std::make_unique<boost::thread>([&cond, args, this] {
setThreadName("CVCMIServer"); setThreadName("CVCMIServer");
CVCMIServer::create(&cond, args); CVCMIServer::create(&cond, args);
@@ -211,7 +207,7 @@ void CServerHandler::startLocalServerAndConnect()
envHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "startServer", true); envHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "startServer", true);
} }
#else #else
threadRunLocalServer = std::make_unique<boost::thread>(&CServerHandler::threadRunServer, this); //runs server executable; threadRunLocalServer = std::make_unique<boost::thread>(&CServerHandler::threadRunServer, this, connectToLobby); //runs server executable;
#endif #endif
logNetwork->trace("Setting up thread calling server: %d ms", th->getDiff()); 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()) if(settings["session"]["donotstartserver"].Bool())
connectToServer(getLocalHostname(), getLocalPort()); connectToServer(getLocalHostname(), getLocalPort());
else else
startLocalServerAndConnect(); startLocalServerAndConnect(false);
boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
@@ -916,22 +912,16 @@ void CServerHandler::visitForClient(CPackForClient & clientPack)
client->handlePack(&clientPack); client->handlePack(&clientPack);
} }
void CServerHandler::threadRunServer() void CServerHandler::threadRunServer(bool connectToLobby)
{ {
#if !defined(VCMI_MOBILE) #if !defined(VCMI_MOBILE)
setThreadName("runServer"); setThreadName("runServer");
const std::string logName = (VCMIDirs::get().userLogsPath() / "server_log.txt").string(); const std::string logName = (VCMIDirs::get().userLogsPath() / "server_log.txt").string();
std::string comm = VCMIDirs::get().serverPath().string() std::string comm = VCMIDirs::get().serverPath().string()
+ " --port=" + std::to_string(getLocalPort()) + " --port=" + std::to_string(getLocalPort())
+ " --run-by-client" + " --run-by-client";
+ " --uuid=" + uuid; if(connectToLobby)
if(settings["session"]["lobby"].Bool() && settings["session"]["host"].Bool()) comm += " --lobby";
{
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();
}
comm += " > \"" + logName + '\"'; comm += " > \"" + logName + '\"';
logGlobal->info("Server command line: %s", comm); logGlobal->info("Server command line: %s", comm);

View File

@@ -94,7 +94,7 @@ class CServerHandler : public IServerAPI, public LobbyInfo, public INetworkClien
std::shared_ptr<HighScoreCalculation> highScoreCalc; std::shared_ptr<HighScoreCalculation> highScoreCalc;
void threadRunNetwork(); void threadRunNetwork();
void threadRunServer(); void threadRunServer(bool connectToLobby);
void onServerFinished(); void onServerFinished();
void sendLobbyPack(const CPackForLobby & pack) const override; void sendLobbyPack(const CPackForLobby & pack) const override;
@@ -137,7 +137,7 @@ public:
~CServerHandler(); ~CServerHandler();
void resetStateForLobby(const StartInfo::EMode mode, const std::vector<std::string> * names = nullptr); void resetStateForLobby(const StartInfo::EMode mode, const std::vector<std::string> * names = nullptr);
void startLocalServerAndConnect(); void startLocalServerAndConnect(bool connectToLobby);
void connectToServer(const std::string & addr, const ui16 port); void connectToServer(const std::string & addr, const ui16 port);
GlobalLobbyClient & getGlobalLobby(); GlobalLobbyClient & getGlobalLobby();

View File

@@ -19,6 +19,7 @@
#include "lobby/ExtraOptionsTab.h" #include "lobby/ExtraOptionsTab.h"
#include "lobby/SelectionTab.h" #include "lobby/SelectionTab.h"
#include "lobby/CBonusSelection.h" #include "lobby/CBonusSelection.h"
#include "globalLobby/GlobalLobbyWindow.h"
#include "CServerHandler.h" #include "CServerHandler.h"
#include "CGameInfo.h" #include "CGameInfo.h"
@@ -40,12 +41,20 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon
{ {
handler.c->connectionID = pack.clientId; handler.c->connectionID = pack.clientId;
if(handler.mapToStart) if(handler.mapToStart)
{
handler.setMapInfo(handler.mapToStart); handler.setMapInfo(handler.mapToStart);
}
else if(!settings["session"]["headless"].Bool()) else if(!settings["session"]["headless"].Bool())
{ {
if (GH.windows().topWindow<CSimpleJoinScreen>()) if (GH.windows().topWindow<CSimpleJoinScreen>())
GH.windows().popWindows(1); GH.windows().popWindows(1);
while (!GH.windows().findWindows<GlobalLobbyWindow>().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<CLobbyScreen>(static_cast<ESelectionScreen>(handler.screenType)); GH.windows().createAndPushWindow<CLobbyScreen>(static_cast<ESelectionScreen>(handler.screenType));
} }
handler.state = EClientState::LOBBY; handler.state = EClientState::LOBBY;

View File

@@ -66,7 +66,8 @@ void GlobalLobbyLoginWindow::onLogin()
config->String() = inputUsername->getText(); 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(); if (!CSH->getGlobalLobby().isConnected())
CSH->getGlobalLobby().connect();
buttonClose->block(true); buttonClose->block(true);
} }

View File

@@ -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<FilledTexturePlayerColored>(ImagePath::builtin("DiBoxBck"), Rect(0, 0, pos.w, pos.h));
labelTitle = std::make_shared<CLabel>( pos.w / 2, 20, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.create"));
labelPlayerLimit = std::make_shared<CLabel>( pos.w / 2, 48, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.players.limit"));
labelRoomType = std::make_shared<CLabel>( pos.w / 2, 108, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.type"));
labelGameMode = std::make_shared<CLabel>( pos.w / 2, 158, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.mode"));
togglePlayerLimit = std::make_shared<CToggleGroup>(nullptr);
togglePlayerLimit->addToggle(2, std::make_shared<CToggleButton>(Point(10 + 39*0, 60), AnimationPath::builtin("RanNum2"), CButton::tooltip(), 0));
togglePlayerLimit->addToggle(3, std::make_shared<CToggleButton>(Point(10 + 39*1, 60), AnimationPath::builtin("RanNum3"), CButton::tooltip(), 0));
togglePlayerLimit->addToggle(4, std::make_shared<CToggleButton>(Point(10 + 39*2, 60), AnimationPath::builtin("RanNum4"), CButton::tooltip(), 0));
togglePlayerLimit->addToggle(5, std::make_shared<CToggleButton>(Point(10 + 39*3, 60), AnimationPath::builtin("RanNum5"), CButton::tooltip(), 0));
togglePlayerLimit->addToggle(6, std::make_shared<CToggleButton>(Point(10 + 39*4, 60), AnimationPath::builtin("RanNum6"), CButton::tooltip(), 0));
togglePlayerLimit->addToggle(7, std::make_shared<CToggleButton>(Point(10 + 39*5, 60), AnimationPath::builtin("RanNum7"), CButton::tooltip(), 0));
togglePlayerLimit->addToggle(8, std::make_shared<CToggleButton>(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<CToggleButton>(Point(10, 120), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0);
auto buttonPrivate = std::make_shared<CToggleButton>(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<CToggleGroup>(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<CToggleButton>(Point(10, 170), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0);
auto buttonLoadGame = std::make_shared<CToggleButton>(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<CToggleGroup>(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<CTextBox>("", Rect(10, 195, pos.w - 20, 80), 1, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE);
buttonCreate = std::make_shared<CButton>(Point(10, 300), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this](){ onCreate(); });
buttonClose = std::make_shared<CButton>(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();
}

View File

@@ -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<FilledTexturePlayerColored> background;
std::shared_ptr<CLabel> labelTitle;
std::shared_ptr<CLabel> labelPlayerLimit;
std::shared_ptr<CLabel> labelRoomType;
std::shared_ptr<CLabel> labelGameMode;
std::shared_ptr<CToggleGroup> togglePlayerLimit; // 2-8
std::shared_ptr<CToggleGroup> toggleRoomType; // public or private
std::shared_ptr<CToggleGroup> toggleGameMode; // new game or load game
std::shared_ptr<CTextBox> labelDescription;
std::shared_ptr<CTextBox> labelStatus;
std::shared_ptr<CButton> buttonCreate;
std::shared_ptr<CButton> buttonClose;
void updateDescription();
void onPlayerLimitChanged(int value);
void onRoomTypeChanged(int value);
void onGameModeChanged(int value);
void onCreate();
void onClose();
public:
GlobalLobbyServerSetup();
};

View File

@@ -13,8 +13,10 @@
#include "GlobalLobbyWidget.h" #include "GlobalLobbyWidget.h"
#include "GlobalLobbyClient.h" #include "GlobalLobbyClient.h"
#include "GlobalLobbyServerSetup.h"
#include "../gui/CGuiHandler.h" #include "../gui/CGuiHandler.h"
#include "../gui/WindowHandler.h"
#include "../widgets/TextControls.h" #include "../widgets/TextControls.h"
#include "../CServerHandler.h" #include "../CServerHandler.h"
@@ -47,6 +49,7 @@ void GlobalLobbyWindow::doSendChatMessage()
void GlobalLobbyWindow::doCreateGameRoom() void GlobalLobbyWindow::doCreateGameRoom()
{ {
GH.windows().createAndPushWindow<GlobalLobbyServerSetup>();
// TODO: // TODO:
// start local server and supply our UUID / client credentials to it // 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' // server logs into lobby ( uuid = client, mode = server ). This creates 'room' in mode 'empty'

View File

@@ -458,10 +458,11 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType)
playerName->setText(getPlayerName()); playerName->setText(getPlayerName());
playerName->cb += std::bind(&CMultiMode::onNameChange, this, _1); playerName->cb += std::bind(&CMultiMode::onNameChange, this, _1);
buttonHotseat = std::make_shared<CButton>(Point(373, 78), AnimationPath::builtin("MUBHOT.DEF"), CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this)); buttonHotseat = std::make_shared<CButton>(Point(373, 78 + 57 * 0), AnimationPath::builtin("MUBHOT.DEF"), CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this));
buttonHost = std::make_shared<CButton>(Point(373, 78 + 57 * 1), AnimationPath::builtin("MUBHOST.DEF"), CButton::tooltip(CGI->generaltexth->translate("vcmi.mainMenu.hostTCP"), ""), std::bind(&CMultiMode::hostTCP, this)); buttonLobby = std::make_shared<CButton>(Point(373, 78 + 57 * 1), AnimationPath::builtin("MUBONL.DEF"), CGI->generaltexth->zelp[265], std::bind(&CMultiMode::openLobby, this));
buttonJoin = std::make_shared<CButton>(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<CButton>(Point(373, 78 + 57 * 4), AnimationPath::builtin("MUBONL.DEF"), CGI->generaltexth->zelp[265], std::bind(&CMultiMode::openLobby, this)); buttonHost = std::make_shared<CButton>(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<CButton>(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<CButton>(Point(373, 424), AnimationPath::builtin("MUBCANC.DEF"), CGI->generaltexth->zelp[288], [=](){ close();}, EShortcut::GLOBAL_CANCEL); buttonCancel = std::make_shared<CButton>(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 #endif
if(addr.empty()) if(addr.empty())
CSH->startLocalServerAndConnect(); CSH->startLocalServerAndConnect(false);
else else
CSH->connectToServer(addr, port); CSH->connectToServer(addr, port);
} }

View File

@@ -553,7 +553,7 @@
"type" : "object", "type" : "object",
"additionalProperties" : false, "additionalProperties" : false,
"default" : {}, "default" : {},
"required" : [ "mapPreview", "accountID", "accountCookie", "displayName", "hostname", "port" ], "required" : [ "mapPreview", "accountID", "accountCookie", "displayName", "hostname", "port", "roomPlayerLimit", "roomType", "roomMode" ],
"properties" : { "properties" : {
"mapPreview" : { "mapPreview" : {
"type" : "boolean", "type" : "boolean",
@@ -583,6 +583,21 @@
"type" : "number", "type" : "number",
"default" : 30303 "default" : 30303
}, },
"roomPlayerLimit" : {
"type" : "number",
"default" : 2
},
"roomType" : {
"type" : "number",
"default" : 0
},
"roomMode" : {
"type" : "number",
"default" : 0
},
} }
}, },
"gameTweaks" : { "gameTweaks" : {

View File

@@ -58,7 +58,7 @@
{ {
"type": "areaFilled", "type": "areaFilled",
"rect": {"x": 5, "y": 210, "w": 250, "h": 310} "rect": {"x": 5, "y": 210, "w": 250, "h": 340}
}, },
{ {
"type": "labelTitle", "type": "labelTitle",
@@ -115,6 +115,24 @@
"text" : "Player List" "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", "type": "button",
"position": {"x": 940, "y": 10}, "position": {"x": 940, "y": 10},
@@ -129,7 +147,7 @@
"font": "medium", "font": "medium",
"alignment": "center", "alignment": "center",
"color": "yellow", "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", "type": "button",
"position": {"x": 10, "y": 555}, "position": {"x": 10, "y": 555},
@@ -184,7 +184,7 @@
"font": "medium", "font": "medium",
"alignment": "center", "alignment": "center",
"color": "yellow", "color": "yellow",
"text": "Start Private Game" "text": "Create Room"
} }
] ]
}, },

View File

@@ -266,17 +266,11 @@ void CVCMIServer::establishOutgoingConnection()
if(!cmdLineOptions.count("lobby")) if(!cmdLineOptions.count("lobby"))
return; return;
uuid = cmdLineOptions["lobby-uuid"].as<std::string>(); std::string hostname = settings["lobby"]["hostname"].String();
auto address = cmdLineOptions["lobby"].as<std::string>(); int16_t port = settings["lobby"]["port"].Integer();
int port = cmdLineOptions["lobby-port"].as<ui16>();
logNetwork->info("Establishing connection to remote at %s:%d with uuid %s", address, port, uuid);
outgoingConnection = std::make_unique<NetworkClient>(*this); outgoingConnection = std::make_unique<NetworkClient>(*this);
outgoingConnection->start(hostname, port);
outgoingConnection->start(address, port);//, SERVER_NAME, uuid);
// connections.insert(c);
// remoteConnections.insert(c);
} }
void CVCMIServer::prepareToRestart() void CVCMIServer::prepareToRestart()
@@ -1004,12 +998,7 @@ static void handleCommandOptions(int argc, const char * argv[], boost::program_o
("help,h", "display help and exit") ("help,h", "display help and exit")
("version,v", "display version information and exit") ("version,v", "display version information and exit")
("run-by-client", "indicate that server launched by client on same machine") ("run-by-client", "indicate that server launched by client on same machine")
("uuid", po::value<std::string>(), "") ("port", po::value<ui16>(), "port at which server will listen to connections from client");
("port", po::value<ui16>(), "port at which server will listen to connections from client")
("lobby", po::value<std::string>(), "address to remote lobby")
("lobby-port", po::value<ui16>(), "port at which server connect to remote lobby")
("lobby-uuid", po::value<std::string>(), "")
("connections", po::value<ui16>(), "amount of connections to remote lobby");
if(argc > 1) if(argc > 1)
{ {