From 4bcc16245cc0066114de3bf3933752fd2df93e2f Mon Sep 17 00:00:00 2001 From: Perfare Date: Wed, 18 Apr 2018 12:04:46 +0800 Subject: [PATCH] Improve extract file --- AssetStudio/AssetStudioForm.Designer.cs | 26 +++--- AssetStudio/AssetStudioForm.cs | 14 +-- AssetStudio/StudioClasses/Importer.cs | 52 ----------- AssetStudio/StudioClasses/Studio.cs | 116 ++++++++++++++++++++---- 4 files changed, 116 insertions(+), 92 deletions(-) diff --git a/AssetStudio/AssetStudioForm.Designer.cs b/AssetStudio/AssetStudioForm.Designer.cs index 72c2e9c..5a2470a 100644 --- a/AssetStudio/AssetStudioForm.Designer.cs +++ b/AssetStudio/AssetStudioForm.Designer.cs @@ -35,7 +35,7 @@ this.loadFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.loadFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 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.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.displayAll = new System.Windows.Forms.ToolStripMenuItem(); @@ -154,7 +154,7 @@ this.loadFileToolStripMenuItem, this.loadFolderToolStripMenuItem, this.toolStripMenuItem1, - this.extractBundleToolStripMenuItem, + this.extractFileToolStripMenuItem, this.extractFolderToolStripMenuItem}); this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; this.fileToolStripMenuItem.Size = new System.Drawing.Size(39, 21); @@ -163,33 +163,33 @@ // 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.Click += new System.EventHandler(this.loadFile_Click); // // 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.Click += new System.EventHandler(this.loadFolder_Click); // // 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.extractBundleToolStripMenuItem.Size = new System.Drawing.Size(159, 22); - this.extractBundleToolStripMenuItem.Text = "Extract bundle"; - this.extractBundleToolStripMenuItem.Click += new System.EventHandler(this.extractBundleToolStripMenuItem_Click); + this.extractFileToolStripMenuItem.Name = "extractFileToolStripMenuItem"; + this.extractFileToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.extractFileToolStripMenuItem.Text = "Extract file"; + this.extractFileToolStripMenuItem.Click += new System.EventHandler(this.extractFileToolStripMenuItem_Click); // // 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.Click += new System.EventHandler(this.extractFolderToolStripMenuItem_Click); // @@ -397,7 +397,7 @@ this.allToolStripMenuItem.CheckOnClick = true; this.allToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; 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.Click += new System.EventHandler(this.typeToolStripMenuItem_Click); // @@ -1029,7 +1029,7 @@ private System.Windows.Forms.ToolStripMenuItem enablePreview; private System.Windows.Forms.ToolStripMenuItem displayInfo; 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 exportallobjectsMenuItem; private System.Windows.Forms.ToolStripMenuItem exportselectedobjectsMenuItem; diff --git a/AssetStudio/AssetStudioForm.cs b/AssetStudio/AssetStudioForm.cs index 48e5bc2..ebda6a8 100644 --- a/AssetStudio/AssetStudioForm.cs +++ b/AssetStudio/AssetStudioForm.cs @@ -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 { - Filter = "Bundle files|*.*", + Filter = "All types|*.*", FilterIndex = 1, RestoreDirectory = true, Multiselect = true @@ -152,7 +152,7 @@ namespace AssetStudio { progressBar1.Value = 0; progressBar1.Maximum = openBundleDialog.FileNames.Length; - ExtractBundle(openBundleDialog.FileNames); + ExtractFile(openBundleDialog.FileNames); } } @@ -161,10 +161,10 @@ namespace AssetStudio var openFolderDialog1 = new OpenFolderDialog(); 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.Maximum = bundleFiles.Length; - ExtractBundle(bundleFiles); + progressBar1.Maximum = files.Length; + ExtractFile(files); } } @@ -231,7 +231,7 @@ namespace AssetStudio showTypeToolStripMenuItem.DropDownItems.Add(typeItem); } 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(); })); } diff --git a/AssetStudio/StudioClasses/Importer.cs b/AssetStudio/StudioClasses/Importer.cs index dff7a43..a066f19 100644 --- a/AssetStudio/StudioClasses/Importer.cs +++ b/AssetStudio/StudioClasses/Importer.cs @@ -14,58 +14,6 @@ namespace AssetStudio public static HashSet importFilesHash = new HashSet(); //to improve the loading speed public static HashSet assetsfileListHash = new HashSet(); //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) { switch (CheckFileType(fullName, out var reader)) diff --git a/AssetStudio/StudioClasses/Studio.cs b/AssetStudio/StudioClasses/Studio.cs index 85905ad..7dfc739 100644 --- a/AssetStudio/StudioClasses/Studio.cs +++ b/AssetStudio/StudioClasses/Studio.cs @@ -34,45 +34,121 @@ namespace AssetStudio public static Action StatusStripUpdate; public static Action 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 => { 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(); } 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); reader.Dispose(); if (bundleFile.fileList.Count > 0) { 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 fileList) + { + int extractedCount = 0; + foreach (var memFile in fileList) + { + var filePath = extractPath + memFile.fileName; + if (!Directory.Exists(extractPath)) { - var filePath = extractPath + memFile.fileName.Replace('/', '\\'); - if (!Directory.Exists(Path.GetDirectoryName(filePath))) - { - Directory.CreateDirectory(Path.GetDirectoryName(filePath)); - } - if (!File.Exists(filePath)) - { - File.WriteAllBytes(filePath, memFile.stream.ToArray()); - memFile.stream.Dispose(); - extractedCount += 1; - } + Directory.CreateDirectory(extractPath); + } + if (!File.Exists(filePath)) + { + File.WriteAllBytes(filePath, memFile.stream.ToArray()); + memFile.stream.Dispose(); + extractedCount += 1; } } return extractedCount;