1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-10-31 00:07:39 +02:00

Show all rooms (including private) in room list

This commit is contained in:
Ivan Savenko
2024-03-12 19:52:42 +02:00
parent dcf35e4877
commit 7c9aa9d953
13 changed files with 98 additions and 40 deletions

View File

@@ -92,6 +92,9 @@
"vcmi.lobby.room.load" : "Load Game", "vcmi.lobby.room.load" : "Load Game",
"vcmi.lobby.room.type" : "Room Type", "vcmi.lobby.room.type" : "Room Type",
"vcmi.lobby.room.mode" : "Game Mode", "vcmi.lobby.room.mode" : "Game Mode",
"vcmi.lobby.room.state.public" : "Public",
"vcmi.lobby.room.state.private" : "Private",
"vcmi.lobby.room.state.busy" : "Busy", // Alternative translations: in game / playing
"vcmi.client.errors.invalidMap" : "{Invalid map or campaign}\n\nFailed to start game! Selected map or campaign might be invalid or corrupted. Reason:\n%s", "vcmi.client.errors.invalidMap" : "{Invalid map or campaign}\n\nFailed to start game! Selected map or campaign might be invalid or corrupted. Reason:\n%s",
"vcmi.client.errors.missingCampaigns" : "{Missing data files}\n\nCampaigns data files were not found! You may be using incomplete or corrupted Heroes 3 data files. Please reinstall game data.", "vcmi.client.errors.missingCampaigns" : "{Missing data files}\n\nCampaigns data files were not found! You may be using incomplete or corrupted Heroes 3 data files. Please reinstall game data.",

View File

@@ -183,6 +183,7 @@ void GlobalLobbyClient::receiveActiveGameRooms(const JsonNode & json)
room.hostAccountID = jsonEntry["hostAccountID"].String(); room.hostAccountID = jsonEntry["hostAccountID"].String();
room.hostAccountDisplayName = jsonEntry["hostAccountDisplayName"].String(); room.hostAccountDisplayName = jsonEntry["hostAccountDisplayName"].String();
room.description = jsonEntry["description"].String(); room.description = jsonEntry["description"].String();
room.statusID = jsonEntry["status"].String();
room.playersCount = jsonEntry["playersCount"].Integer(); room.playersCount = jsonEntry["playersCount"].Integer();
room.playerLimit = jsonEntry["playerLimit"].Integer(); room.playerLimit = jsonEntry["playerLimit"].Integer();

View File

@@ -22,6 +22,7 @@ struct GlobalLobbyRoom
std::string hostAccountID; std::string hostAccountID;
std::string hostAccountDisplayName; std::string hostAccountDisplayName;
std::string description; std::string description;
std::string statusID;
int playersCount; int playersCount;
int playerLimit; int playerLimit;
}; };

View File

