Jelajahi Sumber

Lobby works

nordsoft 2 tahun lalu
induk
melakukan
97e5fc8a07

+ 18 - 6
client/CMT.cpp

@@ -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"))

+ 38 - 8
client/CServerHandler.cpp

@@ -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";

+ 3 - 0
client/CServerHandler.h

@@ -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();

+ 2 - 2
client/mainmenu/CMainMenu.cpp

@@ -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));

+ 2 - 24
config/schemas/settings.json

@@ -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",

+ 12 - 17
launcher/lobby/lobby_moc.cpp

@@ -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)
 {

+ 1 - 1
launcher/lobby/lobby_moc.h

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

+ 3 - 1
launcher/mainwindow_moc.cpp

@@ -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

+ 13 - 1
proxyServer.py

@@ -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

+ 10 - 8
server/CVCMIServer.cpp

@@ -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)
 	{