-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
302 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using System.Runtime.InteropServices; | ||
|
||
namespace TweaksLauncher; | ||
|
||
internal static unsafe class Mono | ||
{ | ||
public static void Init() | ||
{ | ||
var lib = NativeLibrary.Load(Program.runtimePath); | ||
|
||
mono_domain_assembly_open = Marshal.GetDelegateForFunctionPointer<mono_domain_assembly_open_sig>(NativeLibrary.GetExport(lib, "mono_domain_assembly_open")); | ||
mono_assembly_get_image = Marshal.GetDelegateForFunctionPointer<mono_assembly_get_image_sig>(NativeLibrary.GetExport(lib, "mono_assembly_get_image")); | ||
mono_class_from_name = Marshal.GetDelegateForFunctionPointer<mono_class_from_name_sig>(NativeLibrary.GetExport(lib, "mono_class_from_name")); | ||
mono_class_get_method_from_name = Marshal.GetDelegateForFunctionPointer<mono_class_get_method_from_name_sig>(NativeLibrary.GetExport(lib, "mono_class_get_method_from_name")); | ||
mono_runtime_invoke = Marshal.GetDelegateForFunctionPointer<mono_runtime_invoke_sig>(NativeLibrary.GetExport(lib, "mono_runtime_invoke")); | ||
mono_string_new = Marshal.GetDelegateForFunctionPointer<mono_string_new_sig>(NativeLibrary.GetExport(lib, "mono_string_new")); | ||
mono_add_internal_call = Marshal.GetDelegateForFunctionPointer<mono_add_internal_call_sig>(NativeLibrary.GetExport(lib, "mono_add_internal_call")); | ||
mono_string_to_utf16 = Marshal.GetDelegateForFunctionPointer<mono_string_to_utf16_sig>(NativeLibrary.GetExport(lib, "mono_string_to_utf16")); | ||
} | ||
|
||
#pragma warning disable IDE1006 // Naming Styles | ||
internal static mono_domain_assembly_open_sig mono_domain_assembly_open { get; private set; } = null!; | ||
internal static mono_assembly_get_image_sig mono_assembly_get_image { get; private set; } = null!; | ||
internal static mono_class_from_name_sig mono_class_from_name { get; private set; } = null!; | ||
internal static mono_class_get_method_from_name_sig mono_class_get_method_from_name { get; private set; } = null!; | ||
internal static mono_runtime_invoke_sig mono_runtime_invoke { get; private set; } = null!; | ||
internal static mono_string_new_sig mono_string_new { get; private set; } = null!; | ||
internal static mono_add_internal_call_sig mono_add_internal_call { get; private set; } = null!; | ||
internal static mono_string_to_utf16_sig mono_string_to_utf16 { get; private set; } = null!; | ||
#pragma warning restore IDE1006 // Naming Styles | ||
|
||
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)] | ||
internal delegate nint mono_domain_assembly_open_sig(nint domain, string name); | ||
|
||
[UnmanagedFunctionPointer(CallingConvention.StdCall)] | ||
internal delegate nint mono_assembly_get_image_sig(nint assembly); | ||
|
||
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)] | ||
internal delegate nint mono_class_from_name_sig(nint image, string nameSpace, string name); | ||
|
||
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)] | ||
internal delegate nint mono_class_get_method_from_name_sig(nint clas, string name, int argsCount); | ||
|
||
[UnmanagedFunctionPointer(CallingConvention.StdCall)] | ||
internal delegate nint mono_runtime_invoke_sig(nint method, nint obj, nint* args, nint* exception); | ||
|
||
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)] | ||
internal delegate nint mono_string_new_sig(nint domain, string value); | ||
|
||
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)] | ||
internal delegate nint mono_add_internal_call_sig(string methodName, nint func); | ||
|
||
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)] | ||
internal delegate string? mono_string_to_utf16_sig(nint monoString); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Drawing; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace TweaksLauncher; | ||
|
||
internal static unsafe class MonoHandler | ||
{ | ||
[NotNull] private static Dobby.Patch<MonoJitInitSig>? monoJitInit = null; | ||
|
||
private static LogImplSig? logImpl; | ||
|
||
internal static int Start() | ||
{ | ||
monoJitInit = Dobby.CreatePatch<MonoJitInitSig>(Program.runtimePath, "mono_jit_init_version", OnDomainInit); | ||
|
||
return GameManager.Start(); | ||
} | ||
|
||
private static void LoadModHandler(nint domain) | ||
{ | ||
var handlerPath = Path.Combine(Program.baseDir, "bin", "Mono", "TweaksLauncher.dll"); | ||
if (!File.Exists(handlerPath)) | ||
{ | ||
Logger.Log($"Could not find the mod handler. Please reinstall TweaksLauncher.", Color.Red); | ||
return; | ||
} | ||
|
||
Mono.Init(); | ||
|
||
var modHandlerAsm = Mono.mono_domain_assembly_open(domain, handlerPath); | ||
if (modHandlerAsm == 0) | ||
{ | ||
Logger.Log($"Failed to load Mod Handler into the Mono domain.", Color.Red); | ||
return; | ||
} | ||
|
||
var modHandlerImg = Mono.mono_assembly_get_image(modHandlerAsm); | ||
var modHandlerClass = Mono.mono_class_from_name(modHandlerImg, "TweaksLauncher", "ModHandler"); | ||
var startMethod = Mono.mono_class_get_method_from_name(modHandlerClass, "Start", 3); | ||
|
||
if (startMethod == 0) | ||
{ | ||
Logger.Log($"Failed to get the Mod Handler's Start method'.", Color.Red); | ||
return; | ||
} | ||
|
||
logImpl = new LogImplSig(LogImpl); | ||
var logImplPtr = Marshal.GetFunctionPointerForDelegate(logImpl); | ||
Mono.mono_add_internal_call("TweaksLauncher.ModHandler::LogInternal", logImplPtr); | ||
|
||
var baseDir = Mono.mono_string_new(domain, Program.baseDir); | ||
var gameName = Mono.mono_string_new(domain, Program.gameName); | ||
var gameDir = Mono.mono_string_new(domain, Program.gamePath); | ||
|
||
var args = stackalloc nint[3]; | ||
args[0] = baseDir; | ||
args[1] = gameName; | ||
args[2] = gameDir; | ||
|
||
Mono.mono_runtime_invoke(startMethod, 0, args, null); | ||
} | ||
|
||
private static void LogImpl(nint monoMessage, int baseColor, nint monoModuleName, int moduleColor) | ||
{ | ||
Logger.Log(monoMessage == 0 ? null : Mono.mono_string_to_utf16(monoMessage), Color.FromArgb(baseColor), monoModuleName == 0 ? null : Mono.mono_string_to_utf16(monoModuleName), Color.FromArgb(moduleColor)); | ||
} | ||
|
||
private static nint OnDomainInit(nint domainName, nint a) | ||
{ | ||
monoJitInit.Destroy(); | ||
|
||
Logger.Log("Creating Mono Domain"); | ||
|
||
var domain = monoJitInit.Original(domainName, a); | ||
|
||
LoadModHandler(domain); | ||
|
||
return domain; | ||
} | ||
|
||
internal delegate nint MonoJitInitSig(nint domainName, nint a); | ||
private delegate void LogImplSig(nint monoMessage, int baseColor, nint monoModuleName, int moduleColor); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.