lobby_moc.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include "StdInc.h"
  2. #include "main.h"
  3. #include "lobby_moc.h"
  4. #include "ui_lobby_moc.h"
  5. #include "lobbyroomrequest_moc.h"
  6. #include "../mainwindow_moc.h"
  7. #include "../../lib/CConfigHandler.h"
  8. Lobby::Lobby(QWidget *parent) :
  9. QWidget(parent),
  10. ui(new Ui::Lobby)
  11. {
  12. ui->setupUi(this);
  13. ui->buttonReady->setEnabled(false);
  14. connect(&socketLobby, SIGNAL(text(QString)), this, SLOT(sysMessage(QString)));
  15. connect(&socketLobby, SIGNAL(receive(QString)), this, SLOT(dispatchMessage(QString)));
  16. connect(&socketLobby, SIGNAL(disconnect()), this, SLOT(onDisconnected()));
  17. ui->hostEdit->setText(QString::fromStdString(settings["launcher"]["lobbyUrl"].String()));
  18. ui->portEdit->setText(QString::number(settings["launcher"]["lobbyPort"].Integer()));
  19. ui->userEdit->setText(QString::fromStdString(settings["launcher"]["lobbyUsername"].String()));
  20. }
  21. Lobby::~Lobby()
  22. {
  23. delete ui;
  24. }
  25. void Lobby::serverCommand(const ServerCommand & command) try
  26. {
  27. //initialize variables outside of switch block
  28. const QString statusPlaceholder("%1 %2\n");
  29. QString resText;
  30. const auto & args = command.arguments;
  31. int amount, tagPoint;
  32. QString joinStr;
  33. switch(command.command)
  34. {
  35. case SRVERROR:
  36. protocolAssert(args.size());
  37. chatMessage("System error", args[0], true);
  38. if(authentificationStatus == 0)
  39. authentificationStatus = 2;
  40. break;
  41. case CREATED:
  42. protocolAssert(args.size());
  43. hostSession = args[0];
  44. session = args[0];
  45. sysMessage("new session started");
  46. ui->buttonReady->setEnabled(true);
  47. break;
  48. case SESSIONS:
  49. protocolAssert(args.size());
  50. amount = args[0].toInt();
  51. protocolAssert(amount * 4 == (args.size() - 1));
  52. ui->sessionsTable->setRowCount(amount);
  53. tagPoint = 1;
  54. for(int i = 0; i < amount; ++i)
  55. {
  56. QTableWidgetItem * sessionNameItem = new QTableWidgetItem(args[tagPoint++]);
  57. ui->sessionsTable->setItem(i, 0, sessionNameItem);
  58. int playersJoined = args[tagPoint++].toInt();
  59. int playersTotal = args[tagPoint++].toInt();
  60. QTableWidgetItem * sessionPlayerItem = new QTableWidgetItem(QString("%1/%2").arg(playersJoined).arg(playersTotal));
  61. ui->sessionsTable->setItem(i, 1, sessionPlayerItem);
  62. QTableWidgetItem * sessionProtectedItem = new QTableWidgetItem();
  63. bool isPrivate = (args[tagPoint++] == "True");
  64. sessionProtectedItem->setData(Qt::UserRole, isPrivate);
  65. if(isPrivate)
  66. sessionProtectedItem->setIcon(QIcon("icons:room-private.png"));
  67. ui->sessionsTable->setItem(i, 2, sessionProtectedItem);
  68. }
  69. break;
  70. case JOINED:
  71. case KICKED:
  72. protocolAssert(args.size() == 2);
  73. joinStr = (command.command == JOINED ? "%1 joined to the session %2" : "%1 left session %2");
  74. if(args[1] == username)
  75. {
  76. ui->chat->clear(); //cleanup the chat
  77. sysMessage(joinStr.arg("you", args[0]));
  78. session = args[0];
  79. ui->stackedWidget->setCurrentWidget(command.command == JOINED ? ui->roomPage : ui->sessionsPage);
  80. if(command.command == KICKED)
  81. ui->buttonReady->setEnabled(false);
  82. }
  83. else
  84. {
  85. sysMessage(joinStr.arg(args[1], args[0]));
  86. }
  87. break;
  88. case STATUS:
  89. protocolAssert(args.size() > 0);
  90. amount = args[0].toInt();
  91. protocolAssert(amount * 2 == (args.size() - 1));
  92. tagPoint = 1;
  93. ui->roomChat->clear();
  94. resText.clear();
  95. for(int i = 0; i < amount; ++i, tagPoint += 2)
  96. {
  97. resText += statusPlaceholder.arg(args[tagPoint], args[tagPoint + 1] == "True" ? "ready" : "");
  98. }
  99. ui->roomChat->setPlainText(resText);
  100. break;
  101. case START: {
  102. protocolAssert(args.size() == 1);
  103. //actually start game
  104. gameArgs << "--lobby";
  105. gameArgs << "--lobby-address" << ui->hostEdit->text();
  106. gameArgs << "--lobby-port" << ui->portEdit->text();
  107. gameArgs << "--uuid" << args[0];
  108. startGame(gameArgs);
  109. break;
  110. }
  111. case HOST: {
  112. protocolAssert(args.size() == 2);
  113. gameArgs << "--lobby-host";
  114. gameArgs << "--lobby-uuid" << args[0];
  115. gameArgs << "--lobby-connections" << args[1];
  116. break;
  117. }
  118. case CHAT:
  119. protocolAssert(args.size() > 1);
  120. QString msg;
  121. for(int i = 1; i < args.size(); ++i)
  122. msg += args[i];
  123. chatMessage(args[0], msg);
  124. break;
  125. }
  126. if(authentificationStatus == 2)
  127. socketLobby.disconnectServer();
  128. else
  129. authentificationStatus = 1;
  130. }
  131. catch(const ProtocolError & e)
  132. {
  133. chatMessage("System error", e.what(), true);
  134. }
  135. void Lobby::dispatchMessage(QString txt) try
  136. {
  137. if(txt.isEmpty())
  138. return;
  139. QStringList parseTags = txt.split(":>>");
  140. protocolAssert(parseTags.size() > 1 && parseTags[0].isEmpty() && !parseTags[1].isEmpty());
  141. for(int c = 1; c < parseTags.size(); ++c)
  142. {
  143. QStringList parseArgs = parseTags[c].split(":");
  144. protocolAssert(parseArgs.size() > 1);
  145. auto ctype = ProtocolStrings.key(parseArgs[0]);
  146. parseArgs.pop_front();
  147. ServerCommand cmd(ctype, parseArgs);
  148. serverCommand(cmd);
  149. }
  150. }
  151. catch(const ProtocolError & e)
  152. {
  153. chatMessage("System error", e.what(), true);
  154. }
  155. void Lobby::onDisconnected()
  156. {
  157. authentificationStatus = 0;
  158. ui->stackedWidget->setCurrentWidget(ui->sessionsPage);
  159. ui->connectButton->setChecked(false);
  160. }
  161. void Lobby::chatMessage(QString title, QString body, bool isSystem)
  162. {
  163. QTextCharFormat fmtBody, fmtTitle;
  164. fmtTitle.setFontWeight(QFont::Bold);
  165. if(isSystem)
  166. fmtBody.setFontWeight(QFont::DemiBold);
  167. QTextCursor curs(ui->chat->document());
  168. curs.movePosition(QTextCursor::End);
  169. curs.insertText(title + ": ", fmtTitle);
  170. curs.insertText(body + "\n", fmtBody);
  171. ui->chat->ensureCursorVisible();
  172. }
  173. void Lobby::sysMessage(QString body)
  174. {
  175. chatMessage("System", body, true);
  176. }
  177. void Lobby::protocolAssert(bool expr)
  178. {
  179. if(!expr)
  180. throw ProtocolError("Protocol error");
  181. }
  182. void Lobby::on_messageEdit_returnPressed()
  183. {
  184. socketLobby.send(ProtocolStrings[MESSAGE].arg(ui->messageEdit->text()));
  185. ui->messageEdit->clear();
  186. }
  187. void Lobby::on_connectButton_toggled(bool checked)
  188. {
  189. if(checked)
  190. {
  191. authentificationStatus = 0;
  192. username = ui->userEdit->text();
  193. const int connectionTimeout = settings["launcher"]["connectionTimeout"].Integer();
  194. Settings node = settings.write["launcher"];
  195. node["lobbyUrl"].String() = ui->hostEdit->text().toStdString();
  196. node["lobbyPort"].Integer() = ui->portEdit->text().toInt();
  197. node["lobbyUsername"].String() = username.toStdString();
  198. sysMessage("Connecting to " + ui->hostEdit->text() + ":" + ui->portEdit->text());
  199. //show text immediately
  200. ui->chat->repaint();
  201. qApp->processEvents();
  202. socketLobby.connectServer(ui->hostEdit->text(), ui->portEdit->text().toInt(), username, connectionTimeout);
  203. }
  204. else
  205. {
  206. socketLobby.disconnectServer();
  207. }
  208. }
  209. void Lobby::on_newButton_clicked()
  210. {
  211. new LobbyRoomRequest(socketLobby, "", this);
  212. }
  213. void Lobby::on_joinButton_clicked()
  214. {
  215. auto * item = ui->sessionsTable->item(ui->sessionsTable->currentRow(), 0);
  216. if(item)
  217. {
  218. auto isPrivate = ui->sessionsTable->item(ui->sessionsTable->currentRow(), 2)->data(Qt::UserRole).toBool();
  219. if(isPrivate)
  220. new LobbyRoomRequest(socketLobby, item->text(), this);
  221. else
  222. socketLobby.requestJoinSession(item->text(), "");
  223. }
  224. }
  225. void Lobby::on_buttonLeave_clicked()
  226. {
  227. socketLobby.requestLeaveSession(session);
  228. }
  229. void Lobby::on_buttonReady_clicked()
  230. {
  231. socketLobby.requestReadySession(session);
  232. }