diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs index 940d001c5b..a78a8aa028 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs @@ -5,12 +5,11 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Extensions; -using osu.Game.Online.API; -using osu.Game.Online.API.Requests; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Mania; @@ -23,38 +22,28 @@ namespace osu.Game.Tests.Visual.SongSelect { public class TestSceneBeatmapRecommendations : OsuGameTestScene { + [Resolved] + private IRulesetStore rulesetStore { get; set; } + [SetUpSteps] public override void SetUpSteps() { - AddStep("register request handling", () => - { - ((DummyAPIAccess)API).HandleRequest = req => - { - switch (req) - { - case GetUserRequest userRequest: - userRequest.TriggerSuccess(getUser(userRequest.Ruleset.OnlineID)); - return true; - } - - return false; - }; - }); - base.SetUpSteps(); - APIUser getUser(int? rulesetID) + AddStep("populate ruleset statistics", () => { - return new APIUser + Dictionary rulesetStatistics = new Dictionary(); + + rulesetStore.AvailableRulesets.Where(ruleset => ruleset.IsLegacyRuleset()).ForEach(rulesetInfo => { - Username = @"Dummy", - Id = 1001, - Statistics = new UserStatistics + rulesetStatistics[rulesetInfo.ShortName] = new UserStatistics { - PP = getNecessaryPP(rulesetID) - } - }; - } + PP = getNecessaryPP(rulesetInfo.OnlineID) + }; + }); + + API.LocalUser.Value.RulesetsStatistics = rulesetStatistics; + }); decimal getNecessaryPP(int? rulesetID) { diff --git a/osu.Game/Beatmaps/DifficultyRecommender.cs b/osu.Game/Beatmaps/DifficultyRecommender.cs index 93c2fccbc7..72f1931c86 100644 --- a/osu.Game/Beatmaps/DifficultyRecommender.cs +++ b/osu.Game/Beatmaps/DifficultyRecommender.cs @@ -7,11 +7,8 @@ using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; -using osu.Game.Extensions; using osu.Game.Online.API; -using osu.Game.Online.API.Requests; using osu.Game.Rulesets; namespace osu.Game.Beatmaps @@ -25,26 +22,15 @@ namespace osu.Game.Beatmaps [Resolved] private IAPIProvider api { get; set; } - [Resolved] - private IRulesetStore rulesets { get; set; } - [Resolved] private Bindable ruleset { get; set; } - /// - /// The user for which the last requests were run. - /// - private int? requestedUserId; - - private readonly Dictionary recommendedDifficultyMapping = new Dictionary(); - - private readonly IBindable apiState = new Bindable(); + private readonly Dictionary recommendedDifficultyMapping = new Dictionary(); [BackgroundDependencyLoader] private void load() { - apiState.BindTo(api.State); - apiState.BindValueChanged(onlineStateChanged, true); + api.LocalUser.BindValueChanged(_ => populateValues(), true); } /// @@ -58,12 +44,12 @@ namespace osu.Game.Beatmaps [CanBeNull] public BeatmapInfo GetRecommendedBeatmap(IEnumerable beatmaps) { - foreach (var r in orderedRulesets) + foreach (string r in orderedRulesets) { if (!recommendedDifficultyMapping.TryGetValue(r, out double recommendation)) continue; - BeatmapInfo beatmapInfo = beatmaps.Where(b => b.Ruleset.Equals(r)).OrderBy(b => + BeatmapInfo beatmapInfo = beatmaps.Where(b => b.Ruleset.ShortName.Equals(r)).OrderBy(b => { double difference = b.StarRating - recommendation; return difference >= 0 ? difference * 2 : difference * -1; // prefer easier over harder @@ -76,55 +62,37 @@ namespace osu.Game.Beatmaps return null; } - private void fetchRecommendedValues() + private void populateValues() { - if (recommendedDifficultyMapping.Count > 0 && api.LocalUser.Value.Id == requestedUserId) + if (api.LocalUser.Value.RulesetsStatistics == null) return; - requestedUserId = api.LocalUser.Value.Id; - - // only query API for built-in rulesets - rulesets.AvailableRulesets.Where(ruleset => ruleset.IsLegacyRuleset()).ForEach(rulesetInfo => + foreach (var statistic in api.LocalUser.Value.RulesetsStatistics) { - var req = new GetUserRequest(api.LocalUser.Value.Id, rulesetInfo); - - req.Success += result => - { - // algorithm taken from https://github.com/ppy/osu-web/blob/e6e2825516449e3d0f3f5e1852c6bdd3428c3437/app/Models/User.php#L1505 - recommendedDifficultyMapping[rulesetInfo] = Math.Pow((double)(result.Statistics.PP ?? 0), 0.4) * 0.195; - }; - - api.Queue(req); - }); + decimal? pp = api.LocalUser.Value.RulesetsStatistics[statistic.Key].PP; + // algorithm taken from https://github.com/ppy/osu-web/blob/e6e2825516449e3d0f3f5e1852c6bdd3428c3437/app/Models/User.php#L1505 + double recommended = Math.Pow((double)(pp ?? 0), 0.4) * 0.195; + recommendedDifficultyMapping[statistic.Key] = recommended; + } } /// /// Rulesets ordered descending by their respective recommended difficulties. /// The currently selected ruleset will always be first. /// - private IEnumerable orderedRulesets + private IEnumerable orderedRulesets { get { if (LoadState < LoadState.Ready || ruleset.Value == null) - return Enumerable.Empty(); + return Enumerable.Empty(); return recommendedDifficultyMapping .OrderByDescending(pair => pair.Value) .Select(pair => pair.Key) - .Where(r => !r.Equals(ruleset.Value)) - .Prepend(ruleset.Value); + .Where(r => !r.Equals(ruleset.Value.ShortName)) + .Prepend(ruleset.Value.ShortName); } } - - private void onlineStateChanged(ValueChangedEvent state) => Schedule(() => - { - switch (state.NewValue) - { - case APIState.Online: - fetchRecommendedValues(); - break; - } - }); } }