diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68f8ef51ef..2139572601 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,7 @@ jobs: run: dotnet build -c Debug -warnaserror osu.Desktop.slnf - name: Test - run: dotnet test $pwd/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx" + run: dotnet test $pwd/*.Tests/bin/Debug/*/*.Tests.dll --blame-crash --blame-hang --blame-hang-timeout 5m --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx" shell: pwsh # Attempt to upload results even if test fails. @@ -48,7 +48,7 @@ jobs: if: ${{ always() }} with: name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}} - path: ${{github.workspace}}/TestResults/TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx + path: ${{github.workspace}}/TestResults/**/* build-only-android: name: Build only (Android) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index 29a7b03ad3..4f527e9a0f 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -168,6 +168,28 @@ namespace osu.Game.Rulesets.Catch.Tests checkHyperDash(false); } + [Test] + public void TestLastBananaShouldClearPlateOnMiss() + { + AddStep("catch fruit", () => attemptCatch(new Fruit())); + checkPlate(1); + AddStep("miss banana", () => attemptCatch(new Banana { X = 100 })); + checkPlate(1); + AddStep("miss last banana", () => attemptCatch(new Banana { LastInCombo = true, X = 100 })); + checkPlate(0); + } + + [Test] + public void TestLastBananaShouldClearPlateOnCatch() + { + AddStep("catch fruit", () => attemptCatch(new Fruit())); + checkPlate(1); + AddStep("catch banana", () => attemptCatch(new Banana())); + checkPlate(2); + AddStep("catch last banana", () => attemptCatch(new Banana { LastInCombo = true })); + checkPlate(0); + } + [Test] public void TestCatcherRandomStacking() { diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 2a13190cc5..04708c8796 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -210,6 +210,7 @@ namespace osu.Game.Rulesets.Catch.UI catchResult.CatcherAnimationState = CurrentState; catchResult.CatcherHyperDash = HyperDashing; + // Ignore JuiceStreams and BananaShowers if (!(drawableObject is DrawablePalpableCatchHitObject palpableObject)) return; var hitObject = palpableObject.HitObject; @@ -244,6 +245,14 @@ namespace osu.Game.Rulesets.Catch.UI CurrentState = hitObject.Kiai ? CatcherAnimationState.Kiai : CatcherAnimationState.Idle; else if (!(hitObject is Banana)) CurrentState = CatcherAnimationState.Fail; + + if (palpableObject.HitObject.LastInCombo) + { + if (result.Judgement is CatchJudgement catchJudgement && catchJudgement.ShouldExplodeFor(result)) + Explode(); + else + Drop(); + } } public void OnRevertResult(DrawableCatchHitObject drawableObject, JudgementResult result) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 604e878782..37002d1051 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -6,11 +6,9 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; -using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osuTK; @@ -72,18 +70,6 @@ namespace osu.Game.Rulesets.Catch.UI public void OnNewResult(DrawableCatchHitObject hitObject, JudgementResult result) { Catcher.OnNewResult(hitObject, result); - - if (!result.Type.IsScorable()) - return; - - if (hitObject.HitObject.LastInCombo) - { - if (result.Judgement is CatchJudgement catchJudgement && catchJudgement.ShouldExplodeFor(result)) - Catcher.Explode(); - else - Catcher.Drop(); - } - comboDisplay.OnNewResult(hitObject, result); } diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs index 69ea1dc520..194341d1ab 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs @@ -428,7 +428,7 @@ namespace osu.Game.Tests.Visual.Background public float CurrentDim => dimmable.DimLevel; - public Vector2 CurrentBlur => Background.BlurSigma; + public Vector2 CurrentBlur => Background?.BlurSigma ?? Vector2.Zero; private TestDimmableBackground dimmable; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs index e7998fc01c..44efef53f5 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs @@ -1,7 +1,10 @@ // 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.Diagnostics; using System.Linq; +using Microsoft.AspNetCore.SignalR; using osu.Framework.Allocation; using osu.Framework.Logging; using osu.Framework.Screens; @@ -69,13 +72,28 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer { loadingLayer.Hide(); - if (t.IsCompletedSuccessfully) - this.Exit(); - else + if (t.IsFaulted) { - Logger.Log($"Could not use current beatmap ({t.Exception?.Message})", level: LogLevel.Important); + Exception exception = t.Exception; + + if (exception is AggregateException ae) + exception = ae.InnerException; + + Debug.Assert(exception != null); + + string message = exception is HubException + // HubExceptions arrive with additional message context added, but we want to display the human readable message: + // "An unexpected error occurred invoking 'AddPlaylistItem' on the server.InvalidStateException: Can't enqueue more than 3 items at once." + // We generally use the message field for a user-parseable error (eventually to be replaced), so drop the first part for now. + ? exception.Message.Substring(exception.Message.IndexOf(':') + 1).Trim() + : exception.Message; + + Logger.Log(message, level: LogLevel.Important); Carousel.AllowSelection = true; + return; } + + this.Exit(); }); }); }