Skip to content

Commit

Permalink
Merge branch 'master' into upgrade-to-SDL3
Browse files Browse the repository at this point in the history
  • Loading branch information
peppy committed Apr 18, 2024
2 parents 46e2cfd + 15d286e commit c39eb5c
Show file tree
Hide file tree
Showing 24 changed files with 368 additions and 45 deletions.
4 changes: 3 additions & 1 deletion osu.Desktop/DiscordRichPresence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,9 @@ private void updatePresence(bool hideIdentifiableInformation)
Password = room.Settings.Password,
};

presence.Secrets.JoinSecret = JsonConvert.SerializeObject(roomSecret);
if (client.HasRegisteredUriScheme)
presence.Secrets.JoinSecret = JsonConvert.SerializeObject(roomSecret);

// discord cannot handle both secrets and buttons at the same time, so we need to choose something.
// the multiplayer room seems more important.
presence.Buttons = null;
Expand Down
25 changes: 21 additions & 4 deletions osu.Desktop/Performance/HighPerformanceSessionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Runtime;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Logging;
using osu.Game.Performance;
Expand All @@ -11,16 +12,26 @@ namespace osu.Desktop.Performance
{
public class HighPerformanceSessionManager : IHighPerformanceSessionManager
{
public bool IsSessionActive => activeSessions > 0;

private int activeSessions;

private GCLatencyMode originalGCMode;

public IDisposable BeginSession()
{
enableHighPerformanceSession();
return new InvokeOnDisposal<HighPerformanceSessionManager>(this, static m => m.disableHighPerformanceSession());
enterSession();
return new InvokeOnDisposal<HighPerformanceSessionManager>(this, static m => m.exitSession());
}

private void enableHighPerformanceSession()
private void enterSession()
{
if (Interlocked.Increment(ref activeSessions) > 1)
{
Logger.Log($"High performance session requested ({activeSessions} running in total)");
return;
}

Logger.Log("Starting high performance session");

originalGCMode = GCSettings.LatencyMode;
Expand All @@ -30,8 +41,14 @@ private void enableHighPerformanceSession()
GC.Collect(0);
}

private void disableHighPerformanceSession()
private void exitSession()
{
if (Interlocked.Decrement(ref activeSessions) > 0)
{
Logger.Log($"High performance session finished ({activeSessions} others remain)");
return;
}

Logger.Log("Ending high performance session");

if (GCSettings.LatencyMode == GCLatencyMode.LowLatency)
Expand Down
20 changes: 20 additions & 0 deletions osu.Game.Rulesets.Mania/ManiaFilterCriteria.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using System.Linq;
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Filter;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring.Legacy;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
Expand All @@ -30,5 +35,20 @@ public bool TryParseCustomKeywordCriteria(string key, Operator op, string value)

return false;
}

public bool FilterMayChangeFromMods(ValueChangedEvent<IReadOnlyList<Mod>> mods)
{
if (keys.HasFilter)
{
// Interpreting as the Mod type is required for equality comparison.
HashSet<Mod> oldSet = mods.OldValue.OfType<ManiaKeyMod>().AsEnumerable<Mod>().ToHashSet();
HashSet<Mod> newSet = mods.NewValue.OfType<ManiaKeyMod>().AsEnumerable<Mod>().ToHashSet();

if (!oldSet.SetEquals(newSet))
return true;
}

return false;
}
}
}
69 changes: 69 additions & 0 deletions osu.Game.Rulesets.Osu.Tests/TestSceneResume.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Screens.Play;
using osu.Game.Tests.Visual;
using osuTK;
using osuTK.Input;

namespace osu.Game.Rulesets.Osu.Tests
{
public partial class TestSceneResume : PlayerTestScene
{
protected override Ruleset CreatePlayerRuleset() => new OsuRuleset();

protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, false, AllowBackwardsSeeks);

[Test]
public void TestPauseViaKeyboard()
{
AddStep("move mouse to center", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.Centre));
AddUntilStep("wait for gameplay start", () => Player.LocalUserPlaying.Value);
AddStep("press escape", () => InputManager.PressKey(Key.Escape));
AddUntilStep("wait for pause overlay", () => Player.ChildrenOfType<PauseOverlay>().Single().State.Value, () => Is.EqualTo(Visibility.Visible));
AddStep("release escape", () => InputManager.ReleaseKey(Key.Escape));
AddStep("resume", () =>
{
InputManager.Key(Key.Down);
InputManager.Key(Key.Space);
});
AddUntilStep("pause overlay present", () => Player.DrawableRuleset.ResumeOverlay.State.Value, () => Is.EqualTo(Visibility.Visible));
}

