diff --git a/Il2CppInspector/Reflection/Extensions.cs b/Il2CppInspector/Reflection/Extensions.cs index 96f2248..2c34d50 100644 --- a/Il2CppInspector/Reflection/Extensions.cs +++ b/Il2CppInspector/Reflection/Extensions.cs @@ -63,7 +63,7 @@ namespace Il2CppInspector.Reflection }; // Output a value in C#-friendly syntax - public static string ToCSharpValue(this object value) { + public static string ToCSharpValue(this object value, TypeInfo type, Scope usingScope = null) { if (value is bool) return (bool) value ? "true" : "false"; if (value is float) @@ -79,12 +79,27 @@ namespace Il2CppInspector.Reflection : str[i].ToString()); return $"\"{s}\""; } - if (!(value is char)) - return (value?.ToString() ?? "null"); - var cValue = (int) (char) value; - if (cValue < 32 || cValue > 126) - return $"'\\x{cValue:x4}'"; - return $"'{value}'"; + if (value is char) { + var cValue = (int) (char) value; + if (cValue < 32 || cValue > 126) + return $"'\\x{cValue:x4}'"; + return $"'{value}'"; + } + if (type.IsEnum) { + var flags = type.GetCustomAttributes("System.FlagsAttribute").Any(); + var values = type.GetEnumNames().Zip(type.GetEnumValues().OfType(), (k, v) => new {k, v}).ToDictionary(x => x.k, x => x.v); + var typePrefix = type.GetScopedCSharpName(usingScope) + "."; + + // We don't know what type the enumeration or value is, so we use Object.Equals() to do content-based equality testing + if (!flags) + return typePrefix + values.First(v => v.Value.Equals(value)).Key; + + // Logical OR a series of flags together + var flagValue = Convert.ToInt64(value); + var setFlags = values.Where(x => (Convert.ToInt64(x.Value) & flagValue) == Convert.ToInt64(x.Value)).Select(x => typePrefix + x.Key); + return string.Join(" | ", setFlags); + } + return (value?.ToString() ?? "null"); } } } diff --git a/Il2CppInspector/Reflection/FieldInfo.cs b/Il2CppInspector/Reflection/FieldInfo.cs index 31182cc..8f4ae15 100644 --- a/Il2CppInspector/Reflection/FieldInfo.cs +++ b/Il2CppInspector/Reflection/FieldInfo.cs @@ -24,7 +24,7 @@ namespace Il2CppInspector.Reflection { public bool HasDefaultValue => (Attributes & FieldAttributes.HasDefault) != 0; public object DefaultValue { get; } - public string DefaultValueString => HasDefaultValue ? DefaultValue.ToCSharpValue() : ""; + public string DefaultValueString => HasDefaultValue ? DefaultValue.ToCSharpValue(FieldType) : ""; // Information/flags about the field public FieldAttributes Attributes { get; } diff --git a/Il2CppInspector/Reflection/ParameterInfo.cs b/Il2CppInspector/Reflection/ParameterInfo.cs index 9554157..cf14530 100644 --- a/Il2CppInspector/Reflection/ParameterInfo.cs +++ b/Il2CppInspector/Reflection/ParameterInfo.cs @@ -108,7 +108,8 @@ namespace Il2CppInspector.Reflection (Position == 0 && DeclaringMethod.GetCustomAttributes("System.Runtime.CompilerServices.ExtensionAttribute").Any()? "this ":"") + $"{CustomAttributes.ToString(usingScope, inline: true, emitPointer: emitPointer, mustCompile: compileAttributes).Replace("[ParamArray]", "params")}" + $"{getCSharpSignatureString(usingScope)} {Name}" - + (HasDefaultValue ? " = " + DefaultValue.ToCSharpValue() + (emitPointer && !(DefaultValue is null)? $" /* Metadata: 0x{(uint) DefaultValueMetadataAddress:X8} */" : "") : ""); + + (HasDefaultValue ? " = " + DefaultValue.ToCSharpValue(ParameterType, usingScope) + + (emitPointer && !(DefaultValue is null)? $" /* Metadata: 0x{(uint) DefaultValueMetadataAddress:X8} */" : "") : ""); public string GetReturnParameterString(Scope scope) => !IsRetval? null : getCSharpSignatureString(scope); }