1 Commits

Author SHA1 Message Date
fb7ccba4ba bump to 2025.1209.0-lazer 2025-12-09 20:18:13 +03:00
119 changed files with 354 additions and 723 deletions

View File

@@ -21,7 +21,7 @@
]
},
"ppy.localisationanalyser.tools": {
"version": "2025.1208.0",
"version": "2024.802.0",
"commands": [
"localisation"
]

View File

@@ -39,7 +39,7 @@ jobs:
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
- name: Dotnet code style
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf -p:EnforceCodeStyleInBuild=true
- name: CodeFileSanity
run: |

View File

@@ -21,8 +21,8 @@ jobs:
uses: getsentry/action-release@v1
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: jvnkosu
SENTRY_PROJECT: client
SENTRY_ORG: ppy
SENTRY_PROJECT: osu
SENTRY_URL: https://satellite.jvnko.boats/
with:
environment: production

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PackageType>Template</PackageType>
<PackageId>jvnkosu.Client.Templates</PackageId>
<PackageId>ppy.osu.Game.Templates</PackageId>
<Title>osu! templates</Title>
<Authors>ppy Pty Ltd</Authors>
<PackageLicenseUrl>https://github.com/ppy/osu/blob/master/LICENCE</PackageLicenseUrl>

View File

@@ -148,13 +148,7 @@ namespace osu.Desktop
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
if (iconStream != null)
try
{
host.Window.SetIconFromStream(iconStream);
}
catch
{
}
host.Window.SetIconFromStream(iconStream);
host.Window.Title = Name;
}

View File

@@ -53,8 +53,8 @@ namespace osu.Desktop.Windows
private static readonly UriAssociation[] uri_associations =
{
new UriAssociation(@"jvnkosu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
new UriAssociation(@"jvnkosump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
new UriAssociation(@"osu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
new UriAssociation(@"osump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
};
/// <summary>

View File

@@ -72,9 +72,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
leaderboard.Origin = Anchor.CentreLeft;
leaderboard.X = 10;
}
foreach (var d in container.OfType<ISerialisableDrawable>())
d.UsesFixedAnchor = true;
})
{
Children = new Drawable[]

View File

@@ -57,9 +57,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
if (spectatorList != null)
spectatorList.Position = new Vector2(36, -66);
foreach (var d in container.OfType<ISerialisableDrawable>())
d.UsesFixedAnchor = true;
})
{
new DrawableGameplayLeaderboard(),

View File

@@ -122,9 +122,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
leaderboard.Origin = Anchor.CentreLeft;
leaderboard.X = 10;
}
foreach (var d in container.OfType<ISerialisableDrawable>())
d.UsesFixedAnchor = true;
})
{
new LegacyManiaComboCounter(),

View File

@@ -1,52 +0,0 @@
// 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 NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Testing;
using osu.Game.Configuration;
using osu.Game.Skinning;
using osu.Game.Tests.Visual;
using osuTK.Input;
namespace osu.Game.Rulesets.Osu.Tests
{
public partial class TestSceneGameplayCursorSizeChange : PlayerTestScene
{
private const float initial_cursor_size = 1f;
protected override Ruleset CreatePlayerRuleset() => new OsuRuleset();
[Resolved]
private SkinManager? skins { get; set; }
[BackgroundDependencyLoader]
private void load()
{
if (skins != null) skins.CurrentSkinInfo.Value = skins.DefaultClassicSkin.SkinInfo;
}
[SetUpSteps]
public override void SetUpSteps()
{
base.SetUpSteps();
AddStep("Set gameplay cursor size: 1", () => LocalConfig.SetValue(OsuSetting.GameplayCursorSize, initial_cursor_size));
AddStep("resume player", () => Player.GameplayClockContainer.Start());
AddUntilStep("clock running", () => Player.GameplayClockContainer.IsRunning);
}
[Test]
public void TestPausedChangeCursorSize()
{
AddStep("move cursor to center", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.Centre));
AddStep("move cursor to top left", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopLeft));
AddStep("move cursor to center", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.Centre));
AddStep("move cursor to top right", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopRight));
AddStep("press escape", () => InputManager.Key(Key.Escape));
AddSliderStep("cursor size", 0.1f, 2f, 1f, v => LocalConfig.SetValue(OsuSetting.GameplayCursorSize, v));
}
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, false);
}
}

View File

@@ -0,0 +1,16 @@
// 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 osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Game.Configuration;
using osu.Game.Overlays.Settings;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModRateAdjustConcrete : ModRateAdjustConcrete
{
}
}

View File

@@ -232,7 +232,10 @@ namespace osu.Game.Rulesets.Osu
case ModType.Special:
#if DEBUG
return Array.Empty<Mod>();
return new Mod[]
{
new OsuModRateAdjustConcrete(),
};
#endif
default:
@@ -254,11 +257,7 @@ namespace osu.Game.Rulesets.Osu
public override string ShortName => SHORT_NAME;
#if !DEBUG
public override string PlayingVerb => "Clicking circles";
#else
public override string PlayingVerb => "Debugging circles";
#endif
public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this);

View File

