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:
		| @@ -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.", | ||||||
|   | |||||||
| @@ -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(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -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"))); | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -9,4 +9,11 @@ | |||||||
|  */ |  */ | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| enum class ETextAlignment {TOPLEFT, TOPCENTER, CENTER, BOTTOMRIGHT}; | enum class ETextAlignment | ||||||
|  | { | ||||||
|  | 	TOPLEFT, | ||||||
|  | 	TOPCENTER, | ||||||
|  | 	TOPRIGHT, | ||||||
|  | 	CENTER, | ||||||
|  | 	BOTTOMRIGHT | ||||||
|  | }; | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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", | ||||||
|   | |||||||
| @@ -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} | ||||||
|   | |||||||
| @@ -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(); | ||||||
|   | |||||||
| @@ -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; | ||||||
|  | }; | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
| @@ -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) | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user