diff --git a/Il2CppDumper/Il2CppCSharpDumper.cs b/Il2CppDumper/Il2CppCSharpDumper.cs index 182b8c1..45867be 100644 --- a/Il2CppDumper/Il2CppCSharpDumper.cs +++ b/Il2CppDumper/Il2CppCSharpDumper.cs @@ -261,7 +261,7 @@ namespace Il2CppInspector // Non-indexer if ((!prop.CanRead || !prop.GetMethod.DeclaredParameters.Any()) && (!prop.CanWrite || prop.SetMethod.DeclaredParameters.Count == 1)) - sb.Append($"{prop.Name} {{ "); + sb.Append($"{prop.CSharpName} {{ "); // Indexer else sb.Append("this[" + string.Join(", ", primary.DeclaredParameters.SkipLast(getAccess >= setAccess? 0 : 1) diff --git a/Il2CppInspector/Reflection/MethodBase.cs b/Il2CppInspector/Reflection/MethodBase.cs index eb573c6..15cdbe6 100644 --- a/Il2CppInspector/Reflection/MethodBase.cs +++ b/Il2CppInspector/Reflection/MethodBase.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; namespace Il2CppInspector.Reflection { @@ -53,7 +54,21 @@ namespace Il2CppInspector.Reflection public string CSharpName => // Operator overload or user-defined conversion operator - OperatorMethodNames.ContainsKey(Name)? "operator " + OperatorMethodNames[Name] : Name; + OperatorMethodNames.ContainsKey(Name)? "operator " + OperatorMethodNames[Name] + + // Explicit interface implementation + : (IsVirtual && IsFinal && (Attributes & MethodAttributes.VtableLayoutMask) == MethodAttributes.NewSlot)? + ((Func)(() => { + var implementingInterface = DeclaringType.ImplementedInterfaces.FirstOrDefault(i => Name.StartsWith(Regex.Replace(i.FullName, @"`\d", "").Replace('[', '<').Replace(']', '>') + ".")); + // Regular interface implementation + if (implementingInterface == null) + return Name; + var sliceLength = Regex.Replace(implementingInterface.FullName, @"`\d", "").Length + 1; + return implementingInterface.CSharpName + "." + Name.Substring(sliceLength); + }))() + + // Regular method + : Name; protected MethodBase(Il2CppInspector pkg, int methodIndex, TypeInfo declaringType) : base(declaringType) { Definition = pkg.Methods[methodIndex]; @@ -120,7 +135,7 @@ namespace Il2CppInspector.Reflection { IsConstructor: true, IsStatic: true } => "", // Explicit interface implementations do not have an access level modifier - { Name: var name } when name.IndexOf('.') != -1 => "", + { IsVirtual: true, IsFinal: true, Attributes: var a } when (a & MethodAttributes.VtableLayoutMask) == MethodAttributes.NewSlot => "", { IsPrivate: true } => "private ", { IsPublic: true } => "public ", diff --git a/Il2CppInspector/Reflection/PropertyInfo.cs b/Il2CppInspector/Reflection/PropertyInfo.cs index 70c440c..33ec170 100644 --- a/Il2CppInspector/Reflection/PropertyInfo.cs +++ b/Il2CppInspector/Reflection/PropertyInfo.cs @@ -26,6 +26,13 @@ namespace Il2CppInspector.Reflection { public override string Name { get; protected set; } + public string CSharpName => + // Explicit interface implementation + Name.IndexOf('.') != -1? string.Join('.', Name.Split('.')[^2..]) + + // Regular method + : Name; + public TypeInfo PropertyType => GetMethod?.ReturnType ?? SetMethod.DeclaredParameters[^1].ParameterType; public override MemberTypes MemberType => MemberTypes.Property;