public ThirdGenLanguageGlobals(ThirdGenCacheFile cacheFile, StructureValueCollection values, IndexOffsetConverter converter, BuildInformation buildInfo) { _cacheFile = cacheFile; _converter = converter; _languages = LoadLanguages(values, converter, buildInfo); _alignment = buildInfo.LocaleAlignment; }
private byte[] ExtractRaw() { var outputBytes = new List <byte>(); using (var fileStream = _streamManager.OpenRead()) { _resourcePages = new ResourcePage[3]; _resourcePages[0] = _soundResource.Location.PrimaryPage; _resourcePages[1] = _soundResource.Location.SecondaryPage; _resourcePages[2] = _soundResource.Location.TertiaryPage; for (var i = 0; i < _resourcePages.Length; i++) { var page = _resourcePages[i]; if (page == null || (page.CompressedSize == 0 || page.UncompressedSize == 0)) { continue; } var resourceFile = _cache; Stream resourceStream = null; if (page.FilePath != null) { var resourceCacheInfo = App.AssemblyStorage.AssemblySettings.HalomapResourceCachePaths.FirstOrDefault( r => r.EngineName == _buildInfo.Name); var resourceCachePath = (resourceCacheInfo != null) ? resourceCacheInfo.ResourceCachePath : Path.GetDirectoryName(_cacheLocation); resourceCachePath = Path.Combine(resourceCachePath ?? "", Path.GetFileName(page.FilePath)); if (!File.Exists(resourceCachePath)) { throw new FileNotFoundException("Unable to extract tag, because a resource it relies on is in a external cache '{0}' that could not be found. Check Assembly's settings and set the file path to resource caches."); } resourceStream = File.OpenRead(resourceCachePath); resourceFile = new ThirdGenCacheFile(new EndianReader(resourceStream, Endian.BigEndian), _buildInfo, _cache.BuildString); } var tmpStream = new MemoryStream(); var extractor = new ResourcePageExtractor(resourceFile); var path = Path.GetTempFileName(); var pageStream = File.Open(path, FileMode.Create, FileAccess.ReadWrite); extractor.ExtractPage(page, resourceStream ?? fileStream.BaseStream, tmpStream); pageStream.Close(); File.Delete(path); switch (i) { case 0: tmpStream.Position = _soundResource.Location.PrimaryOffset; break; case 1: tmpStream.Position = _soundResource.Location.SecondaryOffset; break; case 2: tmpStream.Position = _soundResource.Location.TertiaryOffset; break; } var bytes = VariousFunctions.StreamToByteArray(tmpStream); if (bytes.Length > 0) { outputBytes.AddRange(new List <byte>(bytes)); } } } return(outputBytes.ToArray()); }
private static void Main(string[] args) { if (args.Length != 3) { Console.WriteLine("Usage: mapexpand <map file> <section> <page count>"); Console.WriteLine(); Console.WriteLine("Available sections:"); Console.WriteLine(" stringidindex"); Console.WriteLine(" stringiddata"); Console.WriteLine(" tagnameindex"); Console.WriteLine(" tagnamedata"); Console.WriteLine(" resource"); Console.WriteLine(" tag"); return; } int pageCount; if (!int.TryParse(args[2], out pageCount) || pageCount <= 0) { Console.WriteLine("The page count must be a positive integer."); return; } Console.WriteLine("Reading..."); var stream = new EndianStream(File.Open(args[0], FileMode.Open, FileAccess.ReadWrite), Endian.BigEndian); var version = new CacheFileVersionInfo(stream); if (version.Engine != EngineType.ThirdGeneration) { Console.WriteLine("Only third-generation map files are supported."); return; } var database = XMLEngineDatabaseLoader.LoadDatabase("Formats/Engines.xml"); var buildInfo = database.FindEngineByVersion(version.BuildString); var cacheFile = new ThirdGenCacheFile(stream, buildInfo, version.BuildString); FileSegmentGroup area; FileSegment section; int pageSize; switch (args[1]) { case "stringidindex": area = cacheFile.StringArea; section = cacheFile.StringIDIndexTable; pageSize = 0x1000; break; case "stringiddata": area = cacheFile.StringArea; section = cacheFile.StringIDDataTable; pageSize = 0x1000; break; case "tagnameindex": area = cacheFile.StringArea; section = cacheFile.FileNameIndexTable; pageSize = 0x1000; break; case "tagnamedata": area = cacheFile.StringArea; section = cacheFile.FileNameDataTable; pageSize = 0x1000; break; case "resource": area = null; section = cacheFile.RawTable; pageSize = 0x1000; break; case "tag": area = cacheFile.MetaArea; section = cacheFile.MetaArea.Segments[0]; pageSize = 0x10000; break; default: Console.WriteLine("Invalid section name: \"{0}\"", args[1]); return; } Console.WriteLine("- Engine version: {0}", version.BuildString); Console.WriteLine("- Internal name: {0}", cacheFile.InternalName); Console.WriteLine("- Scenario name: {0}", cacheFile.ScenarioName); Console.WriteLine(); Console.WriteLine("Injecting empty pages..."); var injectSize = pageCount * pageSize; section.Resize(section.Size + injectSize, stream); Console.WriteLine("Adjusting the header..."); cacheFile.SaveChanges(stream); stream.Dispose(); Console.WriteLine(); var offset = section.Offset; if (section.ResizeOrigin == SegmentResizeOrigin.End) { offset += section.ActualSize - injectSize; } if (area != null) { Console.WriteLine("Successfully injected 0x{0:X} bytes at 0x{1:X} (offset 0x{2:X}).", injectSize, area.BasePointer, offset); } else { Console.WriteLine("Successfully injected 0x{0:X} bytes at offset 0x{1:X}.", injectSize, offset); } }
public void ProcessTag(ITag bitmapTag) { // I don't feel like writing structure definitions, poaching extraction code // #TODO: Wrap all of this up under a neat function for other uses bitmapTagData = null; processedPages.Clear(); string groupName = VariousFunctions.SterilizeTagGroupName(CharConstant.ToString(bitmapTag.Group.Magic)).Trim(); string pluginPath = string.Format("{0}\\{1}\\{2}.xml", VariousFunctions.GetApplicationLocation() + @"Plugins", _buildInfo.Settings.GetSetting <string>("plugins"), groupName); if (!File.Exists(pluginPath) && _buildInfo.Settings.PathExists("fallbackPlugins")) { pluginPath = string.Format("{0}\\{1}\\{2}.xml", VariousFunctions.GetApplicationLocation() + @"Plugins", _buildInfo.Settings.GetSetting <string>("fallbackPlugins"), groupName); } if (pluginPath == null || !File.Exists(pluginPath)) { StatusUpdater.Update("Plugin doesn't exist for 'bitmap', yet somehow you managed to get to the bitmap tab..."); return; } using (IReader reader = _streamManager.OpenRead()) { bitmapTagData = new DataBlockBuilder(reader, bitmapTag, _cache, _buildInfo); using (XmlReader pluginReader = XmlReader.Create(pluginPath)) { AssemblyPluginLoader.LoadPlugin(pluginReader, bitmapTagData); } } bool multiResouceMagic = false; // debugging 8k textures spread across space and time // Resource check if (bitmapTagData.ReferencedResources.Count == 0) { StatusUpdater.Update("Unable to find any resources in the current tag to get bitmap data from!"); return; } else { if (bitmapTagData.ReferencedResources.Count > 1) { multiResouceMagic = true; } if (_cache.Resources != null) // mandrill compiled debugging cache { using (IReader reader = _streamManager.OpenRead()) { resourceTable = _cache.Resources.LoadResourceTable(reader); } } else { StatusUpdater.Update("Unable to find any resources in the cache file at all! Failed to display bitmap."); return; } } // Grab all the raw pages required foreach (DatumIndex resourceDatum in bitmapTagData.ReferencedResources) { Resource currentResource = resourceTable.Resources[resourceDatum.Index]; if (currentResource.Location == null) { StatusUpdater.Update("A bitmap resource had a null location, bad doo doo! Fix yo compiler nerd."); return; } foreach (ResourcePage currentPage in currentResource.Location.PagesToArray()) { if (currentPage == null) { continue; } using (FileStream fileStream = File.OpenRead(_cacheLocation)) { ThirdGenCacheFile resourceFile = (ThirdGenCacheFile)_cache; Stream resourceStream = fileStream; if (currentPage.FilePath != null) // Mandrill compiles everything into a single cache { ResourceCacheInfo resourceCacheInfo = App.AssemblyStorage.AssemblySettings.HalomapResourceCachePaths.FirstOrDefault(r => r.EngineName == _buildInfo.Name); string resourceCachePath = (resourceCacheInfo != null && resourceCacheInfo.ResourceCachePath != "") ? resourceCacheInfo.ResourceCachePath : Path.GetDirectoryName(_cacheLocation); resourceCachePath = Path.Combine(resourceCachePath ?? "", Path.GetFileName(currentPage.FilePath)); if (!File.Exists(resourceCachePath)) { StatusUpdater.Update("Bitmap exists outside of the local cache, was unable to find this cache: " + Path.GetFileName(resourceCachePath)); return; } resourceStream = File.OpenRead(resourceCachePath); resourceFile = new ThirdGenCacheFile(new EndianReader(resourceStream, _cache.Endianness), _buildInfo, Path.GetFileName(_cacheLocation), _cache.BuildString); } byte[] pageData; ResourcePageExtractor pageExtractor = new ResourcePageExtractor(resourceFile); using (MemoryStream pageStream = new MemoryStream()) { pageExtractor.ExtractPage(currentPage, resourceStream, pageStream); pageData = new byte[pageStream.Length]; Buffer.BlockCopy(pageStream.GetBuffer(), 0, pageData, 0, (int)pageStream.Length); } processedPages.Add(pageData); // Store the page for use } } } }