@@ -103,9 +103,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
leaderboard.Origin = Anchor.BottomLeft;
leaderboard.Position = pos;
}
foreach (var d in container.OfType<ISerialisableDrawable>())
d.UsesFixedAnchor = true;
})
{
Children = new Drawable[]

View File

@@ -49,18 +49,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
/// </summary>
protected bool AllowPartRotation { get; set; }
private Vector2 cursorScale;
public Vector2 CursorScale
{
get => cursorScale;
set
{
cursorScale = value;
Invalidate(Invalidation.DrawNode);
}
}
/// <summary>
/// The trail part texture origin.
/// </summary>
@@ -245,7 +233,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
private float time;
private float fadeExponent;
private float angle;
private Vector2 cursorScale;
private readonly TrailPart[] parts = new TrailPart[max_sprites];
private Vector2 originPosition;
@@ -266,7 +253,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
time = Source.time;
fadeExponent = Source.FadeExponent;
angle = Source.AllowPartRotation ? float.DegreesToRadians(Source.PartRotation) : 0;
cursorScale = Source.cursorScale;
originPosition = Vector2.Zero;
@@ -321,9 +307,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
vertexBatch.Add(new TexturedTrailVertex
{
Position = rotateAround(
new Vector2(
part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X * cursorScale.X,
part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y * cursorScale.Y),
new Vector2(part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X, part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y),
part.Position, sin, cos),
TexturePosition = textureRect.BottomLeft,
TextureRect = new Vector4(0, 0, 1, 1),
@@ -334,10 +318,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
vertexBatch.Add(new TexturedTrailVertex
{
Position = rotateAround(
new Vector2(
part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X * cursorScale.X,
part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y * cursorScale.Y),
part.Position, sin, cos),
new Vector2(part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X,
part.Position.Y + texture.DisplayHeight * (1 - originPosition.Y) * part.Scale.Y), part.Position, sin, cos),
TexturePosition = textureRect.BottomRight,
TextureRect = new Vector4(0, 0, 1, 1),
Colour = DrawColourInfo.Colour.BottomRight.Linear,
@@ -347,9 +329,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
vertexBatch.Add(new TexturedTrailVertex
{
Position = rotateAround(
new Vector2(
part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X * cursorScale.X,
part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y * cursorScale.Y),
new Vector2(part.Position.X + texture.DisplayWidth * (1 - originPosition.X) * part.Scale.X, part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y),
part.Position, sin, cos),
TexturePosition = textureRect.TopRight,
TextureRect = new Vector4(0, 0, 1, 1),
@@ -360,9 +340,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
vertexBatch.Add(new TexturedTrailVertex
{
Position = rotateAround(
new Vector2(
part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X * cursorScale.X,
part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y * cursorScale.Y),
new Vector2(part.Position.X - texture.DisplayWidth * originPosition.X * part.Scale.X, part.Position.Y - texture.DisplayHeight * originPosition.Y * part.Scale.Y),
part.Position, sin, cos),
TexturePosition = textureRect.TopLeft,
TextureRect = new Vector4(0, 0, 1, 1),

View File

@@ -64,14 +64,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
var newScale = new Vector2(e.NewValue);
rippleVisualiser.CursorScale = newScale;
updateTrailScale();
cursorTrail.Scale = newScale;
}, true);
cursorTrail.OnSkinChanged += updateTrailScale;
}
private void updateTrailScale()
{
if (cursorTrail.Drawable is CursorTrail trail) trail.CursorScale = new Vector2(ActiveCursor.CursorScale.Value);
}
private int downCount;

View File

@@ -51,9 +51,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon
spectatorList.Anchor = Anchor.BottomLeft;
spectatorList.Origin = Anchor.TopLeft;
}
foreach (var d in container.OfType<ISerialisableDrawable>())
d.UsesFixedAnchor = true;
})
{
RelativeSizeAxes = Axes.Both,

View File

@@ -51,9 +51,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
spectatorList.Origin = Anchor.TopLeft;
spectatorList.Position = new Vector2(320, -280);
}
foreach (var d in container.OfType<ISerialisableDrawable>())
d.UsesFixedAnchor = true;
})
{
RelativeSizeAxes = Axes.Both,

View File

@@ -79,9 +79,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
spectatorList.Origin = Anchor.TopLeft;
spectatorList.Position = pos;
}
foreach (var d in container.OfType<ISerialisableDrawable>())
d.UsesFixedAnchor = true;
})
{
new LegacyDefaultComboCounter(),

View File

@@ -17,7 +17,7 @@ namespace osu.Game.Tests.Chat
public void OneTimeSetUp()
{
originalWebsiteRootUrl = MessageFormatter.WebsiteRootUrl;
MessageFormatter.WebsiteRootUrl = "osu.jvnko.boats";
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";
}
[OneTimeTearDown]
@@ -47,11 +47,11 @@ namespace osu.Game.Tests.Chat
[Test]
public void TestSupportedProtocolLinkParsing()
{
Message result = MessageFormatter.FormatMessage(new Message { Content = "forgotspacehttps://osu.jvnko.boats joinmyjvnkosump://12345 jointhejvnkosu://chan/#english" });
Message result = MessageFormatter.FormatMessage(new Message { Content = "forgotspacehttps://dev.ppy.sh joinmyosump://12345 jointheosu://chan/#english" });
Assert.AreEqual("https://osu.jvnko.boats", result.Links[0].Url);
Assert.AreEqual("jvnkosump://12345", result.Links[1].Url);
Assert.AreEqual("jvnkosu://chan/#english", result.Links[2].Url);
Assert.AreEqual("https://dev.ppy.sh", result.Links[0].Url);
Assert.AreEqual("osump://12345", result.Links[1].Url);
Assert.AreEqual("osu://chan/#english", result.Links[2].Url);
}
[Test]
@@ -66,15 +66,15 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual(36, result.Links[0].Length);
}
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123#osu/456")]
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123#osu/456?whatever")]
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123/456")]
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/abc/def", "https://osu.jvnko.boats/beatmapsets/abc/def")]
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://osu.jvnko.boats/beatmapsets/123")]
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://osu.jvnko.boats/beatmapsets/123/whatever")]
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/abc", "https://osu.jvnko.boats/beatmapsets/abc")]
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/discussions", "https://osu.jvnko.boats/beatmapsets/discussions")]
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/discussions/123", "https://osu.jvnko.boats/beatmapsets/discussions/123")]
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456")]
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456?whatever")]
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123/456")]
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc/def", "https://dev.ppy.sh/beatmapsets/abc/def")]
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123")]
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123/whatever")]
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc", "https://dev.ppy.sh/beatmapsets/abc")]
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions", "https://dev.ppy.sh/beatmapsets/discussions")]
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions/123", "https://dev.ppy.sh/beatmapsets/discussions/123")]
public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link)
{
Message result = MessageFormatter.FormatMessage(new Message { Content = link });
@@ -150,7 +150,7 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual("This is a Wiki Link.", result.DisplayContent);
Assert.AreEqual(1, result.Links.Count);
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki Link", result.Links[0].Url);
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
Assert.AreEqual(10, result.Links[0].Index);
Assert.AreEqual(9, result.Links[0].Length);
}
@@ -163,15 +163,15 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual("This is a Wiki Link Wiki:LinkWiki.Link.", result.DisplayContent);
Assert.AreEqual(3, result.Links.Count);
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki Link", result.Links[0].Url);
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
Assert.AreEqual(10, result.Links[0].Index);
Assert.AreEqual(9, result.Links[0].Length);
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki:Link", result.Links[1].Url);
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki:Link", result.Links[1].Url);
Assert.AreEqual(20, result.Links[1].Index);
Assert.AreEqual(9, result.Links[1].Length);
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki.Link", result.Links[2].Url);
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki.Link", result.Links[2].Url);
Assert.AreEqual(29, result.Links[2].Index);
Assert.AreEqual(9, result.Links[2].Length);
}
@@ -452,7 +452,7 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual(1, result.Links.Count);
Assert.AreEqual($"{OsuGameBase.OSU_PROTOCOL}chan/#english", result.Links[0].Url);
Assert.AreEqual(26, result.Links[0].Index);
Assert.AreEqual(23, result.Links[0].Length);
Assert.AreEqual(19, result.Links[0].Length);
result = MessageFormatter.FormatMessage(new Message { Content = $"This is a [custom protocol]({OsuGameBase.OSU_PROTOCOL}chan/#english)." });
@@ -467,13 +467,13 @@ namespace osu.Game.Tests.Chat
[Test]
public void TestOsuMpProtocol()
{
Message result = MessageFormatter.FormatMessage(new Message { Content = "Join my multiplayer game jvnkosump://12346." });
Message result = MessageFormatter.FormatMessage(new Message { Content = "Join my multiplayer game osump://12346." });
Assert.AreEqual(result.Content, result.DisplayContent);
Assert.AreEqual(1, result.Links.Count);
Assert.AreEqual("jvnkosump://12346", result.Links[0].Url);
Assert.AreEqual("osump://12346", result.Links[0].Url);
Assert.AreEqual(25, result.Links[0].Index);
Assert.AreEqual(17, result.Links[0].Length);
Assert.AreEqual(13, result.Links[0].Length);
}
[Test]
@@ -499,7 +499,7 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual("This is a simple test with some [traps] and wiki links. Don't forget to visit https://osu.ppy.sh now![emoji]", result.DisplayContent);
Assert.AreEqual(4, result.Links.Count);
Link f = result.Links.Find(l => l.Url == "https://osu.jvnko.boats/wiki/wiki links");
Link f = result.Links.Find(l => l.Url == "https://dev.ppy.sh/wiki/wiki links");
Assert.That(f, Is.Not.Null);
Assert.AreEqual(44, f.Index);
Assert.AreEqual(10, f.Length);
@@ -554,8 +554,8 @@ namespace osu.Game.Tests.Chat
Assert.AreEqual("/relative", result.Argument);
}
[TestCase("https://osu.jvnko.boats/home/changelog", "")]
[TestCase("https://osu.jvnko.boats/home/changelog/lazer/2021.1012", "lazer/2021.1012")]
[TestCase("https://dev.ppy.sh/home/changelog", "")]
[TestCase("https://dev.ppy.sh/home/changelog/lazer/2021.1012", "lazer/2021.1012")]
public void TestChangelogLinks(string link, string expectedArg)
{
LinkDetails result = MessageFormatter.GetLinkDetails(link);

View File

@@ -134,12 +134,10 @@ namespace osu.Game.Tests.Mods
var mod = (OsuModDifficultyAdjust)apiMod.ToMod(ruleset);
// WARNING: this only makes sense for debug builds which have very extended limits
// release builds still use sane values
Assert.Multiple(() =>
{
Assert.That(mod.CircleSize.Value, Is.GreaterThanOrEqualTo(-250).And.LessThanOrEqualTo(13));
Assert.That(mod.ApproachRate.Value, Is.GreaterThanOrEqualTo(-250).And.LessThanOrEqualTo(13));
Assert.That(mod.CircleSize.Value, Is.GreaterThanOrEqualTo(0).And.LessThanOrEqualTo(11));
Assert.That(mod.ApproachRate.Value, Is.GreaterThanOrEqualTo(-10).And.LessThanOrEqualTo(11));
});
}

View File

@@ -39,7 +39,7 @@ namespace osu.Game.Tests.Online
Assert.NotNull(converted);
Assert.That(converted, Is.TypeOf(typeof(UnknownMod)));
Assert.That(converted.Type, Is.EqualTo(ModType.System));
Assert.That(converted.Acronym, Is.EqualTo("WNG!"));
Assert.That(converted.Acronym, Is.EqualTo("WNG??"));
}
[Test]

View File

@@ -225,7 +225,7 @@ namespace osu.Game.Tests.Online
public override Live<BeatmapSetInfo>? ImportModel(BeatmapSetInfo item, ArchiveReader? archive = null, ImportParameters parameters = default,
CancellationToken cancellationToken = default)
{
if (!testBeatmapManager.AllowImport.Wait(TimeSpan.FromSeconds(30), cancellationToken))
if (!testBeatmapManager.AllowImport.Wait(TimeSpan.FromSeconds(10), cancellationToken))
throw new TimeoutException("Timeout waiting for import to be allowed.");
return testBeatmapManager.CurrentImport = base.ImportModel(item, archive, parameters, cancellationToken);
@@ -257,4 +257,4 @@ namespace osu.Game.Tests.Online
protected override string Target => string.Empty;
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -79,12 +79,8 @@ namespace osu.Game.Tests.Skins
"Archives/modified-argon-20250424.osk",
// Covers "Argon" unstable rate counter
"Archives/modified-argon-20250809.osk",
// Covers legacy style performance points counter
"Archives/modified-classic-20250827.osk",
// Covers "Argon" judgement counter
"Archives/modified-argon-20250308.osk",
// Covers "Argon" clicks/s counter, longest combo counter, skinnable SR display and beatmap status pill
"Archives/modified-argon-20251215-jvnkosu.osk",
};
/// <summary>

View File

