diff --git a/Il2CppDumper/Il2CppDumper.cs b/Il2CppDumper/Il2CppDumper.cs index 09ee5cf..2d61b2e 100644 --- a/Il2CppDumper/Il2CppDumper.cs +++ b/Il2CppDumper/Il2CppDumper.cs @@ -39,8 +39,10 @@ namespace Il2CppInspector else writer.Write("class "); - var baseText = type.BaseType?.CSharpName ?? string.Empty; - baseText = (baseText == "object" || baseText == "ValueType" || baseText == string.Empty)? string.Empty : " : " + baseText; + var @base = type.ImplementedInterfaces.Select(x => x.CSharpName).ToList(); + if (type.BaseType != null && type.BaseType.FullName != "System.Object" && type.BaseType.FullName != "System.ValueType") + @base.Insert(0, type.BaseType.CSharpName); + var baseText = @base.Count > 0 ? " : " + string.Join(", ", @base) : string.Empty; writer.Write($"{type.Name}{baseText} // TypeDefIndex: {type.Index}\n{{\n"); diff --git a/Il2CppInspector/Metadata.cs b/Il2CppInspector/Metadata.cs index 293b4d6..9024dc9 100644 --- a/Il2CppInspector/Metadata.cs +++ b/Il2CppInspector/Metadata.cs @@ -23,6 +23,7 @@ namespace Il2CppInspector public Il2CppParameterDefinition[] Params { get; } public Il2CppFieldDefinition[] Fields { get; } public Il2CppFieldDefaultValue[] FieldDefaultValues { get; } + public int[] InterfaceUsageIndices { get; } public Dictionary Strings { get; } = new Dictionary(); @@ -51,7 +52,8 @@ namespace Il2CppInspector Params = ReadArray(Header.parametersOffset, Header.parametersCount / Sizeof(typeof(Il2CppParameterDefinition))); Fields = ReadArray(Header.fieldsOffset, Header.fieldsCount / Sizeof(typeof(Il2CppFieldDefinition))); FieldDefaultValues = ReadArray(Header.fieldDefaultValuesOffset, Header.fieldDefaultValuesCount / Sizeof(typeof(Il2CppFieldDefaultValue))); - // TODO: Events, Properties, ParameterDefaultValue, GenericParameters, ParameterConstraints, GenericContainers, Interfaces, MetadataUsage, CustomAttributes + InterfaceUsageIndices = ReadArray(Header.interfacesOffset, Header.interfacesCount / sizeof(int)); + // TODO: Events, Properties, ParameterDefaultValue, GenericParameters, ParameterConstraints, GenericContainers, MetadataUsage, CustomAttributes // Get all string literals Position = Header.stringOffset; diff --git a/Il2CppInspector/Reflection/TypeInfo.cs b/Il2CppInspector/Reflection/TypeInfo.cs index 799ca97..4985553 100644 --- a/Il2CppInspector/Reflection/TypeInfo.cs +++ b/Il2CppInspector/Reflection/TypeInfo.cs @@ -67,6 +67,10 @@ namespace Il2CppInspector.Reflection { public List GenericTypeParameters { get; } public bool HasElementType => ElementType != null; + + private Il2CppType[] implementedInterfaces; + public IEnumerable ImplementedInterfaces => implementedInterfaces.Select(x => Assembly.Model.GetType(x, MemberTypes.TypeInfo)); + public bool IsAbstract => (Attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract; public bool IsArray { get; } public bool IsByRef => throw new NotImplementedException(); @@ -140,6 +144,11 @@ namespace Il2CppInspector.Reflection { if (!IsInterface) Attributes |= TypeAttributes.Class; + // Add all implemented interfaces + implementedInterfaces = new Il2CppType[Definition.interfaces_count]; + for (var i = 0; i < Definition.interfaces_count; i++) + implementedInterfaces[i] = pkg.TypeUsages[pkg.Metadata.InterfaceUsageIndices[Definition.interfacesStart + i]]; + // Add all fields for (var f = Definition.fieldStart; f < Definition.fieldStart + Definition.field_count; f++) DeclaredFields.Add(new FieldInfo(pkg, f, this));