private void AddFields(Il2CppTypeDefinition typeDef, List <StructFieldInfo> fields, List <StructFieldInfo> staticFields, Il2CppGenericContext context, bool isParent) { if (!typeDef.IsValueType && !typeDef.IsEnum) { if (typeDef.parentIndex >= 0) { var parent = il2Cpp.types[typeDef.parentIndex]; ParseParent(parent, out var parentDef, out var parentContext); if (parentDef != null) { AddFields(parentDef, fields, staticFields, parentContext, true); } } } if (typeDef.field_count > 0) { var fieldEnd = typeDef.fieldStart + typeDef.field_count; for (var i = typeDef.fieldStart; i < fieldEnd; ++i) { var fieldDef = metadata.fieldDefs[i]; var fieldType = il2Cpp.types[fieldDef.typeIndex]; if ((fieldType.attrs & FIELD_ATTRIBUTE_LITERAL) != 0) { continue; } var structFieldInfo = new StructFieldInfo(); structFieldInfo.FieldTypeName = ParseType(fieldType, context); var fieldName = FixName(metadata.GetStringFromIndex(fieldDef.nameIndex)); structFieldInfo.FieldName = fieldName; structFieldInfo.IsValueType = IsValueType(fieldType, context); if ((fieldType.attrs & FIELD_ATTRIBUTE_STATIC) != 0) { if (!isParent) { staticFields.Add(structFieldInfo); } } else { if (isParent) { var access = fieldType.attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK; if (access == FIELD_ATTRIBUTE_PRIVATE) { structFieldInfo.FieldName = $"{FixName(metadata.GetStringFromIndex(typeDef.nameIndex))}_{fieldName}"; } } if (fields.Any(x => x.FieldName == structFieldInfo.FieldName)) { structFieldInfo.FieldName = $"{FixName(metadata.GetStringFromIndex(typeDef.nameIndex))}_{structFieldInfo.FieldName}"; } fields.Add(structFieldInfo); } } } }
private string GetIl2CppStructName(Il2CppType il2CppType, Il2CppGenericContext context = null) { switch (il2CppType.type) { case Il2CppTypeEnum.IL2CPP_TYPE_VOID: case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN: case Il2CppTypeEnum.IL2CPP_TYPE_CHAR: case Il2CppTypeEnum.IL2CPP_TYPE_I1: case Il2CppTypeEnum.IL2CPP_TYPE_U1: case Il2CppTypeEnum.IL2CPP_TYPE_I2: case Il2CppTypeEnum.IL2CPP_TYPE_U2: case Il2CppTypeEnum.IL2CPP_TYPE_I4: case Il2CppTypeEnum.IL2CPP_TYPE_U4: case Il2CppTypeEnum.IL2CPP_TYPE_I8: case Il2CppTypeEnum.IL2CPP_TYPE_U8: case Il2CppTypeEnum.IL2CPP_TYPE_R4: case Il2CppTypeEnum.IL2CPP_TYPE_R8: case Il2CppTypeEnum.IL2CPP_TYPE_STRING: case Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF: case Il2CppTypeEnum.IL2CPP_TYPE_I: case Il2CppTypeEnum.IL2CPP_TYPE_U: case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE: case Il2CppTypeEnum.IL2CPP_TYPE_CLASS: case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT: { var typeDef = metadata.typeDefs[il2CppType.data.klassIndex]; return(structNameDic[typeDef]); } case Il2CppTypeEnum.IL2CPP_TYPE_PTR: { var oriType = il2Cpp.GetIl2CppType(il2CppType.data.type); return(GetIl2CppStructName(oriType)); } case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY: { var arrayType = il2Cpp.MapVATR <Il2CppArrayType>(il2CppType.data.array); var elementType = il2Cpp.GetIl2CppType(arrayType.etype); var elementStructName = GetIl2CppStructName(elementType, context); var typeStructName = elementStructName + "_array"; if (structNameHashSet.Add(typeStructName)) { ParseArrayClassStruct(elementType, context); } return(typeStructName); } case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY: { var elementType = il2Cpp.GetIl2CppType(il2CppType.data.type); var elementStructName = GetIl2CppStructName(elementType, context); var typeStructName = elementStructName + "_array"; if (structNameHashSet.Add(typeStructName)) { ParseArrayClassStruct(elementType, context); } return(typeStructName); } case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST: { var typeStructName = genericClassStructNameDic[il2CppType.data.generic_class]; if (structNameHashSet.Add(typeStructName)) { genericClassList.Add(il2CppType.data.generic_class); } return(typeStructName); } case Il2CppTypeEnum.IL2CPP_TYPE_VAR: { if (context != null) { var genericParameter = metadata.genericParameters[il2CppType.data.genericParameterIndex]; var genericInst = il2Cpp.MapVATR <Il2CppGenericInst>(context.class_inst); var pointers = il2Cpp.MapVATR <ulong>(genericInst.type_argv, genericInst.type_argc); var pointer = pointers[genericParameter.num]; var type = il2Cpp.GetIl2CppType(pointer); return(GetIl2CppStructName(type)); } return("System_Object"); } case Il2CppTypeEnum.IL2CPP_TYPE_MVAR: { if (context != null) { var genericParameter = metadata.genericParameters[il2CppType.data.genericParameterIndex]; var genericInst = il2Cpp.MapVATR <Il2CppGenericInst>(context.method_inst); var pointers = il2Cpp.MapVATR <ulong>(genericInst.type_argv, genericInst.type_argc); var pointer = pointers[genericParameter.num]; var type = il2Cpp.GetIl2CppType(pointer); return(GetIl2CppStructName(type)); } return("System_Object"); } default: throw new NotSupportedException(); } }
private string ParseType(Il2CppType il2CppType, Il2CppGenericContext context = null) { switch (il2CppType.type) { case Il2CppTypeEnum.IL2CPP_TYPE_VOID: return("void"); case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN: return("bool"); case Il2CppTypeEnum.IL2CPP_TYPE_CHAR: return("uint16_t"); //Il2CppChar case Il2CppTypeEnum.IL2CPP_TYPE_I1: return("int8_t"); case Il2CppTypeEnum.IL2CPP_TYPE_U1: return("uint8_t"); case Il2CppTypeEnum.IL2CPP_TYPE_I2: return("int16_t"); case Il2CppTypeEnum.IL2CPP_TYPE_U2: return("uint16_t"); case Il2CppTypeEnum.IL2CPP_TYPE_I4: return("int32_t"); case Il2CppTypeEnum.IL2CPP_TYPE_U4: return("uint32_t"); case Il2CppTypeEnum.IL2CPP_TYPE_I8: return("int64_t"); case Il2CppTypeEnum.IL2CPP_TYPE_U8: return("uint64_t"); case Il2CppTypeEnum.IL2CPP_TYPE_R4: return("float"); case Il2CppTypeEnum.IL2CPP_TYPE_R8: return("double"); case Il2CppTypeEnum.IL2CPP_TYPE_STRING: return("System_String_o*"); case Il2CppTypeEnum.IL2CPP_TYPE_PTR: { var oriType = il2Cpp.GetIl2CppType(il2CppType.data.type); return(ParseType(oriType) + "*"); } case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE: { var typeDef = metadata.typeDefs[il2CppType.data.klassIndex]; if (typeDef.IsEnum) { return(ParseType(il2Cpp.types[typeDef.elementTypeIndex])); } return(structNameDic[typeDef] + "_o"); } case Il2CppTypeEnum.IL2CPP_TYPE_CLASS: { var typeDef = metadata.typeDefs[il2CppType.data.klassIndex]; return(structNameDic[typeDef] + "_o*"); } case Il2CppTypeEnum.IL2CPP_TYPE_VAR: { if (context != null) { var genericParameter = metadata.genericParameters[il2CppType.data.genericParameterIndex]; var genericInst = il2Cpp.MapVATR <Il2CppGenericInst>(context.class_inst); var pointers = il2Cpp.MapVATR <ulong>(genericInst.type_argv, genericInst.type_argc); var pointer = pointers[genericParameter.num]; var type = il2Cpp.GetIl2CppType(pointer); return(ParseType(type)); } return("Il2CppObject*"); } case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY: { var arrayType = il2Cpp.MapVATR <Il2CppArrayType>(il2CppType.data.array); var elementType = il2Cpp.GetIl2CppType(arrayType.etype); var elementStructName = GetIl2CppStructName(elementType, context); var typeStructName = elementStructName + "_array"; if (structNameHashSet.Add(typeStructName)) { ParseArrayClassStruct(elementType, context); } return(typeStructName + "*"); } case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST: { var genericClass = il2Cpp.MapVATR <Il2CppGenericClass>(il2CppType.data.generic_class); var typeDef = metadata.typeDefs[genericClass.typeDefinitionIndex]; var typeStructName = genericClassStructNameDic[il2CppType.data.generic_class]; if (structNameHashSet.Add(typeStructName)) { genericClassList.Add(il2CppType.data.generic_class); } if (typeDef.IsValueType) { if (typeDef.IsEnum) { return(ParseType(il2Cpp.types[typeDef.elementTypeIndex])); } return(typeStructName + "_o"); } return(typeStructName + "_o*"); } case Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF: return("Il2CppObject*"); case Il2CppTypeEnum.IL2CPP_TYPE_I: return("intptr_t"); case Il2CppTypeEnum.IL2CPP_TYPE_U: return("uintptr_t"); case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT: return("Il2CppObject*"); case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY: { var elementType = il2Cpp.GetIl2CppType(il2CppType.data.type); var elementStructName = GetIl2CppStructName(elementType, context); var typeStructName = elementStructName + "_array"; if (structNameHashSet.Add(typeStructName)) { ParseArrayClassStruct(elementType, context); } return(typeStructName + "*"); } case Il2CppTypeEnum.IL2CPP_TYPE_MVAR: { if (context != null) { var genericParameter = metadata.genericParameters[il2CppType.data.genericParameterIndex]; var genericInst = il2Cpp.MapVATR <Il2CppGenericInst>(context.method_inst); var pointers = il2Cpp.MapVATR <ulong>(genericInst.type_argv, genericInst.type_argc); var pointer = pointers[genericParameter.num]; var type = il2Cpp.GetIl2CppType(pointer); return(ParseType(type)); } return("Il2CppObject*"); } default: throw new NotSupportedException(); } }
private void TypeDefinitionFromIl2CppType(Il2CppType il2CppType, out Il2CppTypeDefinition typeDef, out Il2CppGenericContext context) { context = null; switch (il2CppType.type) { case Il2CppTypeEnum.IL2CPP_TYPE_CLASS: case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE: typeDef = metadata.typeDefs[il2CppType.data.klassIndex]; break; case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST: var genericClass = il2Cpp.MapVATR <Il2CppGenericClass>(il2CppType.data.generic_class); context = genericClass.context; typeDef = metadata.typeDefs[genericClass.typeDefinitionIndex]; break; case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT: typeDef = null; break; default: throw new NotSupportedException(); } }