@@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
AddStep("create thumbnail", () =>
{
var beatmapSet = CreateAPIBeatmapSet(Ruleset.Value);
beatmapSet.OnlineID = 1; // ID hardcoded to ensure that the preview track exists online.
beatmapSet.OnlineID = 241526; // ID hardcoded to ensure that the preview track exists online.
Child = thumbnail = new BeatmapCardThumbnail(beatmapSet, beatmapSet)
{

View File

@@ -106,7 +106,7 @@ namespace osu.Game.Tests.Visual.Editing
setUpEditor(new OsuRuleset().RulesetInfo);
AddAssert("is osu! ruleset", () => editorBeatmap.BeatmapInfo.Ruleset.Equals(new OsuRuleset().RulesetInfo));
AddStep("jump to encoded link", () => Game.HandleLink("jvnkosu://edit/00:14:142%20(1)"));
AddStep("jump to encoded link", () => Game.HandleLink("osu://edit/00:14:142%20(1)"));
AddUntilStep("wait for seek", () => editorClock.SeekingOrStopped.Value);

View File

@@ -50,34 +50,6 @@ namespace osu.Game.Tests.Visual.Gameplay
sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Texture == null)));
}
[Test]
public void TestSpriteFadeOverflowBehaviour()
{
AddStep("create sprite", () => SetContents(_ =>
{
var layer = storyboard.GetLayer("Background");
var sprite = new StoryboardSprite(lookup_name, Anchor.TopLeft, new Vector2(256, 192));
sprite.Commands.AddAlpha(Easing.None, Time.Current, Time.Current + 2000, 0, 2);
layer.Elements.Clear();
layer.Add(sprite);
return new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
storyboard.CreateDrawable()
}
};
}));
AddUntilStep("sprite reached high opacity once", () => sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Alpha > 0.8f)));
AddUntilStep("sprite reset to low opacity", () => sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Alpha < 0.2f)));
AddUntilStep("sprite reached high opacity twice", () => sprites.All(sprite => sprite.ChildrenOfType<Sprite>().All(s => s.Alpha > 0.8f)));
}
[Test]
public void TestLookupFromStoryboard()
{

View File

@@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual.Gameplay
KeyCounter counter = null!;
loadPlayer(() => new OsuRuleset());
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
checkKey(() => counter, 0, false);
AddStep("press Z", () => InputManager.PressKey(Key.Z));
@@ -117,7 +117,7 @@ namespace osu.Game.Tests.Visual.Gameplay
KeyCounter counter = null!;
loadPlayer(() => new ManiaRuleset());
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
checkKey(() => counter, 0, false);
AddStep("press space", () => InputManager.PressKey(Key.Space));
@@ -150,8 +150,8 @@ namespace osu.Game.Tests.Visual.Gameplay
KeyCounter counterX = null!;
loadPlayer(() => new OsuRuleset());
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
AddStep("press Z", () => InputManager.PressKey(Key.Z));
AddStep("pause", () => Player.Pause());
@@ -184,7 +184,7 @@ namespace osu.Game.Tests.Visual.Gameplay
KeyCounter counter = null!;
loadPlayer(() => new ManiaRuleset());
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
AddStep("press space", () => InputManager.PressKey(Key.Space));
AddStep("pause", () => Player.Pause());
@@ -204,8 +204,8 @@ namespace osu.Game.Tests.Visual.Gameplay
KeyCounter counterX = null!;
loadPlayer(() => new OsuRuleset());
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
AddStep("get key counter Z", () => counterZ = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
AddStep("get key counter X", () => counterX = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.RightButton));
AddStep("press Z", () => InputManager.PressKey(Key.Z));
AddStep("pause", () => Player.Pause());
@@ -247,7 +247,7 @@ namespace osu.Game.Tests.Visual.Gameplay
KeyCounter counter = null!;
loadPlayer(() => new ManiaRuleset());
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<ManiaAction> actionTrigger && actionTrigger.Action == ManiaAction.Key4));
AddStep("press space", () => InputManager.PressKey(Key.Space));
checkKey(() => counter, 1, true);
@@ -271,7 +271,7 @@ namespace osu.Game.Tests.Visual.Gameplay
KeyCounter counter = null!;
loadPlayer(() => new OsuRuleset());
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
AddStep("pause", () => Player.Pause());
AddStep("resume", () => Player.Resume());
@@ -297,7 +297,7 @@ namespace osu.Game.Tests.Visual.Gameplay
KeyCounter counter = null!;
loadPlayer(() => new OsuRuleset());
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterBindingTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
AddStep("get key counter", () => counter = this.ChildrenOfType<KeyCounter>().Single(k => k.Trigger is KeyCounterActionTrigger<OsuAction> actionTrigger && actionTrigger.Action == OsuAction.LeftButton));
AddStep("press Z", () => InputManager.PressKey(Key.Z));
AddAssert("circle hit", () => Player.ScoreProcessor.HighestCombo.Value, () => Is.EqualTo(1));

View File

@@ -18,7 +18,6 @@ using osu.Game.Rulesets.Osu.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play;
using osu.Game.Screens.Play.HUD;
using osu.Game.Skinning;
using osu.Game.Skinning.Triangles;
using osu.Game.Tests.Gameplay;
@@ -36,7 +35,7 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override Drawable CreateDefaultImplementation() => new TrianglesPerformancePointsCounter();
protected override Drawable CreateArgonImplementation() => new ArgonPerformancePointsCounter();
protected override Drawable CreateLegacyImplementation() => new LegacyPerformancePointsCounter();
protected override Drawable CreateLegacyImplementation() => Empty();
private Bindable<JudgementResult> lastJudgementResult => (Bindable<JudgementResult>)gameplayState.LastJudgementResult;

View File

@@ -642,7 +642,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[BackgroundDependencyLoader]
private void load()
{
if (!AllowLoad.Wait(TimeSpan.FromSeconds(30)))
if (!AllowLoad.Wait(TimeSpan.FromSeconds(10)))
throw new TimeoutException();
}
}

View File

@@ -5,7 +5,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
@@ -379,23 +378,6 @@ namespace osu.Game.Tests.Visual.Gameplay
() => Is.EqualTo(3));
}
[Test]
public void TestCopyPasteIdempotency()
{
string state = null!;
AddStep("select everything", () => InputManager.Keys(PlatformAction.SelectAll));
AddStep("dump state", () =>
{
state = JsonConvert.SerializeObject(skinEditor.SelectedComponents.Cast<Drawable>().Select(s => s.CreateSerialisedInfo()).ToArray());
});
AddStep("copy", () => InputManager.Keys(PlatformAction.Copy));
AddStep("delete", () => InputManager.Keys(PlatformAction.Delete));
AddStep("paste", () => InputManager.Keys(PlatformAction.Paste));
AddAssert("pasted state equals dumped",
() => JsonConvert.SerializeObject(skinEditor.SelectedComponents.Cast<Drawable>().Select(s => s.CreateSerialisedInfo()).ToArray()),
() => Is.EqualTo(state));
}
private SkinnableContainer globalHUDTarget => Player.ChildrenOfType<SkinnableContainer>()
.Single(c => c.Lookup.Lookup == GlobalSkinnableContainers.MainHUDComponents && c.Lookup.Ruleset == null);

View File

@@ -159,7 +159,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("check request received", () =>
{
multiplayerClient.Verify(m => m.SendMatchRequest(It.Is<StartMatchCountdownRequest>(req =>
req.Duration == TimeSpan.FromSeconds(30)
req.Duration == TimeSpan.FromSeconds(10)
)), Times.Once);
});
}
@@ -181,7 +181,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
AddStep("check request received", () =>
{
multiplayerClient.Verify(m => m.SendMatchRequest(It.Is<StartMatchCountdownRequest>(req =>
req.Duration == TimeSpan.FromSeconds(30)
req.Duration == TimeSpan.FromSeconds(10)
)), Times.Once);
});

View File

