GlobalLobbyProcessor.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. GlobalLobbyProcessor::GlobalLobbyProcessor(CVCMIServer & owner)
  15. : owner(owner)
  16. {
  17. logGlobal->info("Connecting to lobby server");
  18. establishNewConnection();
  19. }
  20. void GlobalLobbyProcessor::establishNewConnection()
  21. {
  22. std::string hostname = settings["lobby"]["hostname"].String();
  23. int16_t port = settings["lobby"]["port"].Integer();
  24. owner.getNetworkHandler().connectToRemote(*this, hostname, port);
  25. }
  26. void GlobalLobbyProcessor::onDisconnected(const std::shared_ptr<INetworkConnection> & connection, const std::string & errorMessage)
  27. {
  28. if (connection == controlConnection)
  29. {
  30. throw std::runtime_error("Lost connection to a lobby server!");
  31. }
  32. else
  33. {
  34. // player disconnected
  35. owner.onDisconnected(connection, errorMessage);
  36. }
  37. }
  38. void GlobalLobbyProcessor::onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<std::byte> & message)
  39. {
  40. if (connection == controlConnection)
  41. {
  42. JsonNode json(message.data(), message.size());
  43. if(json["type"].String() == "operationFailed")
  44. return receiveOperationFailed(json);
  45. if(json["type"].String() == "loginSuccess")
  46. return receiveLoginSuccess(json);
  47. if(json["type"].String() == "accountJoinsRoom")
  48. return receiveAccountJoinsRoom(json);
  49. logGlobal->error("Received unexpected message from lobby server of type '%s' ", json["type"].String());
  50. }
  51. else
  52. {
  53. // received game message via proxy connection
  54. owner.onPacketReceived(connection, message);
  55. }
  56. }
  57. void GlobalLobbyProcessor::receiveOperationFailed(const JsonNode & json)
  58. {
  59. logGlobal->info("Lobby: Failed to login into a lobby server!");
  60. throw std::runtime_error("Failed to login into a lobby server!");
  61. }
  62. void GlobalLobbyProcessor::receiveLoginSuccess(const JsonNode & json)
  63. {
  64. // no-op, wait just for any new commands from lobby
  65. logGlobal->info("Lobby: Succesfully connected to lobby server");
  66. owner.startAcceptingIncomingConnections();
  67. }
  68. void GlobalLobbyProcessor::receiveAccountJoinsRoom(const JsonNode & json)
  69. {
  70. std::string accountID = json["accountID"].String();
  71. logGlobal->info("Lobby: Account %s will join our room!", accountID);
  72. assert(proxyConnections.count(accountID) == 0);
  73. proxyConnections[accountID] = nullptr;
  74. establishNewConnection();
  75. }
  76. void GlobalLobbyProcessor::onConnectionFailed(const std::string & errorMessage)
  77. {
  78. throw std::runtime_error("Failed to connect to a lobby server!");
  79. }
  80. void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & connection)
  81. {
  82. if (controlConnection == nullptr)
  83. {
  84. controlConnection = connection;
  85. logGlobal->info("Connection to lobby server established");
  86. JsonNode toSend;
  87. toSend["type"].String() = "serverLogin";
  88. toSend["gameRoomID"].String() = owner.uuid;
  89. toSend["accountID"] = settings["lobby"]["accountID"];
  90. toSend["accountCookie"] = settings["lobby"]["accountCookie"];
  91. sendMessage(connection, toSend);
  92. }
  93. else
  94. {
  95. // Proxy connection for a player
  96. std::string guestAccountID;
  97. for (auto const & proxies : proxyConnections)
  98. if (proxies.second == nullptr)
  99. guestAccountID = proxies.first;
  100. JsonNode toSend;
  101. toSend["type"].String() = "serverProxyLogin";
  102. toSend["gameRoomID"].String() = owner.uuid;
  103. toSend["guestAccountID"].String() = guestAccountID;
  104. toSend["accountCookie"] = settings["lobby"]["accountCookie"];
  105. sendMessage(connection, toSend);
  106. proxyConnections[guestAccountID] = connection;
  107. owner.onNewConnection(connection);
  108. }
  109. }
  110. void GlobalLobbyProcessor::sendMessage(const NetworkConnectionPtr & target, const JsonNode & data)
  111. {
  112. target->sendPacket(data.toBytes(true));
  113. }