Favor public GetEnumerator over private. Use GetActualType. Improve logging.

This commit is contained in:
Sinai 2021-07-06 16:42:20 +10:00
parent e2b2c9038a
commit f5bce439cb

View File

@ -799,23 +799,24 @@ namespace UnityExplorer
// Some ugly reflection to use the il2cpp interface for the instance type // Some ugly reflection to use the il2cpp interface for the instance type
var type = list.GetType(); var type = list.GetActualType();
var key = type.AssemblyQualifiedName; var key = type.AssemblyQualifiedName;
if (!getEnumeratorMethods.ContainsKey(key)) if (!getEnumeratorMethods.ContainsKey(key))
{ {
var method = type.GetMethod("System_Collections_IEnumerable_GetEnumerator", FLAGS) var method = type.GetMethod("GetEnumerator")
?? type.GetMethod("GetEnumerator"); ?? type.GetMethod("System_Collections_IEnumerable_GetEnumerator", FLAGS);
getEnumeratorMethods.Add(key, method); getEnumeratorMethods.Add(key, method);
// ensure the enumerator type is supported // ensure the enumerator type is supported
try try
{ {
var test = getEnumeratorMethods[key].Invoke(list, null); var test = getEnumeratorMethods[key].Invoke(list, null);
test.GetType().GetMethod("MoveNext").Invoke(test, null); test.GetActualType().GetMethod("MoveNext").Invoke(test, null);
} }
catch catch (Exception ex)
{ {
ExplorerCore.Log($"IEnumerable failed to enumerate: {ex}");
notSupportedTypes.Add(key); notSupportedTypes.Add(key);
} }
} }
@ -824,7 +825,7 @@ namespace UnityExplorer
throw new NotSupportedException($"The IEnumerable type '{type.FullName}' does not support MoveNext."); throw new NotSupportedException($"The IEnumerable type '{type.FullName}' does not support MoveNext.");
cppEnumerator = getEnumeratorMethods[key].Invoke(list, null); cppEnumerator = getEnumeratorMethods[key].Invoke(list, null);
var enumeratorType = cppEnumerator.GetType(); var enumeratorType = cppEnumerator.GetActualType();
var enumInfoKey = enumeratorType.AssemblyQualifiedName; var enumInfoKey = enumeratorType.AssemblyQualifiedName;
@ -878,7 +879,7 @@ namespace UnityExplorer
try try
{ {
var type = dictionary.GetType(); var type = dictionary.GetActualType();
if (typeof(Il2CppSystem.Collections.Hashtable).IsAssignableFrom(type)) if (typeof(Il2CppSystem.Collections.Hashtable).IsAssignableFrom(type))
{ {
@ -888,22 +889,23 @@ namespace UnityExplorer
var keys = type.GetProperty("Keys").GetValue(dictionary, null); var keys = type.GetProperty("Keys").GetValue(dictionary, null);
var keyCollType = keys.GetType(); var keyCollType = keys.GetActualType();
var cacheKey = keys.GetType().AssemblyQualifiedName; var cacheKey = keyCollType.AssemblyQualifiedName;
if (!getEnumeratorMethods.ContainsKey(cacheKey)) if (!getEnumeratorMethods.ContainsKey(cacheKey))
{ {
var method = keyCollType.GetMethod("System_Collections_IDictionary_GetEnumerator", FLAGS) var method = keyCollType.GetMethod("GetEnumerator")
?? keyCollType.GetMethod("GetEnumerator"); ?? keyCollType.GetMethod("System_Collections_IDictionary_GetEnumerator", FLAGS);
getEnumeratorMethods.Add(cacheKey, method); getEnumeratorMethods.Add(cacheKey, method);
// test support // test support
try try
{ {
var test = getEnumeratorMethods[cacheKey].Invoke(keys, null); var test = getEnumeratorMethods[cacheKey].Invoke(keys, null);
test.GetType().GetMethod("MoveNext").Invoke(test, null); test.GetActualType().GetMethod("MoveNext").Invoke(test, null);
} }
catch catch (Exception ex)
{ {
ExplorerCore.Log($"IDictionary failed to enumerate: {ex}");
notSupportedTypes.Add(cacheKey); notSupportedTypes.Add(cacheKey);
} }
} }
@ -914,16 +916,16 @@ namespace UnityExplorer
var keyEnumerator = getEnumeratorMethods[cacheKey].Invoke(keys, null); var keyEnumerator = getEnumeratorMethods[cacheKey].Invoke(keys, null);
var keyInfo = new EnumeratorInfo var keyInfo = new EnumeratorInfo
{ {
current = keyEnumerator.GetType().GetProperty("Current"), current = keyEnumerator.GetActualType().GetProperty("Current"),
moveNext = keyEnumerator.GetType().GetMethod("MoveNext"), moveNext = keyEnumerator.GetActualType().GetMethod("MoveNext"),
}; };
var values = type.GetProperty("Values").GetValue(dictionary, null); var values = type.GetProperty("Values").GetValue(dictionary, null);
var valueEnumerator = values.GetType().GetMethod("GetEnumerator").Invoke(values, null); var valueEnumerator = values.GetActualType().GetMethod("GetEnumerator").Invoke(values, null);
var valueInfo = new EnumeratorInfo var valueInfo = new EnumeratorInfo
{ {
current = valueEnumerator.GetType().GetProperty("Current"), current = valueEnumerator.GetActualType().GetProperty("Current"),
moveNext = valueEnumerator.GetType().GetMethod("MoveNext"), moveNext = valueEnumerator.GetActualType().GetMethod("MoveNext"),
}; };
dictEnumerator = EnumerateCppDict(keyInfo, keyEnumerator, valueInfo, valueEnumerator); dictEnumerator = EnumerateCppDict(keyInfo, keyEnumerator, valueInfo, valueEnumerator);