@@ -305,8 +305,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
new APIMod(new OsuModDoubleTime { SpeedChange = { Value = 2.0 } }),
new APIMod(new OsuModStrictTracking()),
new APIMod(new OsuModAutoplay()), // THIS IS PURELY TO ENABLE UNRANKED BADGE AND LET TEST PASS
// I AM NOT PROUD OF THIS
},
AllowedMods = new[]
{

View File

@@ -387,7 +387,7 @@ namespace osu.Game.Tests.Visual.Navigation
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
// Importantly, this occurs before base.load().
if (!loader.AllowLoad.Wait(TimeSpan.FromSeconds(30)))
if (!loader.AllowLoad.Wait(TimeSpan.FromSeconds(10)))
throw new TimeoutException();
return base.CreateChildDependencies(parent);

View File

@@ -24,7 +24,6 @@ using osu.Game.Configuration;
using osu.Game.Extensions;
using osu.Game.Graphics.Carousel;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.Notifications.WebSocket;
@@ -34,7 +33,6 @@ using osu.Game.Overlays.BeatmapListing;
using osu.Game.Overlays.Mods;
using osu.Game.Overlays.Notifications;
using osu.Game.Overlays.Toolbar;
using osu.Game.Overlays.Volume;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Mania.Configuration;
@@ -922,12 +920,8 @@ namespace osu.Game.Tests.Visual.Navigation
}
[Test]
[Explicit("Featured Artist dialog is never displayed as the filter is disabled by default.")]
public void TestFeaturedArtistDisclaimerDialog()
{
// NO-OP: FA dialog is not displayed ever
/*
BeatmapListingOverlay getBeatmapListingOverlay() => Game.ChildrenOfType<BeatmapListingOverlay>().FirstOrDefault();
AddStep("Wait for notifications to load", () => Game.SearchBeatmapSet(string.Empty));
@@ -945,7 +939,6 @@ namespace osu.Game.Tests.Visual.Navigation
AddAssert("dialog dismissed", () => Game.ChildrenOfType<DialogOverlay>().Single().CurrentDialog == null);
AddUntilStep("featured artist filter is off", () => !getBeatmapListingOverlay().ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
*/
}
[Test]
@@ -1338,34 +1331,6 @@ namespace osu.Game.Tests.Visual.Navigation
AddAssert("still nothing selected", () => Game.Beatmap.IsDefault);
}
[Test]
public void TestVolumeMeterDragDoesNotDismissFocusedOverlay()
{
AddStep("show beatmap overlay", () => Game.ShowBeatmapSet(1));
AddUntilStep("beatmap overlay still visible",
() => Game.ChildrenOfType<BeatmapSetOverlay>().SingleOrDefault()?.State.Value,
() => Is.EqualTo(Visibility.Visible));
AddStep("set game volume to max", () => Game.Dependencies.Get<FrameworkConfigManager>().SetValue(FrameworkSetting.VolumeUniversal, 1d));
AddStep("move to centre", () => InputManager.MoveMouseTo(Game));
AddStep("alt-scroll down", () =>
{
InputManager.PressKey(Key.AltLeft);
InputManager.ScrollVerticalBy(-1);
InputManager.ReleaseKey(Key.AltLeft);
});
AddUntilStep("wait for volume overlay to show", () => Game.ChildrenOfType<VolumeOverlay>().SingleOrDefault()?.State.Value, () => Is.EqualTo(Visibility.Visible));
AddStep("start dragging meter", () =>
{
InputManager.MoveMouseTo(Game.ChildrenOfType<VolumeMeter>().First().ChildrenOfType<OsuSpriteText>().First());
InputManager.PressButton(MouseButton.Left);
});
AddStep("drag away", () => InputManager.MoveMouseTo(Game.ChildrenOfType<VolumeMeter>().First().ChildrenOfType<OsuSpriteText>().First(), new Vector2(0, -100)));
AddStep("release mouse", () => InputManager.ReleaseButton(MouseButton.Left));
AddAssert("beatmap overlay still visible",
() => Game.ChildrenOfType<BeatmapSetOverlay>().SingleOrDefault()?.State.Value,
() => Is.EqualTo(Visibility.Visible));
}
private Func<Player> playToResults()
{
var player = playToCompletion();

View File

@@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual.Navigation
private const int requested_beatmap_id = 75;
private const int requested_beatmap_set_id = 1;
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"jvnkosu://b/{requested_beatmap_id}" });
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"osu://b/{requested_beatmap_id}" });
[SetUp]
public void Setup() => Schedule(() =>

View File

@@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Navigation
{
private const int requested_beatmap_set_id = 1;
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"jvnkosu://s/{requested_beatmap_set_id}" });
protected override TestOsuGame CreateTestGame() => new TestOsuGame(LocalStorage, API, new[] { $"osu://s/{requested_beatmap_set_id}" });
[SetUp]
public void Setup() => Schedule(() =>

View File

@@ -84,9 +84,9 @@ namespace osu.Game.Tests.Visual.Online
public void TestFeaturedArtistFilter()
{
AddAssert("is visible", () => overlay.State.Value == Visibility.Visible);
AddAssert("featured artist filter is off", () => !overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
AddStep("toggle featured artist filter", () => overlay.ChildrenOfType<FilterTabItem<SearchGeneral>>().First(i => i.Value == SearchGeneral.FeaturedArtists).TriggerClick());
AddAssert("featured artist filter is on", () => overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
AddStep("toggle featured artist filter", () => overlay.ChildrenOfType<FilterTabItem<SearchGeneral>>().First(i => i.Value == SearchGeneral.FeaturedArtists).TriggerClick());
AddAssert("featured artist filter is off", () => !overlay.ChildrenOfType<BeatmapSearchGeneralFilterRow>().First().Current.Contains(SearchGeneral.FeaturedArtists));
}
[Test]

View File

@@ -55,31 +55,31 @@ namespace osu.Game.Tests.Visual.Online
});
[TestCase("test!")]
[TestCase("osu.jvnko.boats!")]
[TestCase("https://osu.jvnko.boats!", LinkAction.External)]
[TestCase("http://osu.jvnko.boats!", LinkAction.External)]
[TestCase("forgothttps://osu.jvnko.boats!", LinkAction.External)]
[TestCase("forgothttp://osu.jvnko.boats!", LinkAction.External)]
[TestCase("dev.ppy.sh!")]
[TestCase("https://dev.ppy.sh!", LinkAction.External)]
[TestCase("http://dev.ppy.sh!", LinkAction.External)]
[TestCase("forgothttps://dev.ppy.sh!", LinkAction.External)]
[TestCase("forgothttp://dev.ppy.sh!", LinkAction.External)]
[TestCase("00:12:345 - Test?", LinkAction.OpenEditorTimestamp)]
[TestCase("00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)]
[TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 - Test?", LinkAction.OpenEditorTimestamp)]
[TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)]
[TestCase($"{OsuGameBase.OSU_PROTOCOL}00:12:345 - not an editor timestamp", LinkAction.External)]
[TestCase("Wiki link for tasty [[Performance Points]]", LinkAction.OpenWiki)]
[TestCase("(osu forums)[https://osu.jvnko.boats/forum] (old link format)", LinkAction.External)]
[TestCase("[https://osu.jvnko.boats/home New site] (new link format)", LinkAction.External)]
[TestCase("[osu forums](https://osu.jvnko.boats/forum) (new link format 2)", LinkAction.External)]
[TestCase("[https://osu.jvnko.boats/home This is only a link to the new osu webpage but this is supposed to test word wrap.]", LinkAction.External)]
[TestCase("Let's (try)[https://osu.jvnko.boats/home] [https://osu.jvnko.boats/b/252238 multiple links] https://osu.jvnko.boats/home", LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External)]
[TestCase("[https://osu.jvnko.boats/home New link format with escaped [and \\[ paired] braces]", LinkAction.External)]
[TestCase("[Markdown link format with escaped [and \\[ paired] braces](https://osu.jvnko.boats/home)", LinkAction.External)]
[TestCase("(Old link format with escaped (and \\( paired) parentheses)[https://osu.jvnko.boats/home] and [[also a rogue wiki link]]", LinkAction.External, LinkAction.OpenWiki)]
[TestCase("(osu forums)[https://dev.ppy.sh/forum] (old link format)", LinkAction.External)]
[TestCase("[https://dev.ppy.sh/home New site] (new link format)", LinkAction.External)]
[TestCase("[osu forums](https://dev.ppy.sh/forum) (new link format 2)", LinkAction.External)]
[TestCase("[https://dev.ppy.sh/home This is only a link to the new osu webpage but this is supposed to test word wrap.]", LinkAction.External)]
[TestCase("Let's (try)[https://dev.ppy.sh/home] [https://dev.ppy.sh/b/252238 multiple links] https://dev.ppy.sh/home", LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External)]
[TestCase("[https://dev.ppy.sh/home New link format with escaped [and \\[ paired] braces]", LinkAction.External)]
[TestCase("[Markdown link format with escaped [and \\[ paired] braces](https://dev.ppy.sh/home)", LinkAction.External)]
[TestCase("(Old link format with escaped (and \\( paired) parentheses)[https://dev.ppy.sh/home] and [[also a rogue wiki link]]", LinkAction.External, LinkAction.OpenWiki)]
[TestCase("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present).")] // note that there's 0 links here (they get removed if a channel is not found)
[TestCase("Join my multiplayer game jvnkosu://room/12346.", LinkAction.JoinRoom)]
[TestCase("Join my multiplayer gamejvnkosu://room/12346.", LinkAction.JoinRoom)]
[TestCase("Join my [multiplayer game](jvnkosu://room/12346).", LinkAction.JoinRoom)]
[TestCase("Join my multiplayer game http://osu.jvnko.boats/multiplayer/rooms/12346", LinkAction.JoinRoom)]
[TestCase("Join my [multiplayer game](http://osu.jvnko.boats/multiplayer/rooms/12346).", LinkAction.JoinRoom)]
[TestCase("Join my multiplayer game osu://room/12346.", LinkAction.JoinRoom)]
[TestCase("Join my multiplayer gameosu://room/12346.", LinkAction.JoinRoom)]
[TestCase("Join my [multiplayer game](osu://room/12346).", LinkAction.JoinRoom)]
[TestCase("Join my multiplayer game http://dev.ppy.sh/multiplayer/rooms/12346", LinkAction.JoinRoom)]
[TestCase("Join my [multiplayer game](http://dev.ppy.sh/multiplayer/rooms/12346).", LinkAction.JoinRoom)]
[TestCase($"Join my [#english]({OsuGameBase.OSU_PROTOCOL}chan/#english).", LinkAction.OpenChannel)]
[TestCase($"Join my {OsuGameBase.OSU_PROTOCOL}chan/#english.", LinkAction.OpenChannel)]
[TestCase($"Join my{OsuGameBase.OSU_PROTOCOL}chan/#english.", LinkAction.OpenChannel)]
@@ -91,11 +91,11 @@ namespace osu.Game.Tests.Visual.Online
addMessageWithChecks(text, expectedActions: actions);
}
[TestCase("is now listening to [https://osu.jvnko.boats/s/93523 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmapSet)]
[TestCase("is now playing [https://osu.jvnko.boats/b/252238 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmap)]
[TestCase("is now listening to [https://dev.ppy.sh/s/93523 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmapSet)]
[TestCase("is now playing [https://dev.ppy.sh/b/252238 IMAGE -MATERIAL- <Version 0>]", true, false, LinkAction.OpenBeatmap)]
[TestCase("I am important!", false, true)]
[TestCase("feels important", true, true)]
[TestCase("likes to post this [https://osu.jvnko.boats/home link].", true, true, LinkAction.External)]
[TestCase("likes to post this [https://dev.ppy.sh/home link].", true, true, LinkAction.External)]
public void TestActionAndImportantLinks(string text, bool isAction, bool isImportant, params LinkAction[] expectedActions)
{
addMessageWithChecks(text, isAction, isImportant, expectedActions);
@@ -135,9 +135,9 @@ namespace osu.Game.Tests.Visual.Online
int messageIndex = 0;
addEchoWithWait("sent!", "received!");
addEchoWithWait("https://osu.jvnko.boats/home", null, 500);
addEchoWithWait("[https://osu.jvnko.boats/forum let's try multiple words too!]");
addEchoWithWait("(long loading times! clickable while loading?)[https://osu.jvnko.boats/home]", null, 5000);
addEchoWithWait("https://dev.ppy.sh/home", null, 500);
addEchoWithWait("[https://dev.ppy.sh/forum let's try multiple words too!]");
addEchoWithWait("(long loading times! clickable while loading?)[https://dev.ppy.sh/home]", null, 5000);
void addEchoWithWait(string text, string? completeText = null, double delay = 250)
{

View File

@@ -93,7 +93,7 @@ namespace osu.Game.Tests.Visual.Ranking
AddStep("show example score", () =>
{
var score = TestResources.CreateTestScoreInfo(createTestBeatmap(new RealmUser()));
score.Mods = score.Mods.Append(new OsuModAutoplay()).ToArray();
score.Mods = score.Mods.Append(new OsuModDifficultyAdjust()).ToArray();
showPanel(score);
});

View File

@@ -115,7 +115,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private void testInfoLabels(int expectedCount)
{
AddAssert("check info labels exists", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Any());
AddAssert("check info labels count", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Count() >= expectedCount);
AddAssert("check info labels count", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Count() == expectedCount);
}
[SetUpSteps]

View File

@@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
assertGroup(results, 3, "Pending", pendingBeatmap.Beatmaps, ref total);
assertGroup(results, 4, "Graveyard", graveyardBeatmap.Beatmaps, ref total);
assertGroup(results, 5, "Local", localBeatmap.Beatmaps, ref total);
assertGroup(results, 6, "Offline", noneBeatmap.Beatmaps, ref total);
assertGroup(results, 6, "Unknown", noneBeatmap.Beatmaps, ref total);
assertGroup(results, 7, "Loved", lovedBeatmap.Beatmaps, ref total);
assertTotal(results, total);
}

View File

@@ -99,7 +99,7 @@ namespace osu.Game.Tests.Visual.SongSelectV2
[Test]
public void TestUnrankedBadge()
{
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModAutoplay() }));
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModDeflate() }));
AddUntilStep("Unranked badge shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 1);
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
AddUntilStep("Unranked badge not shown", () => footerButtonMods.ChildrenOfType<FooterButtonMods.UnrankedBadge>().Single().Alpha == 0);

View File

@@ -71,7 +71,7 @@ namespace osu.Game.Tests.Visual.UserInterface
[Test]
public void TestUnrankedBadge()
{
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModAutoplay() }));
AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModDeflate() }));
AddAssert("Unranked badge shown", () => footerButtonMods.UnrankedBadge.Alpha == 1);
AddStep(@"Clear selected mod", () => changeMods(Array.Empty<Mod>()));
AddAssert("Unranked badge not shown", () => footerButtonMods.UnrankedBadge.Alpha == 0);

