1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
/*
* ServerRunner.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 "ServerRunner.h"
#include "../lib/VCMIDirs.h"
#include "../lib/CThreadHelper.h"
#include "../lib/network/NetworkInterface.h"
#include "../lib/CConfigHandler.h"
#include "../server/CVCMIServer.h"
#ifdef ENABLE_SERVER_PROCESS
#if BOOST_VERSION >= 108600
// TODO: upgrade code to use v2 API instead of deprecated v1
#include <boost/process/v1/child.hpp>
#include <boost/process/v1/io.hpp>
#else
#include <boost/process/child.hpp>
#include <boost/process/io.hpp>
#endif
#endif
#include <future>
ServerThreadRunner::ServerThreadRunner() = default;
ServerThreadRunner::~ServerThreadRunner() = default;
void ServerThreadRunner::start(bool listenForConnections, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo)
{
// cfgport may be 0 -- the real port is returned after calling prepare()
uint16_t port = settings["server"]["localPort"].Integer();
server = std::make_unique<CVCMIServer>(port, true);
lobbyMode = connectToLobby;
if (startingInfo)
{
server->si = startingInfo; //Else use default
}
std::promise<uint16_t> promise;
threadRunLocalServer = std::thread([this, connectToLobby, listenForConnections, &promise]{
setThreadName("runServer");
uint16_t port = server->prepare(connectToLobby, listenForConnections);
promise.set_value(port);
server->run();
});
logNetwork->trace("Waiting for server port...");
serverPort = promise.get_future().get();
logNetwork->debug("Server port: %d", serverPort);
}
void ServerThreadRunner::shutdown()
{
server->setState(EServerState::SHUTDOWN);
}
void ServerThreadRunner::wait()
{
threadRunLocalServer.join();
}
int ServerThreadRunner::exitCode()
{
return 0;
}
void ServerThreadRunner::connect(INetworkHandler & network, INetworkClientListener & listener)
{
if (lobbyMode)
{
std::string host = settings["server"]["localHostname"].String();
uint16_t port = settings["server"]["localPort"].Integer();
logNetwork->info("Establishing connection to %s:%d...", host, port);
network.connectToRemote(listener, host, port);
}
else
{
network.createInternalConnection(listener, server->getNetworkServer());
}
}
#ifdef ENABLE_SERVER_PROCESS
ServerProcessRunner::ServerProcessRunner() = default;
ServerProcessRunner::~ServerProcessRunner() = default;
void ServerProcessRunner::shutdown()
{
child->terminate();
}
void ServerProcessRunner::wait()
{
child->wait();
}
int ServerProcessRunner::exitCode()
{
return child->exit_code();
}
void ServerProcessRunner::start(bool listenForConnections, bool connectToLobby, std::shared_ptr<StartInfo> startingInfo)
{
uint16_t port = settings["server"]["localPort"].Integer();
boost::filesystem::path serverPath = VCMIDirs::get().serverPath();
boost::filesystem::path logPath = VCMIDirs::get().userLogsPath() / "server_log.txt";
std::vector<std::string> args;
args.push_back("--port=" + std::to_string(port));
args.push_back("--run-by-client");
if(connectToLobby)
args.push_back("--lobby");
std::error_code ec;
child = std::make_unique<boost::process::child>(serverPath, args, ec, boost::process::std_out > logPath);
if (ec)
throw std::runtime_error("Failed to start server! Reason: " + ec.message());
}
void ServerProcessRunner::connect(INetworkHandler & network, INetworkClientListener & listener)
{
std::string host = settings["server"]["localHostname"].String();
uint16_t port = settings["server"]["localPort"].Integer();
logNetwork->info("Establishing connection to %s:%d...", host, port);
network.connectToRemote(listener, host, port);
}
#endif
|