From d4adb8cdb61ee6d069c560b326482ee38490669c Mon Sep 17 00:00:00 2001 From: Anairkoen Schno Date: Thu, 21 Jul 2022 01:54:49 -0500 Subject: [PATCH] Fix #79 #81 using Zinga's suggestion The config now contains a ResetGameAssembliesOnVersionChange property, which, when true, sets the GameAssemblies property to its default when a verison change is detected. --- IPA.Injector/GameVersionEarly.cs | 7 +- IPA.Injector/Injector.cs | 6 +- IPA.Loader/Config/Data/Value.cs | 295 ++++++++++++------------ IPA.Loader/Config/SelfConfig.cs | 29 ++- IPA.Loader/Utilities/CriticalSection.cs | 19 +- 5 files changed, 185 insertions(+), 171 deletions(-) diff --git a/IPA.Injector/GameVersionEarly.cs b/IPA.Injector/GameVersionEarly.cs index e6e0280c..5ed1ace7 100644 --- a/IPA.Injector/GameVersionEarly.cs +++ b/IPA.Injector/GameVersionEarly.cs @@ -1,4 +1,5 @@ -using IPA.Utilities; +#nullable enable +using IPA.Utilities; using System; using System.Collections.Generic; using System.IO; @@ -48,7 +49,7 @@ namespace IPA.Injector } var rewind = -sizeof(int) - sizeof(byte); - stream.Seek(rewind, SeekOrigin.Current); // rewind to the string length + _ = stream.Seek(rewind, SeekOrigin.Current); // rewind to the string length var strlen = reader.ReadInt32(); var strbytes = reader.ReadBytes(strlen); @@ -57,7 +58,7 @@ namespace IPA.Injector } } - internal static AlmostVersion SafeParseVersion() => new AlmostVersion(GetGameVersion()); + internal static AlmostVersion SafeParseVersion() => new(GetGameVersion()); private static void _Load() { diff --git a/IPA.Injector/Injector.cs b/IPA.Injector/Injector.cs index acfbe4a2..7d338af7 100644 --- a/IPA.Injector/Injector.cs +++ b/IPA.Injector/Injector.cs @@ -80,11 +80,13 @@ namespace IPA.Injector Logging.Logger.Injector.Debug("Prepping bootstrapper"); + // make sure to load the game version and check boundaries before installing the bootstrap, because that uses the game assemblies property + GameVersionEarly.Load(); + SelfConfig.Instance.CheckVersionBoundary(); + // updates backup InstallBootstrapPatch(); - GameVersionEarly.Load(); - AntiMalwareEngine.Initialize(); Updates.InstallPendingUpdates(); diff --git a/IPA.Loader/Config/Data/Value.cs b/IPA.Loader/Config/Data/Value.cs index 0d61cebd..966f844c 100644 --- a/IPA.Loader/Config/Data/Value.cs +++ b/IPA.Loader/Config/Data/Value.cs @@ -1,151 +1,146 @@ -#nullable enable -using System; -using System.Collections; -using System.Collections.Generic; +#nullable enable +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace IPA.Config.Data -{ - /// - /// A base value type for config data abstract representations, to be serialized with an - /// . If a is , then - /// that represents just that: a null in whatever serialization is being used. - /// Also contains factory functions for all derived types. - /// - public abstract class Value - { - /// - /// Converts this into a human-readable format. - /// - /// a human-readable string containing the value provided - public abstract override string ToString(); - - /// - /// Creates a Null . - /// - /// - public static Value? Null() => null; - - /// - /// Creates an empty . - /// - /// an empty - /// - public static List List() => new(); - /// - /// Creates an empty . - /// - /// an empty - /// - /// - public static Map Map() => new(); - - /// - /// Creates a new representing a . - /// - /// the value to wrap - /// a wrapping - /// - [return: NotNullIfNotNull("val")] - public static Text? From(string? val) => Text(val); - /// - /// Creates a new object wrapping a . - /// - /// the value to wrap - /// a wrapping - /// - [return: NotNullIfNotNull("val")] - public static Text? Text(string? val) => val == null ? null : new(val); - - /// - /// Creates a new wrapping a . - /// - /// the value to wrap - /// a wrapping - /// - public static Integer From(long val) => Integer(val); - /// - /// Creates a new wrapping a . - /// - /// the value to wrap - /// a wrapping - /// - public static Integer Integer(long val) => new(val); - - /// - /// Creates a new wrapping a . - /// - /// the value to wrap - /// a wrapping - /// - public static FloatingPoint From(decimal val) => Float(val); - /// - /// Creates a new wrapping a . - /// - /// the value to wrap - /// a wrapping - /// - public static FloatingPoint Float(decimal val) => new(val); - - /// - /// Creates a new wrapping a . - /// - /// the value to wrap - /// a wrapping - /// - public static Boolean From(bool val) => Bool(val); - /// - /// Creates a new wrapping a . - /// - /// the value to wrap - /// a wrapping - /// - public static Boolean Bool(bool val) => new(val); - - /// - /// Creates a new holding the content of an - /// of . - /// - /// the s to initialize the with - /// a containing the content of - /// - [return: NotNullIfNotNull("vals")] - public static List? From(IEnumerable? vals) - { - if (vals is null) return null; - var l = List(); - l.AddRange(vals); - return l; - } - - /// - /// Creates a new holding the content of an - /// of to . - /// - /// the dictionary of s to initialize the wtih - /// a containing the content of - /// - /// - public static Map From(IDictionary vals) => From(vals as IEnumerable>); - - /// - /// Creates a new holding the content of an - /// of of to . - /// - /// the enumerable of of name to - /// a containing the content of - /// - /// - [return: NotNullIfNotNull("vals")] - public static Map? From(IEnumerable>? vals) - { - if (vals is null) return null; - var m = Map(); - foreach (var v in vals) m.Add(v.Key, v.Value); - return m; - } - } -} + +namespace IPA.Config.Data +{ + /// + /// A base value type for config data abstract representations, to be serialized with an + /// . If a is , then + /// that represents just that: a null in whatever serialization is being used. + /// Also contains factory functions for all derived types. + /// + public abstract class Value + { + /// + /// Converts this into a human-readable format. + /// + /// a human-readable string containing the value provided + public abstract override string ToString(); + + /// + /// Creates a Null . + /// + /// + public static Value? Null() => null; + + /// + /// Creates an empty . + /// + /// an empty + /// + public static List List() => new(); + /// + /// Creates an empty . + /// + /// an empty + /// + /// + public static Map Map() => new(); + + /// + /// Creates a new representing a . + /// + /// the value to wrap + /// a wrapping + /// + [return: NotNullIfNotNull("val")] + public static Text? From(string? val) => Text(val); + /// + /// Creates a new object wrapping a . + /// + /// the value to wrap + /// a wrapping + /// + [return: NotNullIfNotNull("val")] + public static Text? Text(string? val) => val == null ? null : new(val); + + /// + /// Creates a new wrapping a . + /// + /// the value to wrap + /// a wrapping + /// + public static Integer From(long val) => Integer(val); + /// + /// Creates a new wrapping a . + /// + /// the value to wrap + /// a wrapping + /// + public static Integer Integer(long val) => new(val); + + /// + /// Creates a new wrapping a . + /// + /// the value to wrap + /// a wrapping + /// + public static FloatingPoint From(decimal val) => Float(val); + /// + /// Creates a new wrapping a . + /// + /// the value to wrap + /// a wrapping + /// + public static FloatingPoint Float(decimal val) => new(val); + + /// + /// Creates a new wrapping a . + /// + /// the value to wrap + /// a wrapping + /// + public static Boolean From(bool val) => Bool(val); + /// + /// Creates a new wrapping a . + /// + /// the value to wrap + /// a wrapping + /// + public static Boolean Bool(bool val) => new(val); + + /// + /// Creates a new holding the content of an + /// of . + /// + /// the s to initialize the with + /// a containing the content of + /// + [return: NotNullIfNotNull("vals")] + public static List? From(IEnumerable? vals) + { + if (vals is null) return null; + var l = List(); + l.AddRange(vals); + return l; + } + + /// + /// Creates a new holding the content of an + /// of to . + /// + /// the dictionary of s to initialize the wtih + /// a containing the content of + /// + /// + public static Map From(IDictionary vals) => From(vals as IEnumerable>); + + /// + /// Creates a new holding the content of an + /// of of to . + /// + /// the enumerable of of name to + /// a containing the content of + /// + /// + [return: NotNullIfNotNull("vals")] + public static Map? From(IEnumerable>? vals) + { + if (vals is null) return null; + var m = Map(); + foreach (var v in vals) m.Add(v.Key, v.Value); + return m; + } + } +} diff --git a/IPA.Loader/Config/SelfConfig.cs b/IPA.Loader/Config/SelfConfig.cs index 433ac088..0bfefb92 100644 --- a/IPA.Loader/Config/SelfConfig.cs +++ b/IPA.Loader/Config/SelfConfig.cs @@ -54,7 +54,7 @@ namespace IPA.Config CommandLineValues.YeetMods = false; break; case "--no-logs": - CommandLineValues.WriteLogs = true; + CommandLineValues.WriteLogs = false; break; case "--condense-logs": CommandLineValues.Debug.CondenseModLogs = true; @@ -75,6 +75,14 @@ namespace IPA.Config } } + public void CheckVersionBoundary() + { + if (ResetGameAssebliesOnVersionChange && Utilities.UnityGame.IsGameVersionBoundary) + { + GameAssemblies = GetDefaultGameAssemblies(); + } + } + internal const string IPAName = "Beat Saber IPA"; internal const string IPAVersion = "4.2.2.0"; @@ -180,19 +188,30 @@ namespace IPA.Config [JsonIgnore] public bool WriteLogs { get; set; } = true; + public virtual bool ResetGameAssebliesOnVersionChange { get; set; } = true; + // LINE: ignore [NonNullable, UseConverter(typeof(CollectionConverter>))] - public virtual HashSet GameAssemblies { get; set; } = new HashSet + public virtual HashSet GameAssemblies { get; set; } = GetDefaultGameAssemblies(); + + // BEGIN: section ignore + public static HashSet GetDefaultGameAssemblies() + => new() { - // LINE: ignore 5 #if BeatSaber // provide these defaults only for Beat Saber builds - "Main.dll", "Core.dll", "HMLib.dll", "HMUI.dll", "HMRendering.dll", "VRUI.dll", + "Main.dll", "Core.dll", "HMLib.dll", "HMUI.dll", "HMRendering.dll", "VRUI.dll", "BeatmapCore.dll", "GameplayCore.dll","HMLibAttributes.dll", #else // otherwise specify Assembly-CSharp.dll "Assembly-CSharp.dll" - // LINE: ignore #endif }; + // END: section ignore + + // LINE: ignore +#if false // used to make schema gen happy + private static HashSet GetDefaultGameAssemblies() => null; + // LINE: ignore +#endif // LINE: ignore public static HashSet GameAssemblies_ => Instance?.GameAssemblies ?? new HashSet { "Assembly-CSharp.dll" }; diff --git a/IPA.Loader/Utilities/CriticalSection.cs b/IPA.Loader/Utilities/CriticalSection.cs index 4630f572..61d3d85d 100644 --- a/IPA.Loader/Utilities/CriticalSection.cs +++ b/IPA.Loader/Utilities/CriticalSection.cs @@ -1,9 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; +#nullable enable +using System; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; using IPA.Logging; namespace IPA.Utilities @@ -21,9 +18,9 @@ namespace IPA.Utilities ResetExitHandlers(); } - private static void Reset(object sender, EventArgs e) + private static void Reset(object? sender, EventArgs? e) { - Win32.SetConsoleCtrlHandler(registeredHandler, false); + _ = Win32.SetConsoleCtrlHandler(registeredHandler, false); WinHttp.SetPeekMessageHook(null); } @@ -32,8 +29,8 @@ namespace IPA.Utilities private static readonly Win32.ConsoleCtrlDelegate registeredHandler = HandleExit; internal static void ResetExitHandlers() { - Win32.SetConsoleCtrlHandler(registeredHandler, false); - Win32.SetConsoleCtrlHandler(registeredHandler, true); + _ = Win32.SetConsoleCtrlHandler(registeredHandler, false); + _ = Win32.SetConsoleCtrlHandler(registeredHandler, true); WinHttp.SetPeekMessageHook(PeekMessageHook); AppDomain.CurrentDomain.ProcessExit -= OnProcessExit; @@ -60,14 +57,14 @@ namespace IPA.Utilities [DllImport("bsipa-doorstop")] public static extern void SetPeekMessageHook( [MarshalAs(UnmanagedType.FunctionPtr)] - PeekMessageHook hook); + PeekMessageHook? hook); [DllImport("bsipa-doorstop")] public static extern void SetIgnoreUnhandledExceptions( [MarshalAs(UnmanagedType.Bool)] bool ignore); } - private static Win32.ConsoleCtrlDelegate _handler = null; + private static Win32.ConsoleCtrlDelegate? _handler = null; private static volatile bool isInExecuteSection = false; // returns true to continue looping and calling PeekMessage