From 1173ef089099e2468b80cf33eeb8f9bf79bbcc80 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 11 Nov 2020 12:37:00 +0900 Subject: [PATCH 1/3] 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/3] 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/3] 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(); }