From c41ca10715d2d1b5b3dd2c71f291c3562d8e39c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Sep 2017 18:34:58 +0900 Subject: [PATCH] Allow files missing on disk to be restored on beatmap import Previously, in the rare case the database became out of sync with the disk store, it was impossible to feasibly repair a beatmap. Now reimporting checks each file exists on disk and adds it back if it doesn't. --- osu.Game/Beatmaps/BeatmapManager.cs | 9 ++++++++ osu.Game/IO/FileStore.cs | 32 ++++++++++++++--------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f58b3505c5..a1b678392b 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -429,6 +429,15 @@ namespace osu.Game.Beatmaps if (beatmapSet != null) { Undelete(beatmapSet); + + // ensure all files are present and accessible + foreach (var f in beatmapSet.Files) + { + if (!storage.Exists(f.FileInfo.StoragePath)) + using (Stream s = reader.GetStream(f.Filename)) + files.Add(s, false); + } + return beatmapSet; } diff --git a/osu.Game/IO/FileStore.cs b/osu.Game/IO/FileStore.cs index 1011fa3236..c3d8c1df46 100644 --- a/osu.Game/IO/FileStore.cs +++ b/osu.Game/IO/FileStore.cs @@ -78,33 +78,33 @@ namespace osu.Game.IO } } - public FileInfo Add(Stream data) + public FileInfo Add(Stream data, bool reference = true) { string hash = data.ComputeSHA2Hash(); var existing = Connection.Table().Where(f => f.Hash == hash).FirstOrDefault(); var info = existing ?? new FileInfo { Hash = hash }; - if (existing != null) + + string path = Path.Combine(prefix, info.StoragePath); + + // we may be re-adding a file to fix missing store entries. + if (!Storage.Exists(path)) { - info = existing; + data.Seek(0, SeekOrigin.Begin); + + using (var output = Storage.GetStream(path, FileAccess.Write)) + data.CopyTo(output); + + data.Seek(0, SeekOrigin.Begin); } - else - { - string path = Path.Combine(prefix, info.StoragePath); - - data.Seek(0, SeekOrigin.Begin); - - if (!Storage.Exists(path)) - using (var output = Storage.GetStream(path, FileAccess.Write)) - data.CopyTo(output); - - data.Seek(0, SeekOrigin.Begin); + if (existing == null) Connection.Insert(info); - } - Reference(info); + if (reference || existing == null) + Reference(info); + return info; }