@@ -144,16 +144,19 @@ GlobalLobbyRoomCard::GlobalLobbyRoomCard(GlobalLobbyWindow * window, const Globa
roomSizeText.replaceNumber(roomDescription.playersCount); roomSizeText.replaceNumber(roomDescription.playersCount);
roomSizeText.replaceNumber(roomDescription.playerLimit); roomSizeText.replaceNumber(roomDescription.playerLimit);
auto roomStatusText = MetaString::createFromTextID("vcmi.lobby.room.state." + roomDescription.statusID);
pos.w = 230; pos.w = 230;
pos.h = 40; pos.h = 40;
backgroundOverlay = std::make_shared<TransparentFilledRectangle>(Rect(0, 0, pos.w, pos.h), ColorRGBA(0, 0, 0, 128), ColorRGBA(64, 64, 64, 64)); backgroundOverlay = std::make_shared<TransparentFilledRectangle>(Rect(0, 0, pos.w, pos.h), ColorRGBA(0, 0, 0, 128), ColorRGBA(64, 64, 64, 64));
labelName = std::make_shared<CLabel>(5, 2, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, roomDescription.hostAccountDisplayName); labelName = std::make_shared<CLabel>(5, 2, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, roomDescription.hostAccountDisplayName);
labelDescription = std::make_shared<CLabel>(5, 20, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, roomDescription.description); labelDescription = std::make_shared<CLabel>(5, 20, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, roomDescription.description);
labelRoomSize = std::make_shared<CLabel>(160, 2, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, roomSizeText.toString()); labelRoomSize = std::make_shared<CLabel>(178, 2, FONT_SMALL, ETextAlignment::TOPRIGHT, Colors::YELLOW, roomSizeText.toString());
iconRoomSize = std::make_shared<CPicture>(ImagePath::builtin("lobby/iconPlayer"), Point(145, 5)); labelRoomStatus = std::make_shared<CLabel>(190, 20, FONT_SMALL, ETextAlignment::TOPRIGHT, Colors::YELLOW, roomStatusText.toString());
iconRoomSize = std::make_shared<CPicture>(ImagePath::builtin("lobby/iconPlayer"), Point(180, 5));
if(!CSH->inGame()) if(!CSH->inGame() && roomDescription.statusID == "public")
{ {
buttonJoin = std::make_shared<CButton>(Point(194, 4), AnimationPath::builtin("lobbyJoinRoom"), CButton::tooltip(), onJoinClicked); buttonJoin = std::make_shared<CButton>(Point(194, 4), AnimationPath::builtin("lobbyJoinRoom"), CButton::tooltip(), onJoinClicked);
buttonJoin->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("lobby/iconEnter"))); buttonJoin->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("lobby/iconEnter")));

View File

@@ -52,6 +52,7 @@ public:
std::shared_ptr<TransparentFilledRectangle> backgroundOverlay; std::shared_ptr<TransparentFilledRectangle> backgroundOverlay;
std::shared_ptr<CLabel> labelName; std::shared_ptr<CLabel> labelName;
std::shared_ptr<CLabel> labelRoomSize; std::shared_ptr<CLabel> labelRoomSize;
std::shared_ptr<CLabel> labelRoomStatus;
std::shared_ptr<CLabel> labelDescription; std::shared_ptr<CLabel> labelDescription;
std::shared_ptr<CButton> buttonJoin; std::shared_ptr<CButton> buttonJoin;
std::shared_ptr<CPicture> iconRoomSize; std::shared_ptr<CPicture> iconRoomSize;

View File

@@ -9,4 +9,11 @@
*/ */
#pragma once #pragma once
enum class ETextAlignment {TOPLEFT, TOPCENTER, CENTER, BOTTOMRIGHT}; enum class ETextAlignment
{
TOPLEFT,
TOPCENTER,
TOPRIGHT,
CENTER,
BOTTOMRIGHT
};

View File

