Browse Source

Implemented support of protocol 4

nordsoft 2 năm trước cách đây
mục cha
commit
8e1d8f835a
5 tập tin đã thay đổi với 216 bổ sung59 xóa
  1. 35 17
      client/CMT.cpp
  2. 27 4
      launcher/lobby/lobby.h
  3. 63 2
      launcher/lobby/lobby_moc.cpp
  4. 7 0
      launcher/lobby/lobby_moc.h
  5. 84 36
      launcher/lobby/lobby_moc.ui

+ 35 - 17
client/CMT.cpp

@@ -208,6 +208,8 @@ int main(int argc, char * argv[])
 		("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<bool>(), "use 0 for new game and 1 for load game")
 		("uuid", po::value<std::string>(), "uuid for the client");
 
 	if(argc > 1)
@@ -489,13 +491,41 @@ int main(int argc, char * argv[])
 	session["autoSkip"].Bool()  = vm.count("autoSkip");
 	session["oneGoodAI"].Bool() = vm.count("oneGoodAI");
 	session["aiSolo"].Bool() = false;
+	std::shared_ptr<CMainMenu> mmenu;
 	
+	if(vm.count("testmap"))
+	{
+		session["testmap"].String() = vm["testmap"].as<std::string>();
+		session["onlyai"].Bool() = true;
+		boost::thread(&CServerHandler::debugStartTest, CSH, session["testmap"].String(), false);
+	}
+	else if(vm.count("testsave"))
+	{
+		session["testsave"].String() = vm["testsave"].as<std::string>();
+		session["onlyai"].Bool() = true;
+		boost::thread(&CServerHandler::debugStartTest, CSH, session["testsave"].String(), true);
+	}
+	else
+	{
+		mmenu = CMainMenu::create();
+		GH.curInt = mmenu.get();
+	}
+	
+	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);
@@ -510,23 +540,11 @@ int main(int argc, char * argv[])
 		//we should not reconnect to previous game in online mode
 		Settings saveSession = settings.write["server"]["reconnect"];
 		saveSession->Bool() = false;
-	}
-
-	if(vm.count("testmap"))
-	{
-		session["testmap"].String() = vm["testmap"].as<std::string>();
-		session["onlyai"].Bool() = true;
-		boost::thread(&CServerHandler::debugStartTest, CSH, session["testmap"].String(), false);
-	}
-	else if(vm.count("testsave"))
-	{
-		session["testsave"].String() = vm["testsave"].as<std::string>();
-		session["onlyai"].Bool() = true;
-		boost::thread(&CServerHandler::debugStartTest, CSH, session["testsave"].String(), true);
-	}
-	else
-	{
-		GH.curInt = CMainMenu::create().get();
+		
+		//start lobby immediately
+		names.push_back(session["username"].String());
+		ESelectionScreen sscreen = session["gamemode"].Integer() == 0 ? ESelectionScreen::newGame : ESelectionScreen::loadGame;
+		mmenu->openLobby(sscreen, session["host"].Bool(), &names, ELoadMode::MULTI);
 	}
 	
 	// Restore remote session - start game immediately

+ 27 - 4
launcher/lobby/lobby.h

@@ -12,7 +12,7 @@
 #include <QTcpSocket>
 #include <QAbstractSocket>
 
-const unsigned int ProtocolVersion = 3;
+const unsigned int ProtocolVersion = 4;
 const std::string ProtocolEncoding = "utf8";
 
 class ProtocolError: public std::runtime_error
@@ -24,10 +24,10 @@ public:
 enum ProtocolConsts
 {
 	//client consts
-	GREETING, USERNAME, MESSAGE, VERSION, CREATE, JOIN, LEAVE, KICK, READY, FORCESTART,
+	GREETING, USERNAME, MESSAGE, VERSION, CREATE, JOIN, LEAVE, KICK, READY, FORCESTART, HERE, ALIVE, HOSTMODE,
 
 	//server consts
-	SESSIONS, CREATED, JOINED, KICKED, SRVERROR, CHAT, START, STATUS, HOST, MODS, CLIENTMODS
+	SESSIONS, CREATED, JOINED, KICKED, SRVERROR, CHAT, START, STATUS, HOST, MODS, CLIENTMODS, USERS, HEALTH, GAMEMODE
 };
 
 const QMap<ProtocolConsts, QString> ProtocolStrings
@@ -78,6 +78,16 @@ const QMap<ProtocolConsts, QString> ProtocolStrings
 	//[unsupported] start session immediately
 	//%1: room name
 	{FORCESTART, "<FORCESTART>%1"},
+	
+	//request user list
+	{HERE, "<HERE>"},
+	
+	//used as reponse to healcheck
+	{ALIVE, "<ALIVE>"},
+	
+	//host sets game mode (new game or load game)
+	//%1: game mode - 0 for new game, 1 for load game
+	{HOSTMODE, "<HOSTMODE>%1"},
 
 	//=== server commands ===
 	//server commands are started from :>>, arguments are enumerated by : symbol
