GlobalLobbyProcessor.cpp 4.0 KB

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