View File

@@ -129,9 +129,8 @@ namespace osu.Game.Tests.Visual.UserInterface
setSliderValue("Circle Size", 99);
// debug build maximum value
checkSliderAtValue("Circle Size", 13);
checkBindableAtValue("Circle Size", 13);
checkSliderAtValue("Circle Size", 11);
checkBindableAtValue("Circle Size", 11);
setSliderValue("Approach Rate", -5);

View File

@@ -207,23 +207,23 @@ namespace osu.Game.Tests.Visual.UserInterface
AddUntilStep("any column dimmed", () => this.ChildrenOfType<ModColumn>().Any(column => !column.Active.Value));
ModSelectColumn secondColumn = null!;
ModSelectColumn lastColumn = null!;
AddAssert("second column dimmed", () => !this.ChildrenOfType<ModColumn>().ElementAt(2).Active.Value);
AddStep("request scroll to second column", () =>
AddAssert("last column dimmed", () => !this.ChildrenOfType<ModColumn>().Last().Active.Value);
AddStep("request scroll to last column", () =>
{
var secondDimContainer = this.ChildrenOfType<ModSelectOverlay.ColumnDimContainer>().ElementAt(2);
secondColumn = secondDimContainer.Column;
secondDimContainer.RequestScroll?.Invoke(secondDimContainer);
var lastDimContainer = this.ChildrenOfType<ModSelectOverlay.ColumnDimContainer>().Last();
lastColumn = lastDimContainer.Column;
lastDimContainer.RequestScroll?.Invoke(lastDimContainer);
});
AddUntilStep("column undimmed", () => secondColumn.Active.Value);
AddUntilStep("column undimmed", () => lastColumn.Active.Value);
AddStep("click panel", () =>
{
InputManager.MoveMouseTo(secondColumn.ChildrenOfType<ModPanel>().First());
InputManager.MoveMouseTo(lastColumn.ChildrenOfType<ModPanel>().First());
InputManager.Click(MouseButton.Left);
});
AddUntilStep("panel selected", () => secondColumn.ChildrenOfType<ModPanel>().First().Active.Value);
AddUntilStep("panel selected", () => lastColumn.ChildrenOfType<ModPanel>().First().Active.Value);
}
[Test]
@@ -810,7 +810,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
AddStep("unset filter", () => modSelectOverlay.IsValidMod = _ => true);
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
AddStep("filter out everything", () => modSelectOverlay.IsValidMod = _ => false);
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
@@ -839,7 +839,7 @@ namespace osu.Game.Tests.Visual.UserInterface
waitForColumnLoad();
changeRuleset(0);
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
AddStep("set search", () => modSelectOverlay.SearchTerm = "HD");
AddAssert("two columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 2);
@@ -848,7 +848,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("no columns visible", () => this.ChildrenOfType<ModColumn>().All(col => !col.IsPresent));
AddStep("clear search bar", () => modSelectOverlay.SearchTerm = "");
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
}
[Test]
@@ -863,7 +863,7 @@ namespace osu.Game.Tests.Visual.UserInterface
waitForColumnLoad();
changeRuleset(0);
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
AddStep("set search", () => modSelectOverlay.SearchTerm = "fail");
AddAssert("one column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);
@@ -871,7 +871,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("hide", () => modSelectOverlay.Hide());
AddStep("show", () => modSelectOverlay.Show());
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 4);
AddAssert("all columns visible", () => this.ChildrenOfType<ModColumn>().All(col => col.IsPresent));
}
[Test]
@@ -880,13 +880,13 @@ namespace osu.Game.Tests.Visual.UserInterface
createScreen();
changeRuleset(0);
AddAssert("5 or more columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 5);
AddAssert("5 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 5);
AddStep("change to ruleset without all mod types", () => Ruleset.Value = TestCustomisableModRuleset.CreateTestRulesetInfo());
AddUntilStep("1 column visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 1);
changeRuleset(0);
AddAssert("5 or more columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) >= 5);
AddAssert("5 columns visible", () => this.ChildrenOfType<ModColumn>().Count(col => col.IsPresent) == 5);
}
[Test]

View File

@@ -107,7 +107,7 @@ namespace osu.Game.Audio
Logger.Log($"A {nameof(PreviewTrack)} was created without a containing {nameof(IPreviewTrackOwner)}. An owner should be added for correct behaviour.");
}
protected override Track GetTrack() => trackManager.Get($"https://osu.jvnko.boats/uploads/preview/{beatmapSetInfo.OnlineID}.mp3");
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo.OnlineID}.mp3");
}
}
}

View File

@@ -214,7 +214,7 @@ namespace osu.Game.Database
#if !DEBUG
// in the lazer. straight up "migrating it". and by "it", haha, well. let's just say. My realm .
string altFilename = filename;
applyFilenameSchemaSuffix(ref altFilename);
applyFilenameSchemaSuffix(ref altFilename); // it also migrates older versions automagically! (sorry, I only used that word for irony...)
if (storage.Exists(altFilename) && !storage.Exists(Filename))
{
using (var previous = storage.GetStream(altFilename))
@@ -222,7 +222,6 @@ namespace osu.Game.Database
{
Logger.Log($@"Migrating production build DB: {altFilename} -> {Filename}");
previous.CopyTo(current);
Logger.Log("Sucessfully migrated local database!", level: LogLevel.Important);
}
}
#endif

View File

@@ -124,10 +124,10 @@ namespace osu.Game.Graphics.Backgrounds
api.PerformAsync(request);
}
public Background LoadNextBackground()
public SeasonalBackground LoadNextBackground()
{
if (!shouldShowCustomBackgrounds || !shouldFetchCustomBackgrounds || currentBackgrounds.Value?.Backgrounds?.Any() != true)
return new Background($@"Menu/menu-background-{RNG.Next(1, 9)}");
return (SeasonalBackground)(new Background($@"Menu/menu-background-{RNG.Next(1, 9)}"));
var backgrounds = currentBackgrounds.Value.Backgrounds;
currentBackgroundIndex = (currentBackgroundIndex + 1) % backgrounds.Count;

View File

@@ -1,13 +1,11 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Input.Handlers.Tablet;
using osu.Framework.Layout;
using osu.Framework.Platform;
using osu.Framework.Screens;
@@ -52,8 +50,6 @@ namespace osu.Game.Graphics.Containers
private RectangleF? customRect;
private bool customRectIsRelativePosition;
private ITabletHandler? tabletHandler;
/// <summary>
/// Set a custom position and scale which overrides any user specification.
/// </summary>
@@ -127,7 +123,7 @@ namespace osu.Game.Graphics.Containers
}
[BackgroundDependencyLoader]
private void load(GameHost host, OsuConfigManager config, ISafeArea safeArea)
private void load(OsuConfigManager config, ISafeArea safeArea)
{
scalingMode = config.GetBindable<ScalingMode>(OsuSetting.Scaling);
scalingMode.ValueChanged += _ => Scheduler.AddOnce(updateSize);
@@ -152,8 +148,6 @@ namespace osu.Game.Graphics.Containers
scalingMenuBackgroundDim = config.GetBindable<float>(OsuSetting.ScalingBackgroundDim);
scalingMenuBackgroundDim.ValueChanged += _ => Scheduler.AddOnce(updateSize);
tabletHandler = host.AvailableInputHandlers.OfType<ITabletHandler>().SingleOrDefault();
}
protected override void LoadComplete()
@@ -228,13 +222,6 @@ namespace osu.Game.Graphics.Containers
// An example of how this can occur is when the skin editor is visible and the game screen scaling is set to "Everything".
sizableContainer.TransformTo(nameof(CornerRadius), requiresMasking ? corner_radius : 0, TRANSITION_DURATION, requiresMasking ? Easing.OutQuart : Easing.None)
.OnComplete(_ => { sizableContainer.Masking = requiresMasking; });
// when "everything" scaling mode is active, tablets are expected to constrain output area to the scaled size of the game
if (tabletHandler != null)
{
tabletHandler.OutputAreaSize.Value = scalingMode.Value == ScalingMode.Everything ? new Vector2(sizeX.Value, sizeY.Value) : Vector2.One;
tabletHandler.OutputAreaOffset.Value = scalingMode.Value == ScalingMode.Everything ? new Vector2(posX.Value, posY.Value) : new Vector2(0.5f);
}
}
private partial class ScalingBackgroundScreen : BackgroundScreenDefault