@@ -140,7 +150,20 @@ const QMap<ProtocolConsts, QString> ProtocolStrings
 	//received chat message
 	//arg[0]: sender username
 	//arg[1]: message text
-	{CHAT, "MSG"}
+	{CHAT, "MSG"},
+	
+	//list of users currently in lobby
+	//arg[0]: amount of players, following arguments depend on it
+	//arg[x]: username
+	//arg[x+1]: room (empty if not in the room)
+	{USERS, "USERS"},
+	
+	//healthcheck from server
+	{HEALTH, "HEALTH"},
+	
+	//game mode (new game or load game) set by host
+	//arg[0]: game mode
+	{GAMEMODE, "GAMEMODE"}
 };
 
 class ServerCommand

+ 63 - 2
launcher/lobby/lobby_moc.cpp

@@ -135,9 +135,12 @@ void Lobby::serverCommand(const ServerCommand & command) try
 		if(args[1] == username)
 		{
 			ui->buttonReady->setText("Ready");
-			ui->chat->clear(); //cleanup the chat
+			ui->optNewGame->setChecked(true);
 			sysMessage(joinStr.arg("you", args[0]));
 			session = args[0];
+			bool isHost = command.command == JOINED && hostSession == session;
+			ui->optNewGame->setEnabled(isHost);
+			ui->optLoadGame->setEnabled(isHost);
 			ui->stackedWidget->setCurrentWidget(command.command == JOINED ? ui->roomPage : ui->sessionsPage);
 		}
 		else
@@ -217,6 +220,8 @@ void Lobby::serverCommand(const ServerCommand & command) try
 		gameArgs << "--lobby";
 		gameArgs << "--lobby-address" << serverUrl;
 		gameArgs << "--lobby-port" << QString::number(serverPort);
+		gameArgs << "--lobby-username" << username;
+		gameArgs << "--lobby-gamemode" << QString::number(isLoadGameMode);
 		gameArgs << "--uuid" << args[0];
 		startGame(gameArgs);		
 		break;
@@ -238,6 +243,35 @@ void Lobby::serverCommand(const ServerCommand & command) try
 		chatMessage(args[0], msg);
 		break;
 		}
+			
+	case HEALTH: {
+		protocolAssert(args.size() == 0);
+		socketLobby.send(ProtocolStrings[ALIVE]);
+		break;
+	}
+			
+	case USERS: {
+		protocolAssert(args.size() > 0);
+		amount = args[0].toInt();
+		
+		protocolAssert(amount == (args.size() - 1));
+		ui->listUsers->clear();
+		for(int i = 0; i < amount; ++i)
+		{
+			ui->listUsers->addItem(new QListWidgetItem(args[i + 1]));
+		}
+		break;
+	}
+			
+	case GAMEMODE: {
+		protocolAssert(args.size() == 1);
+		isLoadGameMode = args[0].toInt();
+		if(isLoadGameMode == 1)
+			ui->optLoadGame->setChecked(true);
+		else
+			ui->optNewGame->setChecked(true);
+		break;
+	}
 
 	default:
 		sysMessage("Unknown server command");
@@ -291,7 +325,7 @@ void Lobby::onDisconnected()
 	ui->userEdit->setEnabled(true);
 	ui->newButton->setEnabled(false);
 	ui->joinButton->setEnabled(false);
-	ui->sessionsTable->clear();
+	ui->sessionsTable->setRowCount(0);
 }
 
 void Lobby::chatMessage(QString title, QString body, bool isSystem)
@@ -329,6 +363,7 @@ void Lobby::on_connectButton_toggled(bool checked)
 {
 	if(checked)
 	{
+		ui->connectButton->setText("Disconnect");
 		authentificationStatus = AuthStatus::AUTH_NONE;
 		username = ui->userEdit->text();
 		const int connectionTimeout = settings["launcher"]["connectionTimeout"].Integer();
@@ -360,8 +395,10 @@ void Lobby::on_connectButton_toggled(bool checked)
 	}
 	else
 	{
+		ui->connectButton->setText("Connection");
 		ui->serverEdit->setEnabled(true);
 		ui->userEdit->setEnabled(true);
+		ui->listUsers->clear();
 		socketLobby.disconnectServer();
 	}
 }
@@ -417,3 +454,27 @@ void Lobby::on_kickButton_clicked()
 		socketLobby.send(ProtocolStrings[KICK].arg(ui->playersList->currentItem()->text()));
 }
 
+
+void Lobby::on_buttonResolve_clicked()
+{
+	//TODO: auto-resolve mods conflicts
+}
+
+void Lobby::on_optNewGame_toggled(bool checked)
+{
+	if(checked)
+	{
+		if(isLoadGameMode)
+			socketLobby.send(ProtocolStrings[HOSTMODE].arg(0));
+	}
+}
+
+void Lobby::on_optLoadGame_toggled(bool checked)
+{
+	if(checked)
+	{
+		if(!isLoadGameMode)
+			socketLobby.send(ProtocolStrings[HOSTMODE].arg(1));
+	}
+}
+

