Browse Source

Add uname libc call on Unix systems as platform check
Rebase of 7647862

Bepis 3 years ago
parent
commit
c2ecb50a22

+ 10 - 18
BepInEx.Core/Console/ConsoleManager.cs

@@ -32,25 +32,17 @@ namespace BepInEx
 
 		public static void Initialize(bool alreadyActive)
 		{
-			switch (Utility.CurrentPlatform & ~Platform.Bits64)
+			if (PlatformHelper.Is(Platform.MacOS) || PlatformHelper.Is(Platform.Linux))
 			{
-				case Platform.MacOS:
-				case Platform.Linux:
-				{
-					Driver = new LinuxConsoleDriver();
-					break;
-				}
-
-				case Platform.Windows:
-				{
-					Driver = new WindowsConsoleDriver();
-					break;
-				}
-
-				default:
-				{
-					throw new PlatformNotSupportedException("Was unable to determine console driver for platform " + Utility.CurrentPlatform);
-				}
+				Driver = new LinuxConsoleDriver();
+			}
+			else if (PlatformHelper.Is(Platform.Windows))
+			{
+				Driver = new WindowsConsoleDriver();
+			}
+			else
+			{
+				throw new PlatformNotSupportedException("Was unable to determine console driver for platform " + PlatformHelper.Current);
 			}
 
 			Driver.Initialize(alreadyActive);

+ 1 - 1
BepInEx.Core/Paths.cs

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

+ 0 - 23
BepInEx.Core/Utility.cs

@@ -333,28 +333,5 @@ namespace BepInEx
 				return false;
 			}
 		}
-
-		public static Platform CurrentPlatform { get; private set; } = CheckPlatform();
-
-		// Adapted from https://github.com/MonoMod/MonoMod.Common/blob/master/Utils/PlatformHelper.cs#L13
-		private static Platform 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;
-
-			if (IntPtr.Size == 8)
-				cur |= Platform.Bits64;
-
-			return cur;
-		}
 	}
 }

+ 3 - 0
BepInEx.IL2CPP/DoorstopEntrypoint.cs

@@ -2,6 +2,7 @@
 using System.IO;
 using System.Linq;
 using System.Reflection;
+using BepInEx.Preloader.Core;
 
 namespace BepInEx.IL2CPP
 {
@@ -17,6 +18,8 @@ namespace BepInEx.IL2CPP
 			AppDomain.CurrentDomain.AssemblyResolve += LocalResolve;
 			AppDomain.CurrentDomain.AssemblyResolve -= DoorstopEntrypoint.ResolveCurrentDirectory;
 
+			PlatformUtils.SetPlatform();
+
 			Preloader.Run();
 		}
 

+ 2 - 35
BepInEx.NetLauncher/NetPreloader.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using System.Reflection;
@@ -8,7 +7,7 @@ using BepInEx.Configuration;
 using BepInEx.Logging;
 using BepInEx.NetLauncher.RuntimeFixes;
 using BepInEx.Preloader.Core;
-using MonoMod.RuntimeDetour;
+using BepInEx.Preloader.Core.Logging;
 
 namespace BepInEx.NetLauncher
 {
@@ -39,34 +38,12 @@ namespace BepInEx.NetLauncher
 			Program.ResolveDirectories.Add(Paths.GameRootPath);
 			TypeLoader.SearchDirectories.Add(Paths.GameRootPath);
 
-			bool bridgeInitialized = Utility.TryDo(() =>
-			{
-				if (ConfigShimHarmony.Value)
-					HarmonyDetourBridge.Init();
-			}, out var harmonyBridgeException);
-
 			Logger.Sources.Add(TraceLogSource.CreateSource());
 
-			string consoleTile = $"BepInEx {typeof(Paths).Assembly.GetName().Version} - {Process.GetCurrentProcess().ProcessName}";
-			Log.LogMessage(consoleTile);
-
-			if (ConsoleManager.ConsoleActive)
-				ConsoleManager.SetConsoleTitle(consoleTile);
-
-			//See BuildInfoAttribute for more information about this section.
-			object[] attributes = typeof(BuildInfoAttribute).Assembly.GetCustomAttributes(typeof(BuildInfoAttribute), false);
-
-			if (attributes.Length > 0)
-			{
-				var attribute = (BuildInfoAttribute)attributes[0];
-				Log.LogMessage(attribute.Info);
-			}
+			ChainloaderLogHelper.PrintLogInfo(Log);
 
 			Log.LogInfo($"CLR runtime version: {Environment.Version}");
 
-			if (harmonyBridgeException != null)
-				Log.LogWarning($"Failed to enable fix for Harmony for .NET Standard API. Error message: {harmonyBridgeException.Message}");
-
 			Log.LogMessage("Preloader started");
 
 			Assembly entrypointAssembly;
@@ -118,16 +95,6 @@ namespace BepInEx.NetLauncher
 			null,
 			"The local filename of the .NET executable to target.");
 
