diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj index a7078f1c09..3c6aaa39ca 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj index c133b0e3f8..0719dd30df 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj index 92b48470e8..d0db43cc81 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj index c133b0e3f8..0719dd30df 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj index a8599f2cb6..57b914bee6 100644 --- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj +++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj @@ -9,7 +9,7 @@ - + diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs index 23f6222eb6..f078a4353d 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.Tests { Artist = @"Unknown", Title = @"You're breathtaking", - AuthorString = @"Everyone", + Author = { Username = @"Everyone" }, }, Ruleset = new CatchRuleset().RulesetInfo }, diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index d5496b7479..13f2e25f05 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index 2f12b1535e..d51a6da4f9 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index e5b2e070d8..fea2e408f6 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -5,7 +5,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko.Tests/DrawableTaikoRulesetTestScene.cs b/osu.Game.Rulesets.Taiko.Tests/DrawableTaikoRulesetTestScene.cs index 4bdb85ba60..54bc6f1912 100644 --- a/osu.Game.Rulesets.Taiko.Tests/DrawableTaikoRulesetTestScene.cs +++ b/osu.Game.Rulesets.Taiko.Tests/DrawableTaikoRulesetTestScene.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Tests { Artist = @"Unknown", Title = @"Sample Beatmap", - AuthorString = @"peppy", + Author = { Username = @"peppy" }, }, Ruleset = new TaikoRuleset().RulesetInfo }, diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs index b976735223..e73fb6bb1f 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs @@ -163,7 +163,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning { Artist = "Unknown", Title = "Sample Beatmap", - AuthorString = "Craftplacer", + Author = { Username = "Craftplacer" }, }, Ruleset = new TaikoRuleset().RulesetInfo }, diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index e48d80323a..ad3713e047 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Tests/NonVisual/Filtering/FilterMatchingTest.cs b/osu.Game.Tests/NonVisual/Filtering/FilterMatchingTest.cs index 3d78043c73..7ac26699a5 100644 --- a/osu.Game.Tests/NonVisual/Filtering/FilterMatchingTest.cs +++ b/osu.Game.Tests/NonVisual/Filtering/FilterMatchingTest.cs @@ -30,7 +30,7 @@ namespace osu.Game.Tests.NonVisual.Filtering ArtistUnicode = "check unicode too", Title = "Title goes here", TitleUnicode = "Title goes here", - AuthorString = "The Author", + Author = { Username = "The Author" }, Source = "unit tests", Tags = "look for tags too", }, diff --git a/osu.Game.Tests/Resources/TestResources.cs b/osu.Game.Tests/Resources/TestResources.cs index 1d99a5c20d..e1da31abcb 100644 --- a/osu.Game.Tests/Resources/TestResources.cs +++ b/osu.Game.Tests/Resources/TestResources.cs @@ -89,7 +89,7 @@ namespace osu.Game.Tests.Resources // 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}) {Guid.NewGuid()}", - AuthorString = "Some Guy " + RNG.Next(0, 9), + Author = { Username = "Some Guy " + RNG.Next(0, 9) }, }; var beatmapSet = new BeatmapSetInfo diff --git a/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs index 9b8567e853..d100fba8d6 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs @@ -29,9 +29,10 @@ namespace osu.Game.Tests.Visual.Editing [Cached] private EditorClipboard clipboard = new EditorClipboard(); - [BackgroundDependencyLoader] - private void load() + protected override void LoadComplete() { + base.LoadComplete(); + Beatmap.Value = CreateWorkingBeatmap(editorBeatmap.PlayableBeatmap); Child = new ComposeScreen diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorClock.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorClock.cs index 0abf0c47f8..4b9be77471 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorClock.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorClock.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Osu; @@ -37,9 +36,10 @@ namespace osu.Game.Tests.Visual.Editing }); } - [BackgroundDependencyLoader] - private void load() + protected override void LoadComplete() { + base.LoadComplete(); + Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); // ensure that music controller does not change this beatmap due to it // completing naturally as part of the test. diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSeekSnapping.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSeekSnapping.cs index 3a19eabe81..863f42520b 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSeekSnapping.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSeekSnapping.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -23,9 +22,10 @@ namespace osu.Game.Tests.Visual.Editing BeatDivisor.Value = 4; } - [BackgroundDependencyLoader] - private void load() + protected override void LoadComplete() { + base.LoadComplete(); + var testBeatmap = new Beatmap { ControlPointInfo = new ControlPointInfo(), diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs index 4bbffbdc7a..17b8189fc7 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs @@ -29,9 +29,10 @@ namespace osu.Game.Tests.Visual.Editing editorBeatmap = new EditorBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); } - [BackgroundDependencyLoader] - private void load() + protected override void LoadComplete() { + base.LoadComplete(); + Beatmap.Value = CreateWorkingBeatmap(editorBeatmap.PlayableBeatmap); Beatmap.Disabled = true; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs index 181b0c71f2..ae7705b97d 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs @@ -52,7 +52,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { Artist = "Some Artist", Title = "Some Beatmap", - AuthorString = "Some Author" + Author = { Username = "Some Author" }, }; var beatmapSetInfo = new BeatmapSetInfo diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs index 69b30ec6a0..1b82094603 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs @@ -100,7 +100,7 @@ namespace osu.Game.Tests.Visual.Navigation var metadata = new BeatmapMetadata { Artist = "SomeArtist", - AuthorString = "SomeAuthor", + Author = { Username = "SomeAuthor" }, Title = $"import {i}" }; diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs index f9649db135..b8e49d155e 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.Navigation Metadata = new BeatmapMetadata { Artist = "SomeArtist", - AuthorString = "SomeAuthor", + Author = { Username = "SomeAuthor" }, Title = "import" }, BaseDifficulty = new BeatmapDifficulty(), @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Navigation Metadata = new BeatmapMetadata { Artist = "SomeArtist", - AuthorString = "SomeAuthor", + Author = { Username = "SomeAuthor" }, Title = "import" }, BaseDifficulty = new BeatmapDifficulty(), diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneStartupRuleset.cs b/osu.Game.Tests/Visual/Navigation/TestSceneStartupRuleset.cs new file mode 100644 index 0000000000..85dd501fd3 --- /dev/null +++ b/osu.Game.Tests/Visual/Navigation/TestSceneStartupRuleset.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Development; +using osu.Game.Configuration; + +namespace osu.Game.Tests.Visual.Navigation +{ + [TestFixture] + public class TestSceneStartupRuleset : OsuGameTestScene + { + protected override TestOsuGame CreateTestGame() + { + // Must be done in this function due to the RecycleLocalStorage call just before. + var config = DebugUtils.IsDebugBuild + ? new DevelopmentOsuConfigManager(LocalStorage) + : new OsuConfigManager(LocalStorage); + + config.SetValue(OsuSetting.Ruleset, "mania"); + config.Save(); + + return base.CreateTestGame(); + } + + [Test] + public void TestRulesetConsumed() + { + AddUntilStep("ruleset correct", () => Game.Ruleset.Value.ShortName == "mania"); + } + } +} diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsScreen.cs index e52f823f0b..63bd7c8068 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsScreen.cs @@ -2,8 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; -using osu.Framework.Allocation; -using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Playlists { @@ -12,9 +10,6 @@ namespace osu.Game.Tests.Visual.Playlists { protected override bool UseOnlineAPI => true; - [Cached] - private MusicController musicController { get; set; } = new MusicController(); - public TestScenePlaylistsScreen() { var multi = new Screens.OnlinePlay.Playlists.Playlists(); diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 0f5bea10e8..0298c3bea9 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -409,7 +409,7 @@ namespace osu.Game.Tests.Visual.SongSelect set.Beatmaps.ForEach(b => b.Metadata.Artist = zzz_string); if (i == 16) - set.Beatmaps.ForEach(b => b.Metadata.AuthorString = zzz_string); + set.Beatmaps.ForEach(b => b.Metadata.Author.Username = zzz_string); sets.Add(set); } diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs index 9ad5242df4..efacc395f1 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs @@ -208,7 +208,7 @@ namespace osu.Game.Tests.Visual.SongSelect { Metadata = new BeatmapMetadata { - AuthorString = $"{ruleset.ShortName}Author", + Author = { Username = $"{ruleset.ShortName}Author" }, Artist = $"{ruleset.ShortName}Artist", Source = $"{ruleset.ShortName}Source", Title = $"{ruleset.ShortName}Title" @@ -230,7 +230,7 @@ namespace osu.Game.Tests.Visual.SongSelect { Metadata = new BeatmapMetadata { - AuthorString = "WWWWWWWWWWWWWWW", + Author = { Username = "WWWWWWWWWWWWWWW" }, Artist = "Verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long Artist", Source = "Verrrrry long Source", Title = "Verrrrry long Title" diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index c64ef918e3..3b115d43e5 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs b/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs index db019f9242..65753bfe00 100644 --- a/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs @@ -35,9 +35,9 @@ namespace osu.Game.Tournament.Tests.NonVisual public class TestTournament : TournamentGameBase { - [BackgroundDependencyLoader] - private void load() + protected override void LoadComplete() { + base.LoadComplete(); Ruleset.Value = new RulesetInfo(); // not available } } diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index fb09a7be1e..130fcfaca1 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -7,7 +7,7 @@ - + WinExe diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index ccecd69d21..a9eb7da5c9 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps { Artist = @"Unknown", Title = @"Unknown", - AuthorString = @"Unknown Creator", + Author = { Username = @"Unknown Creator" }, }, DifficultyName = @"Normal", BaseDifficulty = Difficulty, diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index b0e10c2c38..9ad9e9b1c9 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -64,6 +64,7 @@ namespace osu.Game.Beatmaps [Ignored] public RealmNamedFileUsage? File => BeatmapSet?.Files.FirstOrDefault(f => f.File.Hash == Hash); + [Ignored] public BeatmapOnlineStatus Status { get => (BeatmapOnlineStatus)StatusInt; diff --git a/osu.Game/Beatmaps/BeatmapMetadata.cs b/osu.Game/Beatmaps/BeatmapMetadata.cs index 6349476550..a3385e3abe 100644 --- a/osu.Game/Beatmaps/BeatmapMetadata.cs +++ b/osu.Game/Beatmaps/BeatmapMetadata.cs @@ -45,16 +45,6 @@ namespace osu.Game.Beatmaps IUser IBeatmapMetadataInfo.Author => Author; - #region Compatibility properties - - public string AuthorString - { - get => Author.Username; - set => Author.Username = value; - } - - #endregion - public override string ToString() => this.GetDisplayTitle(); } } diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index f6ca184ea3..a934d1a2e3 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -32,6 +32,7 @@ namespace osu.Game.Beatmaps public IList Files { get; } = null!; + [Ignored] public BeatmapOnlineStatus Status { get => (BeatmapOnlineStatus)StatusInt; diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index e5db9d045a..893eb8ab78 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -251,7 +251,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"Creator": - metadata.AuthorString = pair.Value; + metadata.Author.Username = pair.Value; break; case @"Version": diff --git a/osu.Game/Database/DatabaseContextFactory.cs b/osu.Game/Database/DatabaseContextFactory.cs index cc690a9fda..635c4373cd 100644 --- a/osu.Game/Database/DatabaseContextFactory.cs +++ b/osu.Game/Database/DatabaseContextFactory.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Threading; using Microsoft.EntityFrameworkCore.Storage; +using osu.Framework.Development; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Framework.Statistics; @@ -146,11 +147,15 @@ namespace osu.Game.Database Database = { AutoTransactionsEnabled = false } }; - public void CreateBackup(string filename) + public void CreateBackup(string backupFilename) { - Logger.Log($"Creating full EF database backup at {filename}", LoggingTarget.Database); + Logger.Log($"Creating full EF database backup at {backupFilename}", LoggingTarget.Database); + + if (DebugUtils.IsDebugBuild) + Logger.Log("Your development database has been fully migrated to realm. If you switch back to a pre-realm branch and need your previous database, rename the backup file back to \"client.db\".\n\nNote that doing this can potentially leave your file store in a bad state.", level: LogLevel.Important); + using (var source = storage.GetStream(DATABASE_NAME)) - using (var destination = storage.GetStream(filename, FileAccess.Write, FileMode.CreateNew)) + using (var destination = storage.GetStream(backupFilename, FileAccess.Write, FileMode.CreateNew)) source.CopyTo(destination); } diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index 1a8b312c6c..1de6c25070 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -23,6 +23,8 @@ namespace osu.Game.Database private readonly RealmContextFactory realmContextFactory; private readonly OsuConfigManager config; + private bool hasTakenBackup; + public EFToRealmMigrator(DatabaseContextFactory efContextFactory, RealmContextFactory realmContextFactory, OsuConfigManager config) { this.efContextFactory = efContextFactory; @@ -33,16 +35,12 @@ namespace osu.Game.Database public void Run() { using (var ef = efContextFactory.GetForWrite()) + { migrateSettings(ef); - - using (var ef = efContextFactory.GetForWrite()) migrateSkins(ef); - - using (var ef = efContextFactory.GetForWrite()) migrateBeatmaps(ef); - - using (var ef = efContextFactory.GetForWrite()) migrateScores(ef); + } // Delete the database permanently. // Will cause future startups to not attempt migration. @@ -74,19 +72,25 @@ namespace osu.Game.Database using (var realm = realmContextFactory.CreateContext()) { Logger.Log($"Found {count} beatmaps in EF", LoggingTarget.Database); - string migration = $"before_beatmap_migration_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}"; - efContextFactory.CreateBackup($"client.{migration}.db"); + + if (!hasTakenBackup) + { + string migration = $"before_beatmap_migration_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}"; + + efContextFactory.CreateBackup($"client.{migration}.db"); + realmContextFactory.CreateBackup($"client.{migration}.realm"); + + hasTakenBackup = true; + } // only migrate data if the realm database is empty. - // note that this cannot be written as: `realm.All().All(s => s.Protected)`, because realm does not support `.All()`. + // note that this cannot be written as: `realm.All().All(s => s.Protected)`, because realm does not support `.All()`. if (realm.All().Any(s => !s.Protected)) { Logger.Log("Skipping migration as realm already has beatmaps loaded", LoggingTarget.Database); } else { - realmContextFactory.CreateBackup($"client.{migration}.realm"); - using (var transaction = realm.BeginWrite()) { foreach (var beatmapSet in existingBeatmapSets) @@ -144,10 +148,9 @@ namespace osu.Game.Database } transaction.Commit(); + Logger.Log($"Successfully migrated {count} beatmaps to realm", LoggingTarget.Database); } } - - Logger.Log($"Successfully migrated {count} beatmaps to realm", LoggingTarget.Database); } } @@ -171,7 +174,6 @@ namespace osu.Game.Database PreviewTime = metadata.PreviewTime, AudioFile = metadata.AudioFile, BackgroundFile = metadata.BackgroundFile, - AuthorString = metadata.AuthorString, }; } @@ -198,19 +200,24 @@ namespace osu.Game.Database using (var realm = realmContextFactory.CreateContext()) { Logger.Log($"Found {count} scores in EF", LoggingTarget.Database); - string migration = $"before_score_migration_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}"; - efContextFactory.CreateBackup($"client.{migration}.db"); + + if (!hasTakenBackup) + { + string migration = $"before_score_migration_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}"; + + efContextFactory.CreateBackup($"client.{migration}.db"); + realmContextFactory.CreateBackup($"client.{migration}.realm"); + + hasTakenBackup = true; + } // only migrate data if the realm database is empty. - // note that this cannot be written as: `realm.All().All(s => s.Protected)`, because realm does not support `.All()`. if (realm.All().Any()) { Logger.Log("Skipping migration as realm already has scores loaded", LoggingTarget.Database); } else { - realmContextFactory.CreateBackup($"client.{migration}.realm"); - using (var transaction = realm.BeginWrite()) { foreach (var score in existingScores) @@ -247,10 +254,9 @@ namespace osu.Game.Database } transaction.Commit(); + Logger.Log($"Successfully migrated {count} scores to realm", LoggingTarget.Database); } } - - Logger.Log($"Successfully migrated {count} scores to realm", LoggingTarget.Database); } } diff --git a/osu.Game/Database/RealmContextFactory.cs b/osu.Game/Database/RealmContextFactory.cs index 10c2438df9..8be8eab567 100644 --- a/osu.Game/Database/RealmContextFactory.cs +++ b/osu.Game/Database/RealmContextFactory.cs @@ -361,13 +361,13 @@ namespace osu.Game.Database private string? getRulesetShortNameFromLegacyID(long rulesetId) => efContextFactory?.Get().RulesetInfo.FirstOrDefault(r => r.ID == rulesetId)?.ShortName; - public void CreateBackup(string filename) + public void CreateBackup(string backupFilename) { using (BlockAllOperations()) { - Logger.Log($"Creating full realm database backup at {filename}", LoggingTarget.Database); + Logger.Log($"Creating full realm database backup at {backupFilename}", LoggingTarget.Database); using (var source = storage.GetStream(Filename)) - using (var destination = storage.GetStream(filename, FileAccess.Write, FileMode.CreateNew)) + using (var destination = storage.GetStream(backupFilename, FileAccess.Write, FileMode.CreateNew)) source.CopyTo(destination); } } diff --git a/osu.Game/Graphics/UserInterface/OsuNumberBox.cs b/osu.Game/Graphics/UserInterface/OsuNumberBox.cs index 3d565a4464..8a3b77d3c2 100644 --- a/osu.Game/Graphics/UserInterface/OsuNumberBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuNumberBox.cs @@ -7,6 +7,8 @@ namespace osu.Game.Graphics.UserInterface { public class OsuNumberBox : OsuTextBox { + protected override bool AllowIme => false; + protected override bool CanAddCharacter(char character) => character.IsAsciiDigit(); } } diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index 8e82f4a7c1..b276159558 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -29,6 +29,10 @@ namespace osu.Game.Graphics.UserInterface protected override bool AllowClipboardExport => false; + protected override bool AllowWordNavigation => false; + + protected override bool AllowIme => false; + private readonly CapsWarning warning; [Resolved] diff --git a/osu.Game/Input/Bindings/RealmKeyBinding.cs b/osu.Game/Input/Bindings/RealmKeyBinding.cs index 6a408847fe..32813ada16 100644 --- a/osu.Game/Input/Bindings/RealmKeyBinding.cs +++ b/osu.Game/Input/Bindings/RealmKeyBinding.cs @@ -20,12 +20,14 @@ namespace osu.Game.Input.Bindings public int? Variant { get; set; } + [Ignored] public KeyCombination KeyCombination { get => KeyCombinationString; set => KeyCombinationString = value.ToString(); } + [Ignored] public object Action { get => ActionInt; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 18b22588a6..b24fdf2bfe 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -301,6 +301,7 @@ namespace osu.Game dependencies.CacheAs(MusicController); Ruleset.BindValueChanged(onRulesetChanged); + Beatmap.BindValueChanged(onBeatmapChanged); } protected virtual void InitialiseFonts() @@ -421,8 +422,17 @@ namespace osu.Game protected override Storage CreateStorage(GameHost host, Storage defaultStorage) => new OsuStorage(host, defaultStorage); + private void onBeatmapChanged(ValueChangedEvent valueChangedEvent) + { + if (IsLoaded && !ThreadSafety.IsUpdateThread) + throw new InvalidOperationException("Global beatmap bindable must be changed from update thread."); + } + private void onRulesetChanged(ValueChangedEvent r) { + if (IsLoaded && !ThreadSafety.IsUpdateThread) + throw new InvalidOperationException("Global ruleset bindable must be changed from update thread."); + Ruleset instance = null; try diff --git a/osu.Game/Overlays/Settings/SettingsNumberBox.cs b/osu.Game/Overlays/Settings/SettingsNumberBox.cs index cc4446033a..d931c53e73 100644 --- a/osu.Game/Overlays/Settings/SettingsNumberBox.cs +++ b/osu.Game/Overlays/Settings/SettingsNumberBox.cs @@ -68,6 +68,8 @@ namespace osu.Game.Overlays.Settings private class OutlinedNumberBox : OutlinedTextBox { + protected override bool AllowIme => false; + protected override bool CanAddCharacter(char character) => character.IsAsciiDigit(); public new void NotifyInputError() => base.NotifyInputError(); diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index e1328d8a06..b268e2cd91 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -104,6 +104,7 @@ namespace osu.Game.Scoring } } + [Ignored] public ScoreRank Rank { get => (ScoreRank)RankInt; diff --git a/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs b/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs index ee9d86029e..c39b4d6f41 100644 --- a/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs +++ b/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs @@ -13,6 +13,8 @@ namespace osu.Game.Screens.Edit.Setup private class RomanisedTextBox : OsuTextBox { + protected override bool AllowIme => false; + protected override bool CanAddCharacter(char character) => MetadataUtils.IsRomanised(character); } diff --git a/osu.Game/Screens/Edit/Setup/MetadataSection.cs b/osu.Game/Screens/Edit/Setup/MetadataSection.cs index 0d2b093a2e..f0ca3e1bbc 100644 --- a/osu.Game/Screens/Edit/Setup/MetadataSection.cs +++ b/osu.Game/Screens/Edit/Setup/MetadataSection.cs @@ -110,7 +110,7 @@ namespace osu.Game.Screens.Edit.Setup Beatmap.Metadata.TitleUnicode = TitleTextBox.Current.Value; Beatmap.Metadata.Title = RomanisedTitleTextBox.Current.Value; - Beatmap.Metadata.AuthorString = creatorTextBox.Current.Value; + Beatmap.Metadata.Author.Username = creatorTextBox.Current.Value; Beatmap.BeatmapInfo.DifficultyName = difficultyTextBox.Current.Value; Beatmap.Metadata.Source = sourceTextBox.Current.Value; Beatmap.Metadata.Tags = tagsTextBox.Current.Value; diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index c2e9892735..66ab427565 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -35,9 +35,9 @@ namespace osu.Game.Tests.Visual return dependencies; } - [BackgroundDependencyLoader] - private void load() + protected override void LoadComplete() { + base.LoadComplete(); Beatmap.BindValueChanged(beatmapChanged, true); } diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs index 570e4c26b3..6cc009514d 100644 --- a/osu.Game/Tests/Visual/EditorTestScene.cs +++ b/osu.Game/Tests/Visual/EditorTestScene.cs @@ -42,17 +42,27 @@ namespace osu.Game.Tests.Visual Alpha = 0 }; + private TestBeatmapManager testBeatmapManager; + private WorkingBeatmap working; + [BackgroundDependencyLoader] private void load(GameHost host, AudioManager audio, RulesetStore rulesets) { Add(logo); - var working = CreateWorkingBeatmap(Ruleset.Value); - - Beatmap.Value = working; + working = CreateWorkingBeatmap(Ruleset.Value); if (IsolateSavingFromDatabase) - Dependencies.CacheAs(new TestBeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default, working)); + Dependencies.CacheAs(testBeatmapManager = new TestBeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default)); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Beatmap.Value = working; + if (testBeatmapManager != null) + testBeatmapManager.TestBeatmap = working; } protected virtual bool EditorComponentsReady => Editor.ChildrenOfType().FirstOrDefault()?.IsLoaded == true @@ -114,12 +124,11 @@ namespace osu.Game.Tests.Visual private class TestBeatmapManager : BeatmapManager { - private readonly WorkingBeatmap testBeatmap; + public WorkingBeatmap TestBeatmap; - public TestBeatmapManager(Storage storage, RealmContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, IResourceStore resources, GameHost host, WorkingBeatmap defaultBeatmap, WorkingBeatmap testBeatmap) + public TestBeatmapManager(Storage storage, RealmContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, IResourceStore resources, GameHost host, WorkingBeatmap defaultBeatmap) : base(storage, contextFactory, rulesets, api, audioManager, resources, host, defaultBeatmap) { - this.testBeatmap = testBeatmap; } protected override BeatmapModelManager CreateBeatmapModelManager(Storage storage, RealmContextFactory contextFactory, RulesetStore rulesets, BeatmapOnlineLookupQueue onlineLookupQueue) @@ -143,7 +152,7 @@ namespace osu.Game.Tests.Visual } public override WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo) - => testBeatmapManager.testBeatmap; + => testBeatmapManager.TestBeatmap; } internal class TestBeatmapModelManager : BeatmapModelManager diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 4af8ec3a99..da8af49158 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -28,7 +28,6 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; -using osu.Game.Screens; using osu.Game.Storyboards; using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Rulesets; @@ -38,13 +37,16 @@ namespace osu.Game.Tests.Visual [ExcludeFromDynamicCompile] public abstract class OsuTestScene : TestScene { - protected Bindable Beatmap { get; private set; } + [Cached] + protected Bindable Beatmap { get; } = new Bindable(); - protected Bindable Ruleset; + [Cached] + protected Bindable Ruleset { get; } = new Bindable(); - protected Bindable> SelectedMods; + [Cached] + protected Bindable> SelectedMods { get; } = new Bindable>(Array.Empty()); - protected new OsuScreenDependencies Dependencies { get; private set; } + protected new DependencyContainer Dependencies { get; private set; } protected IResourceStore Resources; @@ -132,17 +134,15 @@ namespace osu.Game.Tests.Visual var providedRuleset = CreateRuleset(); if (providedRuleset != null) - baseDependencies = rulesetDependencies = new DrawableRulesetDependencies(providedRuleset, baseDependencies); + isolatedBaseDependencies = rulesetDependencies = new DrawableRulesetDependencies(providedRuleset, baseDependencies); - Dependencies = new OsuScreenDependencies(false, baseDependencies); + Dependencies = isolatedBaseDependencies; - Beatmap = Dependencies.Beatmap; + Beatmap.Default = parent.Get>().Default; Beatmap.SetDefault(); - Ruleset = Dependencies.Ruleset; - Ruleset.SetDefault(); + Ruleset.Value = CreateRuleset()?.RulesetInfo ?? parent.Get().AvailableRulesets.First(); - SelectedMods = Dependencies.Mods; SelectedMods.SetDefault(); if (!UseOnlineAPI) @@ -155,6 +155,23 @@ namespace osu.Game.Tests.Visual return Dependencies; } + protected override void LoadComplete() + { + base.LoadComplete(); + + var parentBeatmap = Parent.Dependencies.Get>(); + parentBeatmap.Value = Beatmap.Value; + Beatmap.BindTo(parentBeatmap); + + var parentRuleset = Parent.Dependencies.Get>(); + parentRuleset.Value = Ruleset.Value; + Ruleset.BindTo(parentRuleset); + + var parentMods = Parent.Dependencies.Get>>(); + parentMods.Value = SelectedMods.Value; + SelectedMods.BindTo(parentMods); + } + protected override Container Content => content ?? base.Content; private readonly Container content; @@ -279,12 +296,6 @@ namespace osu.Game.Tests.Visual protected virtual WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, Clock, Audio); - [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) - { - Ruleset.Value = CreateRuleset()?.RulesetInfo ?? rulesets.AvailableRulesets.First(); - } - protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing);