Implement `archive list` and `archive extract` for web `.data` files · satyamisme/UnityDataTools@4505f12 · GitHub
Skip to content

Commit 4505f12

Browse files
Implement archive list and archive extract for web .data files
* Add sample .data file for testing * Add function to determine if a file is a web bundle * Rename test to disambiguate with forthcoming test * HandleExtractArchive handles .data files as well as asset bundles * Propagate specific error message to console output * Simplify IsWebBundle test to use file extension Since we also need to support gzip- and brotli-compressed web bundles, and we don't want to decompress more than once. * Check for invalid web bundle in ParseWebBundleHeader And throw the appropriate exception type (requires adding package System.IO.Packaging). * Remove unneeded `using` statement * Simplify namespace paths where possible * Support extracting gzip- and brotli-compressed web bundles * Clean up `using` statements * Extract function to facilitate error handling * Reading less than the expected number of bytes raises FileFormatException * Extract function ReadUInt32 to facilitate error handling * EndOfStream from ReadUInt32 raises FileFormatException * Rename test to disambiguate with forthcoming test * Wrap console redirection in try/finally to ensure it's restored * Whitespace * Extract function ListAssetBundle * Test `archive list` on web bundle (fails) * Log error message in `archive list` * Add function ListWebBundle * HandleListArchive branches on archive type * Move members related to `archive` command to a new file * Remove redundancy in function names * Update CLI command descriptions * Update README description of `archive` command * Normalize wording: "content" -> "contents" * Whitespace * Add .gitattributes to specify auto line endings
1 parent 53b1288 commit 4505f12

10 files changed

Lines changed: 349 additions & 92 deletions

File tree

.gitattributes

Lines changed: 12 additions & 0 deletions
2.39 MB
Binary file not shown.
675 KB
Binary file not shown.
814 KB
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is NOT a web bundle.

UnityDataTool.Tests/UnityDataToolTests.cs

Lines changed: 104 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
using System.Text.RegularExpressions;
66
using System.Threading.Tasks;
77
using NUnit.Framework;
8-
using UnityDataTools.TestCommon;
98
using UnityDataTools.FileSystem;
9+
using UnityDataTools.TestCommon;
1010

1111
namespace UnityDataTools.UnityDataTool.Tests;
1212

@@ -57,8 +57,22 @@ public async Task InvalidFile(
5757
Assert.AreNotEqual(0, await Program.Main(command.ToArray()));
5858
}
5959

