Improve extract file

This commit is contained in:
Perfare 2018-04-18 12:04:46 +08:00
parent bd5eb3be5d
commit 4bcc16245c
4 changed files with 116 additions and 92 deletions

View File

@ -35,7 +35,7 @@
this.loadFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.loadFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.loadFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.loadFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.extractBundleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.extractFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.extractFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.extractFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.displayAll = new System.Windows.Forms.ToolStripMenuItem(); this.displayAll = new System.Windows.Forms.ToolStripMenuItem();
@ -154,7 +154,7 @@
this.loadFileToolStripMenuItem, this.loadFileToolStripMenuItem,
this.loadFolderToolStripMenuItem, this.loadFolderToolStripMenuItem,
this.toolStripMenuItem1, this.toolStripMenuItem1,
this.extractBundleToolStripMenuItem, this.extractFileToolStripMenuItem,
this.extractFolderToolStripMenuItem}); this.extractFolderToolStripMenuItem});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(39, 21); this.fileToolStripMenuItem.Size = new System.Drawing.Size(39, 21);
@ -163,33 +163,33 @@
// loadFileToolStripMenuItem // loadFileToolStripMenuItem
// //
this.loadFileToolStripMenuItem.Name = "loadFileToolStripMenuItem"; this.loadFileToolStripMenuItem.Name = "loadFileToolStripMenuItem";
this.loadFileToolStripMenuItem.Size = new System.Drawing.Size(159, 22); this.loadFileToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.loadFileToolStripMenuItem.Text = "Load file"; this.loadFileToolStripMenuItem.Text = "Load file";
this.loadFileToolStripMenuItem.Click += new System.EventHandler(this.loadFile_Click); this.loadFileToolStripMenuItem.Click += new System.EventHandler(this.loadFile_Click);
// //
// loadFolderToolStripMenuItem // loadFolderToolStripMenuItem
// //
this.loadFolderToolStripMenuItem.Name = "loadFolderToolStripMenuItem"; this.loadFolderToolStripMenuItem.Name = "loadFolderToolStripMenuItem";
this.loadFolderToolStripMenuItem.Size = new System.Drawing.Size(159, 22); this.loadFolderToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.loadFolderToolStripMenuItem.Text = "Load folder"; this.loadFolderToolStripMenuItem.Text = "Load folder";
this.loadFolderToolStripMenuItem.Click += new System.EventHandler(this.loadFolder_Click); this.loadFolderToolStripMenuItem.Click += new System.EventHandler(this.loadFolder_Click);
// //
// toolStripMenuItem1 // toolStripMenuItem1
// //
this.toolStripMenuItem1.Name = "toolStripMenuItem1"; this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(156, 6); this.toolStripMenuItem1.Size = new System.Drawing.Size(177, 6);
// //
// extractBundleToolStripMenuItem // extractFileToolStripMenuItem
// //
this.extractBundleToolStripMenuItem.Name = "extractBundleToolStripMenuItem"; this.extractFileToolStripMenuItem.Name = "extractFileToolStripMenuItem";
this.extractBundleToolStripMenuItem.Size = new System.Drawing.Size(159, 22); this.extractFileToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.extractBundleToolStripMenuItem.Text = "Extract bundle"; this.extractFileToolStripMenuItem.Text = "Extract file";
this.extractBundleToolStripMenuItem.Click += new System.EventHandler(this.extractBundleToolStripMenuItem_Click); this.extractFileToolStripMenuItem.Click += new System.EventHandler(this.extractFileToolStripMenuItem_Click);
// //
// extractFolderToolStripMenuItem // extractFolderToolStripMenuItem
// //
this.extractFolderToolStripMenuItem.Name = "extractFolderToolStripMenuItem"; this.extractFolderToolStripMenuItem.Name = "extractFolderToolStripMenuItem";
this.extractFolderToolStripMenuItem.Size = new System.Drawing.Size(159, 22); this.extractFolderToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.extractFolderToolStripMenuItem.Text = "Extract folder"; this.extractFolderToolStripMenuItem.Text = "Extract folder";
this.extractFolderToolStripMenuItem.Click += new System.EventHandler(this.extractFolderToolStripMenuItem_Click); this.extractFolderToolStripMenuItem.Click += new System.EventHandler(this.extractFolderToolStripMenuItem_Click);
// //
@ -397,7 +397,7 @@
this.allToolStripMenuItem.CheckOnClick = true; this.allToolStripMenuItem.CheckOnClick = true;
this.allToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; this.allToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.allToolStripMenuItem.Name = "allToolStripMenuItem"; this.allToolStripMenuItem.Name = "allToolStripMenuItem";
this.allToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.allToolStripMenuItem.Size = new System.Drawing.Size(90, 22);
this.allToolStripMenuItem.Text = "All"; this.allToolStripMenuItem.Text = "All";
this.allToolStripMenuItem.Click += new System.EventHandler(this.typeToolStripMenuItem_Click); this.allToolStripMenuItem.Click += new System.EventHandler(this.typeToolStripMenuItem_Click);
// //
@ -1029,7 +1029,7 @@
private System.Windows.Forms.ToolStripMenuItem enablePreview; private System.Windows.Forms.ToolStripMenuItem enablePreview;
private System.Windows.Forms.ToolStripMenuItem displayInfo; private System.Windows.Forms.ToolStripMenuItem displayInfo;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem extractBundleToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem extractFileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem extractFolderToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem extractFolderToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem exportallobjectsMenuItem; private System.Windows.Forms.ToolStripMenuItem exportallobjectsMenuItem;
private System.Windows.Forms.ToolStripMenuItem exportselectedobjectsMenuItem; private System.Windows.Forms.ToolStripMenuItem exportselectedobjectsMenuItem;

