diff --git a/osu.Game.Tests/Scores/IO/ImportScoreTest.cs b/osu.Game.Tests/Scores/IO/ImportScoreTest.cs index 3e6a877a35..fc7f3229df 100644 --- a/osu.Game.Tests/Scores/IO/ImportScoreTest.cs +++ b/osu.Game.Tests/Scores/IO/ImportScoreTest.cs @@ -10,6 +10,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Platform; using osu.Game.Beatmaps; +using osu.Game.Database; using osu.Game.IO.Archives; using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets.Mods; @@ -142,7 +143,7 @@ namespace osu.Game.Tests.Scores.IO var scoreManager = osu.Dependencies.Get(); beatmapManager.Delete(beatmapManager.QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == imported.BeatmapInfo.ID))!.Value); - Assert.That(scoreManager.Query(s => s.Equals(imported)).Value.DeletePending, Is.EqualTo(true)); + Assert.That(scoreManager.Query(s => s.Equals(imported)).DeletePending, Is.EqualTo(true)); var secondImport = await LoadScoreIntoOsu(osu, imported); Assert.That(secondImport, Is.Null); @@ -187,7 +188,7 @@ namespace osu.Game.Tests.Scores.IO var scoreManager = osu.Dependencies.Get(); await scoreManager.Import(score, archive); - return scoreManager.Query(_ => true).Value; + return scoreManager.Query(_ => true).Detach(); } internal class TestArchiveReader : ArchiveReader diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index c20ab84a68..98732bfb58 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Skins private void load() { var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).GetResultSafely(); - beatmap = beatmaps.GetWorkingBeatmap(imported.Value.Beatmaps[0]); + beatmap = beatmaps.GetWorkingBeatmap(imported?.Value.Beatmaps[0]); beatmap.LoadTrack(); } diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs index 81aacf61cd..69b30ec6a0 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs @@ -97,7 +97,6 @@ namespace osu.Game.Tests.Visual.Navigation BeatmapSetInfo imported = null; AddStep($"import beatmap {i}", () => { - var difficulty = new BeatmapDifficulty(); var metadata = new BeatmapMetadata { Artist = "SomeArtist", @@ -115,18 +114,18 @@ namespace osu.Game.Tests.Visual.Navigation { OnlineID = i * 1024, Metadata = metadata, - BaseDifficulty = difficulty, + BaseDifficulty = new BeatmapDifficulty(), Ruleset = ruleset ?? new OsuRuleset().RulesetInfo }, new BeatmapInfo { OnlineID = i * 2048, Metadata = metadata, - BaseDifficulty = difficulty, + BaseDifficulty = new BeatmapDifficulty(), Ruleset = ruleset ?? new OsuRuleset().RulesetInfo }, } - }).GetResultSafely().Value; + }).GetResultSafely()?.Value; }); AddAssert($"import {i} succeeded", () => imported != null); diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index b1414d5896..cbcfc07202 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.SongSelect { AddStep("store selection", () => selection = carousel.SelectedBeatmapInfo); if (isIterating) - AddUntilStep("selection changed", () => !carousel.SelectedBeatmapInfo.Equals(selection)); + AddUntilStep("selection changed", () => !carousel.SelectedBeatmapInfo?.Equals(selection) == true); else AddUntilStep("selection not changed", () => carousel.SelectedBeatmapInfo.Equals(selection)); } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 2479390700..4f6b74ba0a 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -200,6 +200,7 @@ namespace osu.Game.Beatmaps /// The query. /// The first result for the provided query, or null if no results were found. public BeatmapInfo? QueryBeatmap(Expression> query) => beatmapModelManager.QueryBeatmap(query)?.Detach(); + // TODO: move detach to usages? /// /// Saves an file against a given . diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 149de9bc76..b9e0aac6ef 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -491,10 +491,10 @@ namespace osu.Game ScoreInfo databasedScoreInfo = null; if (score.OnlineID > 0) - databasedScoreInfo = ScoreManager.Query(s => s.OnlineID == score.OnlineID)?.Value; + databasedScoreInfo = ScoreManager.Query(s => s.OnlineID == score.OnlineID); if (score is ScoreInfo scoreInfo) - databasedScoreInfo ??= ScoreManager.Query(s => s.Hash == scoreInfo.Hash)?.Value; + databasedScoreInfo ??= ScoreManager.Query(s => s.Hash == scoreInfo.Hash); if (databasedScoreInfo == null) { diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 159c3c2da0..62e61d3a94 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -49,10 +49,10 @@ namespace osu.Game.Scoring /// /// The query. /// The first result for the provided query, or null if no results were found. - public ILive Query(Expression> query) + public ScoreInfo Query(Expression> query) { using (var context = contextFactory.CreateContext()) - return context.All().FirstOrDefault(query)?.ToLive(contextFactory); + return context.All().FirstOrDefault(query)?.Detach(); } /// diff --git a/osu.Game/Scoring/ScoreModelManager.cs b/osu.Game/Scoring/ScoreModelManager.cs index 8f04e50f63..27b02fc2f0 100644 --- a/osu.Game/Scoring/ScoreModelManager.cs +++ b/osu.Game/Scoring/ScoreModelManager.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Newtonsoft.Json; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Beatmaps; @@ -63,6 +64,9 @@ namespace osu.Game.Scoring if (!model.Ruleset.IsManaged) model.Ruleset = realm.Find(model.Ruleset.ShortName); + if (string.IsNullOrEmpty(model.StatisticsJson)) + model.StatisticsJson = JsonConvert.SerializeObject(model.Statistics); + return Task.CompletedTask; } } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 226d2df619..ffb5c6a2a5 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -111,7 +111,7 @@ namespace osu.Game.Screens.Select newRoot.AddChildren(beatmapSets.Select(createCarouselSet).Where(g => g != null)); root = newRoot; - if (selectedBeatmapSet != null && !beatmapSets.Contains(selectedBeatmapSet.BeatmapSet)) + if (selectedBeatmapSet != null && (!selectedBeatmapSet.BeatmapSet.IsManaged || !beatmapSets.Contains(selectedBeatmapSet.BeatmapSet))) selectedBeatmapSet = null; Scroll.Clear(false); diff --git a/osu.Game/Stores/BeatmapImporter.cs b/osu.Game/Stores/BeatmapImporter.cs index 2c73bd22eb..e0eee84456 100644 --- a/osu.Game/Stores/BeatmapImporter.cs +++ b/osu.Game/Stores/BeatmapImporter.cs @@ -59,8 +59,15 @@ namespace osu.Game.Stores beatmapSet.Beatmaps.AddRange(createBeatmapDifficulties(beatmapSet.Files, realm)); foreach (BeatmapInfo b in beatmapSet.Beatmaps) + { b.BeatmapSet = beatmapSet; + // ensure we aren't trying to add a new ruleset to the database + // this can happen in tests, mostly + if (!b.Ruleset.IsManaged) + b.Ruleset = realm.Find(b.Ruleset.ShortName); + } + validateOnlineIds(beatmapSet, realm); bool hadOnlineIDs = beatmapSet.Beatmaps.Any(b => b.OnlineID > 0); diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs index 76acac3f8b..15ede6cc26 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs @@ -409,18 +409,18 @@ namespace osu.Game.Tests.Visual.Multiplayer public override Task GetAPIBeatmap(int beatmapId, CancellationToken cancellationToken = default) { - IBeatmapSetInfo? set = roomManager.ServerSideRooms.SelectMany(r => r.Playlist) - .FirstOrDefault(p => p.BeatmapID == beatmapId)?.Beatmap.Value.BeatmapSet - ?? beatmaps.QueryBeatmap(b => b.OnlineID == beatmapId)?.BeatmapSet; + IBeatmapInfo? beatmap = roomManager.ServerSideRooms.SelectMany(r => r.Playlist) + .FirstOrDefault(p => p.BeatmapID == beatmapId)?.Beatmap.Value + ?? beatmaps.QueryBeatmap(b => b.OnlineID == beatmapId); - if (set == null) + if (beatmap == null) throw new InvalidOperationException("Beatmap not found."); return Task.FromResult(new APIBeatmap { - BeatmapSet = new APIBeatmapSet { OnlineID = set.OnlineID }, + BeatmapSet = new APIBeatmapSet { OnlineID = beatmap.BeatmapSet?.OnlineID ?? -1 }, OnlineID = beatmapId, - Checksum = set.Beatmaps.First(b => b.OnlineID == beatmapId).MD5Hash + Checksum = beatmap.MD5Hash }); }