From 1173ef089099e2468b80cf33eeb8f9bf79bbcc80 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Nov 2020 12:37:00 +0900 Subject: [PATCH 1/5] Fix mania notelock crashing with overlapping hitwindows --- .../TestSceneHoldNoteInput.cs | 2 +- .../TestSceneOutOfOrderHits.cs | 23 +++++++++++++++++++ .../Objects/Drawables/DrawableHoldNote.cs | 2 +- .../UI/OrderedHitPolicy.cs | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 5cb1519196..6c9f184c2c 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mania.Tests assertHeadJudgement(HitResult.Miss); assertTickJudgement(HitResult.LargeTickMiss); assertTailJudgement(HitResult.Miss); - assertNoteJudgement(HitResult.IgnoreHit); + assertNoteJudgement(HitResult.IgnoreMiss); } /// diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs index e8c2472c3b..d699921307 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs @@ -54,6 +54,29 @@ namespace osu.Game.Rulesets.Mania.Tests } } + [Test] + public void TestMissAfterNextObjectStartTime() + { + var objects = new List + { + new HoldNote + { + StartTime = 1000, + EndTime = 1200, + }, + new HoldNote + { + StartTime = 1220, + EndTime = 1420 + } + }; + + performTest(objects, new List()); + + addJudgementAssert(objects[0], HitResult.IgnoreMiss); + addJudgementAssert(objects[1], HitResult.IgnoreMiss); + } + private void addJudgementAssert(ManiaHitObject hitObject, HitResult result) { AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judgement is {result}", diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index d9d740c145..3b3f72157a 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -233,7 +233,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { if (Tail.AllJudged) { - ApplyResult(r => r.Type = r.Judgement.MaxResult); + ApplyResult(r => r.Type = Tail.IsHit ? r.Judgement.MaxResult : r.Judgement.MinResult); endHold(); } diff --git a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs index 0f9cd48dd8..9bc577a81e 100644 --- a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Mania.UI /// The that was hit. public void HandleHit(DrawableHitObject hitObject) { - if (!IsHittable(hitObject, hitObject.HitObject.StartTime + hitObject.Result.TimeOffset)) + if (hitObject.IsHit && !IsHittable(hitObject, hitObject.HitObject.StartTime + hitObject.Result.TimeOffset)) throw new InvalidOperationException($"A {hitObject} was hit before it became hittable!"); foreach (var obj in enumerateHitObjectsUpTo(hitObject.HitObject.StartTime)) From 626231d90626790a063f9b93256276e2b4d8135e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Nov 2020 12:53:32 +0900 Subject: [PATCH 2/5] Completely remove check as it can occur for hits too --- .../TestSceneOutOfOrderHits.cs | 51 +++++++++++++++++-- .../UI/OrderedHitPolicy.cs | 4 -- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs index d699921307..86a142f2f6 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.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 System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -55,19 +56,19 @@ namespace osu.Game.Rulesets.Mania.Tests } [Test] - public void TestMissAfterNextObjectStartTime() + public void TestHoldNoteMissAfterNextObjectStartTime() { var objects = new List { new HoldNote { StartTime = 1000, - EndTime = 1200, + EndTime = 1010, }, new HoldNote { - StartTime = 1220, - EndTime = 1420 + StartTime = 1020, + EndTime = 1030 } }; @@ -77,12 +78,54 @@ namespace osu.Game.Rulesets.Mania.Tests addJudgementAssert(objects[1], HitResult.IgnoreMiss); } + [Test] + public void TestHoldNoteReleasedHitAfterNextObjectStartTime() + { + var objects = new List + { + new HoldNote + { + StartTime = 1000, + EndTime = 1010, + }, + new HoldNote + { + StartTime = 1020, + EndTime = 1030 + } + }; + + var frames = new List + { + new ManiaReplayFrame(1000, ManiaAction.Key1), + new ManiaReplayFrame(1030), + new ManiaReplayFrame(1040, ManiaAction.Key1), + new ManiaReplayFrame(1050) + }; + + performTest(objects, frames); + + addJudgementAssert(objects[0], HitResult.IgnoreHit); + addJudgementAssert("first head", () => ((HoldNote)objects[0]).Head, HitResult.Perfect); + addJudgementAssert("first tail", () => ((HoldNote)objects[0]).Tail, HitResult.Perfect); + + addJudgementAssert(objects[1], HitResult.IgnoreHit); + addJudgementAssert("second head", () => ((HoldNote)objects[1]).Head, HitResult.Great); + addJudgementAssert("second tail", () => ((HoldNote)objects[1]).Tail, HitResult.Perfect); + } + private void addJudgementAssert(ManiaHitObject hitObject, HitResult result) { AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judgement is {result}", () => judgementResults.Single(r => r.HitObject == hitObject).Type == result); } + private void addJudgementAssert(string name, Func hitObject, HitResult result) + { + AddAssert($"{name} judgement is {result}", + () => judgementResults.Single(r => r.HitObject == hitObject()).Type == result); + } + private void addJudgementOffsetAssert(ManiaHitObject hitObject, double offset) { AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judged at {offset}", diff --git a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs index 9bc577a81e..961858b62b 100644 --- a/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Mania/UI/OrderedHitPolicy.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.Extensions.IEnumerableExtensions; using osu.Game.Rulesets.Mania.Objects.Drawables; @@ -44,9 +43,6 @@ namespace osu.Game.Rulesets.Mania.UI /// The that was hit. public void HandleHit(DrawableHitObject hitObject) { - if (hitObject.IsHit && !IsHittable(hitObject, hitObject.HitObject.StartTime + hitObject.Result.TimeOffset)) - throw new InvalidOperationException($"A {hitObject} was hit before it became hittable!"); - foreach (var obj in enumerateHitObjectsUpTo(hitObject.HitObject.StartTime)) { if (obj.Judged) From 508ae91a978e3d706d654457cbfaff4206aea266 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Nov 2020 12:53:53 +0900 Subject: [PATCH 3/5] Revert unnecessary change --- osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs | 2 +- osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs | 4 ++-- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 6c9f184c2c..5cb1519196 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mania.Tests assertHeadJudgement(HitResult.Miss); assertTickJudgement(HitResult.LargeTickMiss); assertTailJudgement(HitResult.Miss); - assertNoteJudgement(HitResult.IgnoreMiss); + assertNoteJudgement(HitResult.IgnoreHit); } /// diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs index 86a142f2f6..cecac38f70 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs @@ -74,8 +74,8 @@ namespace osu.Game.Rulesets.Mania.Tests performTest(objects, new List()); - addJudgementAssert(objects[0], HitResult.IgnoreMiss); - addJudgementAssert(objects[1], HitResult.IgnoreMiss); + addJudgementAssert(objects[0], HitResult.IgnoreHit); + addJudgementAssert(objects[1], HitResult.IgnoreHit); } [Test] diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 3b3f72157a..d9d740c145 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -233,7 +233,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { if (Tail.AllJudged) { - ApplyResult(r => r.Type = Tail.IsHit ? r.Judgement.MaxResult : r.Judgement.MinResult); + ApplyResult(r => r.Type = r.Judgement.MaxResult); endHold(); } From 8d38d9cc93497a0f32d253afc15e14769670b456 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Nov 2020 13:05:03 +0900 Subject: [PATCH 4/5] Add hotkey to select random skin --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- .../Input/Bindings/GlobalActionContainer.cs | 5 +++++ osu.Game/OsuGame.cs | 4 ++++ .../Overlays/Settings/Sections/SkinSection.cs | 17 +---------------- osu.Game/Skinning/SkinManager.cs | 15 +++++++++++++++ 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 795ad96170..a4b99bb6e6 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -189,7 +189,7 @@ namespace osu.Game.Configuration new TrackedSetting(OsuSetting.Skin, m => { string skinName = LookupSkinName(m) ?? string.Empty; - return new SettingDescription(skinName, "skin", skinName); + return new SettingDescription(skinName, "skin", skinName, $"random: {LookupKeyBindings(GlobalAction.RandomSkin)}"); }) }; } diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 3de4bb1f9d..e5d3a89a88 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -48,6 +48,8 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.Space, GlobalAction.Select), new KeyBinding(InputKey.Enter, GlobalAction.Select), new KeyBinding(InputKey.KeypadEnter, GlobalAction.Select), + + new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.R }, GlobalAction.RandomSkin), }; public IEnumerable EditorKeyBindings => new[] @@ -191,5 +193,8 @@ namespace osu.Game.Input.Bindings [Description("Hold for HUD")] HoldForHUD, + + [Description("Random Skin")] + RandomSkin, } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 7f0465604b..1e94becb98 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -887,6 +887,10 @@ namespace osu.Game case GlobalAction.ToggleGameplayMouseButtons: LocalConfig.Set(OsuSetting.MouseDisableButtons, !LocalConfig.Get(OsuSetting.MouseDisableButtons)); return true; + + case GlobalAction.RandomSkin: + SkinManager.SelectRandomSkin(); + return true; } return false; diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 8297b56db8..3e7068f1ff 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -9,7 +9,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Logging; -using osu.Framework.Utils; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Skinning; @@ -103,7 +102,7 @@ namespace osu.Game.Overlays.Settings.Sections { if (skin.NewValue == random_skin_info) { - randomizeSkin(); + skins.SelectRandomSkin(); return; } @@ -111,20 +110,6 @@ namespace osu.Game.Overlays.Settings.Sections }); } - private void randomizeSkin() - { - // choose from only user skins, removing the current selection to ensure a new one is chosen. - var randomChoices = skinItems.Where(s => s.ID > 0 && s.ID != configBindable.Value).ToArray(); - - if (randomChoices.Length == 0) - { - configBindable.Value = SkinInfo.Default.ID; - return; - } - - configBindable.Value = randomChoices.ElementAt(RNG.Next(0, randomChoices.Length)).ID; - } - private void updateItems() { skinItems = skins.GetAllUsableSkins(); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 2e4c24a89e..bef3e86a4d 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -19,6 +19,7 @@ using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Framework.Platform; using osu.Framework.Testing; +using osu.Framework.Utils; using osu.Game.Audio; using osu.Game.Database; using osu.Game.IO.Archives; @@ -87,6 +88,20 @@ namespace osu.Game.Skinning /// A newly allocated list of available . public List GetAllUserSkins() => ModelStore.ConsumableItems.Where(s => !s.DeletePending).ToList(); + public void SelectRandomSkin() + { + // choose from only user skins, removing the current selection to ensure a new one is chosen. + var randomChoices = GetAllUsableSkins().Where(s => s.ID > 0 && s.ID != CurrentSkinInfo.Value.ID).ToArray(); + + if (randomChoices.Length == 0) + { + CurrentSkinInfo.Value = SkinInfo.Default; + return; + } + + CurrentSkinInfo.Value = randomChoices.ElementAt(RNG.Next(0, randomChoices.Length)); + } + protected override SkinInfo CreateModel(ArchiveReader archive) => new SkinInfo { Name = archive.Name }; private const string unknown_creator_string = "Unknown"; From 804450e707300b51abfc13014d354f9a9a1123ce Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Nov 2020 15:49:45 +0900 Subject: [PATCH 5/5] Remove duplicate instantiation of externalLinkOpener --- osu.Game/OsuGame.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 5119f262d5..a4e7214d32 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -662,7 +662,6 @@ namespace osu.Game loadComponentSingleFile(new AccountCreationOverlay(), topMostOverlayContent.Add, true); loadComponentSingleFile(new DialogOverlay(), topMostOverlayContent.Add, true); - loadComponentSingleFile(externalLinkOpener = new ExternalLinkOpener(), topMostOverlayContent.Add); chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;