1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Lobby works

This commit is contained in:
nordsoft 2022-11-08 04:44:34 +04:00
parent 7b6d9c23b3
commit 97e5fc8a07
10 changed files with 102 additions and 68 deletions

View File

@ -202,7 +202,13 @@ int main(int argc, char * argv[])
("serverport", po::value<si64>(), "override port specified in config file")
("saveprefix", po::value<std::string>(), "prefix for auto save files")
("savefrequency", po::value<si64>(), "limit auto save creation to each N days")
("lobby", po::value<std::array<std::string, 3>>(), "parameters to connect ro remote lobby session");
("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<std::string>(), "connections of server")
("uuid", po::value<std::string>(), "uuid for the client");
if(argc > 1)
{
@ -485,14 +491,20 @@ int main(int argc, char * argv[])
session["oneGoodAI"].Bool() = vm.count("oneGoodAI");
session["aiSolo"].Bool() = false;
session["lobby"] = false;
session["lobby"].Bool() = false;
if(vm.count("lobby"))
{
auto lobbyParams = vc["lobby"].as<std::array<std::string, 3>>();
session["lobby"].Bool() = true;
session["address"].String() = lobbyParams[0];
session["port"].Integer() = std::stoi(lobbyParams[1]);
session["uuid"].String() = lobbyParams[2];
session["host"].Bool() = false;
session["address"].String() = vm["lobby-address"].as<std::string>();
CSH->uuid = vm["uuid"].as<std::string>();
session["port"].Integer() = vm["lobby-port"].as<ui16>();
if(vm.count("lobby-host"))
{
session["host"].Bool() = true;
session["hostConnections"].String() = vm["lobby-connections"].as<std::string>();
session["hostUuid"].String() = vm["lobby-uuid"].as<std::string>();
}
}
if(vm.count("testmap"))

View File

@ -117,9 +117,9 @@ extern std::string NAME;
CServerHandler::CServerHandler()
: state(EClientState::NONE), mx(std::make_shared<boost::recursive_mutex>()), client(nullptr), loadMode(0), campaignStateToSend(nullptr), campaignServerRestartLock(false)
{
if(settings["server"]["uuid"].isNull() || settings["server"]["uuid"].String().empty())
uuid = boost::uuids::to_string(boost::uuids::random_generator()());
else
uuid = boost::uuids::to_string(boost::uuids::random_generator()());
//read from file to restore last session
if(!settings["server"]["uuid"].isNull() && !settings["server"]["uuid"].String().empty())
uuid = settings["server"]["uuid"].String();
applier = std::make_shared<CApplier<CBaseForLobbyApply>>();
registerTypesLobbyPacks(*applier);
@ -262,8 +262,8 @@ void CServerHandler::justConnectToServer(const std::string & addr, const ui16 po
{
logNetwork->info("Establishing connection...");
c = std::make_shared<CConnection>(
addr.size() ? addr : settings["server"]["server"].String(),
port ? port : getDefaultPort(),
addr.size() ? addr : getHostAddress(),
port ? port : getHostPort(),
NAME, uuid);
}
catch(...)
@ -281,12 +281,12 @@ void CServerHandler::justConnectToServer(const std::string & addr, const ui16 po
c->handler = std::make_shared<boost::thread>(&CServerHandler::threadHandleConnection, this);
if(!addr.empty() && addr != localhostAddress)
if(!addr.empty() && addr != getHostAddress())
{
Settings serverAddress = settings.write["server"]["server"];
serverAddress->String() = addr;
}
if(port && port != getDefaultPort())
if(port && port != getHostPort())
{
Settings serverPort = settings.write["server"]["port"];
serverPort->Integer() = port;
@ -369,6 +369,28 @@ std::string CServerHandler::getDefaultPortStr()
return boost::lexical_cast<std::string>(getDefaultPort());
}
std::string CServerHandler::getHostAddress() const
{
if(settings["session"]["lobby"].isNull() || !settings["session"]["lobby"].Bool())
return settings["server"]["server"].String();
if(settings["session"]["host"].Bool())
return localhostAddress;
return settings["session"]["address"].String();
}
ui16 CServerHandler::getHostPort() const
{
if(settings["session"]["lobby"].isNull() || !settings["session"]["lobby"].Bool())
return getDefaultPort();
if(settings["session"]["host"].Bool())
return getDefaultPort();
return settings["session"]["port"].Integer();
}
void CServerHandler::sendClientConnecting() const
{
LobbyClientConnected lcc;
@ -813,9 +835,17 @@ void CServerHandler::threadRunServer()
setThreadName("CServerHandler::threadRunServer");
const std::string logName = (VCMIDirs::get().userLogsPath() / "server_log.txt").string();
std::string comm = VCMIDirs::get().serverPath().string()
+ " --port=" + getDefaultPortStr()
+ " --port=" + boost::lexical_cast<std::string>(getHostPort())
+ " --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=" + boost::lexical_cast<std::string>(settings["session"]["port"].Integer());
comm += " --lobby-uuid=" + settings["session"]["hostUuid"].String();
}
if(shm)
{
comm += " --enable-shm";

View File

@ -111,6 +111,9 @@ public:
static const std::string localhostAddress;
CServerHandler();
std::string getHostAddress() const;
ui16 getHostPort() const;
void resetStateForLobby(const StartInfo::EMode mode, const std::vector<std::string> * names = nullptr);
void startLocalServerAndConnect();

View File

@ -481,8 +481,8 @@ CSimpleJoinScreen::CSimpleJoinScreen(bool host)
inputAddress->giveFocus();
}
inputAddress->setText(host ? CServerHandler::localhostAddress : settings["server"]["server"].String(), true);
inputPort->setText(CServerHandler::getDefaultPortStr(), true);
inputAddress->setText(host ? CServerHandler::localhostAddress : CSH->getHostAddress(), true);
inputPort->setText(boost::lexical_cast<std::string>(CSH->getHostPort()), true);
buttonCancel = std::make_shared<CButton>(Point(142, 142), "MUBCANC.DEF", CGI->generaltexth->zelp[561], std::bind(&CSimpleJoinScreen::leaveScreen, this), SDLK_ESCAPE);
statusBar = CGStatusBar::create(std::make_shared<CPicture>(Rect(7, 186, 218, 18), 0));

View File

@ -253,7 +253,7 @@
"type" : "object",
"additionalProperties" : false,
"default": {},
"required" : [ "server", "port", "serverport", "localInformation", "playerAI", "friendlyAI","neutralAI", "enemyAI", "reconnect", "uuid", "names", "lobby", "host" ],
"required" : [ "server", "port", "localInformation", "playerAI", "friendlyAI","neutralAI", "enemyAI", "reconnect", "uuid", "names" ],
"properties" : {
"server" : {
"type":"string",
@ -263,10 +263,6 @@
"type" : "number",
"default" : 3030
},
"serverport" : {
"type" : "number",
"default" : 5002
},
"localInformation" : {
"type" : "number",
"default" : 2
@ -295,20 +291,6 @@
"type" : "string",
"default" : ""
},
"host" : {
"type" : "object",
"additionalProperties" : false,
"default" :
{
"host" : true
},
"required" : [ "host", "uuid", "connections" ],
"properties" : {
"uuid" : { "type" : "string" },
"connections" : { "type" : "number" },
"host" : {"type" : "boolean", "default" : false}
}
},
"names" : {
"type" : "array",
"default" : [],
@ -317,10 +299,6 @@
"type" : "string",
"default" : ""
}
},
"lobby" : {
"type" : "boolean",
"default" : false
}
}
},
@ -435,7 +413,7 @@
},
"lobbyUrl" : {
"type" : "string",
"default" : "127.0.0.1"
"default" : "beholder.vcmi.eu"
},
"lobbyPort" : {
"type" : "number",

View File

@ -119,6 +119,10 @@ Lobby::Lobby(QWidget *parent) :
connect(&socketLobby, SIGNAL(text(QString)), this, SLOT(chatMessage(QString)));
connect(&socketLobby, SIGNAL(receive(QString)), this, SLOT(dispatchMessage(QString)));
connect(&socketLobby, SIGNAL(disconnect()), this, SLOT(onDisconnected()));
ui->hostEdit->setText(QString::fromStdString(settings["launcher"]["lobbyUrl"].String()));
ui->portEdit->setText(QString::number(settings["launcher"]["lobbyPort"].Integer()));
ui->userEdit->setText(QString::fromStdString(settings["launcher"]["lobbyUsername"].String()));
}
Lobby::~Lobby()
@ -209,17 +213,11 @@ void Lobby::serverCommand(const ServerCommand & command) try
case START: {
protocolAssert(args.size() == 1);
//actually start game
//Settings node = settings.write["server"];
gameArguments.clear();
gameArguments << "--lobby";
gameArguments << ui->hostEdit->text();
gameArguments << ui->portEdit->text();
gameArguments << args[0];
/*node["lobby"].Bool() = true;
node["server"].String() = ui->hostEdit->text().toStdString();
node["serverport"].Integer() = ui->portEdit->text().toInt();
node["uuid"].String() = args[0].toStdString();*/
startGame = true;
gameArgs << "--lobby";
gameArgs << "--lobby-address" << ui->hostEdit->text();
gameArgs << "--lobby-port" << ui->portEdit->text();
gameArgs << "--uuid" << args[0];
qobject_cast<MainWindow *>(qApp->activeWindow())->startGame(gameArgs);
//on_startGameButton_clicked
//node["names"].Vector().clear();
//node["names"].Vector().pushBack(username.toStdString());
@ -229,9 +227,9 @@ void Lobby::serverCommand(const ServerCommand & command) try
case HOST: {
protocolAssert(args.size() == 2);
Settings node = settings.write["server"]["host"];
node["uuid"].String() = args[0].toStdString();
node["connections"].Integer() = args[1].toInt();
gameArgs << "--lobby-host";
gameArgs << "--lobby-uuid" << args[0];
gameArgs << "--lobby-connections" << args[1];
break;
}
@ -267,9 +265,6 @@ void Lobby::dispatchMessage(QString txt) try
ServerCommand cmd(ctype, parseArgs);
serverCommand(cmd);
}
if(startGame)
qobject_cast<MainWindow *>(qApp->activeWindow())->startGame(gameArguments);
}
catch(const ProtocolError & e)
{

View File

@ -131,7 +131,7 @@ private:
QString session;
QString username;
bool startGame = false;
QStringList gameArguments;
QStringList gameArgs;
private:
void protocolAssert(bool);

View File

@ -122,8 +122,10 @@ void MainWindow::startGame(const QStringList & args)
const char * s = args[i].toLocal8Bit().constData();
__argv[i] = new char[strlen(s)];
strcpy(__argv[i], s);
}
logGlobal->warn("Starting game with the arguments: %s", args.join(" ").toStdString());
#ifdef Q_OS_IOS
qApp->quit();
#else

View File

@ -59,7 +59,7 @@ class Session:
protected = False # if True, password is required to join to the session
name: str # name of session
host: socket # player socket who created the session (lobby mode)
host_uuid: str # uuid of vcmiserver for hosting player
token: str # uuid of vcmiserver for hosting player
players = [] # list of sockets of players, joined to the session
connections = [] # list of GameConnections for vcmiclient (game mode)
started = False # True - game mode, False - lobby mode
@ -216,16 +216,21 @@ def dispatch(client: socket, sender: dict, arr: bytes):
if arr == None or len(arr) == 0:
return
print(f"[{sender['address']}] dispatching message")
#check for game mode connection
msg = str(arr)
if msg.find("Aiya!") != -1:
sender["pipe"] = True #switch to pipe mode
print(" vcmi recognized")
if sender["pipe"]:
if sender["game"]: #if already playing - sending raw bytes as is
sender["prevmessages"].append(arr)
print(" storing message")
else:
sender["prevmessages"].append(struct.pack('<I', len(arr)) + arr) #pack message
print(" packing message")
#search fo application type in the message
match = re.search(r"\((\w+)\)", msg)
_appType = ''
@ -235,12 +240,14 @@ def dispatch(client: socket, sender: dict, arr: bytes):
#extract uuid from message
_uuid = arr.decode()
print(f" decoding {_uuid}")
if not _uuid == '' and not sender["apptype"] == '':
#search for uuid
for session in sessions.values():
if session.started:
#verify uuid of connected application
if _uuid.find(session.host_uuid) != -1 and sender["apptype"] == "server":
print(f" apptype {sender['apptype']} uuid {_uuid}")
session.addConnection(client, True)
sender["session"] = session
sender["game"] = True
@ -248,11 +255,13 @@ def dispatch(client: socket, sender: dict, arr: bytes):
# this is workaround to send only one remaining byte
# WARNING: reversed byte order is not supported
sender["prevmessages"].append(client.recv(1))
print(f" binding server connection to session {session.name}")
return
if sender["apptype"] == "client":
for p in session.players:
if _uuid.find(client_sockets[p]["uuid"]) != -1:
print(f" apptype {sender['apptype']} uuid {_uuid}")
#client connection
session.addConnection(client, False)
sender["session"] = session
@ -261,10 +270,12 @@ def dispatch(client: socket, sender: dict, arr: bytes):
# this is workaround to send only one remaining byte
# WARNING: reversed byte order is not supported
sender["prevmessages"].append(client.recv(1))
print(f" binding client connection to session {session.name}")
break
#game mode
if sender["pipe"] and sender["game"] and sender["session"].validPipe(client):
print(f" pipe for {sender['session'].name}")
#send messages from queue
opposite = sender["session"].getPipe(client)
for x in client_sockets[opposite]["prevmessages"]:
@ -283,6 +294,7 @@ def dispatch(client: socket, sender: dict, arr: bytes):
#we are in pipe mode but game still not started - waiting other clients to connect
if sender["pipe"]:
print(f" waiting other clients")
return
#lobby mode

View File

@ -170,11 +170,9 @@ void CVCMIServer::run()
#endif
startAsyncAccept();
if(!remoteConnectionsThread && !settings["server"]["lobby"].isNull() && settings["server"]["lobby"].Bool())
if(!remoteConnectionsThread && cmdLineOptions.count("lobby"))
{
remoteConnectionsThread = vstd::make_unique<boost::thread>(&CVCMIServer::establishRemoteConnections, this);
Settings node = settings.write["server"]["lobby"];
node->Bool() = false;
}
#if defined(VCMI_ANDROID)
@ -203,10 +201,10 @@ void CVCMIServer::run()
void CVCMIServer::establishRemoteConnections()
{
uuid = settings["server"]["host"]["uuid"].String();
int numOfConnections = settings["server"]["host"]["connections"].Integer();
auto address = settings["server"]["server"].String();
int port = settings["server"]["serverport"].Integer();
uuid = cmdLineOptions["lobby-uuid"].as<std::string>();
int numOfConnections = cmdLineOptions["connections"].as<ui8>();
auto address = cmdLineOptions["lobby"].as<std::string>();
int port = cmdLineOptions["lobby-port"].as<ui16>();
for(int i = 0; i < numOfConnections; ++i)
connectToRemote(address, port);
@ -1001,7 +999,11 @@ static void handleCommandOptions(int argc, char * argv[], boost::program_options
("uuid", po::value<std::string>(), "")
("enable-shm-uuid", "use UUID for shared memory identifier")
("enable-shm", "enable usage of shared memory")
("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<ui8>(), "amount of connections to remote lobby");
if(argc > 1)
{