From ce254f8b46e5dcc82a70ebda40440aef5b976839 Mon Sep 17 00:00:00 2001 From: Gustas <37534529+PunkPun@users.noreply.github.com> Date: Wed, 10 Aug 2022 12:58:59 +0300 Subject: [PATCH] Add per player mutes --- OpenRA.Game/Network/OrderManager.cs | 2 ++ OpenRA.Game/TextNotificationsManager.cs | 3 ++ .../Logic/Ingame/GameInfoStatsLogic.cs | 29 +++++++++++++++++-- .../Widgets/Logic/Ingame/IngameChatLogic.cs | 8 +++++ mods/cnc/chrome.yaml | 27 +++++++++++++++++ mods/cnc/chrome/ingame-infostats.yaml | 14 +++++++++ mods/common/chrome/ingame-infostats.yaml | 14 +++++++++ mods/common/languages/en.ftl | 4 +++ mods/d2k/chrome.yaml | 27 +++++++++++++++++ mods/d2k/chrome/ingame-infostats.yaml | 14 +++++++++ mods/ra/chrome.yaml | 27 +++++++++++++++++ mods/ts/chrome.yaml | 27 +++++++++++++++++ 12 files changed, 193 insertions(+), 3 deletions(-) diff --git a/OpenRA.Game/Network/OrderManager.cs b/OpenRA.Game/Network/OrderManager.cs index 37c4e11a03..1faf4722b4 100644 --- a/OpenRA.Game/Network/OrderManager.cs +++ b/OpenRA.Game/Network/OrderManager.cs @@ -27,6 +27,8 @@ namespace OpenRA.Network readonly Dictionary syncForFrame = new Dictionary(); public Session LobbyInfo = new Session(); + + /// Null when watching a replay public Session.Client LocalClient => LobbyInfo.ClientWithIndex(Connection.LocalClientId); public World World; public int OrderQueueLength => pendingOrders.Count > 0 ? pendingOrders.Min(q => q.Value.Count) : 0; diff --git a/OpenRA.Game/TextNotificationsManager.cs b/OpenRA.Game/TextNotificationsManager.cs index e709f76329..63f320f6b8 100644 --- a/OpenRA.Game/TextNotificationsManager.cs +++ b/OpenRA.Game/TextNotificationsManager.cs @@ -21,6 +21,8 @@ namespace OpenRA static readonly string SystemMessageLabel; public static long ChatDisabledUntil { get; internal set; } + public static readonly Dictionary MutedPlayers = new Dictionary(); + static readonly List NotificationsCache = new List(); public static IReadOnlyList Notifications => NotificationsCache; @@ -94,6 +96,7 @@ namespace OpenRA public static void Clear() { NotificationsCache.Clear(); + MutedPlayers.Clear(); } } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs index 47e254e4c1..e5d0e3c816 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/GameInfoStatsLogic.cs @@ -22,11 +22,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic { class GameInfoStatsLogic : ChromeLogic { + [TranslationReference] + static readonly string Unmute = "unmute"; + + [TranslationReference] + static readonly string Mute = "mute"; + [ObjectCreator.UseCtor] - public GameInfoStatsLogic(Widget widget, World world, OrderManager orderManager, WorldRenderer worldRenderer, Action hideMenu) + public GameInfoStatsLogic(Widget widget, ModData modData, World world, OrderManager orderManager, WorldRenderer worldRenderer, Action hideMenu) { var player = world.LocalPlayer; var playerPanel = widget.Get("PLAYER_LIST"); + var statsHeader = widget.Get("STATS_HEADERS"); if (player != null && !player.NonCombatant) { @@ -51,7 +58,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic { // Expand the stats window to cover the hidden objectives var objectiveGroup = widget.Get("OBJECTIVE"); - var statsHeader = widget.Get("STATS_HEADERS"); objectiveGroup.Visible = false; statsHeader.Bounds.Y -= objectiveGroup.Bounds.Height; @@ -59,9 +65,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic playerPanel.Bounds.Height += objectiveGroup.Bounds.Height; } + if (!orderManager.LobbyInfo.Clients.Any(c => !c.IsBot && c.Index != orderManager.LocalClient?.Index && c.State != Session.ClientState.Disconnected)) + statsHeader.Get("ACTIONS").Visible = false; + var teamTemplate = playerPanel.Get("TEAM_TEMPLATE"); var playerTemplate = playerPanel.Get("PLAYER_TEMPLATE"); var spectatorTemplate = playerPanel.Get("SPECTATOR_TEMPLATE"); + var unmuteTooltip = modData.Translation.GetString(Unmute); + var muteTooltip = modData.Translation.GetString(Mute); playerPanel.RemoveChildren(); var teams = world.Players.Where(p => !p.NonCombatant && p.Playable) @@ -112,6 +123,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic var scoreCache = new CachedTransform(s => s.ToString()); item.Get("SCORE").GetText = () => scoreCache.Update(p.PlayerStatistics?.Experience ?? 0); + var muteCheckbox = item.Get("MUTE"); + muteCheckbox.IsChecked = () => TextNotificationsManager.MutedPlayers[pp.ClientIndex]; + muteCheckbox.OnClick = () => TextNotificationsManager.MutedPlayers[pp.ClientIndex] ^= true; + muteCheckbox.IsVisible = () => !pp.IsBot && client.State != Session.ClientState.Disconnected && pp.ClientIndex != orderManager.LocalClient?.Index; + muteCheckbox.GetTooltipText = () => muteCheckbox.IsChecked() ? unmuteTooltip : muteTooltip; + playerPanel.AddChild(item); } } @@ -143,7 +160,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic }; var kickButton = item.Get("KICK"); - kickButton.IsVisible = () => Game.IsHost && client.Index != orderManager.LocalClient.Index && client.State != Session.ClientState.Disconnected; + kickButton.IsVisible = () => Game.IsHost && client.Index != orderManager.LocalClient?.Index && client.State != Session.ClientState.Disconnected; kickButton.OnClick = () => { hideMenu(true); @@ -159,6 +176,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic confirmText: "Kick"); }; + var muteCheckbox = item.Get("MUTE"); + muteCheckbox.IsChecked = () => TextNotificationsManager.MutedPlayers[client.Index]; + muteCheckbox.OnClick = () => TextNotificationsManager.MutedPlayers[client.Index] ^= true; + muteCheckbox.IsVisible = () => !client.IsBot && client.State != Session.ClientState.Disconnected && client.Index != orderManager.LocalClient?.Index; + muteCheckbox.GetTooltipText = () => muteCheckbox.IsChecked() ? unmuteTooltip : muteTooltip; + playerPanel.AddChild(item); } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs index 935a6eed0c..0014ba1c63 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/IngameChatLogic.cs @@ -69,6 +69,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic var teamMessage = modData.Translation.GetString(Team); var allMessage = modData.Translation.GetString(All); + // Only execute this once, the first time this widget is loaded + if (TextNotificationsManager.MutedPlayers.Count == 0) + foreach (var c in orderManager.LobbyInfo.Clients) + TextNotificationsManager.MutedPlayers.Add(c.Index, false); + tabCompletion.Commands = chatTraits.OfType().ToArray().SelectMany(x => x.Commands.Keys); tabCompletion.Names = orderManager.LobbyInfo.Clients.Select(c => c.Name).Distinct().ToList(); @@ -273,6 +278,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (!IsNotificationEligible(notification)) return; + if (notification.ClientId != TextNotificationsManager.SystemClientId && TextNotificationsManager.MutedPlayers[notification.ClientId]) + return; + if (!IsNotificationMuted(notification)) chatOverlayDisplay?.AddNotification(notification); diff --git a/mods/cnc/chrome.yaml b/mods/cnc/chrome.yaml index f9ede3236a..69b9a829fe 100644 --- a/mods/cnc/chrome.yaml +++ b/mods/cnc/chrome.yaml @@ -265,6 +265,22 @@ checkbox-highlighted-disabled: checkbox-highlighted-pressed: Inherits: button-highlighted-pressed +checkbox-toggle: + +checkbox-toggle-hover: + Inherits: checkbox + +checkbox-toggle-pressed: + Inherits: checkbox-pressed + +checkbox-toggle-highlighted: + +checkbox-toggle-highlighted-hover: + Inherits: checkbox-highlighted + +checkbox-toggle-highlighted-pressed: + Inherits: checkbox-highlighted-pressed + # # Panels # === @@ -418,6 +434,17 @@ checkmark-cross: checkmark-highlighted-cross: Inherits: checkmark-cross +checkmark-mute: + Inherits: ^Chrome + Regions: + unchecked: 989, 34, 16, 16 + unchecked-pressed: 1006, 34, 16, 16 + checked: 1006, 34, 16, 16 + checked-pressed: 989, 34, 16, 16 + +checkmark-highlighted-mute: + Inherits: checkmark-mute + flags: Inherits: ^Chrome Regions: diff --git a/mods/cnc/chrome/ingame-infostats.yaml b/mods/cnc/chrome/ingame-infostats.yaml index b8383e50fd..cd7b5ae6fe 100644 --- a/mods/cnc/chrome/ingame-infostats.yaml +++ b/mods/cnc/chrome/ingame-infostats.yaml @@ -125,6 +125,13 @@ Container@SKIRMISH_STATS: Width: 60 Height: 25 Shadow: True + Checkbox@MUTE: + X: 457 + Width: 25 + Height: 25 + Checkmark: mute + Background: checkbox-toggle + TooltipContainer: TOOLTIP_CONTAINER Container@SPECTATOR_TEMPLATE: Width: PARENT_RIGHT - 27 Height: 25 @@ -148,6 +155,13 @@ Container@SKIRMISH_STATS: Width: 191 Height: 25 Shadow: True + Checkbox@MUTE: + X: 457 + Width: 25 + Height: 25 + Checkmark: mute + Background: checkbox-toggle + TooltipContainer: TOOLTIP_CONTAINER Button@KICK: X: 485 Width: 25 diff --git a/mods/common/chrome/ingame-infostats.yaml b/mods/common/chrome/ingame-infostats.yaml index 981b796489..aff44ed39e 100644 --- a/mods/common/chrome/ingame-infostats.yaml +++ b/mods/common/chrome/ingame-infostats.yaml @@ -123,6 +123,13 @@ Container@SKIRMISH_STATS: Width: 60 Height: 25 Shadow: True + Checkbox@MUTE: + X: 457 + Width: 25 + Height: 25 + Checkmark: mute + Background: checkbox-toggle + TooltipContainer: TOOLTIP_CONTAINER Container@SPECTATOR_TEMPLATE: Width: PARENT_RIGHT - 26 Height: 25 @@ -146,6 +153,13 @@ Container@SKIRMISH_STATS: Width: 191 Height: 25 Shadow: True + Checkbox@MUTE: + X: 457 + Width: 25 + Height: 25 + Checkmark: mute + Background: checkbox-toggle + TooltipContainer: TOOLTIP_CONTAINER Button@KICK: X: 485 Width: 25 diff --git a/mods/common/languages/en.ftl b/mods/common/languages/en.ftl index fc47d218e8..408a6b3d75 100644 --- a/mods/common/languages/en.ftl +++ b/mods/common/languages/en.ftl @@ -117,6 +117,10 @@ in-progress = In progress accomplished = Accomplished failed = Failed +## GameInfoStatsLogic +mute = Mute this player +unmute = Unmute this player + ## GameTimerLogic paused = Paused max-speed = Max Speed diff --git a/mods/d2k/chrome.yaml b/mods/d2k/chrome.yaml index 4c936e79b8..834c7b5a2c 100644 --- a/mods/d2k/chrome.yaml +++ b/mods/d2k/chrome.yaml @@ -395,6 +395,17 @@ checkmark-cross: checkmark-highlighted-cross: Inherits: checkmark-cross +checkmark-mute: + Inherits: ^Glyphs + Regions: + unchecked: 221, 34, 16, 16 + unchecked-pressed: 238, 34, 16, 16 + checked: 238, 34, 16, 16 + checked-pressed: 221, 34, 16, 16 + +checkmark-highlighted-mute: + Inherits: checkmark-mute + checkbox-hover: Inherits: ^Dialog PanelRegion: 641, 129, 2, 2, 122, 122, 2, 2 @@ -419,6 +430,22 @@ checkbox-highlighted-pressed: checkbox-highlighted-disabled: Inherits: checkbox-disabled +checkbox-toggle: + +checkbox-toggle-hover: + Inherits: button + +checkbox-toggle-pressed: + Inherits: checkbox-pressed + +checkbox-toggle-highlighted: + +checkbox-toggle-highlighted-hover: + Inherits: button-highlighted + +checkbox-toggle-highlighted-pressed: + Inherits: checkbox-highlighted-pressed + scrollitem-selected: Inherits: button-pressed diff --git a/mods/d2k/chrome/ingame-infostats.yaml b/mods/d2k/chrome/ingame-infostats.yaml index 9dc7e0c75e..615ea370aa 100644 --- a/mods/d2k/chrome/ingame-infostats.yaml +++ b/mods/d2k/chrome/ingame-infostats.yaml @@ -125,6 +125,13 @@ Container@SKIRMISH_STATS: Width: 60 Height: 25 Shadow: True + Checkbox@MUTE: + X: 457 + Width: 25 + Height: 25 + Checkmark: mute + Background: checkbox-toggle + TooltipContainer: TOOLTIP_CONTAINER Container@SPECTATOR_TEMPLATE: Width: PARENT_RIGHT - 27 Height: 25 @@ -148,6 +155,13 @@ Container@SKIRMISH_STATS: Width: 191 Height: 25 Shadow: True + Checkbox@MUTE: + X: 457 + Width: 25 + Height: 25 + Checkmark: mute + Background: checkbox-toggle + TooltipContainer: TOOLTIP_CONTAINER Button@KICK: X: 485 Width: 25 diff --git a/mods/ra/chrome.yaml b/mods/ra/chrome.yaml index f023df0b4a..17e9b15767 100644 --- a/mods/ra/chrome.yaml +++ b/mods/ra/chrome.yaml @@ -524,6 +524,17 @@ checkmark-cross: checkmark-highlighted-cross: Inherits: checkmark-cross +checkmark-mute: + Inherits: ^Glyphs + Regions: + unchecked: 0, 170, 16, 16 + unchecked-pressed: 17, 170, 16, 16 + checked: 17, 170, 16, 16 + checked-pressed: 0, 170, 16, 16 + +checkmark-highlighted-mute: + Inherits: checkmark-mute + checkbox-hover: Inherits: ^Dialog PanelRegion: 641, 129, 2, 2, 122, 122, 2, 2 @@ -548,6 +559,22 @@ checkbox-highlighted-pressed: checkbox-highlighted-disabled: Inherits: checkbox-disabled +checkbox-toggle: + +checkbox-toggle-hover: + Inherits: button + +checkbox-toggle-pressed: + Inherits: checkbox-pressed + +checkbox-toggle-highlighted: + +checkbox-toggle-highlighted-hover: + Inherits: button-highlighted + +checkbox-toggle-highlighted-pressed: + Inherits: checkbox-highlighted-pressed + scrollitem-selected: Inherits: button-pressed diff --git a/mods/ts/chrome.yaml b/mods/ts/chrome.yaml index 7d771a24ad..147be67589 100644 --- a/mods/ts/chrome.yaml +++ b/mods/ts/chrome.yaml @@ -657,6 +657,17 @@ checkmark-cross: checkmark-highlighted-cross: Inherits: checkmark-cross +checkmark-mute: + Inherits: ^Glyphs + Regions: + unchecked: 221, 34, 16, 16 + unchecked-pressed: 238, 34, 16, 16 + checked: 238, 34, 16, 16 + checked-pressed: 221, 34, 16, 16 + +checkmark-highlighted-mute: + Inherits: checkmark-mute + checkbox-hover: Inherits: ^Dialog PanelRegion: 641, 129, 2, 2, 122, 122, 2, 2 @@ -681,6 +692,22 @@ checkbox-highlighted-pressed: checkbox-highlighted-disabled: Inherits: checkbox-disabled +checkbox-toggle: + +checkbox-toggle-hover: + Inherits: button + +checkbox-toggle-pressed: + Inherits: checkbox-pressed + +checkbox-toggle-highlighted: + +checkbox-toggle-highlighted-hover: + Inherits: button-highlighted + +checkbox-toggle-highlighted-pressed: + Inherits: checkbox-highlighted-pressed + scrollitem-selected: Inherits: button-pressed