+ 7 - 0
launcher/lobby/lobby_moc.h

@@ -49,9 +49,16 @@ private slots:
 
 	void on_kickButton_clicked();
 
+	void on_buttonResolve_clicked();
+
+	void on_optNewGame_toggled(bool checked);
+
+	void on_optLoadGame_toggled(bool checked);
+
 private:
 	QString serverUrl;
 	int serverPort;
+	bool isLoadGameMode = false;
 	
 	Ui::Lobby *ui;
 	SocketLobby socketLobby;

+ 84 - 36
launcher/lobby/lobby_moc.ui

@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>652</width>
-    <height>329</height>
+    <height>331</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -30,9 +30,6 @@
      </property>
     </widget>
    </item>
-   <item row="3" column="0" colspan="3">
-    <widget class="QLineEdit" name="messageEdit"/>
-   </item>
    <item row="0" column="3">
     <widget class="QLabel" name="label_4">
      <property name="sizePolicy">
@@ -56,13 +53,6 @@
      </property>
     </widget>
    </item>
-   <item row="2" column="0" colspan="3">
-    <widget class="QPlainTextEdit" name="chat">
-     <property name="readOnly">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
    <item row="0" column="0">
     <widget class="QLabel" name="label">
      <property name="text">
@@ -147,27 +137,47 @@
      </widget>
      <widget class="QWidget" name="roomPage">
       <layout class="QGridLayout" name="gridLayout_3">
-       <item row="5" column="1">
-        <widget class="QPushButton" name="buttonReady">
+       <item row="1" column="1">
+        <widget class="QPushButton" name="kickButton">
          <property name="text">
-          <string>Ready</string>
+          <string>Kick player</string>
          </property>
         </widget>
        </item>
-       <item row="3" column="0">
-        <widget class="QLabel" name="label_5">
+       <item row="2" column="0" colspan="2">
+        <widget class="QListWidget" name="playersList">
+         <property name="editTriggers">
+          <set>QAbstractItemView::NoEditTriggers</set>
+         </property>
+         <property name="selectionMode">
+          <enum>QAbstractItemView::SingleSelection</enum>
+         </property>
+         <property name="selectionBehavior">
+          <enum>QAbstractItemView::SelectRows</enum>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0">
+        <widget class="QLabel" name="label_3">
          <property name="text">
-          <string>Mods mismatch</string>
+          <string>Players in the room</string>
          </property>
         </widget>
        </item>
-       <item row="5" column="0">
+       <item row="6" column="0">
         <widget class="QPushButton" name="buttonLeave">
          <property name="text">
           <string>Leave</string>
          </property>
         </widget>
        </item>
+       <item row="3" column="0">
+        <widget class="QLabel" name="label_5">
+         <property name="text">
+          <string>Mods mismatch</string>
+         </property>
+        </widget>
+       </item>
        <item row="4" column="0" colspan="2">
         <widget class="QListWidget" name="modsList">
          <property name="editTriggers">
@@ -178,37 +188,75 @@
          </property>
         </widget>
        </item>
-       <item row="2" column="0" colspan="2">
-        <widget class="QListWidget" name="playersList">
-         <property name="editTriggers">
-          <set>QAbstractItemView::NoEditTriggers</set>
-         </property>
-         <property name="selectionMode">
-          <enum>QAbstractItemView::SingleSelection</enum>
-         </property>
-         <property name="selectionBehavior">
-          <enum>QAbstractItemView::SelectRows</enum>
+       <item row="6" column="1">
+        <widget class="QPushButton" name="buttonReady">
+         <property name="text">
+          <string>Ready</string>
          </property>
         </widget>
        </item>
-       <item row="1" column="1">
-        <widget class="QPushButton" name="kickButton">
+       <item row="3" column="1">
+        <widget class="QPushButton" name="buttonResolve">
          <property name="text">
-          <string>Kick player</string>
+          <string>Resolve conflicts</string>
          </property>
         </widget>
        </item>
-       <item row="1" column="0">
-        <widget class="QLabel" name="label_3">
-         <property name="text">
-          <string>Players in the room</string>
+       <item row="5" column="0" colspan="2">
+        <layout class="QHBoxLayout" name="horizontalLayout_3">
+         <property name="bottomMargin">
+          <number>0</number>
          </property>
-        </widget>
+         <item>
+          <widget class="QRadioButton" name="optNewGame">
+           <property name="text">
+            <string>New game</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="optLoadGame">
+           <property name="text">
+            <string>Load game</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
        </item>
       </layout>
      </widget>
     </widget>
    </item>
+   <item row="1" column="0" rowspan="3" colspan="3">
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <property name="bottomMargin">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QListWidget" name="listUsers">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>120</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="editTriggers">
+        <set>QAbstractItemView::NoEditTriggers</set>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPlainTextEdit" name="chat">
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="messageEdit"/>
+     </item>
+    </layout>
+   </item>
   </layout>
  </widget>
  <resources/>