Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of StartupAccelerator v1.0.3
patchers/StartupAccelerator.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Preloader; using HarmonyLib; using HarmonyLib.Public.Patching; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("StartupAccelerator")] [assembly: AssemblyDescription("https://valheim.thunderstore.io/package/Smoothbrain/StartupAccelerator")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("StartupAccelerator")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("962424CE-1773-46A0-A340-36A173D2DF0C")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace StartupAccelerator { public static class StartupAccelerator { private enum Toggle { On, Off } [HarmonyPatch] private static class Patch_Preloader_PatchEntrypoint { private static readonly MethodInfo ChainloaderFinishedCallInstructionAdder = AccessTools.DeclaredMethod(typeof(Patch_Preloader_PatchEntrypoint), "AddChainloaderFinishedCall", (Type[])null, (Type[])null); private static readonly MethodInfo ChainloaderStart = AccessTools.DeclaredMethod(typeof(Patch_Preloader_PatchEntrypoint), "PreChainloader", (Type[])null, (Type[])null); private static readonly MethodInfo ILInstructionInserter = AccessTools.DeclaredMethod(typeof(ILProcessor), "InsertBefore", (Type[])null, (Type[])null); private static bool patched = false; private static IEnumerable<MethodInfo> TargetMethods() { return new MethodInfo[1] { AccessTools.DeclaredMethod(typeof(EnvVars).Assembly.GetType("BepInEx.Preloader.Preloader"), "PatchEntrypoint", (Type[])null, (Type[])null) }; } private static void AddChainloaderFinishedCall(ILProcessor ilProcessor, Instruction instruction, AssemblyDefinition assembly) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ilProcessor.InsertBefore(instruction, ilProcessor.Create(OpCodes.Call, assembly.MainModule.ImportReference((MethodBase)ChainloaderStart))); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { bool foundInitMethod = false; foreach (CodeInstruction instruction in instructions) { yield return instruction; if (instruction.opcode == OpCodes.Ldloc_S && instruction.operand is LocalBuilder localBuilder && localBuilder.LocalIndex == 6) { foundInitMethod = true; } else if (foundInitMethod && CodeInstructionExtensions.Calls(instruction, ILInstructionInserter)) { yield return new CodeInstruction(OpCodes.Ldloc_S, (object)11); yield return new CodeInstruction(OpCodes.Ldloc_S, (object)12); yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null); yield return new CodeInstruction(OpCodes.Ldind_Ref, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)ChainloaderFinishedCallInstructionAdder); } } } private static void PreChainloader() { if (!patched) { patched = true; if (delayedPatcher.Value == Toggle.On) { delayedPatcherHarmony.PatchAll(typeof(InterceptChainloader)); } if (unifiedLocalization.Value == Toggle.On) { harmony.PatchAll(typeof(InterceptLocalization)); harmony.PatchAll(typeof(InterceptLanguageLoad)); } if (optimizeConfigSave.Value == Toggle.On) { harmony.PatchAll(typeof(DelayConfigSave)); harmony.PatchAll(typeof(ChangeConfigSaveBack)); harmony.PatchAll(typeof(SkipManuallyChangedSaveOnConfigSet)); } } } } [HarmonyPatch] private static class InterceptLocalization { private static readonly Dictionary<string, Dictionary<string, string>> localizationCache = new Dictionary<string, Dictionary<string, string>>(); private static readonly HashSet<MethodBase> alreadyAppliedEnglishLoadCSV = new HashSet<MethodBase>(); private static MethodInfo TargetMethod() { return AccessTools.DeclaredMethod(Type.GetType("Localization, assembly_guiutils"), "SetupLanguage", (Type[])null, (Type[])null); } [HarmonyPriority(0)] private static bool Prefix(object __instance, string language, ref Dictionary<string, string> ___m_translations, ref bool __result) { if (localizationCache.TryGetValue(language, out Dictionary<string, string> value)) { ___m_translations = value; if (language == "English" && (string)AccessTools.DeclaredMethod(Type.GetType("UnityEngine.PlayerPrefs, UnityEngine.CoreModule"), "GetString", new Type[2] { typeof(string), typeof(string) }, (Type[])null).Invoke(null, new object[2] { "language", "English" }) != "English") { Patch[] postfixes = PatchManager.ToPatchInfo((MethodBase)AccessTools.DeclaredMethod(Type.GetType("Localization, assembly_guiutils"), "LoadCSV", (Type[])null, (Type[])null)).postfixes; foreach (Patch val in postfixes) { if (alreadyAppliedEnglishLoadCSV.Contains(val.PatchMethod)) { continue; } ParameterInfo[] parameters = val.PatchMethod.GetParameters(); object[] array = new object[parameters.Length]; int num = 0; ParameterInfo[] array2 = parameters; foreach (ParameterInfo parameterInfo in array2) { if (parameterInfo.Name == "__instance") { array[num] = __instance; } else if (parameterInfo.Name == "language") { array[num] = language; } else if (parameterInfo.Name == "__result") { array[num] = true; } else if (parameterInfo.Name.StartsWith("___")) { array[num] = AccessTools.Field(__instance.GetType(), parameterInfo.Name.Substring(3)).GetValue(__instance); } num++; } val.PatchMethod.Invoke(null, array); alreadyAppliedEnglishLoadCSV.Add(val.PatchMethod); } } __result = true; return false; } if (language != "English") { ___m_translations = new Dictionary<string, string>(___m_translations); } return true; } [HarmonyPriority(0)] private static void Postfix(string language, Dictionary<string, string> ___m_translations, bool __result) { if (__result) { localizationCache[language] = ___m_translations; } } } [HarmonyPatch] private static class InterceptLanguageLoad { private static MethodInfo TargetMethod() { return AccessTools.DeclaredMethod(Type.GetType("Localization, assembly_guiutils"), "LoadLanguages", (Type[])null, (Type[])null); } [HarmonyPriority(0)] private static bool Prefix(ref List<string> __result) { Type type = Type.GetType("Localization, assembly_guiutils"); object value = AccessTools.DeclaredField(type, "m_instance").GetValue(null); if (value != null) { __result = (List<string>)AccessTools.DeclaredMethod(type, "GetLanguages", (Type[])null, (Type[])null).Invoke(value, Array.Empty<object>()); return false; } return true; } } [HarmonyPatch] private static class InterceptChainloader { private static bool postChainloader = false; private static bool doNotSkipUpdate = false; private static readonly HashSet<MethodBase> methods = new HashSet<MethodBase>(); private static readonly MethodInfo patchSkip = AccessTools.DeclaredMethod(typeof(InterceptChainloader), "SkipUpdates", (Type[])null, (Type[])null); private static readonly MethodInfo addReplacementOriginal = AccessTools.DeclaredMethod(typeof(PatchManager), "AddReplacementOriginal", (Type[])null, (Type[])null); private static MethodInfo TargetMethod() { return postChainloader ? AccessTools.DeclaredMethod(Type.GetType("FejdStartup, assembly_valheim"), "Awake", (Type[])null, (Type[])null) : AccessTools.DeclaredMethod(typeof(Chainloader), "Start", (Type[])null, (Type[])null); } private static bool SkipUpdates(MethodBase original, ref MethodInfo? __result) { if (!doNotSkipUpdate) { Type declaringType = original.DeclaringType; if ((object)declaringType == null || !passthroughClasses.Contains(declaringType.FullName)) { methods.Add(original); __result = null; return false; } } return true; } [HarmonyPriority(800)] public static void Prefix() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown doNotSkipUpdate = false; delayedPatcherHarmony.Patch((MethodBase)harmonyPatcher, new HarmonyMethod(patchSkip), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } [HarmonyPriority(0)] public static void Postfix() { doNotSkipUpdate = true; string arg; if (postChainloader) { delayedPatcherHarmony.UnpatchSelf(); arg = "after FejdStartup.Awake"; } else { delayedPatcherHarmony.Unpatch((MethodBase)TargetMethod(), (HarmonyPatchType)0, delayedPatcherHarmony.Id); postChainloader = true; delayedPatcherHarmony.PatchAll(typeof(InterceptChainloader)); arg = "after Chainloader end"; } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); lock (AccessTools.DeclaredField(typeof(PatchProcessor), "locker").GetValue(null)) { foreach (MethodBase method in methods) { object obj = harmonyPatcher.Invoke(null, new object[2] { method, PatchManager.ToPatchInfo(method) }); addReplacementOriginal.Invoke(null, new object[2] { method, obj }); } } logger.LogInfo((object)$"Batch-patched {methods.Count} methods {arg} in {stopwatch.ElapsedMilliseconds} ms"); methods.Clear(); } } [HarmonyPatch] private static class DelayConfigSave { private static MethodBase TargetMethod() { return AccessTools.DeclaredConstructor(typeof(ConfigFile), new Type[3] { typeof(string), typeof(bool), typeof(BepInPlugin) }, false); } private static void Postfix(ConfigFile __instance) { __instance.SaveOnConfigSet = false; changedConfigFiles.Add(__instance); } } [HarmonyPatch] private static class ChangeConfigSaveBack { private static MethodInfo TargetMethod() { return AccessTools.DeclaredMethod(Type.GetType("FejdStartup, assembly_valheim"), "Awake", (Type[])null, (Type[])null); } private static void Prefix() { List<ConfigFile> changedConfigFiles = StartupAccelerator.changedConfigFiles; StartupAccelerator.changedConfigFiles = new List<ConfigFile>(); foreach (ConfigFile item in changedConfigFiles) { item.Save(); item.SaveOnConfigSet = true; } } } [HarmonyPatch] private static class SkipManuallyChangedSaveOnConfigSet { private static MethodBase TargetMethod() { return AccessTools.DeclaredPropertySetter(typeof(ConfigFile), "SaveOnConfigSet"); } private static void Prefix(ConfigFile __instance) { if (changedConfigFiles.Remove(__instance)) { __instance.Save(); } } } private const string CONFIG_FILE_NAME = "StartupAccelerator.cfg"; private static readonly ConfigFile Config = new ConfigFile(Path.Combine(Paths.ConfigPath, "StartupAccelerator.cfg"), true); private static readonly ManualLogSource logger = Logger.CreateLogSource("StartupAccelerator"); private static readonly Harmony delayedPatcherHarmony = new Harmony("org.bepinex.patchers.startupaccelerator.delayed_patcher"); private static readonly Harmony harmony = new Harmony("org.bepinex.patchers.startupaccelerator"); private static readonly MethodInfo harmonyPatcher = AccessTools.DeclaredMethod(typeof(Harmony).Assembly.GetType("HarmonyLib.PatchFunctions"), "UpdateWrapper", (Type[])null, (Type[])null); private static readonly string[] hardcodedPassthrough = new string[4] { typeof(Assembly).FullName, "BepInEx.Preloader.RuntimeFixes.HarmonyInteropFix", "BepInEx.PluginInfo", typeof(Enum).FullName }; private static HashSet<string> passthroughClasses = new HashSet<string>(); private static readonly ConfigEntry<Toggle> delayedPatcher = Config.Bind<Toggle>("General", "Delay Patching", Toggle.On, new ConfigDescription("Delay Harmony patching until after Chainloader and after FejdStartup.Awake respectively.", (AcceptableValueBase)null, Array.Empty<object>())); private static readonly ConfigEntry<Toggle> unifiedLocalization = Config.Bind<Toggle>("General", "Merge Localization Data", Toggle.On, new ConfigDescription("Merge localization data to avoid re-reading it over and over.", (AcceptableValueBase)null, Array.Empty<object>())); private static readonly ConfigEntry<Toggle> optimizeConfigSave = Config.Bind<Toggle>("General", "Delay Config Save", Toggle.On, new ConfigDescription("Delay config save so that it saves the config once after start up and not over and over again.", (AcceptableValueBase)null, Array.Empty<object>())); private static List<ConfigFile> changedConfigFiles = new List<ConfigFile>(); public static IEnumerable<string> TargetDLLs { get; } = Array.Empty<string>(); public static void Patch(AssemblyDefinition assembly) { } public static void Initialize() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown ConfigEntry<string> passthrough = Config.Bind<string>("General", "Passthrough Patched Classes", "", new ConfigDescription("Comma-separated list of classes to unconditionally patch immediately.", (AcceptableValueBase)null, Array.Empty<object>())); passthrough.SettingChanged += delegate { calcPassthrough(); }; calcPassthrough(); harmony.PatchAll(typeof(Patch_Preloader_PatchEntrypoint)); void calcPassthrough() { HashSet<string> hashSet = new HashSet<string>(); foreach (string item in hardcodedPassthrough.Concat((unifiedLocalization.Value != 0) ? ((IEnumerable<string>)Array.Empty<string>()) : ((IEnumerable<string>)new string[1] { "Localization" })).Concat(passthrough.Value.Split(new char[1] { ',' }))) { hashSet.Add(item); } passthroughClasses = hashSet; } } } }