From bf386598b6abe4be1758bf2b7045a26cb3208679 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Thu, 30 Nov 2017 10:58:32 +0100 Subject: [PATCH 1/8] Added a new "undelete" button that restores every beatmap with "DeletePending" set to true. --- osu.Game/Beatmaps/BeatmapManager.cs | 22 +++++++++++++++++++ .../Sections/Maintenance/GeneralSettings.cs | 14 ++++++++++++ 2 files changed, 36 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 0641cabcd8..376cbe183a 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -338,6 +338,28 @@ namespace osu.Game.Beatmaps } } + public void Undelete(BeatmapSetInfo beatmapSet) + { + lock (importContext) + { + var context = importContext.Value; + + using (var transaction = context.BeginTransaction()) + { + context.ChangeTracker.AutoDetectChangesEnabled = false; + + var iFiles = new FileStore(() => context, storage); + var iBeatmaps = createBeatmapStore(() => context); + + if (iBeatmaps.Undelete(beatmapSet)) + iFiles.Reference(beatmapSet.Files.Select(f => f.FileInfo).ToArray()); + + context.ChangeTracker.AutoDetectChangesEnabled = true; + context.SaveChanges(transaction); + } + } + } + /// /// Delete a beatmap difficulty. /// diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs index 4f4f381ae1..dcad5ab52c 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs @@ -15,6 +15,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance private TriangleButton importButton; private TriangleButton deleteButton; private TriangleButton restoreButton; + private TriangleButton undeleteButton; protected override string Header => "General"; @@ -55,6 +56,19 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance }).ContinueWith(t => Schedule(() => restoreButton.Enabled.Value = true)); } }, + undeleteButton = new SettingsButton + { + Text = "Restore all recently deleted beatmaps", + Action = () => + { + undeleteButton.Enabled.Value = false; + Task.Run(() => + { + foreach (var bs in beatmaps.QueryBeatmapSets(bs => bs.DeletePending).ToList()) + beatmaps.Undelete(bs); + }).ContinueWith(t => Schedule(() => undeleteButton.Enabled.Value = true)); + } + }, }; } } From b09ba19d3fa45a3b650014f6f7ec057d788ca5d3 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Thu, 30 Nov 2017 11:02:53 +0100 Subject: [PATCH 2/8] Used the already-existing private method to undelete a mapset --- osu.Game/Beatmaps/BeatmapManager.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 376cbe183a..cfebaf083e 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -351,8 +351,7 @@ namespace osu.Game.Beatmaps var iFiles = new FileStore(() => context, storage); var iBeatmaps = createBeatmapStore(() => context); - if (iBeatmaps.Undelete(beatmapSet)) - iFiles.Reference(beatmapSet.Files.Select(f => f.FileInfo).ToArray()); + undelete(iBeatmaps, iFiles, beatmapSet); context.ChangeTracker.AutoDetectChangesEnabled = true; context.SaveChanges(transaction); From e1c04a1f445933c1deb21b26a4bc39e190eb130c Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Fri, 8 Dec 2017 12:50:04 +0100 Subject: [PATCH 3/8] Added check for "menu music beatmap hash" before undeleting so circles.osu doesn't get imported on Undelete. Also moved the const property to BeatmapManager. --- osu.Game/Beatmaps/BeatmapManager.cs | 9 +++++++++ osu.Game/Screens/Menu/Intro.cs | 4 +--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index e00505d9b3..bc9a3bbacb 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -34,6 +34,11 @@ namespace osu.Game.Beatmaps /// public class BeatmapManager { + /// + /// The hash of the supplied menu music's beatmap set. + /// + public const string MENU_MUSIC_BEATMAP_HASH = "3c8b1fcc9434dbb29e2fb613d3b9eada9d7bb6c125ceb32396c3b53437280c83"; + /// /// Fired when a new becomes available in the database. /// @@ -341,6 +346,10 @@ namespace osu.Game.Beatmaps public void Undelete(BeatmapSetInfo beatmapSet) { + // So circles.osz doesn't get added as a map + if (beatmapSet.Hash == MENU_MUSIC_BEATMAP_HASH) + return; + lock (importContext) { var context = importContext.Value; diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index d7beb34a2f..6a6351305b 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -20,8 +20,6 @@ namespace osu.Game.Screens.Menu { public class Intro : OsuScreen { - private const string menu_music_beatmap_hash = "3c8b1fcc9434dbb29e2fb613d3b9eada9d7bb6c125ceb32396c3b53437280c83"; - /// /// Whether we have loaded the menu previously. /// @@ -58,7 +56,7 @@ namespace osu.Game.Screens.Menu if (setInfo == null) { - setInfo = beatmaps.QueryBeatmapSet(b => b.Hash == menu_music_beatmap_hash); + setInfo = beatmaps.QueryBeatmapSet(b => b.Hash == BeatmapManager.MENU_MUSIC_BEATMAP_HASH); if (setInfo == null) { From 8cbd6f32cbe8d9bbb82dd7cae8ccb6748c23b614 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Sun, 10 Dec 2017 11:31:37 +0100 Subject: [PATCH 4/8] Moved menu music hash property back to intro and changed check (before undeleting) to "Protected" field. --- osu.Game/Beatmaps/BeatmapManager.cs | 8 +------- osu.Game/Screens/Menu/Intro.cs | 4 +++- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6dba8106ae..b70f11185f 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -34,11 +34,6 @@ namespace osu.Game.Beatmaps /// public class BeatmapManager { - /// - /// The hash of the supplied menu music's beatmap set. - /// - public const string MENU_MUSIC_BEATMAP_HASH = "3c8b1fcc9434dbb29e2fb613d3b9eada9d7bb6c125ceb32396c3b53437280c83"; - /// /// Fired when a new becomes available in the database. /// @@ -346,8 +341,7 @@ namespace osu.Game.Beatmaps public void Undelete(BeatmapSetInfo beatmapSet) { - // So circles.osz doesn't get added as a map - if (beatmapSet.Hash == MENU_MUSIC_BEATMAP_HASH) + if (beatmapSet.Protected) return; lock (importContext) diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index 6a6351305b..d7beb34a2f 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -20,6 +20,8 @@ namespace osu.Game.Screens.Menu { public class Intro : OsuScreen { + private const string menu_music_beatmap_hash = "3c8b1fcc9434dbb29e2fb613d3b9eada9d7bb6c125ceb32396c3b53437280c83"; + /// /// Whether we have loaded the menu previously. /// @@ -56,7 +58,7 @@ namespace osu.Game.Screens.Menu if (setInfo == null) { - setInfo = beatmaps.QueryBeatmapSet(b => b.Hash == BeatmapManager.MENU_MUSIC_BEATMAP_HASH); + setInfo = beatmaps.QueryBeatmapSet(b => b.Hash == menu_music_beatmap_hash); if (setInfo == null) { From d2b80fdbfc9bc3e85cd32594a25b44a893cb4b27 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Mon, 18 Dec 2017 10:55:07 +0100 Subject: [PATCH 5/8] Moved "undelete all" logic to BeatmapManager and added a progress notification --- osu.Game/Beatmaps/BeatmapManager.cs | 30 +++++++++++++++++++ .../Sections/Maintenance/GeneralSettings.cs | 6 +--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 1acca352a7..8170ec959c 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -339,6 +339,36 @@ namespace osu.Game.Beatmaps } } + public void UndeleteAll() + { + var mapSets = QueryBeatmapSets(bs => bs.DeletePending); + + if (mapSets.Count() == 0) return; + + var notification = new ProgressNotification + { + Progress = 0, + State = ProgressNotificationState.Active, + }; + + PostNotification?.Invoke(notification); + + int i = 0; + + foreach (var bs in mapSets) + { + if (notification.State == ProgressNotificationState.Cancelled) + // user requested abort + return; + + notification.Text = $"Restoring ({i} of {mapSets.Count()})"; + notification.Progress = (float)++i / mapSets.Count(); + Undelete(bs); + } + + notification.State = ProgressNotificationState.Completed; + } + public void Undelete(BeatmapSetInfo beatmapSet) { if (beatmapSet.Protected) diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs index dcad5ab52c..0b0cc1a17f 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs @@ -62,11 +62,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance Action = () => { undeleteButton.Enabled.Value = false; - Task.Run(() => - { - foreach (var bs in beatmaps.QueryBeatmapSets(bs => bs.DeletePending).ToList()) - beatmaps.Undelete(bs); - }).ContinueWith(t => Schedule(() => undeleteButton.Enabled.Value = true)); + Task.Run(() => beatmaps.UndeleteAll()).ContinueWith(t => Schedule(() => undeleteButton.Enabled.Value = true)); } }, }; From ba614883ea9140de83abe64bb5031cea6c87f372 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Mon, 18 Dec 2017 11:16:57 +0100 Subject: [PATCH 6/8] used Any() instead of manually checking count == 0 (CI) --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 8170ec959c..9933606952 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -343,7 +343,7 @@ namespace osu.Game.Beatmaps { var mapSets = QueryBeatmapSets(bs => bs.DeletePending); - if (mapSets.Count() == 0) return; + if (!mapSets.Any()) return; var notification = new ProgressNotification { From e4ead365446526371a51d5d172be61db12fd05bb Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Thu, 21 Dec 2017 13:01:14 +0100 Subject: [PATCH 7/8] Added completion text --- osu.Game/Beatmaps/BeatmapManager.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index e0285e7ae0..1544d4fc01 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -349,6 +349,7 @@ namespace osu.Game.Beatmaps var notification = new ProgressNotification { + CompletionText = "Restored all deleted beatmaps!", Progress = 0, State = ProgressNotificationState.Active, }; From 620e9737c33a9d02626d4cbf8fcf579f267e3471 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 21 Dec 2017 22:33:16 +0900 Subject: [PATCH 8/8] Avoid many many unnecessary enumerations --- osu.Game/Beatmaps/BeatmapManager.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 1544d4fc01..0325785016 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -343,9 +343,9 @@ namespace osu.Game.Beatmaps public void UndeleteAll() { - var mapSets = QueryBeatmapSets(bs => bs.DeletePending); + var deleteMaps = QueryBeatmapSets(bs => bs.DeletePending).ToList(); - if (!mapSets.Any()) return; + if (!deleteMaps.Any()) return; var notification = new ProgressNotification { @@ -358,14 +358,14 @@ namespace osu.Game.Beatmaps int i = 0; - foreach (var bs in mapSets) + foreach (var bs in deleteMaps) { if (notification.State == ProgressNotificationState.Cancelled) // user requested abort return; - notification.Text = $"Restoring ({i} of {mapSets.Count()})"; - notification.Progress = (float)++i / mapSets.Count(); + notification.Text = $"Restoring ({i} of {deleteMaps.Count})"; + notification.Progress = (float)++i / deleteMaps.Count; Undelete(bs); }