Przeglądaj źródła

Merge changes from master

ghorsington 5 lat temu
rodzic
commit
e78f956bdc

+ 1 - 1
BepInEx.Preloader/Entrypoint.cs

@@ -51,7 +51,7 @@ namespace BepInEx.Preloader
 		public static void Main(string[] args)
 		{
 			// Get the path of this DLL via Doorstop env var because Assembly.Location mangles non-ASCII characters on some versions of Mono for unknown reasons
-			preloaderPath = Path.GetDirectoryName(Path.GetFullPath(Environment.GetEnvironmentVariable("DOORSTOP_INVOKE_DLL_PATH")));
+			preloaderPath = Path.GetDirectoryName(Path.GetFullPath(EnvVars.DOORSTOP_INVOKE_DLL_PATH));
 
 			AppDomain.CurrentDomain.AssemblyResolve += ResolveCurrentDirectory;
 

+ 3 - 3
BepInEx.Preloader/Preloader.cs

@@ -198,11 +198,11 @@ namespace BepInEx.Preloader
 					var ins = il.Body.Instructions.First();
 
 					il.InsertBefore(ins,
-						il.Create(OpCodes.Ldstr, Paths.ExecutablePath)); //containerExePath
-					il.InsertBefore(ins,
+						il.Create(OpCodes.Ldnull)); // gameExePath (always null, we initialize the Paths class in Entrypoint
+                    il.InsertBefore(ins,
 						il.Create(OpCodes.Ldc_I4_0)); //startConsole (always false, we already load the console in Preloader)
 					il.InsertBefore(ins,
-						il.Create(OpCodes.Call, initMethod)); // Chainloader.Initialize(string containerExePath, string managedPath = null, bool startConsole = true)
+						il.Create(OpCodes.Call, initMethod)); // Chainloader.Initialize(string gamePath, string managedPath = null, bool startConsole = true)
 					il.InsertBefore(ins,
 						il.Create(OpCodes.Call, startMethod));
 				}

+ 35 - 9
BepInEx/Bootstrap/Chainloader.cs

@@ -7,6 +7,7 @@ using System.IO;
 using System.Linq;
 using System.Reflection;
 using System.Text;
+using System.Text.RegularExpressions;
 using BepInEx.Contract;
 using Mono.Cecil;
 using UnityEngine;
@@ -39,22 +40,27 @@ namespace BepInEx.Bootstrap
 		/// <summary>
         /// Initializes BepInEx to be able to start the chainloader.
         /// </summary>
-        public static void Initialize(string containerExePath, bool startConsole = true)
+        public static void Initialize(string gameExePath, bool startConsole = true)
 		{
 			if (_initialized)
 				return;
 
-			//Set vitals
-			Paths.SetExecutablePath(containerExePath, pluginPath: ConfigPluginsDirectory.Value);
+            // Set vitals
+			if (gameExePath != null)
+			{
+				// Checking for null allows a more advanced initialization workflow, where the Paths class has been initialized before calling Chainloader.Initialize
+				// This is used by Preloader to use environment variables, for example
+				Paths.SetExecutablePath(gameExePath);
+			}
 
-            //Start logging
+            // Start logging
             if (ConsoleWindow.ConfigConsoleEnabled.Value && startConsole)
 			{
 				ConsoleWindow.Attach();
 				Logger.Listeners.Add(new ConsoleLogListener());
             }
 
-			//Fix for standard output getting overwritten by UnityLogger
+			// Fix for standard output getting overwritten by UnityLogger
 			if (ConsoleWindow.StandardOut != null)
 			{
 				Console.SetOut(ConsoleWindow.StandardOut);
@@ -79,7 +85,9 @@ namespace BepInEx.Bootstrap
 			_initialized = true;
 		}
 
-		private static PluginInfo ToPluginInfo(TypeDefinition type)
+		private static Regex allowedGuidRegex { get; } = new Regex(@"^[a-zA-Z0-9\._]+$");
+
+        private static PluginInfo ToPluginInfo(TypeDefinition type)
 		{
 			if (type.IsInterface || type.IsAbstract || !type.IsSubtypeOf(typeof(BaseUnityPlugin)))
 				return null;
@@ -88,12 +96,30 @@ namespace BepInEx.Bootstrap
 
 			if (metadata == null)
 			{
-				Logger.LogWarning($"Skipping over type [{type.Name}] as no metadata attribute is specified");
+				Logger.LogWarning($"Skipping over type [{type.FullName}] as no metadata attribute is specified");
+				return null;
+			}
+
+			if (string.IsNullOrEmpty(metadata.GUID) || !allowedGuidRegex.IsMatch(metadata.GUID))
+			{
+				Logger.LogWarning($"Skipping type [{type.FullName}] because its GUID [{metadata.GUID}] is of an illegal format.");
+				return null;
+			}
+
+			if (metadata.Version == null)
+			{
+				Logger.LogWarning($"Skipping type [{type.FullName}] because its version is invalid.");
+				return null;
+			}
+
+			if (metadata.Name == null)
+			{
+				Logger.LogWarning($"Skipping type [{type.FullName}] because its name is null.");
 				return null;
 			}
 
-			//Perform a filter for currently running process
-			var filters = BepInProcess.FromCecilType(type);
+            //Perform a filter for currently running process
+            var filters = BepInProcess.FromCecilType(type);
 
 			bool invalidProcessName = filters.Any(x => !string.Equals(x.ProcessName.Replace(".exe", ""), Paths.ProcessName, StringComparison.InvariantCultureIgnoreCase));
 

+ 26 - 1
BepInEx/Utility.cs

@@ -152,5 +152,30 @@ namespace BepInEx
 		/// <param name="assembly">The loaded assembly.</param>
 		/// <returns>True, if the assembly was found and loaded. Otherwise, false.</returns>
 		public static bool TryResolveDllAssembly(AssemblyName assemblyName, string directory, ReaderParameters readerParameters, out AssemblyDefinition assembly) { return TryResolveDllAssembly(assemblyName, directory, s => AssemblyDefinition.ReadAssembly(s, readerParameters), out assembly); }
-	}
+
+		/// <summary>
+		/// Tries to create a file with the given name
+		/// </summary>
+		/// <param name="path">Path of the file to create</param>
+		/// <param name="mode">File open mode</param>
+		/// <param name="fileStream">Resulting filestream</param>
+		/// <param name="access">File access options</param>
+		/// <param name="share">File share options</param>
+		/// <returns></returns>
+		public static bool TryOpenFileStream(string path, FileMode mode, out FileStream fileStream, FileAccess access = FileAccess.ReadWrite, FileShare share = FileShare.Read)
+		{
+			try
+			{
+				fileStream = new FileStream(path, mode, access, share);
+
+				return true;
+			}
+			catch (IOException)
+			{
+				fileStream = null;
+
+				return false;
+			}
+		}
+    }
 }