Skip to content
This repository was archived by the owner on May 9, 2023. It is now read-only.

Commit 2cc403a

Browse files
committed
Cleanup runtime-specific
1 parent c2d9b9b commit 2cc403a

29 files changed

+362
-288
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
An in-game explorer and a suite of debugging tools for <a href="https://docs.unity3d.com/Manual/IL2CPP.html">IL2CPP</a> and <b>Mono</b> Unity games, to aid with modding development.
77
</p>
88

9-
## Releases [![](https://img.shields.io/github/release/sinai-dev/Explorer.svg?label=release%20notes)](../../releases/latest) [![](https://img.shields.io/github/downloads/sinai-dev/Explorer/total.svg)](../../releases) [![](https://img.shields.io/github/downloads/sinai-dev/Explorer/latest/total.svg)](../../releases/latest)
9+
## Releases [![](https://img.shields.io/github/release/sinai-dev/UnityExplorer.svg?label=release%20notes)](../../releases/latest) [![](https://img.shields.io/github/downloads/sinai-dev/UnityExplorer/total.svg)](../../releases) [![](https://img.shields.io/github/downloads/sinai-dev/UnityExplorer/latest/total.svg)](../../releases/latest)
1010

1111
| Mod Loader | IL2CPP | Mono |
1212
| ----------- | ------ | ---- |

src/Core/CSharp/ScriptInteraction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static void Log(object message)
2020

2121
public static void StartCoroutine(IEnumerator ienumerator)
2222
{
23-
RuntimeProvider.Instance.StartConsoleCoroutine(ienumerator);
23+
RuntimeProvider.Instance.StartCoroutine(ienumerator);
2424
}
2525

2626
public static void AddUsing(string directive)

src/Core/Input/CursorUnlocker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,4 @@ public static void Prefix_set_visible(ref bool value)
189189
}
190190
}
191191
}
192-
}
192+
}

src/Core/Input/IHandleInput.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ public interface IHandleInput
1818
void AddUIInputModule();
1919
void ActivateModule();
2020
}
21-
}
21+
}

src/Core/Input/InputSystem.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
using UnityExplorer.UI;
77
using System.Collections.Generic;
88
using UnityExplorer.UI.Inspectors;
9-
#if CPP
10-
using UnhollowerRuntimeLib;
11-
#endif
129

1310
namespace UnityExplorer.Core.Input
1411
{
@@ -152,13 +149,9 @@ public void AddUIInputModule()
152149
}
153150

154151
var assetType = ReflectionUtility.GetTypeByName("UnityEngine.InputSystem.InputActionAsset");
155-
#if CPP
156-
m_newInputModule = UIManager.CanvasRoot.AddComponent(Il2CppType.From(TInputSystemUIInputModule)).TryCast<BaseInputModule>();
157-
var asset = ScriptableObject.CreateInstance(Il2CppType.From(assetType));
158-
#else
159-
m_newInputModule = (BaseInputModule)UIManager.CanvasRoot.AddComponent(TInputSystemUIInputModule);
160-
var asset = ScriptableObject.CreateInstance(assetType);
161-
#endif
152+
m_newInputModule = RuntimeProvider.Instance.AddComponent<BaseInputModule>(UIManager.CanvasRoot, TInputSystemUIInputModule);
153+
var asset = RuntimeProvider.Instance.CreateScriptable(assetType);
154+
162155
inputExtensions = ReflectionUtility.GetTypeByName("UnityEngine.InputSystem.InputActionSetupExtensions");
163156

164157
var addMap = inputExtensions.GetMethod("AddActionMap", new Type[] { assetType, typeof(string) });
@@ -205,4 +198,4 @@ public void ActivateModule()
205198
UI_Enable.Invoke(UI_ActionMap, new object[0]);
206199
}
207200
}
208-
}
201+
}

src/Core/Input/LegacyInput.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,4 @@ public void ActivateModule()
5454
m_inputModule.ActivateModule();
5555
}
5656
}
57-
}
57+
}

src/Core/Input/NoInput.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ public class NoInput : IHandleInput
1919
public void ActivateModule() { }
2020
public void AddUIInputModule() { }
2121
}
22-
}
22+
}

src/Core/ReflectionUtility.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ public static object Cast(this object obj)
4343
public static object Cast(this object obj, Type castTo)
4444
=> ReflectionProvider.Instance.Cast(obj, castTo);
4545

