瀏覽代碼

Indicate rooms with active invites, fix invite acceptance

Ivan Savenko 1 年之前
父節點
當前提交
d59fb87504

+ 12 - 4
client/globalLobby/GlobalLobbyClient.cpp

@@ -285,13 +285,15 @@ void GlobalLobbyClient::receiveInviteReceived(const JsonNode & json)
 	auto lobbyWindowPtr = lobbyWindow.lock();
 	std::string gameRoomID = json["gameRoomID"].String();
 	std::string accountID = json["accountID"].String();
+
+	activeInvites.insert(gameRoomID);
 	if(lobbyWindowPtr)
 	{
 		std::string message = MetaString::createFromTextID("vcmi.lobby.invite.notification").toString();
 		std::string time = getCurrentTimeFormatted();
 
 		lobbyWindowPtr->onGameChatMessage("System", message, time, "player", accountID);
-		lobbyWindowPtr->onInviteReceived(gameRoomID, accountID);
+		lobbyWindowPtr->onInviteReceived(gameRoomID);
 	}
 
 	CCS->soundh->playSound(AudioPath::builtin("CHAT"));
@@ -299,8 +301,6 @@ void GlobalLobbyClient::receiveInviteReceived(const JsonNode & json)
 
 void GlobalLobbyClient::receiveJoinRoomSuccess(const JsonNode & json)
 {
-	currentGameRoomUUID = json["gameRoomID"].String();
-
 	if (json["proxyMode"].Bool())
 	{
 		CSH->resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOBBY_GUEST, {});
@@ -310,6 +310,9 @@ void GlobalLobbyClient::receiveJoinRoomSuccess(const JsonNode & json)
 		int16_t port = settings["lobby"]["port"].Integer();
 		CSH->connectToServer(hostname, port);
 	}
+
+	// NOTE: must be set after CSH->resetStateForLobby call
+	currentGameRoomUUID = json["gameRoomID"].String();
 }
 
 void GlobalLobbyClient::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & connection)
@@ -500,7 +503,7 @@ void GlobalLobbyClient::sendProxyConnectionLogin(const NetworkConnectionPtr & ne
 	toSend["type"].String() = "clientProxyLogin";
 	toSend["accountID"] = settings["lobby"]["accountID"];
 	toSend["accountCookie"] = settings["lobby"]["accountCookie"];
-	toSend["gameRoomID"] = settings["session"]["lobby"]["roomID"];
+	toSend["gameRoomID"].String() = currentGameRoomUUID;
 
 	assert(JsonUtils::validate(toSend, "vcmi:lobbyProtocol/" + toSend["type"].String(), toSend["type"].String() + " pack"));
 	netConnection->sendPacket(toSend.toBytes());
@@ -527,3 +530,8 @@ void GlobalLobbyClient::sendMatchChatMessage(const std::string & messageText)
 
 	CSH->getGlobalLobby().sendMessage(toSend);
 }
+
+bool GlobalLobbyClient::isInvitedToRoom(const std::string & gameRoomID)
+{
+	return activeInvites.count(gameRoomID) > 0;
+}

+ 2 - 0
client/globalLobby/GlobalLobbyClient.h

@@ -24,6 +24,7 @@ class GlobalLobbyClient final : public INetworkClientListener, boost::noncopyabl
 	std::vector<GlobalLobbyAccount> activeAccounts;
 	std::vector<GlobalLobbyRoom> activeRooms;
 	std::vector<std::string> activeChannels;
+	std::set<std::string> activeInvites;
 	std::vector<GlobalLobbyRoom> matchesHistory;
 
 	/// Contains known history of each channel
@@ -82,4 +83,5 @@ public:
 
 	void connect();
 	bool isConnected() const;
+	bool isInvitedToRoom(const std::string & gameRoomID);
 };

+ 15 - 3
client/globalLobby/GlobalLobbyWidget.cpp

@@ -217,23 +217,35 @@ GlobalLobbyRoomCard::GlobalLobbyRoomCard(GlobalLobbyWindow * window, const Globa
 		window->doJoinRoom(roomID);
 	};
 
+	bool publicRoom = roomDescription.statusID == "public";
+	bool hasInvite = CSH->getGlobalLobby().isInvitedToRoom(roomDescription.gameRoomID);
+	bool canJoin = publicRoom || hasInvite;
+
 	auto roomSizeText = MetaString::createFromRawString("%d/%d");
 	roomSizeText.replaceNumber(roomDescription.participants.size());
 	roomSizeText.replaceNumber(roomDescription.playerLimit);
 
