/// <summary> /// Singlular file extract and patch worker function. /// </summary> /// <param name="treeNode">The current file/folder tree node.</param> /// <param name="overwrite">A referenced and static file overwrite option.</param> /// <param name="indexToWrite">A Hashtable of IndexFiles that require writing due to patching.</param> /// <param name="extractPatchArgs">The operation arguments to perform.</param> /// <returns>True upon successful extraction and/or patching of the file.</returns> private bool _ExtractPatchFile(TreeNode treeNode, ref DialogResult overwrite, Hashtable indexToWrite, ExtractPackPatchArgs extractPatchArgs) { if (treeNode == null) return false; //if (treeNode.Text == "affixes.txt.cooked") //{ // int bp = 0; //} // loop through for folders, etc NodeObject nodeObject = (NodeObject)treeNode.Tag; if (nodeObject.IsFolder) { foreach (TreeNode childNode in treeNode.Nodes) { if (!_ExtractPatchFile(childNode, ref overwrite, indexToWrite, extractPatchArgs)) return false; } return true; } // make sure we want to extract this file if (!treeNode.Checked || nodeObject.Index == null || nodeObject.FileEntry == null) return true; PackFileEntry fileEntry = nodeObject.FileEntry; // are we extracting? if (extractPatchArgs.ExtractFiles) { // get path String filePath = extractPatchArgs.KeepStructure ? Path.Combine(extractPatchArgs.RootDir, treeNode.FullPath) : Path.Combine(extractPatchArgs.RootDir, fileEntry.Name); // does it exist? bool fileExists = File.Exists(filePath); if (fileExists && overwrite == DialogResult.None) { overwrite = MessageBox.Show("An extract file already exists, do you wish to overwrite the file, and all following?\nFile: " + filePath, "Question", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (overwrite == DialogResult.Cancel) return false; } if (fileExists && overwrite == DialogResult.No) return true; // save file DialogResult extractDialogResult = DialogResult.Retry; while (extractDialogResult == DialogResult.Retry) { byte[] fileBytes = _fileManager.GetFileBytes(fileEntry, extractPatchArgs.PatchFiles); if (fileBytes == null) { extractDialogResult = MessageBox.Show("Failed to read file from .dat! Try again?", "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error); if (extractDialogResult == DialogResult.Abort) { overwrite = DialogResult.Cancel; return false; } continue; } Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllBytes(filePath, fileBytes); File.SetLastWriteTime(filePath, fileEntry.LastModified); break; } } // are we patching? if (!extractPatchArgs.PatchFiles) return true; // don't patch out string files or sound/movie files if (IndexFile.NoPatchExt.Any(ext => fileEntry.Name.EndsWith(ext))) return true; // if we're patching out the file, then change its bgColor and set its nodeObject state to backup treeNode.ForeColor = BackupColor; // is this file located else where? (i.e. does it have Siblings) String indexFileKey; if (fileEntry.Siblings != null && fileEntry.Siblings.Count > 0) { // this file has siblings - loop through foreach (PackFileEntry siblingFileEntry in fileEntry.Siblings.Where(siblingFileEntry => !siblingFileEntry.IsPatchedOut)) { siblingFileEntry.IsPatchedOut = true; indexFileKey = siblingFileEntry.Pack.NameWithoutExtension; if (!indexToWrite.ContainsKey(indexFileKey)) { indexToWrite.Add(indexFileKey, siblingFileEntry.Pack); } } } // now patch the curr file as well // only add index to list if it needs to be PackFile indexFile = nodeObject.Index; if (fileEntry.IsPatchedOut) return true; fileEntry.IsPatchedOut = true; indexFileKey = indexFile.NameWithoutExtension; if (!indexToWrite.ContainsKey(indexFileKey)) { indexToWrite.Add(indexFileKey, fileEntry.Pack); } return true; }
/// <summary> /// Event Function for "Extract to..." Button - Click. /// Checks and extracts files to prompted location. /// </summary> /// <param name="sender">The button clicked.</param> /// <param name="e">The Click event args.</param> private void _ExtractButton_Click(object sender, EventArgs e) { // make sure we have at least 1 checked file List<TreeNode> checkedNodes = new List<TreeNode>(); if (_GetCheckedNodes(_files_fileTreeView.Nodes, checkedNodes) == 0) { MessageBox.Show("No files checked for extraction!", "Need Files", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // where do we want to save it FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog { SelectedPath = Config.HglDir }; if (folderBrowserDialog.ShowDialog(this) != DialogResult.OK) return; // do we want to keep the directory structure? DialogResult drKeepStructure = MessageBox.Show("Keep directory structure?", "Path", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (drKeepStructure == DialogResult.Cancel) return; ExtractPackPatchArgs extractPatchArgs = new ExtractPackPatchArgs { ExtractFiles = true, KeepStructure = (drKeepStructure == DialogResult.Yes), PatchFiles = false, RootDir = folderBrowserDialog.SelectedPath, CheckedNodes = checkedNodes }; ProgressForm progressForm = new ProgressForm(_DoExtractPatch, extractPatchArgs); progressForm.SetLoadingText(String.Format("Extracting file(s)... ({0})", checkedNodes.Count)); progressForm.Show(this); }
/// <summary> /// Event Function for "Extract and Patch Index" Button - Click. /// Checks and extracts files to HGL data locations, then patches out files and saves updated index files. /// </summary> /// <param name="sender">The button clicked.</param> /// <param name="e">The Click event args.</param> private void _ExtractPatchButton_Click(object sender, EventArgs e) { // make sure we have at least 1 checked file List<TreeNode> checkedNodes = new List<TreeNode>(); if (_GetCheckedNodes(_files_fileTreeView.Nodes, checkedNodes) == 0) { MessageBox.Show("No files checked for extraction!", "Need Files", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } DialogResult dialogResult = MessageBox.Show( "Extract & Patch out checked file's?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dialogResult == DialogResult.No) return; ExtractPackPatchArgs extractPatchArgs = new ExtractPackPatchArgs { ExtractFiles = true, KeepStructure = true, PatchFiles = true, RootDir = Config.HglDir, CheckedNodes = checkedNodes }; _files_fileTreeView.BeginUpdate(); ProgressForm progressForm = new ProgressForm(_DoExtractPatch, extractPatchArgs); progressForm.SetLoadingText(String.Format("Extracting and Patching file(s)... ({0})", checkedNodes.Count)); progressForm.Disposed += delegate { _files_fileTreeView.EndUpdate(); }; progressForm.Show(this); }
/// <summary> /// Event Function for "Start" Button - Click. /// Extracts and/or patches files out of selected index files to the specified location. /// </summary> /// <param name="sender">The button clicked.</param> /// <param name="e">The Click event args.</param> private void _StartProcess_Button_Click(object sender, EventArgs e) { // make sure we have at least 1 checked file List<TreeNode> checkedNodes = new List<TreeNode>(); if (_GetCheckedNodes(_files_fileTreeView.Nodes, checkedNodes) == 0) { MessageBox.Show("No files checked for extraction!", "Need Files", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // are we extracting? bool extractFiles = _fileActionsExtract_checkBox.Checked; String savePath = String.Empty; bool keepStructure = false; if (extractFiles) { // where do we want to save it savePath = _fileActionsPath_textBox.Text; if (String.IsNullOrEmpty(savePath)) { // where do we want to save it FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog { SelectedPath = Config.HglDir }; if (folderBrowserDialog.ShowDialog(this) != DialogResult.OK) return; savePath = folderBrowserDialog.SelectedPath; } // do we want to keep the directory structure? DialogResult drKeepStructure = MessageBox.Show("Keep directory structure?", "Path", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (drKeepStructure == DialogResult.Cancel) return; keepStructure = (drKeepStructure == DialogResult.Yes); } // are we patching? bool patchFiles = _fileActionsPatch_checkBox.Checked; // are we doing anything... if (!extractFiles && !patchFiles) { MessageBox.Show("Please select at least one action out of extracting or patching to perform!", "No Actions Checked", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } // start process ExtractPackPatchArgs extractPatchArgs = new ExtractPackPatchArgs { ExtractFiles = extractFiles, KeepStructure = keepStructure, PatchFiles = patchFiles, RootDir = savePath, CheckedNodes = checkedNodes }; ProgressForm progressForm = new ProgressForm(_DoExtractPatch, extractPatchArgs); progressForm.SetLoadingText(String.Format("Extracting file(s)... ({0})", checkedNodes.Count)); progressForm.Show(this); }
private void _QuickXmlButtonClick(object sender, EventArgs e) { // where do we want to save it FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog { SelectedPath = Config.HglDir, Description = "Select folder to save uncooked XML files..."}; if (folderBrowserDialog.ShowDialog(this) != DialogResult.OK) return; ExtractPackPatchArgs extractPatchArgs = new ExtractPackPatchArgs { RootDir = folderBrowserDialog.SelectedPath }; ProgressForm progressForm = new ProgressForm(_QuickXmlWorker, extractPatchArgs); progressForm.SetLoadingText("Extracting and uncooking *.xml.cooked files..."); progressForm.Show(this); }
// todo: rewrite me private void _PackPatchButton_Click(object sender, EventArgs e) { // make sure we have at least 1 checked file List<TreeNode> checkedNodes = new List<TreeNode>(); if (_GetCheckedNodes(_files_fileTreeView.Nodes, checkedNodes) == 0) { MessageBox.Show("No files checked for packing!", "Need Files", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // get our custom index - or create if doesn't exist IndexFile packIndex = null; // todo: rewrite IndexFiles.FirstOrDefault(index => index.FileNameWithoutExtension == ReanimatorIndex); if (packIndex == null) { String indexPath = String.Format(@"data\{0}.idx", ReanimatorIndex); indexPath = Path.Combine(Config.HglDir, indexPath); try { File.Create(indexPath); } catch (Exception ex) { MessageBox.Show("Failed to create custom index file!\n\n" + ex, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // todo: rewrite packIndex = new Index(indexPath); // todo: rewrite IndexFiles.Add(packIndex); } ExtractPackPatchArgs extractPackPatchArgs = new ExtractPackPatchArgs { PackIndex = packIndex, RootDir = Config.HglDir, CheckedNodes = checkedNodes, PatchFiles = false }; _files_fileTreeView.BeginUpdate(); ProgressForm progressForm = new ProgressForm(_DoPackPatch, extractPackPatchArgs); progressForm.Disposed += delegate { _files_fileTreeView.EndUpdate(); }; progressForm.SetLoadingText("Packing and Patching files..."); progressForm.Show(); }
/// <summary> /// Singlular file extract and patch worker function. /// </summary> /// <param name="treeNode">The current file/folder tree node.</param> /// <param name="overwrite">A referenced and static file overwrite option.</param> /// <param name="indexToWrite">A Hashtable of IndexFiles that require writing due to patching.</param> /// <param name="extractPatchArgs">The operation arguments to perform.</param> /// <returns>True upon successful extraction and/or patching of the file.</returns> private bool _ExtractPatchFile(TreeNode treeNode, ref DialogResult overwrite, Hashtable indexToWrite, ExtractPackPatchArgs extractPatchArgs) { if (treeNode == null) { return(false); } //if (treeNode.Text == "affixes.txt.cooked") //{ // int bp = 0; //} // loop through for folders, etc NodeObject nodeObject = (NodeObject)treeNode.Tag; if (nodeObject.IsFolder) { foreach (TreeNode childNode in treeNode.Nodes) { if (!_ExtractPatchFile(childNode, ref overwrite, indexToWrite, extractPatchArgs)) { return(false); } } return(true); } // make sure we want to extract this file if (!treeNode.Checked || nodeObject.Index == null || nodeObject.FileEntry == null) { return(true); } PackFileEntry fileEntry = nodeObject.FileEntry; // are we extracting? if (extractPatchArgs.ExtractFiles) { // get path String filePath = extractPatchArgs.KeepStructure ? Path.Combine(extractPatchArgs.RootDir, treeNode.FullPath) : Path.Combine(extractPatchArgs.RootDir, fileEntry.Name); // does it exist? bool fileExists = File.Exists(filePath); if (fileExists && overwrite == DialogResult.None) { overwrite = MessageBox.Show("An extract file already exists, do you wish to overwrite the file, and all following?\nFile: " + filePath, "Question", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (overwrite == DialogResult.Cancel) { return(false); } } if (fileExists && overwrite == DialogResult.No) { return(true); } // save file DialogResult extractDialogResult = DialogResult.Retry; while (extractDialogResult == DialogResult.Retry) { byte[] fileBytes = _fileManager.GetFileBytes(fileEntry, extractPatchArgs.PatchFiles); if (fileBytes == null) { extractDialogResult = MessageBox.Show("Failed to read file from .dat! Try again?", "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error); if (extractDialogResult == DialogResult.Abort) { overwrite = DialogResult.Cancel; return(false); } continue; } Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllBytes(filePath, fileBytes); File.SetLastWriteTime(filePath, fileEntry.LastModified); break; } } // are we patching? if (!extractPatchArgs.PatchFiles) { return(true); } // don't patch out string files or sound/movie files if (IndexFile.NoPatchExt.Any(ext => fileEntry.Name.EndsWith(ext))) { return(true); } // if we're patching out the file, then change its bgColor and set its nodeObject state to backup treeNode.ForeColor = BackupColor; // is this file located else where? (i.e. does it have Siblings) String indexFileKey; if (fileEntry.Siblings != null && fileEntry.Siblings.Count > 0) { // this file has siblings - loop through foreach (PackFileEntry siblingFileEntry in fileEntry.Siblings.Where(siblingFileEntry => !siblingFileEntry.IsPatchedOut)) { siblingFileEntry.IsPatchedOut = true; indexFileKey = siblingFileEntry.Pack.NameWithoutExtension; if (!indexToWrite.ContainsKey(indexFileKey)) { indexToWrite.Add(indexFileKey, siblingFileEntry.Pack); } } } // now patch the curr file as well // only add index to list if it needs to be PackFile indexFile = nodeObject.Index; if (fileEntry.IsPatchedOut) { return(true); } fileEntry.IsPatchedOut = true; indexFileKey = indexFile.NameWithoutExtension; if (!indexToWrite.ContainsKey(indexFileKey)) { indexToWrite.Add(indexFileKey, fileEntry.Pack); } return(true); }
/// <summary> /// Shared threaded function for extracting and/or patching out files. /// </summary> /// <param name="progressForm">A valid user progress display form.</param> /// <param name="param">The operation arguments to perform.</param> private void _DoExtractPatch(ProgressForm progressForm, Object param) { ExtractPackPatchArgs extractPatchArgs = (ExtractPackPatchArgs)param; DialogResult overwrite = DialogResult.None; Hashtable indexToWrite = new Hashtable(); const int progressStepRate = 50; progressForm.ConfigBar(1, extractPatchArgs.CheckedNodes.Count, progressStepRate); progressForm.SetCurrentItemText("Extracting file(s)..."); try { _fileManager.BeginAllDatReadAccess(); } catch (Exception e) { MessageBox.Show("Failed to open dat files for reading!\nEnsure no other programs are using them and try again.\n" + e, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } int i = 0; foreach (TreeNode extractNode in extractPatchArgs.CheckedNodes) { if (i % progressStepRate == 0) { progressForm.SetCurrentItemText(extractNode.FullPath); } i++; if (_ExtractPatchFile(extractNode, ref overwrite, indexToWrite, extractPatchArgs)) { continue; } if (overwrite != DialogResult.Cancel) { MessageBox.Show("Unexpected error, extraction process terminated!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } return; } _fileManager.EndAllDatAccess(); // are we patching? if (!extractPatchArgs.PatchFiles) { MessageBox.Show("Extraction process completed sucessfully!", "Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (indexToWrite.Count == 0) { MessageBox.Show("Extraction process completed sucessfully!\nNo index files require modifications.", "Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } progressForm.SetCurrentItemText("Performing index modifications..."); foreach (IndexFile idx in from DictionaryEntry indexDictionary in indexToWrite select(IndexFile) indexDictionary.Value) { byte[] idxData = idx.ToByteArray(); Crypt.Encrypt(idxData); File.WriteAllBytes(idx.Path, idxData); } MessageBox.Show("Index modification process completed sucessfully!", "Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); }