Skip to content

Commit f8f6028

Browse files
"Dump" command supports outputing a single object (#30)
Support dump filtering by objectid Example: UnityDataTool dump imagelist.bundle -i -8066222900050932585
1 parent d9b21ba commit f8f6028

5 files changed

Lines changed: 26 additions & 11 deletions

File tree

Documentation/comparing-builds.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ As expected, it's only fields on the MonoBehaviour and one of the Transforms tha
164164

165165
In a normal case we would not know exactly what changed in the build, so rather than confirming the expected changes we probably would be working in the other direction - using comparison technique to see which objects and values changed and try to build an understanding of whether this is "expected" or not.
166166

167+
Note: When you know the id of the object that has changed you can pass the `--objectid` argument to the `dump` command to only dump that object. This can be useful for large Serialized Files with many objects, where you want to focus on changes to a single object.
168+
167169
# Example 2 - Changes in a texture
168170

169171
The previous example covers the common case where the changes are limited to serialized values directly inside Serialized Files. However its also common that data inside the auxiliary .resS and .resource files can change, based on changes to textures, meshes, audio or video. This can also cause the AssetBundle content to change, even if the Serialized Files themselves are unchanged.

TextDumper/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ file (AssetBundle or SerializedFile) into human-readable yaml-style text file.
55

66
## How to use
77

8-
The library consists of a single class called [TextDumperTool](./TextDumperTool.cs). It has a single
9-
method named Dump and takes three parameters:
8+
The library consists of a single class called [TextDumperTool](./TextDumperTool.cs). It has a method named Dump and takes four parameters:
109
* path (string): path of the data file.
1110
* outputPath (string): path where the output files will be created.
1211
* skipLargeArrays (bool): if true, the content of arrays larger than 1KB won't be dumped.
12+
* objectId (long, optional): if specified and not 0, only the object with this signed 64-bit id will be dumped. If 0 (default), all objects are dumped.
1313

1414
## How to interpret the output files
1515

TextDumper/TextDumperTool.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ public class TextDumperTool
1313
SerializedFile m_SerializedFile;
1414
StreamWriter m_Writer;
1515

16-
public int Dump(string path, string outputPath, bool skipLargeArrays)
16+
public int Dump(string path, string outputPath, bool skipLargeArrays, long objectId = 0)
1717
{
1818
m_SkipLargeArrays = skipLargeArrays;
1919

2020
try
2121
{
2222
try
2323
{
24+
// Try the input as an unity archive, e.g. an AssetBundle
25+
// In that case we dump each serialized file contained inside it.
2426
using var archive = UnityFileSystem.MountArchive(path, "/");
2527
foreach (var node in archive.Nodes)
2628
{
@@ -30,7 +32,7 @@ public int Dump(string path, string outputPath, bool skipLargeArrays)
3032
{
3133
using (m_Writer = new StreamWriter(Path.Combine(outputPath, Path.GetFileName(node.Path) + ".txt"), false))
3234
{
33-
OutputSerializedFile("/" + node.Path);
35+
OutputSerializedFile("/" + node.Path, objectId);
3436
}
3537
}
3638
}
@@ -40,7 +42,7 @@ public int Dump(string path, string outputPath, bool skipLargeArrays)
4042
// Try as SerializedFile
4143
using (m_Writer = new StreamWriter(Path.Combine(outputPath, Path.GetFileName(path) + ".txt"), false))
4244
{
43-
OutputSerializedFile(path);
45+
OutputSerializedFile(path, objectId);
4446
}
4547
}
4648
}
@@ -340,7 +342,7 @@ bool DumpManagedReferenceData(TypeTreeNode refTypeNode, TypeTreeNode referencedT
340342
return true;
341343
}
342344

343-
void OutputSerializedFile(string path)
345+
void OutputSerializedFile(string path, long objectId)
344346
{
345347
using (m_Reader = new UnityFileReader(path, 64 * 1024 * 1024))
346348
using (m_SerializedFile = UnityFileSystem.OpenSerializedFile(path))
@@ -355,15 +357,23 @@ void OutputSerializedFile(string path)
355357
}
356358
m_Writer.WriteLine();
357359

360+
bool dumpedObject = false;
358361
foreach (var obj in m_SerializedFile.Objects)
359362
{
363+
if (objectId != 0 && obj.Id != objectId)
364+
continue;
365+
360366
var root = m_SerializedFile.GetTypeTreeRoot(obj.Id);
361367
var offset = obj.Offset;
362368

363369
m_Writer.Write($"ID: {obj.Id} (ClassID: {obj.TypeId}) ");
364370
RecursiveDump(root, ref offset, 0);
365371
m_Writer.WriteLine();
372+
dumpedObject = true;
366373
}
374+
375+
if (objectId != 0 && !dumpedObject)
376+
m_Writer.WriteLine($"Object with ID {objectId} not found.");
367377
}
368378
}
369379