View File

@@ -60,7 +60,7 @@ namespace osu.Game.Graphics.UserInterface
}
[Resolved]
protected OverlayColourProvider? ColourProvider { get; private set; } = null!;
protected OverlayColourProvider ColourProvider { get; private set; } = null!;
private readonly Box background;
private readonly OsuSpriteText text;
@@ -190,9 +190,9 @@ namespace osu.Game.Graphics.UserInterface
private void updateState()
{
var colourDark = darkerColour ?? ColourProvider?.Background3 ?? Colour4.DarkGray;
var colourLight = lighterColour ?? ColourProvider?.Background1 ?? Colour4.LightGray;
var colourContent = textColour ?? ColourProvider?.Content1 ?? Colour4.White;
var colourDark = darkerColour ?? ColourProvider.Background3;
var colourLight = lighterColour ?? ColourProvider.Background1;
var colourContent = textColour ?? ColourProvider.Content1;
if (!Enabled.Value)
{

View File

@@ -5,7 +5,6 @@ using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
namespace osu.Game.Graphics.UserInterface
{
@@ -64,9 +63,9 @@ namespace osu.Game.Graphics.UserInterface
protected virtual void UpdateActiveState()
{
DarkerColour = Active.Value ? ColourProvider?.Highlight1 ?? Colour4.Gray : ColourProvider?.Background3 ?? Colour4.DimGray;
LighterColour = Active.Value ? ColourProvider?.Colour0 ?? Colour4.AliceBlue : ColourProvider?.Background1 ?? Colour4.LightGray;
TextColour = Active.Value ? ColourProvider?.Background6 ?? Colour4.Black : ColourProvider?.Content1 ?? Colour4.DarkGray;
DarkerColour = Active.Value ? ColourProvider.Highlight1 : ColourProvider.Background3;
LighterColour = Active.Value ? ColourProvider.Colour0 : ColourProvider.Background1;
TextColour = Active.Value ? ColourProvider.Background6 : ColourProvider.Content1;
}
private void playSample()

View File

@@ -30,7 +30,7 @@ namespace osu.Game.Online.Chat
// http[s]://<domain>.<tld>[:port][/path][?query][#fragment]
private static readonly Regex advanced_link_regex = new Regex(
// protocol
@"(?<link>(https?|jvnkosu(mp)?):\/\/" +
@"(?<link>(https?|osu(mp)?):\/\/" +
// domain + tld
@"(?<domain>(?:[a-z0-9]\.|[a-z0-9][a-z0-9-]*[a-z0-9]\.)*[a-z0-9-]*[a-z0-9]" +
// port (optional)
@@ -60,7 +60,7 @@ namespace osu.Game.Online.Chat
.Split('/').Last(); // only keep domain name, ignoring protocol.
}
private static string websiteRootUrl = "osu.jvnko.boats";
private static string websiteRootUrl = "osu.ppy.sh";
private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null, char[]? escapeChars = null)
{
@@ -211,7 +211,7 @@ namespace osu.Game.Online.Chat
break;
case @"jvnkosu":
case @"osu":
// every internal link also needs some kind of argument
if (args.Length < 3)
break;

View File

@@ -16,6 +16,7 @@ namespace osu.Game.Online.Multiplayer
/// <summary>
/// Request to leave the currently joined room.
/// </summary>
/// <exception cref="NotJoinedRoomException">If the user is not in a room.</exception>
Task LeaveRoom();
/// <summary>

View File

@@ -319,6 +319,9 @@ namespace osu.Game.Online.Multiplayer
public Task LeaveRoom()
{
if (Room == null)
return Task.CompletedTask;
// The join may have not completed yet, so certain tasks that either update the room or reference the room should be cancelled.
// This includes the setting of Room itself along with the initial update of the room settings on join.
joinCancellationSource?.Cancel();

View File

@@ -81,7 +81,7 @@ namespace osu.Game
public const string GAME_NAME = "jvnkosu!";
#endif
public const string OSU_PROTOCOL = "jvnkosu://";
public const string OSU_PROTOCOL = "jnvkosu://";
/// <summary>
/// The filename of the main client database.

View File

@@ -33,27 +33,7 @@ namespace osu.Game.Overlays.Chat
{
var request = new ChatReportRequest(message.Id, reason, comments);
request.Success += () =>
{
string thanksMessage;
switch (channelManager.CurrentChannel.Value.Type)
{
case ChannelType.PM:
thanksMessage = """
Chat moderators have been alerted. You have reported a private message so they will not be able to read history to maintain your privacy. Please make sure to include as much details as you can.
You can submit a second report with more details if required, or contact abuse@ppy.sh if a user is being extremely offensive.
You can also block a user via the block button on their user profile, or by right-clicking on their name in the chat and selecting "Block".
""";
break;
default:
thanksMessage = @"Chat moderators have been alerted. Thanks for your help.";
break;
}
channelManager.CurrentChannel.Value.AddNewMessages(new InfoMessage(thanksMessage));
};
request.Success += () => channelManager.CurrentChannel.Value.AddNewMessages(new InfoMessage(UsersStrings.ReportThanks.ToString()));
api.Queue(request);
}

View File

@@ -61,15 +61,10 @@ namespace osu.Game.Overlays
audio.Samples.AddAdjustment(AdjustableProperty.Volume, audioVolume);
}
protected void RemoveAudioAdjustments()
protected override void Dispose(bool isDisposing)
{
audio?.Tracks.RemoveAdjustment(AdjustableProperty.Volume, audioVolume);
audio?.Samples.RemoveAdjustment(AdjustableProperty.Volume, audioVolume);
}
protected override void Dispose(bool isDisposing)
{
RemoveAudioAdjustments();
base.Dispose(isDisposing);
}
}

View File

@@ -54,9 +54,9 @@ namespace osu.Game.Overlays.Mods
protected override void UpdateActiveState()
{
DarkerColour = Active.Value ? colours.Orange1 : ColourProvider?.Background3 ?? Colour4.DarkGray;
LighterColour = Active.Value ? colours.Orange0 : ColourProvider?.Background1 ?? Colour4.LightGray;
TextColour = Active.Value ? ColourProvider?.Background6 ?? Colour4.Black : ColourProvider?.Content1 ?? Colour4.Gray;
DarkerColour = Active.Value ? colours.Orange1 : ColourProvider.Background3;
LighterColour = Active.Value ? colours.Orange0 : ColourProvider.Background1;
TextColour = Active.Value ? ColourProvider.Background6 : ColourProvider.Content1;
if (Active.Value)
this.ShowPopover();

View File

@@ -438,9 +438,7 @@ namespace osu.Game.Overlays.Mods
foreach (var modState in AllAvailableMods)
{
// BUG: when trying to switch ruleset in a multiplayer room this was previously throwing an InvalidOperationException.
// If it still throws, then I guess it's not good
var matchingSelectedMod = SelectedMods.Value.FirstOrDefault(selected => selected.GetType() == modState.Mod.GetType());
var matchingSelectedMod = SelectedMods.Value.SingleOrDefault(selected => selected.GetType() == modState.Mod.GetType());
if (matchingSelectedMod != null)
{

View File

@@ -228,7 +228,7 @@ namespace osu.Game.Overlays
private void onSeek(double progress)
{
if (!musicController.IsPlaying || lastSeekTime == null || Time.Current - lastSeekTime > TRACK_DRAG_SEEK_DEBOUNCE)
if (lastSeekTime == null || Time.Current - lastSeekTime > TRACK_DRAG_SEEK_DEBOUNCE)
{
musicController.SeekTo(progress);
lastSeekTime = Time.Current;

View File

@@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
private readonly string slug;
private readonly Sprite sprite;
private string url => $@"https://osu.jvnko.boats/images/medals-client/{slug}@2x.png";
private string url => $@"https://s.ppy.sh/images/medals-client/{slug}@2x.png";
public MedalIcon(string slug)
{

View File

@@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Rankings
case RankingsScope.Performance:
case RankingsScope.Score:
case RankingsScope.Country:
case RankingsScope.Playlists:
case RankingsScope.Spotlights:
return true;
default:

View File

@@ -17,8 +17,8 @@ namespace osu.Game.Overlays.Rankings
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeCountry))]
Country,
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypePlaylists))]
Playlists,
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeCharts))]
Spotlights,
[LocalisableDescription(typeof(RankingsStrings), nameof(RankingsStrings.TypeKudosu))]
Kudosu,

View File

