mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Implemented connecting to server via proxy
This commit is contained in:
parent
bed05eb52d
commit
c5c46a7c9a
@ -139,6 +139,7 @@ CServerHandler::CServerHandler()
|
||||
, state(EClientState::NONE)
|
||||
, campaignStateToSend(nullptr)
|
||||
, screenType(ESelectionScreen::unknown)
|
||||
, serverMode(EServerMode::NONE)
|
||||
, loadMode(ELoadMode::NONE)
|
||||
, client(nullptr)
|
||||
, campaignServerRestartLock(false)
|
||||
@ -156,10 +157,11 @@ void CServerHandler::threadRunNetwork()
|
||||
logGlobal->info("Ending network thread");
|
||||
}
|
||||
|
||||
void CServerHandler::resetStateForLobby(EStartMode mode, ESelectionScreen screen, const std::vector<std::string> & names)
|
||||
void CServerHandler::resetStateForLobby(EStartMode mode, ESelectionScreen screen, EServerMode newServerMode, const std::vector<std::string> & names)
|
||||
{
|
||||
hostClientId = -1;
|
||||
state = EClientState::NONE;
|
||||
serverMode = newServerMode;
|
||||
mapToStart = nullptr;
|
||||
th = std::make_unique<CStopWatch>();
|
||||
c.reset();
|
||||
@ -297,11 +299,18 @@ void CServerHandler::onTimer()
|
||||
networkHandler->connectToRemote(*this, getLocalHostname(), getLocalPort());
|
||||
}
|
||||
|
||||
void CServerHandler::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & netConnection)
|
||||
void CServerHandler::onConnectionEstablished(const NetworkConnectionPtr & netConnection)
|
||||
{
|
||||
networkConnection = netConnection;
|
||||
|
||||
logNetwork->info("Connection established");
|
||||
|
||||
if (serverMode == EServerMode::LOBBY_GUEST)
|
||||
{
|
||||
// say hello to lobby to switch connection to proxy mode
|
||||
getGlobalLobby().sendProxyConnectionLogin(netConnection);
|
||||
}
|
||||
|
||||
c = std::make_shared<CConnection>(netConnection);
|
||||
nextClient = std::make_unique<CClient>();
|
||||
c->uuid = uuid;
|
||||
@ -791,12 +800,12 @@ void CServerHandler::debugStartTest(std::string filename, bool save)
|
||||
auto mapInfo = std::make_shared<CMapInfo>();
|
||||
if(save)
|
||||
{
|
||||
resetStateForLobby(EStartMode::LOAD_GAME, ESelectionScreen::loadGame, {});
|
||||
resetStateForLobby(EStartMode::LOAD_GAME, ESelectionScreen::loadGame, EServerMode::LOCAL, {});
|
||||
mapInfo->saveInit(ResourcePath(filename, EResType::SAVEGAME));
|
||||
}
|
||||
else
|
||||
{
|
||||
resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, {});
|
||||
resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOCAL, {});
|
||||
mapInfo->mapInit(filename);
|
||||
}
|
||||
if(settings["session"]["donotstartserver"].Bool())
|
||||
|
@ -57,6 +57,14 @@ enum class EClientState : ui8
|
||||
CONNECTION_FAILED // We could not connect to server
|
||||
};
|
||||
|
||||
enum class EServerMode : uint8_t
|
||||
{
|
||||
NONE = 0,
|
||||
LOCAL, // no global lobby
|
||||
LOBBY_HOST, // We are hosting global server available via global lobby
|
||||
LOBBY_GUEST // Connecting to a remote server via proxy provided by global lobby
|
||||
};
|
||||
|
||||
class IServerAPI
|
||||
{
|
||||
protected:
|
||||
@ -106,10 +114,10 @@ class CServerHandler final : public IServerAPI, public LobbyInfo, public INetwor
|
||||
void onServerFinished();
|
||||
void sendLobbyPack(const CPackForLobby & pack) const override;
|
||||
|
||||
void onPacketReceived(const std::shared_ptr<INetworkConnection> &, const std::vector<uint8_t> & message) override;
|
||||
void onPacketReceived(const NetworkConnectionPtr &, const std::vector<uint8_t> & message) override;
|
||||
void onConnectionFailed(const std::string & errorMessage) override;
|
||||
void onConnectionEstablished(const std::shared_ptr<INetworkConnection> &) override;
|
||||
void onDisconnected(const std::shared_ptr<INetworkConnection> &) override;
|
||||
void onConnectionEstablished(const NetworkConnectionPtr &) override;
|
||||
void onDisconnected(const NetworkConnectionPtr &) override;
|
||||
void onTimer() override;
|
||||
|
||||
void applyPackOnLobbyScreen(CPackForLobby & pack);
|
||||
@ -132,6 +140,7 @@ public:
|
||||
std::shared_ptr<CampaignState> campaignStateToSend;
|
||||
|
||||
ESelectionScreen screenType; // To create lobby UI only after server is setup
|
||||
EServerMode serverMode;
|
||||
ELoadMode loadMode; // For saves filtering in SelectionTab
|
||||
////////////////////
|
||||
|
||||
@ -146,7 +155,7 @@ public:
|
||||
CServerHandler();
|
||||
~CServerHandler();
|
||||
|
||||
void resetStateForLobby(EStartMode mode, ESelectionScreen screen, const std::vector<std::string> & names);
|
||||
void resetStateForLobby(EStartMode mode, ESelectionScreen screen, EServerMode serverMode, const std::vector<std::string> & names);
|
||||
void startLocalServerAndConnect(bool connectToLobby);
|
||||
void connectToServer(const std::string & addr, const ui16 port);
|
||||
|
||||
|
@ -53,6 +53,7 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon
|
||||
|
||||
if (!GH.windows().findWindows<GlobalLobbyServerSetup>().empty())
|
||||
{
|
||||
assert(handler.serverMode == EServerMode::LOBBY_HOST);
|
||||
// announce opened game room
|
||||
// TODO: find better approach?
|
||||
int roomType = settings["lobby"]["roomType"].Integer();
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "../gui/WindowHandler.h"
|
||||
#include "../windows/InfoWindows.h"
|
||||
#include "../CServerHandler.h"
|
||||
#include "../mainmenu/CMainMenu.h"
|
||||
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include "../../lib/MetaString.h"
|
||||
@ -190,7 +191,18 @@ void GlobalLobbyClient::receiveActiveGameRooms(const JsonNode & json)
|
||||
|
||||
void GlobalLobbyClient::receiveJoinRoomSuccess(const JsonNode & json)
|
||||
{
|
||||
// TODO: store "gameRoomID" field and use it for future queries
|
||||
Settings configRoom = settings.write["lobby"]["roomID"];
|
||||
configRoom->String() = json["gameRoomID"].String();
|
||||
|
||||
if (json["proxyMode"].Bool())
|
||||
{
|
||||
CSH->resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOBBY_GUEST, {});
|
||||
CSH->loadMode = ELoadMode::MULTI;
|
||||
|
||||
std::string hostname = settings["lobby"]["hostname"].String();
|
||||
int16_t port = settings["lobby"]["port"].Integer();
|
||||
CSH->connectToServer(hostname, port);
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalLobbyClient::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & connection)
|
||||
@ -334,3 +346,22 @@ void GlobalLobbyClient::activateInterface()
|
||||
else
|
||||
GH.windows().pushWindow(createLoginWindow());
|
||||
}
|
||||
|
||||
void GlobalLobbyClient::sendProxyConnectionLogin(const NetworkConnectionPtr & netConnection)
|
||||
{
|
||||
JsonNode toSend;
|
||||
toSend["type"].String() = "clientProxyLogin";
|
||||
toSend["accountID"] = settings["lobby"]["accountID"];
|
||||
toSend["accountCookie"] = settings["lobby"]["accountCookie"];
|
||||
toSend["gameRoomID"] = settings["lobby"]["roomID"];
|
||||
|
||||
std::string payloadString = toSend.toJson(true);
|
||||
|
||||
// FIXME: find better approach
|
||||
uint8_t * payloadBegin = reinterpret_cast<uint8_t *>(payloadString.data());
|
||||
uint8_t * payloadEnd = payloadBegin + payloadString.size();
|
||||
|
||||
std::vector<uint8_t> payloadBuffer(payloadBegin, payloadEnd);
|
||||
|
||||
netConnection->sendPacket(payloadBuffer);
|
||||
}
|
||||
|
@ -63,6 +63,8 @@ public:
|
||||
void sendOpenPublicRoom();
|
||||
void sendOpenPrivateRoom();
|
||||
|
||||
void sendProxyConnectionLogin(const NetworkConnectionPtr & netConnection);
|
||||
|
||||
void connect();
|
||||
bool isConnected();
|
||||
};
|
||||
|
@ -125,9 +125,9 @@ void GlobalLobbyServerSetup::onGameModeChanged(int value)
|
||||
void GlobalLobbyServerSetup::onCreate()
|
||||
{
|
||||
if(toggleGameMode->getSelected() == 0)
|
||||
CSH->resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, {});
|
||||
CSH->resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOBBY_HOST, {});
|
||||
else
|
||||
CSH->resetStateForLobby(EStartMode::LOAD_GAME, ESelectionScreen::loadGame, {});
|
||||
CSH->resetStateForLobby(EStartMode::LOAD_GAME, ESelectionScreen::loadGame, EServerMode::LOBBY_HOST, {});
|
||||
|
||||
CSH->loadMode = ELoadMode::MULTI;
|
||||
CSH->startLocalServerAndConnect(true);
|
||||
|
@ -361,7 +361,7 @@ void CMainMenu::update()
|
||||
|
||||
void CMainMenu::openLobby(ESelectionScreen screenType, bool host, const std::vector<std::string> & names, ELoadMode loadMode)
|
||||
{
|
||||
CSH->resetStateForLobby(screenType == ESelectionScreen::newGame ? EStartMode::NEW_GAME : EStartMode::LOAD_GAME, screenType, names);
|
||||
CSH->resetStateForLobby(screenType == ESelectionScreen::newGame ? EStartMode::NEW_GAME : EStartMode::LOAD_GAME, screenType, EServerMode::LOCAL, names);
|
||||
CSH->loadMode = loadMode;
|
||||
|
||||
GH.windows().createAndPushWindow<CSimpleJoinScreen>(host);
|
||||
@ -376,7 +376,7 @@ void CMainMenu::openCampaignLobby(const std::string & campaignFileName, std::str
|
||||
|
||||
void CMainMenu::openCampaignLobby(std::shared_ptr<CampaignState> campaign)
|
||||
{
|
||||
CSH->resetStateForLobby(EStartMode::CAMPAIGN, ESelectionScreen::campaignList, {});
|
||||
CSH->resetStateForLobby(EStartMode::CAMPAIGN, ESelectionScreen::campaignList, EServerMode::LOCAL, {});
|
||||
CSH->campaignStateToSend = campaign;
|
||||
GH.windows().createAndPushWindow<CSimpleJoinScreen>();
|
||||
}
|
||||
|
@ -553,28 +553,24 @@
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default" : {},
|
||||
"required" : [ "mapPreview", "accountID", "accountCookie", "displayName", "hostname", "port", "roomPlayerLimit", "roomType", "roomMode" ],
|
||||
"required" : [ "mapPreview", "accountID", "accountCookie", "displayName", "hostname", "port", "roomPlayerLimit", "roomType", "roomMode", "roomID" ],
|
||||
"properties" : {
|
||||
"mapPreview" : {
|
||||
"type" : "boolean",
|
||||
"default" : true
|
||||
},
|
||||
|
||||
"accountID" : {
|
||||
"type" : "string",
|
||||
"default" : ""
|
||||
},
|
||||
|
||||
"accountCookie" : {
|
||||
"type" : "string",
|
||||
"default" : ""
|
||||
},
|
||||
|
||||
"displayName" : {
|
||||
"type" : "string",
|
||||
"default" : ""
|
||||
},
|
||||
|
||||
"hostname" : {
|
||||
"type" : "string",
|
||||
"default" : "127.0.0.1"
|
||||
@ -583,21 +579,22 @@
|
||||
"type" : "number",
|
||||
"default" : 30303
|
||||
},
|
||||
|
||||
"roomPlayerLimit" : {
|
||||
"type" : "number",
|
||||
"default" : 2
|
||||
},
|
||||
|
||||
"roomType" : {
|
||||
"type" : "number",
|
||||
"default" : 0
|
||||
},
|
||||
|
||||
"roomMode" : {
|
||||
"type" : "number",
|
||||
"default" : 0
|
||||
},
|
||||
"roomID" : {
|
||||
"type" : "string",
|
||||
"default" : ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"gameTweaks" : {
|
||||
|
@ -53,15 +53,20 @@ void NetworkServer::sendPacket(const std::shared_ptr<INetworkConnection> & conne
|
||||
|
||||
void NetworkServer::closeConnection(const std::shared_ptr<INetworkConnection> & connection)
|
||||
{
|
||||
logNetwork->info("Closing connection!");
|
||||
assert(connections.count(connection));
|
||||
connections.erase(connection);
|
||||
}
|
||||
|
||||
void NetworkServer::onDisconnected(const std::shared_ptr<INetworkConnection> & connection)
|
||||
{
|
||||
logNetwork->info("Connection lost!");
|
||||
assert(connections.count(connection));
|
||||
if (connections.count(connection)) // how? Connection was explicitly closed before?
|
||||
{
|
||||
connections.erase(connection);
|
||||
listener.onDisconnected(connection);
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkServer::onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message)
|
||||
|
@ -155,6 +155,12 @@ void LobbyDatabase::prepareStatements()
|
||||
LIMIT 1
|
||||
)";
|
||||
|
||||
static const std::string getGameRoomStatusText = R"(
|
||||
SELECT status
|
||||
FROM gameRooms
|
||||
WHERE roomID = ?
|
||||
)";
|
||||
|
||||
static const std::string getAccountGameRoomText = R"(
|
||||
SELECT grp.roomID
|
||||
FROM gameRoomPlayers grp
|
||||
@ -209,14 +215,16 @@ void LobbyDatabase::prepareStatements()
|
||||
|
||||
static const std::string isPlayerInGameRoomText = R"(
|
||||
SELECT COUNT(accountID)
|
||||
FROM gameRoomPlayers
|
||||
WHERE accountID = ? AND roomID = ?
|
||||
FROM gameRoomPlayers grp
|
||||
LEFT JOIN gameRooms gr ON gr.roomID = grp.roomID
|
||||
WHERE accountID = ? AND grp.roomID = ? AND status IN (1, 2)
|
||||
)";
|
||||
|
||||
static const std::string isPlayerInAnyGameRoomText = R"(
|
||||
SELECT COUNT(accountID)
|
||||
FROM gameRoomPlayers
|
||||
WHERE accountID = ?
|
||||
FROM gameRoomPlayers grp
|
||||
LEFT JOIN gameRooms gr ON gr.roomID = grp.roomID
|
||||
WHERE accountID = ? AND status IN (1, 2)
|
||||
)";
|
||||
|
||||
static const std::string isAccountIDExistsText = R"(
|
||||
@ -247,6 +255,7 @@ void LobbyDatabase::prepareStatements()
|
||||
|
||||
getRecentMessageHistoryStatement = database->prepare(getRecentMessageHistoryText);
|
||||
getIdleGameRoomStatement = database->prepare(getIdleGameRoomText);
|
||||
getGameRoomStatusStatement = database->prepare(getGameRoomStatusText);
|
||||
getAccountGameRoomStatement = database->prepare(getAccountGameRoomText);
|
||||
getActiveAccountsStatement = database->prepare(getActiveAccountsText);
|
||||
getActiveGameRoomsStatement = database->prepare(getActiveGameRoomsText);
|
||||
@ -406,7 +415,16 @@ LobbyInviteStatus LobbyDatabase::getAccountInviteStatus(const std::string & acco
|
||||
|
||||
LobbyRoomState LobbyDatabase::getGameRoomStatus(const std::string & roomID)
|
||||
{
|
||||
return {};
|
||||
int result = -1;
|
||||
|
||||
getGameRoomStatusStatement->setBinds(roomID);
|
||||
if(getGameRoomStatusStatement->execute())
|
||||
getGameRoomStatusStatement->getColumns(result);
|
||||
getGameRoomStatusStatement->reset();
|
||||
|
||||
if (result != -1)
|
||||
return static_cast<LobbyRoomState>(result);
|
||||
return LobbyRoomState::CLOSED;
|
||||
}
|
||||
|
||||
uint32_t LobbyDatabase::getGameRoomFreeSlots(const std::string & roomID)
|
||||
|
@ -37,6 +37,7 @@ class LobbyDatabase
|
||||
|
||||
SQLiteStatementPtr getRecentMessageHistoryStatement;
|
||||
SQLiteStatementPtr getIdleGameRoomStatement;
|
||||
SQLiteStatementPtr getGameRoomStatusStatement;
|
||||
SQLiteStatementPtr getActiveGameRoomsStatement;
|
||||
SQLiteStatementPtr getActiveAccountsStatement;
|
||||
SQLiteStatementPtr getAccountGameRoomStatement;
|
||||
|
@ -148,7 +148,7 @@ void LobbyServer::broadcastActiveAccounts()
|
||||
sendMessage(connection.first, reply);
|
||||
}
|
||||
|
||||
void LobbyServer::broadcastActiveGameRooms()
|
||||
JsonNode LobbyServer::prepareActiveGameRooms()
|
||||
{
|
||||
auto activeGameRoomStats = database->getActiveGameRooms();
|
||||
JsonNode reply;
|
||||
@ -167,6 +167,13 @@ void LobbyServer::broadcastActiveGameRooms()
|
||||
reply["gameRooms"].Vector().push_back(jsonEntry);
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
void LobbyServer::broadcastActiveGameRooms()
|
||||
{
|
||||
auto reply = prepareActiveGameRooms();
|
||||
|
||||
for(const auto & connection : activeAccounts)
|
||||
sendMessage(connection.first, reply);
|
||||
}
|
||||
@ -179,11 +186,12 @@ void LobbyServer::sendAccountJoinsRoom(const NetworkConnectionPtr & target, cons
|
||||
sendMessage(target, reply);
|
||||
}
|
||||
|
||||
void LobbyServer::sendJoinRoomSuccess(const NetworkConnectionPtr & target, const std::string & gameRoomID)
|
||||
void LobbyServer::sendJoinRoomSuccess(const NetworkConnectionPtr & target, const std::string & gameRoomID, bool proxyMode)
|
||||
{
|
||||
JsonNode reply;
|
||||
reply["type"].String() = "joinRoomSuccess";
|
||||
reply["gameRoomID"].String() = gameRoomID;
|
||||
reply["proxyMode"].Bool() = proxyMode;
|
||||
sendMessage(target, reply);
|
||||
}
|
||||
|
||||
@ -230,8 +238,9 @@ void LobbyServer::onPacketReceived(const NetworkConnectionPtr & connection, cons
|
||||
{
|
||||
auto lockedPtr = activeProxies.at(connection).lock();
|
||||
if(lockedPtr)
|
||||
lockedPtr->sendPacket(message);
|
||||
return;
|
||||
return lockedPtr->sendPacket(message);
|
||||
|
||||
throw std::runtime_error("Received unexpected message for inactive proxy!");
|
||||
}
|
||||
|
||||
JsonNode json(message.data(), message.size());
|
||||
@ -257,7 +266,7 @@ void LobbyServer::onPacketReceived(const NetworkConnectionPtr & connection, cons
|
||||
if(json["type"].String() == "declineInvite")
|
||||
return receiveDeclineInvite(connection, json);
|
||||
|
||||
return;
|
||||
throw std::runtime_error("Received unexpected message of type " + json["type"].String());
|
||||
}
|
||||
|
||||
// communication messages from vcmiserver
|
||||
@ -266,7 +275,7 @@ void LobbyServer::onPacketReceived(const NetworkConnectionPtr & connection, cons
|
||||
if(json["type"].String() == "leaveGameRoom")
|
||||
return receiveLeaveGameRoom(connection, json);
|
||||
|
||||
return;
|
||||
throw std::runtime_error("Received unexpected message of type " + json["type"].String());
|
||||
}
|
||||
|
||||
// unauthorized connections - permit only login or register attempts
|
||||
@ -287,6 +296,8 @@ void LobbyServer::onPacketReceived(const NetworkConnectionPtr & connection, cons
|
||||
|
||||
// TODO: add logging of suspicious connections.
|
||||
networkServer->closeConnection(connection);
|
||||
|
||||
throw std::runtime_error("Received unexpected message of type " + json["type"].String());
|
||||
}
|
||||
|
||||
void LobbyServer::receiveSendChatMessage(const NetworkConnectionPtr & connection, const JsonNode & json)
|
||||
@ -358,6 +369,7 @@ void LobbyServer::receiveClientLogin(const NetworkConnectionPtr & connection, co
|
||||
// send active accounts list to new account
|
||||
// and update acount list to everybody else
|
||||
broadcastActiveAccounts();
|
||||
sendMessage(connection, prepareActiveGameRooms());
|
||||
}
|
||||
|
||||
void LobbyServer::receiveServerLogin(const NetworkConnectionPtr & connection, const JsonNode & json)
|
||||
@ -420,18 +432,19 @@ void LobbyServer::receiveServerProxyLogin(const NetworkConnectionPtr & connectio
|
||||
{
|
||||
std::string gameRoomID = json["gameRoomID"].String();
|
||||
std::string guestAccountID = json["guestAccountID"].String();
|
||||
std::string hostCookie = json["hostCookie"].String();
|
||||
std::string accountCookie = json["accountCookie"].String();
|
||||
|
||||
auto clientCookieStatus = database->getGameRoomCookieStatus(gameRoomID, hostCookie, accountCookieLifetime);
|
||||
// FIXME: find host account ID and validate his cookie
|
||||
//auto clientCookieStatus = database->getAccountCookieStatus(hostAccountID, accountCookie, accountCookieLifetime);
|
||||
|
||||
if(clientCookieStatus != LobbyCookieStatus::INVALID)
|
||||
//if(clientCookieStatus != LobbyCookieStatus::INVALID)
|
||||
{
|
||||
NetworkConnectionPtr targetAccount = findAccount(guestAccountID);
|
||||
|
||||
if(targetAccount == nullptr)
|
||||
return; // unknown / disconnected account
|
||||
|
||||
sendJoinRoomSuccess(targetAccount, gameRoomID);
|
||||
sendJoinRoomSuccess(targetAccount, gameRoomID, true);
|
||||
|
||||
AwaitingProxyState proxy;
|
||||
proxy.accountID = guestAccountID;
|
||||
@ -441,7 +454,7 @@ void LobbyServer::receiveServerProxyLogin(const NetworkConnectionPtr & connectio
|
||||
return;
|
||||
}
|
||||
|
||||
networkServer->closeConnection(connection);
|
||||
//networkServer->closeConnection(connection);
|
||||
}
|
||||
|
||||
void LobbyServer::receiveOpenGameRoom(const NetworkConnectionPtr & connection, const JsonNode & json)
|
||||
@ -467,7 +480,7 @@ void LobbyServer::receiveOpenGameRoom(const NetworkConnectionPtr & connection, c
|
||||
|
||||
database->insertPlayerIntoGameRoom(accountID, gameRoomID);
|
||||
broadcastActiveGameRooms();
|
||||
sendJoinRoomSuccess(connection, gameRoomID);
|
||||
sendJoinRoomSuccess(connection, gameRoomID, false);
|
||||
}
|
||||
|
||||
void LobbyServer::receiveJoinGameRoom(const NetworkConnectionPtr & connection, const JsonNode & json)
|
||||
|
@ -70,13 +70,15 @@ class LobbyServer : public INetworkServerListener
|
||||
void broadcastActiveAccounts();
|
||||
void broadcastActiveGameRooms();
|
||||
|
||||
JsonNode prepareActiveGameRooms();
|
||||
|
||||
void sendChatMessage(const NetworkConnectionPtr & target, const std::string & roomMode, const std::string & roomName, const std::string & accountID, const std::string & displayName, const std::string & messageText);
|
||||
void sendAccountCreated(const NetworkConnectionPtr & target, const std::string & accountID, const std::string & accountCookie);
|
||||
void sendLoginFailed(const NetworkConnectionPtr & target, const std::string & reason);
|
||||
void sendLoginSuccess(const NetworkConnectionPtr & target, const std::string & accountCookie, const std::string & displayName);
|
||||
void sendChatHistory(const NetworkConnectionPtr & target, const std::vector<LobbyChatMessage> &);
|
||||
void sendAccountJoinsRoom(const NetworkConnectionPtr & target, const std::string & accountID);
|
||||
void sendJoinRoomSuccess(const NetworkConnectionPtr & target, const std::string & gameRoomID);
|
||||
void sendJoinRoomSuccess(const NetworkConnectionPtr & target, const std::string & gameRoomID, bool proxyMode);
|
||||
void sendInviteReceived(const NetworkConnectionPtr & target, const std::string & accountID, const std::string & gameRoomID);
|
||||
|
||||
void receiveClientRegister(const NetworkConnectionPtr & connection, const JsonNode & json);
|
||||
|
@ -34,6 +34,8 @@ void GlobalLobbyProcessor::onDisconnected(const std::shared_ptr<INetworkConnecti
|
||||
|
||||
void GlobalLobbyProcessor::onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message)
|
||||
{
|
||||
if (connection == controlConnection)
|
||||
{
|
||||
JsonNode json(message.data(), message.size());
|
||||
|
||||
if(json["type"].String() == "loginFailed")
|
||||
@ -46,17 +48,25 @@ void GlobalLobbyProcessor::onPacketReceived(const std::shared_ptr<INetworkConnec
|
||||
return receiveAccountJoinsRoom(json);
|
||||
|
||||
throw std::runtime_error("Received unexpected message from lobby server: " + json["type"].String());
|
||||
}
|
||||
else
|
||||
{
|
||||
// received game message via proxy connection
|
||||
owner.onPacketReceived(connection, message);
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalLobbyProcessor::receiveLoginFailed(const JsonNode & json)
|
||||
{
|
||||
logGlobal->info("Lobby: Failed to login into a lobby server!");
|
||||
|
||||
throw std::runtime_error("Failed to login into a lobby server!");
|
||||
}
|
||||
|
||||
void GlobalLobbyProcessor::receiveLoginSuccess(const JsonNode & json)
|
||||
{
|
||||
// no-op, wait just for any new commands from lobby
|
||||
logGlobal->info("Succesfully connected to lobby server");
|
||||
logGlobal->info("Lobby: Succesfully connected to lobby server");
|
||||
owner.startAcceptingIncomingConnections();
|
||||
}
|
||||
|
||||
@ -64,6 +74,7 @@ void GlobalLobbyProcessor::receiveAccountJoinsRoom(const JsonNode & json)
|
||||
{
|
||||
std::string accountID = json["accountID"].String();
|
||||
|
||||
logGlobal->info("Lobby: Account %s will join our room!", accountID);
|
||||
assert(proxyConnections.count(accountID) == 0);
|
||||
|
||||
proxyConnections[accountID] = nullptr;
|
||||
@ -87,29 +98,29 @@ void GlobalLobbyProcessor::onConnectionEstablished(const std::shared_ptr<INetwor
|
||||
toSend["gameRoomID"].String() = owner.uuid;
|
||||
toSend["accountID"] = settings["lobby"]["accountID"];
|
||||
toSend["accountCookie"] = settings["lobby"]["accountCookie"];
|
||||
sendMessage(toSend);
|
||||
sendMessage(connection, toSend);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Proxy connection for a player
|
||||
std::string accountID;
|
||||
std::string guestAccountID;
|
||||
for (auto const & proxies : proxyConnections)
|
||||
if (proxies.second == nullptr)
|
||||
accountID = proxies.first;
|
||||
guestAccountID = proxies.first;
|
||||
|
||||
JsonNode toSend;
|
||||
toSend["type"].String() = "serverProxyLogin";
|
||||
toSend["gameRoomID"].String() = owner.uuid;
|
||||
toSend["accountID"].String() = accountID;
|
||||
toSend["guestAccountID"].String() = guestAccountID;
|
||||
toSend["accountCookie"] = settings["lobby"]["accountCookie"];
|
||||
sendMessage(toSend);
|
||||
sendMessage(connection, toSend);
|
||||
|
||||
proxyConnections[accountID] = connection;
|
||||
proxyConnections[guestAccountID] = connection;
|
||||
owner.onNewConnection(connection);
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalLobbyProcessor::sendMessage(const JsonNode & data)
|
||||
void GlobalLobbyProcessor::sendMessage(const NetworkConnectionPtr & target, const JsonNode & data)
|
||||
{
|
||||
std::string payloadString = data.toJson(true);
|
||||
|
||||
@ -119,5 +130,5 @@ void GlobalLobbyProcessor::sendMessage(const JsonNode & data)
|
||||
|
||||
std::vector<uint8_t> payloadBuffer(payloadBegin, payloadEnd);
|
||||
|
||||
controlConnection->sendPacket(payloadBuffer);
|
||||
target->sendPacket(payloadBuffer);
|
||||
}
|
||||
|
@ -21,15 +21,15 @@ class GlobalLobbyProcessor : public INetworkClientListener
|
||||
{
|
||||
CVCMIServer & owner;
|
||||
|
||||
std::shared_ptr<INetworkConnection> controlConnection;
|
||||
std::map<std::string, std::shared_ptr<INetworkConnection>> proxyConnections;
|
||||
NetworkConnectionPtr controlConnection;
|
||||
std::map<std::string, NetworkConnectionPtr> proxyConnections;
|
||||
|
||||
void onDisconnected(const std::shared_ptr<INetworkConnection> & connection) override;
|
||||
void onPacketReceived(const std::shared_ptr<INetworkConnection> & connection, const std::vector<uint8_t> & message) override;
|
||||
void onConnectionFailed(const std::string & errorMessage) override;
|
||||
void onConnectionEstablished(const std::shared_ptr<INetworkConnection> &) override;
|
||||
|
||||
void sendMessage(const JsonNode & data);
|
||||
void sendMessage(const NetworkConnectionPtr & target, const JsonNode & data);
|
||||
|
||||
void receiveLoginFailed(const JsonNode & json);
|
||||
void receiveLoginSuccess(const JsonNode & json);
|
||||
|
Loading…
Reference in New Issue
Block a user