1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-10 18:17:19 +08:00

Merge pull request #32235 from bdach/screw-this-feature-who-is-it-even-for

Fix "use these mods" context menu option doing broken things with system mods
This commit is contained in:
Dan Balasescu 2025-03-05 23:43:30 +09:00 committed by GitHub
commit 3f211e33b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 178 additions and 17 deletions

View File

@ -6,6 +6,8 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation;
using osu.Game.Online.API;
using osu.Game.Online.Metadata;
@ -13,9 +15,11 @@ using osu.Game.Online.Rooms;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.SelectV2.Leaderboards;
using osu.Game.Tests.Resources;
using osu.Game.Tests.Visual.Metadata;
using osu.Game.Tests.Visual.OnlinePlay;
using osuTK.Input;
namespace osu.Game.Tests.Visual.DailyChallenge
{
@ -57,6 +61,39 @@ namespace osu.Game.Tests.Visual.DailyChallenge
AddStep("push screen", () => LoadScreen(new Screens.OnlinePlay.DailyChallenge.DailyChallenge(room)));
}
[Test]
public void TestUseTheseModsUnavailableIfNoFreeMods()
{
var room = new Room
{
RoomID = 1234,
Name = "Daily Challenge: June 4, 2024",
Playlist =
[
new PlaylistItem(TestResources.CreateTestBeatmapSetInfo().Beatmaps.First())
{
RequiredMods = [new APIMod(new OsuModTraceable())],
AllowedMods = []
}
],
EndDate = DateTimeOffset.Now.AddHours(12),
Category = RoomCategory.DailyChallenge
};
AddStep("add room", () => API.Perform(new CreateRoomRequest(room)));
Screens.OnlinePlay.DailyChallenge.DailyChallenge screen = null!;
AddStep("push screen", () => LoadScreen(screen = new Screens.OnlinePlay.DailyChallenge.DailyChallenge(room)));
AddUntilStep("wait for pushed", () => screen.IsCurrentScreen());
AddStep("force transforms to finish", () => FinishTransforms(true));
AddStep("right click second score", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<LeaderboardScoreV2>().ElementAt(1));
InputManager.Click(MouseButton.Right);
});
AddAssert("use these mods not present",
() => this.ChildrenOfType<OsuContextMenu>().All(m => m.Items.All(item => item.Text.Value != "Use these mods")));
}
[Test]
public void TestNotifications()
{

View File

@ -12,6 +12,8 @@ using osu.Framework.Graphics;
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Leaderboards;
using osu.Game.Overlays;
@ -20,14 +22,16 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Scoring;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Tests.Resources;
using osu.Game.Users;
using osuTK;
using osuTK.Input;
namespace osu.Game.Tests.Visual.SongSelect
{
public partial class TestSceneBeatmapLeaderboard : OsuTestScene
public partial class TestSceneBeatmapLeaderboard : OsuManualInputManagerTestScene
{
private readonly FailableLeaderboard leaderboard;
@ -37,6 +41,7 @@ namespace osu.Game.Tests.Visual.SongSelect
private ScoreManager scoreManager = null!;
private RulesetStore rulesetStore = null!;
private BeatmapManager beatmapManager = null!;
private PlaySongSelect songSelect = null!;
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
@ -45,25 +50,36 @@ namespace osu.Game.Tests.Visual.SongSelect
dependencies.Cache(rulesetStore = new RealmRulesetStore(Realm));
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, Realm, null, dependencies.Get<AudioManager>(), Resources, dependencies.Get<GameHost>(), Beatmap.Default));
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, Realm, API));
dependencies.CacheAs<Screens.Select.SongSelect>(songSelect = new PlaySongSelect());
Dependencies.Cache(Realm);
return dependencies;
}
[BackgroundDependencyLoader]
private void load()
{
LoadComponent(songSelect);
}
public TestSceneBeatmapLeaderboard()
{
AddRange(new Drawable[]
Add(new OsuContextMenuContainer
{
dialogOverlay = new DialogOverlay
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
Depth = -1
},
leaderboard = new FailableLeaderboard
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(550f, 450f),
Scope = BeatmapLeaderboardScope.Global,
dialogOverlay = new DialogOverlay
{
Depth = -1
},
leaderboard = new FailableLeaderboard
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(550f, 450f),
Scope = BeatmapLeaderboardScope.Global,
}
}
});
}
@ -187,6 +203,40 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep(@"None selected", () => leaderboard.SetErrorState(LeaderboardState.NoneSelected));
}
[Test]
public void TestUseTheseModsDoesNotCopySystemMods()
{
AddStep(@"set scores", () => leaderboard.SetScores(leaderboard.Scores, new ScoreInfo
{
Position = 999,
Rank = ScoreRank.XH,
Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Ruleset = new OsuRuleset().RulesetInfo,
Mods = new Mod[] { new OsuModHidden(), new ModScoreV2(), },
User = new APIUser
{
Id = 6602580,
Username = @"waaiiru",
CountryCode = CountryCode.ES,
}
}));
AddUntilStep("wait for scores", () => this.ChildrenOfType<LeaderboardScore>().Count(), () => Is.GreaterThan(0));
AddStep("right click panel", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<LeaderboardScore>().Single());
InputManager.Click(MouseButton.Right);
});
AddStep("click use these mods", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<DrawableOsuMenuItem>().Single());
InputManager.Click(MouseButton.Left);
});
AddAssert("song select received HD", () => songSelect.Mods.Value.Any(m => m is OsuModHidden));
AddAssert("song select did not receive SV2", () => !songSelect.Mods.Value.Any(m => m is ModScoreV2));
}
private void showPersonalBestWithNullPosition()
{
leaderboard.SetScores(leaderboard.Scores, new ScoreInfo

View File

@ -6,16 +6,17 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Testing;
using osu.Game.Graphics.Cursor;
using osu.Game.Overlays;
namespace osu.Game.Tests.Visual.SongSelectV2
{
public abstract partial class SongSelectComponentsTestScene : OsuTestScene
public abstract partial class SongSelectComponentsTestScene : OsuManualInputManagerTestScene
{
[Cached]
protected readonly OverlayColourProvider ColourProvider = new OverlayColourProvider(OverlayColourScheme.Aquamarine);
protected override Container<Drawable> Content { get; } = new Container
protected override Container<Drawable> Content { get; } = new OsuContextMenuContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,

View File

@ -7,9 +7,11 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Configuration;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Rulesets.Mania;
@ -22,6 +24,7 @@ using osu.Game.Screens.SelectV2.Leaderboards;
using osu.Game.Tests.Resources;
using osu.Game.Users;
using osuTK;
using osuTK.Input;
namespace osu.Game.Tests.Visual.SongSelectV2
{
@ -102,6 +105,69 @@ namespace osu.Game.Tests.Visual.SongSelectV2
});
}
[Test]
public void TestUseTheseModsDoesNotCopySystemMods()
{
LeaderboardScoreV2 score = null!;
AddStep("create content", () =>
{
Children = new Drawable[]
{
fillFlow = new FillFlowContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0f, 2f),
Shear = new Vector2(OsuGame.SHEAR, 0)
},
drawWidthText = new OsuSpriteText(),
};
var scoreInfo = new ScoreInfo
{
Position = 999,
Rank = ScoreRank.X,
Accuracy = 1,
MaxCombo = 244,
TotalScore = RNG.Next(1_800_000, 2_000_000),
MaximumStatistics = { { HitResult.Great, 3000 } },
Mods = new Mod[] { new OsuModHidden(), new ModScoreV2(), },
Ruleset = new OsuRuleset().RulesetInfo,
User = new APIUser
{
Id = 6602580,
Username = @"waaiiru",
CountryCode = CountryCode.ES,
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg",
},
Date = DateTimeOffset.Now.AddYears(-2),
};
fillFlow.Add(score = new LeaderboardScoreV2(scoreInfo)
{
Rank = scoreInfo.Position,
Shear = Vector2.Zero,
});
score.Show();
});
AddStep("right click panel", () =>
{
InputManager.MoveMouseTo(score);
InputManager.Click(MouseButton.Right);
});
AddStep("click use these mods", () =>
{
InputManager.MoveMouseTo(this.ChildrenOfType<DrawableOsuMenuItem>().Single());
InputManager.Click(MouseButton.Left);
});
AddAssert("mods received HD", () => score.SelectedMods.Value.Any(m => m is OsuModHidden));
AddAssert("mods did not receive SV2", () => !score.SelectedMods.Value.Any(m => m is ModScoreV2));
}
public override void SetUpSteps()
{
AddToggleStep("toggle scoring mode", v => config.SetValue(OsuSetting.ScoreDisplayMode, v ? ScoringMode.Classic : ScoringMode.Standardised));

View File

@ -452,8 +452,11 @@ namespace osu.Game.Online.Leaderboards
{
List<MenuItem> items = new List<MenuItem>();
if (Score.Mods.Length > 0 && songSelect != null)
items.Add(new OsuMenuItem("Use these mods", MenuItemType.Highlighted, () => songSelect.Mods.Value = Score.Mods));
// system mods should never be copied across regardless of anything.
var copyableMods = Score.Mods.Where(m => m.Type != ModType.System).ToArray();
if (copyableMods.Length > 0 && songSelect != null)
items.Add(new OsuMenuItem("Use these mods", MenuItemType.Highlighted, () => songSelect.Mods.Value = copyableMods));
if (Score.OnlineID > 0)
items.Add(new OsuMenuItem(CommonStrings.CopyLink, MenuItemType.Standard, () => clipboard?.SetText($@"{api.Endpoints.WebsiteUrl}/scores/{Score.OnlineID}")));

View File

@ -780,8 +780,11 @@ namespace osu.Game.Screens.SelectV2.Leaderboards
{
List<MenuItem> items = new List<MenuItem>();
if (score.Mods.Length > 0)
items.Add(new OsuMenuItem("Use these mods", MenuItemType.Highlighted, () => SelectedMods.Value = score.Mods.Where(m => IsValidMod.Invoke(m)).ToArray()));
// system mods should never be copied across regardless of anything.
var copyableMods = score.Mods.Where(m => IsValidMod.Invoke(m) && m.Type != ModType.System).ToArray();
if (copyableMods.Length > 0)
items.Add(new OsuMenuItem("Use these mods", MenuItemType.Highlighted, () => SelectedMods.Value = copyableMods));
if (score.OnlineID > 0)
items.Add(new OsuMenuItem(CommonStrings.CopyLink, MenuItemType.Standard, () => clipboard?.SetText($@"{api.Endpoints.WebsiteUrl}/scores/{score.OnlineID}")));

View File

@ -126,6 +126,7 @@ namespace osu.Game.Tests.Visual.OnlinePlay
MaxCombo = 100,
TotalScore = 200000,
User = new APIUser { Username = "worst user" },
Mods = [new APIMod { Acronym = @"TD" }],
Statistics = new Dictionary<HitResult, int>()
},
},