mirror of
https://github.com/LavaGang/MelonLoader.git
synced 2026-10-12 02:06:39 +00:00
Fixed an issue with plthook application being used earlier than logging initialization resulting in lost error logs
This commit is contained in:
@@ -51,19 +51,7 @@ internal static class ConsoleHandler
|
||||
if (!string.IsNullOrEmpty(title))
|
||||
Console.Title = title;
|
||||
|
||||
#if LINUX
|
||||
PltHook.InstallHooks(
|
||||
[
|
||||
("fclose", Marshal.GetFunctionPointerForDelegate(HookFCloseDelegate))
|
||||
]);
|
||||
#endif
|
||||
|
||||
#if WINDOWS
|
||||
PltHook.InstallHooks(
|
||||
[
|
||||
("CloseHandle", Marshal.GetFunctionPointerForDelegate(HookCloseHandleDelegate)),
|
||||
]);
|
||||
|
||||
Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = true });
|
||||
Console.SetError(new StreamWriter(Console.OpenStandardError()) { AutoFlush = true });
|
||||
Console.SetIn(new StreamReader(Console.OpenStandardInput()));
|
||||
@@ -77,6 +65,21 @@ internal static class ConsoleHandler
|
||||
IsOpen = true;
|
||||
}
|
||||
|
||||
public static void InstallHooks()
|
||||
{
|
||||
#if LINUX
|
||||
PltHook.InstallHooks(
|
||||
[
|
||||
("fclose", Marshal.GetFunctionPointerForDelegate(HookFCloseDelegate))
|
||||
]);
|
||||
#elif WINDOWS
|
||||
PltHook.InstallHooks(
|
||||
[
|
||||
("CloseHandle", Marshal.GetFunctionPointerForDelegate(HookCloseHandleDelegate)),
|
||||
]);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void NullHandles()
|
||||
{
|
||||
#if WINDOWS
|
||||
|
||||
@@ -105,6 +105,8 @@ internal static class MelonLogger
|
||||
{
|
||||
Core.Logger.Error("Failed to create any log files. Logging to console only");
|
||||
}
|
||||
|
||||
ConsoleHandler.InstallHooks();
|
||||
|
||||
if (LoaderConfig.Current.Loader.CapturePlayerLogs)
|
||||
{
|
||||
@@ -131,7 +133,7 @@ internal static class MelonLogger
|
||||
file.WriteLine(log);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void Log(ColorARGB msgColor, ReadOnlySpan<char> msg, ReadOnlySpan<char> strippedMessage)
|
||||
{
|
||||
var time = DateTime.Now.ToString(timeFormat);
|
||||
|
||||
@@ -159,7 +159,7 @@ internal static class DotnetHandler
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (LoaderConfig.Current.Loader.DebugMode)
|
||||
MelonLogger.LogError(ex.ToString());
|
||||
Core.Logger.Error(ex.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ internal static class DotnetHandler
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (LoaderConfig.Current.Loader.DebugMode)
|
||||
MelonLogger.LogError(ex.ToString());
|
||||
Core.Logger.Error(ex.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ internal static class DotnetHandler
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (LoaderConfig.Current.Loader.DebugMode)
|
||||
MelonLogger.LogError(ex.ToString());
|
||||
Core.Logger.Error(ex.ToString());
|
||||
}
|
||||
|
||||
// Restore Original Root and Path
|
||||
@@ -211,7 +211,7 @@ internal static class DotnetHandler
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (LoaderConfig.Current.Loader.DebugMode)
|
||||
MelonLogger.LogError(ex.ToString());
|
||||
Core.Logger.Error(ex.ToString());
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using MelonLoader.Bootstrap.Logging;
|
||||
|
||||
namespace MelonLoader.Bootstrap;
|
||||
|
||||
@@ -36,19 +35,21 @@ internal static partial class PltHook
|
||||
private static partial nint PlthookError();
|
||||
|
||||
private static bool WasError;
|
||||
private static string? PlayerFileName;
|
||||
private static string? PlayerFilePath;
|
||||
private static nint PlayerModuleHandle;
|
||||
private const string UnityPlayerLibName = "UnityPlayer";
|
||||
|
||||
internal static void InstallHooks(List<(string functionName, nint hookFunctionPtr)> hooks)
|
||||
{
|
||||
if (!EnsureUnityPlayerLibrary())
|
||||
if (!FindUnityPlayerLibrary()
|
||||
|| !LoadUnityPlayerLibrary())
|
||||
return;
|
||||
|
||||
nint pltHook = IntPtr.Zero;
|
||||
if (PlthookOpen(ref pltHook, PlayerFileName) != 0)
|
||||
if (PlthookOpenByHandle(ref pltHook, PlayerModuleHandle) != 0)
|
||||
{
|
||||
MelonLogger.LogError($"plthook_open error: {Marshal.PtrToStringAuto(PlthookError())}");
|
||||
PlayerFileName = null;
|
||||
Core.Logger.Error($"plthook_open error: {Marshal.PtrToStringAuto(PlthookError())}");
|
||||
PlayerFilePath = null;
|
||||
WasError = true;
|
||||
return;
|
||||
}
|
||||
@@ -68,21 +69,45 @@ internal static partial class PltHook
|
||||
PlthookClose(pltHook);
|
||||
}
|
||||
|
||||
private static bool EnsureUnityPlayerLibrary()
|
||||
private static bool LoadUnityPlayerLibrary()
|
||||
{
|
||||
if (WasError)
|
||||
return false;
|
||||
if (PlayerModuleHandle != IntPtr.Zero)
|
||||
return true;
|
||||
|
||||
MelonDebug.Log($"Attempting to use UnityPlayer: '{PlayerFilePath}'");
|
||||
|
||||
#if WINDOWS
|
||||
PlayerModuleHandle = WindowsNative.LoadLibrary(PlayerFilePath!);
|
||||
#else
|
||||
PlayerModuleHandle = LibcNative.Dlopen(PlayerFilePath!, LibcNative.RtldLazy | LibcNative.RtldNoLoad);
|
||||
#endif
|
||||
if (PlayerModuleHandle == IntPtr.Zero)
|
||||
{
|
||||
Core.Logger.Error($"Failed to load {PlayerFilePath}, cannot apply plt hooks");
|
||||
PlayerModuleHandle = IntPtr.Zero;
|
||||
PlayerFilePath = null;
|
||||
WasError = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Core.Logger.Msg($"Using UnityPlayer: '{PlayerFilePath}'");
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool FindUnityPlayerLibrary()
|
||||
{
|
||||
if (WasError)
|
||||
return false;
|
||||
|
||||
if (!string.IsNullOrEmpty(PlayerFileName))
|
||||
if (!string.IsNullOrEmpty(PlayerFilePath))
|
||||
return true;
|
||||
|
||||
PlayerFileName = Process.GetCurrentProcess().Modules.OfType<ProcessModule>()
|
||||
PlayerFilePath = Process.GetCurrentProcess().Modules.OfType<ProcessModule>()
|
||||
.FirstOrDefault(x => x.FileName.Contains(UnityPlayerLibName))?.FileName;
|
||||
if (!string.IsNullOrEmpty(PlayerFileName))
|
||||
{
|
||||
MelonDebug.Log($"Attempting to use UnityPlayer: '{PlayerFileName}'");
|
||||
if (!string.IsNullOrEmpty(PlayerFilePath))
|
||||
return true;
|
||||
}
|
||||
|
||||
string processModulePath = Process.GetCurrentProcess().MainModule!.FileName;
|
||||
string parentPlayerPath = Path.GetDirectoryName(processModulePath)!;
|
||||
@@ -90,37 +115,36 @@ internal static partial class PltHook
|
||||
#if OSX
|
||||
string libName = $"{UnityPlayerLibName}.dylib";
|
||||
parentPlayerPath = Path.Combine(Path.GetDirectoryName(parentPlayerPath)!, "Frameworks");
|
||||
PlayerFileName = Path.Combine(parentPlayerPath, libName);
|
||||
PlayerFilePath = Path.Combine(parentPlayerPath, libName);
|
||||
#elif LINUX
|
||||
string libName = $"{UnityPlayerLibName}.so";
|
||||
PlayerFileName = Path.Combine(parentPlayerPath, libName);
|
||||
PlayerFilePath = Path.Combine(parentPlayerPath, libName);
|
||||
#elif WINDOWS
|
||||
string libName = $"{UnityPlayerLibName}.dll";
|
||||
PlayerFileName = Path.Combine(parentPlayerPath, libName);
|
||||
PlayerFilePath = Path.Combine(parentPlayerPath, libName);
|
||||
#endif
|
||||
|
||||
#if !WINDOWS
|
||||
if (!File.Exists(PlayerFileName))
|
||||
if (!File.Exists(PlayerFilePath))
|
||||
{
|
||||
libName = $"lib{UnityPlayerLibName}.so";
|
||||
PlayerFileName = Path.Combine(parentPlayerPath, libName);
|
||||
PlayerFilePath = Path.Combine(parentPlayerPath, libName);
|
||||
}
|
||||
if (!File.Exists(PlayerFileName))
|
||||
if (!File.Exists(PlayerFilePath))
|
||||
{
|
||||
libName = $"Lib{UnityPlayerLibName}.so";
|
||||
PlayerFileName = Path.Combine(parentPlayerPath, libName);
|
||||
PlayerFilePath = Path.Combine(parentPlayerPath, libName);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!File.Exists(PlayerFileName))
|
||||
if (!File.Exists(PlayerFilePath))
|
||||
{
|
||||
MelonLogger.LogError($"Unable to find {UnityPlayerLibName} library to apply plthook");
|
||||
PlayerFileName = null;
|
||||
Core.Logger.Error($"Unable to find {UnityPlayerLibName} library to apply plthook");
|
||||
PlayerFilePath = null;
|
||||
WasError = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
MelonDebug.Log($"Attempting to use UnityPlayer: '{PlayerFileName}'");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,10 @@ internal static partial class WindowsNative
|
||||
[LibraryImport("kernel32.dll", EntryPoint = "GetProcAddress", StringMarshalling = StringMarshalling.Utf8)]
|
||||
[UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])]
|
||||
internal static partial nint GetProcAddress(nint hModule, string lpProcName);
|
||||
|
||||
[LibraryImport("kernel32.dll", EntryPoint = "LoadLibraryA", StringMarshalling = StringMarshalling.Utf8)]
|
||||
[UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])]
|
||||
internal static partial nint LoadLibrary(string lpLibFileName);
|
||||
|
||||
[LibraryImport("kernel32.dll")]
|
||||
[UnmanagedCallConv(CallConvs = [typeof(CallConvStdcall)])]
|
||||
|
||||
Reference in New Issue
Block a user