1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-21 17:17:06 +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.type" : "Room Type",
"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.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.hostAccountDisplayName = jsonEntry["hostAccountDisplayName"].String();
room.description = jsonEntry["description"].String();
room.statusID = jsonEntry["status"].String();
room.playersCount = jsonEntry["playersCount"].Integer();
room.playerLimit = jsonEntry["playerLimit"].Integer();

View File

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

View File

@ -144,16 +144,19 @@ GlobalLobbyRoomCard::GlobalLobbyRoomCard(GlobalLobbyWindow * window, const Globa
roomSizeText.replaceNumber(roomDescription.playersCount);
roomSizeText.replaceNumber(roomDescription.playerLimit);
auto roomStatusText = MetaString::createFromTextID("vcmi.lobby.room.state." + roomDescription.statusID);
pos.w = 230;
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));
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);
labelRoomSize = std::make_shared<CLabel>(160, 2, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::YELLOW, roomSizeText.toString());
iconRoomSize = std::make_shared<CPicture>(ImagePath::builtin("lobby/iconPlayer"), Point(145, 5));
labelRoomSize = std::make_shared<CLabel>(178, 2, FONT_SMALL, ETextAlignment::TOPRIGHT, Colors::YELLOW, roomSizeText.toString());
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->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("lobby/iconEnter")));

View File

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

View File

@ -9,4 +9,11 @@
*/
#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;
}
if(alignment == ETextAlignment::TOPRIGHT)
{
where.x += getBorderSize().x + destRect.w - ((int)f->getStringWidth(what) - delimitersCount);
where.y += getBorderSize().y;
}
if(alignment == ETextAlignment::CENTER)
{
where.x += (int(destRect.w) - int(f->getStringWidth(what) - delimitersCount)) / 2;

View File

@ -20,7 +20,7 @@
{
"type" : "object",
"additionalProperties" : false,
"required" : [ "gameRoomID", "hostAccountID", "hostAccountDisplayName", "description", "playersCount", "playerLimit" ],
"required" : [ "gameRoomID", "hostAccountID", "hostAccountDisplayName", "description", "playersCount", "playerLimit", "status" ],
"properties" : {
"gameRoomID" :
{
@ -47,6 +47,12 @@
"type" : "number",
"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" :
{
"type" : "number",

View File

@ -67,7 +67,7 @@
{
"type": "areaFilled",
"rect": {"x": 270, "y": 50, "w": 150, "h": 540}
"rect": {"x": 270, "y": 50, "w": 150, "h": 140}
},
{
"type": "labelTitle",
@ -75,6 +75,16 @@
"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",
"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
FROM gameRooms
LEFT JOIN accounts ON hostAccountID = accountID
WHERE status = 1
WHERE status IN (1, 2)
)";
static const std::string countRoomUsedSlotsText = R"(
@ -449,16 +449,16 @@ LobbyInviteStatus LobbyDatabase::getAccountInviteStatus(const std::string & acco
LobbyRoomState LobbyDatabase::getGameRoomStatus(const std::string & roomID)
{
int result = -1;
LobbyRoomState result;
getGameRoomStatusStatement->setBinds(roomID);
if(getGameRoomStatusStatement->execute())
getGameRoomStatusStatement->getColumns(result);
getGameRoomStatusStatement->reset();
else
result = LobbyRoomState::CLOSED;
if (result != -1)
return static_cast<LobbyRoomState>(result);
return LobbyRoomState::CLOSED;
getGameRoomStatusStatement->reset();
return result;
}
uint32_t LobbyDatabase::getGameRoomFreeSlots(const std::string & roomID)
@ -511,7 +511,7 @@ std::vector<LobbyGameRoom> LobbyDatabase::getActiveGameRooms()
while(getActiveGameRoomsStatement->execute())
{
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);
}
getActiveGameRoomsStatement->reset();

View File

@ -9,31 +9,6 @@
*/
#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
{
INVALID,
@ -52,7 +27,32 @@ enum class LobbyRoomState : int32_t
IDLE = 0, // server is ready but no players are in the room
PUBLIC = 1, // host has joined and allows anybody to join
PRIVATE = 2, // host has joined but only allows those he invited to join
//BUSY = 3, // match is ongoing
//CANCELLED = 4, // game room was cancelled without starting the game
BUSY = 3, // match is ongoing and no longer accepts players
CANCELLED = 4, // game room was cancelled without starting the game
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);
}
static constexpr std::array LOBBY_ROOM_STATE_NAMES = {
"idle",
"public",
"private",
"busy",
"cancelled",
"closed"
};
JsonNode LobbyServer::prepareActiveGameRooms()
{
auto activeGameRoomStats = database->getActiveGameRooms();
@ -163,6 +172,7 @@ JsonNode LobbyServer::prepareActiveGameRooms()
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);

View File

@ -69,6 +69,16 @@ private:
void getColumnSingle(size_t index, int64_t & 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>
void getColumnSingle(size_t index, std::chrono::duration<Rep, Period> & value)
{