diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index ef89a86e79..7f9b56e873 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -73,10 +73,10 @@ namespace osu.Game.Tests.Visual.Online Ranked = DateTime.Now, BPM = 111, HasVideo = true, + Ratings = Enumerable.Range(0, 11).ToArray(), HasStoryboard = true, Covers = new BeatmapSetOnlineCovers(), }, - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = new List { new BeatmapInfo @@ -92,17 +92,17 @@ namespace osu.Game.Tests.Visual.Online OverallDifficulty = 4.5f, ApproachRate = 6, }, - OnlineInfo = new BeatmapOnlineInfo + OnlineInfo = new APIBeatmap { CircleCount = 111, SliderCount = 12, PlayCount = 222, PassCount = 21, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), + }, }, }, }, @@ -153,8 +153,8 @@ namespace osu.Game.Tests.Visual.Online Covers = new BeatmapSetOnlineCovers(), Language = new BeatmapSetOnlineLanguage { Id = 3, Name = "English" }, Genre = new BeatmapSetOnlineGenre { Id = 4, Name = "Rock" }, + Ratings = Enumerable.Range(0, 11).ToArray(), }, - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = new List { new BeatmapInfo @@ -170,17 +170,17 @@ namespace osu.Game.Tests.Visual.Online OverallDifficulty = 7, ApproachRate = 6, }, - OnlineInfo = new BeatmapOnlineInfo + OnlineInfo = new APIBeatmap { CircleCount = 123, SliderCount = 45, PlayCount = 567, PassCount = 89, - }, - Metrics = new BeatmapMetrics - { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), + }, }, }, }, @@ -204,12 +204,14 @@ namespace osu.Game.Tests.Visual.Online Version = ruleset.Name, Ruleset = ruleset, BaseDifficulty = new BeatmapDifficulty(), - OnlineInfo = new BeatmapOnlineInfo(), - Metrics = new BeatmapMetrics + OnlineInfo = new APIBeatmap { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), + }, + } }); } @@ -228,8 +230,8 @@ namespace osu.Game.Tests.Visual.Online OnlineInfo = new APIBeatmapSet { Covers = new BeatmapSetOnlineCovers(), + Ratings = Enumerable.Range(0, 11).ToArray(), }, - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = beatmaps }); }); @@ -288,12 +290,14 @@ namespace osu.Game.Tests.Visual.Online { OverallDifficulty = 3.5f, }, - OnlineInfo = new BeatmapOnlineInfo(), - Metrics = new BeatmapMetrics + OnlineInfo = new APIBeatmap { - Fails = Enumerable.Range(1, 100).Select(j => j % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(j => j % 12 - 6).ToArray(), - }, + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(j => j % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(j => j % 12 - 6).ToArray(), + }, + } }); } @@ -316,8 +320,8 @@ namespace osu.Game.Tests.Visual.Online HasVideo = true, HasStoryboard = true, Covers = new BeatmapSetOnlineCovers(), + Ratings = Enumerable.Range(0, 11).ToArray(), }, - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() }, Beatmaps = beatmaps, }; } diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs index c15c9f44e4..d14f9f47d1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs @@ -39,27 +39,30 @@ namespace osu.Game.Tests.Visual.Online var secondSet = createSet(); AddStep("set first set", () => details.BeatmapSet = firstSet); - AddAssert("ratings set", () => details.Ratings.Metrics == firstSet.Metrics); + AddAssert("ratings set", () => details.Ratings.Ratings == firstSet.Ratings); AddStep("set second set", () => details.BeatmapSet = secondSet); - AddAssert("ratings set", () => details.Ratings.Metrics == secondSet.Metrics); + AddAssert("ratings set", () => details.Ratings.Ratings == secondSet.Ratings); static BeatmapSetInfo createSet() => new BeatmapSetInfo { - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).Select(_ => RNG.Next(10)).ToArray() }, Beatmaps = new List { new BeatmapInfo { - Metrics = new BeatmapMetrics + OnlineInfo = new APIBeatmap { - Fails = Enumerable.Range(1, 100).Select(_ => RNG.Next(10)).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(_ => RNG.Next(10)).ToArray(), - }, + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(_ => RNG.Next(10)).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(_ => RNG.Next(10)).ToArray(), + }, + } } }, OnlineInfo = new APIBeatmapSet { + Ratings = Enumerable.Range(0, 11).Select(_ => RNG.Next(10)).ToArray(), Status = BeatmapSetOnlineStatus.Ranked } }; diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs index fe8e33f783..b3b67fcbca 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs @@ -11,6 +11,7 @@ using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.BeatmapSet; using osu.Game.Screens.Select.Details; @@ -59,17 +60,20 @@ namespace osu.Game.Tests.Visual.Online var secondBeatmap = createBeatmap(); AddStep("set first set", () => successRate.BeatmapInfo = firstBeatmap); - AddAssert("ratings set", () => successRate.Graph.Metrics == firstBeatmap.Metrics); + AddAssert("ratings set", () => successRate.Graph.FailTimes == firstBeatmap.FailTimes); AddStep("set second set", () => successRate.BeatmapInfo = secondBeatmap); - AddAssert("ratings set", () => successRate.Graph.Metrics == secondBeatmap.Metrics); + AddAssert("ratings set", () => successRate.Graph.FailTimes == secondBeatmap.FailTimes); static BeatmapInfo createBeatmap() => new BeatmapInfo { - Metrics = new BeatmapMetrics + OnlineInfo = new APIBeatmap { - Fails = Enumerable.Range(1, 100).Select(_ => RNG.Next(10)).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(_ => RNG.Next(10)).ToArray(), + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(_ => RNG.Next(10)).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(_ => RNG.Next(10)).ToArray(), + } } }; } @@ -79,13 +83,16 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set beatmap", () => successRate.BeatmapInfo = new BeatmapInfo { - Metrics = new BeatmapMetrics + OnlineInfo = new APIBeatmap { - Fails = Enumerable.Range(1, 100).ToArray(), + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).ToArray(), + } } }); - AddAssert("graph max values correct", - () => successRate.ChildrenOfType().All(graph => graph.MaxValue == 100)); + + AddAssert("graph max values correct", () => successRate.ChildrenOfType().All(graph => graph.MaxValue == 100)); } [Test] @@ -93,11 +100,13 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set beatmap", () => successRate.BeatmapInfo = new BeatmapInfo { - Metrics = new BeatmapMetrics() + OnlineInfo = new APIBeatmap + { + FailTimes = new APIFailTimes(), + } }); - AddAssert("graph max values correct", - () => successRate.ChildrenOfType().All(graph => graph.MaxValue == 0)); + AddAssert("graph max values correct", () => successRate.ChildrenOfType().All(graph => graph.MaxValue == 0)); } private class GraphExposingSuccessRate : SuccessRate diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs index d5b4fb9a80..1125e16d91 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs @@ -6,6 +6,7 @@ using NUnit.Framework; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Online.API; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Screens.Select; namespace osu.Game.Tests.Visual.SongSelect @@ -34,7 +35,10 @@ namespace osu.Game.Tests.Visual.SongSelect { BeatmapSet = new BeatmapSetInfo { - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() } + OnlineInfo = new APIBeatmapSet + { + Ratings = Enumerable.Range(0, 11).ToArray(), + } }, Version = "All Metrics", Metadata = new BeatmapMetadata @@ -50,11 +54,14 @@ namespace osu.Game.Tests.Visual.SongSelect ApproachRate = 3.5f, }, StarDifficulty = 5.3f, - Metrics = new BeatmapMetrics + OnlineInfo = new APIBeatmap { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), + }, + } }); } @@ -65,7 +72,10 @@ namespace osu.Game.Tests.Visual.SongSelect { BeatmapSet = new BeatmapSetInfo { - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() } + OnlineInfo = new APIBeatmapSet + { + Ratings = Enumerable.Range(0, 11).ToArray(), + } }, Version = "All Metrics", Metadata = new BeatmapMetadata @@ -80,11 +90,14 @@ namespace osu.Game.Tests.Visual.SongSelect ApproachRate = 3.5f, }, StarDifficulty = 5.3f, - Metrics = new BeatmapMetrics + OnlineInfo = new APIBeatmap { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), + }, + } }); } @@ -95,7 +108,10 @@ namespace osu.Game.Tests.Visual.SongSelect { BeatmapSet = new BeatmapSetInfo { - Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() } + OnlineInfo = new APIBeatmapSet + { + Ratings = Enumerable.Range(0, 11).ToArray(), + } }, Version = "Only Ratings", Metadata = new BeatmapMetadata @@ -133,11 +149,14 @@ namespace osu.Game.Tests.Visual.SongSelect ApproachRate = 7, }, StarDifficulty = 2.91f, - Metrics = new BeatmapMetrics + OnlineInfo = new APIBeatmap { - Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), - Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), - }, + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(), + }, + } }); } diff --git a/osu.Game.Tournament.Tests/TournamentTestScene.cs b/osu.Game.Tournament.Tests/TournamentTestScene.cs index bd079eb8de..ce9fd91ff1 100644 --- a/osu.Game.Tournament.Tests/TournamentTestScene.cs +++ b/osu.Game.Tournament.Tests/TournamentTestScene.cs @@ -8,6 +8,7 @@ using osu.Framework.Platform; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; using osu.Game.Tests.Visual; using osu.Game.Tournament.IO; @@ -160,7 +161,7 @@ namespace osu.Game.Tournament.Tests Artist = "Test Artist", ID = RNG.Next(0, 1000000) }, - OnlineInfo = new BeatmapOnlineInfo(), + OnlineInfo = new APIBeatmap(), }; protected override ITestSceneTestRunner CreateRunner() => new TournamentTestSceneTestRunner(); diff --git a/osu.Game/Beatmaps/BeatmapMetrics.cs b/osu.Game/Beatmaps/APIFailTimes.cs similarity index 96% rename from osu.Game/Beatmaps/BeatmapMetrics.cs rename to osu.Game/Beatmaps/APIFailTimes.cs index b164aa6b30..7218906b38 100644 --- a/osu.Game/Beatmaps/BeatmapMetrics.cs +++ b/osu.Game/Beatmaps/APIFailTimes.cs @@ -9,7 +9,7 @@ namespace osu.Game.Beatmaps /// /// Beatmap metrics based on accumulated online data from community plays. /// - public class BeatmapMetrics + public class APIFailTimes { /// /// Points of failure on a relative time scale (usually 0..100). diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 3bcc00f5de..9069ea4404 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -9,6 +9,7 @@ using System.Linq; using Newtonsoft.Json; using osu.Framework.Testing; using osu.Game.Database; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; using osu.Game.Scoring; @@ -16,7 +17,7 @@ namespace osu.Game.Beatmaps { [ExcludeFromDynamicCompile] [Serializable] - public class BeatmapInfo : IEquatable, IHasPrimaryKey, IBeatmapInfo + public class BeatmapInfo : IEquatable, IHasPrimaryKey, IBeatmapInfo, IBeatmapOnlineInfo { public int ID { get; set; } @@ -47,10 +48,7 @@ namespace osu.Game.Beatmaps public BeatmapDifficulty BaseDifficulty { get; set; } [NotMapped] - public BeatmapMetrics Metrics { get; set; } - - [NotMapped] - public BeatmapOnlineInfo OnlineInfo { get; set; } + public APIBeatmap OnlineInfo { get; set; } [NotMapped] public int? MaxCombo { get; set; } @@ -184,13 +182,43 @@ namespace osu.Game.Beatmaps #region Implementation of IBeatmapInfo + [JsonIgnore] string IBeatmapInfo.DifficultyName => Version; + + [JsonIgnore] IBeatmapMetadataInfo IBeatmapInfo.Metadata => Metadata; + + [JsonIgnore] IBeatmapDifficultyInfo IBeatmapInfo.Difficulty => BaseDifficulty; + + [JsonIgnore] IBeatmapSetInfo IBeatmapInfo.BeatmapSet => BeatmapSet; + + [JsonIgnore] IRulesetInfo IBeatmapInfo.Ruleset => Ruleset; + + [JsonIgnore] double IBeatmapInfo.StarRating => StarDifficulty; #endregion + + #region Implementation of IBeatmapOnlineInfo + + [JsonIgnore] + public int CircleCount => OnlineInfo.CircleCount; + + [JsonIgnore] + public int SliderCount => OnlineInfo.SliderCount; + + [JsonIgnore] + public int PlayCount => OnlineInfo.PlayCount; + + [JsonIgnore] + public int PassCount => OnlineInfo.PassCount; + + [JsonIgnore] + public APIFailTimes FailTimes => OnlineInfo.FailTimes; + + #endregion } } diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 0c032e1482..ae32ad000e 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -38,9 +38,6 @@ namespace osu.Game.Beatmaps [NotMapped] public APIBeatmapSet OnlineInfo { get; set; } - [NotMapped] - public BeatmapSetMetrics Metrics { get; set; } - /// /// The maximum star difficulty of all beatmaps in this set. /// @@ -172,6 +169,10 @@ namespace osu.Game.Beatmaps [JsonIgnore] public int? TrackId => OnlineInfo?.TrackId; + [NotMapped] + [JsonIgnore] + public int[] Ratings => OnlineInfo?.Ratings; + #endregion } } diff --git a/osu.Game/Beatmaps/BeatmapSetMetrics.cs b/osu.Game/Beatmaps/BeatmapSetMetrics.cs deleted file mode 100644 index 51c5de19a6..0000000000 --- a/osu.Game/Beatmaps/BeatmapSetMetrics.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using Newtonsoft.Json; - -namespace osu.Game.Beatmaps -{ - public class BeatmapSetMetrics - { - /// - /// Total vote counts of user ratings on a scale of 0..10 where 0 is unused (probably will be fixed at API?). - /// - [JsonProperty("ratings")] - public int[] Ratings { get; set; } = Array.Empty(); - } -} diff --git a/osu.Game/Beatmaps/BeatmapOnlineInfo.cs b/osu.Game/Beatmaps/IBeatmapOnlineInfo.cs similarity index 51% rename from osu.Game/Beatmaps/BeatmapOnlineInfo.cs rename to osu.Game/Beatmaps/IBeatmapOnlineInfo.cs index bfeacd9bfc..385646eeaa 100644 --- a/osu.Game/Beatmaps/BeatmapOnlineInfo.cs +++ b/osu.Game/Beatmaps/IBeatmapOnlineInfo.cs @@ -1,31 +1,40 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +#nullable enable + namespace osu.Game.Beatmaps { /// - /// Beatmap info retrieved for previewing locally without having the beatmap downloaded. + /// Beatmap info retrieved for previewing locally. /// - public class BeatmapOnlineInfo + public interface IBeatmapOnlineInfo { + /// + /// The max combo of this beatmap. + /// + int? MaxCombo { get; } + /// /// The amount of circles in this beatmap. /// - public int CircleCount { get; set; } + public int CircleCount { get; } /// /// The amount of sliders in this beatmap. /// - public int SliderCount { get; set; } + public int SliderCount { get; } /// /// The amount of plays this beatmap has. /// - public int PlayCount { get; set; } + public int PlayCount { get; } /// /// The amount of passes this beatmap has. /// - public int PassCount { get; set; } + public int PassCount { get; } + + APIFailTimes? FailTimes { get; } } } diff --git a/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs index 1d2bb46bde..6def6ec21d 100644 --- a/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/IBeatmapSetOnlineInfo.cs @@ -97,5 +97,10 @@ namespace osu.Game.Beatmaps /// Non-null only if the track is linked to a featured artist track entry. /// int? TrackId { get; } + + /// + /// Total vote counts of user ratings on a scale of 0..10 where 0 is unused (probably will be fixed at API?). + /// + int[]? Ratings { get; } } } diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index fee3e56859..0945ad30b4 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests.Responses { - public class APIBeatmap : IBeatmapInfo + public class APIBeatmap : IBeatmapInfo, IBeatmapOnlineInfo { [JsonProperty(@"id")] public int OnlineID { get; set; } @@ -31,10 +31,10 @@ namespace osu.Game.Online.API.Requests.Responses public APIBeatmapSet? BeatmapSet { get; set; } [JsonProperty(@"playcount")] - private int playCount { get; set; } + public int PlayCount { get; set; } [JsonProperty(@"passcount")] - private int passCount { get; set; } + public int PassCount { get; set; } [JsonProperty(@"mode_int")] public int RulesetID { get; set; } @@ -60,19 +60,21 @@ namespace osu.Game.Online.API.Requests.Responses private double lengthInSeconds { get; set; } [JsonProperty(@"count_circles")] - private int circleCount { get; set; } + public int CircleCount { get; set; } [JsonProperty(@"count_sliders")] - private int sliderCount { get; set; } + public int SliderCount { get; set; } [JsonProperty(@"version")] public string DifficultyName { get; set; } = string.Empty; [JsonProperty(@"failtimes")] - private BeatmapMetrics? metrics { get; set; } + public APIFailTimes? FailTimes { get; set; } [JsonProperty(@"max_combo")] - private int? maxCombo { get; set; } + public int? MaxCombo { get; set; } + + public double BPM { get; set; } public virtual BeatmapInfo ToBeatmapInfo(RulesetStore rulesets) { @@ -90,8 +92,7 @@ namespace osu.Game.Online.API.Requests.Responses Status = Status, MD5Hash = Checksum, BeatmapSet = set, - Metrics = metrics, - MaxCombo = maxCombo, + MaxCombo = MaxCombo, BaseDifficulty = new BeatmapDifficulty { DrainRate = drainRate, @@ -99,13 +100,7 @@ namespace osu.Game.Online.API.Requests.Responses ApproachRate = approachRate, OverallDifficulty = overallDifficulty, }, - OnlineInfo = new BeatmapOnlineInfo - { - PlayCount = playCount, - PassCount = passCount, - CircleCount = circleCount, - SliderCount = sliderCount, - }, + OnlineInfo = this, }; } @@ -127,7 +122,7 @@ namespace osu.Game.Online.API.Requests.Responses public IRulesetInfo Ruleset => new RulesetInfo { ID = RulesetID }; - public double BPM => throw new NotImplementedException(); + [JsonIgnore] public string Hash => throw new NotImplementedException(); #endregion diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 24d0e09649..17b1e9d3fe 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -58,8 +58,8 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"last_updated")] public DateTimeOffset? LastUpdated { get; set; } - [JsonProperty(@"ratings")] - private int[] ratings { get; set; } = Array.Empty(); + [JsonProperty("ratings")] + public int[] Ratings { get; set; } = Array.Empty(); [JsonProperty(@"track_id")] public int? TrackId { get; set; } @@ -128,7 +128,6 @@ namespace osu.Game.Online.API.Requests.Responses OnlineBeatmapSetID = OnlineID, Metadata = metadata, Status = Status, - Metrics = new BeatmapSetMetrics { Ratings = ratings }, OnlineInfo = this }; diff --git a/osu.Game/Overlays/BeatmapSet/Details.cs b/osu.Game/Overlays/BeatmapSet/Details.cs index 92361ae4f8..d6720e5f35 100644 --- a/osu.Game/Overlays/BeatmapSet/Details.cs +++ b/osu.Game/Overlays/BeatmapSet/Details.cs @@ -52,7 +52,7 @@ namespace osu.Game.Overlays.BeatmapSet private void updateDisplay() { - Ratings.Metrics = BeatmapSet?.Metrics; + Ratings.Ratings = BeatmapSet?.Ratings; ratingBox.Alpha = BeatmapSet?.OnlineInfo?.Status > 0 ? 1 : 0; } diff --git a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs index 4a9b8244a5..604c4e1949 100644 --- a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.BeatmapSet successRate.Length = rate; percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic); - Graph.Metrics = beatmapInfo?.Metrics; + Graph.FailTimes = beatmapInfo?.FailTimes; } public SuccessRate() diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 6ace92370c..16455940bf 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Select private const float transition_duration = 250; private readonly AdvancedStats advanced; - private readonly UserRatings ratings; + private readonly UserRatings ratingsDisplay; private readonly MetadataSection description, source, tags; private readonly Container failRetryContainer; private readonly FailRetryGraph failRetryGraph; @@ -43,6 +43,10 @@ namespace osu.Game.Screens.Select private BeatmapInfo beatmapInfo; + private APIFailTimes failTimes; + + private int[] ratings; + public BeatmapInfo BeatmapInfo { get => beatmapInfo; @@ -52,6 +56,9 @@ namespace osu.Game.Screens.Select beatmapInfo = value; + failTimes = beatmapInfo?.OnlineInfo?.FailTimes; + ratings = beatmapInfo?.BeatmapSet?.Ratings; + Scheduler.AddOnce(updateStatistics); } } @@ -110,7 +117,7 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.X, Height = 134, Padding = new MarginPadding { Horizontal = spacing, Top = spacing }, - Child = ratings = new UserRatings + Child = ratingsDisplay = new UserRatings { RelativeSizeAxes = Axes.Both, }, @@ -176,7 +183,7 @@ namespace osu.Game.Screens.Select tags.Text = BeatmapInfo?.Metadata?.Tags; // metrics may have been previously fetched - if (BeatmapInfo?.BeatmapSet?.Metrics != null && BeatmapInfo?.Metrics != null) + if (ratings != null && failTimes != null) { updateMetrics(); return; @@ -201,14 +208,8 @@ namespace osu.Game.Screens.Select // the beatmap has been changed since we started the lookup. return; - var b = res.ToBeatmapInfo(rulesets); - - if (requestedBeatmap.BeatmapSet == null) - requestedBeatmap.BeatmapSet = b.BeatmapSet; - else - requestedBeatmap.BeatmapSet.Metrics = b.BeatmapSet.Metrics; - - requestedBeatmap.Metrics = b.Metrics; + ratings = res.BeatmapSet?.Ratings; + failTimes = res.FailTimes; updateMetrics(); }); @@ -232,29 +233,28 @@ namespace osu.Game.Screens.Select private void updateMetrics() { - var hasRatings = beatmapInfo?.BeatmapSet?.Metrics?.Ratings?.Any() ?? false; - var hasRetriesFails = (beatmapInfo?.Metrics?.Retries?.Any() ?? false) || (beatmapInfo?.Metrics?.Fails?.Any() ?? false); + var hasMetrics = (failTimes?.Retries?.Any() ?? false) || (failTimes?.Fails?.Any() ?? false); - if (hasRatings) + if (ratings?.Any() ?? false) { - ratings.Metrics = beatmapInfo.BeatmapSet.Metrics; - ratings.FadeIn(transition_duration); + ratingsDisplay.Ratings = ratings; + ratingsDisplay.FadeIn(transition_duration); } else { // loading or just has no data server-side. - ratings.Metrics = new BeatmapSetMetrics { Ratings = new int[10] }; - ratings.FadeTo(0.25f, transition_duration); + ratingsDisplay.Ratings = new int[10]; + ratingsDisplay.FadeTo(0.25f, transition_duration); } - if (hasRetriesFails) + if (hasMetrics) { - failRetryGraph.Metrics = beatmapInfo.Metrics; + failRetryGraph.FailTimes = failTimes; failRetryContainer.FadeIn(transition_duration); } else { - failRetryGraph.Metrics = new BeatmapMetrics + failRetryGraph.FailTimes = new APIFailTimes { Fails = new int[100], Retries = new int[100], diff --git a/osu.Game/Screens/Select/Details/FailRetryGraph.cs b/osu.Game/Screens/Select/Details/FailRetryGraph.cs index 7cc80acfd3..ecaf02cb30 100644 --- a/osu.Game/Screens/Select/Details/FailRetryGraph.cs +++ b/osu.Game/Screens/Select/Details/FailRetryGraph.cs @@ -16,19 +16,19 @@ namespace osu.Game.Screens.Select.Details { private readonly BarGraph retryGraph, failGraph; - private BeatmapMetrics metrics; + private APIFailTimes failTimes; - public BeatmapMetrics Metrics + public APIFailTimes FailTimes { - get => metrics; + get => failTimes; set { - if (value == metrics) return; + if (value == failTimes) return; - metrics = value; + failTimes = value; - var retries = Metrics?.Retries ?? Array.Empty(); - var fails = Metrics?.Fails ?? Array.Empty(); + var retries = FailTimes?.Retries ?? Array.Empty(); + var fails = FailTimes?.Fails ?? Array.Empty(); var retriesAndFails = sumRetriesAndFails(retries, fails); float maxValue = retriesAndFails.Any() ? retriesAndFails.Max() : 0; diff --git a/osu.Game/Screens/Select/Details/UserRatings.cs b/osu.Game/Screens/Select/Details/UserRatings.cs index eabc476db9..aa316d6e40 100644 --- a/osu.Game/Screens/Select/Details/UserRatings.cs +++ b/osu.Game/Screens/Select/Details/UserRatings.cs @@ -1,15 +1,14 @@ // Copyright (c) ppy Pty Ltd . 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.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using System.Linq; -using osu.Framework.Extensions.LocalisationExtensions; -using osu.Game.Beatmaps; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Screens.Select.Details @@ -22,20 +21,20 @@ namespace osu.Game.Screens.Select.Details private readonly Container graphContainer; private readonly BarGraph graph; - private BeatmapSetMetrics metrics; + private int[] ratings; - public BeatmapSetMetrics Metrics + public int[] Ratings { - get => metrics; + get => ratings; set { - if (value == metrics) return; + if (value == ratings) return; - metrics = value; + ratings = value; const int rating_range = 10; - if (metrics == null) + if (ratings == null) { negativeRatings.Text = 0.ToLocalisableString(@"N0"); positiveRatings.Text = 0.ToLocalisableString(@"N0"); @@ -44,15 +43,15 @@ namespace osu.Game.Screens.Select.Details } else { - var ratings = Metrics.Ratings.Skip(1).Take(rating_range); // adjust for API returning weird empty data at 0. + var usableRange = Ratings.Skip(1).Take(rating_range); // adjust for API returning weird empty data at 0. - var negativeCount = ratings.Take(rating_range / 2).Sum(); - var totalCount = ratings.Sum(); + var negativeCount = usableRange.Take(rating_range / 2).Sum(); + var totalCount = usableRange.Sum(); negativeRatings.Text = negativeCount.ToLocalisableString(@"N0"); positiveRatings.Text = (totalCount - negativeCount).ToLocalisableString(@"N0"); ratingsBar.Length = totalCount == 0 ? 0 : (float)negativeCount / totalCount; - graph.Values = ratings.Take(rating_range).Select(r => (float)r); + graph.Values = usableRange.Take(rating_range).Select(r => (float)r); } } } diff --git a/osu.Game/Tests/Beatmaps/TestBeatmap.cs b/osu.Game/Tests/Beatmaps/TestBeatmap.cs index d8e72d31a7..15b72ce6e3 100644 --- a/osu.Game/Tests/Beatmaps/TestBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestBeatmap.cs @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Beatmaps BeatmapInfo.BeatmapSet.Metadata = BeatmapInfo.Metadata; BeatmapInfo.BeatmapSet.Beatmaps = new List { BeatmapInfo }; BeatmapInfo.Length = 75000; - BeatmapInfo.OnlineInfo = new BeatmapOnlineInfo(); + BeatmapInfo.OnlineInfo = new APIBeatmap(); BeatmapInfo.BeatmapSet.OnlineInfo = new APIBeatmapSet { Status = BeatmapSetOnlineStatus.Ranked,