@@ -52,7 +52,7 @@ namespace osu.Game.Overlays
ruleset.BindValueChanged(_ =>
{
if (Header.Current.Value == RankingsScope.Playlists)
if (Header.Current.Value == RankingsScope.Spotlights)
return;
Scheduler.AddOnce(triggerTabChanged);
@@ -99,7 +99,7 @@ namespace osu.Game.Overlays
{
lastRequest?.Cancel();
if (Header.Current.Value == RankingsScope.Playlists)
if (Header.Current.Value == RankingsScope.Spotlights)
{
LoadDisplay(new SpotlightsLayout
{

View File

@@ -13,7 +13,6 @@ using osu.Framework.Input.Handlers.Tablet;
using osu.Framework.Localisation;
using osu.Framework.Platform;
using osu.Framework.Threading;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
@@ -35,8 +34,6 @@ namespace osu.Game.Overlays.Settings.Sections.Input
private readonly Bindable<Vector2> areaOffset = new Bindable<Vector2>();
private readonly Bindable<Vector2> areaSize = new Bindable<Vector2>();
private readonly Bindable<Vector2> outputAreaSize = new Bindable<Vector2>();
private readonly Bindable<Vector2> outputAreaOffset = new Bindable<Vector2>();
private readonly IBindable<TabletInfo> tablet = new Bindable<TabletInfo>();
private readonly BindableNumber<float> offsetX = new BindableNumber<float> { MinValue = 0, Precision = 1 };
@@ -49,10 +46,6 @@ namespace osu.Game.Overlays.Settings.Sections.Input
private readonly BindableNumber<float> pressureThreshold = new BindableNumber<float> { MinValue = 0.0f, MaxValue = 1.0f, Precision = 0.005f };
private Bindable<ScalingMode> scalingMode = null!;
private Bindable<float> scalingSizeX = null!;
private Bindable<float> scalingSizeY = null!;
[Resolved]
private GameHost host { get; set; }
@@ -84,12 +77,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, LocalisationManager localisation, OsuConfigManager osuConfig)
private void load(OsuColour colours, LocalisationManager localisation)
{
scalingMode = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling);
scalingSizeX = osuConfig.GetBindable<float>(OsuSetting.ScalingSizeX);
scalingSizeY = osuConfig.GetBindable<float>(OsuSetting.ScalingSizeY);
Children = new Drawable[]
{
new SettingsCheckbox
@@ -163,16 +152,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
Text = TabletSettingsStrings.ConformToCurrentGameAspectRatio,
Action = () =>
{
float gameplayWidth = host.Window.ClientSize.Width;
float gameplayHeight = host.Window.ClientSize.Height;
if (scalingMode.Value == ScalingMode.Everything)
{
gameplayWidth *= scalingSizeX.Value;
gameplayHeight *= scalingSizeY.Value;
}
forceAspectRatio(gameplayWidth / gameplayHeight);
forceAspectRatio((float)host.Window.ClientSize.Width / host.Window.ClientSize.Height);
},
CanBeShown = { BindTarget = enabled }
},
@@ -269,9 +249,6 @@ namespace osu.Game.Overlays.Settings.Sections.Input
sizeY.Value = val.NewValue.Y;
}), true);
outputAreaSize.BindTo(tabletHandler.OutputAreaSize);
outputAreaOffset.BindTo(tabletHandler.OutputAreaOffset);
sizeX.BindValueChanged(val =>
{
areaSize.Value = new Vector2(val.NewValue, areaSize.Value.Y);

View File

@@ -1,7 +1,7 @@
// 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 enable
#nullable disable
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@@ -19,22 +19,19 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
{
protected override LocalisableString Header => UserInterfaceStrings.MainMenuHeader;
// TODO: refactor seasonal bg code to the way it was before options were introduced
private SeasonalBackgroundLoader? backgroundLoader = null!;
[Resolved]
private SeasonalBackgroundLoader backgroundLoader { get; set; }
private IBindable<APIUser> user = null!;
private IBindable<APIUser> user;
private SettingsEnumDropdown<BackgroundSource> backgroundSourceDropdown = null!;
private SettingsEnumDropdown<BackgroundSource> backgroundSourceDropdown;
private Bindable<bool> useSeasonalBackgrounds = null!;
private Bindable<bool> useSeasonalBackgrounds;
[BackgroundDependencyLoader]
private void load(OsuConfigManager config, IAPIProvider api, SeasonalBackgroundLoader? backgroundLoader)
private void load(OsuConfigManager config, IAPIProvider api)
{
user = api.LocalUser.GetBoundCopy();
this.backgroundLoader = backgroundLoader;
useSeasonalBackgrounds = config.GetBindable<bool>(OsuSetting.UseSeasonalBackgroundsV2);
var backgroundToggle = new SettingsCheckbox
@@ -53,17 +50,17 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
var refreshButton = new SettingsButton
{
Text = UserInterfaceStrings.SeasonalBackgroundsRefresh,
Action = () => backgroundLoader?.RefreshCategories()
Action = () => backgroundLoader.RefreshCategories()
};
// TODO: the category dropdown disappear if no backgrounds (e.g. when first enabling the setting)
refreshButton.CanBeShown.BindTo(useSeasonalBackgrounds);
categoryDropdown.CanBeShown.BindTo(useSeasonalBackgrounds);
useSeasonalBackgrounds.BindValueChanged(
_ => backgroundLoader?.RefreshCategories(true)
_ => backgroundLoader.RefreshCategories(true)
);
backgroundLoader?.AvailableCategories.BindValueChanged(categories => categoryDropdown.Items = categories.NewValue, true);
backgroundLoader.AvailableCategories.BindValueChanged(categories => categoryDropdown.Items = categories.NewValue, true);
Children = new Drawable[]
{

View File

@@ -529,9 +529,7 @@ namespace osu.Game.Overlays.SkinEditor
}
SelectedComponents.Add(component);
if (!component.UsesFixedAnchor)
SkinSelectionHandler.ApplyClosestAnchorOrigin(drawableComponent);
SkinSelectionHandler.ApplyClosestAnchorOrigin(drawableComponent);
return true;
}

View File

@@ -255,16 +255,19 @@ namespace osu.Game.Overlays.Volume
bool intVolumeChanged = intValue != displayVolumeInt;
displayVolumeInt = intValue;
text.WireframeTemplate = new string('#', intValue.ToString(CultureInfo.CurrentCulture).Length);
text.Text = intValue.ToString(CultureInfo.CurrentCulture);
text.WireframeTemplate = new string('#', intValue.ToString().Length);
if (displayVolume >= 0.995f)
maxGlow.EffectColour = meterColour.Opacity(5f);
else if (displayVolume < 0.01f)
maxGlow.EffectColour = meterColour.Opacity(0f);
{
text.Text = "100";
maxGlow.EffectColour = meterColour.Opacity(2f);
}
else
maxGlow.EffectColour = meterColour.Opacity((float)displayVolume * 3f + 1f);
{
maxGlow.EffectColour = Color4.Transparent;
text.Text = intValue.ToString(CultureInfo.CurrentCulture);
}
volumeCircle.Progress = displayVolume * 0.75f;
volumeCircleGlow.Progress = displayVolume * 0.75f;
@@ -318,8 +321,6 @@ namespace osu.Game.Overlays.Volume
private float dragDelta;
protected override bool OnMouseDown(MouseDownEvent e) => true; // handle to prevent drawables behind from potentially receiving the mouse down
protected override bool OnDragStart(DragStartEvent e)
{
dragDelta = 0;

View File

@@ -0,0 +1,47 @@
// 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;
using System.Collections.Generic;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Localisation;
using osu.Game.Configuration;
using osu.Game.Overlays.Settings;
namespace osu.Game.Rulesets.Mods
{
public abstract class ModRateAdjustConcrete : ModRateAdjust
{
public override string Name => "Rate Adjust";
public override LocalisableString Description => "[DEBUG BUILDS ONLY] Set any speed";
public override string Acronym => "_R";
private readonly RateAdjustModHelper rateAdjustHelper;
[SettingSource("Speed decrease", "The actual decrease to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
public override BindableNumber<double> SpeedChange { get; } = new BindableDouble(0.75)
{
MinValue = 0.1, // BASS breaks at lower rates
MaxValue = 10,
Precision = 0.01
};
[SettingSource("Adjust pitch", "Should pitch be adjusted with speed")]
public virtual BindableBool AdjustPitch { get; } = new BindableBool();
protected ModRateAdjustConcrete()
{
rateAdjustHelper = new RateAdjustModHelper(SpeedChange);
rateAdjustHelper.HandleAudioAdjustments(AdjustPitch);
}
public override double ScoreMultiplier => 1.0;
public override void ApplyToTrack(IAdjustableAudioComponent track)
{
rateAdjustHelper.ApplyToTrack(track);
}
public override bool Ranked => false;
public override ModType Type => ModType.Special;
}
}

View File

@@ -159,9 +159,8 @@ namespace osu.Game.Rulesets.UI
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Alpha = 0,
Font = OsuFont.TorusAlternate.With(size: 36, weight: FontWeight.SemiBold),
Margin = new MarginPadding { Bottom = 5 },
UseFullGlyphHeight = true,
Font = OsuFont.Numeric.With(size: 22f, weight: FontWeight.Black),
UseFullGlyphHeight = false,
Text = mod.Acronym
},
modIcon = new SpriteIcon

View File

@@ -91,12 +91,11 @@ namespace osu.Game.Rulesets.UI
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Shadow = false,
Font = OsuFont.TorusAlternate.With(size: 36, weight: FontWeight.Bold),
Font = OsuFont.Numeric.With(size: 24, weight: FontWeight.Black),
Text = mod.Acronym,
Margin = new MarginPadding
{
Top = 3,
Bottom = 6
Top = 4
}
},
},

View File

@@ -13,14 +13,12 @@ using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Screens.Edit;
using osu.Game.Storyboards.Drawables;
namespace osu.Game.Screens.Backgrounds
{
public partial class EditorBackgroundScreen : BackgroundScreen
{
private readonly EditorBeatmap editorBeatmap;
private readonly Container dimContainer;
private CancellationTokenSource? cancellationTokenSource;
@@ -38,9 +36,8 @@ namespace osu.Game.Screens.Backgrounds
[Resolved]
private IBindable<WorkingBeatmap> beatmap { get; set; } = null!;
public EditorBackgroundScreen(EditorBeatmap editorBeatmap)
public EditorBackgroundScreen()
{
this.editorBeatmap = editorBeatmap;
InternalChild = dimContainer = new Container
{
RelativeSizeAxes = Axes.Both,
@@ -61,11 +58,10 @@ namespace osu.Game.Screens.Backgrounds
private IEnumerable<Drawable> createContent() =>
[
new BeatmapBackground(beatmap.Value) { RelativeSizeAxes = Axes.Both, },
// one reason for this kooky container nesting being here is that the storyboard needs a custom clock
// this kooky container nesting is here because the storyboard needs a custom clock
// but also needs it on an isolated-enough level that doesn't break screen stack expiry logic (which happens if the clock was put on `this`),
// or doesn't make it literally impossible to fade the storyboard in/out in real time (which happens if the fade transforms were to be applied directly to the storyboard).
// another is that we need `EditorSkinProvidingContainer` so that storyboard sample lookups succeed.
new EditorSkinProvidingContainer(editorBeatmap)
new Container
{
RelativeSizeAxes = Axes.Both,
Child = new DrawableStoryboard(beatmap.Value.Storyboard)

View File

@@ -67,7 +67,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
double seekDestination = markerPos / DrawWidth * editorClock.TrackLength;
marker.X = (float)seekDestination;
if (editorClock.IsRunning && !instant && lastSeekTime != null && Time.Current - lastSeekTime < NowPlayingOverlay.TRACK_DRAG_SEEK_DEBOUNCE)
if (!instant && lastSeekTime != null && Time.Current - lastSeekTime < NowPlayingOverlay.TRACK_DRAG_SEEK_DEBOUNCE)
return;
editorClock.SeekSmoothlyTo(seekDestination);

View File

@@ -481,7 +481,7 @@ namespace osu.Game.Screens.Edit
[Resolved]
private MusicController musicController { get; set; }
protected override BackgroundScreen CreateBackground() => new EditorBackgroundScreen(editorBeatmap);
protected override BackgroundScreen CreateBackground() => new EditorBackgroundScreen();
protected override void LoadComplete()
{

View File

@@ -169,20 +169,6 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
{
Text = "Searching for opponents...";
Activated = () =>
{
performer?.PerformFromScreen(s =>
{
if (s is ScreenIntro || s is ScreenQueue)
return;
s.Push(new ScreenIntro());
}, [typeof(ScreenIntro), typeof(ScreenQueue)]);
// Closed when appropriate by SearchInForeground().
return false;
};
CompletionClickAction = () =>
{
client.MatchmakingAcceptInvitation().FireAndForget();

View File

@@ -354,9 +354,37 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
break;
case MatchmakingScreenState.PendingAccept:
client.MatchmakingAcceptInvitation().FireAndForget();
SetState(MatchmakingScreenState.AcceptedWaitingForRoom);
mainContent.Child = new FillFlowContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Spacing = new Vector2(20),
Children = new Drawable[]
{
new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = "Found a match!",
Font = OsuFont.GetFont(size: 32, weight: FontWeight.Regular, typeface: Typeface.TorusAlternate),
},
new SelectionButton(200)
{
DarkerColour = colours.YellowDark,
LighterColour = colours.YellowLight,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = () =>
{
client.MatchmakingAcceptInvitation().FireAndForget();
SetState(MatchmakingScreenState.AcceptedWaitingForRoom);
},
Text = "Join match!",
}
}
};
matchFoundSample?.Play();
musicController.DuckMomentarily(1250);
break;
@@ -375,7 +403,7 @@ namespace osu.Game.Screens.OnlinePlay.Matchmaking.Queue
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = "Waiting for opponents...",
Text = "Waiting for all players...",
Font = OsuFont.GetFont(size: 32, weight: FontWeight.Light, typeface: Typeface.TorusAlternate),
},
new LoadingSpinner

View File

@@ -90,15 +90,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
client.ChangeState(MultiplayerUserState.Idle).FireAndForget();
}
public override bool OnExiting(ScreenExitEvent e)
{
if (base.OnExiting(e))
return true;
client.LeaveRoom().FireAndForget();
return false;
}
protected override string ScreenTitle => "Multiplayer";
protected override LoungeSubScreen CreateLounge() => new MultiplayerLoungeSubScreen();

View File

@@ -42,11 +42,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
{
}
protected override OsuClickableContainer CreateButton(IBindable<bool> inSkipPeriod) => skipButton = new Button
protected override OsuClickableContainer CreateButton() => skipButton = new Button
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
InSkipPeriod = { BindTarget = inSkipPeriod },
};
protected override void LoadComplete()
@@ -120,9 +119,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
public readonly BindableInt SkippedCount = new BindableInt();
public readonly BindableInt RequiredCount = new BindableInt();
public readonly BindableBool InSkipPeriod = new BindableBool();
private readonly BindableBool clicked = new BindableBool();
[Resolved]
private OsuColour colours { get; set; } = null!;
@@ -205,17 +201,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
SkippedCount.BindValueChanged(_ => updateCount());
RequiredCount.BindValueChanged(_ => updateCount(), true);
InSkipPeriod.BindValueChanged(_ => updateEnabledState());
clicked.BindValueChanged(_ => updateEnabledState(), true);
Enabled.BindValueChanged(_ => updateColours(), true);
FinishTransforms(true);
}
private void updateEnabledState() => Enabled.Value = InSkipPeriod.Value && !clicked.Value;
private void updateChevronsSpacing()
{
if (SkippedCount.Value > 0 && RequiredCount.Value > 1)
@@ -310,7 +300,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
base.OnClick(e);
clicked.Value = true;
Enabled.Value = false;
return true;
}

View File

@@ -18,7 +18,7 @@ namespace osu.Game.Screens.Play
{
public partial class FailOverlay : GameplayMenuOverlay
{
public Func<Task<ScoreInfo>>? SaveReplay { get; init; }
public Func<Task<ScoreInfo>>? SaveReplay;
public override LocalisableString Header => GameplayMenuOverlayStrings.FailedHeader;

View File

@@ -18,12 +18,14 @@ 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;
using osuTK;
using osuTK.Graphics;
using osu.Game.Localisation;
using osu.Game.Resources.Localisation.Web;
using osu.Game.Utils;
using System.Runtime.InteropServices;
namespace osu.Game.Screens.Play
{
@@ -71,6 +73,8 @@ namespace osu.Game.Screens.Play
[Resolved]
private GlobalActionContainer globalAction { get; set; } = null!;
private ShearedButton saveReplay { get; set; } = null!;
protected GameplayMenuOverlay()
{
RelativeSizeAxes = Axes.Both;
@@ -120,20 +124,15 @@ namespace osu.Game.Screens.Play
Radius = 50
},
},
// XXX: I have mixed feelings about this, but it works at least
(OnQuitReplay != null)
? new ShearedButton
{
Text = "Quit and save replay",
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Height = 32,
Colour = colours.PurpleLight,
Action = () => OnQuitReplay.Invoke()
}
: [],
saveReplay = new ShearedButton
{
Text = "Quit and save replay",
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Height = 32,
Colour = colours.PurpleLight,
// Visibility = false
},
playInfoText = new OsuTextFlowContainer(cp => cp.Font = OsuFont.GetFont(size: 18))
{
Origin = Anchor.TopCentre,
@@ -154,6 +153,12 @@ namespace osu.Game.Screens.Play
if (OnQuit != null)
AddButton(GameplayMenuOverlayStrings.Quit, new Color4(170, 27, 39, 255), () => OnQuit.Invoke());
if (OnQuitReplay != null)
{
// saveReplay.Visibility = true;
saveReplay.Action = () => OnQuitReplay.Invoke();
}
State.ValueChanged += _ => InternalButtons.Deselect();
updateInfoText();

View File

@@ -357,7 +357,7 @@ namespace osu.Game.Screens.Play.HUD
else if (Tracked)
{
widthExtension = true;
setPanelColour(BackgroundColour ?? colours.Orange2);
setTrackedPanelColour(BackgroundColour);
}
else if (isFriend)
{
@@ -380,6 +380,13 @@ namespace osu.Game.Screens.Play.HUD
scorePanel.BorderColour = ColourInfo.GradientVertical(baseColour.Opacity(0.2f), baseColour);
}
private void setTrackedPanelColour(Color4? backgroundColour)
{
leftLayerGradient.Colour = ColourInfo.GradientVertical((backgroundColour ?? colours.Blue2).Opacity(0.3f), backgroundColour ?? colours.Blue2);
rightLayerGradient.Colour = ColourInfo.GradientVertical((backgroundColour ?? colours.Blue4).Opacity(0.25f), (backgroundColour ?? colours.Blue3).Opacity(0.6f));
scorePanel.BorderColour = ColourInfo.GradientVertical((backgroundColour ?? colours.Blue1).Opacity(0.2f), backgroundColour ?? colours.Blue1);
}
protected override void Update()
{
base.Update();

View File

@@ -27,14 +27,5 @@ namespace osu.Game.Screens.Play
AbortConfirm();
}
protected override void Confirm()
{
base.Confirm();
// Not removing immediately can lead to delays due to async disposal.
// This is done here rather than in `Player` because it's simpler to handle.
RemoveAudioAdjustments();
}
}
}

View File

@@ -27,14 +27,5 @@ namespace osu.Game.Screens.Play
AbortConfirm();
}
protected override void Confirm()
{
base.Confirm();
// Not removing immediately can lead to delays due to async disposal.
// This is done here rather than in `Player` because it's simpler to handle.
RemoveAudioAdjustments();
}
}
}

Some files were not shown because too many files have changed in this diff Show More