private void _DoLoadingThread(ProgressForm progressForm, Object var) { //// Single Player/Standard data files //// progressForm.SetCurrentItemText("Loading File Manager..."); _fileManager = new FileManager(Config.HglDir); //_fileManager = new FileManager(Config.HglDir, FileManager.ClientVersions.Mod); foreach (PackFile file in _fileManager.IndexFiles) file.BeginDatReading(); progressForm.SetCurrentItemText("Loading Excel and Strings Tables..."); if (!_fileManager.LoadTableFiles()) { MessageBox.Show("Failed to load excel and strings files!", "Data Table Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } foreach (PackFile file in _fileManager.IndexFiles) file.EndDatAccess(); if (_fileManager.IsVersionMod) _fileManager.ProcessTables(); if (!Config.LoadTCv4DataFiles) return; //// TCv4 data files //// progressForm.SetCurrentItemText("Loading TCv4 File Manager..."); _fileManagerTCv4 = new FileManager(Config.HglDir, FileManager.ClientVersions.TestCenter); foreach (PackFile file in _fileManagerTCv4.IndexFiles) file.BeginDatReading(); progressForm.SetCurrentItemText("Loading TCv4 Excel and Strings Tables..."); if (!_fileManagerTCv4.LoadTableFiles()) { MessageBox.Show("Failed to load TCv4 excel and strings files!", "Data Table Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } foreach (PackFile file in _fileManagerTCv4.IndexFiles) file.EndDatAccess(); }
private void _DoPackPatch(ProgressForm progressForm, Object param) { ExtractPackPatchArgs args = (ExtractPackPatchArgs)param; // find which checked nodes actually have files we can pack StringWriter packResults = new StringWriter(); String state = String.Format("Checking {0} file(s) for packing...", args.CheckedNodes.Count); const int packCheckStep = 200; progressForm.SetLoadingText(state); progressForm.ConfigBar(0, args.CheckedNodes.Count, packCheckStep); packResults.WriteLine(state); int i = 0; List<TreeNode> packNodes = new List<TreeNode>(); foreach (TreeNode checkedNode in args.CheckedNodes) { String filePath = Path.Combine(args.RootDir, checkedNode.FullPath); if (i % packCheckStep == 0) { progressForm.SetCurrentItemText(filePath); } i++; // ensure exists if (!File.Exists(filePath)) { packResults.WriteLine("{0} - File Not Found", filePath); continue; } // ensure it was once packed (need FilePathHash etc) // todo: implement Crypt.StringHash for FilePathHash and FolderPathHash NodeObject nodeObject = (NodeObject)checkedNode.Tag; if (nodeObject.FileEntry == null || nodeObject.FileEntry.NameHash == 0) { packResults.WriteLine("{0} - File Has No Base Version", filePath); continue; } packResults.WriteLine(filePath); packNodes.Add(checkedNode); } // write our error log if we have it const String packResultsFile = "packResults.log"; if (packNodes.Count != args.CheckedNodes.Count) { try { File.WriteAllText(packResultsFile, packResults.ToString()); } catch (Exception e) { MessageBox.Show("Failed to write to log file!\n\n" + e, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } // can we pack any? if (packNodes.Count == 0) { String errorMsg = String.Format("None of the {0} files were able to be packed!\nSee {1} for more details.", args.CheckedNodes.Count, packResultsFile); MessageBox.Show(errorMsg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } else { String errorMsg = String.Format("Of the {0} files checked, only {1} will be able to be packed.\nSee {2} for more details.\n\nContinue with packing and patching process?", args.CheckedNodes.Count, packNodes.Count, packResultsFile); DialogResult continuePacking = MessageBox.Show(errorMsg, "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (continuePacking == DialogResult.No) return; } } // pack our files // todo: rewrite //if (!_BeginDatAccess(IndexFiles, true)) //{ // MessageBox.Show( // "Failed to open dat files for writing!\nEnsure no other programs are using them and try again.", // "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); // return; //} state = String.Format("Packing {0} files...", packNodes.Count); progressForm.ConfigBar(0, packNodes.Count, packCheckStep); progressForm.SetLoadingText(state); packResults.WriteLine(state); i = 0; bool allNodesPacked = true; bool datNeedsCleaning = false; foreach (TreeNode packNode in packNodes) { NodeObject oldNodeObject = (NodeObject)packNode.Tag; if (i % packCheckStep == 0) { progressForm.SetCurrentItemText(packNode.FullPath); } i++; // add to our custom index if not already present PackFileEntry fileEntry = null; // todo: rewrite args.PackIndex.GetFileFromIndex(packNode.FullPath); if (fileEntry == null) { //fileEntry = args.PackIndex.AddFileToIndex(oldNodeObject.FileEntry); } else { // file exists - we'll need to clean the dat afterwards and remove orphaned data bytes datNeedsCleaning = true; } // update fileTime to now - ensures it will override older versions fileEntry.FileTime = DateTime.Now.ToFileTime(); // read in file data String filePath = Path.Combine(Config.HglDir, packNode.FullPath); byte[] fileData; try { fileData = File.ReadAllBytes(filePath); } catch (Exception) { packResults.WriteLine("{0} - Failed to read file data", filePath); allNodesPacked = false; continue; } // append to dat file try { // todo: rewite args.PackIndex.AddFileToDat(fileData, fileEntry); } catch (Exception) { packResults.WriteLine("{0} - Failed to add to data file", filePath); allNodesPacked = false; continue; } packResults.WriteLine(filePath); // update our node object while we're here //oldNodeObject.AddSibling(oldNodeObject); //NodeObject newNodeObject = new NodeObject //{ // Siblings = oldNodeObject.Siblings, // CanEdit = oldNodeObject.CanEdit, // FileEntry = fileEntry, // Index = args.PackIndex, // IsFolder = false //}; //packNode.Tag = newNodeObject; //packNode.ForeColor = BaseColor; } // were all files packed? if (!allNodesPacked) { try { File.WriteAllText(packResultsFile, packResults.ToString()); } catch (Exception e) { MessageBox.Show("Failed to write to log file!\n\n" + e, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } String warningMsg = String.Format("Not all files were packed!\nCheck {0} for more details.", packResultsFile); MessageBox.Show(warningMsg, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } // do we need to clean our dat? progressForm.SetLoadingText("Generating and saving files..."); progressForm.SetStyle(ProgressBarStyle.Marquee); if (datNeedsCleaning) { progressForm.SetCurrentItemText("Removing orphan data..."); // todo: rewrite args.PackIndex.RebuildDatFile(); } _fileManager.EndAllDatAccess(); // write updated index progressForm.SetCurrentItemText("Writing update dat index..."); try { byte[] idxBytes = args.PackIndex.ToByteArray(); Crypt.Encrypt(idxBytes); File.WriteAllBytes(args.PackIndex.FilePath, idxBytes); } catch (Exception e) { MessageBox.Show("Failed to write updated index file!\n\n" + e, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } MessageBox.Show("File packing and idx/dat writing completed!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); }
private void _DoCooking(ProgressForm progressForm, Object param) { List<TreeNode> cookNodes = (List<TreeNode>)param; const int progressUpdateFreq = 20; if (progressForm != null) { progressForm.ConfigBar(1, cookNodes.Count, progressUpdateFreq); } int i = 0; //foreach (String nodeFullPath in cookNodes.Select(treeNode => treeNode.FullPath)) foreach (TreeNode treeNode in cookNodes) { TreeNode cookedNode = treeNode.Parent; String nodeFullPath = cookedNode.FullPath.Replace(".cooked", ""); String filePath = Path.Combine(Config.HglDir, nodeFullPath); Debug.Assert(filePath.EndsWith(".xml")); if (i % progressUpdateFreq == 0 && progressForm != null) { progressForm.SetCurrentItemText(filePath); } i++; //if (nodeFullPath.Contains("actor_ghost.xml")) //{ // int bp = 0; //} if (!File.Exists(filePath)) continue; XmlDocument xmlDocument = new XmlDocument(); XmlCookedFile cookedXmlFile = new XmlCookedFile(_fileManager); DialogResult dr = DialogResult.Retry; byte[] cookedBytes = null; while (dr == DialogResult.Retry && cookedBytes == null) { try { xmlDocument.Load(filePath); cookedBytes = cookedXmlFile.CookXmlDocument(xmlDocument); } catch (Exception e) { ExceptionLogger.LogException(e, true); String errorMsg = String.Format("Failed to cook file!\n{0}\n\n{1}", nodeFullPath, e); dr = MessageBox.Show(errorMsg, "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation); if (dr == DialogResult.Abort) return; if (dr == DialogResult.Ignore) break; } } if (cookedBytes == null) continue; // todo: update newly cooked file to file tree String savePath = Path.Combine(Config.HglDir, filePath + ".cooked"); File.WriteAllBytes(savePath, cookedBytes); // debug section //String savePath2 = Path.Combine(Config.HglDir, filePath + ".cooked2"); //File.WriteAllBytes(savePath2, cookedBytes); //byte[] origBytes = File.ReadAllBytes(savePath); //if (cookedBytes.Length != origBytes.Length) //{ // int bp = 0; //} //if (!origBytes.SequenceEqual(cookedBytes)) //{ // int bp = 0; //} } }
/// <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); }
/// <summary> /// User-friendly uncooking of Tree Node list. /// </summary> /// <param name="progressForm">A progress form to update.</param> /// <param name="param">The Tree Node List.</param> private void _DoUnooking(ProgressForm progressForm, Object param) { List<TreeNode> uncookingNodes = (List<TreeNode>)param; const int progressUpdateFreq = 20; if (progressForm != null) { progressForm.ConfigBar(1, uncookingNodes.Count, progressUpdateFreq); } int i = 0; foreach (TreeNode treeNode in uncookingNodes) { NodeObject nodeObject = (NodeObject)treeNode.Tag; PackFileEntry fileEntry = nodeObject.FileEntry; // update progress if applicable if (i % progressUpdateFreq == 0 && progressForm != null) { progressForm.SetCurrentItemText(fileEntry.Path); } i++; // get the file bytes String relativePath = fileEntry.Path; byte[] fileBytes; try { fileBytes = _fileManager.GetFileBytes(fileEntry, true); if (fileBytes == null) continue; } catch (Exception e) { ExceptionLogger.LogException(e); continue; } // determine file type HellgateFile hellgateFile; if (relativePath.EndsWith(XmlCookedFile.Extension)) { hellgateFile = new XmlCookedFile(_fileManager); } else if (relativePath.EndsWith(RoomDefinitionFile.Extension)) { hellgateFile = new RoomDefinitionFile(relativePath); } else if (relativePath.EndsWith(MLIFile.Extension)) { hellgateFile = new MLIFile(); } else { Debug.Assert(false, "wtf"); continue; } // deserialise file DialogResult dr = DialogResult.Retry; bool uncooked = false; while (dr == DialogResult.Retry && !uncooked) { try { hellgateFile.ParseFileBytes(fileBytes); uncooked = true; } catch (Exception e) { ExceptionLogger.LogException(e, true); String errorMsg = String.Format("Failed to uncooked file!\n{0}\n\n{1}", relativePath, e); dr = MessageBox.Show(errorMsg, "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation); if (dr == DialogResult.Abort) return; if (dr == DialogResult.Ignore) break; } } if (!uncooked) continue; // save file String relativeSavePath = relativePath.Replace(HellgateFile.Extension, HellgateFile.ExtensionDeserialised); String savePath = Path.Combine(Config.HglDir, relativeSavePath); dr = DialogResult.Retry; bool saved = false; byte[] documentBytes = null; while (dr == DialogResult.Retry && !saved) { try { if (documentBytes == null) documentBytes = hellgateFile.ExportAsDocument(); File.WriteAllBytes(savePath, documentBytes); saved = true; } catch (Exception e) { ExceptionLogger.LogException(e, true); String errorMsg = String.Format("Failed to save file!\n{0}\n\n{1}", relativePath, e); dr = MessageBox.Show(errorMsg, "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation); if (dr == DialogResult.Abort) return; if (dr == DialogResult.Ignore) break; } } // update tree view TreeNode newTreeNode = new TreeNode(); NodeObject newNodeObject = new NodeObject { CanEdit = true, IsUncookedVersion = true }; newTreeNode.Tag = newNodeObject; treeNode.Nodes.Add(newTreeNode); } }
private void _SaveSinglePlayerFiles(ProgressForm progress, object obj) { // string savePath = (string)obj; // foreach (DataTable spDataTable in _tableDataSet.XlsDataSet.Tables) // { // if (spDataTable.TableName.Contains("_TCv4_")) continue; // if (spDataTable.TableName.Contains("Strings_")) continue; // progress.SetCurrentItemText("Current table... " + spDataTable.TableName); // ExcelFile spExcelFile = _tableDataSet.TableFiles.GetExcelTableFromId(spDataTable.TableName); // byte[] buffer = spExcelFile.GenerateFile(spDataTable); // string path = Path.Combine(savePath, spExcelFile.FilePath); // string filename = spExcelFile.FileName + "." + spExcelFile.FileExtension; // if (!Directory.Exists(path)) // { // Directory.CreateDirectory(path); // } // File.WriteAllBytes(path + filename, buffer); // } }
private void DoExtractFiles(ProgressForm progressBar, Object param) { PackFileEntry[] files = (PackFileEntry[])param; FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog { SelectedPath = _packFile.Directory }; if (ShowDialog(folderBrowserDialog) != DialogResult.OK) { return; } String extractToPath = folderBrowserDialog.SelectedPath; bool keepPath = false; DialogResult dr = MessageBox("Keep directory structure?", "Path", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (dr == DialogResult.Cancel) { return; } if (dr == DialogResult.Yes) { keepPath = true; extractToPath += @"\" + _packFile.NameWithoutExtension; } progressBar.ConfigBar(0, files.Length, 1); progressBar.SetLoadingText("Extracting files to... " + extractToPath); int filesSaved = 0; _packFile.BeginDatReading(); foreach (PackFileEntry file in files) { while (true) { try { byte[] buffer = _packFile.GetFileBytes(file); string keepPathString = "\\"; if (keepPath) { keepPathString += file.Directory; Directory.CreateDirectory(extractToPath + keepPathString); } progressBar.SetCurrentItemText(file.Name); FileStream fileOut = new FileStream(extractToPath + keepPathString + file.Name, FileMode.Create); fileOut.Write(buffer, 0, buffer.Length); fileOut.Close(); filesSaved++; break; } catch (Exception e) { DialogResult failedDr = MessageBox("Failed to extract file from dat!\nFile: " + file.Name + "\n\n" + e.ToString(), "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error); if (failedDr == DialogResult.Ignore || failedDr == DialogResult.Abort) { break; } } } } _packFile.EndDatAccess(); MessageBox(filesSaved + " file(s) saved!", "Notice", MessageBoxButtons.OK, MessageBoxIcon.Information); }
/// <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); }
private void _QuickExcel_Button_Click(object sender, EventArgs e) { ProgressForm progressForm = new ProgressForm(_DoQuickExcel, _fileManager); progressForm.ConfigBar(0, 20, 1); progressForm.SetLoadingText("Uncooking excel files..."); ; progressForm.Show(this); if (!_quickExcelTCv4_checkBox.Checked || !_quickExcelTCv4_checkBox.Enabled) return; ProgressForm progressFormTCv4 = new ProgressForm(_DoQuickExcel, _fileManagerTCv4); progressFormTCv4.ConfigBar(0, 20, 1); progressFormTCv4.SetLoadingText("Uncooking TCv4 excel files..."); ; progressFormTCv4.Show(this); progressFormTCv4.Top = progressForm.Top + progressForm.Height + 20; }
// 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(); }
private void _LoadFileExplorerThread(ProgressForm progress, object obj) { _fileExplorer = new FileExplorer(_fileManager, _fileManagerTCv4); }
private void _OpenFileExplorer() { if (_fileExplorer != null && !_fileExplorer.IsDisposed) // it works - but probably should be tested a bit more if we keep this option { DialogResult dr = MessageBox.Show("An instance of FileExplorer is already open.\nDo you want to open another instance? (Not fully tested)", "Already Open", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dr == DialogResult.No) return; } ProgressForm progressForm = new ProgressForm(_LoadFileExplorerThread, null); progressForm.SetStyle(ProgressBarStyle.Marquee); progressForm.SetLoadingText("Initializing File Explorer..."); progressForm.SetCurrentItemText(""); progressForm.Disposed += delegate { _fileExplorer.Show(); }; progressForm.Show(this); }
/// <summary> /// User-friendly uncooking of Tree Node list. /// </summary> /// <param name="progressForm">A progress form to update.</param> /// <param name="param">The Tree Node List.</param> private void _DoUnooking(ProgressForm progressForm, Object param) { List <TreeNode> uncookingNodes = (List <TreeNode>)param; const int progressUpdateFreq = 20; if (progressForm != null) { progressForm.ConfigBar(1, uncookingNodes.Count, progressUpdateFreq); } int i = 0; foreach (TreeNode treeNode in uncookingNodes) { NodeObject nodeObject = (NodeObject)treeNode.Tag; PackFileEntry fileEntry = nodeObject.FileEntry; // update progress if applicable if (i % progressUpdateFreq == 0 && progressForm != null) { progressForm.SetCurrentItemText(fileEntry.Path); } i++; // get the file bytes String relativePath = fileEntry.Path; byte[] fileBytes; try { fileBytes = _fileManager.GetFileBytes(fileEntry, true); if (fileBytes == null) { continue; } } catch (Exception e) { ExceptionLogger.LogException(e); continue; } // determine file type HellgateFile hellgateFile; if (relativePath.EndsWith(XmlCookedFile.Extension)) { hellgateFile = new XmlCookedFile(_fileManager); } else if (relativePath.EndsWith(RoomDefinitionFile.Extension)) { hellgateFile = new RoomDefinitionFile(relativePath); } else if (relativePath.EndsWith(MLIFile.Extension)) { hellgateFile = new MLIFile(); } else { Debug.Assert(false, "wtf"); continue; } // deserialise file DialogResult dr = DialogResult.Retry; bool uncooked = false; while (dr == DialogResult.Retry && !uncooked) { try { hellgateFile.ParseFileBytes(fileBytes); uncooked = true; } catch (Exception e) { ExceptionLogger.LogException(e, true); String errorMsg = String.Format("Failed to uncooked file!\n{0}\n\n{1}", relativePath, e); dr = MessageBox.Show(errorMsg, "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation); if (dr == DialogResult.Abort) { return; } if (dr == DialogResult.Ignore) { break; } } } if (!uncooked) { continue; } // save file String relativeSavePath = relativePath.Replace(HellgateFile.Extension, HellgateFile.ExtensionDeserialised); String savePath = Path.Combine(Config.HglDir, relativeSavePath); dr = DialogResult.Retry; bool saved = false; byte[] documentBytes = null; while (dr == DialogResult.Retry && !saved) { try { if (documentBytes == null) { documentBytes = hellgateFile.ExportAsDocument(); } File.WriteAllBytes(savePath, documentBytes); saved = true; } catch (Exception e) { ExceptionLogger.LogException(e, true); String errorMsg = String.Format("Failed to save file!\n{0}\n\n{1}", relativePath, e); dr = MessageBox.Show(errorMsg, "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation); if (dr == DialogResult.Abort) { return; } if (dr == DialogResult.Ignore) { break; } } } // update tree view TreeNode newTreeNode = new TreeNode(); NodeObject newNodeObject = new NodeObject { CanEdit = true, IsUncookedVersion = true }; newTreeNode.Tag = newNodeObject; treeNode.Nodes.Add(newTreeNode); } }
private void _DoQuickExcel(ProgressForm progressForm, Object param) { FileManager fileManager = (FileManager)param; String root = _quickExcelDir_textBox.Text; if (root == "") return; if (fileManager.IsVersionTestCenter) root = Path.Combine(root, "tcv4"); foreach (IndexFile file in fileManager.IndexFiles) // Open Dats for reading file.BeginDatReading(); int i = 0; foreach (PackFileEntry fileEntry in fileManager.FileEntries.Values) { if (!fileEntry.Name.EndsWith(ExcelFile.Extension) && (!fileEntry.Name.EndsWith(StringsFile.Extention) || !fileEntry.Directory.Contains(fileManager.Language))) continue; if (i++ % 10 == 0 && progressForm != null) progressForm.SetCurrentItemText(fileEntry.Path); byte[] fileBytes; try { fileBytes = fileManager.GetFileBytes(fileEntry, true); } catch (Exception e) { String error = String.Format("Failed to get '{0}' file bytes, continue?\n\n{1}", fileEntry.Path, e); DialogResult dr = MessageBox.Show(error, "Excel Extration Error", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (dr == DialogResult.No) return; continue; } ExcelFile excelFile = null; if (fileEntry.Name.EndsWith(ExcelFile.Extension)) { excelFile = new ExcelFile(fileBytes, fileEntry.Path, fileManager.ClientVersion); if (excelFile.Attributes.IsEmpty) continue; } byte[] writeBytes = fileBytes; if (excelFile != null) { String[] columns = null; if (fileManager.IsVersionTestCenter) { DataFile spVersion; if (_fileManager.DataFiles.TryGetValue(excelFile.StringId, out spVersion)) { ObjectDelegator objectDelegator = _fileManager.DataFileDelegators[spVersion.StringId]; FieldInfo[] fieldInfos = spVersion.Attributes.RowType.GetFields(); columns = new String[objectDelegator.PublicFieldCount]; int col = 0; foreach (ObjectDelegator.FieldDelegate fieldDelegate in objectDelegator.FieldDelegatesPublicList) { columns[col++] = fieldDelegate.Name; } } } try { writeBytes = excelFile.ExportCSV(fileManager, columns); } catch (Exception e) { String error = String.Format("Failed to export CSV for '{0}', continue?\n\n{1}", fileEntry.Path, e); DialogResult dr = MessageBox.Show(error, "Excel Extration Error", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (dr == DialogResult.No) return; continue; } } String filePath = Path.Combine(root, fileEntry.Path).Replace(ExcelFile.Extension, ExcelFile.ExtensionDeserialised); Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.WriteAllBytes(filePath, writeBytes); } foreach (IndexFile file in fileManager.IndexFiles) // Close Dats file.EndDatAccess(); }
private void _QuickLevelRulesWorker(ProgressForm progressForm, Object param) { const int progressStepRate = 50; const String outputResultsName = "conversion_results_drl.txt"; ExtractPackPatchArgs extractPatchArgs = (ExtractPackPatchArgs)param; TextWriter consoleOut = Console.Out; TextWriter textWriter = new StreamWriter(outputResultsName); Console.SetOut(textWriter); Console.WriteLine("Results of most recent conversion of *.drl files. Please scroll to end for tallied results."); // get files List<PackFileEntry> drlFiles = _fileManager.FileEntries.Values.Where(fileEntry => fileEntry.Name.EndsWith(LevelRulesFile.Extension)).ToList(); _fileManager.BeginAllDatReadAccess(); // loop through file entries int count = drlFiles.Count(); progressForm.ConfigBar(1, count, progressStepRate); progressForm.SetLoadingText("Converting *.drl files... (" + count + ")"); int i = 0; int successful = 0; int readFailed = 0; int exportFailed = 0; int saveFailed = 0; int failed = 0; foreach (PackFileEntry fileEntry in drlFiles) { // update progress if (i % progressStepRate == 0) { progressForm.SetCurrentItemText(fileEntry.Path); } i++; // get file and convert Console.WriteLine("Processing file " + fileEntry.Path + "..."); byte[] fileBytes; LevelRulesFile levelRulesFile = new LevelRulesFile(); try { fileBytes = _fileManager.GetFileBytes(fileEntry); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); Console.WriteLine("Error: FileManager failed to read file!\n"); readFailed++; continue; } try { levelRulesFile.ParseFileBytes(fileBytes); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); Console.WriteLine("Warning: Failed to convert file: " + fileEntry.Name + "\n"); failed++; continue; } // generate file String savePath = Path.Combine(extractPatchArgs.RootDir, fileEntry.Path); byte[] documentBytes; try { documentBytes = levelRulesFile.ExportAsDocument(); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); Console.WriteLine("Warning: ExportAsDocument() failed for file: " + savePath + "\n"); exportFailed++; continue; } // save file String filePath = savePath.Replace(LevelRulesFile.Extension, LevelRulesFile.ExtensionDeserialised); try { String directoryName = Path.GetDirectoryName(savePath); Debug.Assert(directoryName != null); Directory.CreateDirectory(directoryName); // FormTools.WriteFileWithRetry(filePath, documentBytes); should use this - but want a way to "cancel all" first, or will get endless questions for big failures File.WriteAllBytes(filePath, documentBytes); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); Console.WriteLine("Warning: WriteAllBytes() failed for file: " + filePath + "\n"); saveFailed++; continue; } successful++; } _fileManager.EndAllDatAccess(); // output final results Console.WriteLine("\nFiles Found: " + count); Console.WriteLine("\nFiles Created: " + successful); if (readFailed > 0) Console.WriteLine(readFailed + " file(s) could not be read from the data files."); if (exportFailed > 0) Console.WriteLine(readFailed + " file(s) could not be exported."); if (saveFailed > 0) Console.WriteLine(readFailed + " file(s) could not be saved."); if (failed > 0) Console.WriteLine(failed + " file(s) failed."); textWriter.Close(); Console.SetOut(consoleOut); try { Process process = new Process { StartInfo = { FileName = Config.TxtEditor, Arguments = outputResultsName } }; process.Start(); } catch (Exception e) { MessageBox.Show( "Failed to open results!\nThe " + outputResultsName + " can be found in your Reanimator folder.\n" + e, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <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); }
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); }
private void _QuickXmlWorker(ProgressForm progressForm, Object param) { const int progressStepRate = 50; const String outputResultsName = "uncook_results.txt"; ExtractPackPatchArgs extractPatchArgs = (ExtractPackPatchArgs)param; TextWriter consoleOut = Console.Out; TextWriter textWriter = new StreamWriter(outputResultsName); Console.SetOut(textWriter); Console.WriteLine("Results of most recent uncooking of .xml.cooked files. Please scroll to end for tallied results."); // get all .xml.cooked List<PackFileEntry> xmlCookedFiles = _fileManager.FileEntries.Values.Where(fileEntry => fileEntry.Name.EndsWith(XmlCookedFile.Extension)).ToList(); _fileManager.BeginAllDatReadAccess(); // loop through file entries int count = xmlCookedFiles.Count(); progressForm.ConfigBar(1, count, progressStepRate); progressForm.SetLoadingText("Extracting and uncooking .xml.cooked files... (" + count + ")"); int i = 0; int uncooked = 0; int readFailed = 0; int uncookFailed = 0; int testCentreWarnings = 0; int resurrectionWarnings = 0; int excelWarnings = 0; foreach (PackFileEntry fileEntry in xmlCookedFiles) { // update progress if (i % progressStepRate == 0) { progressForm.SetCurrentItemText(fileEntry.Path); } i++; // get file and uncook Console.WriteLine(fileEntry.Path); byte[] fileBytes; XmlCookedFile xmlCookedFile = new XmlCookedFile(_fileManager); try { fileBytes = _fileManager.GetFileBytes(fileEntry); } catch (Exception) { Console.WriteLine("Error: FileManager failed to read file!\n"); readFailed++; continue; } try { xmlCookedFile.ParseFileBytes(fileBytes, true); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); Console.WriteLine("Warning: Failed to uncook file: " + fileEntry.Name + "\n"); uncookFailed++; continue; } // did we have any uncooking issues? bool hadWarning = false; if (xmlCookedFile.HasTestCentreElements) { Console.WriteLine("Warning: File has TestCentre-specific elements."); hadWarning = true; testCentreWarnings++; } if (xmlCookedFile.HasResurrectionElements) { Console.WriteLine("Warning: File has Resurrection-specific elements."); hadWarning = true; resurrectionWarnings++; } if (xmlCookedFile.HasExcelStringsMissing) { Console.WriteLine("Warning: File has " + xmlCookedFile.ExcelStringsMissing.Count + " unknown excel strings: "); foreach (String str in xmlCookedFile.ExcelStringsMissing) Console.WriteLine("\t- \"" + str + "\""); hadWarning = true; excelWarnings++; } // save file String savePath = Path.Combine(extractPatchArgs.RootDir, fileEntry.Path); Directory.CreateDirectory(Path.GetDirectoryName(savePath)); try { xmlCookedFile.SaveXmlDocument(savePath.Replace(".cooked", "")); } catch (Exception) { Console.WriteLine("Warning: Failed to save XML file: " + savePath + "\n"); continue; } if (hadWarning) Console.WriteLine(); uncooked++; } _fileManager.EndAllDatAccess(); // output final results Console.WriteLine("\nXML Files Uncooked: " + uncooked); if (readFailed > 0) Console.WriteLine(readFailed + " file(s) could not be read from the data files."); if (uncookFailed > 0) Console.WriteLine(uncookFailed + " file(s) failed to uncook at all."); if (testCentreWarnings > 0) Console.WriteLine(testCentreWarnings + " file(s) had TestCentre-specific XML elements which wont be included when recooked."); if (resurrectionWarnings > 0) Console.WriteLine(resurrectionWarnings + " file(s) had Resurrection-specific XML elements which wont be included when recooked."); if (excelWarnings > 0) Console.WriteLine(excelWarnings + " file(s) had excel warnings and cannot be safely recooked."); textWriter.Close(); Console.SetOut(consoleOut); try { Process process = new Process { StartInfo = { FileName = Config.TxtEditor, Arguments = outputResultsName } }; process.Start(); } catch (Exception e) { MessageBox.Show( "Failed to open results!\nThe " + outputResultsName + " can be found in your Reanimator folder.\n" + e, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void _ReanimatorLoad(object sender, EventArgs e) { try { Height = Config.ClientHeight; Width = Config.ClientWidth; Show(); Refresh(); if (_CheckInstallation()) { ProgressForm progressForm = new ProgressForm(_DoLoadingThread, null); progressForm.SetStyle(ProgressBarStyle.Marquee); progressForm.SetLoadingText("Initializing Reanimator subsystems..."); progressForm.Disposed += delegate { _OpenExcelTableEditor(); _OpenExcelTableEditorTCv4(); if (Config.ShowFileExplorer) _OpenFileExplorer(); }; progressForm.Show(this); } } catch (Exception ex) { ExceptionLogger.LogException(ex); MessageBox.Show(ex.Message, "ReanimatorLoad"); } }
/// <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); }
/// <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); }
/// <summary> /// Determines if the file HGL tries to load exists.<br /> /// That is, checks .dat, if patched out, checks HGL data dir's. /// </summary> /// <param name="filePath">The path to the file - relative to HGL e.g. "data\colorsets.xml.cooked"</param> /// <returns>true for file exists, false otherwise.</returns> //public bool GetFileExists(String filePath) //{ // if (String.IsNullOrEmpty(filePath)) return false; // if (filePath[0] == '\\') // { // filePath = filePath.Replace(@"\data", "data"); // } // TreeNode treeNode = (TreeNode)_fileTable[filePath]; // if (treeNode == null) return false; // // is not backup (in idx/dat) // NodeObject nodeObject = (NodeObject)treeNode.Tag; // if (!nodeObject.IsBackup) return true; // // get full file path // filePath = Path.Combine(Config.HglDir, treeNode.FullPath); // return File.Exists(filePath); //} /// <summary> /// Event Function for "Uncook" Button - Click. /// Uncooks checked files to their respective HGL file system location. /// </summary> /// <param name="sender">The button clicked.</param> /// <param name="e">The Click event args.</param> private void _UncookButton_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; } // we're uncooking, so we want only uncook-able files List<TreeNode> uncookingNodes = (from treeNode in checkedNodes let nodeObject = (NodeObject)treeNode.Tag where nodeObject.CanCookWith && !nodeObject.IsUncookedVersion select treeNode).ToList(); if (uncookingNodes.Count == 0) { MessageBox.Show("Unable to find any checked files that can be uncooked!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } ProgressForm progressForm = new ProgressForm(_DoUnooking, uncookingNodes); progressForm.SetLoadingText(String.Format("Uncooking file(s)... ({0})", uncookingNodes.Count)); progressForm.Show(this); }
private void DoExtractFiles(ProgressForm progressBar, Object param) { PackFileEntry[] files = (PackFileEntry[]) param; FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog {SelectedPath = _packFile.Directory}; if (ShowDialog(folderBrowserDialog) != DialogResult.OK) return; String extractToPath = folderBrowserDialog.SelectedPath; bool keepPath = false; DialogResult dr = MessageBox("Keep directory structure?", "Path", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (dr == DialogResult.Cancel) return; if (dr == DialogResult.Yes) { keepPath = true; extractToPath += @"\" + _packFile.NameWithoutExtension; } progressBar.ConfigBar(0, files.Length, 1); progressBar.SetLoadingText("Extracting files to... " + extractToPath); int filesSaved = 0; _packFile.BeginDatReading(); foreach (PackFileEntry file in files) { while (true) { try { byte[] buffer = _packFile.GetFileBytes(file); string keepPathString = "\\"; if (keepPath) { keepPathString += file.Directory; Directory.CreateDirectory(extractToPath + keepPathString); } progressBar.SetCurrentItemText(file.Name); FileStream fileOut = new FileStream(extractToPath + keepPathString + file.Name, FileMode.Create); fileOut.Write(buffer, 0, buffer.Length); fileOut.Close(); filesSaved++; break; } catch (Exception e) { DialogResult failedDr = MessageBox("Failed to extract file from dat!\nFile: " + file.Name + "\n\n" + e.ToString(), "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error); if (failedDr == DialogResult.Ignore || failedDr == DialogResult.Abort) break; } } } _packFile.EndDatAccess(); MessageBox(filesSaved + " file(s) saved!", "Notice", MessageBoxButtons.OK, MessageBoxIcon.Information); }
/// <summary> /// The operations called from this method can take a long time to run, launch new thread. /// </summary> /// <param name="progressForm"></param> /// <param name="var"></param> public void InitThreadedComponents(ProgressForm progressForm, Object var) { _CreateDataTable(); _CreateTableView(); // don't create row view for UnitData type until specifically asked to due to large number of columns //if (_dataFile.StringId == "ITEMS" || _dataFile.StringId == "MONSTERS" || // _dataFile.StringId == "PLAYERS" || _dataFile.StringId == "OBJECTS" || // _dataFile.StringId == "MISSILES") return; _CreateRowView(); }