private void ExtractFiles(object sender, bool decompile) { TreeViewWithSearchResults.TreeViewPackageTag package = null; TreeNode selectedNode = null; // the context menu can come from a TreeView or a ListView depending on where the user clicked to extract // each option has a difference in where we can get the values to extract if (((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl is TreeView) { var tree = ((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl as TreeView; selectedNode = tree.SelectedNode; package = tree.Tag as TreeViewWithSearchResults.TreeViewPackageTag; } else if (((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl is ListView) { var listView = ((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl as ListView; selectedNode = listView.SelectedItems[0].Tag as TreeNode; package = listView.Tag as TreeViewWithSearchResults.TreeViewPackageTag; } if (selectedNode.Tag.GetType() == typeof(PackageEntry)) { // We are a file var file = selectedNode.Tag as PackageEntry; var fileName = file.GetFileName(); package.Package.ReadEntry(file, out var output); if (decompile && fileName.EndsWith("_c", StringComparison.Ordinal)) { using (var resource = new Resource()) using (var memory = new MemoryStream(output)) { resource.Read(memory); var extension = FileExtract.GetExtension(resource); if (extension == null) { fileName = fileName.Substring(0, fileName.Length - 2); } else { fileName = Path.ChangeExtension(fileName, extension); } output = FileExtract.Extract(resource).ToArray(); } } var dialog = new SaveFileDialog { InitialDirectory = Settings.Config.SaveDirectory, Filter = "All files (*.*)|*.*", FileName = fileName, }; var userOK = dialog.ShowDialog(); if (userOK == DialogResult.OK) { Settings.Config.SaveDirectory = Path.GetDirectoryName(dialog.FileName); Settings.Save(); using (var stream = dialog.OpenFile()) { stream.Write(output, 0, output.Length); } } } else { //We are a folder var dialog = new FolderBrowserDialog(); if (dialog.ShowDialog() == DialogResult.OK) { var extractDialog = new ExtractProgressForm(package.Package, selectedNode, dialog.SelectedPath, decompile); extractDialog.ShowDialog(); } } }
private void ExportToolStripMenuItem_Click(object sender, EventArgs e) { //ToolTipText is the full filename var fileName = ((ToolStripMenuItem)sender).ToolTipText; var tag = ((ToolStripMenuItem)sender).Tag as ExportData; var resource = tag.Resource; Console.WriteLine($"Export requested for {fileName}"); string[] extensions = null; switch (resource.ResourceType) { case ResourceType.Sound: //WAV or MP3 extensions = new[] { ((Sound)resource.Blocks[BlockType.DATA]).Type.ToString().ToLower() }; break; case ResourceType.Texture: extensions = new[] { "png", "jpg", "gif", "bmp" }; break; case ResourceType.PanoramaLayout: extensions = new[] { "xml", "vxml" }; break; case ResourceType.PanoramaScript: extensions = new[] { "js", "vjs" }; break; case ResourceType.PanoramaStyle: extensions = new[] { "css", "vcss" }; break; case ResourceType.Mesh: extensions = new[] { "obj" }; break; } //Did we find a format we like? if (extensions != null) { var dialog = new SaveFileDialog { FileName = Path.GetFileName(Path.ChangeExtension(fileName, extensions[0])), InitialDirectory = Settings.Config.SaveDirectory, DefaultExt = extensions[0], }; var filter = string.Empty; foreach (var extension in extensions) { filter += $"{extension} files (*.{extension})|*.{extension}|"; } //Remove the last | dialog.Filter = filter.Substring(0, filter.Length - 1); var result = dialog.ShowDialog(); if (result == DialogResult.OK) { Settings.Config.SaveDirectory = Path.GetDirectoryName(dialog.FileName); Settings.Save(); using (var stream = dialog.OpenFile()) { switch (resource.ResourceType) { case ResourceType.Sound: var soundData = ((Sound)resource.Blocks[BlockType.DATA]).GetSound(); stream.Write(soundData, 0, soundData.Length); break; case ResourceType.Texture: var format = SKEncodedImageFormat.Png; switch (dialog.FilterIndex) { case 2: format = SKEncodedImageFormat.Jpeg; break; case 3: format = SKEncodedImageFormat.Gif; break; case 4: format = SKEncodedImageFormat.Bmp; break; } var image = SKImage.FromBitmap(((Texture)resource.Blocks[BlockType.DATA]).GenerateBitmap()); using (var data = image.Encode(format, 100)) { data.SaveTo(stream); } break; case ResourceType.PanoramaLayout: case ResourceType.PanoramaScript: case ResourceType.PanoramaStyle: var panoramaData = ((Panorama)resource.Blocks[BlockType.DATA]).Data; stream.Write(panoramaData, 0, panoramaData.Length); break; case ResourceType.Mesh: using (var objStream = new StreamWriter(stream)) using (var mtlStream = new StreamWriter(Path.ChangeExtension(dialog.FileName, "mtl"))) { MeshObject.WriteObject(objStream, mtlStream, Path.GetFileNameWithoutExtension(dialog.FileName), resource); } foreach (var texture in tag.Renderer.MaterialLoader.LoadedTextures) { Console.WriteLine($"Exporting texture for mesh: {texture}"); var textureResource = FileExtensions.LoadFileByAnyMeansNecessary(texture + "_c", tag.Renderer.CurrentFileName, tag.Renderer.CurrentPackage); var textureImage = SKImage.FromBitmap(((Texture)textureResource.Blocks[BlockType.DATA]).GenerateBitmap()); using (var texStream = new FileStream(Path.Combine(Path.GetDirectoryName(dialog.FileName), Path.GetFileNameWithoutExtension(texture) + ".png"), FileMode.Create, FileAccess.Write)) using (var data = textureImage.Encode(SKEncodedImageFormat.Png, 100)) { data.SaveTo(texStream); } } break; } } } } Console.WriteLine($"Export requested for {fileName} Complete"); }
private void ExtractToolStripMenuItem_Click(object sender, EventArgs e) { Package package = null; TreeNode selectedNode = null; // the context menu can come from a TreeView or a ListView depending on where the user clicked to extract // each option has a difference in where we can get the values to extract if (((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl is TreeView) { var tree = ((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl as TreeView; selectedNode = tree.SelectedNode; package = tree.Tag as Package; } else if (((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl is ListView) { var listView = ((ContextMenuStrip)((ToolStripMenuItem)sender).Owner).SourceControl as ListView; selectedNode = listView.SelectedItems[0].Tag as TreeNode; package = listView.Tag as Package; } if (selectedNode.Tag.GetType() == typeof(PackageEntry)) { // We are a file var file = selectedNode.Tag as PackageEntry; var dialog = new SaveFileDialog { InitialDirectory = Settings.Config.SaveDirectory, Filter = "All files (*.*)|*.*", FileName = file.FileName + "." + file.TypeName, }; var userOK = dialog.ShowDialog(); if (userOK == DialogResult.OK) { Settings.Config.SaveDirectory = Path.GetDirectoryName(dialog.FileName); Settings.Save(); using (var stream = dialog.OpenFile()) { package.ReadEntry(file, out var output); stream.Write(output, 0, output.Length); } } } else { //We are a folder var dialog = new FolderBrowserDialog(); if (dialog.ShowDialog() == DialogResult.OK) { foreach (TreeNode node in selectedNode.Nodes) { if (node.Tag.GetType() == typeof(PackageEntry)) { var file = node.Tag as PackageEntry; Console.WriteLine(node.Text); using (var stream = new FileStream(dialog.SelectedPath + Path.DirectorySeparatorChar + file.FileName + "." + file.TypeName, FileMode.Create)) { package.ReadEntry(file, out var output); stream.Write(output, 0, output.Length); } } else { MessageBox.Show("Nested Folder Extract Soon (tm)"); } } } } }