private void bw_DoWork(object sender, DoWorkEventArgs e) { var startTime = DateTime.Now; var completionMessages = new List <string>(); var worker = sender as BackgroundWorker; var reader = new EndianReader(new FileStream(mapPath, FileMode.Open, FileAccess.Read), Endian.BigEndian); var map = new CasheFile(reader); GetTagAdresses(reader, map); if (hscCheckBox.Checked) { ExtractHscMethod(reader, map, completionMessages); } worker.ReportProgress(33); if (stringsCheckBox.Checked) { DumpStringsMethod(reader, map, completionMessages); } worker.ReportProgress(66); if (valueSearchCheckBox.Checked) { SearchValueTypeMethod(reader, map, completionMessages); } var completionTime = DateTime.Now - startTime; var result = new Tuple <TimeSpan, List <string> >(completionTime, completionMessages); worker.ReportProgress(100); e.Result = result; }
private void ExtractHscMethod(IReader reader, CasheFile Map, List <string> messageList) { /// the list which will be used to store all individual files and be used to ectract them later SortedList <string, HscFile> sourceFiles = new SortedList <string, HscFile>(); /// filter the map's tags by their tagclass. the hsdt tags are the interesting ones. List <Tag> hsdtTags = Map.GetTagsByClass("hsdt"); if (hsdtTags.Count == 0) { messageList.Add("This map doesn't contain any hsdt tags."); return; } #region Collecting the files... foreach (Tag tag in hsdtTags) { /// move the reader to the start of the tag data reader.SeekTo(tag.metaAddress - Map.MapMagic); Int32 sourceFileBlockCount = reader.ReadInt32(); if (sourceFileBlockCount > 0) { UInt32 sourceFileBlockAddress = reader.ReadUInt32(); reader.SeekTo(sourceFileBlockAddress - Map.MapMagic); for (int i = 0; i < sourceFileBlockCount; i++) { HscFile sourceFile = new HscFile(reader); /// if our file list doesnt contain this file yet, it will be added, so we can extract it later. if (!sourceFiles.ContainsKey(sourceFile.Name)) { sourceFiles.Add(sourceFile.Name, sourceFile); } } } } #endregion if (sourceFiles.Count == 0) { messageList.Add("This map doesn't contain any script files."); return; } #region Extract the files... foreach (KeyValuePair <string, HscFile> hscFile in sourceFiles) { reader.SeekTo(hscFile.Value.Address - Map.MapMagic); var data = reader.ReadBlock(hscFile.Value.Size); var path = Path.Combine(outputPath, hscFile.Value.Name + ".hsc"); var stream = System.IO.File.Open(path, FileMode.Create); stream.Write(data, 0, data.Length); stream.Dispose(); stream.Close(); } messageList.Add(sourceFiles.Count + " script files have been extracted."); #endregion }
private void GetTagAdresses(IReader reader, CasheFile Map) { var scnrTag = Map.GetTagByClass("scnr"); var stringsDir = Path.Combine(outputPath, "Strings"); if (scnrTag == null) { return; } #region scnr reader.SeekTo((scnrTag.metaAddress - Map.MapMagic) + 0x498 + 0xE); Int16 scenarioTagIndex = reader.ReadInt16(); reader.Skip(0xC + 0xE); Int16 globalHscnTagIndex = reader.ReadInt16(); #endregion if (scenarioTagIndex > -1) { var tag = Map.Tags[scenarioTagIndex]; if (tag.Class.Name == "hsdt") { containsScenario = true; scenarioHsdtAddress = tag.metaAddress; } } if (globalHscnTagIndex > -1) { var tag = Map.Tags[globalHscnTagIndex]; if (tag.Class.Name == "hscn") { reader.SeekTo((tag.metaAddress - Map.MapMagic) + 0x18 + 0xE); Int16 globalHsdtTagIndex = reader.ReadInt16(); if (globalHsdtTagIndex > -1) { var hsdtTag = Map.Tags[globalHsdtTagIndex]; if (hsdtTag.Class.Name == "hsdt") { containsGlobal = true; globalHsdtAddress = hsdtTag.metaAddress; } } } } }
private void SearchValueTypeMethod(IReader reader, CasheFile Map, List <string> messageList) { var occurrences = new List <string>(); #region Scenario if (containsScenario) { reader.SeekTo((scenarioHsdtAddress - Map.MapMagic) + 0x48); Int32 count = reader.ReadInt32(); UInt32 address = reader.ReadUInt32(); if (count != 0 && address != 0) { reader.SeekTo(address - Map.MapMagic); for (Int32 currentNode = 0; currentNode < count; currentNode++) { var node = new ScriptNode(reader); ProcessScriptNode(node, "Scenario", currentNode, valueTypeIndex, occurrences); } } } #endregion #region Global if (containsGlobal) { reader.SeekTo((scenarioHsdtAddress - Map.MapMagic) + 0x48); Int32 count = reader.ReadInt32(); UInt32 address = reader.ReadUInt32(); if (count != 0 && address != 0) { reader.SeekTo(address - Map.MapMagic); for (Int32 currentNode = 0; currentNode < count; currentNode++) { var node = new ScriptNode(reader); ProcessScriptNode(node, "Global", currentNode, valueTypeIndex, occurrences); } } } #endregion if (occurrences.Count > 0) { var ValueTypeDir = Path.Combine(outputPath, "Value Types"); if (!Directory.Exists(ValueTypeDir)) { Directory.CreateDirectory(ValueTypeDir); } var fileName = Path.Combine(ValueTypeDir, ("Value Type" + valueTypeIndex + ".txt")); var writer = new StreamWriter(fileName, false); foreach (string str in occurrences) { writer.WriteLine(str); } writer.Dispose(); writer.Close(); messageList.Add(occurrences.Count + " occurrences of the value type " + valueTypeIndex + " have been found."); } else { messageList.Add("No occurences of the value type " + valueTypeIndex + " have been found."); } }
private void DumpStringsMethod(IReader reader, CasheFile Map, List <string> messageList) { var stringsDir = Path.Combine(outputPath, "Strings"); bool dumpedScenario = false; bool dumpedGlobal = false; #region scenario hsdt if (containsScenario) { reader.SeekTo((scenarioHsdtAddress - Map.MapMagic) + 0x54); UInt32 size = reader.ReadUInt32(); reader.Skip(8); UInt32 address = reader.ReadUInt32(); if (size > 0) { var strings = ReadStringTableNew(reader, (address - Map.MapMagic), size); if (strings.Count != 0) { if (!Directory.Exists(stringsDir)) { Directory.CreateDirectory(stringsDir); } var fileName = Path.Combine(stringsDir, (mapName + "_scenario" + ".txt")); var writer = new StreamWriter(fileName, false); foreach (string str in strings) { writer.WriteLine(str); } writer.Dispose(); writer.Close(); dumpedScenario = true; } } } #endregion #region global hsdt if (containsGlobal) { reader.SeekTo((globalHsdtAddress - Map.MapMagic) + 0x54); UInt32 size = reader.ReadUInt32(); reader.Skip(8); UInt32 address = reader.ReadUInt32(); if (size > 0) { var strings = ReadStringTableNew(reader, address - Map.MapMagic, size); if (strings.Count != 0) { if (!Directory.Exists(stringsDir)) { Directory.CreateDirectory(stringsDir); } var fileName = Path.Combine(stringsDir, (mapName + "_global" + ".txt")); var writer = new StreamWriter(fileName, false); foreach (string str in strings) { writer.WriteLine(str); } writer.Dispose(); writer.Close(); dumpedGlobal = true; } } } #endregion if (dumpedScenario && dumpedGlobal) { messageList.Add("All global and scenario strings have been dumped."); } else if (!dumpedScenario && !dumpedGlobal) { messageList.Add("This map doesn't contain any strings."); } else if (dumpedScenario) { messageList.Add("All scenario strings have been dumped."); } else if (dumpedGlobal) { messageList.Add("All global strings have been dumped."); } }