From f9d9ad388b565a517bc2ad918368265a6a05fe56 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 25 Feb 2022 16:03:28 +0900 Subject: [PATCH 1/3] Add chat display to multiplayer spectator screen --- .../TestSceneMultiSpectatorScreen.cs | 7 ++--- .../Multiplayer/MultiplayerMatchSubScreen.cs | 2 +- .../Spectate/MultiSpectatorScreen.cs | 27 +++++++++++++------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index 7ce0c6a94d..77a06e5746 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -15,6 +15,7 @@ using osu.Game.Configuration; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus; +using osu.Game.Online.Rooms; using osu.Game.Rulesets.UI; using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate; using osu.Game.Screens.Play; @@ -377,7 +378,7 @@ namespace osu.Game.Tests.Visual.Multiplayer Beatmap.Value = beatmapManager.GetWorkingBeatmap(importedBeatmap); Ruleset.Value = importedBeatmap.Ruleset; - LoadScreen(spectatorScreen = new TestMultiSpectatorScreen(playingUsers.ToArray(), gameplayStartTime)); + LoadScreen(spectatorScreen = new TestMultiSpectatorScreen(SelectedRoom.Value, playingUsers.ToArray(), gameplayStartTime)); }); AddUntilStep("wait for screen load", () => spectatorScreen.LoadState == LoadState.Loaded && (!waitForPlayerLoad || spectatorScreen.AllPlayersLoaded)); @@ -465,8 +466,8 @@ namespace osu.Game.Tests.Visual.Multiplayer { private readonly double? gameplayStartTime; - public TestMultiSpectatorScreen(MultiplayerRoomUser[] users, double? gameplayStartTime = null) - : base(users) + public TestMultiSpectatorScreen(Room room, MultiplayerRoomUser[] users, double? gameplayStartTime = null) + : base(room, users) { this.gameplayStartTime = gameplayStartTime; } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 429b0ad89b..c78dcb7cb6 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -449,7 +449,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer switch (client.LocalUser.State) { case MultiplayerUserState.Spectating: - return new MultiSpectatorScreen(users.Take(PlayerGrid.MAX_PLAYERS).ToArray()); + return new MultiSpectatorScreen(Room, users.Take(PlayerGrid.MAX_PLAYERS).ToArray()); default: return new MultiplayerPlayerLoader(() => new MultiplayerPlayer(Room, SelectedItem.Value, users)); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs index e5eeeb3448..1cc4497675 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs @@ -11,10 +11,12 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Online.Multiplayer; +using osu.Game.Online.Rooms; using osu.Game.Online.Spectator; using osu.Game.Screens.Play; using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Spectate; +using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { @@ -48,15 +50,18 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate private PlayerArea currentAudioSource; private bool canStartMasterClock; + private readonly Room room; private readonly MultiplayerRoomUser[] users; /// /// Creates a new . /// + /// The room. /// The players to spectate. - public MultiSpectatorScreen(MultiplayerRoomUser[] users) + public MultiSpectatorScreen(Room room, MultiplayerRoomUser[] users) : base(users.Select(u => u.UserID).ToArray()) { + this.room = room; this.users = users; instances = new PlayerArea[Users.Count]; @@ -65,7 +70,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate [BackgroundDependencyLoader] private void load() { - Container leaderboardContainer; + FillFlowContainer leaderboardFlow; Container scoreDisplayContainer; masterClockContainer = CreateMasterGameplayClockContainer(Beatmap.Value); @@ -97,10 +102,13 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { new Drawable[] { - leaderboardContainer = new Container + leaderboardFlow = new FillFlowContainer { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(5) }, grid = new PlayerGrid { RelativeSizeAxes = Axes.Both } } @@ -125,14 +133,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate LoadComponentAsync(leaderboard = new MultiSpectatorLeaderboard(scoreProcessor, users) { Expanded = { Value = true }, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, }, l => { foreach (var instance in instances) leaderboard.AddClock(instance.UserId, instance.GameplayClock); - leaderboardContainer.Add(leaderboard); + leaderboardFlow.Insert(0, leaderboard); if (leaderboard.TeamScores.Count == 2) { @@ -143,6 +149,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate }, scoreDisplayContainer.Add); } }); + + LoadComponentAsync(new GameplayChatDisplay(room) + { + Expanded = { Value = true }, + }, chat => leaderboardFlow.Insert(1, chat)); } protected override void LoadComplete() From 48ed9c61442ca05bb7fda4eaf8d7c64f8a37cdad Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 25 Feb 2022 16:03:46 +0900 Subject: [PATCH 2/3] Enable high chat polling rate --- osu.Game/OsuGame.cs | 3 ++- .../Multiplayer/Spectate/MultiSpectatorScreen.cs | 3 +++ osu.Game/Users/UserActivity.cs | 10 ++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index fa5a336b7c..fb81e4fd14 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -838,7 +838,8 @@ namespace osu.Game channelManager.HighPollRate.Value = chatOverlay.State.Value == Visibility.Visible || API.Activity.Value is UserActivity.InLobby - || API.Activity.Value is UserActivity.InMultiplayerGame; + || API.Activity.Value is UserActivity.InMultiplayerGame + || API.Activity.Value is UserActivity.SpectatingMultiplayerGame; } Add(difficultyRecommender); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs index 1cc4497675..3bb76c4a76 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs @@ -16,6 +16,7 @@ using osu.Game.Online.Spectator; using osu.Game.Screens.Play; using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Spectate; +using osu.Game.Users; using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate @@ -36,6 +37,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// public bool AllPlayersLoaded => instances.All(p => p?.PlayerLoaded == true); + protected override UserActivity InitialActivity => new UserActivity.SpectatingMultiplayerGame(Beatmap.Value.BeatmapInfo, Ruleset.Value); + [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game/Users/UserActivity.cs b/osu.Game/Users/UserActivity.cs index 516aa80652..2f945d6e1c 100644 --- a/osu.Game/Users/UserActivity.cs +++ b/osu.Game/Users/UserActivity.cs @@ -50,6 +50,16 @@ namespace osu.Game.Users public override string Status => $@"{base.Status} with others"; } + public class SpectatingMultiplayerGame : InGame + { + public SpectatingMultiplayerGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset) + : base(beatmapInfo, ruleset) + { + } + + public override string Status => $"Watching others {base.Status.ToLowerInvariant()}"; + } + public class InPlaylistGame : InGame { public InPlaylistGame(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset) From 387ae59bc4108372afaa75f3050b10eb04ee26dc Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 25 Feb 2022 16:12:25 +0900 Subject: [PATCH 3/3] Fix nullref in tests --- .../OnlinePlay/Multiplayer/GameplayChatDisplay.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs index 53fd111c27..d08a63e21f 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -15,10 +16,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer { public class GameplayChatDisplay : MatchChatDisplay, IKeyBindingHandler { - [Resolved] + [Resolved(CanBeNull = true)] + [CanBeNull] private ILocalUserPlayInfo localUserInfo { get; set; } - private IBindable localUserPlaying = new Bindable(); + private readonly IBindable localUserPlaying = new Bindable(); public override bool PropagatePositionalInputSubTree => !localUserPlaying.Value; @@ -46,7 +48,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer { base.LoadComplete(); - localUserPlaying = localUserInfo.IsPlaying.GetBoundCopy(); + if (localUserInfo != null) + localUserPlaying.BindTo(localUserInfo.IsPlaying); + localUserPlaying.BindValueChanged(playing => { // for now let's never hold focus. this avoid misdirected gameplay keys entering chat.