View File

@ -138,11 +138,11 @@ namespace AssetStudio
} }
} }
private void extractBundleToolStripMenuItem_Click(object sender, EventArgs e) private void extractFileToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var openBundleDialog = new OpenFileDialog var openBundleDialog = new OpenFileDialog
{ {
Filter = "Bundle files|*.*", Filter = "All types|*.*",
FilterIndex = 1, FilterIndex = 1,
RestoreDirectory = true, RestoreDirectory = true,
Multiselect = true Multiselect = true
@ -152,7 +152,7 @@ namespace AssetStudio
{ {
progressBar1.Value = 0; progressBar1.Value = 0;
progressBar1.Maximum = openBundleDialog.FileNames.Length; progressBar1.Maximum = openBundleDialog.FileNames.Length;
ExtractBundle(openBundleDialog.FileNames); ExtractFile(openBundleDialog.FileNames);
} }
} }
@ -161,10 +161,10 @@ namespace AssetStudio
var openFolderDialog1 = new OpenFolderDialog(); var openFolderDialog1 = new OpenFolderDialog();
if (openFolderDialog1.ShowDialog(this) == DialogResult.OK) if (openFolderDialog1.ShowDialog(this) == DialogResult.OK)
{ {
var bundleFiles = Directory.GetFiles(openFolderDialog1.Folder, "*.*", SearchOption.AllDirectories); var files = Directory.GetFiles(openFolderDialog1.Folder, "*.*", SearchOption.AllDirectories);
progressBar1.Value = 0; progressBar1.Value = 0;
progressBar1.Maximum = bundleFiles.Length; progressBar1.Maximum = files.Length;
ExtractBundle(bundleFiles); ExtractFile(files);
} }
} }
@ -231,7 +231,7 @@ namespace AssetStudio
showTypeToolStripMenuItem.DropDownItems.Add(typeItem); showTypeToolStripMenuItem.DropDownItems.Add(typeItem);
} }
allToolStripMenuItem.Checked = true; allToolStripMenuItem.Checked = true;
StatusStripUpdate($"Finished loading {assetsfileList.Count} files with {assetListView.Items.Count} exportable assets."); StatusStripUpdate(assetsfileList.Count == 0 ? "No file was loaded." : $"Finished loading {assetsfileList.Count} files with {assetListView.Items.Count} exportable assets.");
treeSearch.Select(); treeSearch.Select();
})); }));
} }

View File