60+
public void IsWebBundle_True()
61+
{
62+
63+
var webBundlePath = Path.Combine(Context.TestDataFolder, "WebBundles", "HelloWorld.data");
64+
Assert.IsTrue(Archive.IsWebBundle(new FileInfo(webBundlePath)));
65+
}
66+
67+
[Test]
68+
public void IsWebBundle_False()
69+
{
70+
var nonWebBundlePath = Path.Combine(Context.TestDataFolder, "WebBundles", "NotAWebBundle.txt");
71+
Assert.IsFalse(Archive.IsWebBundle(new FileInfo(nonWebBundlePath)));
72+
}
73+
6074
[Test]
61-
public async Task ArchiveExtract_FilesExtractedSuccessfully(
75+
public async Task ArchiveExtract_AssetBundle_FilesExtractedSuccessfully(
6276
[Values("", "-o archive", "--output-path archive")] string options)
6377
{
6478
var path = Path.Combine(Context.UnityDataFolder, "assetbundle");
@@ -70,32 +84,105 @@ public async Task ArchiveExtract_FilesExtractedSuccessfully(
7084
}
7185

7286
[Test]
73-
public async Task ArchiveList_ListFilesCorrectly()
87+
public async Task ArchiveExtract_WebBundle_FileExtractedSuccessfully(
88+
[Values("", "-o archive", "--output-path archive")] string options,
89+
[Values("HelloWorld.data", "HelloWorld.data.gz", "HelloWorld.data.br")] string bundlePath)
7490
{
75-
var path = Path.Combine(Context.UnityDataFolder, "assetbundle");
91+
var path = Path.Combine(Context.TestDataFolder, "WebBundles", bundlePath);
92+
string[] expectedFiles = {
93+
"boot.config",
94+
"data.unity3d",
95+
"RuntimeInitializeOnLoads.json",
96+
"ScriptingAssemblies.json",
97+
Path.Combine("Il2CppData", "Metadata", "global-metadata.dat"),
98+
Path.Combine("Resources", "unity_default_resources"),
99+
};
100+
Assert.AreEqual(0, await Program.Main(new string[] { "archive", "extract", path }.Concat(options.Split(" ", StringSplitOptions.RemoveEmptyEntries)).ToArray()));
101+
foreach (var file in expectedFiles)
102+
{
103+
Assert.IsTrue(File.Exists(Path.Combine(m_TestOutputFolder, "archive", file)));
104+
}
105+
}
76106

107+
[Test]
108+
public async Task ArchiveList_AssetBundle_ListFilesCorrectly()
109+
{
110+
var path = Path.Combine(Context.UnityDataFolder, "assetbundle");
77111
using var sw = new StringWriter();
112+
var currentOut = Console.Out;
113+
try
114+
{
115+
Console.SetOut(sw);
78116

117+
Assert.AreEqual(0, await Program.Main(new string[] { "archive", "list", path }));
118+
119+
var lines = sw.ToString().Split(sw.NewLine);
120+
121+
Assert.AreEqual("CAB-5d40f7cad7c871cf2ad2af19ac542994", lines[0]);
122+
Assert.AreEqual($" Size: {Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994-Size")}", lines[1]);
123+
Assert.AreEqual($" Flags: {(ArchiveNodeFlags)(long)Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994-Flags")}", lines[2]);
124+
125+
Assert.AreEqual("CAB-5d40f7cad7c871cf2ad2af19ac542994.resS", lines[4]);
126+
Assert.AreEqual($" Size: {Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994.resS-Size")}", lines[5]);
127+
Assert.AreEqual($" Flags: {(ArchiveNodeFlags)(long)Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994.resS-Flags")}", lines[6]);
128+
129+
Assert.AreEqual("CAB-5d40f7cad7c871cf2ad2af19ac542994.resource", lines[8]);
130+
Assert.AreEqual($" Size: {Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994.resource-Size")}", lines[9]);
131+
Assert.AreEqual($" Flags: {(ArchiveNodeFlags)(long)Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994.resource-Flags")}", lines[10]);
132+
133+
}
134+
finally
135+
{
136+
Console.SetOut(currentOut);
137+
}
138+
}
139+
140+
[Test]
141+
public async Task ArchiveList_WebBundle_ListFilesCorrectly(
142+
[Values(
143+
"HelloWorld.data",
144+
"HelloWorld.data.gz",
145+
"HelloWorld.data.br"
146+
)] string bundlePath)
147+
{
148+
var path = Path.Combine(Context.TestDataFolder, "WebBundles", bundlePath);
149+
using var sw = new StringWriter();
79150
var currentOut = Console.Out;
80-
Console.SetOut(sw);
151+
try
152+
{
153+
Console.SetOut(sw);
154+
155+
Assert.AreEqual(0, await Program.Main(new string[] { "archive", "list", path }));
81156

82-
Assert.AreEqual(0, await Program.Main(new string[] { "archive", "list", path }));
157+
var actualOutput = sw.ToString();
158+
var expectedOutput = (
159+
@"data.unity3d
160+
Size: 253044
83161
84-
var lines = sw.ToString().Split(sw.NewLine);
162+
RuntimeInitializeOnLoads.json
163+
Size: 700
85164
86-
Assert.AreEqual("CAB-5d40f7cad7c871cf2ad2af19ac542994", lines[0]);
87-
Assert.AreEqual($" Size: {Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994-Size")}", lines[1]);
88-
Assert.AreEqual($" Flags: {(ArchiveNodeFlags)(long)Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994-Flags")}", lines[2]);
165+
ScriptingAssemblies.json
166+
Size: 3060
89167
90-
Assert.AreEqual("CAB-5d40f7cad7c871cf2ad2af19ac542994.resS", lines[4]);
91-
Assert.AreEqual($" Size: {Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994.resS-Size")}", lines[5]);
92-
Assert.AreEqual($" Flags: {(ArchiveNodeFlags)(long)Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994.resS-Flags")}", lines[6]);
168+
boot.config
169+
Size: 93
93170
94-
Assert.AreEqual("CAB-5d40f7cad7c871cf2ad2af19ac542994.resource", lines[8]);
95-
Assert.AreEqual($" Size: {Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994.resource-Size")}", lines[9]);
96-
Assert.AreEqual($" Flags: {(ArchiveNodeFlags)(long)Context.ExpectedData.Get("CAB-5d40f7cad7c871cf2ad2af19ac542994.resource-Flags")}", lines[10]);
171+
Il2CppData/Metadata/global-metadata.dat
172+
Size: 1641180
97173
98-
Console.SetOut(currentOut);
174+
Resources/unity_default_resources
175+
Size: 607376
176+
177+
"
178+
);
179+
180+
Assert.AreEqual(expectedOutput, actualOutput);
181+
}
182+
finally
183+
{
184+
Console.SetOut(currentOut);
185+
}
99186
}
100187

101188
[Test]

UnityDataTool/Archive.cs

Lines changed: 217 additions & 0 deletions

0 commit comments

Comments
 (0)