GlobalLobbyProcessor.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * GlobalLobbyProcessor.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "GlobalLobbyProcessor.h"
  12. #include "CVCMIServer.h"
  13. #include "../lib/CConfigHandler.h"
  14. #include "../lib/json/JsonUtils.h"
  15. GlobalLobbyProcessor::GlobalLobbyProcessor(CVCMIServer & owner)
  16. : owner(owner)
  17. {
  18. logGlobal->info("Connecting to lobby server");
  19. establishNewConnection();
  20. }
  21. void GlobalLobbyProcessor::establishNewConnection()
  22. {
  23. std::string hostname = settings["lobby"]["hostname"].String();
  24. int16_t port = settings["lobby"]["port"].Integer();
  25. owner.getNetworkHandler().connectToRemote(*this, hostname, port);
  26. }
  27. void GlobalLobbyProcessor::onDisconnected(const std::shared_ptr<INetworkConnection> & connection, const std::string & errorMessage)
  28. {
  29. if (connection == controlConnection)
  30. {
  31. owner.setState(EServerState::SHUTDOWN);
  32. return;
  33. }
  34. else
  35. {
  36. if (owner.getState() == EServerState::LOBBY)
  37. {
  38. for (auto const & proxy : proxyConnections)
  39. {
  40. if (proxy.second == connection)
  41. {
  42. JsonNode message;
  43. message["type"].String() = "leaveGameRoom";
  44. message["accountID"].String() = proxy.first;
  45. assert(JsonUtils::validate(message, "vcmi:lobbyProtocol/" + message["type"].String(), "network"));
  46. controlConnection->sendPacket(message.toBytes());
  47. break;
  48. }
  49. }
  50. }
  51. // player disconnected
  52. owner.onDisconnected(connection, errorMessage);
  53. }
  54. }
  55. void GlobalLobbyProcessor::onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<std::byte> & message)
  56. {
  57. if (connection == controlConnection)
  58. {
  59. JsonNode json(message.data(), message.size());
  60. if(json["type"].String() == "operationFailed")
  61. return receiveOperationFailed(json);
  62. if(json["type"].String() == "loginSuccess")
  63. return receiveLoginSuccess(json);
  64. if(json["type"].String() == "accountJoinsRoom")
  65. return receiveAccountJoinsRoom(json);
  66. logGlobal->error("Received unexpected message from lobby server of type '%s' ", json["type"].String());
  67. }
  68. else
  69. {
  70. // received game message via proxy connection
  71. owner.onPacketReceived(connection, message);
  72. }
  73. }
  74. void GlobalLobbyProcessor::receiveOperationFailed(const JsonNode & json)
  75. {
  76. logGlobal->info("Lobby: Failed to login into a lobby server!");
  77. owner.setState(EServerState::SHUTDOWN);
  78. }
  79. void GlobalLobbyProcessor::receiveLoginSuccess(const JsonNode & json)
  80. {
  81. // no-op, wait just for any new commands from lobby
  82. logGlobal->info("Lobby: Succesfully connected to lobby server");
  83. owner.startAcceptingIncomingConnections();
  84. }
  85. void GlobalLobbyProcessor::receiveAccountJoinsRoom(const JsonNode & json)
  86. {
  87. std::string accountID = json["accountID"].String();
  88. logGlobal->info("Lobby: Account %s will join our room!", accountID);
  89. assert(proxyConnections.count(accountID) == 0);
  90. proxyConnections[accountID] = nullptr;
  91. establishNewConnection();
  92. }
  93. void GlobalLobbyProcessor::onConnectionFailed(const std::string & errorMessage)
  94. {
  95. owner.setState(EServerState::SHUTDOWN);
  96. }
  97. void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & connection)
  98. {
  99. if (controlConnection == nullptr)
  100. {
  101. controlConnection = connection;
  102. logGlobal->info("Connection to lobby server established");
  103. JsonNode toSend;
  104. toSend["type"].String() = "serverLogin";
  105. toSend["gameRoomID"].String() = owner.uuid;
  106. toSend["accountID"] = settings["lobby"]["accountID"];
  107. toSend["accountCookie"] = settings["lobby"]["accountCookie"];
  108. assert(JsonUtils::validate(toSend, "vcmi:lobbyProtocol/" + toSend["type"].String(), "network"));
  109. connection->sendPacket(toSend.toBytes());
  110. }
  111. else
  112. {
  113. // Proxy connection for a player
  114. std::string guestAccountID;
  115. for (auto const & proxies : proxyConnections)
  116. if (proxies.second == nullptr)
  117. guestAccountID = proxies.first;
  118. JsonNode toSend;
  119. toSend["type"].String() = "serverProxyLogin";
  120. toSend["gameRoomID"].String() = owner.uuid;
  121. toSend["guestAccountID"].String() = guestAccountID;
  122. toSend["accountCookie"] = settings["lobby"]["accountCookie"];
  123. assert(JsonUtils::validate(toSend, "vcmi:lobbyProtocol/" + toSend["type"].String(), "network"));
  124. connection->sendPacket(toSend.toBytes());
  125. proxyConnections[guestAccountID] = connection;
  126. owner.onNewConnection(connection);
  127. }
  128. }