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 _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(); } }
/// <summary> /// Creates a new data table inside a tabbed control. /// </summary> /// <param name="id">string id associated with the datafile</param> public void CreateTab(String id) { DataFile dataFile = _fileManager.GetDataFile(id); DatafileEditor editor = new DatafileEditor(dataFile, _fileManager) { Dock = DockStyle.Fill }; TabPage tabPage = new TabPage(id) { Parent = _tabControl, Name = id }; // must disconnect the DataGridView forms controls from the DataSet to modify it (the DataSet) in a non-UI thread; see: (essentially the problem we were having) // http://connect.microsoft.com/VisualStudio/feedback/details/117148/datagridview-throws-system-invalidoperationexception-when-used-with-a-ibindinglist-that-raises-listchanged-on-a-background-thread // while we are disconnecting every grid view, we only actually need to do it if it's going to be modified due to relations // however this doesn't appear to lag them or the process in any significant manner, so this will do foreach (DatafileEditor datafileEditor in _datafileEditors) { datafileEditor.DisconnectFromDataSet(); } ProgressForm progress = new ProgressForm(editor.InitThreadedComponents, null); progress.SetStyle(ProgressBarStyle.Marquee); progress.SetLoadingText("Generating DataTable..."); progress.SetCurrentItemText(String.Empty); progress.ShowDialog(this); _tabControl.SuspendLayout(); tabPage.SuspendLayout(); tabPage.Controls.Add(editor); editor.AddedToTabPage = true; tabPage.ResumeLayout(); _tabControl.ResumeLayout(); foreach (DatafileEditor datafileEditor in _datafileEditors) { datafileEditor.ReconnectToDataSet(); } _datafileEditors.Add(editor); }
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); }
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> /// 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); } }
/// <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); }
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); }
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 _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; //} } }
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 _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); } }
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); } }
/// <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); }