diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 0b6f65a0e0..2de0fcef9c 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -5,8 +5,10 @@ using System; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Screens.Select.Leaderboards; -using osu.Framework.IO.Network; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Rulesets.Mods; +using System.Text; +using System.Collections.Generic; namespace osu.Game.Online.API.Requests { @@ -15,8 +17,9 @@ namespace osu.Game.Online.API.Requests private readonly BeatmapInfo beatmap; private readonly BeatmapLeaderboardScope scope; private readonly RulesetInfo ruleset; + private readonly IEnumerable mods; - public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global) + public GetScoresRequest(BeatmapInfo beatmap, RulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global, IEnumerable mods = null) { if (!beatmap.OnlineBeatmapID.HasValue) throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}."); @@ -27,6 +30,7 @@ namespace osu.Game.Online.API.Requests this.beatmap = beatmap; this.scope = scope; this.ruleset = ruleset ?? throw new ArgumentNullException(nameof(ruleset)); + this.mods = mods ?? Array.Empty(); Success += onSuccess; } @@ -37,17 +41,19 @@ namespace osu.Game.Online.API.Requests score.Beatmap = beatmap; } - protected override WebRequest CreateWebRequest() + protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores{createQueryParameters()}"; + + private string createQueryParameters() { - var req = base.CreateWebRequest(); + StringBuilder query = new StringBuilder(@"?"); - req.Timeout = 30000; - req.AddParameter(@"type", scope.ToString().ToLowerInvariant()); - req.AddParameter(@"mode", ruleset.ShortName); + query.Append($@"type={scope.ToString().ToLowerInvariant()}&"); + query.Append($@"mode={ruleset.ShortName}&"); - return req; + foreach (var mod in mods) + query.Append($@"mods[]={mod.Acronym}&"); + + return query.ToString().TrimEnd('&'); } - - protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores"; } } diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index 477037355c..b66a2ffe0f 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -41,6 +41,8 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.X, OnFilter = (tab, mods) => { + Leaderboard.FilterMods = mods; + switch (tab) { case BeatmapDetailTab.Details: diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index aafa6bb0eb..890cc7e9a3 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -11,6 +11,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.Leaderboards; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Scoring; namespace osu.Game.Screens.Select.Leaderboards @@ -36,12 +37,31 @@ namespace osu.Game.Screens.Select.Leaderboards } } + private bool filterMods; + + public bool FilterMods + { + get => filterMods; + set + { + if (value == filterMods) + return; + + filterMods = value; + + UpdateScores(); + } + } + [Resolved] private ScoreManager scoreManager { get; set; } [Resolved] private IBindable ruleset { get; set; } + [Resolved] + private IBindable> mods { get; set; } + [Resolved] private IAPIProvider api { get; set; } @@ -49,6 +69,11 @@ namespace osu.Game.Screens.Select.Leaderboards private void load() { ruleset.ValueChanged += _ => UpdateScores(); + mods.ValueChanged += _ => + { + if (filterMods) + UpdateScores(); + }; } protected override APIRequest FetchScores(Action> scoresCallback) @@ -72,7 +97,15 @@ namespace osu.Game.Screens.Select.Leaderboards return null; } - var req = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope); + IReadOnlyList requestMods = null; + + if (filterMods && mods.Value.Count == 0) + // add nomod for the request + requestMods = new Mod[] { new ModNoMod() }; + else if (filterMods) + requestMods = mods.Value; + + var req = new GetScoresRequest(Beatmap, ruleset.Value ?? Beatmap.Ruleset, Scope, requestMods); req.Success += r => scoresCallback?.Invoke(r.Scores);