Skip to content

Commit 981353a

Browse files
support for external methods
1 parent 990b746 commit 981353a

4 files changed

Lines changed: 112 additions & 65 deletions

File tree

android_compatibility_module/IL2CPP/Extentions.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ public static string GetInfo(this Type info)
116116
}
117117
public static string GetInfo(this CodeInstruction info)
118118
{
119+
if (info == null)
120+
{
121+
return "Null Instruction";
122+
}
119123
string msg = "";
120124
if (info.operand is MemberInfo member)
121125
{
@@ -126,20 +130,32 @@ public static string GetInfo(this CodeInstruction info)
126130
}
127131
public static string GetInfo(this ParameterInfo info)
128132
{
133+
if (info == null)
134+
{
135+
return "Null Parameter";
136+
}
129137
return $"parameter {info.Name} of {info.ParameterType.GetInfo()}";
130138
}
131139
public static string GetInfo(this MemberInfo info)
132140
{
141+
if (info == null)
142+
{
143+
return "Null member";
144+
}
133145
return $"member {info.Name} of {info.DeclaringType.GetInfo()}";
134146
}
135147
public static string GetInfo(this MethodBase info)
136148
{
149+
if(info == null)
150+
{
151+
return "Null Method";
152+
}
137153
string msg = "";
138154
foreach (var param in info.GetParameters())
139155
{
140156
msg += param.GetInfo();
141157
}
142-
return $"member {info.Name} of {info.DeclaringType.GetInfo()} with params {msg}";
158+
return $"method {info.Name} of {info.DeclaringType.GetInfo()} with params {msg}";
143159
}
144160
public static WrappedBehaviour AddComponent(this GameObject gameObject, Type type)
145161
{

android_compatibility_module/IL2CPP/TranspilerSupport.cs

Lines changed: 94 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
using System.Linq.Expressions;
2-
using System.Reflection;
3-
using System.Reflection.Emit;
4-
using System.Runtime.Loader;
51
using HarmonyLib;
62
using HarmonyLib.Public.Patching;
3+
using HarmonyLib.Tools;
4+
using Il2CppSystem.Runtime.Remoting.Messaging;
5+
using MelonLoader;
76
using MonoMod.Cil;
87
using NeoModLoader.constants;
98
using NeoModLoader.services;
109
using NeoModLoader.utils;
10+
using System.Linq.Expressions;
11+
using System.Reflection;
12+
using System.Reflection.Emit;
13+
using System.Runtime.Loader;
14+
using static NeoModLoader.AndroidCompatibilityModule.TranspilerSupport.TranspilerSupport;
1115

1216
namespace NeoModLoader.AndroidCompatibilityModule.TranspilerSupport;
1317

@@ -88,7 +92,7 @@ public static object InvokeMirror(MethodBase original, object[] args)
8892

8993
internal static void Initialize(Harmony harmony)
9094
{
91-
MirroredAssemblies.Init();
95+
MirroredAssemblies.Init(AppDomain.CurrentDomain);
9296
harmony.Patch(
9397
AccessTools.Method(typeof(HarmonyManipulator), nameof(HarmonyManipulator.Manipulate),
9498
new[] { typeof(MethodBase), typeof(PatchInfo), typeof(ILContext) }),
@@ -232,6 +236,13 @@ private static IEnumerable<CodeInstruction> IL2CPP2Managed(IEnumerable<CodeInstr
232236

233237
return code;
234238
}
239+
public static void Log(string msg)
240+
{
241+
if (DEBUG)
242+
{
243+
MelonLogger.Msg(msg);
244+
}
245+
}
235246
}
236247
/// <summary>
237248
/// The Managed mirrored assemblies, all loaded in a separate context. this is where all the mirror methods are stored and generated from.
@@ -248,7 +259,6 @@ public static MirrorData GetMirror(MethodBase Method)
248259
{
249260
return Mirrors.GetValueOrDefault(Method);
250261
}
251-
252262
/// <summary>
253263
/// the assembly from the PC version
254264
/// </summary>
@@ -273,16 +283,15 @@ public static bool IsManaged(Assembly Assembly)
273283
{
274284
return Assembly != null && ( Assembly == ManagedAssembly || StubToNativeMap.ContainsKey(Assembly));
275285
}
276-
internal static void Init()
286+
internal static void Init(AppDomain appDomain)
277287
{
278288
Instance = new MirroredAssemblies();
279289
ManagedAssembly = LoadMirrorAssembly(Paths.PublicizedAssemblyPath);
280290
foreach (var path in Directory.GetFiles(Paths.ManagedPath, "*.dll"))
281291
{
282-
LogService.LogInfo(path);
283-
Assembly stub = LoadMirrorAssembly(path);
292+
Assembly stub = LoadMirrorAssembly(path);
284293
string name = stub.GetName().Name;
285-
Assembly native = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == name);
294+
Assembly native = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => (a.GetName().Name == name || a.GetName().Name == "Il2Cpp"+name) && a != stub);
286295
if (native != null)
287296
{
288297
StubToNativeMap.Add(stub, native);
@@ -300,28 +309,27 @@ public static Assembly LoadMirrorAssembly(string path)
300309
{
301310
return Instance.LoadFromAssemblyPath(Path.GetFullPath(path));
302311
}
303-
304-
public static Type RemapType(Type type, Assembly targetAssembly, Type nativeDeclaringType = null)
312+
public static Type RemapType(Type type, Assembly targetAssembly, Type nativeDeclaringType = null, string NewName = null)
305313
{
306314
if (type == null)
307315
return null;
308316

309317
if (type.Assembly == targetAssembly)
310318
return type;
311-
312319
if (StubToNativeMap.TryGetValue(type.Assembly, out Assembly native) && native != targetAssembly){
320+
Log($"remapped type {type.FullName} to new namespace target " + native.FullName);
313321
return RemapType(type, native, nativeDeclaringType);
314322
}
315323

316324
if (type.IsByRef)
317-
return RemapType(type.GetElementType(), targetAssembly, nativeDeclaringType).MakeByRefType();
325+
return RemapType(type.GetElementType(), targetAssembly, nativeDeclaringType, NewName).MakeByRefType();
318326

319327
if (type.IsPointer)
320-
return RemapType(type.GetElementType(), targetAssembly, nativeDeclaringType).MakePointerType();
328+
return RemapType(type.GetElementType(), targetAssembly, nativeDeclaringType, NewName).MakePointerType();
321329

322330
if (type.IsArray)
323331
{
324-
var element = RemapType(type.GetElementType(), targetAssembly, nativeDeclaringType);
332+
var element = RemapType(type.GetElementType(), targetAssembly, nativeDeclaringType, NewName);
325333
return type.GetArrayRank() == 1 ? element.MakeArrayType() : element.MakeArrayType(type.GetArrayRank());
326334
}
327335

@@ -342,16 +350,40 @@ public static Type RemapType(Type type, Assembly targetAssembly, Type nativeDecl
342350
if (type.IsGenericType && !type.IsGenericTypeDefinition)
343351
{
344352
var genericDef = type.GetGenericTypeDefinition();
345-
var remappedDef = RemapType(genericDef, targetAssembly, nativeDeclaringType);
353+
var remappedDef = RemapType(genericDef, targetAssembly, nativeDeclaringType, NewName);
346354
var args = type.GetGenericArguments()
347-
.Select(t => RemapType(t, targetAssembly, nativeDeclaringType))
355+
.Select(t => RemapType(t, targetAssembly, nativeDeclaringType, NewName))
348356
.ToArray();
349357

350358
return remappedDef.MakeGenericType(args);
351359
}
352-
353-
var remapped = targetAssembly.GetType(type.FullName);
354-
return remapped ?? type;
360+
if (!type.IsValueType && type != typeof(string))
361+
{
362+
if (type.FullName.StartsWith("System.") && targetAssembly == NativeAssembly)
363+
{
364+
Log($"remapped type {type.FullName} to il2cpp system");
365+
return RemapType(type, null, nativeDeclaringType, "Il2Cpp" + type.FullName);
366+
}
367+
else if (type.FullName.StartsWith("Il2Cpp") && targetAssembly == ManagedAssembly)
368+
{
369+
Log($"remapped type {type.FullName} to system");
370+
return RemapType(type, null, nativeDeclaringType, type.FullName[6..]);
371+
}
372+
}
373+
var remapped = targetAssembly?.GetType(NewName ?? type.FullName);
374+
return remapped ?? GetType(NewName ?? type.FullName);
375+
}
376+
public static Type GetType(string FullName)
377+
{
378+
foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
379+
{
380+
Type type = assembly.GetType(FullName);
381+
if (type != null)
382+
{
383+
return type;
384+
}
385+
}
386+
return null;
355387
}
356388

357389
/// <summary>
@@ -452,7 +484,8 @@ public static MirrorData GenerateMirror(MethodBase original, List<MethodInfo> tr
452484
catch (Exception e)
453485
{
454486
LogService.LogError(
455-
$"Mirror Method Generator encountered an error at stage {Stage.Method.Name}, with Exception {e.Message} at {e.StackTrace}");
487+
$"Mirror Method Generator encountered an error at stage {Stage.Method.Name}, with Exception {e.Message} {e.StackTrace}");
488+
Log(Data, true);
456489
throw new InvalidOperationException(e.Message);
457490
}
458491
}
@@ -483,10 +516,45 @@ public static Delegate GenerateDelegate(DynamicMethod dm)
483516
throw new InvalidDataException($"Mirror is Invalid! {ex}");
484517
}
485518
}
486-
487-
public static void getilcode(MethodInfo info)
519+
public static void Log(GeneratorData Data, bool Error)
488520
{
489-
info.GetMethodBody().GetILAsByteArray();
521+
522+
void L(string msg)
523+
{
524+
MelonHelper.Log(msg);
525+
}
526+
527+
if (!TranspilerSupport.DEBUG && !Error)
528+
{
529+
LogService.LogInfo("Not logging debug mirror info");
530+
return;
531+
}
532+
533+
LogService.LogInfo("|--------Mirror Debug Data Dump--------|");
534+
L($"Original Method: {Data.OriginalMethod.GetInfo()}");
535+
L("return type: " + Data.OriginalMethod.ReturnType.GetInfo());
536+
537+
L($"Mirror Method: {Data.MirrorMethod.GetInfo()}");
538+
L("return type: " + Data.MirrorMethod.ReturnType.GetInfo());
539+
L("|------Instructions-----|");
540+
int i = 0;
541+
foreach (var instr in PatchProcessor.GetOriginalInstructions(Data.MirrorMethod))
542+
{
543+
L($"{i} : {instr.GetInfo()}");
544+
i++;
545+
}
546+
547+
L($"Dynamic Method: {Data.Method.GetInfo()}");
548+
L("|------Instructions-----|");
549+
i = 0;
550+
foreach (var instr in Data.Instructions)
551+
{
552+
L($"{i} : {instr.GetInfo()}");
553+
i++;
554+
}
555+
556+
L("return type: " + Data.Method.ReturnType.GetInfo());
557+
LogService.LogInfo("|--------Mirror Debug Data Dump--------|");
490558
}
491559
/// <summary>
492560
/// class containing all default stages for generating mirror methods
@@ -564,45 +632,9 @@ public static void TransformFields(GeneratorData Data)
564632
TransformField(ref instr.opcode, ref instr.operand);
565633
}
566634
}
567-
568635
public static void LogInfo(GeneratorData Data)
569636
{
570-
void L(string msg)
571-
{
572-
MelonHelper.Log(msg);
573-
}
574-
575-
if (!TranspilerSupport.DEBUG)
576-
{
577-
LogService.LogInfo("Not logging debug mirror info");
578-
return;
579-
}
580-
581-
LogService.LogInfo("|--------Mirror Debug Data Dump--------|");
582-
L($"Original Method: {Data.OriginalMethod.GetInfo()}");
583-
L("return type: " + Data.OriginalMethod.ReturnType.GetInfo());
584-
585-
L($"Mirror Method: {Data.MirrorMethod.GetInfo()}");
586-
L("return type: " + Data.MirrorMethod.ReturnType.GetInfo());
587-
L("|------Instructions-----|");
588-
int i = 0;
589-
foreach (var instr in PatchProcessor.GetOriginalInstructions(Data.MirrorMethod))
590-
{
591-
L($"{i} : {instr.GetInfo()}");
592-
i++;
593-
}
594-
595-
L($"Dynamic Method: {Data.Method.GetInfo()}");
596-
L("|------Instructions-----|");
597-
i = 0;
598-
foreach (var instr in Data.Instructions)
599-
{
600-
L($"{i} : {instr.GetInfo()}");
601-
i++;
602-
}
603-
604-
L("return type: " + Data.Method.ReturnType.GetInfo());
605-
LogService.LogInfo("|--------Mirror Debug Data Dump--------|");
637+
Log(Data, false);
606638
}
607639
}
608640

constants/Paths.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static class Paths
4444
public static readonly string NativeModsPath = Combine(StreamingAssetsPath, Others.IsAndroid ? "mods" : "Mods");
4545

4646
/// <summary>
47-
/// Path to game native Managed folder,if on android these are STUB DLLS! DO NOT USE THEM!
47+
/// Path to game native Managed folder, on android these are STUB DLLS! DO NOT USE THEM!
4848
/// </summary>
4949
public static readonly string ManagedPath = !Others.IsAndroid
5050
? Others.is_editor

services/ModCompileLoadService.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ void LoadAddInc()
240240
"System.Collections.Concurrent.dll"
241241
// add any additional DLLs
242242
};
243-
244243
private static List<MetadataReference> LoadDotNetReferencesFromApk(string DotNetPathInApk)
245244
{
246245
List<MetadataReference> references = new List<MetadataReference>();

0 commit comments

Comments
 (0)