@ -14,58 +14,6 @@ namespace AssetStudio
public static HashSet<string> importFilesHash = new HashSet<string>(); //to improve the loading speed public static HashSet<string> importFilesHash = new HashSet<string>(); //to improve the loading speed
public static HashSet<string> assetsfileListHash = new HashSet<string>(); //to improve the loading speed public static HashSet<string> assetsfileListHash = new HashSet<string>(); //to improve the loading speed
private enum FileType
{
AssetsFile,
BundleFile,
WebFile
}
private static FileType CheckFileType(MemoryStream stream, out EndianBinaryReader reader)
{
reader = new EndianBinaryReader(stream);
return CheckFileType(reader);
}
private static FileType CheckFileType(string fileName, out EndianBinaryReader reader)
{
reader = new EndianBinaryReader(File.OpenRead(fileName));
return CheckFileType(reader);
}
private static FileType CheckFileType(EndianBinaryReader reader)
{
var signature = reader.ReadStringToNull();
reader.Position = 0;
switch (signature)
{
case "UnityWeb":
case "UnityRaw":
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA":
case "UnityFS":
return FileType.BundleFile;
case "UnityWebData1.0":
return FileType.WebFile;
default:
{
var magic = reader.ReadBytes(2);
reader.Position = 0;
if (WebFile.gzipMagic.SequenceEqual(magic))
{
return FileType.WebFile;
}
reader.Position = 0x20;
magic = reader.ReadBytes(6);
reader.Position = 0;
if (WebFile.brotliMagic.SequenceEqual(magic))
{
return FileType.WebFile;
}
return FileType.AssetsFile;
}
}
}
public static void LoadFile(string fullName) public static void LoadFile(string fullName)
{ {
switch (CheckFileType(fullName, out var reader)) switch (CheckFileType(fullName, out var reader))

View File

@ -34,45 +34,121 @@ namespace AssetStudio
public static Action<string> StatusStripUpdate; public static Action<string> StatusStripUpdate;
public static Action<int> ProgressBarMaximumAdd; public static Action<int> ProgressBarMaximumAdd;
public enum FileType
{
AssetsFile,
BundleFile,
WebFile
}
public static void ExtractBundle(string[] bundleFileName) public static FileType CheckFileType(MemoryStream stream, out EndianBinaryReader reader)
{
reader = new EndianBinaryReader(stream);
return CheckFileType(reader);
}
public static FileType CheckFileType(string fileName, out EndianBinaryReader reader)
{
reader = new EndianBinaryReader(File.OpenRead(fileName));
return CheckFileType(reader);
}
private static FileType CheckFileType(EndianBinaryReader reader)
{
var signature = reader.ReadStringToNull();
reader.Position = 0;
switch (signature)
{
case "UnityWeb":
case "UnityRaw":
case "\xFA\xFA\xFA\xFA\xFA\xFA\xFA\xFA":
case "UnityFS":
return FileType.BundleFile;
case "UnityWebData1.0":
return FileType.WebFile;
default:
{
var magic = reader.ReadBytes(2);
reader.Position = 0;
if (WebFile.gzipMagic.SequenceEqual(magic))
{
return FileType.WebFile;
}
reader.Position = 0x20;
magic = reader.ReadBytes(6);
reader.Position = 0;
if (WebFile.brotliMagic.SequenceEqual(magic))
{
return FileType.WebFile;
}
return FileType.AssetsFile;
}
}
}
public static void ExtractFile(string[] fileNames)
{ {
ThreadPool.QueueUserWorkItem(state => ThreadPool.QueueUserWorkItem(state =>
{ {
int extractedCount = 0; int extractedCount = 0;
foreach (var fileName in bundleFileName) foreach (var fileName in fileNames)
{ {
extractedCount += ExtractBundleFile(fileName); var type = CheckFileType(fileName, out var reader);
if (type == FileType.BundleFile)
extractedCount += ExtractBundleFile(fileName, reader);
else if (type == FileType.WebFile)
extractedCount += ExtractWebDataFile(fileName, reader);
else
reader.Dispose();
ProgressBarPerformStep(); ProgressBarPerformStep();
} }
StatusStripUpdate($"Finished extracting {extractedCount} files."); StatusStripUpdate($"Finished extracting {extractedCount} files.");
}); });
} }
private static int ExtractBundleFile(string bundleFileName) private static int ExtractBundleFile(string bundleFileName, EndianBinaryReader reader)
{ {
int extractedCount = 0;
var extractPath = bundleFileName + "_unpacked\\";
Directory.CreateDirectory(extractPath);
var reader = new EndianBinaryReader(File.OpenRead(bundleFileName));
var bundleFile = new BundleFile(reader); var bundleFile = new BundleFile(reader);
reader.Dispose(); reader.Dispose();
if (bundleFile.fileList.Count > 0) if (bundleFile.fileList.Count > 0)
{ {
StatusStripUpdate($"Decompressing {Path.GetFileName(bundleFileName)} ..."); StatusStripUpdate($"Decompressing {Path.GetFileName(bundleFileName)} ...");
foreach (var memFile in bundleFile.fileList) var extractPath = bundleFileName + "_unpacked\\";
Directory.CreateDirectory(extractPath);
return ExtractMemoryFile(extractPath, bundleFile.fileList);
}
return 0;
}
private static int ExtractWebDataFile(string webFileName, EndianBinaryReader reader)
{
var webFile = new WebFile(reader);
reader.Dispose();
if (webFile.fileList.Count > 0)
{
StatusStripUpdate($"Decompressing {Path.GetFileName(webFileName)} ...");
var extractPath = webFileName + "_unpacked\\";
Directory.CreateDirectory(extractPath);
return ExtractMemoryFile(extractPath, webFile.fileList);
}
return 0;
}
private static int ExtractMemoryFile(string extractPath, List<MemoryFile> fileList)
{
int extractedCount = 0;
foreach (var memFile in fileList)
{
var filePath = extractPath + memFile.fileName;
if (!Directory.Exists(extractPath))
{ {
var filePath = extractPath + memFile.fileName.Replace('/', '\\'); Directory.CreateDirectory(extractPath);
if (!Directory.Exists(Path.GetDirectoryName(filePath))) }
{ if (!File.Exists(filePath))
Directory.CreateDirectory(Path.GetDirectoryName(filePath)); {
} File.WriteAllBytes(filePath, memFile.stream.ToArray());
if (!File.Exists(filePath)) memFile.stream.Dispose();
{ extractedCount += 1;
File.WriteAllBytes(filePath, memFile.stream.ToArray());
memFile.stream.Dispose();
extractedCount += 1;
}
} }
} }
return extractedCount; return extractedCount;