diff --git a/Il2CppDumper/Il2CppCSharpDumper.cs b/Il2CppDumper/Il2CppCSharpDumper.cs index 5a7dbf2..1f55114 100644 --- a/Il2CppDumper/Il2CppCSharpDumper.cs +++ b/Il2CppDumper/Il2CppCSharpDumper.cs @@ -59,7 +59,7 @@ namespace Il2CppInspector usedAssemblyAttributes.Clear(); Parallel.ForEach(model.Assemblies, asm => { // Sort namespaces into alphabetical order, then sort types within the namespaces by the specified sort function - writeFile($"{outPath}\\{asm.ShortName}.cs", asm.DefinedTypes.OrderBy(t => t.Namespace).ThenBy(orderBy)); + writeFile($"{outPath}\\{asm.ShortName.Replace(".dll", "")}.cs", asm.DefinedTypes.OrderBy(t => t.Namespace).ThenBy(orderBy)); }); } @@ -67,7 +67,15 @@ namespace Il2CppInspector usedAssemblyAttributes.Clear(); Parallel.ForEach(model.Assemblies.SelectMany(x => x.DefinedTypes), type => { writeFile($"{outPath}\\" + (type.Namespace + (type.Namespace.Length > 0 ? "." : "") + Regex.Replace(type.Name, "`[0-9]", "")) - .Replace('.', flattenHierarchy ? '.' : '\\') + ".cs",new[] {type}); + .Replace('.', flattenHierarchy ? '.' : '\\') + ".cs", new[] {type}); + }); + } + + public void WriteFilesByClassTree(string outPath) { + usedAssemblyAttributes.Clear(); + Parallel.ForEach(model.Assemblies.SelectMany(x => x.DefinedTypes), type => { + writeFile($"{outPath}\\{type.Assembly.ShortName.Replace(".dll", "")}\\" + (type.Namespace + (type.Namespace.Length > 0 ? "." : "") + Regex.Replace(type.Name, "`[0-9]", "")) + .Replace('.', '\\') + ".cs", new[] {type}); }); } diff --git a/Il2CppDumper/Program.cs b/Il2CppDumper/Program.cs index 7b12e33..52312e6 100644 --- a/Il2CppDumper/Program.cs +++ b/Il2CppDumper/Program.cs @@ -39,13 +39,13 @@ namespace Il2CppInspector })] public IEnumerable ExcludedNamespaces { get; set; } - [Option('l', "layout", Required = false, HelpText = "Partitioning of C# output ('single' = single file, 'namespace' = one file per namespace, 'assembly' = one file per assembly, 'class' = one file per class)", Default = "single")] + [Option('l', "layout", Required = false, HelpText = "Partitioning of C# output ('single' = single file, 'namespace' = one file per namespace in folders, 'assembly' = one file per assembly, 'class' = one file per class in namespace folders, 'tree' = one file per class in assembly and namespace folders)", Default = "single")] public string LayoutSchema { get; set; } - [Option('s', "sort", Required = false, HelpText = "Sort order of type definitions in C# output ('index' = by type definition index, 'name' = by type name). No effect when using file-per-class layout", Default = "index")] + [Option('s', "sort", Required = false, HelpText = "Sort order of type definitions in C# output ('index' = by type definition index, 'name' = by type name). No effect when using file-per-class or tree layout", Default = "index")] public string SortOrder { get; set; } - [Option('f', "flatten", Required = false, HelpText = "Flatten the namespace hierarchy into a single folder rather than using per-namespace subfolders. Only used when layout is per-namespace or per-class")] + [Option('f', "flatten", Required = false, HelpText = "Flatten the namespace hierarchy into a single folder rather than using per-namespace subfolders. Only used when layout is per-namespace or per-class. Ignored for tree layout")] public bool FlattenHierarchy { get; set; } [Option('n', "suppress-metadata", Required = false, HelpText = "Diff tidying: suppress method pointers, field offsets and type indices from C# output. Useful for comparing two versions of a binary for changes with a diff tool")] @@ -152,6 +152,10 @@ namespace Il2CppInspector case ("class", _): writer.WriteFilesByClass(csOut, options.FlattenHierarchy); break; + + case ("tree", _): + writer.WriteFilesByClassTree(csOut); + break; } // IDA Python script output diff --git a/README.md b/README.md index 27e5485..7b3924d 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,9 @@ File format and architecture are automatically detected. -m, --metadata Required. (Default: global-metadata.dat) IL2CPP metadata file input -c, --cs-out (Default: types.cs) C# output file (when using single-file layout) or path (when using per namespace, assembly or class layout) -e, --exclude-namespaces (Default: System Unity UnityEngine UnityEngineInternal Mono Microsoft.Win32) Comma-separated list of namespaces to suppress in C# output, or 'none' to include all namespaces - -l, --layout (Default: single) Partitioning of C# output ('single' = single file, 'namespace' = one file per namespace, 'assembly' = one file per assembly, 'class' = one file per class) - -s, --sort (Default: index) Sort order of type definitions in C# output ('index' = by type definition index, 'name' = by type name). No effect when using file-per-class layout - -f, --flatten Flatten the namespace hierarchy into a single folder rather than using per-namespace subfolders. Only used when layout is per-namespace or per-class + -l, --layout (Default: single) Partitioning of C# output ('single' = single file, 'namespace' = one file per namespace in folders, 'assembly' = one file per assembly, 'class' = one file per class in namespace folders, 'tree' = one file per class in assembly and namespace folders) + -s, --sort (Default: index) Sort order of type definitions in C# output ('index' = by type definition index, 'name' = by type name). No effect when using file-per-class or tree layout + -f, --flatten Flatten the namespace hierarchy into a single folder rather than using per-namespace subfolders. Only used when layout is per-namespace or per-class. Ignored for tree layout -n, --suppress-metadata Diff tidying: suppress method pointers, field offsets and type indices from C# output. Useful for comparing two versions of a binary for changes with a diff tool -k, --must-compile Compilation tidying: try really hard to make code that compiles. Suppress generation of code for items with CompilerGenerated attribute. Comment out attributes without parameterless constructors or all-optional constructor arguments. Don't emit add/remove/raise on events. Specify AttributeTargets.All on classes with AttributeUsage attribute. Force auto-properties to have get accessors. Force regular properties to have bodies. ```