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.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;

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
{
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();
}));
}

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> 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)
{
switch (CheckFileType(fullName, out var reader))

View File

@ -34,45 +34,121 @@ namespace AssetStudio
public static Action<string> StatusStripUpdate;
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 =>
{
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<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('/', '\\');
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;