From e4644203f8ab42073fc2382baf2efd840c6978fe Mon Sep 17 00:00:00 2001 From: Usagirei Date: Thu, 1 Mar 2018 11:41:47 -0300 Subject: [PATCH 1/6] Change patcher output directory to Game Root --- BepInEx.Patcher/BepInEx.Patcher.csproj | 2 +- BepInEx.Patcher/Program.cs | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/BepInEx.Patcher/BepInEx.Patcher.csproj b/BepInEx.Patcher/BepInEx.Patcher.csproj index 9f3272b..d2d0ef2 100644 --- a/BepInEx.Patcher/BepInEx.Patcher.csproj +++ b/BepInEx.Patcher/BepInEx.Patcher.csproj @@ -18,7 +18,7 @@ true full false - K:\KoikatuTrial_Data\Managed\ + K:\ DEBUG;TRACE prompt 4 diff --git a/BepInEx.Patcher/Program.cs b/BepInEx.Patcher/Program.cs index db20afc..021e531 100644 --- a/BepInEx.Patcher/Program.cs +++ b/BepInEx.Patcher/Program.cs @@ -59,20 +59,27 @@ namespace BepInEx.Patcher static void InjectAssembly(AssemblyDefinition unity, AssemblyDefinition injected) { //Entry point - var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader").Methods.First(x => x.Name == "Initialize"); + var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader") + .Methods.First(x => x.Name == "Initialize"); var injectMethod = unity.MainModule.Import(originalInjectMethod); - var sceneManager = unity.MainModule.Types.First(x => x.Name == "SceneManager"); + var sceneManager = unity.MainModule.Types.First(x => x.Name == "Application"); - ILProcessor IL; + var voidType = unity.MainModule.Import(typeof(void)); + var cctor = new MethodDefinition(".cctor", + Mono.Cecil.MethodAttributes.Static + | Mono.Cecil.MethodAttributes.Private + | Mono.Cecil.MethodAttributes.HideBySig + | Mono.Cecil.MethodAttributes.SpecialName + | Mono.Cecil.MethodAttributes.RTSpecialName, + voidType); - foreach (var loadScene in sceneManager.Methods.Where(x => x.Name == "LoadScene")) - { - IL = loadScene.Body.GetILProcessor(); + var ilp = cctor.Body.GetILProcessor(); + ilp.Append(ilp.Create(OpCodes.Call, injectMethod)); + ilp.Append(ilp.Create(OpCodes.Ret)); - IL.InsertBefore(loadScene.Body.Instructions[0], IL.Create(OpCodes.Call, injectMethod)); - } + sceneManager.Methods.Add(cctor); } } } From bbe165db87ce47e436f6902811cd1858a4415ccf Mon Sep 17 00:00:00 2001 From: Usagirei Date: Thu, 1 Mar 2018 11:42:30 -0300 Subject: [PATCH 2/6] Revert "Change patcher output directory to Game Root" This reverts commit e4644203f8ab42073fc2382baf2efd840c6978fe. --- BepInEx.Patcher/BepInEx.Patcher.csproj | 2 +- BepInEx.Patcher/Program.cs | 23 ++++++++--------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/BepInEx.Patcher/BepInEx.Patcher.csproj b/BepInEx.Patcher/BepInEx.Patcher.csproj index d2d0ef2..9f3272b 100644 --- a/BepInEx.Patcher/BepInEx.Patcher.csproj +++ b/BepInEx.Patcher/BepInEx.Patcher.csproj @@ -18,7 +18,7 @@ true full false - K:\ + K:\KoikatuTrial_Data\Managed\ DEBUG;TRACE prompt 4 diff --git a/BepInEx.Patcher/Program.cs b/BepInEx.Patcher/Program.cs index 021e531..db20afc 100644 --- a/BepInEx.Patcher/Program.cs +++ b/BepInEx.Patcher/Program.cs @@ -59,27 +59,20 @@ namespace BepInEx.Patcher static void InjectAssembly(AssemblyDefinition unity, AssemblyDefinition injected) { //Entry point - var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader") - .Methods.First(x => x.Name == "Initialize"); + var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader").Methods.First(x => x.Name == "Initialize"); var injectMethod = unity.MainModule.Import(originalInjectMethod); - var sceneManager = unity.MainModule.Types.First(x => x.Name == "Application"); + var sceneManager = unity.MainModule.Types.First(x => x.Name == "SceneManager"); - var voidType = unity.MainModule.Import(typeof(void)); - var cctor = new MethodDefinition(".cctor", - Mono.Cecil.MethodAttributes.Static - | Mono.Cecil.MethodAttributes.Private - | Mono.Cecil.MethodAttributes.HideBySig - | Mono.Cecil.MethodAttributes.SpecialName - | Mono.Cecil.MethodAttributes.RTSpecialName, - voidType); + ILProcessor IL; - var ilp = cctor.Body.GetILProcessor(); - ilp.Append(ilp.Create(OpCodes.Call, injectMethod)); - ilp.Append(ilp.Create(OpCodes.Ret)); + foreach (var loadScene in sceneManager.Methods.Where(x => x.Name == "LoadScene")) + { + IL = loadScene.Body.GetILProcessor(); - sceneManager.Methods.Add(cctor); + IL.InsertBefore(loadScene.Body.Instructions[0], IL.Create(OpCodes.Call, injectMethod)); + } } } } From 1b636d66fc1938bc96e70411963d1642c503bfba Mon Sep 17 00:00:00 2001 From: Usagirei Date: Thu, 1 Mar 2018 11:49:27 -0300 Subject: [PATCH 3/6] Change loader entrypoint to an earlier one --- BepInEx.Patcher/Program.cs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/BepInEx.Patcher/Program.cs b/BepInEx.Patcher/Program.cs index db20afc..021e531 100644 --- a/BepInEx.Patcher/Program.cs +++ b/BepInEx.Patcher/Program.cs @@ -59,20 +59,27 @@ namespace BepInEx.Patcher static void InjectAssembly(AssemblyDefinition unity, AssemblyDefinition injected) { //Entry point - var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader").Methods.First(x => x.Name == "Initialize"); + var originalInjectMethod = injected.MainModule.Types.First(x => x.Name == "Chainloader") + .Methods.First(x => x.Name == "Initialize"); var injectMethod = unity.MainModule.Import(originalInjectMethod); - var sceneManager = unity.MainModule.Types.First(x => x.Name == "SceneManager"); + var sceneManager = unity.MainModule.Types.First(x => x.Name == "Application"); - ILProcessor IL; + var voidType = unity.MainModule.Import(typeof(void)); + var cctor = new MethodDefinition(".cctor", + Mono.Cecil.MethodAttributes.Static + | Mono.Cecil.MethodAttributes.Private + | Mono.Cecil.MethodAttributes.HideBySig + | Mono.Cecil.MethodAttributes.SpecialName + | Mono.Cecil.MethodAttributes.RTSpecialName, + voidType); - foreach (var loadScene in sceneManager.Methods.Where(x => x.Name == "LoadScene")) - { - IL = loadScene.Body.GetILProcessor(); + var ilp = cctor.Body.GetILProcessor(); + ilp.Append(ilp.Create(OpCodes.Call, injectMethod)); + ilp.Append(ilp.Create(OpCodes.Ret)); - IL.InsertBefore(loadScene.Body.Instructions[0], IL.Create(OpCodes.Call, injectMethod)); - } + sceneManager.Methods.Add(cctor); } } } From 3cb5a9a0b5a17f36b195ec4e2994ef7d7169c90f Mon Sep 17 00:00:00 2001 From: Usagirei Date: Thu, 1 Mar 2018 11:50:12 -0300 Subject: [PATCH 4/6] Set patcher output directory to game root --- BepInEx.Patcher/BepInEx.Patcher.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BepInEx.Patcher/BepInEx.Patcher.csproj b/BepInEx.Patcher/BepInEx.Patcher.csproj index 9f3272b..d2d0ef2 100644 --- a/BepInEx.Patcher/BepInEx.Patcher.csproj +++ b/BepInEx.Patcher/BepInEx.Patcher.csproj @@ -18,7 +18,7 @@ true full false - K:\KoikatuTrial_Data\Managed\ + K:\ DEBUG;TRACE prompt 4 From 5f9a7738bcbf6a09731148fba6543f54b5cdc4b0 Mon Sep 17 00:00:00 2001 From: Usagirei Date: Thu, 1 Mar 2018 11:52:04 -0300 Subject: [PATCH 5/6] Wrap ResourceRedirector Hooks in Try-Catch Blocks --- Plugins/ResourceRedirector/Hooks.cs | 78 ++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/Plugins/ResourceRedirector/Hooks.cs b/Plugins/ResourceRedirector/Hooks.cs index 0abe733..cafea41 100644 --- a/Plugins/ResourceRedirector/Hooks.cs +++ b/Plugins/ResourceRedirector/Hooks.cs @@ -47,46 +47,86 @@ namespace ResourceRedirector public static void LoadAssetPostHook(ref AssetBundleLoadAssetOperation __result, string assetBundleName, string assetName, Type type, string manifestAssetBundleName) { - //BepInLogger.Log($"{assetBundleName} : {assetName} : {type.FullName} : {manifestAssetBundleName ?? ""}"); + try + { + //BepInLogger.Log($"{assetBundleName} : {assetName} : {type.FullName} : {manifestAssetBundleName ?? ""}"); - __result = ResourceRedirector.HandleAsset(assetBundleName, assetName, type, manifestAssetBundleName, ref __result); + __result = ResourceRedirector.HandleAsset(assetBundleName, assetName, type, manifestAssetBundleName, ref __result); + } + catch (Exception ex) + { + Console.WriteLine("---" + nameof(LoadAssetPostHook) + "---"); + Console.WriteLine(ex.Message); + Console.WriteLine(ex.StackTrace); + Console.WriteLine("---"); + } } public static void LoadAssetBundlePostHook(string assetBundleName, bool isAsync, string manifestAssetBundleName) { - //BepInLogger.Log($"{assetBundleName} : {manifestAssetBundleName} : {isAsync}"); + try + { + //BepInLogger.Log($"{assetBundleName} : {manifestAssetBundleName} : {isAsync}"); + } + catch (Exception ex) + { + Console.WriteLine("---" + nameof(LoadAssetBundlePostHook) + "---"); + Console.WriteLine(ex.Message); + Console.WriteLine(ex.StackTrace); + Console.WriteLine("---"); + } } public static void LoadAssetAsyncPostHook(ref AssetBundleLoadAssetOperation __result, string assetBundleName, string assetName, Type type, string manifestAssetBundleName) { - //BepInLogger.Log($"{assetBundleName} : {assetName} : {type.FullName} : {manifestAssetBundleName ?? ""}", true); + try + { + //BepInLogger.Log($"{assetBundleName} : {assetName} : {type.FullName} : {manifestAssetBundleName ?? ""}", true); - __result = ResourceRedirector.HandleAsset(assetBundleName, assetName, type, manifestAssetBundleName, ref __result); + __result = ResourceRedirector.HandleAsset(assetBundleName, assetName, type, manifestAssetBundleName, ref __result); + } + catch (Exception ex) + { + Console.WriteLine("---" + nameof(LoadAssetAsyncPostHook) + "---"); + Console.WriteLine(ex.Message); + Console.WriteLine(ex.StackTrace); + Console.WriteLine("---"); + } } public static void LoadAllAssetPostHook(ref AssetBundleLoadAssetOperation __result, string assetBundleName, Type type, string manifestAssetBundleName = null) { - //BepInLogger.Log($"{assetBundleName} : {type.FullName} : {manifestAssetBundleName ?? ""}"); - - if (assetBundleName == "sound/data/systemse/brandcall/00.unity3d" || - assetBundleName == "sound/data/systemse/titlecall/00.unity3d") + try { - string dir = $"{BepInEx.Common.Utility.PluginsDirectory}\\introclips"; + //BepInLogger.Log($"{assetBundleName} : {type.FullName} : {manifestAssetBundleName ?? ""}"); - if (!Directory.Exists(dir)) - Directory.CreateDirectory(dir); + if (assetBundleName == "sound/data/systemse/brandcall/00.unity3d" || + assetBundleName == "sound/data/systemse/titlecall/00.unity3d") + { + string dir = $"{BepInEx.Common.Utility.PluginsDirectory}\\introclips"; - var files = Directory.GetFiles(dir, "*.wav"); + if (!Directory.Exists(dir)) + Directory.CreateDirectory(dir); - if (files.Length == 0) - return; + var files = Directory.GetFiles(dir, "*.wav"); - List loadedClips = new List(); + if (files.Length == 0) + return; - foreach (string path in files) - loadedClips.Add(AssetLoader.LoadAudioClip(path, AudioType.WAV)); + List loadedClips = new List(); - __result = new AssetBundleLoadAssetOperationSimulation(loadedClips.ToArray()); + foreach (string path in files) + loadedClips.Add(AssetLoader.LoadAudioClip(path, AudioType.WAV)); + + __result = new AssetBundleLoadAssetOperationSimulation(loadedClips.ToArray()); + } + } + catch (Exception ex) + { + Console.WriteLine("---" + nameof(LoadAllAssetPostHook) + "---"); + Console.WriteLine(ex.Message); + Console.WriteLine(ex.StackTrace); + Console.WriteLine("---"); } } } From b982e360ce4da5e3fba3a0dc2564ecd542fe7cef Mon Sep 17 00:00:00 2001 From: Usagirei Date: Thu, 1 Mar 2018 23:06:21 -0300 Subject: [PATCH 6/6] Config class minor changes --- BepInEx/Config.cs | 125 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 97 insertions(+), 28 deletions(-) diff --git a/BepInEx/Config.cs b/BepInEx/Config.cs index 444e42c..0b620a0 100644 --- a/BepInEx/Config.cs +++ b/BepInEx/Config.cs @@ -1,7 +1,8 @@ using BepInEx.Common; +using System; using System.Collections.Generic; using System.IO; -using System.Linq; +using System.Text.RegularExpressions; namespace BepInEx { @@ -14,6 +15,17 @@ namespace BepInEx private static string configPath => Path.Combine(Utility.PluginsDirectory, "config.ini"); + private static Regex sanitizeKeyRegex = new Regex("[^a-zA-Z0-9]+"); + + private static void RaiseConfigReloaded() + { + var handler = ConfigReloaded; + if (handler != null) + handler.Invoke(); + } + + public static event Action ConfigReloaded; + /// /// If enabled, writes the config to disk every time a value is set. /// @@ -30,6 +42,31 @@ namespace BepInEx SaveConfig(); } } + + /// + /// Returns the value of the key if found, otherwise returns the default value. + /// + /// The key to search for. + /// The default value to return if the key is not found. + /// The value of the key. + public static string GetEntry(string key, string defaultValue = "", string section = "") + { + key = Sanitize(key); + if (section.IsNullOrWhiteSpace()) + section = "Global"; + else + section = Sanitize(section); + + Dictionary subdict; + + if (!cache.TryGetValue(section, out subdict)) + return defaultValue; + + if (subdict.TryGetValue(key, out string value)) + return value; + else + return defaultValue; + } /// /// Reloads the config from disk. Unwritten changes are lost. @@ -44,10 +81,10 @@ namespace BepInEx { string line = rawLine.Trim(); - int commentIndex = line.IndexOf("//"); + bool commentIndex = line.StartsWith("//"); - if (commentIndex != -1) //trim comment - line = line.Remove(commentIndex); + if (commentIndex) //trim comment + continue; if (line.StartsWith("[") && line.EndsWith("]")) //section { @@ -64,6 +101,8 @@ namespace BepInEx cache[currentSection][split[0]] = split[1]; } + + RaiseConfigReloaded(); } /// @@ -83,29 +122,6 @@ namespace BepInEx } } - /// - /// Returns the value of the key if found, otherwise returns the default value. - /// - /// The key to search for. - /// The default value to return if the key is not found. - /// The value of the key. - public static string GetEntry(string key, string defaultValue = "", string section = "") - { - if (section.IsNullOrWhiteSpace()) - section = "Global"; - - Dictionary subdict; - - if (!cache.TryGetValue(section, out subdict)) - return defaultValue; - - - if (subdict.TryGetValue(key, out string value)) - return value; - else - return defaultValue; - } - /// /// Sets the value of the key in the config. /// @@ -113,8 +129,11 @@ namespace BepInEx /// The value to set. public static void SetEntry(string key, string value, string section = "") { + key = Sanitize(key); if (section.IsNullOrWhiteSpace()) section = "Global"; + else + section = Sanitize(section); Dictionary subdict; @@ -129,8 +148,53 @@ namespace BepInEx if (SaveOnConfigSet) SaveConfig(); } + + /// + /// Returns wether a value is currently set. + /// + /// The key to check against + /// The section to check in + /// True if the key is present + public static bool HasEntry(string key, string section = "") + { + key = Sanitize(key); + if (section.IsNullOrWhiteSpace()) + section = "Global"; + else + section = Sanitize(section); + + return cache.ContainsKey(section) && cache[section].ContainsKey(key); + } + + + /// + /// Removes a value from the config. + /// + /// The key to remove + /// The section to remove from + /// True if the key was removed + public static bool UnsetEntry(string key, string section = "") + { + key = Sanitize(key); + if (section.IsNullOrWhiteSpace()) + section = "Global"; + else + section = Sanitize(section); + + if (!HasEntry(key, section)) + return false; + + cache[section].Remove(key); + return true; + } + + public static string Sanitize(string key) + { + return sanitizeKeyRegex.Replace(key, "_"); + } #region Extensions + public static string GetEntry(this BaseUnityPlugin plugin, string key, string defaultValue = "") { return GetEntry(key, defaultValue, plugin.ID); @@ -140,6 +204,11 @@ namespace BepInEx { SetEntry(key, value, plugin.ID); } - #endregion + + public static bool HasEntry(this BaseUnityPlugin plugin, string key) + { + return HasEntry(key, plugin.ID); + } + #endregion Extensions } }