diff --git a/osu.Game.Tournament/TournamentStorage.cs b/osu.Game.Tournament/TournamentStorage.cs index e5d19831d0..48eef76a28 100644 --- a/osu.Game.Tournament/TournamentStorage.cs +++ b/osu.Game.Tournament/TournamentStorage.cs @@ -1,10 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Linq; +using System.Threading; using osu.Framework.IO.Stores; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.IO; +using System.IO; using osu.Game.Tournament.Configuration; namespace osu.Game.Tournament @@ -32,16 +36,77 @@ public TournamentStorage(GameHost host) this.host = host; storageConfig = new TournamentStorageManager(host.Storage); - var customTournamentPath = storageConfig.Get(StorageConfig.CurrentTournament); + var currentTournament = storageConfig.Get(StorageConfig.CurrentTournament); - if (!string.IsNullOrEmpty(customTournamentPath)) + if (!string.IsNullOrEmpty(currentTournament)) { - ChangeTargetStorage(UnderlyingStorage.GetStorageForDirectory("tournaments/" + customTournamentPath)); - } else { - ChangeTargetStorage(UnderlyingStorage.GetStorageForDirectory("tournaments/default")); + ChangeTargetStorage(UnderlyingStorage.GetStorageForDirectory("tournaments" + Path.DirectorySeparatorChar + currentTournament)); } + else + { + // Migrating old storage format to the new one. + Migrate(); + Logger.Log("Migrating files from old storage to new."); + } + VideoStorage = new TournamentVideoStorage(this); Logger.Log("Using tournament storage: " + GetFullPath(string.Empty)); } + + private void Migrate() + { + var defaultPath = "tournaments/default"; + var source = new DirectoryInfo(GetFullPath("tournament")); + var destination = new DirectoryInfo(GetFullPath(defaultPath)); + + Directory.CreateDirectory(destination.FullName); + + if (host.Storage.Exists("bracket.json")) + { + Logger.Log("Migrating bracket to default tournament storage."); + var bracketFile = new System.IO.FileInfo(GetFullPath(string.Empty) + Path.DirectorySeparatorChar + GetFiles(string.Empty, "bracket.json").First()); + attemptOperation(() => bracketFile.CopyTo(Path.Combine(destination.FullName, bracketFile.Name), true)); + } + + Logger.Log("Migrating other assets to default tournament storage."); + copyRecursive(source, destination); + ChangeTargetStorage(UnderlyingStorage.GetStorageForDirectory(defaultPath)); + storageConfig.Set(StorageConfig.CurrentTournament, defaultPath); + storageConfig.Save(); + } + + private void copyRecursive(DirectoryInfo source, DirectoryInfo destination, bool topLevelExcludes = true) + { + // based off example code https://docs.microsoft.com/en-us/dotnet/api/system.io.directoryinfo + + foreach (System.IO.FileInfo fi in source.GetFiles()) + { + attemptOperation(() => fi.CopyTo(Path.Combine(destination.FullName, fi.Name), true)); + } + + foreach (DirectoryInfo dir in source.GetDirectories()) + { + copyRecursive(dir, destination.CreateSubdirectory(dir.Name), false); + } + } + + private void attemptOperation(Action action, int attempts = 10) + { + while (true) + { + try + { + action(); + return; + } + catch (Exception) + { + if (attempts-- == 0) + throw; + } + + Thread.Sleep(250); + } + } } }