[Test]
public void TestPauseViaKeyboardWhenMouseOutsidePlayfield()
{
AddStep("move mouse outside playfield", () => InputManager.MoveMouseTo(Player.DrawableRuleset.Playfield.ScreenSpaceDrawQuad.BottomRight + new Vector2(1)));
AddUntilStep("wait for gameplay start", () => Player.LocalUserPlaying.Value);
AddStep("press escape", () => InputManager.PressKey(Key.Escape));
AddUntilStep("wait for pause overlay", () => Player.ChildrenOfType<PauseOverlay>().Single().State.Value, () => Is.EqualTo(Visibility.Visible));
AddStep("release escape", () => InputManager.ReleaseKey(Key.Escape));
AddStep("resume", () =>
{
InputManager.Key(Key.Down);
InputManager.Key(Key.Space);
});
AddUntilStep("pause overlay present", () => Player.DrawableRuleset.ResumeOverlay.State.Value, () => Is.EqualTo(Visibility.Visible));
}

[Test]
public void TestPauseViaKeyboardWhenMouseOutsideScreen()
{
AddStep("move mouse outside playfield", () => InputManager.MoveMouseTo(new Vector2(-20)));
AddUntilStep("wait for gameplay start", () => Player.LocalUserPlaying.Value);
AddStep("press escape", () => InputManager.PressKey(Key.Escape));
AddUntilStep("wait for pause overlay", () => Player.ChildrenOfType<PauseOverlay>().Single().State.Value, () => Is.EqualTo(Visibility.Visible));
AddStep("release escape", () => InputManager.ReleaseKey(Key.Escape));
AddStep("resume", () =>
{
InputManager.Key(Key.Down);
InputManager.Key(Key.Space);
});
AddUntilStep("pause overlay not present", () => Player.DrawableRuleset.ResumeOverlay.State.Value, () => Is.EqualTo(Visibility.Hidden));
}
}
}
6 changes: 3 additions & 3 deletions osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ private double computeAimValue(ScoreInfo score, OsuDifficultyAttributes attribut

if (score.Mods.Any(m => m is OsuModBlinds))
aimValue *= 1.3 + (totalHits * (0.0016 / (1 + 2 * effectiveMissCount)) * Math.Pow(accuracy, 16)) * (1 - 0.003 * attributes.DrainRate * attributes.DrainRate);
else if (score.Mods.Any(h => h is OsuModHidden))
else if (score.Mods.Any(m => m is OsuModHidden || m is OsuModTraceable))
{
// We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR.
aimValue *= 1.0 + 0.04 * (12.0 - attributes.ApproachRate);
Expand Down Expand Up @@ -162,7 +162,7 @@ private double computeSpeedValue(ScoreInfo score, OsuDifficultyAttributes attrib
// Increasing the speed value by object count for Blinds isn't ideal, so the minimum buff is given.
speedValue *= 1.12;
}
else if (score.Mods.Any(m => m is OsuModHidden))
else if (score.Mods.Any(m => m is OsuModHidden || m is OsuModTraceable))
{
// We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR.
speedValue *= 1.0 + 0.04 * (12.0 - attributes.ApproachRate);
Expand Down Expand Up @@ -212,7 +212,7 @@ private double computeAccuracyValue(ScoreInfo score, OsuDifficultyAttributes att
// Increasing the accuracy value by object count for Blinds isn't ideal, so the minimum buff is given.
if (score.Mods.Any(m => m is OsuModBlinds))
accuracyValue *= 1.14;
else if (score.Mods.Any(m => m is OsuModHidden))
else if (score.Mods.Any(m => m is OsuModHidden || m is OsuModTraceable))
accuracyValue *= 1.08;

if (score.Mods.Any(m => m is OsuModFlashlight))
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Osu/Objects/Slider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public double Duration

public Vector2 StackedPositionAt(double t) => StackedPosition + this.CurvePositionAt(t);

private readonly SliderPath path = new SliderPath();
private readonly SliderPath path = new SliderPath { OptimiseCatmull = true };

public SliderPath Path
{
Expand Down
20 changes: 11 additions & 9 deletions osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable disable

using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
Expand All @@ -12,22 +10,26 @@
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Rulesets.Osu.UI.Cursor;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using osuTK.Graphics;

namespace osu.Game.Rulesets.Osu.UI
{
public partial class OsuResumeOverlay : ResumeOverlay
{
private Container cursorScaleContainer;
private OsuClickToResumeCursor clickToResumeCursor;
private Container cursorScaleContainer = null!;
private OsuClickToResumeCursor clickToResumeCursor = null!;

private OsuCursorContainer localCursorContainer;
private OsuCursorContainer? localCursorContainer;

public override CursorContainer LocalCursor => State.Value == Visibility.Visible ? localCursorContainer : null;
public override CursorContainer? LocalCursor => State.Value == Visibility.Visible ? localCursorContainer : null;

protected override LocalisableString Message => "Click the orange cursor to resume";

[Resolved]
private DrawableRuleset? drawableRuleset { get; set; }

[BackgroundDependencyLoader]
private void load()
{
Expand All @@ -40,7 +42,7 @@ private void load()
protected override void PopIn()
{
// Can't display if the cursor is outside the window.
if (GameplayCursor.LastFrameState == Visibility.Hidden || !Contains(GameplayCursor.ActiveCursor.ScreenSpaceDrawQuad.Centre))
if (GameplayCursor.LastFrameState == Visibility.Hidden || drawableRuleset?.Contains(GameplayCursor.ActiveCursor.ScreenSpaceDrawQuad.Centre) == false)
{
Resume();
return;
Expand Down Expand Up @@ -71,8 +73,8 @@ public partial class OsuClickToResumeCursor : OsuCursor, IKeyBindingHandler<OsuA
{
public override bool HandlePositionalInput => true;

public Action ResumeRequested;
private Container scaleTransitionContainer;
public Action? ResumeRequested;
private Container scaleTransitionContainer = null!;

public OsuClickToResumeCursor()
{
Expand Down
5 changes: 5 additions & 0 deletions osu.Game.Tests/NonVisual/Filtering/FilterMatchingTest.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Filter;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Carousel;
using osu.Game.Screens.Select.Filter;
Expand Down Expand Up @@ -311,6 +314,8 @@ public CustomCriteria(bool shouldMatch)

public bool Matches(BeatmapInfo beatmapInfo, FilterCriteria criteria) => match;
public bool TryParseCustomKeywordCriteria(string key, Operator op, string value) => false;

public bool FilterMayChangeFromMods(ValueChangedEvent<IReadOnlyList<Mod>> mods) => false;
}
}
}
5 changes: 5 additions & 0 deletions osu.Game.Tests/NonVisual/Filtering/FilterQueryParserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Filter;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Carousel;
using osu.Game.Screens.Select.Filter;
Expand Down Expand Up @@ -514,6 +517,8 @@ public bool TryParseCustomKeywordCriteria(string key, Operator op, string value)

return false;
}

public bool FilterMayChangeFromMods(ValueChangedEvent<IReadOnlyList<Mod>> mods) => false;
}

private static readonly object[] correct_date_query_examples =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,21 @@ public void TestPPShownAsProvisionalWhenUnrankedModsArePresent()
});
}

[Test]
public void TestPPNotShownAsProvisionalIfClassicModIsPresentDueToLegacyScore()
{
AddStep("show example score", () =>
{
var score = TestResources.CreateTestScoreInfo(createTestBeatmap(new RealmUser()));
score.PP = 400;
score.Mods = score.Mods.Append(new OsuModClassic()).ToArray();
score.IsLegacyScore = true;
showPanel(score);
});

AddAssert("pp display faded out", () => this.ChildrenOfType<PerformanceStatistic>().Single().Alpha == 1);
}

[Test]
public void TestWithDefaultDate()
{
Expand Down
Loading

0 comments on commit c39eb5c

Please sign in to comment.