diff --git a/Studio/CelesteStudio/Migration/MigrateV3_0_0.cs b/Studio/CelesteStudio/Migration/MigrateV3_0_0.cs index b2d2d363..77df209e 100644 --- a/Studio/CelesteStudio/Migration/MigrateV3_0_0.cs +++ b/Studio/CelesteStudio/Migration/MigrateV3_0_0.cs @@ -71,6 +71,8 @@ public static void PreLoad() { if (oldSettings.themes == "Light") { newDocument.Put("ThemeName", "Light"); } + + Migrator.WriteSettings(newDocument); } catch (Exception ex) { Console.Error.WriteLine($"Failed to read legacy settings file from path '{Path.Combine(Studio.CelesteDirectory, "Celeste Studio.toml")}'"); Console.Error.WriteLine(ex); diff --git a/Studio/CelesteStudio/Migration/MigrateV3_2_0.cs b/Studio/CelesteStudio/Migration/MigrateV3_2_0.cs new file mode 100644 index 00000000..79da849d --- /dev/null +++ b/Studio/CelesteStudio/Migration/MigrateV3_2_0.cs @@ -0,0 +1,26 @@ +using System.IO; +using Tomlet; + +namespace CelesteStudio.Migration; + +/// v3.2.0 Merged "bool ShowGameInfo" and "bool GameInfoPopoutOpen" into "GameInfoType GameInfo" +public static class MigrateV3_2_0 { + public static void PreLoad() { + var document = TomlParser.ParseFile(Settings.SettingsPath); + + bool showGameInfo = document.GetBoolean("ShowGameInfo"); + bool popoutOpen = document.GetBoolean("GameInfoPopoutOpen"); + + if (showGameInfo) { + if (popoutOpen) { + document.Put("GameInfo", "Popout"); + } else { + document.Put("GameInfo", "Panel"); + } + } else { + document.Put("GameInfo", "Disabled"); + } + + Migrator.WriteSettings(document); + } +} diff --git a/Studio/CelesteStudio/Migration/Migrator.cs b/Studio/CelesteStudio/Migration/Migrator.cs index d5909aeb..f9de64ae 100644 --- a/Studio/CelesteStudio/Migration/Migrator.cs +++ b/Studio/CelesteStudio/Migration/Migrator.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; +using Tomlet.Models; namespace CelesteStudio.Migration; @@ -11,12 +12,20 @@ public static class Migrator { private static string LatestVersionPath => Path.Combine(Settings.BaseConfigPath, ".latest-version"); private static readonly (Version Version, Action? PreLoad, Action? PostLoad)[] migrations = [ - (new Version(3, 0, 0), MigrateV3_0_0.PreLoad, null) + (new Version(3, 0, 0), MigrateV3_0_0.PreLoad, null), + (new Version(3, 2, 0), MigrateV3_2_0.PreLoad, null), ]; private static Version oldVersion = null!, newVersion = null!; private static readonly List<(string versionName, Stream stream)> changelogs = []; + public static void WriteSettings(TomlDocument document) { + // Write to another file and then move that over, to avoid getting interrupted while writing and corrupting the settings + var tmpFile = Settings.SettingsPath + ".tmp"; + File.WriteAllText(tmpFile, document.SerializedValue); + File.Move(tmpFile, Settings.SettingsPath, overwrite: true); + } + /// Migrates settings and other configurations from the last used to the current version /// Also shows changelog dialogs when applicable public static void ApplyPreLoadMigrations() { @@ -30,7 +39,12 @@ public static void ApplyPreLoadMigrations() { // Need to check .toml since .exe and .pdb were already deleted by CelesteTAS bool studioV2Present = File.Exists(Path.Combine(Studio.CelesteDirectory ?? string.Empty, "Celeste Studio.toml")); +#if DEBUG + // Always apply the latest migration in debug builds + newVersion = migrations[^1].Version; +#else newVersion = Assembly.GetExecutingAssembly().GetName().Version!; +#endif if (firstV3Launch) { if (studioV2Present) { oldVersion = new Version(2, 0, 0); @@ -44,7 +58,10 @@ public static void ApplyPreLoadMigrations() { File.WriteAllText(LatestVersionPath, newVersion.ToString(3)); - if (oldVersion == newVersion) { + if (oldVersion.Major == newVersion.Major && + oldVersion.Minor == newVersion.Minor && + oldVersion.Build == newVersion.Build) + { return; } diff --git a/Studio/CelesteStudio/Settings.cs b/Studio/CelesteStudio/Settings.cs index 1bd53ab5..132d0b62 100644 --- a/Studio/CelesteStudio/Settings.cs +++ b/Studio/CelesteStudio/Settings.cs @@ -157,7 +157,6 @@ public string ThemeName { public Point LastLocation { get; set; } = Point.Empty; public Size LastSize { get; set; } = new(400, 600); - public bool GameInfoPopoutOpen { get; set; } = false; public bool GameInfoPopoutTopmost { get; set; } = false; public Point GameInfoPopoutLocation { get; set; } = Point.Empty; public Size GameInfoPopoutSize { get; set; } = new(400, 250);