46+
public static T TryCast<T>(this object obj)
47+
=> ReflectionProvider.Instance.TryCast<T>(obj);
48+
4649
/// <summary>
4750
/// Check if the provided Type is assignable to IEnumerable.
4851
/// </summary>
@@ -201,10 +204,9 @@ public static string ReflectionExToString(this Exception e, bool innerMost = fal
201204
{
202205
while (e.InnerException != null)
203206
{
204-
#if CPP
205207
if (e.InnerException is System.Runtime.CompilerServices.RuntimeWrappedException)
206208
break;
207-
#endif
209+
208210
e = e.InnerException;
209211
}
210212
}

src/Core/Runtime/Il2Cpp/Il2CppProvider.cs

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,47 @@ private void Application_logMessageReceived(string condition, string stackTrace,
5050
ExplorerCore.Log(condition, type, true);
5151
}
5252

53-
public override void StartConsoleCoroutine(IEnumerator routine)
53+
public override void StartCoroutine(IEnumerator routine)
5454
{
5555
Il2CppCoroutine.Start(routine);
5656
}
5757

58-
// Unity API Handlers
58+
public override void Update()
59+
{
60+
Il2CppCoroutine.Process();
61+
}
62+
63+
public override T AddComponent<T>(GameObject obj, Type type)
64+
{
65+
return obj.AddComponent(Il2CppType.From(type)).TryCast<T>();
66+
}
67+
68+
public override ScriptableObject CreateScriptable(Type type)
69+
{
70+
return ScriptableObject.CreateInstance(Il2CppType.From(type));
71+
}
72+
73+
public override void GraphicRaycast(GraphicRaycaster raycaster, PointerEventData data, List<RaycastResult> list)
74+
{
75+
var il2cppList = new Il2CppSystem.Collections.Generic.List<RaycastResult>();
76+
77+
raycaster.Raycast(data, il2cppList);
78+
79+
if (il2cppList.Count > 0)
80+
list.AddRange(il2cppList.ToArray());
81+
}
82+
83+
public override bool IsReferenceEqual(object a, object b)
84+
{
85+
if (a.TryCast<UnityEngine.Object>() is UnityEngine.Object ua)
86+
{
87+
var ub = b.TryCast<UnityEngine.Object>();
88+
if (ub && ua.m_CachedPtr == ub.m_CachedPtr)
89+
return true;
90+
}
91+
92+
return base.IsReferenceEqual(a, b);
93+
}
5994

6095
// LayerMask.LayerToName
6196

@@ -162,6 +197,26 @@ public override ColorBlock SetColorBlock(ColorBlock colors, Color? normal = null
162197

163198
return colors;
164199
}
200+
201+
public override void FindSingleton(string[] possibleNames, Type type, BF flags, List<object> instances)
202+
{
203+
PropertyInfo pi;
204+
foreach (var name in possibleNames)
205+
{
206+
pi = type.GetProperty(name, flags);
207+
if (pi != null)
208+
{
209+
var instance = pi.GetValue(null, null);
210+
if (instance != null)
211+
{
212+
instances.Add(instance);
213+
return;
214+
}
215+
}
216+
}
217+
218+
base.FindSingleton(possibleNames, type, flags, instances);
219+
}
165220
}
166221
}
167222

src/Core/Runtime/Il2Cpp/Il2CppReflection.cs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ public override object Cast(object obj, Type castTo)
3232
return Il2CppCast(obj, castTo);
3333
}
3434

