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);
}
}
}
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
}
}