From b31fef7e001c22f5e55c01ff8c3fa4df9c090b01 Mon Sep 17 00:00:00 2001 From: 02Naitsirk <57512128+02Naitsirk@users.noreply.github.com> Date: Thu, 22 Jul 2021 13:49:47 -0400 Subject: [PATCH 01/37] Implement total SR formula that better correlates with pp --- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index e47f82fb39..2f0b7da789 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -34,7 +34,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier; double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; - double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2; + + double baseAimPerformance = Math.Pow(5 * Math.Max(1, aimRating) - 4, 3) / 100000; + double baseSpeedPerformance = Math.Pow(5 * Math.Max(1, speedRating) - 4, 3) / 100000; + double basePerformance = Math.Pow(Math.Pow(baseAimPerformance, 1.1) + Math.Pow(baseSpeedPerformance, 1.1), 1 / 1.1); + double starRating = basePerformance > 0.00001 ? 0.027 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4) : 0; HitWindows hitWindows = new OsuHitWindows(); hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); From 5b5cf30cbd5b862496a26453b6edb5ee69281d1c Mon Sep 17 00:00:00 2001 From: 02Naitsirk <57512128+02Naitsirk@users.noreply.github.com> Date: Sat, 31 Jul 2021 12:23:03 -0400 Subject: [PATCH 02/37] Fix incorrect performance formula MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 2f0b7da789..299d8b8970 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -35,8 +35,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier; double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; - double baseAimPerformance = Math.Pow(5 * Math.Max(1, aimRating) - 4, 3) / 100000; - double baseSpeedPerformance = Math.Pow(5 * Math.Max(1, speedRating) - 4, 3) / 100000; + double baseAimPerformance = Math.Pow(5 * Math.Max(1, aimRating / 0.0675) - 4, 3) / 100000; + double baseSpeedPerformance = Math.Pow(5 * Math.Max(1, speedRating / 0.0675) - 4, 3) / 100000; double basePerformance = Math.Pow(Math.Pow(baseAimPerformance, 1.1) + Math.Pow(baseSpeedPerformance, 1.1), 1 / 1.1); double starRating = basePerformance > 0.00001 ? 0.027 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4) : 0; From ea2ef55a8bcc2867ae414e84c67857263cac8be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 1 Aug 2021 15:27:05 +0200 Subject: [PATCH 03/37] Remove unnecessary whitespace --- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 299d8b8970..b75bf81071 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier; double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; - + double baseAimPerformance = Math.Pow(5 * Math.Max(1, aimRating / 0.0675) - 4, 3) / 100000; double baseSpeedPerformance = Math.Pow(5 * Math.Max(1, speedRating / 0.0675) - 4, 3) / 100000; double basePerformance = Math.Pow(Math.Pow(baseAimPerformance, 1.1) + Math.Pow(baseSpeedPerformance, 1.1), 1 / 1.1); From c371e67d705df820ded3c66344a27cf3d1b07b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 1 Aug 2021 15:32:10 +0200 Subject: [PATCH 04/37] Update diffcalc test to match ground-truth formula --- .../OsuDifficultyCalculatorTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs index 8d8387378e..32fba0b70c 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs @@ -15,13 +15,13 @@ namespace osu.Game.Rulesets.Osu.Tests { protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; - [TestCase(6.7568168283591499d, "diffcalc-test")] - [TestCase(1.0348244046058293d, "zero-length-sliders")] + [TestCase(6.4164199087433484d, "diffcalc-test")] + [TestCase(1.0028132594779837d, "zero-length-sliders")] public void Test(double expected, string name) => base.Test(expected, name); - [TestCase(8.4783236764532557d, "diffcalc-test")] - [TestCase(1.2708532136987165d, "zero-length-sliders")] + [TestCase(8.0749334911818469d, "diffcalc-test")] + [TestCase(1.2251606765323657d, "zero-length-sliders")] public void TestClockRateAdjusted(double expected, string name) => Test(expected, name, new OsuModDoubleTime()); From db1f43f6eb887c2d4c38ad796f00dd075821fb25 Mon Sep 17 00:00:00 2001 From: 02Naitsirk <57512128+02Naitsirk@users.noreply.github.com> Date: Tue, 3 Aug 2021 18:57:33 -0400 Subject: [PATCH 05/37] Multiply star rating by a constant --- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index b75bf81071..da879cb02e 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty double baseAimPerformance = Math.Pow(5 * Math.Max(1, aimRating / 0.0675) - 4, 3) / 100000; double baseSpeedPerformance = Math.Pow(5 * Math.Max(1, speedRating / 0.0675) - 4, 3) / 100000; double basePerformance = Math.Pow(Math.Pow(baseAimPerformance, 1.1) + Math.Pow(baseSpeedPerformance, 1.1), 1 / 1.1); - double starRating = basePerformance > 0.00001 ? 0.027 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4) : 0; + double starRating = basePerformance > 0.00001 ? Math.Cbrt(1.12) * 0.027 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4) : 0; HitWindows hitWindows = new OsuHitWindows(); hitWindows.SetDifficulty(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); From 0d2ab550dd8c1285d94ae8991e040f06ea9a970a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Aug 2021 13:04:32 +0900 Subject: [PATCH 06/37] Update SR values in tests --- .../OsuDifficultyCalculatorTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs index 32fba0b70c..19881b5c33 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs @@ -15,13 +15,13 @@ namespace osu.Game.Rulesets.Osu.Tests { protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; - [TestCase(6.4164199087433484d, "diffcalc-test")] - [TestCase(1.0028132594779837d, "zero-length-sliders")] + [TestCase(6.6634445062299665d, "diffcalc-test")] + [TestCase(1.0414203870195022d, "zero-length-sliders")] public void Test(double expected, string name) => base.Test(expected, name); - [TestCase(8.0749334911818469d, "diffcalc-test")] - [TestCase(1.2251606765323657d, "zero-length-sliders")] + [TestCase(8.3858089051603368d, "diffcalc-test")] + [TestCase(1.2723279173428435d, "zero-length-sliders")] public void TestClockRateAdjusted(double expected, string name) => Test(expected, name, new OsuModDoubleTime()); From b8a1ebb786c6bd8a9581d62f489ccd598563e513 Mon Sep 17 00:00:00 2001 From: sh0ckR6 Date: Tue, 7 Sep 2021 16:54:21 -0400 Subject: [PATCH 07/37] Hide Popover after failed password attempt Instead of throwing an error, just close the popover and let the user continue --- osu.Game/Screens/OnlinePlay/Components/RoomManager.cs | 3 ++- .../Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 11 +++++++---- osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 6 ++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs index 3b6c1c8be0..4b3617c74a 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs @@ -87,7 +87,8 @@ namespace osu.Game.Screens.OnlinePlay.Components currentJoinRoomRequest.Failure += exception => { - if (!(exception is OperationCanceledException)) + // provide error output if the operation wasn't canceled and the error doesn't stem from an invalid password + if (!(exception is OperationCanceledException) && !((APIException)exception).Message.Equals("Invalid room password", StringComparison.Ordinal)) Logger.Log($"Failed to join room: {exception}", level: LogLevel.Important); onError?.Invoke(exception.ToString()); }; diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 6dc3cd18c5..c8b647fc9a 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -178,7 +178,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { private readonly Room room; - public Action JoinRequested; + public Action, Action> JoinRequested; public PasswordEntryPopover(Room room) { @@ -186,6 +186,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge } private OsuPasswordTextBox passwordTextbox; + private TriangleButton joinButton; [BackgroundDependencyLoader] private void load() @@ -201,15 +202,17 @@ namespace osu.Game.Screens.OnlinePlay.Lounge passwordTextbox = new OsuPasswordTextBox { Width = 200, + PlaceholderText = "password", }, - new TriangleButton + joinButton = new TriangleButton { Width = 80, Text = "Join Room", - Action = () => JoinRequested?.Invoke(room, passwordTextbox.Text) } } }; + + joinButton.Action = () => JoinRequested?.Invoke(room, passwordTextbox.Text, null, _ => this.HidePopover()); } protected override void LoadComplete() @@ -217,7 +220,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge base.LoadComplete(); Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox)); - passwordTextbox.OnCommit += (_, __) => JoinRequested?.Invoke(room, passwordTextbox.Text); + passwordTextbox.OnCommit += (_, __) => JoinRequested?.Invoke(room, passwordTextbox.Text, null, _ => this.HidePopover()); } } } diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index cca1394b6d..08bdd0487a 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -290,7 +290,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge popoverContainer.HidePopover(); } - public void Join(Room room, string password) => Schedule(() => + public void Join(Room room, string password, Action onSuccess = null, Action onFailure = null) => Schedule(() => { if (joiningRoomOperation != null) return; @@ -302,10 +302,12 @@ namespace osu.Game.Screens.OnlinePlay.Lounge Open(room); joiningRoomOperation?.Dispose(); joiningRoomOperation = null; - }, _ => + onSuccess?.Invoke(room); + }, error => { joiningRoomOperation?.Dispose(); joiningRoomOperation = null; + onFailure?.Invoke(error); }); }); From b1f91596a7e7a07082056686ba49a8acb81244b2 Mon Sep 17 00:00:00 2001 From: sh0ckR6 Date: Tue, 7 Sep 2021 20:05:24 -0400 Subject: [PATCH 08/37] Give user feedback on password attempt fail Shake the popover Set the input box's color to red and set the placeholder text to "incorrect password" --- .../Graphics/Containers/ShakeContainer.cs | 7 +++ .../OnlinePlay/Lounge/DrawableLoungeRoom.cs | 47 +++++++++++++------ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/osu.Game/Graphics/Containers/ShakeContainer.cs b/osu.Game/Graphics/Containers/ShakeContainer.cs index dca9df1e98..ffa8ef585e 100644 --- a/osu.Game/Graphics/Containers/ShakeContainer.cs +++ b/osu.Game/Graphics/Containers/ShakeContainer.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 System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -26,6 +27,11 @@ namespace osu.Game.Graphics.Containers /// public float ShakeMagnitude = 8; + /// + /// Fired when finishes + /// + public event Action OnShakeFinish; + /// /// Shake the contents of this container. /// @@ -50,6 +56,7 @@ namespace osu.Game.Graphics.Containers } sequence.MoveToX(0, ShakeDuration / 2, Easing.InSine); + sequence.Finally(_ => OnShakeFinish?.Invoke()); } } } diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index c8b647fc9a..bedee39a26 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -15,6 +15,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Input.Bindings; @@ -187,32 +188,50 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private OsuPasswordTextBox passwordTextbox; private TriangleButton joinButton; + private ShakeContainer shakeContainer; [BackgroundDependencyLoader] private void load() { - Child = new FillFlowContainer + shakeContainer = new ShakeContainer { Margin = new MarginPadding(10), - Spacing = new Vector2(5), AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new Drawable[] + Child = new FillFlowContainer { - passwordTextbox = new OsuPasswordTextBox + Margin = new MarginPadding(10), + Spacing = new Vector2(5), + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] { - Width = 200, - PlaceholderText = "password", - }, - joinButton = new TriangleButton - { - Width = 80, - Text = "Join Room", + passwordTextbox = new OsuPasswordTextBox + { + Width = 200, + PlaceholderText = "password", + }, + joinButton = new TriangleButton + { + Width = 80, + Text = "Join Room", + } } } }; + Child = shakeContainer; - joinButton.Action = () => JoinRequested?.Invoke(room, passwordTextbox.Text, null, _ => this.HidePopover()); + joinButton.Action = () => JoinRequested?.Invoke(room, passwordTextbox.Text, null, joinFailed); + } + + private void joinFailed(string error) + { + passwordTextbox.Text = string.Empty; + passwordTextbox.PlaceholderText = "incorrect password"; + passwordTextbox.Colour = Color4.Red; + + shakeContainer.OnShakeFinish += () => passwordTextbox.Colour = Color4.White; + + shakeContainer.Shake(); } protected override void LoadComplete() @@ -220,7 +239,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge base.LoadComplete(); Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox)); - passwordTextbox.OnCommit += (_, __) => JoinRequested?.Invoke(room, passwordTextbox.Text, null, _ => this.HidePopover()); + passwordTextbox.OnCommit += (_, __) => JoinRequested?.Invoke(room, passwordTextbox.Text, null, joinFailed); } } } From b8a6925175cc7b40036d10d1e3d74b12feaf331b Mon Sep 17 00:00:00 2001 From: sh0ckR6 Date: Sat, 11 Sep 2021 17:41:07 -0400 Subject: [PATCH 09/37] Use already-resolved LoungeSubScreen instead of nested delegates --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index bedee39a26..972c7aed47 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -123,7 +122,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge } } - public Popover GetPopover() => new PasswordEntryPopover(Room) { JoinRequested = lounge.Join }; + public Popover GetPopover() => new PasswordEntryPopover(Room) { Lounge = lounge }; public MenuItem[] ContextMenuItems => new MenuItem[] { @@ -179,7 +178,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { private readonly Room room; - public Action, Action> JoinRequested; + public LoungeSubScreen Lounge; public PasswordEntryPopover(Room room) { @@ -220,7 +219,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge }; Child = shakeContainer; - joinButton.Action = () => JoinRequested?.Invoke(room, passwordTextbox.Text, null, joinFailed); + joinButton.Action = () => Lounge?.Join(room, passwordTextbox.Text, null, joinFailed); } private void joinFailed(string error) @@ -239,7 +238,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge base.LoadComplete(); Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox)); - passwordTextbox.OnCommit += (_, __) => JoinRequested?.Invoke(room, passwordTextbox.Text, null, joinFailed); + passwordTextbox.OnCommit += (_, __) => Lounge?.Join(room, passwordTextbox.Text, null, joinFailed); } } } From 6cdc8424527c3c9ccb697f9c9031207d6a3a57bb Mon Sep 17 00:00:00 2001 From: sh0ckR6 Date: Sat, 11 Sep 2021 17:42:49 -0400 Subject: [PATCH 10/37] Remove placeholder text response Weird UX, doesn't feel right compared to the rest of lazer --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 972c7aed47..8cf34cd9f3 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -225,8 +225,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private void joinFailed(string error) { passwordTextbox.Text = string.Empty; - passwordTextbox.PlaceholderText = "incorrect password"; - passwordTextbox.Colour = Color4.Red; shakeContainer.OnShakeFinish += () => passwordTextbox.Colour = Color4.White; From e018071be47e31457c6969d0cbac618e37932b3a Mon Sep 17 00:00:00 2001 From: sh0ckR6 Date: Sat, 11 Sep 2021 19:50:41 -0400 Subject: [PATCH 11/37] Remove OnShakeFinish event --- osu.Game/Graphics/Containers/ShakeContainer.cs | 7 ------- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 2 -- 2 files changed, 9 deletions(-) diff --git a/osu.Game/Graphics/Containers/ShakeContainer.cs b/osu.Game/Graphics/Containers/ShakeContainer.cs index ffa8ef585e..dca9df1e98 100644 --- a/osu.Game/Graphics/Containers/ShakeContainer.cs +++ b/osu.Game/Graphics/Containers/ShakeContainer.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -27,11 +26,6 @@ namespace osu.Game.Graphics.Containers /// public float ShakeMagnitude = 8; - /// - /// Fired when finishes - /// - public event Action OnShakeFinish; - /// /// Shake the contents of this container. /// @@ -56,7 +50,6 @@ namespace osu.Game.Graphics.Containers } sequence.MoveToX(0, ShakeDuration / 2, Easing.InSine); - sequence.Finally(_ => OnShakeFinish?.Invoke()); } } } diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 8cf34cd9f3..db1566999e 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -226,8 +226,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { passwordTextbox.Text = string.Empty; - shakeContainer.OnShakeFinish += () => passwordTextbox.Colour = Color4.White; - shakeContainer.Shake(); } From 447001931cf67b3896c3934d1c23209b2be3ddc7 Mon Sep 17 00:00:00 2001 From: sh0ckR6 Date: Sun, 12 Sep 2021 14:36:11 -0400 Subject: [PATCH 12/37] Resolve LoungeSubScreen from PasswordEntryPopover This is preferred over passing down the already-resolved LoungeSubScreen --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index db1566999e..bec0ea419c 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -122,7 +122,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge } } - public Popover GetPopover() => new PasswordEntryPopover(Room) { Lounge = lounge }; + public Popover GetPopover() => new PasswordEntryPopover(Room); public MenuItem[] ContextMenuItems => new MenuItem[] { @@ -178,7 +178,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { private readonly Room room; - public LoungeSubScreen Lounge; + [Resolved(canBeNull: true)] + private LoungeSubScreen lounge { get; set; } public PasswordEntryPopover(Room room) { @@ -219,7 +220,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge }; Child = shakeContainer; - joinButton.Action = () => Lounge?.Join(room, passwordTextbox.Text, null, joinFailed); + joinButton.Action = () => lounge?.Join(room, passwordTextbox.Text, null, joinFailed); } private void joinFailed(string error) @@ -234,7 +235,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge base.LoadComplete(); Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox)); - passwordTextbox.OnCommit += (_, __) => Lounge?.Join(room, passwordTextbox.Text, null, joinFailed); + passwordTextbox.OnCommit += (_, __) => lounge?.Join(room, passwordTextbox.Text, null, joinFailed); } } } From 80e54d51f2bfe0e367bdd7f65f4a793185bafcd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 11 Sep 2021 16:28:46 +0200 Subject: [PATCH 13/37] Add failing test for preserving editor clock time --- .../Editing/TestSceneDifficultySwitching.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs b/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs index a439555fde..0954bf1b49 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs @@ -55,6 +55,22 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("stack empty", () => Stack.CurrentScreen == null); } + [Test] + public void TestClockPositionPreservedBetweenSwitches() + { + BeatmapInfo targetDifficulty = null; + AddStep("seek editor to 00:05:00", () => EditorClock.Seek(5000)); + + AddStep("set target difficulty", () => targetDifficulty = importedBeatmapSet.Beatmaps.Last(beatmap => !beatmap.Equals(Beatmap.Value.BeatmapInfo))); + switchToDifficulty(() => targetDifficulty); + confirmEditingBeatmap(() => targetDifficulty); + AddAssert("editor clock at 00:05:00", () => EditorClock.CurrentTime == 5000); + + AddStep("exit editor", () => Stack.Exit()); + // ensure editor loader didn't resume. + AddAssert("stack empty", () => Stack.CurrentScreen == null); + } + [Test] public void TestPreventSwitchDueToUnsavedChanges() { @@ -118,7 +134,7 @@ namespace osu.Game.Tests.Visual.Editing private void confirmEditingBeatmap(Func targetDifficulty) { AddUntilStep("current beatmap is correct", () => Beatmap.Value.BeatmapInfo.Equals(targetDifficulty.Invoke())); - AddUntilStep("current screen is editor", () => Stack.CurrentScreen is Editor); + AddUntilStep("current screen is editor", () => Stack.CurrentScreen == Editor && Editor?.IsLoaded == true); } } } From 3fc72271f103918a622d509d86a0fbad01172685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 11 Sep 2021 18:36:57 +0200 Subject: [PATCH 14/37] Restore editor clock time after difficulty switch --- osu.Game/Screens/Edit/Editor.cs | 13 ++++++++++++- osu.Game/Screens/Edit/EditorLoader.cs | 12 ++++++++++-- osu.Game/Screens/Edit/EditorState.cs | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Screens/Edit/EditorState.cs diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 28ae7e620e..502ac7a70f 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -476,6 +476,8 @@ namespace osu.Game.Screens.Edit }); resetTrack(true); + if (loader?.State != null) + restoreState(loader.State); } public override bool OnExiting(IScreen next) @@ -740,7 +742,16 @@ namespace osu.Game.Screens.Edit return new DifficultyMenuItem(beatmapInfo, isCurrentDifficulty, SwitchToDifficulty); } - protected void SwitchToDifficulty(BeatmapInfo beatmapInfo) => loader?.ScheduleDifficultySwitch(beatmapInfo); + protected void SwitchToDifficulty(BeatmapInfo nextBeatmap) => loader?.ScheduleDifficultySwitch(nextBeatmap, new EditorState + { + Time = clock.CurrentTimeAccurate + }); + + private void restoreState([NotNull] EditorState state) + { + if (state.Time != null) + clock.Seek(state.Time.Value); + } private void cancelExit() => loader?.CancelPendingDifficultySwitch(); diff --git a/osu.Game/Screens/Edit/EditorLoader.cs b/osu.Game/Screens/Edit/EditorLoader.cs index 6bbfa92c3b..b6e57b0491 100644 --- a/osu.Game/Screens/Edit/EditorLoader.cs +++ b/osu.Game/Screens/Edit/EditorLoader.cs @@ -20,6 +20,13 @@ namespace osu.Game.Screens.Edit /// public class EditorLoader : ScreenWithBeatmapBackground { + /// + /// The stored state from the last editor opened. + /// This will be read by the next editor instance to be opened to restore any relevant previous state. + /// + [CanBeNull] + public EditorState State; + public override float BackgroundParallaxAmount => 0.1f; public override bool AllowBackButton => false; @@ -61,7 +68,7 @@ namespace osu.Game.Screens.Edit } } - public void ScheduleDifficultySwitch(BeatmapInfo beatmapInfo) + public void ScheduleDifficultySwitch(BeatmapInfo nextBeatmap, EditorState editorState) { scheduledDifficultySwitch?.Cancel(); ValidForResume = true; @@ -70,7 +77,8 @@ namespace osu.Game.Screens.Edit scheduledDifficultySwitch = Schedule(() => { - Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmapInfo); + Beatmap.Value = beatmapManager.GetWorkingBeatmap(nextBeatmap); + State = editorState; // This screen is a weird exception to the rule that nothing after song select changes the global beatmap. // Because of this, we need to update the background stack's beatmap to match. diff --git a/osu.Game/Screens/Edit/EditorState.cs b/osu.Game/Screens/Edit/EditorState.cs new file mode 100644 index 0000000000..3aa92f35bc --- /dev/null +++ b/osu.Game/Screens/Edit/EditorState.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable enable + +namespace osu.Game.Screens.Edit +{ + /// + /// Structure used to transport data between instances on difficulty change. + /// It's intended to be received by from one editor instance and passed down to the next one. + /// + public class EditorState + { + /// + /// The current clock time when a difficulty switch was requested. + /// + public double? Time { get; set; } + } +} From 79d0f4835e0fbc6fd6fd28be2901c48c3ae7a1a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 11 Sep 2021 17:26:31 +0200 Subject: [PATCH 15/37] Add failing tests for preserving clipboard content --- .../Editing/TestSceneDifficultySwitching.cs | 34 +++++++++++++++++++ .../Screens/Edit/Compose/ComposeScreen.cs | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs b/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs index 0954bf1b49..1b548dc1ba 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs @@ -71,6 +71,40 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("stack empty", () => Stack.CurrentScreen == null); } + [Test] + public void TestClipboardPreservedAfterSwitch([Values] bool sameRuleset) + { + BeatmapInfo targetDifficulty = null; + + AddStep("select first object", () => EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects.First())); + AddStep("copy object", () => Editor.Copy()); + + AddStep("set target difficulty", () => + { + targetDifficulty = sameRuleset + ? importedBeatmapSet.Beatmaps.Last(beatmap => !beatmap.Equals(Beatmap.Value.BeatmapInfo) && beatmap.RulesetID == Beatmap.Value.BeatmapInfo.RulesetID) + : importedBeatmapSet.Beatmaps.Last(beatmap => !beatmap.Equals(Beatmap.Value.BeatmapInfo) && beatmap.RulesetID != Beatmap.Value.BeatmapInfo.RulesetID); + }); + switchToDifficulty(() => targetDifficulty); + confirmEditingBeatmap(() => targetDifficulty); + + AddAssert("no objects selected", () => !EditorBeatmap.SelectedHitObjects.Any()); + AddStep("paste object", () => Editor.Paste()); + + if (sameRuleset) + AddAssert("object was pasted", () => EditorBeatmap.SelectedHitObjects.Any()); + else + AddAssert("object was not pasted", () => !EditorBeatmap.SelectedHitObjects.Any()); + + AddStep("exit editor", () => Stack.Exit()); + + AddUntilStep("prompt for save dialog shown", () => DialogOverlay.CurrentDialog is PromptForSaveDialog); + AddStep("discard changes", () => ((PromptForSaveDialog)DialogOverlay.CurrentDialog).PerformOkAction()); + + // ensure editor loader didn't resume. + AddAssert("stack empty", () => Stack.CurrentScreen == null); + } + [Test] public void TestPreventSwitchDueToUnsavedChanges() { diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index 62b3d33069..e324f1edeb 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -80,7 +80,7 @@ namespace osu.Game.Screens.Edit.Compose public bool OnPressed(PlatformAction action) { if (action == PlatformAction.Copy) - host.GetClipboard().SetText(formatSelectionAsString()); + host.GetClipboard()?.SetText(formatSelectionAsString()); return false; } From 35ee889e5b1b567757632b5bb9dd0b350b5820a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 11 Sep 2021 17:55:11 +0200 Subject: [PATCH 16/37] Restore clipboard content after difficulty switch --- osu.Game/Screens/Edit/Editor.cs | 5 ++++- osu.Game/Screens/Edit/EditorState.cs | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 502ac7a70f..eba75f4408 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -744,13 +744,16 @@ namespace osu.Game.Screens.Edit protected void SwitchToDifficulty(BeatmapInfo nextBeatmap) => loader?.ScheduleDifficultySwitch(nextBeatmap, new EditorState { - Time = clock.CurrentTimeAccurate + Time = clock.CurrentTimeAccurate, + ClipboardContent = editorBeatmap.BeatmapInfo.RulesetID == nextBeatmap.RulesetID ? clipboard.Value : null }); private void restoreState([NotNull] EditorState state) { if (state.Time != null) clock.Seek(state.Time.Value); + + clipboard.Value = state.ClipboardContent ?? clipboard.Value; } private void cancelExit() => loader?.CancelPendingDifficultySwitch(); diff --git a/osu.Game/Screens/Edit/EditorState.cs b/osu.Game/Screens/Edit/EditorState.cs index 3aa92f35bc..09cc1184d2 100644 --- a/osu.Game/Screens/Edit/EditorState.cs +++ b/osu.Game/Screens/Edit/EditorState.cs @@ -15,5 +15,10 @@ namespace osu.Game.Screens.Edit /// The current clock time when a difficulty switch was requested. /// public double? Time { get; set; } + + /// + /// The current editor clipboard content at the time when a difficulty switch was requested. + /// + public string? ClipboardContent { get; set; } } } From cbb9ff1c492b51f450f8841277597ff38de61667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 12 Sep 2021 13:44:25 +0200 Subject: [PATCH 17/37] Only run prompt-for-save test logic when relevant --- .../Visual/Editing/TestSceneDifficultySwitching.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs b/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs index 1b548dc1ba..c81a1abfbc 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs @@ -98,8 +98,11 @@ namespace osu.Game.Tests.Visual.Editing AddStep("exit editor", () => Stack.Exit()); - AddUntilStep("prompt for save dialog shown", () => DialogOverlay.CurrentDialog is PromptForSaveDialog); - AddStep("discard changes", () => ((PromptForSaveDialog)DialogOverlay.CurrentDialog).PerformOkAction()); + if (sameRuleset) + { + AddUntilStep("prompt for save dialog shown", () => DialogOverlay.CurrentDialog is PromptForSaveDialog); + AddStep("discard changes", () => ((PromptForSaveDialog)DialogOverlay.CurrentDialog).PerformOkAction()); + } // ensure editor loader didn't resume. AddAssert("stack empty", () => Stack.CurrentScreen == null); From 3df4cbca2cfd09d81226b530f96fba6a5588e2a9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Sep 2021 13:45:10 +0900 Subject: [PATCH 18/37] Reduce precision of difficulty calculator tests --- osu.Game/Tests/Beatmaps/DifficultyCalculatorTest.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Beatmaps/DifficultyCalculatorTest.cs b/osu.Game/Tests/Beatmaps/DifficultyCalculatorTest.cs index 76f229a799..fdb3e1d465 100644 --- a/osu.Game/Tests/Beatmaps/DifficultyCalculatorTest.cs +++ b/osu.Game/Tests/Beatmaps/DifficultyCalculatorTest.cs @@ -23,7 +23,10 @@ namespace osu.Game.Tests.Beatmaps protected abstract string ResourceAssembly { get; } protected void Test(double expected, string name, params Mod[] mods) - => Assert.AreEqual(expected, CreateDifficultyCalculator(getBeatmap(name)).Calculate(mods).StarRating); + { + // Platform-dependent math functions (Pow, Cbrt, Exp, etc) may result in minute differences. + Assert.That(CreateDifficultyCalculator(getBeatmap(name)).Calculate(mods).StarRating, Is.EqualTo(expected).Within(0.00001)); + } private WorkingBeatmap getBeatmap(string name) { From eaac2bad3d31dce24d3e6a6fad03a4ff8b849e85 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Sep 2021 13:49:02 +0900 Subject: [PATCH 19/37] Fix incorrect child margin specifications --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index bec0ea419c..2fc039ad79 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -193,13 +193,12 @@ namespace osu.Game.Screens.OnlinePlay.Lounge [BackgroundDependencyLoader] private void load() { - shakeContainer = new ShakeContainer + Child = shakeContainer = new ShakeContainer { Margin = new MarginPadding(10), AutoSizeAxes = Axes.Both, Child = new FillFlowContainer { - Margin = new MarginPadding(10), Spacing = new Vector2(5), AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, @@ -218,7 +217,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge } } }; - Child = shakeContainer; joinButton.Action = () => lounge?.Join(room, passwordTextbox.Text, null, joinFailed); } From 6851e0000de64ca7bd41339eedcda4f6d3c7c99f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Sep 2021 13:51:18 +0900 Subject: [PATCH 20/37] Add test coverage --- .../TestSceneMultiplayerLoungeSubScreen.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs index 99f6ab1ae1..01bf742177 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs @@ -3,6 +3,7 @@ using System.Linq; using NUnit.Framework; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Framework.Screens; using osu.Framework.Testing; @@ -64,7 +65,23 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] - public void TestJoinRoomWithPassword() + public void TestJoinRoomWithIncorrectPassword() + { + DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null; + + AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true)); + AddStep("select room", () => InputManager.Key(Key.Down)); + AddStep("attempt join room", () => InputManager.Key(Key.Enter)); + AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType().FirstOrDefault()) != null); + AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType().First().Text = "wrong"); + AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType().First().TriggerClick()); + + AddAssert("room not joined", () => loungeScreen.IsCurrentScreen()); + AddUntilStep("password prompt still visible", () => passwordEntryPopover.State.Value == Visibility.Visible); + } + + [Test] + public void TestJoinRoomWithCorrectPassword() { DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null; From e3c56f9ebde94c87276af777164f61581142732a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Sep 2021 14:10:55 +0900 Subject: [PATCH 21/37] Show error message in popover --- .../OnlinePlay/Components/RoomManager.cs | 8 ++-- .../OnlinePlay/Lounge/DrawableLoungeRoom.cs | 37 ++++++++++++++----- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs index 4b3617c74a..a64d89b699 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs @@ -87,10 +87,10 @@ namespace osu.Game.Screens.OnlinePlay.Components currentJoinRoomRequest.Failure += exception => { - // provide error output if the operation wasn't canceled and the error doesn't stem from an invalid password - if (!(exception is OperationCanceledException) && !((APIException)exception).Message.Equals("Invalid room password", StringComparison.Ordinal)) - Logger.Log($"Failed to join room: {exception}", level: LogLevel.Important); - onError?.Invoke(exception.ToString()); + if (exception is OperationCanceledException) + return; + + onError?.Invoke(exception.Message); }; api.Queue(currentJoinRoomRequest); diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 2fc039ad79..0dec9b72bf 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -14,7 +14,9 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Input.Bindings; @@ -189,9 +191,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private OsuPasswordTextBox passwordTextbox; private TriangleButton joinButton; private ShakeContainer shakeContainer; + private OsuSpriteText errorText; [BackgroundDependencyLoader] - private void load() + private void load(OsuColour colours) { Child = shakeContainer = new ShakeContainer { @@ -201,19 +204,32 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { Spacing = new Vector2(5), AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, + Direction = FillDirection.Vertical, Children = new Drawable[] { - passwordTextbox = new OsuPasswordTextBox + new FillFlowContainer { - Width = 200, - PlaceholderText = "password", + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + passwordTextbox = new OsuPasswordTextBox + { + Width = 200, + PlaceholderText = "password", + }, + joinButton = new TriangleButton + { + Width = 80, + Text = "Join Room", + } + } }, - joinButton = new TriangleButton + errorText = new OsuSpriteText { - Width = 80, - Text = "Join Room", - } + Colour = colours.Red, + }, } } }; @@ -225,6 +241,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { passwordTextbox.Text = string.Empty; + errorText.Text = error; + errorText.FadeOutFromOne(1000, Easing.In); + shakeContainer.Shake(); } From 7bd749d0eb8bdda4997a66531691cc4f052b8481 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Sep 2021 14:19:55 +0900 Subject: [PATCH 22/37] Remove weird shaking --- .../OnlinePlay/Lounge/DrawableLoungeRoom.cs | 56 +++++++++---------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 0dec9b72bf..a67389e4c0 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -15,7 +15,6 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; @@ -190,47 +189,44 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private OsuPasswordTextBox passwordTextbox; private TriangleButton joinButton; - private ShakeContainer shakeContainer; private OsuSpriteText errorText; [BackgroundDependencyLoader] private void load(OsuColour colours) { - Child = shakeContainer = new ShakeContainer + Padding = new MarginPadding(10); + + Child = new FillFlowContainer { Margin = new MarginPadding(10), + Spacing = new Vector2(5), AutoSizeAxes = Axes.Both, - Child = new FillFlowContainer + Direction = FillDirection.Vertical, + Children = new Drawable[] { - Spacing = new Vector2(5), - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new FillFlowContainer { - new FillFlowContainer + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), + AutoSizeAxes = Axes.Both, + Children = new Drawable[] { - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5), - AutoSizeAxes = Axes.Both, - Children = new Drawable[] + passwordTextbox = new OsuPasswordTextBox { - passwordTextbox = new OsuPasswordTextBox - { - Width = 200, - PlaceholderText = "password", - }, - joinButton = new TriangleButton - { - Width = 80, - Text = "Join Room", - } + Width = 200, + PlaceholderText = "password", + }, + joinButton = new TriangleButton + { + Width = 80, + Text = "Join Room", } - }, - errorText = new OsuSpriteText - { - Colour = colours.Red, - }, - } + } + }, + errorText = new OsuSpriteText + { + Colour = colours.Red, + }, } }; @@ -243,8 +239,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge errorText.Text = error; errorText.FadeOutFromOne(1000, Easing.In); - - shakeContainer.Shake(); } protected override void LoadComplete() From e17b800470d18095e079699795fe475fbd0c18e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Sep 2021 14:44:23 +0900 Subject: [PATCH 23/37] Move shake logic into extension method --- osu.Game/Extensions/DrawableExtensions.cs | 27 +++++++++++++++ .../Graphics/Containers/ShakeContainer.cs | 34 ++----------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/osu.Game/Extensions/DrawableExtensions.cs b/osu.Game/Extensions/DrawableExtensions.cs index 52d8230fb6..b05a2994ea 100644 --- a/osu.Game/Extensions/DrawableExtensions.cs +++ b/osu.Game/Extensions/DrawableExtensions.cs @@ -38,6 +38,33 @@ namespace osu.Game.Extensions return repeatDelegate; } + /// + /// Shake the contents of this container. + /// + /// The target to shake. + /// The length of a single shake. + /// Pixels of displacement per shake. + /// The maximum length the shake should last. + public static void Shake(this Drawable target, double shakeDuration = 80, float shakeMagnitude = 8, double? maximumLength = null) + { + // if we don't have enough time, don't bother shaking. + if (maximumLength < shakeDuration * 2) + return; + + var sequence = target.MoveToX(shakeMagnitude, shakeDuration / 2, Easing.OutSine).Then() + .MoveToX(-shakeMagnitude, shakeDuration, Easing.InOutSine).Then(); + + // if we don't have enough time for the second shake, skip it. + if (!maximumLength.HasValue || maximumLength >= shakeDuration * 4) + { + sequence = sequence + .MoveToX(shakeMagnitude, shakeDuration, Easing.InOutSine).Then() + .MoveToX(-shakeMagnitude, shakeDuration, Easing.InOutSine).Then(); + } + + sequence.MoveToX(0, shakeDuration / 2, Easing.InSine); + } + /// /// Accepts a delta vector in screen-space coordinates and converts it to one which can be applied to this drawable's position. /// diff --git a/osu.Game/Graphics/Containers/ShakeContainer.cs b/osu.Game/Graphics/Containers/ShakeContainer.cs index dca9df1e98..8a0ce287db 100644 --- a/osu.Game/Graphics/Containers/ShakeContainer.cs +++ b/osu.Game/Graphics/Containers/ShakeContainer.cs @@ -1,8 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Extensions; namespace osu.Game.Graphics.Containers { @@ -16,40 +16,10 @@ namespace osu.Game.Graphics.Containers /// public float ShakeDuration = 80; - /// - /// Total number of shakes. May be shortened if possible. - /// - public float TotalShakes = 4; - - /// - /// Pixels of displacement per shake. - /// - public float ShakeMagnitude = 8; - /// /// Shake the contents of this container. /// /// The maximum length the shake should last. - public void Shake(double? maximumLength = null) - { - const float shake_amount = 8; - - // if we don't have enough time, don't bother shaking. - if (maximumLength < ShakeDuration * 2) - return; - - var sequence = this.MoveToX(shake_amount, ShakeDuration / 2, Easing.OutSine).Then() - .MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then(); - - // if we don't have enough time for the second shake, skip it. - if (!maximumLength.HasValue || maximumLength >= ShakeDuration * 4) - { - sequence = sequence - .MoveToX(shake_amount, ShakeDuration, Easing.InOutSine).Then() - .MoveToX(-shake_amount, ShakeDuration, Easing.InOutSine).Then(); - } - - sequence.MoveToX(0, ShakeDuration / 2, Easing.InSine); - } + public void Shake(double? maximumLength = null) => this.Shake(ShakeDuration, maximumLength: maximumLength); } } From 8865e3cab8abdde1164f1d4cadea2a8a1dac1cb9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Sep 2021 14:44:32 +0900 Subject: [PATCH 24/37] Add back shake and tweak transform of text --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index a67389e4c0..11c3cfe06a 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -14,6 +14,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; +using osu.Game.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -238,7 +239,13 @@ namespace osu.Game.Screens.OnlinePlay.Lounge passwordTextbox.Text = string.Empty; errorText.Text = error; - errorText.FadeOutFromOne(1000, Easing.In); + errorText + .FadeIn() + .FlashColour(Color4.White, 200) + .Delay(1000) + .FadeOutFromOne(1000, Easing.In); + + Body.Shake(); } protected override void LoadComplete() From 5058f285048d9ac7354f02d8514203321584c44f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Sep 2021 14:52:50 +0900 Subject: [PATCH 25/37] Remove breaking padding --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 11c3cfe06a..310df0b91d 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -195,8 +195,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge [BackgroundDependencyLoader] private void load(OsuColour colours) { - Padding = new MarginPadding(10); - Child = new FillFlowContainer { Margin = new MarginPadding(10), From 6cffbee59256e0bca56d424f5b0f77605d3f195a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Sep 2021 17:22:58 +0900 Subject: [PATCH 26/37] Fix random/target mods not working in spectator --- osu.Game/Online/Spectator/SpectatorClient.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Spectator/SpectatorClient.cs b/osu.Game/Online/Spectator/SpectatorClient.cs index 2546374b21..494739797a 100644 --- a/osu.Game/Online/Spectator/SpectatorClient.cs +++ b/osu.Game/Online/Spectator/SpectatorClient.cs @@ -153,9 +153,9 @@ namespace osu.Game.Online.Spectator IsPlaying = true; // transfer state at point of beginning play - currentState.BeatmapID = beatmap.BeatmapInfo.OnlineBeatmapID; - currentState.RulesetID = currentRuleset.Value.ID; - currentState.Mods = currentMods.Value.Select(m => new APIMod(m)); + currentState.BeatmapID = score.ScoreInfo.Beatmap.OnlineBeatmapID; + currentState.RulesetID = score.ScoreInfo.RulesetID; + currentState.Mods = score.ScoreInfo.Mods.Select(m => new APIMod(m)).ToArray(); currentBeatmap = beatmap.PlayableBeatmap; currentScore = score; From b807c161b4907633304322a9525f5569d9bc18d8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Sep 2021 17:23:45 +0900 Subject: [PATCH 27/37] Remove now-unused DI params --- osu.Game/Online/Spectator/SpectatorClient.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/osu.Game/Online/Spectator/SpectatorClient.cs b/osu.Game/Online/Spectator/SpectatorClient.cs index 494739797a..8c617784b9 100644 --- a/osu.Game/Online/Spectator/SpectatorClient.cs +++ b/osu.Game/Online/Spectator/SpectatorClient.cs @@ -15,8 +15,6 @@ using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Replays.Legacy; -using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Scoring; @@ -46,15 +44,8 @@ namespace osu.Game.Online.Spectator private readonly BindableDictionary playingUserStates = new BindableDictionary(); private IBeatmap? currentBeatmap; - private Score? currentScore; - [Resolved] - private IBindable currentRuleset { get; set; } = null!; - - [Resolved] - private IBindable> currentMods { get; set; } = null!; - private readonly SpectatorState currentState = new SpectatorState(); /// From a7759153385c7d7d9bfa78e0b5b060e994d2d60f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Sep 2021 18:20:28 +0900 Subject: [PATCH 28/37] Fix incorrect beatmap count and SR range in multi lounge --- .../Screens/OnlinePlay/Components/ListingPollingComponent.cs | 5 +++++ .../OnlinePlay/Components/SelectionPollingComponent.cs | 3 +++ 2 files changed, 8 insertions(+) diff --git a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs index daac6a66cd..5a74df6ab1 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs @@ -57,7 +57,12 @@ namespace osu.Game.Screens.OnlinePlay.Components } foreach (var incoming in result) + { + // Copy the room to itself to populate some members (such as status and playlist expiry). + incoming.CopyFrom(incoming); + RoomManager.AddOrUpdateRoom(incoming); + } initialRoomsReceived.Value = true; tcs.SetResult(true); diff --git a/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs index 0769d0747b..0a37d47e34 100644 --- a/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs @@ -39,6 +39,9 @@ namespace osu.Game.Screens.OnlinePlay.Components pollReq.Success += result => { + // Copy the room to itself to populate some members (such as status and playlist expiry). + result.CopyFrom(result); + RoomManager.AddOrUpdateRoom(result); tcs.SetResult(true); }; From 2a894e7a3f560ae785e3395b55d36e8695a83741 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Sep 2021 23:26:02 +0900 Subject: [PATCH 29/37] Make `EditorLoader` state `private` --- osu.Game/Screens/Edit/EditorLoader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorLoader.cs b/osu.Game/Screens/Edit/EditorLoader.cs index b6e57b0491..5ad720f7f0 100644 --- a/osu.Game/Screens/Edit/EditorLoader.cs +++ b/osu.Game/Screens/Edit/EditorLoader.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.Edit /// This will be read by the next editor instance to be opened to restore any relevant previous state. /// [CanBeNull] - public EditorState State; + private EditorState state; public override float BackgroundParallaxAmount => 0.1f; @@ -78,7 +78,7 @@ namespace osu.Game.Screens.Edit scheduledDifficultySwitch = Schedule(() => { Beatmap.Value = beatmapManager.GetWorkingBeatmap(nextBeatmap); - State = editorState; + state = editorState; // This screen is a weird exception to the rule that nothing after song select changes the global beatmap. // Because of this, we need to update the background stack's beatmap to match. From f8bdca542d2a6d993b3b0d4a6ddc7ae87ddaf9a4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Sep 2021 23:36:17 +0900 Subject: [PATCH 30/37] Make restoring state a `public` call on `Editor` --- osu.Game/Screens/Edit/Editor.cs | 22 +++++++++++----------- osu.Game/Screens/Edit/EditorLoader.cs | 8 +++++++- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index eba75f4408..5bb47e1c11 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -317,6 +317,16 @@ namespace osu.Game.Screens.Edit /// public void UpdateClockSource() => clock.ChangeSource(Beatmap.Value.Track); + /// + /// Restore the editor to a provided state. + /// + /// The state to restore. + public void RestoreState([NotNull] EditorState state) => Schedule(() => + { + clock.Seek(state.Time); + clipboard.Value = state.ClipboardContent; + }); + protected void Save() { // no longer new after first user-triggered save. @@ -476,8 +486,6 @@ namespace osu.Game.Screens.Edit }); resetTrack(true); - if (loader?.State != null) - restoreState(loader.State); } public override bool OnExiting(IScreen next) @@ -745,17 +753,9 @@ namespace osu.Game.Screens.Edit protected void SwitchToDifficulty(BeatmapInfo nextBeatmap) => loader?.ScheduleDifficultySwitch(nextBeatmap, new EditorState { Time = clock.CurrentTimeAccurate, - ClipboardContent = editorBeatmap.BeatmapInfo.RulesetID == nextBeatmap.RulesetID ? clipboard.Value : null + ClipboardContent = editorBeatmap.BeatmapInfo.RulesetID == nextBeatmap.RulesetID ? clipboard.Value : string.Empty }); - private void restoreState([NotNull] EditorState state) - { - if (state.Time != null) - clock.Seek(state.Time.Value); - - clipboard.Value = state.ClipboardContent ?? clipboard.Value; - } - private void cancelExit() => loader?.CancelPendingDifficultySwitch(); public double SnapTime(double time, double? referenceTime) => editorBeatmap.SnapTime(time, referenceTime); diff --git a/osu.Game/Screens/Edit/EditorLoader.cs b/osu.Game/Screens/Edit/EditorLoader.cs index 5ad720f7f0..2a01a5b6b2 100644 --- a/osu.Game/Screens/Edit/EditorLoader.cs +++ b/osu.Game/Screens/Edit/EditorLoader.cs @@ -91,7 +91,13 @@ namespace osu.Game.Screens.Edit private void pushEditor() { - this.Push(CreateEditor()); + var editor = CreateEditor(); + + this.Push(editor); + + if (state != null) + editor.RestoreState(state); + ValidForResume = false; } From 57f8ccca167d48e79c3c5e89b8d9db6d4a7febe9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Sep 2021 23:36:26 +0900 Subject: [PATCH 31/37] Remove nullability from `EditorState` properties Also update the xmldoc to not be specific to difficulty switching --- osu.Game/Screens/Edit/EditorState.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorState.cs b/osu.Game/Screens/Edit/EditorState.cs index 09cc1184d2..4690074e3d 100644 --- a/osu.Game/Screens/Edit/EditorState.cs +++ b/osu.Game/Screens/Edit/EditorState.cs @@ -6,19 +6,18 @@ namespace osu.Game.Screens.Edit { /// - /// Structure used to transport data between instances on difficulty change. - /// It's intended to be received by from one editor instance and passed down to the next one. + /// Structure used to convey the general state of an instance. /// public class EditorState { /// - /// The current clock time when a difficulty switch was requested. + /// The current audio time. /// - public double? Time { get; set; } + public double Time { get; set; } /// - /// The current editor clipboard content at the time when a difficulty switch was requested. + /// The editor clipboard content. /// - public string? ClipboardContent { get; set; } + public string ClipboardContent { get; set; } = string.Empty; } } From baf99619343ff49ed240c8cc09e3db9453dfda2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 14 Sep 2021 22:50:45 +0200 Subject: [PATCH 32/37] Amend xmldoc of shake extension method --- osu.Game/Extensions/DrawableExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Extensions/DrawableExtensions.cs b/osu.Game/Extensions/DrawableExtensions.cs index b05a2994ea..03cc345947 100644 --- a/osu.Game/Extensions/DrawableExtensions.cs +++ b/osu.Game/Extensions/DrawableExtensions.cs @@ -39,7 +39,7 @@ namespace osu.Game.Extensions } /// - /// Shake the contents of this container. + /// Shakes this drawable. /// /// The target to shake. /// The length of a single shake. From 4b3ab42ffd8cb2b9c60490315dce8470637dffcd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 15 Sep 2021 13:18:46 +0900 Subject: [PATCH 33/37] Ensure beatmap is populated --- osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs | 8 +++++++- .../Visual/Gameplay/TestSceneReplayRecording.cs | 8 +++++++- .../Visual/Gameplay/TestSceneSpectatorPlayback.cs | 4 +++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs index b38f7a998d..aded934b88 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs @@ -17,10 +17,12 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Replays; using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Screens.Play; +using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Visual.UserInterface; using osuTK; using osuTK.Graphics; @@ -54,7 +56,11 @@ namespace osu.Game.Tests.Visual.Gameplay { recordingManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique) { - Recorder = recorder = new TestReplayRecorder(new Score { Replay = replay }) + Recorder = recorder = new TestReplayRecorder(new Score + { + Replay = replay, + ScoreInfo = { Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo } + }) { ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos), }, diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs index 6e338b7202..37fd1a77d5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs @@ -13,10 +13,12 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Replays; using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Screens.Play; +using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Visual.UserInterface; using osuTK; using osuTK.Graphics; @@ -45,7 +47,11 @@ namespace osu.Game.Tests.Visual.Gameplay { recordingManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique) { - Recorder = new TestReplayRecorder(new Score { Replay = replay }) + Recorder = new TestReplayRecorder(new Score + { + Replay = replay, + ScoreInfo = { Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo } + }) { ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos) }, diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs index bb577886cc..039daf39e2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs @@ -25,11 +25,13 @@ using osu.Game.Online.Spectator; using osu.Game.Replays; using osu.Game.Replays.Legacy; using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Screens.Play; +using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Visual.UserInterface; using osuTK; using osuTK.Graphics; @@ -354,7 +356,7 @@ namespace osu.Game.Tests.Visual.Gameplay internal class TestReplayRecorder : ReplayRecorder { public TestReplayRecorder() - : base(new Score()) + : base(new Score { ScoreInfo = { Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo } }) { } From a2dcef7c0aa1acd3557007e3c410443862318512 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Sep 2021 13:37:30 +0900 Subject: [PATCH 34/37] Use local (or barebones `BeatmapInfo`) where feasible --- osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs | 4 +--- osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs | 4 +--- osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs index aded934b88..2ce0213ea2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs @@ -17,12 +17,10 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Replays; using osu.Game.Rulesets; -using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Screens.Play; -using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Visual.UserInterface; using osuTK; using osuTK.Graphics; @@ -59,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay Recorder = recorder = new TestReplayRecorder(new Score { Replay = replay, - ScoreInfo = { Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo } + ScoreInfo = { Beatmap = gameplayBeatmap.BeatmapInfo } }) { ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos), diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs index 37fd1a77d5..85a2870bf9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs @@ -13,12 +13,10 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Replays; using osu.Game.Rulesets; -using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Screens.Play; -using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Visual.UserInterface; using osuTK; using osuTK.Graphics; @@ -50,7 +48,7 @@ namespace osu.Game.Tests.Visual.Gameplay Recorder = new TestReplayRecorder(new Score { Replay = replay, - ScoreInfo = { Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo } + ScoreInfo = { Beatmap = gameplayBeatmap.BeatmapInfo } }) { ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs index 039daf39e2..d9d0dc6c58 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs @@ -25,13 +25,11 @@ using osu.Game.Online.Spectator; using osu.Game.Replays; using osu.Game.Replays.Legacy; using osu.Game.Rulesets; -using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Screens.Play; -using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Visual.UserInterface; using osuTK; using osuTK.Graphics; @@ -356,7 +354,7 @@ namespace osu.Game.Tests.Visual.Gameplay internal class TestReplayRecorder : ReplayRecorder { public TestReplayRecorder() - : base(new Score { ScoreInfo = { Beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo } }) + : base(new Score { ScoreInfo = { Beatmap = new BeatmapInfo() } }) { } From f9af24df23e88659793eb629ab13be689dfb3d5f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 15 Sep 2021 15:22:27 +0900 Subject: [PATCH 35/37] Fix mania hitobject tests --- .../Skinning/ManiaHitObjectTestScene.cs | 4 +-- .../Skinning/ManiaSkinnableTestScene.cs | 25 ++----------------- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs index b7d7af6b8c..68cf3b67df 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning { c.Add(CreateHitObject().With(h => { - h.HitObject.StartTime = START_TIME; + h.HitObject.StartTime = Time.Current + 5000; h.AccentColour.Value = Color4.Orange; })); }) @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning { c.Add(CreateHitObject().With(h => { - h.HitObject.StartTime = START_TIME; + h.HitObject.StartTime = Time.Current + 5000; h.AccentColour.Value = Color4.Orange; })); }) diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaSkinnableTestScene.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaSkinnableTestScene.cs index 1d84a2dfcb..ddfd057cd8 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaSkinnableTestScene.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaSkinnableTestScene.cs @@ -19,8 +19,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning /// public abstract class ManiaSkinnableTestScene : SkinnableTestScene { - protected const double START_TIME = 1000000000; - [Cached(Type = typeof(IScrollingInfo))] private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo(); @@ -55,27 +53,8 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning public readonly Bindable Direction = new Bindable(); IBindable IScrollingInfo.Direction => Direction; - IBindable IScrollingInfo.TimeRange { get; } = new Bindable(1000); - IScrollAlgorithm IScrollingInfo.Algorithm { get; } = new ZeroScrollAlgorithm(); - } - - private class ZeroScrollAlgorithm : IScrollAlgorithm - { - public double GetDisplayStartTime(double originTime, float offset, double timeRange, float scrollLength) - => double.MinValue; - - public float GetLength(double startTime, double endTime, double timeRange, float scrollLength) - => scrollLength; - - public float PositionAt(double time, double currentTime, double timeRange, float scrollLength) - => (float)((time - START_TIME) / timeRange) * scrollLength; - - public double TimeAt(float position, double currentTime, double timeRange, float scrollLength) - => 0; - - public void Reset() - { - } + IBindable IScrollingInfo.TimeRange { get; } = new Bindable(5000); + IScrollAlgorithm IScrollingInfo.Algorithm { get; } = new ConstantScrollAlgorithm(); } } } From f54d554d3099ecf845573bbcb9bda1c4250edc3c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 15 Sep 2021 17:03:26 +0900 Subject: [PATCH 36/37] Extract removal to method --- osu.Game/Online/Rooms/Room.cs | 15 ++++++++++----- .../Components/ListingPollingComponent.cs | 4 +--- .../Components/SelectionPollingComponent.cs | 4 +--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/osu.Game/Online/Rooms/Room.cs b/osu.Game/Online/Rooms/Room.cs index d964060f10..5f71b4be4a 100644 --- a/osu.Game/Online/Rooms/Room.cs +++ b/osu.Game/Online/Rooms/Room.cs @@ -179,11 +179,7 @@ namespace osu.Game.Online.Rooms if (EndDate.Value != null && DateTimeOffset.Now >= EndDate.Value) Status.Value = new RoomStatusEnded(); - // Todo: This is not the best way/place to do this, but the intention is to display all playlist items when the room has ended, - // and display only the non-expired playlist items while the room is still active. In order to achieve this, all expired items are removed from the source Room. - // More refactoring is required before this can be done locally instead - DrawableRoomPlaylist is currently directly bound to the playlist to display items in the room. - if (!(Status.Value is RoomStatusEnded)) - other.Playlist.RemoveAll(i => i.Expired); + other.RemoveExpiredPlaylistItems(); if (!Playlist.SequenceEqual(other.Playlist)) { @@ -200,6 +196,15 @@ namespace osu.Game.Online.Rooms Position.Value = other.Position.Value; } + public void RemoveExpiredPlaylistItems() + { + // Todo: This is not the best way/place to do this, but the intention is to display all playlist items when the room has ended, + // and display only the non-expired playlist items while the room is still active. In order to achieve this, all expired items are removed from the source Room. + // More refactoring is required before this can be done locally instead - DrawableRoomPlaylist is currently directly bound to the playlist to display items in the room. + if (!(Status.Value is RoomStatusEnded)) + Playlist.RemoveAll(i => i.Expired); + } + public bool ShouldSerializeRoomID() => false; public bool ShouldSerializeHost() => false; public bool ShouldSerializeEndDate() => false; diff --git a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs index 5a74df6ab1..fcf7767958 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs @@ -58,9 +58,7 @@ namespace osu.Game.Screens.OnlinePlay.Components foreach (var incoming in result) { - // Copy the room to itself to populate some members (such as status and playlist expiry). - incoming.CopyFrom(incoming); - + incoming.RemoveExpiredPlaylistItems(); RoomManager.AddOrUpdateRoom(incoming); } diff --git a/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs index 0a37d47e34..b9d2bdf23e 100644 --- a/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs @@ -39,9 +39,7 @@ namespace osu.Game.Screens.OnlinePlay.Components pollReq.Success += result => { - // Copy the room to itself to populate some members (such as status and playlist expiry). - result.CopyFrom(result); - + result.RemoveExpiredPlaylistItems(); RoomManager.AddOrUpdateRoom(result); tcs.SetResult(true); }; From cdb44d7239e3ad92a56e40bd04ce5a6ee7ad86c7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 15 Sep 2021 17:16:08 +0900 Subject: [PATCH 37/37] Fix match footer test scene not working in visual testing --- .../Visual/Multiplayer/TestSceneMultiplayerMatchFooter.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchFooter.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchFooter.cs index 4e08ffef17..44a8d7b439 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchFooter.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchFooter.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Multiplayer.Match; @@ -15,11 +16,13 @@ namespace osu.Game.Tests.Visual.Multiplayer { SelectedRoom.Value = new Room(); - Child = new MultiplayerMatchFooter + Child = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Height = 50 + RelativeSizeAxes = Axes.X, + Height = 50, + Child = new MultiplayerMatchFooter() }; }); }