private void NewFile() { //Create and show NewTagViewModel newTagViewModel = new NewTagViewModel(); NewFileDialog newFileDialog = new NewFileDialog() { Owner = Owner, DataContext = newTagViewModel }; if (newFileDialog.ShowDialog() ?? false) { //Get tag group Group tagGroup = TagLookup.CreateTagGroup(newTagViewModel.SelectedTagDefinition.GroupTag); //Create file TagFileModel newTagFileModel = new TagFileModel($"new_{tagGroup.GroupName}.{tagGroup.GroupName}", new AbideTagGroupFile() { TagGroup = tagGroup }) { IsDirty = true, CloseCallback = File_Close }; newTagFileModel.OpenTagReferenceRequested += OpenTagReferenceRequested; Files.Add(newTagFileModel); //Set SelectedFile = newTagFileModel; } }
private void Map_Load(HaloMap map) { //Load cacheResources = new CacheResources(mapFile); //Prepare checkedTagIds.Clear(); resourceManager.Clear(); resourceLookup.Clear(); tagTreeView.BeginUpdate(); tagTreeView.Nodes.Clear(); tagTreeView.PathSeparator = "\\"; //Loop foreach (IndexEntry indexEntry in map.IndexEntries) { TreeView_CreateTagNode(tagTreeView, $"{indexEntry.Filename}.{ indexEntry.Root.FourCc}", indexEntry.Id); ITagGroup tagGroup = TagLookup.CreateTagGroup(indexEntry.Root); resourceLookup.Add($"{indexEntry.Filename}.{tagGroup.GroupName}", indexEntry.Id); } //End tagTreeView.TreeViewNodeSorter = new TagNodeSorter(); tagTreeView.Sort(); tagTreeView.EndUpdate(); //Read sound cache file gestalt var ugh = mapFile.IndexEntries.Last; using (var reader = ugh.Data.GetVirtualStream().CreateReader()) { reader.BaseStream.Seek(mapFile.IndexEntries.Last.Address, SeekOrigin.Begin); soundCacheFileGestalt.Read(reader); } }
public TagForm(MapFile map, IndexEntry tag) : this() { // // this // Text = $"{tag.Filename}.{tag.Root}"; Map = map; Tag = tag; // // gueriallFlowLayoutPanel // gueriallFlowLayoutPanel.Controls.Clear(); // // tagGroup // if ((tagGroup = TagLookup.CreateTagGroup(tag.Root)) != null) { tag.TagData.Seek((uint)tag.PostProcessedOffset, SeekOrigin.Begin); using (BinaryReader reader = tag.TagData.CreateReader()) tagGroup.Read(reader); foreach (Block block in tagGroup) { Tags.GenerateControls(gueriallFlowLayoutPanel, block); } } }
private void tagGroupComboBox_SelectedIndexChanged(object sender, EventArgs e) { //Set try { SelectedGroup = TagLookup.CreateTagGroup((TagFourCc)tagGroupComboBox.SelectedItem); } catch { SelectedGroup = null; } //Enable okButton.Enabled = SelectedGroup != null; }
public void Prepare(TagFourCc tag) { //Create group ITagGroup group = TagLookup.CreateTagGroup(tag); if (group != null) { Prepare(group); //Prepare } }
public void Load(Stream inStream) { if (!inStream.CanRead) { return; } if (!inStream.CanSeek) { return; } if (inStream.Length < TagGroupHeader.Size) { return; } resources.Clear(); TagGroup = null; using (BinaryReader reader = new BinaryReader(inStream)) { TagGroupHeader header = reader.Read <TagGroupHeader>(); inStream.Seek(TagGroupHeader.Size, SeekOrigin.Begin); if ((TagGroup = TagLookup.CreateTagGroup(header.GroupTag)) != null) { TagGroup.Read(reader); } if (header.TagResourceCount > 0) { int[] rawOffsets = new int[header.TagResourceCount]; inStream.Seek(header.RawOffsetsOffset, SeekOrigin.Begin); for (int i = 0; i < header.TagResourceCount; i++) { rawOffsets[i] = reader.ReadInt32(); } int[] lengths = new int[header.TagResourceCount]; inStream.Seek(header.RawLengthsOffset, SeekOrigin.Begin); for (int i = 0; i < header.TagResourceCount; i++) { lengths[i] = reader.ReadInt32(); } inStream.Seek(header.RawDataOffset, SeekOrigin.Begin); for (int i = 0; i < header.TagResourceCount; i++) { if (!resources.ContainsKey(rawOffsets[i])) { resources.Add(rawOffsets[i], reader.ReadBytes(lengths[i])); } } } } PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TagGroup))); }
private ITagGroup ResourceManager_ResolveResource(string resourceName) { //Prepare IndexEntry entry = mapFile.IndexEntries[resourceLookup[resourceName]]; Group tagGroup = TagLookup.CreateTagGroup(entry.Root); //Read using (BinaryReader reader = entry.Data.GetVirtualStream().CreateReader()) { //Read reader.BaseStream.Seek(entry.Address, SeekOrigin.Begin); tagGroup.Read(reader); } //Return return(Convert.ToGuerilla(tagGroup, soundCacheFileGestalt, entry, mapFile)); }
private void ChunkCloner_SelectedEntryChanged(object sender, EventArgs e) { //Reset resetTagToolStripButton.Enabled = false; saveTagToolStripButton.Enabled = false; popOutToolStripButton.Enabled = false; tagStructureTreeView.BeginUpdate(); tagStructureTreeView.Nodes.Clear(); currentEntry = null; tagGroup = null; //Check if (SelectedEntry != null) { //Setup currentEntry = SelectedEntry; //Enable resetTagToolStripButton.Enabled = true; saveTagToolStripButton.Enabled = true; popOutToolStripButton.Enabled = true; //Create empty tag group tagGroup = TagLookup.CreateTagGroup(currentEntry.Root); //Read tag group currentEntry.TagData.Seek((uint)currentEntry.PostProcessedOffset, SeekOrigin.Begin); using (BinaryReader reader = currentEntry.TagData.CreateReader()) tagGroup.Read(reader); //Create tree nodes for each block foreach (Block tagBlock in tagGroup.TagBlocks) { TreeNode tagBlockNode = TagBlock_CreateTreeNode(tagBlock); tagStructureTreeView.Nodes.Add(tagBlockNode); tagBlockNode.Expand(); } } //End tagStructureTreeView.EndUpdate(); }
public override bool IsValidEditor(string path) { if (File.Exists(path)) { using (var stream = File.OpenRead(path)) using (var reader = new BinaryReader(stream)) { var abideTag = reader.ReadTag(); var groupTag = reader.ReadTag(); var tagGroup = TagLookup.CreateTagGroup(groupTag); if (tagGroup != null && abideTag == "atag") { return(true); } } } return(false); }
private static void Map_Scan(MapFile map) { //Loop foreach (IndexEntry entry in map.IndexEntries) { //Create tag group using (Group tagGroup = TagLookup.CreateTagGroup(entry.Root)) { //Read entry.TagData.Seek((uint)entry.PostProcessedOffset, SeekOrigin.Begin); using (BinaryReader reader = entry.TagData.CreateReader()) tagGroup.Read(reader); //Loop foreach (ITagBlock tagBlock in tagGroup.TagBlocks) { TagBlock_Search(tagBlock, entry); } } } }
private void IndexEntry_Export(TagManifest manifest, IndexEntry entry, ITagGroup soundCacheFileGestalt, string outputDirectory) { //Check if (entry == null || manifest == null || outputDirectory == null) { return; } if (manifest.TagIdReferences.Contains(entry.Id.Dword)) { return; } //Prepare AbideTagGroupFile tagGroupFile = new AbideTagGroupFile() { Id = entry.Id }; Group tagGroup = TagLookup.CreateTagGroup(entry.Root); string localPath = $"{entry.Filename}.{tagGroup.GroupName}"; string absolutePath = Path.Combine(outputDirectory, localPath); //Check using (BinaryReader reader = entry.TagData.CreateReader()) { //Add reference manifest.TagIdReferences.Add(entry.Id.Dword); //Read entry.TagData.Seek((uint)entry.PostProcessedOffset, SeekOrigin.Begin); tagGroup.Read(reader); //Get references foreach (ITagBlock tagBlock in tagGroup) { TagBock_BuildReferences(manifest, tagBlock, outputDirectory); } //Add file manifest.TagFileNames.Add(localPath); //Add raws foreach (RawSection section in Enum.GetValues(typeof(RawSection))) { foreach (RawStream raw in entry.Raws[section]) { tagGroupFile.SetRaw(raw.RawOffset, raw.ToArray()); } } //Convert cache to guerilla tagGroup = Guerilla.Library.Convert.ToGuerilla(tagGroup, soundCacheFileGestalt, entry, Map); //Copy raws if (tagGroup.GroupTag == HaloTags.snd_) { int rawOffset = 0; IndexEntry soundCacheFileGestaltEntry = Map.GetSoundCacheFileGestaltEntry(); Block soundBlock = tagGroup.TagBlocks[0]; foreach (Block pitchRangeBlock in ((BlockField)soundBlock.Fields[13]).BlockList) { foreach (Block permutationBlock in ((BlockField)pitchRangeBlock.Fields[7]).BlockList) { foreach (Block permutationChunkBlock in ((BlockField)permutationBlock.Fields[6]).BlockList) { rawOffset = (int)permutationChunkBlock.Fields[0].Value; if (soundCacheFileGestaltEntry.Raws[RawSection.Sound].ContainsRawOffset(rawOffset)) { tagGroupFile.SetRaw(rawOffset, soundCacheFileGestaltEntry.Raws[RawSection.Sound][rawOffset].ToArray()); } } } } foreach (Block extraInfoBlock in ((BlockField)soundBlock.Fields[15]).BlockList) { ITagBlock globalGeometryBlockInfoStruct = (ITagBlock)extraInfoBlock.Fields[2].Value; if (soundCacheFileGestaltEntry.Raws[RawSection.LipSync].ContainsRawOffset(rawOffset)) { tagGroupFile.SetRaw(rawOffset, soundCacheFileGestaltEntry.Raws[RawSection.LipSync][rawOffset].ToArray()); } } } //Create Directory.CreateDirectory(Path.GetDirectoryName(absolutePath)); //Set tag group tagGroupFile.TagGroup = tagGroup; //Create file using (FileStream fs = new FileStream(absolutePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) tagGroupFile.Save(fs); } }
private void decompileButton_Click(object sender, EventArgs e) { //Loop foreach (TagId id in checkedTagIds) { //Get index entry IndexEntry entry = mapFile.IndexEntries[id]; //Check if (entry != null) { //Read Group tagGroup = TagLookup.CreateTagGroup(entry.Root); using (var stream = entry.Data.GetVirtualStream()) using (var reader = stream.CreateReader()) { reader.BaseStream.Seek(entry.Address, SeekOrigin.Begin); tagGroup.Read(reader); } //Collect references AbideTagGroupFile tagGroupFile = new AbideTagGroupFile() { TagGroup = Convert.ToGuerilla(tagGroup, soundCacheFileGestalt, entry, mapFile) }; resourceManager.CollectResources(tagGroupFile.TagGroup); //Get file name string fileName = Path.Combine(RegistrySettings.WorkspaceDirectory, "tags", $"{entry.Filename}.{tagGroup.GroupName}"); //Create directory? if (!Directory.Exists(Path.GetDirectoryName(fileName))) { Directory.CreateDirectory(Path.GetDirectoryName(fileName)); } //Save tag file tagGroupFile.Save(fileName); } } //Decompile resources foreach (string resourceString in resourceManager.GetResources()) { //Find entry IndexEntry entry = mapFile.IndexEntries[cacheResources.FindIndex(resourceString)]; //Check if (entry != null) { //Read Group tagGroup = TagLookup.CreateTagGroup(entry.Root); using (var stream = entry.Data.GetVirtualStream()) using (var reader = stream.CreateReader()) { reader.BaseStream.Seek(entry.Address, SeekOrigin.Begin); tagGroup.Read(reader); } //Collect references AbideTagGroupFile tagGroupFile = new AbideTagGroupFile() { TagGroup = Convert.ToGuerilla(tagGroup, soundCacheFileGestalt, entry, mapFile) }; //Get file name string fileName = Path.Combine(RegistrySettings.WorkspaceDirectory, "tags", $"{entry.Filename}.{tagGroup.GroupName}"); //Create directory? if (!Directory.Exists(Path.GetDirectoryName(fileName))) { Directory.CreateDirectory(Path.GetDirectoryName(fileName)); } //Save tag file tagGroupFile.Save(fileName); } } }
private void Click(object obj) { List <string> strings = new List <string>(); List <TagReference> tags = new List <TagReference>(); List <IndexEntry> entries = new List <IndexEntry>(); TagId currentId = TagId.Null; var openDlg = new OpenFileDialog() { Filter = "XML Files (*.xml)|*.xml" }; if (openDlg.ShowDialog() ?? false) { XmlDocument document = new XmlDocument(); document.Load(openDlg.FileName); var tagsRoot = Path.GetDirectoryName(openDlg.FileName); var manifest = document["AbideTagManifest"]; var tagNameManifest = manifest["TagNames"]; foreach (XmlNode node in tagNameManifest) { var tagName = node.Attributes["Name"].InnerText; var groupTag = new TagFourCc(node.Attributes["GroupTag"].InnerText); tags.Add(new TagReference() { TagName = tagName, GroupTag = groupTag }); } var globals = Map.GetTagById(Map.GlobalsTagId); using (var tagData = Map.ReadTagData(globals)) { _ = tagData.Stream.Seek(globals.MemoryAddress, SeekOrigin.Begin); var globalsTagGroup = TagLookup.CreateTagGroup(globals.Tag); globalsTagGroup.Read(tagData.Stream.CreateReader()); var soundGlobals = (BlockField)globalsTagGroup.TagBlocks[0].Fields[4]; if (soundGlobals.BlockList.Count == 1) { var soundGlobalsBlock = soundGlobals.BlockList[0]; currentId = (TagId)soundGlobalsBlock.Fields[4].Value; } } using (var map = new HaloMap(Map.FileName)) { var soundCacheFileGestaltEntry = map.IndexEntries[currentId]; foreach (var tag in tags) { if (map.IndexEntries.Any(e => e.Filename == tag.TagName && e.Root == tag.GroupTag)) { tag.Id = map.IndexEntries.First(e => e.Filename == tag.TagName && e.Root == tag.GroupTag).Id; } else { var tagGroup = TagLookup.CreateTagGroup(tag.GroupTag); tag.FileName = Path.Combine(tagsRoot, $"{tag.TagName}.{tagGroup.Name}"); var tagGroupFile = new AbideTagGroupFile(); tagGroupFile.Load(tag.FileName); var entry = new IndexEntry() { Filename = tag.TagName, Id = currentId++, Tag = map.Tags.First(t => t.Root == tag.GroupTag), }; entries.Add(entry); tag.TagGroup = tagGroupFile.TagGroup; tag.Id = entry.Id; foreach (var offset in tagGroupFile.GetResourceAddresses()) { var resource = tagGroupFile.GetResource(offset); _ = entry.Resources.AddResource((int)offset, resource); } } } soundCacheFileGestaltEntry.Id = currentId; int insertionIndex = map.IndexEntries.IndexOf(e => e == soundCacheFileGestaltEntry); foreach (var tag in tags.Where(t => File.Exists(t.FileName))) { ConvertToCache(tag.TagGroup, map, tags); var entry = entries.First(e => e.Id == tag.Id); using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { tag.TagGroup.Write(writer); entry.Data.SetBuffer(stream.ToArray()); _ = map.IndexEntries.Insert(insertionIndex, entry); } } map.Save(Path.Combine(tagsRoot, $"{map.Name}.map")); } } }
private void TagDuplicator_Click(object sender, EventArgs e) { //Prepare Group newTagGroup = null; IndexEntry last = Map.IndexEntries.Last; //Check if (SelectedEntry != null) { //Get name string tagName = string.Empty; using (NameDialog nameDlg = new NameDialog()) { //Setup nameDlg.TagName = SelectedEntry.Filename; //Show DialogResult result = DialogResult.OK; while (Map.IndexEntries.Count(i => i.Filename == nameDlg.TagName && i.Root == SelectedEntry.Root) > 0 && result == DialogResult.OK) { result = nameDlg.ShowDialog(); } //Check if (result == DialogResult.OK) { tagName = nameDlg.TagName; } else { return; } } //Initialize BinaryReader instance for the selected tag using (BinaryReader reader = SelectedEntry.TagData.CreateReader()) { //Create tag group for selected entry newTagGroup = TagLookup.CreateTagGroup(SelectedEntry.Root); //Goto tag data and read SelectedEntry.TagData.Seek((uint)SelectedEntry.PostProcessedOffset, SeekOrigin.Begin); newTagGroup.Read(reader); } //Check the root for a scenario structure tag if (SelectedEntry.Root == HaloTags.sbsp || SelectedEntry.Root == HaloTags.ltmp) { //Scenario dialog using (StructureBspSelectDialog scenarioDlg = new StructureBspSelectDialog(Map.Scenario)) if (scenarioDlg.ShowDialog() == DialogResult.OK && scenarioDlg.SelectedBlockIndex >= 0) { //Prepare ScenarioStructureTag bspTag = new ScenarioStructureTag(scenarioDlg.SelectedBlockIndex) { SourceEntry = SelectedEntry, Name = tagName, Id = last.Id, TagGroup = newTagGroup }; //Add Map.AddScenarioStructureTags(bspTag); //Reload Host.Request(this, "ReloadMap"); } } else { //Prepare Tag tag = new Tag() { SourceEntry = SelectedEntry, Name = tagName, Id = last.Id, TagGroup = newTagGroup }; //Add Map.AddTags(tag); //Reload Host.Request(this, "ReloadMap"); } } }
private void analyzeMapsToolStripMenuItem_Click(object sender, EventArgs e) { //Prepare ITagGroup tagGroup = null; sharedResources = new SharedTagResources(); List <string> header = new List <string>(); DateTime start = DateTime.Now; //Add header.Add("Abide Guerilla Analyzer"); header.Add(string.Empty); //Loop foreach (string file in Directory.GetFiles(@"F:\XBox\Original\Games\Halo 2\Clean Maps", "*.map")) { using (MapFile map = new MapFile()) { //Load start = DateTime.Now; map.Load(file); //Check type using (var reader = map.Scenario.TagData.CreateReader()) { reader.BaseStream.Seek(map.Scenario.Offset + 16, SeekOrigin.Begin); short mapType = reader.ReadInt16(); switch (mapType) { case 0: sharedResources.CollideSingleplayer(map.IndexEntries.Select( i => { tagGroup = TagLookup.CreateTagGroup(i.Root); return($"{i.Filename}.{tagGroup.GroupName}"); }).ToArray()); break; case 1: sharedResources.CollideMultiplayer(map.IndexEntries.Select( i => { tagGroup = TagLookup.CreateTagGroup(i.Root); return($"{i.Filename}.{tagGroup.GroupName}"); }).ToArray()); break; } } //Add header.Add($"{file} loaded in {(DateTime.Now - start).TotalSeconds} seconds"); } } //Create file using (StreamWriter writer = File.CreateText(Path.Combine(Application.StartupPath, "resource analysis.log"))) { //Write header foreach (string line in header) { writer.WriteLine(line); } //Write line writer.WriteLine(); writer.WriteLine(); //Write ui resources writer.WriteLine($"ui shared resources (count {sharedResources.UiSharedResourceCount}):"); foreach (string resource in sharedResources.GetUiResources()) { writer.WriteLine($"@\"{resource}\","); } //Write line writer.WriteLine(); writer.WriteLine(); //Write multiplayer resources writer.WriteLine($"multiplayer shared resources (count {sharedResources.MultiplayerSharedResourceCount}):"); foreach (string resource in sharedResources.GetMultiplayerSharedResources()) { writer.WriteLine($"@\"{resource}\","); } //Write line writer.WriteLine(); writer.WriteLine(); //Write singleplayer resources writer.WriteLine($"singleplayer shared resources (count {sharedResources.SingleplayerSharedResourceCount}):"); foreach (string resource in sharedResources.GetSingleplayerSharedResources()) { writer.WriteLine($"@\"{resource}\","); } } }
public SharedTagResources() { //Prepare MapFile resourceMap = null; ITagGroup tagGroup = null; //Gather ui resources using (resourceMap = new MapFile()) { //Load resourceMap.Load(RegistrySettings.MainmenuFileName); //Get tags m_UiSharedResources.AddRange(resourceMap.IndexEntries.Select(e => { tagGroup = TagLookup.CreateTagGroup(e.Root); return($"{e.Filename}.{tagGroup.GroupName}"); })); } //Gather multiplayer shared resources using (resourceMap = new MapFile()) { //Load resourceMap.Load(RegistrySettings.SharedFileName); //Get tags m_MultiplayerSharedResources.AddRange(resourceMap.IndexEntries.Select(e => { tagGroup = TagLookup.CreateTagGroup(e.Root); return($"{e.Filename}.{tagGroup.GroupName}"); })); } //Gather singleplayer shared resources using (resourceMap = new MapFile()) { //Load resourceMap.Load(RegistrySettings.SharedFileName); //Get tags m_SingleplayerSharedResources.AddRange(resourceMap.IndexEntries.Select(e => { tagGroup = TagLookup.CreateTagGroup(e.Root); return($"{e.Filename}.{tagGroup.GroupName}"); })); } }
private void NewTagButton_Click(object sender, EventArgs e) { //Get last IndexEntry last = Map.IndexEntries.Last; if (last.Root != HaloTags.ugh_) { return; } //Prepare using (GroupDialog groupDlg = new GroupDialog()) { //Show if (groupDlg.ShowDialog() == DialogResult.OK) { using (NameDialog nameDialog = new NameDialog()) if (nameDialog.ShowDialog() == DialogResult.OK) { //Prepare string tagName = nameDialog.TagName; Group tagGroup = TagLookup.CreateTagGroup(groupDlg.SelectedGroup); //Check if (tagGroup != null) { if (groupDlg.SelectedGroup == HaloTags.ltmp || groupDlg.SelectedGroup == HaloTags.sbsp) { //Ask for which BSP index to build into using (StructureBspSelectDialog bspSelectDlg = new StructureBspSelectDialog(Map.Scenario)) if (bspSelectDlg.ShowDialog() == DialogResult.OK && bspSelectDlg.SelectedBlockIndex >= 0) { //Create tag ScenarioStructureTag tag = new ScenarioStructureTag(bspSelectDlg.SelectedBlockIndex) { TagGroup = tagGroup, Name = tagName, Id = last.Id, }; //Add Map.AddScenarioStructureTags(tag); } } else { //Create tag Tag tag = new Tag() { TagGroup = tagGroup, Name = tagName, Id = last.Id, }; //Add Map.AddTags(tag); } } //Reload Host.Request(this, "ReloadMap"); } } } }
private void FixSystemLinkButton_Click(object sender, EventArgs e) { /* * Heh I guess Entity is good for something :P */ //Prepare ITagGroup tagGroup = null; ITagGroup scenario = new Scenario(); ITagBlock scenarioBlock = null, simulationDefinitionTableElementBlock = null; BlockField simulationDefinitionTableField = null; List <IndexEntry> simulationDefinitionEntries = new List <IndexEntry>(); bool success = false; //Build table foreach (IndexEntry entry in Map.IndexEntries) { switch (entry.Root) { case "bipd": case "bloc": case "ctrl": case "jpt!": case "mach": case "scen": case "ssce": case "vehi": simulationDefinitionEntries.Add(entry); break; case "eqip": case "garb": case "proj": simulationDefinitionEntries.Add(entry); simulationDefinitionEntries.Add(entry); break; case "weap": simulationDefinitionEntries.Add(entry); simulationDefinitionEntries.Add(entry); simulationDefinitionEntries.Add(entry); break; } } //Read scenario using (BinaryReader reader = Map.Scenario.TagData.CreateReader()) { reader.BaseStream.Seek((uint)Map.Scenario.PostProcessedOffset, SeekOrigin.Begin); scenario.Read(reader); } //Re-create simulation definition table scenarioBlock = scenario[0]; simulationDefinitionTableField = (BlockField)scenarioBlock[143]; simulationDefinitionTableField.BlockList.Clear(); foreach (IndexEntry entry in simulationDefinitionEntries) { //Attempt to add tag block simulationDefinitionTableElementBlock = simulationDefinitionTableField.Add(out success); if (success) { simulationDefinitionTableElementBlock[0].Value = entry.Id; } } //Rebuild map using (VirtualStream tagDataStream = new VirtualStream(Map.TagDataStream.MemoryAddress)) using (BinaryWriter writer = tagDataStream.CreateWriter()) using (BinaryReader reader = Map.TagDataStream.CreateReader()) { //Loop foreach (IndexEntry entry in Map.IndexEntries.Where(ie => ie.Offset > 0 && ie.Size > 0)) { //Read (unless it's our modified scenario) if (entry != Map.Scenario) { tagGroup = TagLookup.CreateTagGroup(entry.Root); reader.BaseStream.Seek(entry.Offset, SeekOrigin.Begin); tagGroup.Read(reader); } else { tagGroup = scenario; } //Create buffer using (VirtualStream stream = new VirtualStream(tagDataStream.Position)) using (BinaryWriter tagWriter = stream.CreateWriter()) using (BinaryReader tagReader = stream.CreateReader()) { //Write tagGroup.Write(tagWriter); //Recalculate raw addresses Helper.RecalculateRawAddresses(entry.Raws, entry.Root, stream, tagReader, tagWriter); //Setup tag entry.Offset = (uint)stream.MemoryAddress; entry.Size = (int)stream.Length; //Write to tag data stream writer.Write(stream.ToArray()); } } //Align tagDataStream.Align(4096); //Swap Map.SwapTagBuffer(tagDataStream.ToArray(), tagDataStream.MemoryAddress); } }
private void Map_Decompile(object state) { Console.WriteLine($"Decompiling {map.Name}..."); Group globalsGroup; Group soundGestaltGroup = null; IndexEntry soundGestalt = null; IndexEntry globals = map.Globals; try { using (var tagReader = globals.Data.GetVirtualStream().CreateReader()) { tagReader.BaseStream.Seek(globals.Address, SeekOrigin.Begin); globalsGroup = TagLookup.CreateTagGroup(globals.Root); globalsGroup.Read(tagReader); BlockField soundGlobalsTagBlock = (BlockField)globalsGroup.TagBlocks[0].Fields[4]; if (soundGlobalsTagBlock.BlockList.Count > 0) { TagId soundGestaltId = (TagId)soundGlobalsTagBlock.BlockList[0].Fields[4].Value; soundGestalt = map.IndexEntries[soundGestaltId]; soundGlobalsTagBlock.BlockList[0].Fields[4].Value = (int)TagId.Null; } } if (soundGestalt != null) { using (BinaryReader reader = soundGestalt.Data.GetVirtualStream().CreateReader()) { soundGestaltGroup = TagLookup.CreateTagGroup(soundGestalt.Root); reader.BaseStream.Seek(soundGestalt.Address, SeekOrigin.Begin); soundGestaltGroup.Read(reader); } } int num = 0; float total = map.IndexEntries.Count; var result = Parallel.ForEach(map.IndexEntries, entry => { num++; Group guerillaTagGroup; var tagGroup = TagLookup.CreateTagGroup(entry.Root); var reader = entry.Data.GetVirtualStream().CreateReader(); reader.BaseStream.Seek(entry.Address, SeekOrigin.Begin); try { tagGroup.Read(reader); } finally { guerillaTagGroup = Convert.ToGuerilla(tagGroup, soundGestaltGroup, entry, map); } string localFileName = Path.Combine($"{entry.Filename}.{guerillaTagGroup.GroupName}"); string tagGroupFileName = Path.Combine(OutputDirectory, localFileName); if (!Directory.Exists(Path.GetDirectoryName(tagGroupFileName))) { Directory.CreateDirectory(Path.GetDirectoryName(tagGroupFileName)); } TagGroupHeader header = new TagGroupHeader(); using (FileStream fs = new FileStream(tagGroupFileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) using (BinaryReader fileReader = new BinaryReader(fs)) using (BinaryWriter fileWriter = new BinaryWriter(fs)) { fs.Seek(TagGroupHeader.Size, SeekOrigin.Begin); guerillaTagGroup.Write(fileWriter); switch (guerillaTagGroup.GroupTag) { case "snd!": SoundTagGroup_CreateResources(guerillaTagGroup, soundGestalt, fileWriter, ref header); break; case "mode": RenderModelTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header); break; case "sbsp": ScenarioStructureBspTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header); break; case "ltmp": ScenarioStructureLightmapTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header); break; case "weat": WeatherSystemTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header); break; case "DECR": DecoratorSetTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header); break; case "PRTM": ParticleModelTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header); break; case "jmad": AnimationTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header); break; case "bitm": BitmapTagGroup_CreateResources(guerillaTagGroup, entry, fileWriter, ref header); break; } header.Checksum = (uint)TagGroup_CalculateChecksum(guerillaTagGroup); header.GroupTag = guerillaTagGroup.GroupTag.FourCc; header.Id = entry.Id.Dword; header.AbideTag = "atag"; fs.Seek(0, SeekOrigin.Begin); fileWriter.Write(header); Host.Report(num / total); } }); } catch { #if DEBUG throw; #endif } finally { GC.Collect(); } Host.Report(1); Thread.Sleep(500); Host.Complete(); }