@@ -195,6 +195,12 @@ void CTextContainer::blitLine(Canvas & to, Rect destRect, std::string what)
where.y += getBorderSize().y; where.y += getBorderSize().y;
} }
if(alignment == ETextAlignment::TOPRIGHT)
{
where.x += getBorderSize().x + destRect.w - ((int)f->getStringWidth(what) - delimitersCount);
where.y += getBorderSize().y;
}
if(alignment == ETextAlignment::CENTER) if(alignment == ETextAlignment::CENTER)
{ {
where.x += (int(destRect.w) - int(f->getStringWidth(what) - delimitersCount)) / 2; where.x += (int(destRect.w) - int(f->getStringWidth(what) - delimitersCount)) / 2;

View File

@@ -20,7 +20,7 @@
{ {
"type" : "object", "type" : "object",
"additionalProperties" : false, "additionalProperties" : false,
"required" : [ "gameRoomID", "hostAccountID", "hostAccountDisplayName", "description", "playersCount", "playerLimit" ], "required" : [ "gameRoomID", "hostAccountID", "hostAccountDisplayName", "description", "playersCount", "playerLimit", "status" ],
"properties" : { "properties" : {
"gameRoomID" : "gameRoomID" :
{ {
@@ -47,6 +47,12 @@
"type" : "number", "type" : "number",
"description" : "Current number of players in this room, including host" "description" : "Current number of players in this room, including host"
}, },
"status" :
{
"type" : "string",
"enum" : [ "idle", "public", "private", "busy", "cancelled", "closed" ],
"description" : "Current status of game room"
},
"playerLimit" : "playerLimit" :
{ {
"type" : "number", "type" : "number",

View File

@@ -67,7 +67,7 @@
{ {
"type": "areaFilled", "type": "areaFilled",
"rect": {"x": 270, "y": 50, "w": 150, "h": 540} "rect": {"x": 270, "y": 50, "w": 150, "h": 140}
}, },
{ {
"type": "labelTitle", "type": "labelTitle",
@@ -75,6 +75,16 @@
"text" : "Channel List" "text" : "Channel List"
}, },
{
"type": "areaFilled",
"rect": {"x": 270, "y": 200, "w": 150, "h": 390}
},
{
"type": "labelTitle",
"position": {"x": 280, "y": 203},
"text" : "Games History"
},
{ {
"type": "areaFilled", "type": "areaFilled",
"rect": {"x": 430, "y": 50, "w": 430, "h": 515} "rect": {"x": 430, "y": 50, "w": 430, "h": 515}

View File

@@ -210,7 +210,7 @@ void LobbyDatabase::prepareStatements()
SELECT roomID, hostAccountID, displayName, description, status, playerLimit SELECT roomID, hostAccountID, displayName, description, status, playerLimit
FROM gameRooms FROM gameRooms
LEFT JOIN accounts ON hostAccountID = accountID LEFT JOIN accounts ON hostAccountID = accountID
WHERE status = 1 WHERE status IN (1, 2)
)"; )";
static const std::string countRoomUsedSlotsText = R"( static const std::string countRoomUsedSlotsText = R"(
@@ -449,16 +449,16 @@ LobbyInviteStatus LobbyDatabase::getAccountInviteStatus(const std::string & acco
LobbyRoomState LobbyDatabase::getGameRoomStatus(const std::string & roomID) LobbyRoomState LobbyDatabase::getGameRoomStatus(const std::string & roomID)
{ {
int result = -1; LobbyRoomState result;
getGameRoomStatusStatement->setBinds(roomID); getGameRoomStatusStatement->setBinds(roomID);
if(getGameRoomStatusStatement->execute()) if(getGameRoomStatusStatement->execute())
getGameRoomStatusStatement->getColumns(result); getGameRoomStatusStatement->getColumns(result);
getGameRoomStatusStatement->reset(); else
result = LobbyRoomState::CLOSED;
if (result != -1) getGameRoomStatusStatement->reset();
return static_cast<LobbyRoomState>(result); return result;
return LobbyRoomState::CLOSED;
} }
uint32_t LobbyDatabase::getGameRoomFreeSlots(const std::string & roomID) uint32_t LobbyDatabase::getGameRoomFreeSlots(const std::string & roomID)
@@ -511,7 +511,7 @@ std::vector<LobbyGameRoom> LobbyDatabase::getActiveGameRooms()
while(getActiveGameRoomsStatement->execute()) while(getActiveGameRoomsStatement->execute())
{ {
LobbyGameRoom entry; LobbyGameRoom entry;
getActiveGameRoomsStatement->getColumns(entry.roomID, entry.hostAccountID, entry.hostAccountDisplayName, entry.description, entry.roomStatus, entry.playerLimit); getActiveGameRoomsStatement->getColumns(entry.roomID, entry.hostAccountID, entry.hostAccountDisplayName, entry.description, entry.roomState, entry.playerLimit);
result.push_back(entry); result.push_back(entry);
} }
getActiveGameRoomsStatement->reset(); getActiveGameRoomsStatement->reset();

View File

@@ -9,31 +9,6 @@
*/ */
#pragma once #pragma once
struct LobbyAccount
{
std::string accountID;
std::string displayName;
};
struct LobbyGameRoom
{
std::string roomID;
std::string hostAccountID;
std::string hostAccountDisplayName;
std::string description;
std::string roomStatus;
uint32_t playersCount;
uint32_t playerLimit;
};
struct LobbyChatMessage
{
std::string accountID;
std::string displayName;
std::string messageText;
std::chrono::seconds age;
};
enum class LobbyCookieStatus : int32_t enum class LobbyCookieStatus : int32_t
{ {
INVALID, INVALID,
@@ -52,7 +27,32 @@ enum class LobbyRoomState : int32_t
IDLE = 0, // server is ready but no players are in the room IDLE = 0, // server is ready but no players are in the room
PUBLIC = 1, // host has joined and allows anybody to join PUBLIC = 1, // host has joined and allows anybody to join
PRIVATE = 2, // host has joined but only allows those he invited to join PRIVATE = 2, // host has joined but only allows those he invited to join
//BUSY = 3, // match is ongoing BUSY = 3, // match is ongoing and no longer accepts players
//CANCELLED = 4, // game room was cancelled without starting the game CANCELLED = 4, // game room was cancelled without starting the game
CLOSED = 5, // game room was closed after playing for some time CLOSED = 5, // game room was closed after playing for some time
}; };
struct LobbyAccount
{
std::string accountID;
std::string displayName;
};
struct LobbyGameRoom
{
std::string roomID;
std::string hostAccountID;
std::string hostAccountDisplayName;
std::string description;
LobbyRoomState roomState;
uint32_t playersCount;
uint32_t playerLimit;
};
struct LobbyChatMessage
{
std::string accountID;
std::string displayName;
std::string messageText;
std::chrono::seconds age;
};

View File

@@ -149,6 +149,15 @@ void LobbyServer::broadcastActiveAccounts()
sendMessage(connection.first, reply); sendMessage(connection.first, reply);
} }
static constexpr std::array LOBBY_ROOM_STATE_NAMES = {
"idle",
"public",
"private",
"busy",
"cancelled",
"closed"
};
JsonNode LobbyServer::prepareActiveGameRooms() JsonNode LobbyServer::prepareActiveGameRooms()
{ {
auto activeGameRoomStats = database->getActiveGameRooms(); auto activeGameRoomStats = database->getActiveGameRooms();
@@ -163,6 +172,7 @@ JsonNode LobbyServer::prepareActiveGameRooms()
jsonEntry["hostAccountID"].String() = gameRoom.hostAccountID; jsonEntry["hostAccountID"].String() = gameRoom.hostAccountID;
jsonEntry["hostAccountDisplayName"].String() = gameRoom.hostAccountDisplayName; jsonEntry["hostAccountDisplayName"].String() = gameRoom.hostAccountDisplayName;
jsonEntry["description"].String() = gameRoom.description; jsonEntry["description"].String() = gameRoom.description;
jsonEntry["status"].String() = LOBBY_ROOM_STATE_NAMES[vstd::to_underlying(gameRoom.roomState)];
jsonEntry["playersCount"].Integer() = gameRoom.playersCount; jsonEntry["playersCount"].Integer() = gameRoom.playersCount;
jsonEntry["playerLimit"].Integer() = gameRoom.playerLimit; jsonEntry["playerLimit"].Integer() = gameRoom.playerLimit;
reply["gameRooms"].Vector().push_back(jsonEntry); reply["gameRooms"].Vector().push_back(jsonEntry);

View File

@@ -69,6 +69,16 @@ private:
void getColumnSingle(size_t index, int64_t & value); void getColumnSingle(size_t index, int64_t & value);
void getColumnSingle(size_t index, std::string & value); void getColumnSingle(size_t index, std::string & value);
template < typename T, typename std::enable_if_t < std::is_enum_v<T>, int > = 0 >
void getColumnSingle(size_t index, T & value)
{
using Integer = std::underlying_type_t<T>;
Integer result;
getColumnSingle(index, result);
value = static_cast<T>(result);
}
template<typename Rep, typename Period> template<typename Rep, typename Period>
void getColumnSingle(size_t index, std::chrono::duration<Rep, Period> & value) void getColumnSingle(size_t index, std::chrono::duration<Rep, Period> & value)
{ {