-		private static readonly ConfigEntry<bool> ConfigShimHarmony = ConfigFile.CoreConfig.Bind(
-			"Preloader", "ShimHarmonySupport",
-			!Utility.CLRSupportsDynamicAssemblies,
-			"If enabled, basic Harmony functionality is patched to use MonoMod's RuntimeDetour instead.\nTry using this if Harmony does not work in a game.");
-
-		private static readonly ConfigEntry<bool> ConfigPreloaderCOutLogging = ConfigFile.CoreConfig.Bind(
-			"Logging", "PreloaderConsoleOutRedirection",
-			true,
-			"Redirects text from Console.Out during preloader patch loading to the BepInEx logging system.");
-
 		#endregion
 	}
 }

+ 2 - 0
BepInEx.NetLauncher/Program.cs

@@ -13,6 +13,8 @@ namespace BepInEx.NetLauncher
 	{
 		internal static void PreloaderMain(string[] args)
 		{
+			PlatformUtils.SetPlatform();
+
 			Logger.Listeners.Add(new ConsoleLogListener());
 
 			ConsoleManager.Initialize(true);

+ 1 - 0
BepInEx.Preloader.Core/BepInEx.Preloader.Core.csproj

@@ -41,6 +41,7 @@
     <Compile Include="Patching\AssemblyPatcher.cs" />
     <Compile Include="Patching\PatcherPlugin.cs" />
     <Compile Include="InternalPreloaderLogger.cs" />
+    <Compile Include="PlatformUtils.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="RuntimeFixes\ConsoleSetOutFix.cs" />
   </ItemGroup>

+ 4 - 3
BepInEx.Preloader.Core/Logging/ChainloaderLogHelper.cs

@@ -1,7 +1,6 @@
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
+using System.Linq;
 using BepInEx.Logging;
+using MonoMod.Utils;
 
 namespace BepInEx.Preloader.Core.Logging
 {
@@ -23,6 +22,8 @@ namespace BepInEx.Preloader.Core.Logging
 				var attribute = (BuildInfoAttribute)attributes[0];
 				log.LogMessage(attribute.Info);
 			}
+
+			Logger.LogInfo($"System platform: {PlatformHelper.Current}");
 		}
 
 		public static void RewritePreloaderLogs()

+ 151 - 0
BepInEx.Preloader.Core/PlatformUtils.cs

@@ -0,0 +1,151 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using MonoMod.Utils;
+
+namespace BepInEx.Preloader.Core
+{
+	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;
+		}
+	}
+}

+ 4 - 0
BepInEx.Preloader.Core/Properties/AssemblyInfo.cs

@@ -22,6 +22,10 @@ using System.Runtime.InteropServices;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("15f8bc38-a761-4f93-8903-1b531ac5d9f9")]
 
+[assembly: InternalsVisibleTo("BepInEx.Preloader.Unity")]
+[assembly: InternalsVisibleTo("BepInEx.NetLauncher")]
+[assembly: InternalsVisibleTo("BepInEx.IL2CPP")]
+
 // Version information for an assembly consists of the following four values:
 //
 //      Major Version

+ 3 - 0
BepInEx.Preloader.Unity/DoorstopEntrypoint.cs

@@ -2,6 +2,7 @@
 using System.IO;
 using System.Linq;
 using System.Reflection;
+using BepInEx.Preloader.Core;
 using BepInEx.Preloader.RuntimeFixes;
 
 namespace BepInEx.Preloader.Unity
@@ -53,6 +54,8 @@ namespace BepInEx.Preloader.Unity
 
 		private static void PreloaderMain()
 		{
+			PlatformUtils.SetPlatform();
+
 			if (UnityPreloader.ConfigApplyRuntimePatches.Value)
 			{
 				XTermFix.Apply();

+ 1 - 1
BepInEx.Preloader.Unity/RuntimeFixes/XTermFix.cs

@@ -13,7 +13,7 @@ namespace BepInEx.Preloader.RuntimeFixes
 	{
 		public static void Apply()
 		{
-			if (Utility.CurrentPlatform == Platform.Windows)
+			if (PlatformHelper.Is(Platform.Windows))
 				return;
 
 			if (typeof(Console).Assembly.GetType("System.ConsoleDriver") == null)

+ 1 - 1
BepInEx.Preloader.Unity/UnityPreloader.cs

@@ -241,7 +241,7 @@ namespace BepInEx.Preloader.Unity
 
 		public static string GetUnityVersion()
 		{
-			if (Utility.CurrentPlatform == Platform.Windows)
+			if (PlatformHelper.Is(Platform.Windows))
 				return FileVersionInfo.GetVersionInfo(Paths.ExecutablePath).FileVersion;
 
 			return $"Unknown ({(IsPostUnity2017 ? "post" : "pre")}-2017)";

+ 1 - 1
BepInEx.Unity/Bootstrap/UnityChainloader.cs

@@ -69,7 +69,7 @@ namespace BepInEx.Unity.Bootstrap
 
 			Logger.Listeners.Add(new UnityLogListener());
 
-			if (Utility.CurrentPlatform != Platform.Windows)
+			if (!PlatformHelper.Is(Platform.Windows))
 			{
 				Logger.LogInfo($"Detected Unity version: v{UnityVersion}");
 			}