Renaming for clarity.
Renamed the class CppDeclarations => CppDeclarationGenerator to better reflect
its function and emphasize its statefulness.
Renamed Visit{Type,Method} => Include{Type,Method} to clarify that these methods
include the type or method into the generator state.
Renamed GenerateVisitedTypes => GenerateRemainingTypeDeclarations to clarify
that it outputs *remaining* declarations, i.e. declarations that haven't been
generated yet.
This commit is contained in:
40
Il2CppInspector.Common/CppUtils/CppDeclarations.cs → Il2CppInspector.Common/CppUtils/CppDeclarationGenerator.cs
Normal file → Executable file
40
Il2CppInspector.Common/CppUtils/CppDeclarations.cs → Il2CppInspector.Common/CppUtils/CppDeclarationGenerator.cs
Normal file → Executable file
@@ -16,7 +16,7 @@ using System.Text.RegularExpressions;
|
|||||||
namespace Il2CppInspector.CppUtils
|
namespace Il2CppInspector.CppUtils
|
||||||
{
|
{
|
||||||
// Class for generating C header declarations from Reflection objects (TypeInfo, etc.)
|
// Class for generating C header declarations from Reflection objects (TypeInfo, etc.)
|
||||||
public class CppDeclarations
|
public class CppDeclarationGenerator
|
||||||
{
|
{
|
||||||
private readonly Il2CppModel model;
|
private readonly Il2CppModel model;
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ namespace Il2CppInspector.CppUtils
|
|||||||
}
|
}
|
||||||
public InheritanceStyleEnum InheritanceStyle;
|
public InheritanceStyleEnum InheritanceStyle;
|
||||||
|
|
||||||
public CppDeclarations(Il2CppModel model, UnityVersion version) {
|
public CppDeclarationGenerator(Il2CppModel model, UnityVersion version) {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
if (version == null) {
|
if (version == null) {
|
||||||
UnityHeader = UnityHeader.GuessHeadersForModel(model)[0];
|
UnityHeader = UnityHeader.GuessHeadersForModel(model)[0];
|
||||||
@@ -328,10 +328,11 @@ namespace Il2CppInspector.CppUtils
|
|||||||
private readonly List<TypeInfo> TodoTypeStructs = new List<TypeInfo>();
|
private readonly List<TypeInfo> TodoTypeStructs = new List<TypeInfo>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Visit a type and all types it depends on. Must call this before generating type structs.
|
/// Include the given type into this generator. This will add the given type and all types it depends on.
|
||||||
|
/// Call GenerateRemainingTypeDeclarations to produce the actual type declarations afterwards.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ti"></param>
|
/// <param name="ti"></param>
|
||||||
public void VisitType(TypeInfo ti) {
|
public void IncludeType(TypeInfo ti) {
|
||||||
if (VisitedTypes.Contains(ti))
|
if (VisitedTypes.Contains(ti))
|
||||||
return;
|
return;
|
||||||
if (ti.ContainsGenericParameters)
|
if (ti.ContainsGenericParameters)
|
||||||
@@ -340,15 +341,15 @@ namespace Il2CppInspector.CppUtils
|
|||||||
|
|
||||||
if (ti.IsArray) {
|
if (ti.IsArray) {
|
||||||
VisitFieldStructs(ti);
|
VisitFieldStructs(ti);
|
||||||
VisitType(ti.ElementType);
|
IncludeType(ti.ElementType);
|
||||||
VisitType(ti.BaseType);
|
IncludeType(ti.BaseType);
|
||||||
return;
|
return;
|
||||||
} else if (ti.HasElementType) {
|
} else if (ti.HasElementType) {
|
||||||
VisitType(ti.ElementType);
|
IncludeType(ti.ElementType);
|
||||||
return;
|
return;
|
||||||
} else if (ti.IsEnum) {
|
} else if (ti.IsEnum) {
|
||||||
VisitFieldStructs(ti);
|
VisitFieldStructs(ti);
|
||||||
VisitType(ti.GetEnumUnderlyingType());
|
IncludeType(ti.GetEnumUnderlyingType());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,16 +358,16 @@ namespace Il2CppInspector.CppUtils
|
|||||||
VisitFieldStructs(ti);
|
VisitFieldStructs(ti);
|
||||||
|
|
||||||
if (ti.BaseType != null)
|
if (ti.BaseType != null)
|
||||||
VisitType(ti.BaseType);
|
IncludeType(ti.BaseType);
|
||||||
|
|
||||||
TypeNamer.GetName(ti);
|
TypeNamer.GetName(ti);
|
||||||
|
|
||||||
foreach (var fi in ti.DeclaredFields)
|
foreach (var fi in ti.DeclaredFields)
|
||||||
VisitType(fi.FieldType);
|
IncludeType(fi.FieldType);
|
||||||
|
|
||||||
foreach (var mi in GetFilledVTable(ti))
|
foreach (var mi in GetFilledVTable(ti))
|
||||||
if (mi != null && !mi.ContainsGenericParameters)
|
if (mi != null && !mi.ContainsGenericParameters)
|
||||||
VisitMethod(mi);
|
IncludeMethod(mi);
|
||||||
|
|
||||||
TodoTypeStructs.Add(ti);
|
TodoTypeStructs.Add(ti);
|
||||||
}
|
}
|
||||||
@@ -444,11 +445,11 @@ namespace Il2CppInspector.CppUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate every type that has been visited so far. Types that have previously been generated
|
/// Output type declarations for every type that was included since the last call to GenerateRemainingTypeDeclarations
|
||||||
/// by this instance will not be generated again.
|
/// Type declarations that have previously been generated by this instance of CppDeclarationGenerator will not be generated again.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A string containing C type declarations</returns>
|
/// <returns>A string containing C type declarations</returns>
|
||||||
public string GenerateVisitedTypes() {
|
public string GenerateRemainingTypeDeclarations() {
|
||||||
var csrc = new StringBuilder();
|
var csrc = new StringBuilder();
|
||||||
GenerateVisitedFieldStructs(csrc);
|
GenerateVisitedFieldStructs(csrc);
|
||||||
|
|
||||||
@@ -463,18 +464,19 @@ namespace Il2CppInspector.CppUtils
|
|||||||
#region Method Generation
|
#region Method Generation
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Visit a method and all types it takes/returns. Must call this before generating method declarations.
|
/// Analyze a method and include all types that it takes and returns.
|
||||||
|
/// Must call this before generating the method's declaration with GenerateMethodDeclaration or GenerateFunctionPointer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="mi"></param>
|
/// <param name="mi"></param>
|
||||||
public void VisitMethod(MethodBase method, TypeInfo declaringType = null) {
|
public void IncludeMethod(MethodBase method, TypeInfo declaringType = null) {
|
||||||
if (!method.IsStatic)
|
if (!method.IsStatic)
|
||||||
VisitType(declaringType ?? method.DeclaringType);
|
IncludeType(declaringType ?? method.DeclaringType);
|
||||||
|
|
||||||
if (method is MethodInfo mi)
|
if (method is MethodInfo mi)
|
||||||
VisitType(mi.ReturnType);
|
IncludeType(mi.ReturnType);
|
||||||
|
|
||||||
foreach (var pi in method.DeclaredParameters) {
|
foreach (var pi in method.DeclaredParameters) {
|
||||||
VisitType(pi.ParameterType);
|
IncludeType(pi.ParameterType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
30
Il2CppInspector.Common/Outputs/IDAPythonScript.cs
Normal file → Executable file
30
Il2CppInspector.Common/Outputs/IDAPythonScript.cs
Normal file → Executable file
@@ -19,19 +19,19 @@ namespace Il2CppInspector.Outputs
|
|||||||
private readonly Il2CppModel model;
|
private readonly Il2CppModel model;
|
||||||
private StreamWriter writer;
|
private StreamWriter writer;
|
||||||
public UnityVersion UnityVersion;
|
public UnityVersion UnityVersion;
|
||||||
private CppDeclarations typeGenerator;
|
private CppDeclarationGenerator declGenerator;
|
||||||
|
|
||||||
public IDAPythonScript(Il2CppModel model) => this.model = model;
|
public IDAPythonScript(Il2CppModel model) => this.model = model;
|
||||||
|
|
||||||
public void WriteScriptToFile(string outputFile) {
|
public void WriteScriptToFile(string outputFile) {
|
||||||
typeGenerator = new CppDeclarations(model, UnityVersion);
|
declGenerator = new CppDeclarationGenerator(model, UnityVersion);
|
||||||
UnityVersion = typeGenerator.UnityVersion;
|
UnityVersion = declGenerator.UnityVersion;
|
||||||
|
|
||||||
using var fs = new FileStream(outputFile, FileMode.Create);
|
using var fs = new FileStream(outputFile, FileMode.Create);
|
||||||
writer = new StreamWriter(fs, Encoding.UTF8);
|
writer = new StreamWriter(fs, Encoding.UTF8);
|
||||||
|
|
||||||
writeLine("# Generated script file by Il2CppInspector - http://www.djkaty.com - https://github.com/djkaty");
|
writeLine("# Generated script file by Il2CppInspector - http://www.djkaty.com - https://github.com/djkaty");
|
||||||
writeLine("# Target Unity version: " + typeGenerator.UnityHeader.ToString());
|
writeLine("# Target Unity version: " + declGenerator.UnityHeader.ToString());
|
||||||
writeLine("print('Generated script file by Il2CppInspector - http://www.djkaty.com - https://github.com/djkaty')");
|
writeLine("print('Generated script file by Il2CppInspector - http://www.djkaty.com - https://github.com/djkaty')");
|
||||||
writeSectionHeader("Preamble");
|
writeSectionHeader("Preamble");
|
||||||
writePreamble();
|
writePreamble();
|
||||||
@@ -83,7 +83,7 @@ typedef __int64 int64_t;
|
|||||||
");
|
");
|
||||||
|
|
||||||
var prefix = (model.Package.BinaryImage.Bits == 32) ? "#define IS_32BIT\n" : "";
|
var prefix = (model.Package.BinaryImage.Bits == 32) ? "#define IS_32BIT\n" : "";
|
||||||
writeDecls(prefix + typeGenerator.UnityHeader.GetHeaderText());
|
writeDecls(prefix + declGenerator.UnityHeader.GetHeaderText());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeMethods() {
|
private void writeMethods() {
|
||||||
@@ -110,10 +110,10 @@ typedef __int64 int64_t;
|
|||||||
|
|
||||||
private void writeMethods(IEnumerable<MethodBase> methods) {
|
private void writeMethods(IEnumerable<MethodBase> methods) {
|
||||||
foreach (var method in methods.Where(m => m.VirtualAddress.HasValue)) {
|
foreach (var method in methods.Where(m => m.VirtualAddress.HasValue)) {
|
||||||
typeGenerator.VisitMethod(method);
|
declGenerator.IncludeMethod(method);
|
||||||
writeDecls(typeGenerator.GenerateVisitedTypes());
|
writeDecls(declGenerator.GenerateRemainingTypeDeclarations());
|
||||||
var address = method.VirtualAddress.Value.Start;
|
var address = method.VirtualAddress.Value.Start;
|
||||||
writeTypedName(address, typeGenerator.GenerateMethodDeclaration(method), typeGenerator.MethodNamer.GetName(method));
|
writeTypedName(address, declGenerator.GenerateMethodDeclaration(method), declGenerator.MethodNamer.GetName(method));
|
||||||
writeComment(address, method);
|
writeComment(address, method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ typedef __int64 int64_t;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var stringType = typeGenerator.AsCType(model.TypesByFullName["System.String"]);
|
var stringType = declGenerator.AsCType(model.TypesByFullName["System.String"]);
|
||||||
foreach (var usage in model.Package.MetadataUsages) {
|
foreach (var usage in model.Package.MetadataUsages) {
|
||||||
var address = usage.VirtualAddress;
|
var address = usage.VirtualAddress;
|
||||||
string name;
|
string name;
|
||||||
@@ -155,10 +155,10 @@ typedef __int64 int64_t;
|
|||||||
case MetadataUsageType.Type:
|
case MetadataUsageType.Type:
|
||||||
case MetadataUsageType.TypeInfo:
|
case MetadataUsageType.TypeInfo:
|
||||||
var type = model.GetMetadataUsageType(usage);
|
var type = model.GetMetadataUsageType(usage);
|
||||||
typeGenerator.VisitType(type);
|
declGenerator.IncludeType(type);
|
||||||
writeDecls(typeGenerator.GenerateVisitedTypes());
|
writeDecls(declGenerator.GenerateRemainingTypeDeclarations());
|
||||||
|
|
||||||
name = typeGenerator.TypeNamer.GetName(type);
|
name = declGenerator.TypeNamer.GetName(type);
|
||||||
if (usage.Type == MetadataUsageType.TypeInfo)
|
if (usage.Type == MetadataUsageType.TypeInfo)
|
||||||
writeTypedName(address, $"struct {name}__Class *", $"{name}__TypeInfo");
|
writeTypedName(address, $"struct {name}__Class *", $"{name}__TypeInfo");
|
||||||
else
|
else
|
||||||
@@ -168,10 +168,10 @@ typedef __int64 int64_t;
|
|||||||
case MetadataUsageType.MethodDef:
|
case MetadataUsageType.MethodDef:
|
||||||
case MetadataUsageType.MethodRef:
|
case MetadataUsageType.MethodRef:
|
||||||
var method = model.GetMetadataUsageMethod(usage);
|
var method = model.GetMetadataUsageMethod(usage);
|
||||||
typeGenerator.VisitMethod(method);
|
declGenerator.IncludeMethod(method);
|
||||||
writeDecls(typeGenerator.GenerateVisitedTypes());
|
writeDecls(declGenerator.GenerateRemainingTypeDeclarations());
|
||||||
|
|
||||||
name = typeGenerator.MethodNamer.GetName(method);
|
name = declGenerator.MethodNamer.GetName(method);
|
||||||
writeTypedName(address, "struct MethodInfo *", $"{name}__MethodInfo");
|
writeTypedName(address, "struct MethodInfo *", $"{name}__MethodInfo");
|
||||||
writeComment(address, method);
|
writeComment(address, method);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user