1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Implemented matches history in lobby

This commit is contained in:
Ivan Savenko 2024-03-20 18:40:37 +02:00
parent 4ed961fb96
commit 829b754091
19 changed files with 249 additions and 63 deletions

View File

@ -78,6 +78,11 @@
"vcmi.lobby.login.error" : "Connection error: %s",
"vcmi.lobby.login.create" : "New Account",
"vcmi.lobby.login.login" : "Login",
"vcmi.lobby.header.rooms" : "Game Rooms",
"vcmi.lobby.header.channels" : "Chat Channels",
"vcmi.lobby.header.chat" : "Game Chat",
"vcmi.lobby.header.history" : "Your Games",
"vcmi.lobby.header.players" : "Players Online",
"vcmi.lobby.room.create" : "Create New Room",
"vcmi.lobby.room.players.limit" : "Players Limit",
"vcmi.lobby.room.description.public" : "Any player can join public room.",

View File

@ -66,7 +66,7 @@
"vcmi.lobby.filepath" : "Назва файлу",
"vcmi.lobby.creationDate" : "Дата створення",
"vcmi.lobby.scenarioName" : "Scenario name",
"vcmi.lobby.scenarioName" : "Назва сценарію",
"vcmi.lobby.mapPreview" : "Огляд мапи",
"vcmi.lobby.noPreview" : "огляд недоступний",
"vcmi.lobby.noUnderground" : "немає підземелля",
@ -78,6 +78,11 @@
"vcmi.lobby.login.error" : "Помилка з'єднання: %s",
"vcmi.lobby.login.create" : "Створити акаунт",
"vcmi.lobby.login.login" : "Увійти",
"vcmi.lobby.header.rooms" : "Кімнати",
"vcmi.lobby.header.channels" : "Канали чату",
"vcmi.lobby.header.chat" : "Чат гри",
"vcmi.lobby.header.history" : "Ваші попередні ігри",
"vcmi.lobby.header.players" : "Гравці в мережі",
"vcmi.lobby.room.create" : "Створити нову кімнату",
"vcmi.lobby.room.players.limit" : "Максимум гравців",
"vcmi.lobby.room.description.public" : "Будь-хто з гравців може приєднатися до публічної кімнати.",

View File

@ -172,8 +172,7 @@ void CServerHandler::resetStateForLobby(EStartMode mode, ESelectionScreen screen
localPlayerNames.push_back(settings["general"]["playerName"].String());
gameChat->resetMatchState();
if (lobbyClient)
lobbyClient->resetMatchState();
lobbyClient->resetMatchState();
}
GameChatHandler & CServerHandler::getGameChat()

View File

@ -13,6 +13,7 @@
#include "CServerHandler.h"
#include "CPlayerInterface.h"
#include "PlayerLocalState.h"
#include "globalLobby/GlobalLobbyClient.h"
#include "lobby/CLobbyScreen.h"
#include "adventureMap/CInGameConsole.h"
@ -34,7 +35,7 @@ static std::string getCurrentTimeFormatted(int timeOffsetSeconds = 0)
return TextOperations::getFormattedTimeLocal(std::chrono::system_clock::to_time_t(timeNowChrono));
}
const std::vector<GameChatMessage> GameChatHandler::getChatHistory()
const std::vector<GameChatMessage> & GameChatHandler::getChatHistory()
{
return chatHistory;
}
@ -47,6 +48,7 @@ void GameChatHandler::resetMatchState()
void GameChatHandler::sendMessageGameplay(const std::string & messageText)
{
LOCPLINT->cb->sendMessage(messageText, LOCPLINT->localState->getCurrentArmy());
CSH->getGlobalLobby().sendMatchChatMessage(messageText);
}
void GameChatHandler::sendMessageLobby(const std::string & senderName, const std::string & messageText)
@ -55,11 +57,22 @@ void GameChatHandler::sendMessageLobby(const std::string & senderName, const std
lcm.message = messageText;
lcm.playerName = senderName;
CSH->sendLobbyPack(lcm);
CSH->getGlobalLobby().sendMatchChatMessage(messageText);
}
void GameChatHandler::onNewLobbyMessageReceived(const std::string & senderName, const std::string & messageText)
{
auto lobby = dynamic_cast<CLobbyScreen*>(SEL);
if (!SEL)
{
logGlobal->debug("Received chat message for lobby but lobby not yet exists!");
return;
}
auto * lobby = dynamic_cast<CLobbyScreen*>(SEL);
// FIXME: when can this happen?
assert(lobby);
assert(lobby->card);
if(lobby && lobby->card)
{

View File

@ -25,7 +25,7 @@ class GameChatHandler : boost::noncopyable
std::vector<GameChatMessage> chatHistory;
public:
/// Returns all message history for current match
const std::vector<GameChatMessage> getChatHistory();
const std::vector<GameChatMessage> & getChatHistory();
/// Erases any local state, must be called when client disconnects from match server
void resetMatchState();

View File

@ -78,6 +78,9 @@ void GlobalLobbyClient::onPacketReceived(const std::shared_ptr<INetworkConnectio
if(json["type"].String() == "inviteReceived")
return receiveInviteReceived(json);
if(json["type"].String() == "matchesHistory")
return receiveMatchesHistory(json);
logGlobal->error("Received unexpected message from lobby server: %s", json["type"].String());
}
@ -211,7 +214,13 @@ void GlobalLobbyClient::receiveActiveGameRooms(const JsonNode & json)
room.hostAccountDisplayName = jsonEntry["hostAccountDisplayName"].String();
room.description = jsonEntry["description"].String();
room.statusID = jsonEntry["status"].String();
room.playersCount = jsonEntry["playersCount"].Integer();
for (auto const & jsonParticipant : jsonEntry["participants"].Vector())
{
GlobalLobbyAccount account;
account.accountID = jsonParticipant["accountID"].String();
account.displayName = jsonParticipant["displayName"].String();
room.participants.push_back(account);
}
room.playerLimit = jsonEntry["playerLimit"].Integer();
activeRooms.push_back(room);
@ -222,6 +231,36 @@ void GlobalLobbyClient::receiveActiveGameRooms(const JsonNode & json)
lobbyWindowPtr->onActiveRooms(activeRooms);
}
void GlobalLobbyClient::receiveMatchesHistory(const JsonNode & json)
{
matchesHistory.clear();
for (auto const & jsonEntry : json["matchesHistory"].Vector())
{
GlobalLobbyRoom room;
room.gameRoomID = jsonEntry["gameRoomID"].String();
room.hostAccountID = jsonEntry["hostAccountID"].String();
room.hostAccountDisplayName = jsonEntry["hostAccountDisplayName"].String();
room.description = jsonEntry["description"].String();
room.statusID = jsonEntry["status"].String();
for (auto const & jsonParticipant : jsonEntry["participants"].Vector())
{
GlobalLobbyAccount account;
account.accountID = jsonParticipant["accountID"].String();
account.displayName = jsonParticipant["displayName"].String();
room.participants.push_back(account);
}
room.playerLimit = jsonEntry["playerLimit"].Integer();
matchesHistory.push_back(room);
}
auto lobbyWindowPtr = lobbyWindow.lock();
if(lobbyWindowPtr)
lobbyWindowPtr->onMatchesHistory(activeRooms);
}
void GlobalLobbyClient::receiveInviteReceived(const JsonNode & json)
{
assert(0); //TODO
@ -372,7 +411,7 @@ const std::vector<std::string> & GlobalLobbyClient::getActiveChannels() const
return activeChannels;
}
const std::vector<GlobalLobbyHistoryMatch> & GlobalLobbyClient::getMatchesHistory() const
const std::vector<GlobalLobbyRoom> & GlobalLobbyClient::getMatchesHistory() const
{
return matchesHistory;
}
@ -435,3 +474,20 @@ void GlobalLobbyClient::resetMatchState()
{
currentGameRoomUUID.clear();
}
void GlobalLobbyClient::sendMatchChatMessage(const std::string & messageText)
{
if (!isConnected())
return; // we are not playing with lobby
if (currentGameRoomUUID.empty())
return; // we are not playing through lobby
JsonNode toSend;
toSend["type"].String() = "sendChatMessage";
toSend["channelType"].String() = "match";
toSend["channelName"].String() = currentGameRoomUUID;
toSend["messageText"].String() = messageText;
CSH->getGlobalLobby().sendMessage(toSend);
}

View File

@ -24,7 +24,7 @@ class GlobalLobbyClient final : public INetworkClientListener, boost::noncopyabl
std::vector<GlobalLobbyAccount> activeAccounts;
std::vector<GlobalLobbyRoom> activeRooms;
std::vector<std::string> activeChannels;
std::vector<GlobalLobbyHistoryMatch> matchesHistory;
std::vector<GlobalLobbyRoom> matchesHistory;
/// Contains known history of each channel
/// Key: concatenated channel type and channel name
@ -50,6 +50,7 @@ class GlobalLobbyClient final : public INetworkClientListener, boost::noncopyabl
void receiveChatMessage(const JsonNode & json);
void receiveActiveAccounts(const JsonNode & json);
void receiveActiveGameRooms(const JsonNode & json);
void receiveMatchesHistory(const JsonNode & json);
void receiveJoinRoomSuccess(const JsonNode & json);
void receiveInviteReceived(const JsonNode & json);
@ -63,12 +64,13 @@ public:
const std::vector<GlobalLobbyAccount> & getActiveAccounts() const;
const std::vector<GlobalLobbyRoom> & getActiveRooms() const;
const std::vector<std::string> & getActiveChannels() const;
const std::vector<GlobalLobbyHistoryMatch> & getMatchesHistory() const;
const std::vector<GlobalLobbyRoom> & getMatchesHistory() const;
const std::vector<GlobalLobbyChannelMessage> & getChannelHistory(const std::string & channelType, const std::string & channelName) const;
/// Activate interface and pushes lobby UI as top window
void activateInterface();
void sendMatchChatMessage(const std::string & messageText);
void sendMessage(const JsonNode & data);
void sendClientRegister(const std::string & accountName);
void sendClientLogin();

View File

@ -23,7 +23,8 @@ struct GlobalLobbyRoom
std::string hostAccountDisplayName;
std::string description;
std::string statusID;
int playersCount;
std::string startDateFormatted;
std::vector<GlobalLobbyAccount> participants;
int playerLimit;
};
@ -34,10 +35,3 @@ struct GlobalLobbyChannelMessage
std::string displayName;
std::string messageText;
};
struct GlobalLobbyHistoryMatch
{
std::string gameRoomID;
std::string startDateFormatted;
std::vector<std::string> opponentDisplayNames;
};

