Parcourir la source

Merge pull request #137 from BepInEx/feature-uname-check

Add uname libc call on Unix systems as platform check
Geoffrey Horsington il y a 4 ans
Parent
commit
2f0acd9c43

+ 5 - 4
BepInEx.Preloader/BepInEx.Preloader.csproj

@@ -39,12 +39,12 @@
     <Reference Include="Mono.Cecil.Rocks, Version=0.10.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
       <HintPath>$(SolutionDir)\packages\Mono.Cecil.0.10.4\lib\net35\Mono.Cecil.Rocks.dll</HintPath>
     </Reference>
-    <Reference Include="MonoMod.RuntimeDetour, Version=20.8.3.5, Culture=neutral, PublicKeyToken=null">
-      <HintPath>$(SolutionDir)\packages\MonoMod.RuntimeDetour.20.8.3.5\lib\net35\MonoMod.RuntimeDetour.dll</HintPath>
+    <Reference Include="MonoMod.RuntimeDetour, Version=20.11.5.1, Culture=neutral, PublicKeyToken=null">
+      <HintPath>$(SolutionDir)\packages\MonoMod.RuntimeDetour.20.11.5.1\lib\net35\MonoMod.RuntimeDetour.dll</HintPath>
       <Private>True</Private>
     </Reference>
-    <Reference Include="MonoMod.Utils, Version=20.8.3.5, Culture=neutral, PublicKeyToken=null">
-      <HintPath>$(SolutionDir)\packages\MonoMod.Utils.20.8.3.5\lib\net35\MonoMod.Utils.dll</HintPath>
+    <Reference Include="MonoMod.Utils, Version=20.11.5.1, Culture=neutral, PublicKeyToken=null">
+      <HintPath>$(SolutionDir)\packages\MonoMod.Utils.20.11.5.1\lib\net35\MonoMod.Utils.dll</HintPath>
       <Private>True</Private>
     </Reference>
     <Reference Include="System" />
@@ -55,6 +55,7 @@
     <Compile Include="Patching\AssemblyPatcher.cs" />
     <Compile Include="Entrypoint.cs" />
     <Compile Include="Patching\PatcherPlugin.cs" />
+    <Compile Include="Platform.cs" />
     <Compile Include="RuntimeFixes\ConsoleSetOutFix.cs" />
     <Compile Include="RuntimeFixes\TraceFix.cs" />
     <Compile Include="Preloader.cs" />

+ 2 - 0
BepInEx.Preloader/Entrypoint.cs