-	auto roomStatusText = MetaString::createFromTextID("vcmi.lobby.room.state." + roomDescription.statusID);
+	MetaString roomStatusText;
+	if (roomDescription.statusID == "private" && hasInvite)
+		roomStatusText.appendTextID("vcmi.lobby.room.state.invited");
+	else
+		roomStatusText.appendTextID("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));
+	if (window->isInviteUnread(roomDescription.gameRoomID))
+		backgroundOverlay = std::make_shared<TransparentFilledRectangle>(Rect(0, 0, pos.w, pos.h), ColorRGBA(0, 0, 0, 128), Colors::WHITE, 1);
+	else
+		backgroundOverlay = std::make_shared<TransparentFilledRectangle>(Rect(0, 0, pos.w, pos.h), ColorRGBA(0, 0, 0, 128), ColorRGBA(64, 64, 64, 64), 1);
+
 	labelName = std::make_shared<CLabel>(5, 10, FONT_SMALL, ETextAlignment::CENTERLEFT, Colors::WHITE, roomDescription.hostAccountDisplayName);
 	labelDescription = std::make_shared<CLabel>(5, 30, FONT_SMALL, ETextAlignment::CENTERLEFT, Colors::YELLOW, roomDescription.description);
 	labelRoomSize = std::make_shared<CLabel>(178, 10, FONT_SMALL, ETextAlignment::CENTERRIGHT, Colors::YELLOW, roomSizeText.toString());
 	labelRoomStatus = std::make_shared<CLabel>(190, 30, FONT_SMALL, ETextAlignment::CENTERRIGHT, Colors::YELLOW, roomStatusText.toString());
 	iconRoomSize = std::make_shared<CPicture>(ImagePath::builtin("lobby/iconPlayer"), Point(180, 5));
 
-	if(!CSH->inGame() && roomDescription.statusID == "public")
+	if(!CSH->inGame() && canJoin)
 	{
 		buttonJoin = std::make_shared<CButton>(Point(194, 4), AnimationPath::builtin("lobbyJoinRoom"), CButton::tooltip(), onJoinClicked);
 		buttonJoin->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("lobby/iconEnter")));

+ 9 - 1
client/globalLobby/GlobalLobbyWindow.cpp

@@ -101,6 +101,8 @@ void GlobalLobbyWindow::doInviteAccount(const std::string & accountID)
 
 void GlobalLobbyWindow::doJoinRoom(const std::string & roomID)
 {
+	unreadInvites.erase(roomID);
+
 	JsonNode toSend;
 	toSend["type"].String() = "joinGameRoom";
 	toSend["gameRoomID"].String() = roomID;
@@ -172,11 +174,17 @@ void GlobalLobbyWindow::onMatchesHistory(const std::vector<GlobalLobbyRoom> & hi
 	widget->getMatchListHeader()->setText(text.toString());
 }
 
-void GlobalLobbyWindow::onInviteReceived(const std::string & invitedRoomID, const std::string & invitedByAccountID)
+void GlobalLobbyWindow::onInviteReceived(const std::string & invitedRoomID)
 {
+	unreadInvites.insert(invitedRoomID);
 	widget->getRoomList()->reset();
 }
 
+bool GlobalLobbyWindow::isInviteUnread(const std::string & gameRoomID)
+{
+	return unreadInvites.count(gameRoomID) > 0;
+}
+
 void GlobalLobbyWindow::onJoinedRoom()
 {
 	widget->getAccountList()->reset();

+ 3 - 1
client/globalLobby/GlobalLobbyWindow.h

@@ -23,6 +23,7 @@ class GlobalLobbyWindow : public CWindowObject
 
 	std::shared_ptr<GlobalLobbyWidget> widget;
 	std::set<std::string> unreadChannels;
+	std::set<std::string> unreadInvites;
 
 public:
 	GlobalLobbyWindow();
@@ -38,6 +39,7 @@ public:
 	/// Returns true if provided chat channel is the one that is currently open in UI
 	bool isChannelOpen(const std::string & channelType, const std::string & channelName);
 	bool isChannelUnread(const std::string & channelType, const std::string & channelName);
+	bool isInviteUnread(const std::string & gameRoomID);
 
 	// Callbacks for network packs
 
@@ -45,7 +47,7 @@ public:
 	void onActiveAccounts(const std::vector<GlobalLobbyAccount> & accounts);
 	void onActiveRooms(const std::vector<GlobalLobbyRoom> & rooms);
 	void onMatchesHistory(const std::vector<GlobalLobbyRoom> & history);
-	void onInviteReceived(const std::string & invitedRoomID, const std::string & invitedByAccountID);
+	void onInviteReceived(const std::string & invitedRoomID);
 	void onJoinedRoom();
 	void onLeftRoom();
 };

+ 1 - 1
config/schemas/lobbyProtocol/clientProxyLogin.json

@@ -10,7 +10,7 @@
 		"type" :
 		{
 			"type" : "string",
-			"const" : "clientLogin"
+			"const" : "clientProxyLogin"
 		},
 		"accountID" :
 		{