Browse Source

Merge branch 'feature-plugin-folder'

Bepis 6 years ago
parent
commit
53a2fd626c

+ 2 - 4
BepInEx.Preloader/Entrypoint.cs

@@ -15,16 +15,14 @@ namespace BepInEx.Preloader
 		/// </param>
 		public static void Main(string[] args)
 		{
-			// Manually set up the path for patchers to work
-			typeof(Paths).GetProperty(nameof(Paths.ExecutablePath)).SetValue(null, args[0], null);
-			//Paths.ExecutablePath = args[0];
+			Paths.ExecutablePath(args[0]);
 			AppDomain.CurrentDomain.AssemblyResolve += LocalResolve;
 
 			Preloader.Run();
 		}
 
 		/// <summary>
-		///     A handler for <see cref="AppDomain" />.AssemblyResolve to perform some special handling.
+		///     A handler for <see cref="AppDomain.AssemblyResolve" /> to perform some special handling.
 		///     <para>
 		///         It attempts to check currently loaded assemblies (ignoring the version), and then checks the BepInEx/core path,
 		///         BepInEx/patchers path and the BepInEx folder, all in that order.

+ 1 - 1
BepInEx.Preloader/Patcher/AssemblyPatcher.cs

@@ -143,7 +143,7 @@ namespace BepInEx.Preloader.Patcher
 				if (DumpingEnabled && patchedAssemblies.Contains(filename))
 					using (var mem = new MemoryStream())
 					{
-						string dirPath = Path.Combine(Paths.PluginPath, "DumpedAssemblies");
+						string dirPath = Path.Combine(Paths.BepInExRootPath, "DumpedAssemblies");
 
 						if (!Directory.Exists(dirPath))
 							Directory.CreateDirectory(dirPath);

+ 7 - 1
BepInEx/Bootstrap/Chainloader.cs

@@ -40,7 +40,9 @@ namespace BepInEx.Bootstrap
 				return;
 
 			//Set vitals
-			Paths.ExecutablePath = containerExePath;
+			Paths.SetExecutablePath(containerExePath);
+
+			Paths.SetPluginPath(Config.GetEntry("chainloader-plugins-directory", "plugins", "BepInEx"));
 
 			//Start logging
 
@@ -76,10 +78,14 @@ namespace BepInEx.Bootstrap
 			if (!Directory.Exists(Paths.PluginPath))
 				Directory.CreateDirectory(Paths.PluginPath);
 
+			if (!Directory.Exists(Paths.PatcherPluginPath))
+				Directory.CreateDirectory(Paths.PatcherPluginPath);
+
 			try
 			{
 				if (bool.Parse(Config.GetEntry("chainloader-log-unity-messages", "false", "BepInEx")))
 					UnityLogWriter.ListenUnityLogs();
+				
 
 				var productNameProp = typeof(Application).GetProperty("productName", BindingFlags.Public | BindingFlags.Static);
 				if (productNameProp != null)

+ 2 - 2
BepInEx/Bootstrap/TypeLoader.cs

@@ -15,7 +15,7 @@ namespace BepInEx.Bootstrap
 		/// <summary>
 		/// Loads a list of types from a directory containing assemblies, that derive from a base type.
 		/// </summary>
-		/// <typeparam name="T">The specfiic base type to search for.</typeparam>
+		/// <typeparam name="T">The specific base type to search for.</typeparam>
 		/// <param name="directory">The directory to search for assemblies.</param>
 		/// <returns>Returns a list of found derivative types.</returns>
 		public static IEnumerable<Type> LoadTypes<T>(string directory)
@@ -23,7 +23,7 @@ namespace BepInEx.Bootstrap
 			List<Type> types = new List<Type>();
 			Type pluginType = typeof(T);
 
-			foreach (string dll in Directory.GetFiles(Path.GetFullPath(directory), "*.dll"))
+			foreach (string dll in Directory.GetFiles(Path.GetFullPath(directory), "*.dll", SearchOption.AllDirectories))
 			{
 				try
 				{

+ 4 - 4
BepInEx/Config.cs

@@ -13,7 +13,7 @@ namespace BepInEx
 	{
 		private static readonly Dictionary<string, Dictionary<string, string>> cache = new Dictionary<string, Dictionary<string, string>>();
 
-		private static string configPath => Path.Combine(Paths.PluginPath, "config.ini");
+		private static string ConfigPath => Path.Combine(Paths.BepInExRootPath, "config.ini");
 
 		private static readonly Regex sanitizeKeyRegex = new Regex(@"[^a-zA-Z0-9\-\.]+");
 
@@ -34,7 +34,7 @@ namespace BepInEx
 
 		static Config()
 		{
-			if (File.Exists(configPath))
+			if (File.Exists(ConfigPath))
 			{
 				ReloadConfig();
 			}
@@ -87,7 +87,7 @@ namespace BepInEx
 
 			string currentSection = "";
 
-			foreach (string rawLine in File.ReadAllLines(configPath))
+			foreach (string rawLine in File.ReadAllLines(ConfigPath))
 			{
 				string line = rawLine.Trim();
 
@@ -120,7 +120,7 @@ namespace BepInEx
 		/// </summary>
 		public static void SaveConfig()
 		{
-			using (StreamWriter writer = new StreamWriter(File.Create(configPath), System.Text.Encoding.UTF8))
+			using (StreamWriter writer = new StreamWriter(File.Create(ConfigPath), System.Text.Encoding.UTF8))
 				foreach (var sectionKv in cache)
 				{
 					writer.WriteLine($"[{sectionKv.Key}]");

+ 28 - 20
BepInEx/Paths.cs

@@ -1,5 +1,4 @@
-using System.Diagnostics;
-using System.IO;
+using System.IO;
 using System.Reflection;
 
 namespace BepInEx
@@ -9,7 +8,23 @@ namespace BepInEx
 	/// </summary>
 	public static class Paths
 	{
-		private static string executablePath;
+		internal static void SetExecutablePath(string executablePath)
+		{
+			ExecutablePath = executablePath;
+			ProcessName = Path.GetFileNameWithoutExtension(executablePath);
+			GameRootPath = Path.GetDirectoryName(executablePath);
+			ManagedPath = Utility.CombinePaths(GameRootPath, $"{ProcessName}_Data", "Managed");
+			BepInExRootPath = Utility.CombinePaths(GameRootPath, "BepInEx");
+			PluginPath = Utility.CombinePaths(BepInExRootPath, "plugins");
+			PatcherPluginPath = Utility.CombinePaths(BepInExRootPath, "patchers");
+			BepInExAssemblyDirectory = Utility.CombinePaths(BepInExRootPath, "core");
+			BepInExAssemblyPath = Utility.CombinePaths(BepInExAssemblyDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.dll");
+		}
+
+		internal static void SetPluginPath(string pluginPath)
+		{
+			PluginPath = Utility.CombinePaths(BepInExRootPath, pluginPath);
+		}
 
 		/// <summary>
 		///     The directory that the core BepInEx DLLs reside in.
@@ -22,24 +37,14 @@ namespace BepInEx
 		public static string BepInExAssemblyPath { get; private set; }
 
 		/// <summary>
+		///     The path to the main BepInEx folder.
+		/// </summary>
+		public static string BepInExRootPath { get; private set; }
+
+		/// <summary>
 		///     The path of the currently executing program BepInEx is encapsulated in.
 		/// </summary>
-		public static string ExecutablePath
-		{
-			get => executablePath;
-			internal set
-			{
-				executablePath = value;
-				ProcessName = Path.GetFileNameWithoutExtension(value);
-				GameRootPath = Path.GetDirectoryName(value);
-				ManagedPath = Utility.CombinePaths(GameRootPath, $"{ProcessName}_Data", "Managed");
-				PluginPath = Utility.CombinePaths(GameRootPath, "BepInEx");
-				PatcherPluginPath = Utility.CombinePaths(GameRootPath, "BepInEx", "patchers");
-				BepInExAssemblyDirectory = Utility.CombinePaths(GameRootPath, "BepInEx", "core");
-				BepInExAssemblyPath =
-					Utility.CombinePaths(BepInExAssemblyDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.dll");
-			}
-		}
+		public static string ExecutablePath { get; private set; }
 
 		/// <summary>
 		///     The directory that the currently executing process resides in.
@@ -57,7 +62,10 @@ namespace BepInEx
 		public static string PatcherPluginPath { get; private set; }
 
 		/// <summary>
-		///     The path to the main BepInEx folder.
+		///     The path to the plugin folder which resides in the BepInEx folder.
+		/// <para>
+		///		This is ONLY guaranteed to be set correctly when Chainloader has been initialized.
+		/// </para>
 		/// </summary>
 		public static string PluginPath { get; private set; }
 

+ 21 - 11
BepInEx/Utility.cs

@@ -12,7 +12,7 @@ namespace BepInEx
 	public static class Utility
 	{
 		/// <summary>
-		/// Combines multiple paths together, as the specfic method is not availble in .NET 3.5.
+		/// Combines multiple paths together, as the specific method is not available in .NET 3.5.
 		/// </summary>
 		/// <param name="parts">The multiple paths to combine together.</param>
 		/// <returns>A combined path.</returns>
@@ -110,21 +110,31 @@ namespace BepInEx
 		public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, out Assembly assembly)
 		{
 			assembly = null;
-			string path = Path.Combine(directory, $"{assemblyName.Name}.dll");
 
-			if (!File.Exists(path))
-				return false;
+			var potentialDirectories = new List<string> { directory };
 
-			try
-			{
-				assembly = Assembly.LoadFile(path);
-			}
-			catch (Exception)
+			potentialDirectories.AddRange(Directory.GetDirectories(directory, "*", SearchOption.AllDirectories));
+
+			foreach (string subDirectory in potentialDirectories)
 			{
-				return false;
+				string path = Path.Combine(subDirectory, $"{assemblyName.Name}.dll");
+
+				if (!File.Exists(path))
+					continue;
+
+				try
+				{
+					assembly = Assembly.LoadFile(path);
+				}
+				catch (Exception)
+				{
+					continue;
+				}
+
+				return true;
 			}
 
-			return true;
+			return false;
 		}
 	}
 }