UnityDataTool/Program.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,19 @@ public static async Task<int> Main(string[] args)
7575
var fOpt = new Option<DumpFormat>(aliases: new[] { "--output-format", "-f" }, description: "Output format", getDefaultValue: () => DumpFormat.Text);
7676
var sOpt = new Option<bool>(aliases: new[] { "--skip-large-arrays", "-s" }, description: "Do not dump large arrays of basic data types");
7777
var oOpt = new Option<DirectoryInfo>(aliases: new[] { "--output-path", "-o"}, description: "Output folder", getDefaultValue: () => new DirectoryInfo(Environment.CurrentDirectory));
78+
var objectIdOpt = new Option<long>(aliases: new[] { "--objectid", "-i" }, () => 0, "Only dump the object with this signed 64-bit id (default: 0, dump all objects)");
7879

7980
var dumpCommand = new Command("dump", "Dump the contents of an AssetBundle or SerializedFile.")
8081
{
8182
pathArg,
8283
fOpt,
8384
sOpt,
8485
oOpt,
86+
objectIdOpt,
8587
};
8688
dumpCommand.SetHandler(
87-
(FileInfo fi, DumpFormat f, bool s, DirectoryInfo o) => Task.FromResult(HandleDump(fi, f, s, o)),
88-
pathArg, fOpt, sOpt, oOpt);
89+
(FileInfo fi, DumpFormat f, bool s, DirectoryInfo o, long objectId) => Task.FromResult(HandleDump(fi, f, s, o, objectId)),
90+
pathArg, fOpt, sOpt, oOpt, objectIdOpt);
8991

9092
rootCommand.AddCommand(dumpCommand);
9193
}
@@ -173,14 +175,14 @@ static int HandleFindReferences(FileInfo databasePath, string outputFile, long?
173175
}
174176
}
175177

176-
static int HandleDump(FileInfo filename, DumpFormat format, bool skipLargeArrays, DirectoryInfo outputFolder)
178+
static int HandleDump(FileInfo filename, DumpFormat format, bool skipLargeArrays, DirectoryInfo outputFolder, long objectId = 0)
177179
{
178180
switch (format)
179181
{
180182
case DumpFormat.Text:
181183
{
182184
var textDumper = new TextDumperTool();
183-
return textDumper.Dump(filename.FullName, outputFolder.FullName, skipLargeArrays);
185+
return textDumper.Dump(filename.FullName, outputFolder.FullName, skipLargeArrays, objectId);
184186
}
185187
}
186188

UnityDataTool/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,10 @@ only supports the 'text' format, which is similar to the binary2text output form
111111

112112
The command takes the path of the file to dump as argument. It also provides the following options:
113113
* -o, --output-path <output-path> Output folder, default is the current folder.
114-
* -f, --output-format \<format\>: output format, default is 'text'.
114+
* -f, --output-format <format>: output format, default is 'text'.
115115
* -s, --skip-large-arrays: the contents of basic data type arrays with a large number of elements
116116
won't be dumped.
117+
* -i, --objectid <objectid>: only dump the object with this local file id. If not specified or 0, all objects will be dumped.
117118

118119
Example: `UnityDataTool dump /path/to/file -o /path/to/output`
119120

0 commit comments

Comments
 (0)