From 4382adad8240fee9c85f1b5cb21efea70c011184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Jan 2022 23:20:33 +0100 Subject: [PATCH 01/12] Add test coverage for editor changes not resetting after exit without save --- .../Visual/Editing/TestSceneEditorSaving.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs index 58daab1ce2..adaa24d542 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs @@ -4,11 +4,13 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Screens; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Compose.Components.Timeline; +using osu.Game.Screens.Select; using osuTK.Input; namespace osu.Game.Tests.Visual.Editing @@ -116,5 +118,24 @@ namespace osu.Game.Tests.Visual.Editing EditorBeatmap.HitObjects[0].SampleControlPoint != SampleControlPoint.DEFAULT && EditorBeatmap.HitObjects[0].DifficultyControlPoint != DifficultyControlPoint.DEFAULT); } + + [Test] + public void TestExitWithoutSaveFromExistingBeatmap() + { + const string tags_to_save = "these tags will be saved"; + const string tags_to_discard = "these tags should be discarded"; + + AddStep("Set tags", () => EditorBeatmap.BeatmapInfo.Metadata.Tags = tags_to_save); + SaveEditor(); + AddAssert("Tags saved correctly", () => EditorBeatmap.BeatmapInfo.Metadata.Tags == tags_to_save); + + ReloadEditorToSameBeatmap(); + AddAssert("Tags saved correctly", () => EditorBeatmap.BeatmapInfo.Metadata.Tags == tags_to_save); + AddStep("Set tags again", () => EditorBeatmap.BeatmapInfo.Metadata.Tags = tags_to_discard); + + AddStep("Exit editor", () => Editor.Exit()); + AddUntilStep("Wait for song select", () => Game.ScreenStack.CurrentScreen is PlaySongSelect); + AddAssert("Tags reverted correctly", () => Game.Beatmap.Value.BeatmapInfo.Metadata.Tags == tags_to_save); + } } } From d760283665b6ecadcdee4989ded6e7684387dd41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Jan 2022 23:31:42 +0100 Subject: [PATCH 02/12] Ensure edited beatmap is restored to a baseline state on exit --- osu.Game/Screens/Edit/Editor.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index b42f629aad..e26453f99a 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -574,7 +574,9 @@ namespace osu.Game.Screens.Edit // To update the game-wide beatmap with any changes, perform a re-fetch on exit/suspend. // This is required as the editor makes its local changes via EditorBeatmap // (which are not propagated outwards to a potentially cached WorkingBeatmap). - var refetchedBeatmap = beatmapManager.GetWorkingBeatmap(Beatmap.Value.BeatmapInfo); + ((IWorkingBeatmapCache)beatmapManager).Invalidate(Beatmap.Value.BeatmapInfo); + var refetchedBeatmapInfo = beatmapManager.QueryBeatmap(b => b.ID == Beatmap.Value.BeatmapInfo.ID); + var refetchedBeatmap = beatmapManager.GetWorkingBeatmap(refetchedBeatmapInfo); if (!(refetchedBeatmap is DummyWorkingBeatmap)) { From e0616476e2a0a772c5998b0194d8a0dab0ad0eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Jan 2022 20:52:14 +0100 Subject: [PATCH 03/12] Fix test gameplay tests failing due to beatmap refetch on suspend --- .../Visual/Editing/TestSceneEditorTestGameplay.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs index 79afc8cf27..e2406a8d27 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs @@ -70,7 +70,11 @@ namespace osu.Game.Tests.Visual.Editing AddUntilStep("current screen is editor", () => Stack.CurrentScreen is Editor); AddUntilStep("background has correct params", () => { - var background = this.ChildrenOfType().Single(); + // the test gameplay player's beatmap may be the "same" beatmap as the one being edited, *but* the `BeatmapInfo` references may differ + // due to the beatmap refetch logic ran on editor suspend. + // this test cares about checking the background belonging to the editor specifically, so check that using reference equality + // (as `.Equals()` cannot discern between the two, as they technically share the same database GUID). + var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo)); return background.Colour == Color4.DarkGray && background.BlurAmount.Value == 0; }); AddAssert("no mods selected", () => SelectedMods.Value.Count == 0); @@ -99,7 +103,11 @@ namespace osu.Game.Tests.Visual.Editing AddUntilStep("current screen is editor", () => Stack.CurrentScreen is Editor); AddUntilStep("background has correct params", () => { - var background = this.ChildrenOfType().Single(); + // the test gameplay player's beatmap may be the "same" beatmap as the one being edited, *but* the `BeatmapInfo` references may differ + // due to the beatmap refetch logic ran on editor suspend. + // this test cares about checking the background belonging to the editor specifically, so check that using reference equality + // (as `.Equals()` cannot discern between the two, as they technically share the same database GUID). + var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo)); return background.Colour == Color4.DarkGray && background.BlurAmount.Value == 0; }); From deb5d75b5f21078d0877fd1ce5b75468fc896e3d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jan 2022 14:33:44 +0900 Subject: [PATCH 04/12] Change migration process to always delete old EF database It is already backed up, so this is probably fine. --- osu.Game/Database/EFToRealmMigrator.cs | 44 +++++++++++++++++++++----- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index 96baad35ec..072d1c95f1 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -15,6 +15,8 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Models; +using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; using osu.Game.Rulesets; using osu.Game.Scoring; using osu.Game.Skinning; @@ -40,6 +42,12 @@ namespace osu.Game.Database [Resolved] private OsuConfigManager config { get; set; } = null!; + [Resolved] + private NotificationOverlay notificationOverlay { get; set; } = null!; + + [Resolved] + private OsuGame game { get; set; } = null!; + private readonly OsuSpriteText currentOperationText; public EFToRealmMigrator() @@ -96,7 +104,11 @@ namespace osu.Game.Database protected override void LoadComplete() { base.LoadComplete(); + beginMigration(); + } + private void beginMigration() + { Task.Factory.StartNew(() => { using (var ef = efContextFactory.Get()) @@ -117,21 +129,37 @@ namespace osu.Game.Database migrateBeatmaps(ef); migrateScores(ef); } - - // Delete the database permanently. - // Will cause future startups to not attempt migration. - log("Migration successful, deleting EF database"); - efContextFactory.ResetDatabase(); - - 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); }, TaskCreationOptions.LongRunning).ContinueWith(t => { + if (t.Exception == null) + { + log("Migration successful!"); + + 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); + } + else + { + log("Migration failed!"); + Logger.Log(t.Exception.ToString(), LoggingTarget.Database); + } + + // Regardless of success, since the game is going to continue with startup let's move the ef database out of the way. + // If we were to not do this, the migration would run another time the next time the user starts the game. + deletePreRealmData(); + migrationCompleted.SetResult(true); efContextFactory.SetMigrationCompletion(); }); } + private void deletePreRealmData() + { + // Delete the database permanently. + // Will cause future startups to not attempt migration. + efContextFactory.ResetDatabase(); + } + private void log(string message) { Logger.Log(message, LoggingTarget.Database); From b745252962b232e3bc3173491ab37495f302a56d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jan 2022 14:34:18 +0900 Subject: [PATCH 05/12] Show notification when migration fails to give users a recovery path --- osu.Game/Database/EFToRealmMigrator.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index 072d1c95f1..d110ac2f9f 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -142,6 +142,16 @@ namespace osu.Game.Database { log("Migration failed!"); Logger.Log(t.Exception.ToString(), LoggingTarget.Database); + + notificationOverlay.Post(new SimpleErrorNotification + { + Text = "IMPORTANT: During data migration, some of your data could not be successfully migrated. It has been backed up in your osu! folder.\n\nFor further assistance, please open a discussion on github and attach your backup files (click to get started).", + Activated = () => + { + game.OpenUrlExternally(@"https://github.com/ppy/osu/discussions/new?title=Realm%20migration%20issue&body=Please%20attach%20your%20database%20backups%20by%20zipping%20them%20and%20dragging%20in%20here!&category=q-a"); + return true; + } + }); } // Regardless of success, since the game is going to continue with startup let's move the ef database out of the way. From 08948f60f3108ccfaf098be3ebe99a69ffe61c93 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jan 2022 14:39:07 +0900 Subject: [PATCH 06/12] Move backups to "backups" subfolder to make them easier to find --- osu.Game/OsuGameBase.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 09ca4e450d..8363c41437 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -202,16 +202,18 @@ namespace osu.Game // See https://github.com/ppy/osu/pull/16547 for more discussion. if (EFContextFactory != null) { + const string backup_folder = "backups"; + string migration = $"before_final_migration_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}"; - EFContextFactory.CreateBackup($"client.{migration}.db"); - realm.CreateBackup($"client.{migration}.realm"); + EFContextFactory.CreateBackup(Path.Combine(backup_folder, $"client.{migration}.db")); + realm.CreateBackup(Path.Combine(backup_folder, $"client.{migration}.realm")); using (var source = Storage.GetStream("collection.db")) { if (source != null) { - using (var destination = Storage.GetStream($"collection.{migration}.db", FileAccess.Write, FileMode.CreateNew)) + using (var destination = Storage.GetStream(Path.Combine(backup_folder, $"collection.{migration}.db"), FileAccess.Write, FileMode.CreateNew)) source.CopyTo(destination); } } From 31abb372e5c2ac123decc43f88aa8d68b5d3c2ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jan 2022 14:52:43 +0900 Subject: [PATCH 07/12] Automatically zip and show the backup archive to the user --- osu.Game/Database/EFToRealmMigrator.cs | 29 ++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index d110ac2f9f..c41461cc68 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; @@ -9,6 +10,7 @@ using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Logging; +using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; @@ -22,6 +24,10 @@ using osu.Game.Scoring; using osu.Game.Skinning; using osuTK; using Realms; +using SharpCompress.Archives; +using SharpCompress.Archives.Zip; +using SharpCompress.Common; +using SharpCompress.Writers.Zip; #nullable enable @@ -48,6 +54,9 @@ namespace osu.Game.Database [Resolved] private OsuGame game { get; set; } = null!; + [Resolved] + private Storage storage { get; set; } = null!; + private readonly OsuSpriteText currentOperationText; public EFToRealmMigrator() @@ -145,10 +154,26 @@ namespace osu.Game.Database notificationOverlay.Post(new SimpleErrorNotification { - Text = "IMPORTANT: During data migration, some of your data could not be successfully migrated. It has been backed up in your osu! folder.\n\nFor further assistance, please open a discussion on github and attach your backup files (click to get started).", + Text = "IMPORTANT: During data migration, some of your data could not be successfully migrated. The previous version has been backed up.\n\nFor further assistance, please open a discussion on github and attach your backup files (click to get started).", Activated = () => { - game.OpenUrlExternally(@"https://github.com/ppy/osu/discussions/new?title=Realm%20migration%20issue&body=Please%20attach%20your%20database%20backups%20by%20zipping%20them%20and%20dragging%20in%20here!&category=q-a"); + game.OpenUrlExternally(@"https://github.com/ppy/osu/discussions/new?title=Realm%20migration%20issue&body=Please%20drag%20the%20""attach_me.zip""%20file%20here!&category=q-a"); + + const string attachment_filename = "attach_me.zip"; + const string backup_folder = "backups"; + + var backupStorage = storage.GetStorageForDirectory(backup_folder); + + backupStorage.Delete(attachment_filename); + + using (var zip = ZipArchive.Create()) + { + zip.AddAllFromDirectory(backupStorage.GetFullPath(string.Empty)); + zip.SaveTo(Path.Combine(backupStorage.GetFullPath(string.Empty), attachment_filename), new ZipWriterOptions(CompressionType.Deflate)); + } + + backupStorage.PresentFileExternally(attachment_filename); + return true; } }); From 465e7d29feb9529dbde477bcf384bf8ef94b2949 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jan 2022 14:53:11 +0900 Subject: [PATCH 08/12] Avoid showing the external link warning --- osu.Game/Database/EFToRealmMigrator.cs | 2 +- osu.Game/Online/Chat/ExternalLinkOpener.cs | 4 ++-- osu.Game/OsuGame.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index c41461cc68..05bc86a7c0 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -157,7 +157,7 @@ namespace osu.Game.Database Text = "IMPORTANT: During data migration, some of your data could not be successfully migrated. The previous version has been backed up.\n\nFor further assistance, please open a discussion on github and attach your backup files (click to get started).", Activated = () => { - game.OpenUrlExternally(@"https://github.com/ppy/osu/discussions/new?title=Realm%20migration%20issue&body=Please%20drag%20the%20""attach_me.zip""%20file%20here!&category=q-a"); + game.OpenUrlExternally(@"https://github.com/ppy/osu/discussions/new?title=Realm%20migration%20issue&body=Please%20drag%20the%20""attach_me.zip""%20file%20here!&category=q-a", true); const string attachment_filename = "attach_me.zip"; const string backup_folder = "backups"; diff --git a/osu.Game/Online/Chat/ExternalLinkOpener.cs b/osu.Game/Online/Chat/ExternalLinkOpener.cs index 8407e2ca6a..328b43c4e8 100644 --- a/osu.Game/Online/Chat/ExternalLinkOpener.cs +++ b/osu.Game/Online/Chat/ExternalLinkOpener.cs @@ -27,9 +27,9 @@ namespace osu.Game.Online.Chat externalLinkWarning = config.GetBindable(OsuSetting.ExternalLinkWarning); } - public void OpenUrlExternally(string url) + public void OpenUrlExternally(string url, bool bypassWarning = false) { - if (externalLinkWarning.Value) + if (!bypassWarning && externalLinkWarning.Value) dialogOverlay.Push(new ExternalLinkDialog(url, () => host.OpenUrlExternally(url))); else host.OpenUrlExternally(url); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index c2e1b25d94..5b58dec0c3 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -357,12 +357,12 @@ namespace osu.Game } }); - public void OpenUrlExternally(string url) => waitForReady(() => externalLinkOpener, _ => + public void OpenUrlExternally(string url, bool bypassExternalUrlWarning = false) => waitForReady(() => externalLinkOpener, _ => { if (url.StartsWith('/')) url = $"{API.APIEndpointUrl}{url}"; - externalLinkOpener.OpenUrlExternally(url); + externalLinkOpener.OpenUrlExternally(url, bypassExternalUrlWarning); }); /// From fb081384e13ca4a09bee571636021ea0ce894dc2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jan 2022 14:55:52 +0900 Subject: [PATCH 09/12] Add safety against zip creation potentially failing (probably can't but still) --- osu.Game/Database/EFToRealmMigrator.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index 05bc86a7c0..723b3eeada 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -166,11 +166,15 @@ namespace osu.Game.Database backupStorage.Delete(attachment_filename); - using (var zip = ZipArchive.Create()) + try { - zip.AddAllFromDirectory(backupStorage.GetFullPath(string.Empty)); - zip.SaveTo(Path.Combine(backupStorage.GetFullPath(string.Empty), attachment_filename), new ZipWriterOptions(CompressionType.Deflate)); + using (var zip = ZipArchive.Create()) + { + zip.AddAllFromDirectory(backupStorage.GetFullPath(string.Empty)); + zip.SaveTo(Path.Combine(backupStorage.GetFullPath(string.Empty), attachment_filename), new ZipWriterOptions(CompressionType.Deflate)); + } } + catch { } backupStorage.PresentFileExternally(attachment_filename); From 67ccb879926f309f3b2d3dbd3bc31a2a8760b05e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jan 2022 14:56:04 +0900 Subject: [PATCH 10/12] Add exception message to discussion template url --- osu.Game/Database/EFToRealmMigrator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/EFToRealmMigrator.cs b/osu.Game/Database/EFToRealmMigrator.cs index 723b3eeada..639bf10e19 100644 --- a/osu.Game/Database/EFToRealmMigrator.cs +++ b/osu.Game/Database/EFToRealmMigrator.cs @@ -157,7 +157,7 @@ namespace osu.Game.Database Text = "IMPORTANT: During data migration, some of your data could not be successfully migrated. The previous version has been backed up.\n\nFor further assistance, please open a discussion on github and attach your backup files (click to get started).", Activated = () => { - game.OpenUrlExternally(@"https://github.com/ppy/osu/discussions/new?title=Realm%20migration%20issue&body=Please%20drag%20the%20""attach_me.zip""%20file%20here!&category=q-a", true); + game.OpenUrlExternally($@"https://github.com/ppy/osu/discussions/new?title=Realm%20migration%20issue ({t.Exception.Message})&body=Please%20drag%20the%20""attach_me.zip""%20file%20here!&category=q-a", true); const string attachment_filename = "attach_me.zip"; const string backup_folder = "backups"; From e67b1fe0ec9c50b7ddb429edb2ee13d534e881ad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jan 2022 15:25:56 +0900 Subject: [PATCH 11/12] Make `Ruleset.RulesetInfo` get only --- osu.Game/Rulesets/Ruleset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index d279f6d6ee..616540b59c 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets [ExcludeFromDynamicCompile] public abstract class Ruleset { - public RulesetInfo RulesetInfo { get; internal set; } + public RulesetInfo RulesetInfo { get; } private static readonly ConcurrentDictionary mod_reference_cache = new ConcurrentDictionary(); From 714177cce13a86d3665d1685831da3a1e30c7382 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Jan 2022 15:23:16 +0900 Subject: [PATCH 12/12] Remove pointless constructor in `RulesetInfo` --- osu.Game.Tests/Database/RealmTest.cs | 2 +- osu.Game/Rulesets/RulesetInfo.cs | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game.Tests/Database/RealmTest.cs b/osu.Game.Tests/Database/RealmTest.cs index c2339dd9ad..838759c991 100644 --- a/osu.Game.Tests/Database/RealmTest.cs +++ b/osu.Game.Tests/Database/RealmTest.cs @@ -114,7 +114,7 @@ namespace osu.Game.Tests.Database } protected static RulesetInfo CreateRuleset() => - new RulesetInfo(0, "osu!", "osu", true); + new RulesetInfo("osu", "osu!", string.Empty, 0) { Available = true }; private class RealmTestGame : Framework.Game { diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index 2e2ec5c024..5171f0d63c 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -37,14 +37,6 @@ namespace osu.Game.Rulesets { } - public RulesetInfo(int? onlineID, string name, string shortName, bool available) - { - OnlineID = onlineID ?? -1; - Name = name; - ShortName = shortName; - Available = available; - } - public bool Available { get; set; } public bool Equals(RulesetInfo? other)