View File

@ -133,6 +133,11 @@ std::shared_ptr<CListBox> GlobalLobbyWidget::getRoomList()
return widget<CListBox>("roomList");
}
std::shared_ptr<CListBox> GlobalLobbyWidget::getMatchList()
{
return widget<CListBox>("matchList");
}
GlobalLobbyChannelCardBase::GlobalLobbyChannelCardBase(GlobalLobbyWindow * window, const std::string & channelType, const std::string & channelName)
: window(window)
, channelType(channelType)
@ -169,7 +174,7 @@ GlobalLobbyRoomCard::GlobalLobbyRoomCard(GlobalLobbyWindow * window, const Globa
};
auto roomSizeText = MetaString::createFromRawString("%d/%d");
roomSizeText.replaceNumber(roomDescription.playersCount);
roomSizeText.replaceNumber(roomDescription.participants.size());
roomSizeText.replaceNumber(roomDescription.playerLimit);
auto roomStatusText = MetaString::createFromTextID("vcmi.lobby.room.state." + roomDescription.statusID);
@ -203,7 +208,7 @@ GlobalLobbyChannelCard::GlobalLobbyChannelCard(GlobalLobbyWindow * window, const
labelName = std::make_shared<CLabel>(5, 20, FONT_SMALL, ETextAlignment::CENTERLEFT, Colors::WHITE, Languages::getLanguageOptions(channelName).nameNative);
}
GlobalLobbyMatchCard::GlobalLobbyMatchCard(GlobalLobbyWindow * window, const GlobalLobbyHistoryMatch & matchDescription)
GlobalLobbyMatchCard::GlobalLobbyMatchCard(GlobalLobbyWindow * window, const GlobalLobbyRoom & matchDescription)
: GlobalLobbyChannelCardBase(window, "match", matchDescription.gameRoomID)
{
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
@ -216,16 +221,16 @@ GlobalLobbyMatchCard::GlobalLobbyMatchCard(GlobalLobbyWindow * window, const Glo
MetaString opponentDescription;
if (matchDescription.opponentDisplayNames.empty())
if (matchDescription.participants.size() == 1)
opponentDescription.appendRawString("Solo game"); // or "Singleplayer game" is better?
if (matchDescription.opponentDisplayNames.size() == 1)
opponentDescription.appendRawString(matchDescription.opponentDisplayNames[0]);
if (matchDescription.participants.size() == 2)
opponentDescription.appendRawString(matchDescription.participants[0].displayName);//FIXME: find opponent - not our player
if (matchDescription.opponentDisplayNames.size() > 1)
if (matchDescription.participants.size() > 2)
{
opponentDescription.appendRawString("%d players");
opponentDescription.replaceNumber(matchDescription.opponentDisplayNames.size());
opponentDescription.replaceNumber(matchDescription.participants.size());
}
labelMatchOpponent = std::make_shared<CLabel>(5, 30, FONT_SMALL, ETextAlignment::CENTERLEFT, Colors::YELLOW, opponentDescription.toString());

View File

@ -14,7 +14,6 @@
class GlobalLobbyWindow;
struct GlobalLobbyAccount;
struct GlobalLobbyRoom;
struct GlobalLobbyHistoryMatch;
class CListBox;
class GlobalLobbyWidget : public InterfaceObjectConfigurable
@ -90,5 +89,5 @@ class GlobalLobbyMatchCard : public GlobalLobbyChannelCardBase
std::shared_ptr<CLabel> labelMatchOpponent;
public:
GlobalLobbyMatchCard(GlobalLobbyWindow * window, const GlobalLobbyHistoryMatch & matchDescription);
GlobalLobbyMatchCard(GlobalLobbyWindow * window, const GlobalLobbyRoom & matchDescription);
};

View File

@ -113,12 +113,20 @@ void GlobalLobbyWindow::onActiveAccounts(const std::vector<GlobalLobbyAccount> &
void GlobalLobbyWindow::onActiveRooms(const std::vector<GlobalLobbyRoom> & rooms)
{
if (rooms.size() == widget->getAccountList()->size())
if (rooms.size() == widget->getRoomList()->size())
widget->getRoomList()->reset();
else
widget->getRoomList()->resize(rooms.size());
}
void GlobalLobbyWindow::onMatchesHistory(const std::vector<GlobalLobbyRoom> & history)
{
if (history.size() == widget->getMatchList()->size())
widget->getMatchList()->reset();
else
widget->getMatchList()->resize(history.size());
}
void GlobalLobbyWindow::onJoinedRoom()
{
widget->getAccountList()->reset();

View File

@ -39,6 +39,7 @@ public:
void onGameChatMessage(const std::string & sender, const std::string & message, const std::string & when, const std::string & channelType, const std::string & channelName);
void onActiveAccounts(const std::vector<GlobalLobbyAccount> & accounts);
void onActiveRooms(const std::vector<GlobalLobbyRoom> & rooms);
void onMatchesHistory(const std::vector<GlobalLobbyRoom> & history);
void onJoinedRoom();
void onLeftRoom();
};

View File

@ -20,7 +20,7 @@
{
"type" : "object",
"additionalProperties" : false,
"required" : [ "gameRoomID", "hostAccountID", "hostAccountDisplayName", "description", "playersCount", "playerLimit", "status" ],
"required" : [ "gameRoomID", "hostAccountID", "hostAccountDisplayName", "description", "participants", "playerLimit", "status" ],
"properties" : {
"gameRoomID" :
{
@ -42,10 +42,28 @@
"type" : "string",
"description" : "Auto-generated description of this room"
},
"playersCount" :
"participants" :
{
"type" : "number",
"description" : "Current number of players in this room, including host"
"type" : "array",
"description" : "List of accounts in the room, including host",
"items" :
{
"type" : "object",
"additionalProperties" : false,
"required" : [ "accountID", "displayName" ],
"properties" : {
"accountID" :
{
"type" : "string",
"description" : "Unique ID of an account"
},
"displayName" :
{
"type" : "string",
"description" : "Display name of an account"
}
}
}
},
"status" :
{

View File

@ -53,7 +53,7 @@
{
"type": "labelTitle",
"position": {"x": 15, "y": 53},
"text" : "Room List"
"text" : "vcmi.lobby.header.rooms"
},
{
"type" : "lobbyItemList",
@ -73,7 +73,7 @@
{
"type": "labelTitle",
"position": {"x": 280, "y": 53},
"text" : "Channel List"
"text" : "vcmi.lobby.header.channels"
},
{
"type" : "lobbyItemList",
@ -91,7 +91,7 @@
{
"type": "labelTitle",
"position": {"x": 280, "y": 213},
"text" : "Games History"
"text" : "vcmi.lobby.header.history"
},
{
"type" : "lobbyItemList",
@ -111,7 +111,7 @@
{
"type": "labelTitle",
"position": {"x": 440, "y": 53},
"text" : "Game Chat"
"text" : "vcmi.lobby.header.chat"
},
{
"type": "textBox",
@ -141,7 +141,7 @@
{
"type": "labelTitle",
"position": {"x": 880, "y": 53},
"text" : "Account List"
"text" : "vcmi.lobby.header.players"
},
{
"type" : "lobbyItemList",

View File

@ -89,6 +89,7 @@ void LobbyDatabase::clearOldData()
WHERE online <> 0
)";
//FIXME: set different status for rooms that never reached in game state
static const std::string removeActiveRooms = R"(
UPDATE gameRooms
SET status = 5
@ -201,6 +202,14 @@ void LobbyDatabase::prepareStatements()
WHERE roomID = ?
)";
static const std::string getAccountGameHistoryText = R"(
SELECT gr.roomID, hostAccountID, displayName, description, status, playerLimit
FROM gameRoomPlayers grp
LEFT JOIN gameRooms gr ON gr.roomID = grp.roomID
LEFT JOIN accounts a ON gr.hostAccountID = a.accountID
WHERE grp.accountID = ? AND status IN (4,5)
)";
static const std::string getAccountGameRoomText = R"(
SELECT grp.roomID
FROM gameRoomPlayers grp
@ -223,8 +232,9 @@ void LobbyDatabase::prepareStatements()
)";
static const std::string countRoomUsedSlotsText = R"(
SELECT COUNT(accountID)
FROM gameRoomPlayers
SELECT a.accountID, a.displayName
FROM gameRoomPlayers grp
LEFT JOIN accounts a ON a.accountID = grp.accountID
WHERE roomID = ?
)";
@ -298,6 +308,7 @@ void LobbyDatabase::prepareStatements()
getFullMessageHistoryStatement = database->prepare(getFullMessageHistoryText);
getIdleGameRoomStatement = database->prepare(getIdleGameRoomText);
getGameRoomStatusStatement = database->prepare(getGameRoomStatusText);
getAccountGameHistoryStatement = database->prepare(getAccountGameHistoryText);
getAccountGameRoomStatement = database->prepare(getAccountGameRoomText);
getActiveAccountsStatement = database->prepare(getActiveAccountsText);
getActiveGameRoomsStatement = database->prepare(getActiveGameRoomsText);
@ -545,8 +556,39 @@ std::vector<LobbyGameRoom> LobbyDatabase::getActiveGameRooms()
for (auto & room : result)
{
countRoomUsedSlotsStatement->setBinds(room.roomID);
if(countRoomUsedSlotsStatement->execute())
countRoomUsedSlotsStatement->getColumns(room.playersCount);
while(countRoomUsedSlotsStatement->execute())
{
LobbyAccount account;
countRoomUsedSlotsStatement->getColumns(account.accountID, account.displayName);
room.participants.push_back(account);
}
countRoomUsedSlotsStatement->reset();
}
return result;
}
std::vector<LobbyGameRoom> LobbyDatabase::getAccountGameHistory(const std::string & accountID)
{
std::vector<LobbyGameRoom> result;
getAccountGameHistoryStatement->setBinds(accountID);
while(getAccountGameHistoryStatement->execute())
{
LobbyGameRoom entry;
getAccountGameHistoryStatement->getColumns(entry.roomID, entry.hostAccountID, entry.hostAccountDisplayName, entry.description, entry.roomState, entry.playerLimit);
result.push_back(entry);
}
getAccountGameHistoryStatement->reset();
for (auto & room : result)
{
countRoomUsedSlotsStatement->setBinds(room.roomID);
while(countRoomUsedSlotsStatement->execute())
{
LobbyAccount account;
countRoomUsedSlotsStatement->getColumns(account.accountID, account.displayName);
room.participants.push_back(account);
}
countRoomUsedSlotsStatement->reset();
}
return result;

View File

@ -41,6 +41,7 @@ class LobbyDatabase
SQLiteStatementPtr getFullMessageHistoryStatement;
SQLiteStatementPtr getIdleGameRoomStatement;
SQLiteStatementPtr getGameRoomStatusStatement;
SQLiteStatementPtr getAccountGameHistoryStatement;
SQLiteStatementPtr getActiveGameRoomsStatement;
SQLiteStatementPtr getActiveAccountsStatement;
SQLiteStatementPtr getAccountGameRoomStatement;
@ -81,6 +82,7 @@ public:
void updateRoomPlayerLimit(const std::string & gameRoomID, int playerLimit);
void updateRoomDescription(const std::string & gameRoomID, const std::string & description);
std::vector<LobbyGameRoom> getAccountGameHistory(const std::string & accountID);
std::vector<LobbyGameRoom> getActiveGameRooms();
std::vector<LobbyAccount> getActiveAccounts();
std::vector<LobbyChatMessage> getRecentMessageHistory(const std::string & channelType, const std::string & channelName);

View File

@ -44,8 +44,8 @@ struct LobbyGameRoom
std::string hostAccountID;
std::string hostAccountDisplayName;
std::string description;
std::vector<LobbyAccount> participants;
LobbyRoomState roomState;
uint32_t playersCount;
uint32_t playerLimit;
};

View File

@ -167,14 +167,53 @@ void LobbyServer::broadcastActiveAccounts()
sendMessage(connection.first, reply);
}
static constexpr std::array LOBBY_ROOM_STATE_NAMES = {
"idle",
"public",
"private",
"busy",
"cancelled",
"closed"
};
static JsonNode loadLobbyAccountToJson(const LobbyAccount & account)
{
JsonNode jsonEntry;
jsonEntry["accountID"].String() = account.accountID;
jsonEntry["displayName"].String() = account.displayName;
return jsonEntry;
}
static JsonNode loadLobbyGameRoomToJson(const LobbyGameRoom & gameRoom)
{
static constexpr std::array LOBBY_ROOM_STATE_NAMES = {
"idle",
"public",
"private",
"busy",
"cancelled",
"closed"
};
JsonNode jsonEntry;
jsonEntry["gameRoomID"].String() = gameRoom.roomID;
jsonEntry["hostAccountID"].String() = gameRoom.hostAccountID;
jsonEntry["hostAccountDisplayName"].String() = gameRoom.hostAccountDisplayName;
jsonEntry["description"].String() = gameRoom.description;
jsonEntry["status"].String() = LOBBY_ROOM_STATE_NAMES[vstd::to_underlying(gameRoom.roomState)];
jsonEntry["playerLimit"].Integer() = gameRoom.playerLimit;
for (auto const & account : gameRoom.participants)
jsonEntry["participants"].Vector().push_back(loadLobbyAccountToJson(account));
return jsonEntry;
}
void LobbyServer::sendMatchesHistory(const NetworkConnectionPtr & target)
{
std::string accountID = activeAccounts.at(target);
auto matchesHistory = database->getAccountGameHistory(accountID);
JsonNode reply;
reply["type"].String() = "matchesHistory";
reply["matchesHistory"].Vector(); // force creation of empty vector
for(const auto & gameRoom : matchesHistory)
reply["matchesHistory"].Vector().push_back(loadLobbyGameRoomToJson(gameRoom));
sendMessage(target, reply);
}
JsonNode LobbyServer::prepareActiveGameRooms()
{
@ -184,17 +223,7 @@ JsonNode LobbyServer::prepareActiveGameRooms()
reply["gameRooms"].Vector(); // force creation of empty vector
for(const auto & gameRoom : activeGameRoomStats)
{
JsonNode jsonEntry;
jsonEntry["gameRoomID"].String() = gameRoom.roomID;
jsonEntry["hostAccountID"].String() = gameRoom.hostAccountID;
jsonEntry["hostAccountDisplayName"].String() = gameRoom.hostAccountDisplayName;
jsonEntry["description"].String() = gameRoom.description;
jsonEntry["status"].String() = LOBBY_ROOM_STATE_NAMES[vstd::to_underlying(gameRoom.roomState)];
jsonEntry["playersCount"].Integer() = gameRoom.playersCount;
jsonEntry["playerLimit"].Integer() = gameRoom.playerLimit;
reply["gameRooms"].Vector().push_back(jsonEntry);
}
reply["gameRooms"].Vector().push_back(loadLobbyGameRoomToJson(gameRoom));
return reply;
}
@ -252,7 +281,12 @@ void LobbyServer::onDisconnected(const NetworkConnectionPtr & connection, const
if(activeGameRooms.count(connection))
{
database->setGameRoomStatus(activeGameRooms.at(connection), LobbyRoomState::CLOSED);
std::string gameRoomID = activeGameRooms.at(connection);
database->setGameRoomStatus(gameRoomID, LobbyRoomState::CLOSED);
for(const auto & connection : activeAccounts)
if (database->isPlayerInGameRoom(connection.second, gameRoomID))
sendMatchesHistory(connection.first);
activeGameRooms.erase(connection);
}
@ -458,9 +492,10 @@ void LobbyServer::receiveSendChatMessage(const NetworkConnectionPtr & connection
database->insertChatMessage(senderAccountID, channelType, channelName, messageText);
// TODO: Don't report match messages if room is still active - players in room will receive these messages via match server
for(const auto & otherConnection : activeAccounts)
{
if (database->isPlayerInGameRoom(senderAccountID, otherConnection.second))
if (database->isPlayerInGameRoom(otherConnection.second, channelName))
sendChatMessage(otherConnection.first, channelType, channelName, senderAccountID, displayName, messageText);
}
}
@ -536,6 +571,7 @@ void LobbyServer::receiveClientLogin(const NetworkConnectionPtr & connection, co
// and update acount list to everybody else including new account
broadcastActiveAccounts();
sendMessage(connection, prepareActiveGameRooms());
sendMatchesHistory(connection);
}
void LobbyServer::receiveServerLogin(const NetworkConnectionPtr & connection, const JsonNode & json)

View File

@ -76,6 +76,7 @@ class LobbyServer final : public INetworkServerListener
void sendAccountJoinsRoom(const NetworkConnectionPtr & target, const std::string & accountID);
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 sendMatchesHistory(const NetworkConnectionPtr & target);
void receiveClientRegister(const NetworkConnectionPtr & connection, const JsonNode & json);
void receiveClientLogin(const NetworkConnectionPtr & connection, const JsonNode & json);