private void _OpenXmlFile(String filePath) { byte[] xmlCookedBytes; try { xmlCookedBytes = File.ReadAllBytes(filePath); } catch (Exception e) { MessageBox.Show("Failed to read in file!\n\n" + e, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } XmlCookedFile xmlCookedFile = new XmlCookedFile(_fileManager); try { xmlCookedFile.ParseFileBytes(xmlCookedBytes, true); } catch (Exception e) { MessageBox.Show("Failed to uncook xml file!\n" + e, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } String xmlPath = filePath.Replace(".cooked", ""); try { xmlCookedFile.SaveXmlDocument(xmlPath); } catch (Exception ex) { MessageBox.Show("Failed to save uncooked xml file!\n\n" + ex, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } try { Process process = new Process { StartInfo = { FileName = Config.XmlEditor, Arguments = xmlPath } }; process.Start(); } catch (Exception ex) { MessageBox.Show("Failed to start default XML Editor.\n" + ex, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public static void CookXmlFile(String xmlPath, FileManager fileManager) { try { Console.WriteLine(String.Format("Cooking {0}", Path.GetFileNameWithoutExtension(xmlPath))); XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(xmlPath); XmlCookedFile cookedXmlFile = new XmlCookedFile(fileManager, xmlPath); byte[] xmlCookedData = cookedXmlFile.CookXmlDocument(xmlDocument); File.WriteAllBytes(xmlPath + ".cooked", xmlCookedData); } catch (Exception ex) { String error = "Error: Failed to cook XML file: " + ex.Message; ExceptionLogger.LogException(ex, error); Console.WriteLine(error); } }
public static void TestAllXml(bool doTCv4 = false) { //System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); //const String root = @"D:\Games\Hellgate\Data\"; //const String root = @"D:\Games\Hellgate London\data\mp_hellgate_1.10.180.3416_1.0.86.4580\"; //const String root = @"D:\Games\Hellgate London\data\mp_hellgate_1.10.180.3416_1.0.86.4580\data\background\"; //List<String> xmlFiles = new List<String>(Directory.GetFiles(root, "*.xml.cooked", SearchOption.AllDirectories)); String debugPath = @"C:\xml_debug\"; FileManager.ClientVersions clientVersion = FileManager.ClientVersions.SinglePlayer; if (doTCv4) { debugPath = Path.Combine(debugPath, "tcv4"); clientVersion = FileManager.ClientVersions.TestCenter; } debugPath += @"\"; // lazy Directory.CreateDirectory(debugPath); FileManager fileManager = new FileManager(Config.HglDir, clientVersion); fileManager.BeginAllDatReadAccess(); fileManager.LoadTableFiles(); int count = 0; List<XmlCookedFile> excelStringWarnings = new List<XmlCookedFile>(); List<String> testCentreWarnings = new List<String>(); List<String> resurrectionWarnings = new List<String>(); int i = 0; foreach (PackFileEntry fileEntry in fileManager.FileEntries.Values) { if (!fileEntry.Path.EndsWith(XmlCookedFile.Extension)) continue; String xmlFilePath = fileEntry.Path; //const String debugStr = "buildintx_inside_env"; //if (!xmlFilePath.Contains(debugStr)) continue; //if (xmlFilePath.Contains(debugStr)) //{ // int bp = 0; //} //foreach (String xmlFilePath in xmlFiles) //{ //bool skip = ((i++ % 23) > 0); //if (skip) //{ // if (xmlFilePath.Contains("\\Data\\colorsets.xml")) continue; // if (xmlFilePath.Contains("\\Data\\ai\\")) continue; // if (xmlFilePath.Contains("\\Data\\background\\")) continue; // if (xmlFilePath.Contains("\\Data\\demolevel\\")) continue; // if (xmlFilePath.Contains("\\Data\\lights\\")) continue; // if (xmlFilePath.Contains("\\Data\\materials\\")) continue; // if (xmlFilePath.Contains("\\Data\\particles\\")) continue; // if (xmlFilePath.Contains("\\Data\\screenfx\\")) continue; // if (xmlFilePath.Contains("\\Data\\skills\\")) continue; // if (xmlFilePath.Contains("\\Data\\sounds\\")) continue; // if (xmlFilePath.Contains("\\Data\\states\\")) continue; // if (xmlFilePath.Contains("\\Data\\units\\items\\")) continue; // if (xmlFilePath.Contains("\\Data\\units\\missiles\\")) continue; // if (xmlFilePath.Contains("\\Data\\units\\monsters\\")) continue; // if (xmlFilePath.Contains("\\Data\\units\\npc\\")) continue; // if (xmlFilePath.Contains("\\Data\\units\\objects\\")) continue; //} String path = xmlFilePath; String fileName = Path.GetFileName(path); Debug.Assert(!String.IsNullOrEmpty(fileName)); //path = @"D:\Games\Hellgate London\data\mp_hellgate_1.10.180.3416_1.0.86.4580\data\background\city\treasury\cap_path.xml.cooked"; //path = "D:\\Games\\Hellgate\\Data\\background\\_environments\\outdoor_redhellcow_env.xml.cooked"; //path = "D:\\Games\\Hellgate\\Data\\particles\\background\\t_background\\tokyo_dark_smoke_c_large_01.xml.cooked"; //if (path == @"D:\Games\Hellgate\Data\background\cans and boxes.xml.cooked") //{ // int bp = 0; //} XmlCookedFile xmlCookedFile = new XmlCookedFile(fileManager, fileName) { CookExcludeTestCentre = !doTCv4 }; byte[] data = fileManager.GetFileBytes(fileEntry); Debug.Assert(data != null && data.Length > 0); Console.Write("Uncooking " + fileName + "... "); try { xmlCookedFile.ParseFileBytes(data, true); } catch (Exception e) { File.WriteAllBytes(debugPath + fileName, data); Console.WriteLine("Failed to uncooked file \"" + path + "\"\n" + e + "\n"); continue; } byte[] newXmlBytes = xmlCookedFile.ExportAsDocument(); count++; if (xmlCookedFile.HasExcelStringsMissing) excelStringWarnings.Add(xmlCookedFile); if (xmlCookedFile.HasTestCentreElements) testCentreWarnings.Add(Path.GetFileName(fileName)); if (xmlCookedFile.HasResurrectionElements) resurrectionWarnings.Add(Path.GetFileName(fileName)); //if (xmlCookedFile.HasExcelStringsMissing || xmlCookedFile.HasTestCentreElements || xmlCookedFile.HasResurrectionElements) continue; XmlCookedFile recookedXmlFile = new XmlCookedFile(fileManager, fileName) { CookExcludeTestCentre = !doTCv4 }; byte[] newXmlCookedBytes = recookedXmlFile.ParseFileBytes(newXmlBytes); // check if *cooking method* is working. i.e. is the cook from the *new* XML format == the original cooked bool identicalNew = data.SequenceEqual(newXmlCookedBytes); // if file passes byte-byte test, then continue if (identicalNew) { Console.WriteLine("OK!"); continue; } if ( path.Contains("female_3p_appearance.xml") || // this file has some weird bytes in a string element path.Contains("focus_item12_mesh_appearance.xml") || // this file has non-zeroed flag base masks (all differing) path.Contains("focus_item10_mesh_appearance.xml") || // as above // (all 3 probably from not zeroing a ptr at original cooking) path.Contains("dof_test.xml") || // as above path.Contains("motionblur.xml") || // as above path.Contains("player dead.xml") ) { Console.WriteLine("OK!"); continue; } File.WriteAllBytes(debugPath + fileName, data); File.WriteAllBytes(debugPath + fileName + "recooked", newXmlCookedBytes); File.WriteAllBytes(debugPath + fileName.Replace(".cooked", ""), newXmlBytes); Console.WriteLine("FAILED!"); } TextWriter consoleOut = Console.Out; TextWriter textWriter = new StreamWriter("uncook_results.txt"); Console.SetOut(textWriter); Console.WriteLine("XML Files Uncooked: " + count); if (excelStringWarnings.Count > 0) { Console.WriteLine("Warning: " + excelStringWarnings.Count + " files had excel strings missing:"); foreach (XmlCookedFile xmlCookedFile in excelStringWarnings) { Console.WriteLine("\t" + xmlCookedFile.FileName); foreach (String str in xmlCookedFile.ExcelStringsMissing) Console.WriteLine("\t\t- \"" + str + "\""); } } if (testCentreWarnings.Count > 0) { Console.WriteLine("Warning: " + testCentreWarnings.Count + " files had TestCentre-specific elements:"); foreach (String str in testCentreWarnings) Console.WriteLine("\t" + str); } if (resurrectionWarnings.Count > 0) { Console.WriteLine("Warning: " + resurrectionWarnings.Count + " files had Resurrection-specific elements:"); foreach (String str in resurrectionWarnings) Console.WriteLine("\t" + str); } textWriter.Close(); Console.SetOut(consoleOut); }
/// <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 _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); } }
/// <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); } }