35+
public override T TryCast<T>(object obj)
36+
{
37+
try
38+
{
39+
return (T)Il2CppCast(obj, typeof(T));
40+
}
41+
catch
42+
{
43+
return default;
44+
}
45+
}
46+
3547
public override string ProcessTypeNameInString(Type type, string theString, ref string typeName)
3648
{
3749
if (!Il2CppTypeNotNull(type))
@@ -367,6 +379,124 @@ public static object Unbox(object obj, Type type)
367379

368380
return s_unboxMethods[name].Invoke(obj, new object[0]);
369381
}
382+
383+
public override string UnboxString(object value)
384+
{
385+
string s = null;
386+
// strings boxed as Il2CppSystem.Objects can behave weirdly.
387+
// GetActualType will find they are a string, but if its boxed
388+
// then we need to unbox it like this...
389+
if (!(value is string) && value is Il2CppSystem.Object cppobj)
390+
s = cppobj.ToString();
391+
392+
return s;
393+
}
394+
395+
internal static readonly Dictionary<Type, MethodInfo> s_getEnumeratorMethods = new Dictionary<Type, MethodInfo>();
396+
397+
internal static readonly Dictionary<Type, EnumeratorInfo> s_enumeratorInfos = new Dictionary<Type, EnumeratorInfo>();
398+
399+
internal class EnumeratorInfo
400+
{
401+
internal MethodInfo moveNext;
402+
internal PropertyInfo current;
403+
}
404+
405+
public override IEnumerable EnumerateEnumerable(object value)
406+
{
407+
if (value == null)
408+
return null;
409+
410+
var cppEnumerable = (value as Il2CppSystem.Object)?.TryCast<Il2CppSystem.Collections.IEnumerable>();
411+
if (cppEnumerable != null)
412+
{
413+
var type = value.GetType();
414+
if (!s_getEnumeratorMethods.ContainsKey(type))
415+
s_getEnumeratorMethods.Add(type, type.GetMethod("GetEnumerator"));
416+
417+
var enumerator = s_getEnumeratorMethods[type].Invoke(value, null);
418+
var enumeratorType = enumerator.GetType();
419+
420+
if (!s_enumeratorInfos.ContainsKey(enumeratorType))
421+
{
422+
s_enumeratorInfos.Add(enumeratorType, new EnumeratorInfo
423+
{
424+
current = enumeratorType.GetProperty("Current"),
425+
moveNext = enumeratorType.GetMethod("MoveNext"),
426+
});
427+
}
428+
var info = s_enumeratorInfos[enumeratorType];
429+
430+
// iterate
431+
var list = new List<object>();
432+
while ((bool)info.moveNext.Invoke(enumerator, null))
433+
list.Add(info.current.GetValue(enumerator));
434+
435+
return list;
436+
}
437+
438+
return null;
439+
}
440+
441+
public override IDictionary EnumerateDictionary(object value, Type typeOfKeys, Type typeOfValues)
442+
{
443+
var valueType = ReflectionUtility.GetActualType(value);
444+
445+
var keyList = new List<object>();
446+
var valueList = new List<object>();
447+
448+
var hashtable = value.Cast(typeof(Il2CppSystem.Collections.Hashtable)) as Il2CppSystem.Collections.Hashtable;
449+
450+
if (hashtable != null)
451+
{
452+
EnumerateCppHashtable(hashtable, keyList, valueList);
453+
}
454+
else
455+
{
456+
var keys = valueType.GetProperty("Keys").GetValue(value, null);
457+
var values = valueType.GetProperty("Values").GetValue(value, null);
458+
459+
EnumerateCppIDictionary(keys, keyList);
460+
EnumerateCppIDictionary(values, valueList);
461+
}
462+
463+
var dict = Activator.CreateInstance(typeof(Dictionary<,>)
464+
.MakeGenericType(typeOfKeys, typeOfValues))
465+
as IDictionary;
466+
467+
for (int i = 0; i < keyList.Count; i++)
468+
dict.Add(keyList[i], valueList[i]);
469+
470+
return dict;
471+
}
472+
473+
private void EnumerateCppIDictionary(object collection, List<object> list)
474+
{
475+
// invoke GetEnumerator
476+
var enumerator = collection.GetType().GetMethod("GetEnumerator").Invoke(collection, null);
477+
// get the type of it
478+
var enumeratorType = enumerator.GetType();
479+
// reflect MoveNext and Current
480+
var moveNext = enumeratorType.GetMethod("MoveNext");
481+
var current = enumeratorType.GetProperty("Current");
482+
// iterate
483+
while ((bool)moveNext.Invoke(enumerator, null))
484+
{
485+
list.Add(current.GetValue(enumerator, null));
486+
}
487+
}
488+
489+
private void EnumerateCppHashtable(Il2CppSystem.Collections.Hashtable hashtable, List<object> keys, List<object> values)
490+
{
491+
for (int i = 0; i < hashtable.buckets.Count; i++)
492+
{
493+
var bucket = hashtable.buckets[i];
494+
if (bucket == null || bucket.key == null)
495+
continue;
496+
keys.Add(bucket.key);
497+
values.Add(bucket.val);
498+
}
499+
}
370500
}
371501
}
372502

0 commit comments

Comments
 (0)