@@ -51,6 +51,8 @@ namespace BepInEx.Preloader
 
 		public static void PreloaderPreMain()
 		{
+			PlatformUtils.SetPlatform();
+
 			string bepinPath = Utility.ParentDirectory(Path.GetFullPath(EnvVars.DOORSTOP_INVOKE_DLL_PATH), 2);
 
 			Paths.SetExecutablePath(EnvVars.DOORSTOP_PROCESS_PATH, bepinPath, EnvVars.DOORSTOP_MANAGED_FOLDER_DIR);

+ 151 - 0
BepInEx.Preloader/Platform.cs

@@ -0,0 +1,151 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using MonoMod.Utils;
+
+namespace BepInEx.Preloader
+{
+	internal static class PlatformUtils
+	{
+		[StructLayout(LayoutKind.Sequential, Pack = 1)]
+		public struct utsname_osx
+		{
+			private const int osx_utslen = 256;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = osx_utslen)]
+			public string sysname;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = osx_utslen)]
+			public string nodename;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = osx_utslen)]
+			public string release;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = osx_utslen)]
+			public string version;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = osx_utslen)]
+			public string machine;
+		}
+
+		[StructLayout(LayoutKind.Sequential, Pack = 1)]
+		public struct utsname_linux
+		{
+			private const int linux_utslen = 65;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
+			public string sysname;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
+			public string nodename;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
+			public string release;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
+			public string version;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
+			public string machine;
+
+			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = linux_utslen)]
+			public string domainname;
+		}
+
+		[DllImport("libc.so.6", EntryPoint = "uname", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern IntPtr uname_linux(ref utsname_linux utsname);
+
+		[DllImport("/usr/lib/libSystem.dylib", EntryPoint = "uname", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+		private static extern IntPtr uname_osx(ref utsname_osx utsname);
+
+		/// <summary>
+		/// Recreation of MonoMod's PlatformHelper.DeterminePlatform method, but with libc calls instead of creating processes.
+		/// </summary>
+		public static void SetPlatform()
+		{
+			var current = Platform.Unknown;
+
+			// For old Mono, get from a private property to accurately get the platform.
+			// static extern PlatformID Platform
+			PropertyInfo p_Platform = typeof(Environment).GetProperty("Platform", BindingFlags.NonPublic | BindingFlags.Static);
+			string platID;
+			if (p_Platform != null)
+			{
+				platID = p_Platform.GetValue(null, new object[0]).ToString();
+			}
+			else
+			{
+				// For .NET and newer Mono, use the usual value.
+				platID = Environment.OSVersion.Platform.ToString();
+			}
+			platID = platID.ToLowerInvariant();
+
+			if (platID.Contains("win"))
+			{
+				current = Platform.Windows;
+			}
+			else if (platID.Contains("mac") || platID.Contains("osx"))
+			{
+				current = Platform.MacOS;
+			}
+			else if (platID.Contains("lin") || platID.Contains("unix"))
+			{
+				current = Platform.Linux;
+			}
+
+			if (Is(current, Platform.Linux) && Directory.Exists("/data") && File.Exists("/system/build.prop"))
+			{
+				current = Platform.Android;
+			}
+			else if (Is(current, Platform.Unix) && Directory.Exists("/System/Library/AccessibilityBundles"))
+			{
+				current = Platform.iOS;
+			}
+
+			// Is64BitOperatingSystem has been added in .NET Framework 4.0
+			MethodInfo m_get_Is64BitOperatingSystem = typeof(Environment).GetProperty("Is64BitOperatingSystem")?.GetGetMethod();
+			if (m_get_Is64BitOperatingSystem != null)
+				current |= (((bool)m_get_Is64BitOperatingSystem.Invoke(null, new object[0])) ? Platform.Bits64 : 0);
+			else
+				current |= (IntPtr.Size >= 8 ? Platform.Bits64 : 0);
+
+			if ((Is(current, Platform.MacOS) || Is(current, Platform.Linux)) && Type.GetType("Mono.Runtime") != null)
+			{
+				string arch;
+				IntPtr result;
+
+				if (Is(current, Platform.MacOS))
+				{
+					utsname_osx utsname_osx = new utsname_osx();
+					result = uname_osx(ref utsname_osx);
+					arch = utsname_osx.machine;
+				}
+				else
+				{
+					// Linux
+					utsname_linux utsname_linux = new utsname_linux();
+					result = uname_linux(ref utsname_linux);
+					arch = utsname_linux.machine;
+				}
+
+				if (result == IntPtr.Zero && (arch.StartsWith("aarch") || arch.StartsWith("arm")))
+					current |= Platform.ARM;
+			}
+			else
+			{
+				// Detect ARM based on PE info or uname.
+				typeof(object).Module.GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine);
+				if (machine == (ImageFileMachine)0x01C4 /* ARM, .NET Framework 4.5 */)
+					current |= Platform.ARM;
+			}
+
+			PlatformHelper.Current = current;
+		}
+
+		private static bool Is(Platform current, Platform expected)
+		{
+			return (current & expected) == expected;
+		}
+	}
+}

+ 2 - 1
BepInEx.Preloader/Preloader.cs

@@ -68,6 +68,7 @@ namespace BepInEx.Preloader
 				Logger.LogInfo($"Running under Unity v{GetUnityVersion()}");
 				Logger.LogInfo($"CLR runtime version: {Environment.Version}");
 				Logger.LogInfo($"Supports SRE: {Utility.CLRSupportsDynamicAssemblies}");
+				Logger.LogInfo($"System platform: {PlatformHelper.Current}");
 
 				if (runtimePatchException != null)
 					Logger.LogWarning($"Failed to apply runtime patches for Mono. See more info in the output log. Error message: {runtimePatchException.Message}");
@@ -236,7 +237,7 @@ namespace BepInEx.Preloader
 
 		public static string GetUnityVersion()
 		{
-			if (Utility.CurrentOs == Platform.Windows)
+			if (PlatformHelper.Is(Platform.Windows))
 				return FileVersionInfo.GetVersionInfo(Paths.ExecutablePath).FileVersion;
 
 			return $"Unknown ({(IsPostUnity2017 ? "post" : "pre")}-2017)";

+ 2 - 2
BepInEx.Preloader/RuntimeFixes/XTermFix.cs

@@ -13,7 +13,7 @@ namespace BepInEx.Preloader.RuntimeFixes
 	{
 		public static void Apply()
 		{
-			if (Utility.CurrentOs == Platform.Windows)
+			if (PlatformHelper.Is(Platform.Windows))
 				return;
 
 			if (typeof(Console).Assembly.GetType("System.ConsoleDriver") == null)
@@ -34,7 +34,7 @@ namespace BepInEx.Preloader.RuntimeFixes
 			// Because Doorstop does not support ARM at the moment, we can get away with just forcing x86 detour platform.
 			// TODO: Figure out a way to detect ARM on Unix without running Process.Start
 			DetourHelper.Native = new DetourNativeX86Platform();
-
+			
 			var harmony = new HarmonyLib.Harmony("com.bepinex.xtermfix");
 
 			harmony.Patch(AccessTools.Method("System.TermInfoReader:ReadHeader"),

+ 2 - 2
BepInEx.Preloader/packages.config

@@ -2,6 +2,6 @@
 <packages>
   <package id="HarmonyX" version="2.1.0-beta.7" targetFramework="net35" />
   <package id="Mono.Cecil" version="0.10.4" targetFramework="net35" />
-  <package id="MonoMod.RuntimeDetour" version="20.8.3.5" targetFramework="net35" />
-  <package id="MonoMod.Utils" version="20.8.3.5" targetFramework="net35" />
+  <package id="MonoMod.RuntimeDetour" version="20.11.5.1" targetFramework="net35" />
+  <package id="MonoMod.Utils" version="20.11.5.1" targetFramework="net35" />
 </packages>

+ 4 - 4
BepInEx/BepInEx.csproj

@@ -57,12 +57,12 @@
     <Reference Include="Mono.Cecil.Rocks, Version=0.10.4.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e, processorArchitecture=MSIL">
       <HintPath>$(SolutionDir)\packages\Mono.Cecil.0.10.4\lib\net35\Mono.Cecil.Rocks.dll</HintPath>
     </Reference>
-    <Reference Include="MonoMod.RuntimeDetour, Version=20.8.3.5, Culture=neutral, PublicKeyToken=null">
-      <HintPath>$(SolutionDir)\packages\MonoMod.RuntimeDetour.20.8.3.5\lib\net35\MonoMod.RuntimeDetour.dll</HintPath>
+    <Reference Include="MonoMod.RuntimeDetour, Version=20.11.5.1, Culture=neutral, PublicKeyToken=null">
+      <HintPath>$(SolutionDir)\packages\MonoMod.RuntimeDetour.20.11.5.1\lib\net35\MonoMod.RuntimeDetour.dll</HintPath>
       <Private>True</Private>
     </Reference>
-    <Reference Include="MonoMod.Utils, Version=20.8.3.5, Culture=neutral, PublicKeyToken=null">
-      <HintPath>$(SolutionDir)\packages\MonoMod.Utils.20.8.3.5\lib\net35\MonoMod.Utils.dll</HintPath>
+    <Reference Include="MonoMod.Utils, Version=20.11.5.1, Culture=neutral, PublicKeyToken=null">
+      <HintPath>$(SolutionDir)\packages\MonoMod.Utils.20.11.5.1\lib\net35\MonoMod.Utils.dll</HintPath>
       <Private>True</Private>
     </Reference>
     <Reference Include="System" />

+ 1 - 1
BepInEx/Bootstrap/Chainloader.cs

@@ -109,7 +109,7 @@ namespace BepInEx.Bootstrap
 				Logger.Sources.Add(new UnityLogSource());
 			Logger.Listeners.Add(new UnityLogListener());
 
-			if (Utility.CurrentOs == Platform.Linux)
+			if (PlatformHelper.Is(Platform.Unix))
 			{
 				Logger.LogInfo($"Detected Unity version: v{UnityVersion}");
 			}

+ 6 - 13
BepInEx/Console/ConsoleManager.cs

@@ -32,20 +32,13 @@ namespace BepInEx
 
 		public static void Initialize(bool alreadyActive)
 		{
-			switch (Utility.CurrentOs)
+			if (PlatformHelper.Is(Platform.Unix))
 			{
-				case Platform.MacOS:
-				case Platform.Linux:
-				{
-					Driver = new LinuxConsoleDriver();
-					break;
-				}
-
-				case Platform.Windows:
-				{
-					Driver = new WindowsConsoleDriver();
-					break;
-				}
+				Driver = new LinuxConsoleDriver();
+			}
+			else if (PlatformHelper.Is(Platform.Windows))
+			{
+				Driver = new WindowsConsoleDriver();
 			}
 
 			Driver.Initialize(alreadyActive);

+ 1 - 1
BepInEx/Paths.cs

@@ -14,7 +14,7 @@ namespace BepInEx
 			ExecutablePath = executablePath;
 			ProcessName = Path.GetFileNameWithoutExtension(executablePath);
 
-			GameRootPath = Utility.CurrentOs == Platform.MacOS
+			GameRootPath = PlatformHelper.Is(Platform.MacOS)
 				? Utility.ParentDirectory(executablePath, 4)
 				: Path.GetDirectoryName(executablePath);
 

+ 0 - 28
BepInEx/Utility.cs

@@ -44,11 +44,6 @@ namespace BepInEx
 			sreEnabled = true;
 			return sreEnabled.Value;
 		}
-		
-		static Utility()
-		{
-			CheckPlatform();
-		}
 
 		/// <summary>
 		/// Try to perform an action.
@@ -299,28 +294,5 @@ namespace BepInEx
 				return false;
 			}
 		}
-
-		// Adapted from https://github.com/MonoMod/MonoMod.Common/blob/master/Utils/PlatformHelper.cs#L13
-		private static void CheckPlatform()
-		{
-			var pPlatform = typeof(Environment).GetProperty("Platform", BindingFlags.NonPublic | BindingFlags.Static);
-			string platId = pPlatform != null ? pPlatform.GetValue(null, new object[0]).ToString() : Environment.OSVersion.Platform.ToString();
-			platId = platId.ToLowerInvariant();
-
-			var cur = Platform.Unknown;
-			if (platId.Contains("win"))
-				cur = Platform.Windows;
-			else if (platId.Contains("mac") || platId.Contains("osx"))
-				cur = Platform.MacOS;
-			else if (platId.Contains("lin") || platId.Contains("unix"))
-				cur = Platform.Linux;
-
-			CurrentOs = cur;
-		}
-
-		/// <summary>
-		/// Current OS BepInEx is running on.
-		/// </summary>
-		public static Platform CurrentOs { get; private set; }
 	}
 }

+ 2 - 2
BepInEx/packages.config

@@ -2,6 +2,6 @@
 <packages>
   <package id="HarmonyX" version="2.1.0-beta.7" targetFramework="net35" />
   <package id="Mono.Cecil" version="0.10.4" targetFramework="net35" />
-  <package id="MonoMod.RuntimeDetour" version="20.8.3.5" targetFramework="net35" />
-  <package id="MonoMod.Utils" version="20.8.3.5" targetFramework="net35" />
+  <package id="MonoMod.RuntimeDetour" version="20.11.5.1" targetFramework="net35" />
+  <package id="MonoMod.Utils" version="20.11.5.1" targetFramework="net35" />
 </packages>

+ 1 - 1
README.md

@@ -25,7 +25,7 @@ Unity plugin framework
 - [NeighTools/UnityDoorstop](https://github.com/NeighTools/UnityDoorstop) - 3.0.2.2 ([7fe6127](https://github.com/NeighTools/UnityDoorstop/commit/7fe6127849c6cbbb4943f3f14146ae6ade7ec0bf))
 - [NeighTools/UnityDoorstop.Unix](https://github.com/NeighTools/UnityDoorstop.Unix) - 1.3.0.0 ([a16f217](https://github.com/NeighTools/UnityDoorstop.Unix/commit/a16f21743fdadedc8e091226c6731dbf7e9113c8))
 - [BepInEx/HarmonyX](https://github.com/BepInEx/HarmonyX) - 2.1.0-beta.8 ([6209d73](https://github.com/BepInEx/HarmonyX/commit/6209d7393eacb1b2213f15c3c57e5e9fc60bc253))
-- [MonoMod/MonoMod](https://github.com/MonoMod/MonoMod) - v20.08.03.05 ([5d8210d](https://github.com/MonoMod/MonoMod/commit/7b5c8c20a14a3a67d716dc3d61d8f6bb67546b0a))
+- [MonoMod/MonoMod](https://github.com/MonoMod/MonoMod) - v20.11.05.01 ([1775ec9](https://github.com/MonoMod/MonoMod/commit/1775ec98e76d3420b2365d6103b4f1b69761a197))
 - [jbevain/cecil](https://github.com/jbevain/cecil) - 0.10.4 ([98ec890](https://github.com/jbevain/cecil/commit/98ec890d44643ad88d573e97be0e120435eda732))
 
 ## Credits