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:
parent
4ed961fb96
commit
829b754091
@ -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.",
|
||||
|
@ -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" : "Будь-хто з гравців може приєднатися до публічної кімнати.",
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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" :
|
||||
{
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user