GlobalLobbyProcessor.cpp 3.8 KB

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