Model and Output: Implement default method parameter values
This commit is contained in:
@@ -37,6 +37,7 @@ namespace Il2CppInspector
|
||||
public int[] NestedTypeIndices => Metadata.NestedTypeIndices;
|
||||
public int[] AttributeTypeIndices => Metadata.AttributeTypeIndices;
|
||||
public Dictionary<int, object> FieldDefaultValue { get; } = new Dictionary<int, object>();
|
||||
public Dictionary<int, object> ParameterDefaultValue { get; } = new Dictionary<int, object>();
|
||||
public List<long> FieldOffsets { get; }
|
||||
public List<Il2CppType> TypeUsages => Binary.Types;
|
||||
public Dictionary<string, Il2CppCodeGenModule> Modules => Binary.Modules;
|
||||
@@ -45,75 +46,77 @@ namespace Il2CppInspector
|
||||
// TODO: Finish all file access in the constructor and eliminate the need for this
|
||||
public IFileFormatReader BinaryImage => Binary.Image;
|
||||
|
||||
private object getDefaultValue(int typeIndex, int dataIndex) {
|
||||
// No default
|
||||
if (dataIndex == -1)
|
||||
return null;
|
||||
|
||||
// Get pointer in binary to default value
|
||||
var pValue = Metadata.Header.fieldAndParameterDefaultValueDataOffset + dataIndex;
|
||||
var type = TypeUsages[typeIndex];
|
||||
|
||||
// Default value is null
|
||||
if (pValue == 0)
|
||||
return null;
|
||||
|
||||
object value = null;
|
||||
Metadata.Position = pValue;
|
||||
switch (type.type) {
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
|
||||
value = Metadata.ReadBoolean();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_U1:
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_I1:
|
||||
value = Metadata.ReadByte();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
|
||||
// UTF-8 character assumed
|
||||
value = BitConverter.ToChar(Metadata.ReadBytes(2), 0);
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_U2:
|
||||
value = Metadata.ReadUInt16();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_I2:
|
||||
value = Metadata.ReadInt16();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_U4:
|
||||
value = Metadata.ReadUInt32();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_I4:
|
||||
value = Metadata.ReadInt32();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_U8:
|
||||
value = Metadata.ReadUInt64();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_I8:
|
||||
value = Metadata.ReadInt64();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_R4:
|
||||
value = Metadata.ReadSingle();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_R8:
|
||||
value = Metadata.ReadDouble();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
|
||||
var uiLen = Metadata.ReadInt32();
|
||||
value = Encoding.UTF8.GetString(Metadata.ReadBytes(uiLen));
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public Il2CppInspector(Il2CppBinary binary, Metadata metadata) {
|
||||
// Store stream representations
|
||||
Binary = binary;
|
||||
Metadata = metadata;
|
||||
|
||||
// Get all field default values
|
||||
foreach (var fdv in Metadata.FieldDefaultValues) {
|
||||
// No default
|
||||
if (fdv.dataIndex == -1) {
|
||||
FieldDefaultValue.Add(fdv.fieldIndex, null);
|
||||
continue;
|
||||
}
|
||||
foreach (var fdv in Metadata.FieldDefaultValues)
|
||||
FieldDefaultValue.Add(fdv.fieldIndex, getDefaultValue(fdv.typeIndex, fdv.dataIndex));
|
||||
|
||||
// Get pointer in binary to default value
|
||||
var pValue = Metadata.Header.fieldAndParameterDefaultValueDataOffset + fdv.dataIndex;
|
||||
var type = TypeUsages[fdv.typeIndex];
|
||||
|
||||
// Default value is null
|
||||
if (pValue == 0) {
|
||||
FieldDefaultValue.Add(fdv.fieldIndex, null);
|
||||
continue;
|
||||
}
|
||||
|
||||
object value = null;
|
||||
Metadata.Position = pValue;
|
||||
switch (type.type) {
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
|
||||
value = Metadata.ReadBoolean();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_U1:
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_I1:
|
||||
value = Metadata.ReadByte();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
|
||||
// UTF-8 character assumed
|
||||
value = BitConverter.ToChar(Metadata.ReadBytes(2), 0);
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_U2:
|
||||
value = Metadata.ReadUInt16();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_I2:
|
||||
value = Metadata.ReadInt16();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_U4:
|
||||
value = Metadata.ReadUInt32();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_I4:
|
||||
value = Metadata.ReadInt32();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_U8:
|
||||
value = Metadata.ReadUInt64();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_I8:
|
||||
value = Metadata.ReadInt64();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_R4:
|
||||
value = Metadata.ReadSingle();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_R8:
|
||||
value = Metadata.ReadDouble();
|
||||
break;
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
|
||||
var uiLen = Metadata.ReadInt32();
|
||||
value = Encoding.UTF8.GetString(Metadata.ReadBytes(uiLen));
|
||||
break;
|
||||
}
|
||||
|
||||
FieldDefaultValue.Add(fdv.fieldIndex, value);
|
||||
}
|
||||
// Get all parameter default values
|
||||
foreach (var pdv in Metadata.ParameterDefaultValues)
|
||||
ParameterDefaultValue.Add(pdv.parameterIndex, getDefaultValue(pdv.typeIndex, pdv.dataIndex));
|
||||
|
||||
// Get all field offsets
|
||||
if (Binary.FieldOffsets != null) {
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Il2CppInspector
|
||||
public Il2CppParameterDefinition[] Params { get; }
|
||||
public Il2CppFieldDefinition[] Fields { get; }
|
||||
public Il2CppFieldDefaultValue[] FieldDefaultValues { get; }
|
||||
public Il2CppParameterDefaultValue[] ParameterDefaultValues { get; }
|
||||
public Il2CppPropertyDefinition[] Properties { get; }
|
||||
public Il2CppEventDefinition[] Events { get; }
|
||||
public Il2CppGenericContainer[] GenericContainers { get; }
|
||||
@@ -98,6 +99,7 @@ namespace Il2CppInspector
|
||||
Params = ReadArray<Il2CppParameterDefinition>(Header.parametersOffset, Header.parametersCount / Sizeof(typeof(Il2CppParameterDefinition)));
|
||||
Fields = ReadArray<Il2CppFieldDefinition>(Header.fieldsOffset, Header.fieldsCount / Sizeof(typeof(Il2CppFieldDefinition)));
|
||||
FieldDefaultValues = ReadArray<Il2CppFieldDefaultValue>(Header.fieldDefaultValuesOffset, Header.fieldDefaultValuesCount / Sizeof(typeof(Il2CppFieldDefaultValue)));
|
||||
ParameterDefaultValues = ReadArray<Il2CppParameterDefaultValue>(Header.parameterDefaultValuesOffset, Header.parameterDefaultValuesCount / Sizeof(typeof(Il2CppParameterDefaultValue)));
|
||||
Properties = ReadArray<Il2CppPropertyDefinition>(Header.propertiesOffset, Header.propertiesCount / Sizeof(typeof(Il2CppPropertyDefinition)));
|
||||
Events = ReadArray<Il2CppEventDefinition>(Header.eventsOffset, Header.eventsCount / Sizeof(typeof(Il2CppEventDefinition)));
|
||||
InterfaceUsageIndices = ReadArray<int>(Header.interfacesOffset, Header.interfacesCount / sizeof(int));
|
||||
@@ -109,7 +111,7 @@ namespace Il2CppInspector
|
||||
AttributeTypeIndices = ReadArray<int>(Header.attributeTypesOffset, Header.attributeTypesCount / sizeof(int));
|
||||
AttributeTypeRanges = ReadArray<Il2CppCustomAttributeTypeRange>(Header.attributesInfoOffset, Header.attributesInfoCount / Sizeof(typeof(Il2CppCustomAttributeTypeRange)));
|
||||
}
|
||||
// TODO: ParameterDefaultValue, ParameterConstraints, MetadataUsage
|
||||
// TODO: ParameterConstraints, MetadataUsage
|
||||
|
||||
// Get all string literals
|
||||
Position = Header.stringOffset;
|
||||
|
||||
@@ -254,6 +254,13 @@ namespace Il2CppInspector
|
||||
public int typeIndex;
|
||||
}
|
||||
|
||||
public class Il2CppParameterDefaultValue
|
||||
{
|
||||
public int parameterIndex;
|
||||
public int typeIndex;
|
||||
public int dataIndex;
|
||||
}
|
||||
|
||||
public class Il2CppFieldDefinition
|
||||
{
|
||||
public int nameIndex;
|
||||
|
||||
@@ -160,7 +160,8 @@ namespace Il2CppInspector.Reflection
|
||||
// Get C# syntax-friendly list of parameters
|
||||
public string GetParametersString() =>
|
||||
string.Join(", ", DeclaredParameters.Select(p => $"{p.CustomAttributes.ToString(inline: true).Replace("[ParamArray]", "params")}"
|
||||
+ $"{p.GetModifierString()}{p.ParameterType.CSharpName} {p.Name}"));
|
||||
+ $"{p.GetModifierString()}{p.ParameterType.CSharpName} {p.Name}"
|
||||
+ (p.HasDefaultValue? " = " + p.DefaultValue.ToCSharpValue() : "")));
|
||||
|
||||
public string GetTypeParametersString() => GenericTypeParameters == null? "" :
|
||||
"<" + string.Join(", ", GenericTypeParameters.Select(p => p.CSharpName)) + ">";
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Il2CppInspector.Reflection
|
||||
public bool HasDefaultValue => (Attributes & ParameterAttributes.HasDefault) != 0;
|
||||
|
||||
// Default value for the parameter
|
||||
public object DefaultValue => throw new NotImplementedException();
|
||||
public object DefaultValue { get; }
|
||||
|
||||
public bool IsIn => (Attributes & ParameterAttributes.In) != 0;
|
||||
public bool IsOptional => (Attributes & ParameterAttributes.Optional) != 0;
|
||||
@@ -80,11 +80,12 @@ namespace Il2CppInspector.Reflection
|
||||
if (Position == -1)
|
||||
Attributes |= ParameterAttributes.Retval;
|
||||
|
||||
// TODO: DefaultValue/HasDefaultValue
|
||||
// Default initialization value if present
|
||||
if (pkg.ParameterDefaultValue.TryGetValue(paramIndex, out object variant))
|
||||
DefaultValue = variant;
|
||||
}
|
||||
|
||||
public string GetModifierString() =>
|
||||
(IsOptional? "optional " : "") +
|
||||
(IsOut? "out " : "");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user