Browse Source

Merge pull request #11 from usagirei/master

Change Chainloader Entrypoint to an Earlier one
Bepis 7 years ago
parent
commit
2ed166bb30
2 changed files with 112 additions and 36 deletions
  1. 15 8
      BepInEx.Patcher/Program.cs
  2. 97 28
      BepInEx/Config.cs

+ 15 - 8
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);
         }
     }
 }

+ 97 - 28
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;
+
         /// <summary>
         /// If enabled, writes the config to disk every time a value is set.
         /// </summary>
@@ -30,6 +42,31 @@ namespace BepInEx
                 SaveConfig();
             }
         }
+        
+        /// <summary>
+        /// Returns the value of the key if found, otherwise returns the default value.
+        /// </summary>
+        /// <param name="key">The key to search for.</param>
+        /// <param name="defaultValue">The default value to return if the key is not found.</param>
+        /// <returns>The value of the key.</returns>
+        public static string GetEntry(string key, string defaultValue = "", string section = "")
+        {
+            key = Sanitize(key);
+            if (section.IsNullOrWhiteSpace())
+                section = "Global";
+            else
+                section = Sanitize(section);
+
+            Dictionary<string, string> subdict;
+
+            if (!cache.TryGetValue(section, out subdict))
+                return defaultValue;
+
+            if (subdict.TryGetValue(key, out string value))
+                return value;
+            else
+                return defaultValue;
+        }
 
         /// <summary>
         /// 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();
         }
 
         /// <summary>
@@ -84,37 +123,17 @@ namespace BepInEx
         }
 
         /// <summary>
-        /// Returns the value of the key if found, otherwise returns the default value.
-        /// </summary>
-        /// <param name="key">The key to search for.</param>
-        /// <param name="defaultValue">The default value to return if the key is not found.</param>
-        /// <returns>The value of the key.</returns>
-        public static string GetEntry(string key, string defaultValue = "", string section = "")
-        {
-            if (section.IsNullOrWhiteSpace())
-                section = "Global";
-
-            Dictionary<string, string> subdict;
-
-            if (!cache.TryGetValue(section, out subdict))
-                return defaultValue;
-                
-
-            if (subdict.TryGetValue(key, out string value))
-                return value;
-            else
-                return defaultValue;
-        }
-
-        /// <summary>
         /// Sets the value of the key in the config.
         /// </summary>
         /// <param name="key">The key to set the value to.</param>
         /// <param name="value">The value to set.</param>
         public static void SetEntry(string key, string value, string section = "")
         {
+            key = Sanitize(key);
             if (section.IsNullOrWhiteSpace())
                 section = "Global";
+            else
+                section = Sanitize(section);
 
             Dictionary<string, string> subdict;
 
@@ -129,8 +148,53 @@ namespace BepInEx
             if (SaveOnConfigSet)
                 SaveConfig();
         }
+       
+        /// <summary>
+        /// Returns wether a value is currently set.
+        /// </summary>
+        /// <param name="key">The key to check against</param>
+        /// <param name="section">The section to check in</param>
+        /// <returns>True if the key is present</returns>
+        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);
+        }
+
+
+        /// <summary>
+        /// Removes a value from the config.
+        /// </summary>
+        /// <param name="key">The key to remove</param>
+        /// <param name="section">The section to remove from</param>
+        /// <returns>True if the key was removed</returns>
+        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
     }
 }