From 2f651e6c35becfe1c0aecf1f62354788193b8141 Mon Sep 17 00:00:00 2001 From: bluepilledgreat <97983689+bluepilledgreat@users.noreply.github.com> Date: Wed, 12 Mar 2025 19:06:11 +0000 Subject: [PATCH] fix potential race condition with RobloxState --- Bloxstrap/Bootstrapper.cs | 13 +++++++++++-- Bloxstrap/JsonManager.cs | 24 ++++++++++++++++++++++-- Bloxstrap/Utility/MD5Hash.cs | 5 +++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 0319397..f2330f6 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -1259,8 +1259,17 @@ namespace Bloxstrap } } - App.RobloxState.Prop.ModManifest = modFolderFiles; - App.RobloxState.Save(); + // make sure we're not overwriting a new update + // if we're the background update process, always overwrite + if (App.LaunchSettings.BackgroundUpdaterFlag.Active || !App.RobloxState.HasFileOnDiskChanged()) + { + App.RobloxState.Prop.ModManifest = modFolderFiles; + App.RobloxState.Save(); + } + else + { + App.Logger.WriteLine(LOG_IDENT, "RobloxState disk mismatch, not saving ModManifest"); + } App.Logger.WriteLine(LOG_IDENT, $"Finished checking file mods"); diff --git a/Bloxstrap/JsonManager.cs b/Bloxstrap/JsonManager.cs index bb1eb77..6c04a2a 100644 --- a/Bloxstrap/JsonManager.cs +++ b/Bloxstrap/JsonManager.cs @@ -8,6 +8,11 @@ namespace Bloxstrap public T Prop { get; set; } = new(); + /// + /// The file hash when last retrieved from disk + /// + public string? LastFileHash { get; private set; } + public virtual string ClassName => typeof(T).Name; public virtual string FileLocation => Path.Combine(Paths.Base, $"{ClassName}.json"); @@ -22,12 +27,15 @@ namespace Bloxstrap try { - T? settings = JsonSerializer.Deserialize(File.ReadAllText(FileLocation)); + string contents = File.ReadAllText(FileLocation); + + T? settings = JsonSerializer.Deserialize(contents); if (settings is null) throw new ArgumentNullException("Deserialization returned null"); Prop = settings; + LastFileHash = MD5Hash.FromString(contents); App.Logger.WriteLine(LOG_IDENT, "Loaded successfully!"); } @@ -74,7 +82,11 @@ namespace Bloxstrap try { - File.WriteAllText(FileLocation, JsonSerializer.Serialize(Prop, new JsonSerializerOptions { WriteIndented = true })); + string contents = JsonSerializer.Serialize(Prop, new JsonSerializerOptions { WriteIndented = true }); + + File.WriteAllText(FileLocation, contents); + + LastFileHash = MD5Hash.FromString(contents); } catch (Exception ex) when (ex is IOException or UnauthorizedAccessException) { @@ -89,5 +101,13 @@ namespace Bloxstrap App.Logger.WriteLine(LOG_IDENT, "Save complete!"); } + + /// + /// Is the file on disk different to the one deserialised during this session? + /// + public bool HasFileOnDiskChanged() + { + return LastFileHash != MD5Hash.FromFile(FileLocation); + } } } diff --git a/Bloxstrap/Utility/MD5Hash.cs b/Bloxstrap/Utility/MD5Hash.cs index c282c0a..df49d44 100644 --- a/Bloxstrap/Utility/MD5Hash.cs +++ b/Bloxstrap/Utility/MD5Hash.cs @@ -25,6 +25,11 @@ namespace Bloxstrap.Utility return FromStream(stream); } + public static string FromString(string str) + { + return FromBytes(Encoding.UTF8.GetBytes(str)); + } + public static string Stringify(byte[] hash) { return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();