From 49c2cb91254fe4a3ff193826a97482b144cc1a31 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Nov 2021 13:25:52 +0900 Subject: [PATCH 1/6] Initialise `BeatmapSet.Beatmaps` list to line up with realm expectations --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Beatmaps/BeatmapModelManager.cs | 1 - osu.Game/Beatmaps/BeatmapSetInfo.cs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index c2a2e93caf..4378da2dd3 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -86,7 +86,7 @@ namespace osu.Game.Beatmaps var set = new BeatmapSetInfo { Metadata = metadata, - Beatmaps = new List + Beatmaps = { new BeatmapInfo { diff --git a/osu.Game/Beatmaps/BeatmapModelManager.cs b/osu.Game/Beatmaps/BeatmapModelManager.cs index 8f55232031..132f15809a 100644 --- a/osu.Game/Beatmaps/BeatmapModelManager.cs +++ b/osu.Game/Beatmaps/BeatmapModelManager.cs @@ -370,7 +370,6 @@ namespace osu.Game.Beatmaps return new BeatmapSetInfo { OnlineID = beatmap.BeatmapInfo.BeatmapSet?.OnlineID, - Beatmaps = new List(), Metadata = beatmap.Metadata, DateAdded = DateTimeOffset.UtcNow }; diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 35468ce831..818a6dd48f 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -30,7 +30,7 @@ namespace osu.Game.Beatmaps public BeatmapMetadata Metadata { get; set; } - public List Beatmaps { get; set; } + public List Beatmaps { get; } = new List(); public BeatmapSetOnlineStatus Status { get; set; } = BeatmapSetOnlineStatus.None; From 8c60f37508cf52dbedab69a65a8d22c900695b0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Nov 2021 13:25:26 +0900 Subject: [PATCH 2/6] Fix cases of dynamically assigning `Beatmap`s to `BeatmapSetInfo` using list assignment --- .../Beatmaps/IO/ImportBeatmapTest.cs | 2 +- ...eneOnlinePlayBeatmapAvailabilityTracker.cs | 9 ++-- .../Menus/TestSceneMusicActionHandling.cs | 2 +- .../TestSceneMultiplayerMatchSongSelect.cs | 36 +++++++++------ .../TestScenePlaylistsSongSelect.cs | 34 +++++++------- .../Navigation/TestScenePresentBeatmap.cs | 3 +- .../Navigation/TestScenePresentScore.cs | 3 +- .../SongSelect/TestSceneBeatmapCarousel.cs | 46 ++++++++++--------- .../TestSceneBeatmapRecommendations.cs | 20 ++++---- .../SongSelect/TestScenePlaySongSelect.cs | 33 ++++++------- osu.Game/Beatmaps/BeatmapModelManager.cs | 2 +- osu.Game/Tests/Beatmaps/TestBeatmap.cs | 12 +++-- osu.Game/Tests/Visual/OsuTestScene.cs | 21 ++++++--- 13 files changed, 123 insertions(+), 100 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 836cbfa6c5..a404a54ee4 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -584,7 +584,7 @@ namespace osu.Game.Tests.Beatmaps.IO { OnlineID = 1, Metadata = metadata, - Beatmaps = new List + Beatmaps = { new BeatmapInfo { diff --git a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs index b66da028f1..748de6c9a8 100644 --- a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs @@ -2,7 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -143,8 +143,11 @@ namespace osu.Game.Tests.Online var beatmap = decoder.Decode(reader); info = beatmap.BeatmapInfo; - info.BeatmapSet.Beatmaps = new List { info }; - info.BeatmapSet.Metadata = info.Metadata; + info.Metadata = info.Metadata; + + Debug.Assert(info.BeatmapSet != null); + + info.BeatmapSet.Beatmaps.Add(info); info.MD5Hash = stream.ComputeMD5Hash(); info.Hash = stream.ComputeSHA2Hash(); } diff --git a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs index 6dda8df6f0..f429b5b2a8 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs @@ -36,7 +36,7 @@ namespace osu.Game.Tests.Visual.Menus // ensure we have at least two beatmaps available to identify the direction the music controller navigated to. AddRepeatStep("import beatmap", () => Game.BeatmapManager.Import(new BeatmapSetInfo { - Beatmaps = new List + Beatmaps = { new BeatmapInfo { diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs index aef1fb31d6..f308886bf4 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs @@ -47,6 +47,13 @@ namespace osu.Game.Tests.Visual.Multiplayer beatmaps = new List(); + var beatmapSetInfo = new BeatmapSetInfo + { + OnlineID = 10, + Hash = Guid.NewGuid().ToString().ComputeMD5Hash(), + DateAdded = DateTimeOffset.UtcNow + }; + for (int i = 0; i < 8; ++i) { int beatmapId = 10 * 10 + i; @@ -54,29 +61,28 @@ namespace osu.Game.Tests.Visual.Multiplayer int length = RNG.Next(30000, 200000); double bpm = RNG.NextSingle(80, 200); - beatmaps.Add(new BeatmapInfo + var metadata = new BeatmapMetadata + { + Artist = "Some Artist", + Title = "Some Beatmap", + AuthorString = "Some Author" + }; + + var beatmap = new BeatmapInfo { Ruleset = rulesets.GetRuleset(i % 4), OnlineID = beatmapId, Length = length, BPM = bpm, + Metadata = metadata, BaseDifficulty = new BeatmapDifficulty() - }); + }; + + beatmaps.Add(beatmap); + beatmapSetInfo.Beatmaps.Add(beatmap); } - manager.Import(new BeatmapSetInfo - { - OnlineID = 10, - Hash = Guid.NewGuid().ToString().ComputeMD5Hash(), - Metadata = new BeatmapMetadata - { - Artist = "Some Artist", - Title = "Some Beatmap", - AuthorString = "Some Author" - }, - Beatmaps = beatmaps, - DateAdded = DateTimeOffset.UtcNow - }).Wait(); + manager.Import(beatmapSetInfo).Wait(); } public override void SetUpSteps() diff --git a/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs index 05f9a94cf7..04e47e17e5 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; @@ -42,7 +41,20 @@ namespace osu.Game.Tests.Visual.Multiplayer Dependencies.Cache(rulesets = new RulesetStore(ContextFactory)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default)); - var beatmaps = new List(); + var metadata = new BeatmapMetadata + { + // Create random metadata, then we can check if sorting works based on these + Artist = "Some Artist " + RNG.Next(0, 9), + Title = "Some Song (set id 10)", + AuthorString = "Some Guy " + RNG.Next(0, 9), + }; + + var beatmapSet = new BeatmapSetInfo + { + OnlineID = 10, + Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), + DateAdded = DateTimeOffset.UtcNow, + }; for (int i = 0; i < 6; i++) { @@ -51,12 +63,13 @@ namespace osu.Game.Tests.Visual.Multiplayer int length = RNG.Next(30000, 200000); double bpm = RNG.NextSingle(80, 200); - beatmaps.Add(new BeatmapInfo + beatmapSet.Beatmaps.Add(new BeatmapInfo { Ruleset = new OsuRuleset().RulesetInfo, OnlineID = beatmapId, DifficultyName = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})", Length = length, + Metadata = metadata, BPM = bpm, BaseDifficulty = new BeatmapDifficulty { @@ -65,20 +78,7 @@ namespace osu.Game.Tests.Visual.Multiplayer }); } - manager.Import(new BeatmapSetInfo - { - OnlineID = 10, - Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), - Metadata = new BeatmapMetadata - { - // Create random metadata, then we can check if sorting works based on these - Artist = "Some Artist " + RNG.Next(0, 9), - Title = $"Some Song (set id 10), max bpm {beatmaps.Max(b => b.BPM):0.#})", - AuthorString = "Some Guy " + RNG.Next(0, 9), - }, - Beatmaps = beatmaps, - DateAdded = DateTimeOffset.UtcNow, - }).Wait(); + manager.Import(beatmapSet).Wait(); } public override void SetUpSteps() diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs index d1ee984682..2d1512209e 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Screens; @@ -110,7 +109,7 @@ namespace osu.Game.Tests.Visual.Navigation Hash = Guid.NewGuid().ToString(), OnlineID = i, Metadata = metadata, - Beatmaps = new List + Beatmaps = { new BeatmapInfo { diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs index 72f160c9a9..1d4459a852 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Screens; @@ -41,7 +40,7 @@ namespace osu.Game.Tests.Visual.Navigation Hash = Guid.NewGuid().ToString(), OnlineID = 1, Metadata = metadata, - Beatmaps = new List + Beatmaps = { new BeatmapInfo { diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 5c40a3dd94..512e34975e 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -836,23 +836,27 @@ namespace osu.Game.Tests.Visual.SongSelect private BeatmapSetInfo createTestBeatmapSet(int id, bool randomDifficultyCount = false) { - return new BeatmapSetInfo + var metadata = new BeatmapMetadata + { + // Create random metadata, then we can check if sorting works based on these + Artist = $"peppy{id.ToString().PadLeft(6, '0')}", + Title = $"test set #{id}!", + AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, id - 1)), 5)) + }; + + var beatmapSet = new BeatmapSetInfo { - ID = id, OnlineID = id, Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), - Metadata = new BeatmapMetadata - { - // Create random metadata, then we can check if sorting works based on these - Artist = $"peppy{id.ToString().PadLeft(6, '0')}", - Title = $"test set #{id}!", - AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, id - 1)), 5)) - }, - Beatmaps = getBeatmaps(randomDifficultyCount ? RNG.Next(1, 20) : 3).ToList() }; + + foreach (var b in getBeatmaps(randomDifficultyCount ? RNG.Next(1, 20) : 3, metadata)) + beatmapSet.Beatmaps.Add(b); + + return beatmapSet; } - private IEnumerable getBeatmaps(int count) + private IEnumerable getBeatmaps(int count, BeatmapMetadata metadata) { int id = 0; @@ -872,6 +876,7 @@ namespace osu.Game.Tests.Visual.SongSelect DifficultyName = version, StarRating = diff, Ruleset = new OsuRuleset().RulesetInfo, + Metadata = metadata, BaseDifficulty = new BeatmapDifficulty { OverallDifficulty = diff, @@ -882,19 +887,18 @@ namespace osu.Game.Tests.Visual.SongSelect private BeatmapSetInfo createTestBeatmapSetWithManyDifficulties(int id) { + var metadata = new BeatmapMetadata + { + // Create random metadata, then we can check if sorting works based on these + Artist = $"peppy{id.ToString().PadLeft(6, '0')}", + Title = $"test set #{id}!", + AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, id - 1)), 5)) + }; + var toReturn = new BeatmapSetInfo { - ID = id, OnlineID = id, Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), - Metadata = new BeatmapMetadata - { - // Create random metadata, then we can check if sorting works based on these - Artist = $"peppy{id.ToString().PadLeft(6, '0')}", - Title = $"test set #{id}!", - AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, id - 1)), 5)) - }, - Beatmaps = new List(), }; for (int b = 1; b < 101; b++) @@ -902,10 +906,10 @@ namespace osu.Game.Tests.Visual.SongSelect toReturn.Beatmaps.Add(new BeatmapInfo { OnlineID = b * 10, - Path = $"extra{b}.osu", DifficultyName = $"Extra {b}", Ruleset = rulesets.GetRuleset((b - 1) % 4), StarRating = 2, + Metadata = metadata, BaseDifficulty = new BeatmapDifficulty { OverallDifficulty = 3.5f, diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs index c9ec53cfd5..73144b584f 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs @@ -182,18 +182,18 @@ namespace osu.Game.Tests.Visual.SongSelect { Hash = Guid.NewGuid().ToString(), OnlineID = importID, - Metadata = metadata, - Beatmaps = difficultyRulesets.Select((ruleset, difficultyIndex) => new BeatmapInfo - { - OnlineID = importID * 1024 + difficultyIndex, - Metadata = metadata, - BaseDifficulty = new BeatmapDifficulty(), - Ruleset = ruleset, - StarRating = difficultyIndex + 1, - DifficultyName = $"SR{difficultyIndex + 1}" - }).ToList() }; + beatmapSet.Beatmaps.AddRange(difficultyRulesets.Select((ruleset, difficultyIndex) => new BeatmapInfo + { + OnlineID = importID * 1024 + difficultyIndex, + Metadata = metadata, + BaseDifficulty = new BeatmapDifficulty(), + Ruleset = ruleset, + StarRating = difficultyIndex + 1, + DifficultyName = $"SR{difficultyIndex + 1}" + })); + return Game.BeatmapManager.Import(beatmapSet).Result.Value; } diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index f09dc38378..025c7f0dfd 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -907,7 +907,20 @@ namespace osu.Game.Tests.Visual.SongSelect int setId = getImportId(); - var beatmaps = new List(); + var beatmapSet = new BeatmapSetInfo + { + OnlineID = setId, + Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), + DateAdded = DateTimeOffset.UtcNow, + }; + + var metadata = new BeatmapMetadata + { + // Create random metadata, then we can check if sorting works based on these + Artist = "Some Artist " + RNG.Next(0, 9), + Title = $"Some Song (set id {setId})", + AuthorString = "Some Guy " + RNG.Next(0, 9), + }; for (int i = 0; i < countPerRuleset; i++) { @@ -916,12 +929,13 @@ namespace osu.Game.Tests.Visual.SongSelect int length = RNG.Next(30000, 200000); double bpm = RNG.NextSingle(80, 200); - beatmaps.Add(new BeatmapInfo + beatmapSet.Beatmaps.Add(new BeatmapInfo { Ruleset = getRuleset(), OnlineID = beatmapId, DifficultyName = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})", Length = length, + Metadata = metadata, BPM = bpm, BaseDifficulty = new BeatmapDifficulty { @@ -930,20 +944,7 @@ namespace osu.Game.Tests.Visual.SongSelect }); } - return new BeatmapSetInfo - { - OnlineID = setId, - Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), - Metadata = new BeatmapMetadata - { - // Create random metadata, then we can check if sorting works based on these - Artist = "Some Artist " + RNG.Next(0, 9), - Title = $"Some Song (set id {setId}, max bpm {beatmaps.Max(b => b.BPM):0.#})", - AuthorString = "Some Guy " + RNG.Next(0, 9), - }, - Beatmaps = beatmaps, - DateAdded = DateTimeOffset.UtcNow, - }; + return beatmapSet; } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Beatmaps/BeatmapModelManager.cs b/osu.Game/Beatmaps/BeatmapModelManager.cs index 132f15809a..15eac962cc 100644 --- a/osu.Game/Beatmaps/BeatmapModelManager.cs +++ b/osu.Game/Beatmaps/BeatmapModelManager.cs @@ -82,7 +82,7 @@ namespace osu.Game.Beatmaps protected override async Task Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive, CancellationToken cancellationToken = default) { if (archive != null) - beatmapSet.Beatmaps = createBeatmapDifficulties(beatmapSet.Files); + beatmapSet.Beatmaps.AddRange(createBeatmapDifficulties(beatmapSet.Files)); foreach (BeatmapInfo b in beatmapSet.Beatmaps) { diff --git a/osu.Game/Tests/Beatmaps/TestBeatmap.cs b/osu.Game/Tests/Beatmaps/TestBeatmap.cs index 32a9b0b9d1..729253e25c 100644 --- a/osu.Game/Tests/Beatmaps/TestBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestBeatmap.cs @@ -2,7 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Text; using System.Threading; @@ -33,12 +33,16 @@ namespace osu.Game.Tests.Beatmaps BeatmapInfo.Ruleset = ruleset; BeatmapInfo.RulesetID = ruleset.ID ?? 0; - BeatmapInfo.BeatmapSet.Metadata = BeatmapInfo.Metadata; - BeatmapInfo.BeatmapSet.Beatmaps = new List { BeatmapInfo }; - BeatmapInfo.BeatmapSet.OnlineID = Interlocked.Increment(ref onlineSetID); + BeatmapInfo.Metadata = BeatmapInfo.Metadata; BeatmapInfo.Length = 75000; BeatmapInfo.OnlineInfo = new APIBeatmap(); BeatmapInfo.OnlineID = Interlocked.Increment(ref onlineBeatmapID); + + Debug.Assert(BeatmapInfo.BeatmapSet != null); + + BeatmapInfo.BeatmapSet.Metadata = BeatmapInfo.Metadata; + BeatmapInfo.BeatmapSet.Beatmaps.Add(BeatmapInfo); + BeatmapInfo.BeatmapSet.OnlineID = Interlocked.Increment(ref onlineSetID); } protected virtual Beatmap CreateBeatmap() => createTestBeatmap(); diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index eedf266bbe..d774514dda 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -220,6 +221,8 @@ namespace osu.Game.Tests.Visual { var beatmap = CreateBeatmap(ruleset ?? Ruleset.Value).BeatmapInfo; + Debug.Assert(beatmap.BeatmapSet != null); + return new APIBeatmapSet { OnlineID = ((IBeatmapSetInfo)beatmap.BeatmapSet).OnlineID, @@ -230,13 +233,17 @@ namespace osu.Game.Tests.Visual Card = "https://assets.ppy.sh/beatmaps/163112/covers/card.jpg", List = "https://assets.ppy.sh/beatmaps/163112/covers/list.jpg" }, - Title = beatmap.BeatmapSet.Metadata.Title, - TitleUnicode = beatmap.BeatmapSet.Metadata.TitleUnicode, - Artist = beatmap.BeatmapSet.Metadata.Artist, - ArtistUnicode = beatmap.BeatmapSet.Metadata.ArtistUnicode, - Author = beatmap.BeatmapSet.Metadata.Author, - Source = beatmap.BeatmapSet.Metadata.Source, - Tags = beatmap.BeatmapSet.Metadata.Tags, + Title = beatmap.Metadata.Title, + TitleUnicode = beatmap.Metadata.TitleUnicode, + Artist = beatmap.Metadata.Artist, + ArtistUnicode = beatmap.Metadata.ArtistUnicode, + Author = new APIUser + { + Username = beatmap.Metadata.Author.Username, + Id = beatmap.Metadata.Author.OnlineID + }, + Source = beatmap.Metadata.Source, + Tags = beatmap.Metadata.Tags, Beatmaps = new[] { new APIBeatmap From a3fdab34d5b39840ca60b79cf80bebfe4bfbb780 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Nov 2021 13:34:52 +0900 Subject: [PATCH 3/6] Avoid json serialisation of aggregate helper properties Also avoids `throw`ing when there are no beatmaps available. Until now this wasn't an issue due to the `Beatmaps` list being null instead of empty. --- osu.Game/Beatmaps/BeatmapSetInfo.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 818a6dd48f..998bc6f16c 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using JetBrains.Annotations; +using Newtonsoft.Json; using osu.Framework.Testing; using osu.Game.Database; using osu.Game.Extensions; @@ -30,6 +31,7 @@ namespace osu.Game.Beatmaps public BeatmapMetadata Metadata { get; set; } + [NotNull] public List Beatmaps { get; } = new List(); public BeatmapSetOnlineStatus Status { get; set; } = BeatmapSetOnlineStatus.None; @@ -40,17 +42,20 @@ namespace osu.Game.Beatmaps /// /// The maximum star difficulty of all beatmaps in this set. /// - public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarRating) ?? 0; + [JsonIgnore] + public double MaxStarDifficulty => Beatmaps.Count == 0 ? 0 : Beatmaps.Max(b => b.StarRating); /// /// The maximum playable length in milliseconds of all beatmaps in this set. /// - public double MaxLength => Beatmaps?.Max(b => b.Length) ?? 0; + [JsonIgnore] + public double MaxLength => Beatmaps.Count == 0 ? 0 : Beatmaps.Max(b => b.Length); /// /// The maximum BPM of all beatmaps in this set. /// - public double MaxBPM => Beatmaps?.Max(b => b.BPM) ?? 0; + [JsonIgnore] + public double MaxBPM => Beatmaps.Count == 0 ? 0 : Beatmaps.Max(b => b.BPM); [NotMapped] public bool DeletePending { get; set; } From a7853fc9cc96fa50b92b12b5c25dee18f9ccc11a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Nov 2021 14:26:23 +0900 Subject: [PATCH 4/6] Fix cases of known-non-null --- osu.Game/Beatmaps/WorkingBeatmapCache.cs | 2 -- osu.Game/Overlays/Music/PlaylistOverlay.cs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmapCache.cs b/osu.Game/Beatmaps/WorkingBeatmapCache.cs index 0af28902a0..857a1ca06f 100644 --- a/osu.Game/Beatmaps/WorkingBeatmapCache.cs +++ b/osu.Game/Beatmaps/WorkingBeatmapCache.cs @@ -55,8 +55,6 @@ namespace osu.Game.Beatmaps public void Invalidate(BeatmapSetInfo info) { - if (info.Beatmaps == null) return; - foreach (var b in info.Beatmaps) Invalidate(b); } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index b8d04eab4e..41c4942c55 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Music filter.Search.OnCommit += (sender, newText) => { - BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); + BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps.FirstOrDefault(); if (toSelect != null) { From 44c34ca7b2473d65e24dffde56ca2270724267dd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Nov 2021 14:32:18 +0900 Subject: [PATCH 5/6] Revert changes causing `BeatmapSet.Metadata` to be expectedly null in some tests --- ...stSceneOnlinePlayBeatmapAvailabilityTracker.cs | 1 + .../TestSceneMultiplayerMatchSongSelect.cs | 15 ++++++++------- .../Multiplayer/TestScenePlaylistsSongSelect.cs | 1 + .../Visual/SongSelect/TestSceneBeatmapCarousel.cs | 3 +++ .../SongSelect/TestSceneBeatmapRecommendations.cs | 1 + .../Visual/SongSelect/TestScenePlaySongSelect.cs | 15 ++++++++------- 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs index 748de6c9a8..0fba0eb7a9 100644 --- a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs @@ -148,6 +148,7 @@ namespace osu.Game.Tests.Online Debug.Assert(info.BeatmapSet != null); info.BeatmapSet.Beatmaps.Add(info); + info.BeatmapSet.Metadata = info.Metadata; info.MD5Hash = stream.ComputeMD5Hash(); info.Hash = stream.ComputeSHA2Hash(); } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs index f308886bf4..6b67a979e5 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs @@ -47,10 +47,18 @@ namespace osu.Game.Tests.Visual.Multiplayer beatmaps = new List(); + var metadata = new BeatmapMetadata + { + Artist = "Some Artist", + Title = "Some Beatmap", + AuthorString = "Some Author" + }; + var beatmapSetInfo = new BeatmapSetInfo { OnlineID = 10, Hash = Guid.NewGuid().ToString().ComputeMD5Hash(), + Metadata = metadata, DateAdded = DateTimeOffset.UtcNow }; @@ -61,13 +69,6 @@ namespace osu.Game.Tests.Visual.Multiplayer int length = RNG.Next(30000, 200000); double bpm = RNG.NextSingle(80, 200); - var metadata = new BeatmapMetadata - { - Artist = "Some Artist", - Title = "Some Beatmap", - AuthorString = "Some Author" - }; - var beatmap = new BeatmapInfo { Ruleset = rulesets.GetRuleset(i % 4), diff --git a/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs index 04e47e17e5..3e24b7a1d0 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs @@ -53,6 +53,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { OnlineID = 10, Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), + Metadata = metadata, DateAdded = DateTimeOffset.UtcNow, }; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 512e34975e..1808f98c23 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -846,8 +846,10 @@ namespace osu.Game.Tests.Visual.SongSelect var beatmapSet = new BeatmapSetInfo { + ID = id, OnlineID = id, Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), + Metadata = metadata, }; foreach (var b in getBeatmaps(randomDifficultyCount ? RNG.Next(1, 20) : 3, metadata)) @@ -899,6 +901,7 @@ namespace osu.Game.Tests.Visual.SongSelect { OnlineID = id, Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), + Metadata = metadata, }; for (int b = 1; b < 101; b++) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs index 73144b584f..7d855a88e2 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs @@ -182,6 +182,7 @@ namespace osu.Game.Tests.Visual.SongSelect { Hash = Guid.NewGuid().ToString(), OnlineID = importID, + Metadata = metadata, }; beatmapSet.Beatmaps.AddRange(difficultyRulesets.Select((ruleset, difficultyIndex) => new BeatmapInfo diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 025c7f0dfd..c89b7e858b 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -907,13 +907,6 @@ namespace osu.Game.Tests.Visual.SongSelect int setId = getImportId(); - var beatmapSet = new BeatmapSetInfo - { - OnlineID = setId, - Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), - DateAdded = DateTimeOffset.UtcNow, - }; - var metadata = new BeatmapMetadata { // Create random metadata, then we can check if sorting works based on these @@ -922,6 +915,14 @@ namespace osu.Game.Tests.Visual.SongSelect AuthorString = "Some Guy " + RNG.Next(0, 9), }; + var beatmapSet = new BeatmapSetInfo + { + OnlineID = setId, + Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), + DateAdded = DateTimeOffset.UtcNow, + Metadata = metadata + }; + for (int i = 0; i < countPerRuleset; i++) { int beatmapId = setId * 1000 + i; From cb093e1e017202836d14ad233ddb13b959eec15a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 24 Nov 2021 15:08:04 +0900 Subject: [PATCH 6/6] Remove reundant self-sets of metadata --- .../Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs | 1 - osu.Game/Tests/Beatmaps/TestBeatmap.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs index 0fba0eb7a9..a4c69075be 100644 --- a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs @@ -143,7 +143,6 @@ namespace osu.Game.Tests.Online var beatmap = decoder.Decode(reader); info = beatmap.BeatmapInfo; - info.Metadata = info.Metadata; Debug.Assert(info.BeatmapSet != null); diff --git a/osu.Game/Tests/Beatmaps/TestBeatmap.cs b/osu.Game/Tests/Beatmaps/TestBeatmap.cs index 729253e25c..99944bcf6d 100644 --- a/osu.Game/Tests/Beatmaps/TestBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestBeatmap.cs @@ -33,7 +33,6 @@ namespace osu.Game.Tests.Beatmaps BeatmapInfo.Ruleset = ruleset; BeatmapInfo.RulesetID = ruleset.ID ?? 0; - BeatmapInfo.Metadata = BeatmapInfo.Metadata; BeatmapInfo.Length = 75000; BeatmapInfo.OnlineInfo = new APIBeatmap(); BeatmapInfo.OnlineID = Interlocked.Increment(ref onlineBeatmapID);