11using HarmonyLib ;
22using HarmonyLib . Public . Patching ;
33using HarmonyLib . Tools ;
4+ using Il2CppInterop . Runtime . InteropTypes . Arrays ;
45using Il2CppSystem . Runtime . Remoting . Messaging ;
56using MelonLoader ;
67using MonoMod . Cil ;
@@ -105,9 +106,9 @@ internal static void Initialize(Harmony harmony)
105106
106107 static void ManagedField ( ref Type type )
107108 {
108- if ( MirroredAssemblies . TryGetNative ( type . Assembly , out Assembly native ) )
109+ if ( MirroredAssemblies . TryGetManaged ( type . Assembly , out Assembly managed ) )
109110 {
110- type = MirroredAssemblies . RemapType ( type , native ) ;
111+ type = MirroredAssemblies . RemapType ( type , managed ) ;
111112 }
112113 }
113114
@@ -268,10 +269,23 @@ public static MirrorData GetMirror(MethodBase Method)
268269 /// the IL2CPP Assembly
269270 /// </summary>
270271 public static Assembly NativeAssembly { get ; internal set ; }
271- static Dictionary < Assembly , Assembly > StubToNativeMap = [ ] ;
272+ static Dictionary < Assembly , Assembly > ManagedToNative = [ ] ;
272273 public static bool TryGetNative ( Assembly Managed , out Assembly Native )
273274 {
274- return StubToNativeMap . TryGetValue ( Managed , out Native ) ;
275+ return ManagedToNative . TryGetValue ( Managed , out Native ) ;
276+ }
277+ public static bool TryGetManaged ( Assembly Native , out Assembly Managed )
278+ {
279+ foreach ( KeyValuePair < Assembly , Assembly > pair in ManagedToNative )
280+ {
281+ if ( pair . Value == Native )
282+ {
283+ Managed = pair . Key ;
284+ return true ;
285+ }
286+ }
287+ Managed = null ;
288+ return false ;
275289 }
276290 private MirroredAssemblies ( ) : base ( "ManagedAssemblies" , isCollectible : false )
277291 {
@@ -281,42 +295,51 @@ private MirroredAssemblies() : base("ManagedAssemblies", isCollectible: false)
281295 private static MirroredAssemblies Instance ;
282296 public static bool IsManaged ( Assembly Assembly )
283297 {
284- return Assembly != null && ( Assembly == ManagedAssembly || StubToNativeMap . ContainsKey ( Assembly ) ) ;
298+ return Assembly != null && ( Assembly == ManagedAssembly || ManagedToNative . ContainsKey ( Assembly ) ) ;
285299 }
286300 internal static void Init ( AppDomain appDomain )
287301 {
288302 Instance = new MirroredAssemblies ( ) ;
289303 ManagedAssembly = LoadMirrorAssembly ( Paths . PublicizedAssemblyPath ) ;
304+ NativeAssembly = typeof ( Actor ) . Assembly ;
305+ ManagedToNative . Add ( ManagedAssembly , NativeAssembly ) ;
290306 foreach ( var path in Directory . GetFiles ( Paths . ManagedPath , "*.dll" ) )
291307 {
292308 Assembly stub = LoadMirrorAssembly ( path ) ;
293309 string name = stub . GetName ( ) . Name ;
294310 Assembly native = AppDomain . CurrentDomain . GetAssemblies ( ) . FirstOrDefault ( a => ( a . GetName ( ) . Name == name || a . GetName ( ) . Name == "Il2Cpp" + name ) && a != stub ) ;
295311 if ( native != null )
296312 {
297- StubToNativeMap . Add ( stub , native ) ;
313+ ManagedToNative . Add ( stub , native ) ;
298314 }
299315 else
300316 {
301317 LogService . LogWarning ( $ "Failed to find native assembly for { name } ") ;
302318 }
303319 }
304- NativeAssembly = typeof ( Actor ) . Assembly ;
305320 Generator . Init ( ) ;
306321 }
307322
308323 public static Assembly LoadMirrorAssembly ( string path )
309324 {
310325 return Instance . LoadFromAssemblyPath ( Path . GetFullPath ( path ) ) ;
311326 }
327+ /// <summary>
328+ /// Remaps a type from native assemblies and managed assemblies
329+ /// </summary>
330+ /// <param name="type">the type</param>
331+ /// <param name="targetAssembly">the target assembly. this can be overwritten automatically</param>
332+ /// <param name="nativeDeclaringType">if this is a generic argument, the declaringtype is the class that has this generic argument</param>
333+ /// <param name="NewName">its new Full name</param>
334+ /// <returns></returns>
312335 public static Type RemapType ( Type type , Assembly targetAssembly , Type nativeDeclaringType = null , string NewName = null )
313336 {
314337 if ( type == null )
315338 return null ;
316339
317340 if ( type . Assembly == targetAssembly )
318341 return type ;
319- if ( StubToNativeMap . TryGetValue ( type . Assembly , out Assembly native ) && native != targetAssembly ) {
342+ if ( ManagedToNative . TryGetValue ( type . Assembly , out Assembly native ) && native != targetAssembly ) {
320343 Log ( $ "remapped type { type . FullName } to new namespace target " + native . FullName ) ;
321344 return RemapType ( type , native , nativeDeclaringType ) ;
322345 }
@@ -330,7 +353,21 @@ public static Type RemapType(Type type, Assembly targetAssembly, Type nativeDecl
330353 if ( type . IsArray )
331354 {
332355 var element = RemapType ( type . GetElementType ( ) , targetAssembly , nativeDeclaringType , NewName ) ;
333- return type . GetArrayRank ( ) == 1 ? element . MakeArrayType ( ) : element . MakeArrayType ( type . GetArrayRank ( ) ) ;
356+
357+ if ( targetAssembly != ManagedAssembly )
358+ {
359+ if ( element == typeof ( string ) )
360+ {
361+ return typeof ( Il2CppStringArray ) ;
362+ }
363+ var wrapper = element . IsValueType
364+ ? typeof ( Il2CppStructArray < > )
365+ : typeof ( Il2CppReferenceArray < > ) ;
366+
367+ return wrapper . MakeGenericType ( element ) ;
368+ }
369+
370+ return element . MakeArrayType ( ) ;
334371 }
335372
336373 if ( type . IsGenericParameter )
@@ -357,7 +394,7 @@ public static Type RemapType(Type type, Assembly targetAssembly, Type nativeDecl
357394
358395 return remappedDef . MakeGenericType ( args ) ;
359396 }
360- if ( ! type . IsValueType && type != typeof ( string ) )
397+ if ( ! IsCoreValueType ( type ) )
361398 {
362399 if ( type . FullName . StartsWith ( "System." ) && targetAssembly == NativeAssembly )
363400 {
@@ -370,9 +407,24 @@ public static Type RemapType(Type type, Assembly targetAssembly, Type nativeDecl
370407 return RemapType ( type , null , nativeDeclaringType , type . FullName [ 6 ..] ) ;
371408 }
372409 }
410+ else
411+ {
412+ return type ;
413+ }
373414 var remapped = targetAssembly ? . GetType ( NewName ?? type . FullName ) ;
374415 return remapped ?? GetType ( NewName ?? type . FullName ) ;
375416 }
417+ static bool IsCoreValueType ( Type t )
418+ {
419+ if ( t . IsPrimitive )
420+ return true ;
421+
422+ return t == typeof ( decimal )
423+ || t == typeof ( DateTime )
424+ || t == typeof ( Guid )
425+ || t == typeof ( string )
426+ || t == typeof ( void ) ;
427+ }
376428 public static Type GetType ( string FullName )
377429 {
378430 foreach ( Assembly assembly in AppDomain . CurrentDomain . GetAssemblies ( ) )
@@ -513,7 +565,7 @@ public static Delegate GenerateDelegate(DynamicMethod dm)
513565 catch ( Exception ex )
514566 {
515567 LogService . LogError ( $ "Failed to Generate Mirror Delegate! the IL Code is Invalid! { ex } ") ;
516- throw new InvalidDataException ( $ "Mirror is Invalid! { ex } ") ;
568+ throw new InvalidDataException ( $ "Mirror is Invalid!") ;
517569 }
518570 }
519571 public static void Log ( GeneratorData Data , bool Error )
@@ -705,7 +757,7 @@ private static object RemapOperand(object operand)
705757 if ( t1 . GetGenericTypeDefinition ( ) != t2 . GetGenericTypeDefinition ( ) )
706758 return false ;
707759 }
708- else if ( t1 != t2 )
760+ else if ( ! t2 . IsAssignableFrom ( t1 ) )
709761 return false ;
710762 }
711763
0 commit comments