private void Load(StructureValueCollection values, FileSegmenter segmenter) { segmenter.DefineSegment(0, HeaderSize, 1, SegmentResizeOrigin.Beginning); // Define a segment for the header _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size")); Type = (CacheFileType)values.GetInteger("type"); LoadInteropData(values); RawTable = CalculateRawTableSegment(segmenter); InternalName = values.GetString("internal name"); ScenarioName = values.GetString("scenario name"); XDKVersion = (int)values.GetInteger("xdk version"); FileSegment metaSegment = CalculateTagDataSegment(values, segmenter); if (metaSegment != null) { ulong virtualBase = values.GetInteger("virtual base address"); MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, (long)virtualBase)); MetaArea.AddSegment(metaSegment); IndexHeaderLocation = SegmentPointer.FromPointer((long)values.GetInteger("index header address"), MetaArea); Partitions = LoadPartitions(values.GetArray("partitions")); } else { Partitions = new Partition[0]; } CalculateStringGroup(values, segmenter); Checksum = (uint)values.GetInteger("checksum"); }
/* * private void AdjustPartitions() * { * if (MetaArea == null) * return; * * // Find the first partition with a non-null address and change it to the meta area's base address * Partition partition = Partitions.First(p => p.BasePointer != null); * if (partition != null) * partition.BasePointer = SegmentPointer.FromPointer(MetaArea.BasePointer, MetaArea); * * // Recalculate the size of each partition * int partitionEnd = MetaArea.Offset + MetaArea.Size; * for (int i = Partitions.Length - 1; i >= 0; i--) * { * if (Partitions[i].BasePointer == null) * continue; * * int offset = Partitions[i].BasePointer.AsOffset(); * Partitions[i].Size = (uint) (partitionEnd - offset); * partitionEnd = offset; * } * } */ /* * private StructureValueCollection[] SerializePartitions() * { * if (Partitions == null) * return new StructureValueCollection[0]; * * var results = new StructureValueCollection[Partitions.Length]; * for (int i = 0; i < Partitions.Length; i++) * { * var values = new StructureValueCollection(); * values.SetInteger("load address", Partitions[i].BasePointer != null ? Partitions[i].BasePointer.AsPointer() : 0); * values.SetInteger("size", Partitions[i].Size); * results[i] = values; * } * return results; * } */ /// <summary> /// Rebuilds the interop data table in a cache file. /// </summary> /// <param name="localeArea">The localization area of the file.</param> /* * private void RebuildInteropData(FileSegmentGroup localeArea) * { * * FourthGenInteropSection debugSection = Sections[(int) FourthGenInteropSectionType.Debug]; * FourthGenInteropSection rsrcSection = Sections[(int) FourthGenInteropSectionType.Resource]; * FourthGenInteropSection tagSection = Sections[(int) FourthGenInteropSectionType.Tag]; * FourthGenInteropSection localeSection = Sections[(int) FourthGenInteropSectionType.Localization]; * * // Recompute base addresses * // Section addresses are usually in the following order: resource, locale, tag, debug. * // Each address can immediately follow after the previous non-null section, * // even though this isn't the case in some of the official files (because of removed debug data). * // * // TODO: This could possibly be made into a for loop and cleaned up if the pointer converters are stored in an array. * // I just want to get this working for now. * rsrcSection.VirtualAddress = 0; // This is always zero * rsrcSection.Size = (ResourcePointerConverter != null) ? (uint) RawTable.Size : 0; * localeSection.VirtualAddress = (LocalePointerConverter != null) ? rsrcSection.VirtualAddress + rsrcSection.Size : 0; * localeSection.Size = (LocalePointerConverter != null) ? (uint) localeArea.Size : 0; * tagSection.VirtualAddress = (TagBufferPointerConverter != null) * ? rsrcSection.VirtualAddress + rsrcSection.Size + localeSection.Size * : 0; * tagSection.Size = (TagBufferPointerConverter != null) ? (uint) MetaArea.Size : 0; * debugSection.VirtualAddress = (DebugPointerConverter != null) * ? rsrcSection.VirtualAddress + rsrcSection.Size + localeSection.Size + tagSection.Size * : 0; * debugSection.Size = (DebugPointerConverter != null) ? (uint) StringArea.Size : 0; * * // If the offset mask for the debug section wasn't originally zero, then we have to subtract the first partition size from the debug base address * // Not entirely sure why this is the case, but that's what the official files do * if (debugSection.VirtualAddress != 0 && SectionOffsetMasks[(int) FourthGenInteropSectionType.Debug] != 0) * debugSection.VirtualAddress -= Partitions[0].Size; * * // Recompute offset masks * SectionOffsetMasks[(int) FourthGenInteropSectionType.Debug] = (debugSection.Size > 0) * ? (uint) (StringArea.Offset - debugSection.VirtualAddress) * : 0; * SectionOffsetMasks[(int) FourthGenInteropSectionType.Resource] = (rsrcSection.Size > 0) * ? (uint) (RawTable.Offset - rsrcSection.VirtualAddress) * : 0; * SectionOffsetMasks[(int) FourthGenInteropSectionType.Tag] = (tagSection.Size > 0) * ? (uint) (MetaArea.Offset - tagSection.VirtualAddress) * : 0; * SectionOffsetMasks[(int) FourthGenInteropSectionType.Localization] = (localeSection.Size > 0) * ? (uint) (localeArea.Offset - localeSection.VirtualAddress) * : 0; * * // Update pointer converters * if (DebugPointerConverter != null) * DebugPointerConverter.BasePointer = debugSection.VirtualAddress; * if (ResourcePointerConverter != null) * ResourcePointerConverter.BasePointer = rsrcSection.VirtualAddress; * if (TagBufferPointerConverter != null) * TagBufferPointerConverter.BasePointer = tagSection.VirtualAddress; * if (LocalePointerConverter != null) * LocalePointerConverter.BasePointer = localeSection.VirtualAddress; * } */ private void Load(StructureValueCollection map_values, StructureValueCollection tag_values, StructureValueCollection string_values, FileSegmenter map_segmenter) { map_segmenter.DefineSegment(0, HeaderSize, 1, SegmentResizeOrigin.Beginning); // Define a segment for the header _eofSegment = map_segmenter.WrapEOF((int)map_values.GetInteger("file size")); //LoadInteropData(map_values, tag_values); //RawTable = CalculateRawTableSegment(segmenter); Type = (CacheFileType)map_values.GetInteger("type"); InternalName = map_values.GetString("internal name"); ScenarioPath = map_values.GetString("scenario path"); uint index_header_address = map_values.GetInteger("index header address"); // File Segment FileSegmenter tags_segmenter = new FileSegmenter(); tags_segmenter.DefineSegment(0, (int)EngineInfo.TagsDataSize, 0x1, SegmentResizeOrigin.Beginning); // Define a segment for the header FileSegment metaSegment = new FileSegment(0, tags_segmenter); //FileSegment metaSegment = CalculateTagDataSegment(tag_values, segmenter); MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, index_header_address)); MetaArea.AddSegment(metaSegment); IndexHeaderLocation = SegmentPointer.FromPointer(index_header_address, MetaArea); //XDKVersion = (int) values.GetInteger("xdk version"); /* * FileSegment metaSegment = CalculateTagDataSegment(values, segmenter); * if (metaSegment != null) * { * uint virtualBase = values.GetInteger("virtual base address"); * MetaArea = new FileSegmentGroup(new MetaAddressConverter(metaSegment, virtualBase)); * MetaArea.AddSegment(metaSegment); * * IndexHeaderLocation = SegmentPointer.FromPointer(values.GetInteger("index header address"), MetaArea); * Partitions = LoadPartitions(values.GetArray("partitions")); * } * else * { * Partitions = new Partition[0]; * } */ CalculateStringGroup(string_values, map_segmenter); }
private void Load(StructureValueCollection values, StringIDSource stringIDs) { Name = values.HasInteger("name index") ? stringIDs.GetString(new StringID(values.GetInteger("name index"))) : values.GetString("name"); Type = (short)values.GetInteger("type"); ExpressionIndex = new DatumIndex(values.GetInteger("expression index")); }
private string GetObjectName(StructureValueCollection values, StringIDSource stringIDs) { if (values.HasString("name")) { return(values.GetString("name")); } if (values.HasInteger("name stringid")) { var sid = new StringID(values.GetInteger("name stringid")); return(stringIDs.GetString(sid)); } throw new InvalidOperationException("Unable to determine the name of objects in the \"" + _layoutName + "\" layout"); }
/// <summary> /// Creates a context object from meta data. /// </summary> /// <param name="index">The index of the object.</param> /// <param name="group">The object group of the object.</param> /// <param name="isChildObject">is true if thi sobject is the child of another object.</param> /// <param name="data">The meta data.</param> /// <returns>A context object.</returns> private static ScriptingContextObject CreateContextObject(int index, string group, bool isChildObject, StructureValueCollection data, int wrapperIndex = -1) { string name = data.HasStringID("Name") ? data.GetStringID("Name") : data.GetString("Name"); var result = new ScriptingContextObject(name.ToLowerInvariant(), index, group, isChildObject, wrapperIndex); var childBlocks = data.GetTagBlocks(); if (childBlocks.Length > 0) { foreach (var block in childBlocks.Where(b => b.Value.Length > 0)) { // Handle child blocks, which are wrapped up in another block without a name field. if (IsWrapperBlock(block)) { var wrappedBlocks = new Dictionary <string, List <ScriptingContextObject> >(); // Iterate through the wrapper elements and collect all wrapped blocks and their objects. for (int i = 0; i < block.Value.Length; i++) { var innerChildrenBlocks = block.Value[i].GetTagBlocks(); foreach (var inner in innerChildrenBlocks) { var wrappedObjects = GetWrapperContextObjects(inner, i); if (wrappedBlocks.ContainsKey(inner.Key)) { wrappedBlocks[inner.Key].AddRange(wrappedObjects); } else { wrappedBlocks[inner.Key] = wrappedObjects.ToList(); } } } // Add the grouped blocks and objects to the result. foreach (var groupedBlock in wrappedBlocks) { result.AddChildBlock(new ScriptingContextBlock(groupedBlock.Key, groupedBlock.Value)); } } // Handle regular child blocks. else { result.AddChildBlock(CreateContextBlock(block, true)); } } } return(result); }
private void Load(StructureValueCollection values, FileSegmenter segmenter) { _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size")); var metaOffset = (int)values.GetInteger("meta offset"); int metaSize; // TODO (Dragon): hack for h2 alpha if (BuildString == "02.01.07.4998") { metaSize = (int)values.GetInteger("tag data offset") + (int)values.GetInteger("tag data size"); // hack to rewrite the "meta size" value even though its not actually the meta size //_saved_meta_size_hack = (uint)values.GetInteger("meta size"); } else { metaSize = (int)values.GetInteger("meta size"); } var metaSegment = new FileSegment( segmenter.DefineSegment(metaOffset, metaSize, 0x4, SegmentResizeOrigin.Beginning), segmenter); // we hacked in a meta header size into the values earlier in the cache load uint metaOffsetMask = (uint)(values.GetInteger("tag table offset") - values.GetInteger("meta header size")); MetaArea = new FileSegmentGroup(new MetaOffsetConverter(metaSegment, metaOffsetMask)); IndexHeaderLocation = MetaArea.AddSegment(metaSegment); Type = (CacheFileType)values.GetInteger("type"); var headerGroup = new FileSegmentGroup(); headerGroup.AddSegment(segmenter.WrapSegment(0, HeaderSize, 1, SegmentResizeOrigin.None)); InternalName = values.GetString("internal name"); Checksum = (uint)values.GetInteger("checksum"); // dummy partition Partitions = new Partition[1]; Partitions[0] = new Partition(SegmentPointer.FromOffset(MetaArea.Offset, MetaArea), (uint)MetaArea.Size); // dummy stringids StringIDCount = 0; StringIDData = _eofSegment; StringIDIndexTable = _eofSegment; }
private void Load(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, StringIDSource stringIDs, EngineDescription buildInfo) { Name = values.HasInteger("name index") ? stringIDs.GetString(new StringID(values.GetInteger("name index"))) : values.GetString("name"); ExecutionType = (short)values.GetInteger("execution type"); ReturnType = (short)values.GetInteger("return type"); RootExpressionIndex = new DatumIndex(values.GetInteger("first expression index")); if (Name == null) { Name = "script_" + RootExpressionIndex.Value.ToString("X8"); } Parameters = LoadParameters(reader, values, metaArea, buildInfo); }
private void Load(StructureValueCollection values, FileSegmenter segmenter) { _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size")); var metaOffset = (int)values.GetInteger("meta offset"); var metaSize = (int)values.GetInteger("meta size"); uint metaOffsetMask = values.GetInteger("meta offset mask"); var metaSegment = new FileSegment( segmenter.DefineSegment(metaOffset, metaSize, 0x200, SegmentResizeOrigin.Beginning), segmenter); MetaArea = new FileSegmentGroup(new MetaOffsetConverter(metaSegment, metaOffsetMask)); IndexHeaderLocation = MetaArea.AddSegment(metaSegment); Type = (CacheFileType)values.GetInteger("type"); var headerGroup = new FileSegmentGroup(); headerGroup.AddSegment(segmenter.WrapSegment(0, HeaderSize, 1, SegmentResizeOrigin.None)); StringIDCount = (int)values.GetInteger("string table count"); var sidDataSize = (int)values.GetInteger("string table size"); StringIDData = segmenter.WrapSegment((int)values.GetInteger("string table offset"), sidDataSize, 1, SegmentResizeOrigin.End); StringIDIndexTable = segmenter.WrapSegment((int)values.GetInteger("string index table offset"), StringIDCount * 4, 4, SegmentResizeOrigin.End); FileNameCount = (int)values.GetInteger("file table count"); var fileDataSize = (int)values.GetInteger("file table size"); FileNameData = segmenter.WrapSegment((int)values.GetInteger("file table offset"), fileDataSize, 1, SegmentResizeOrigin.End); FileNameIndexTable = segmenter.WrapSegment((int)values.GetInteger("file index table offset"), FileNameCount * 4, 4, SegmentResizeOrigin.End); InternalName = values.GetString("internal name"); ScenarioName = values.GetString("scenario name"); StringArea = new FileSegmentGroup(); StringArea.AddSegment(segmenter.WrapSegment((int)values.GetInteger("string block offset"), StringIDCount * 0x80, 0x80, SegmentResizeOrigin.End)); StringArea.AddSegment(StringIDIndexTable); StringArea.AddSegment(StringIDData); StringArea.AddSegment(FileNameIndexTable); StringArea.AddSegment(FileNameData); StringIDIndexTableLocation = SegmentPointer.FromOffset(StringIDIndexTable.Offset, StringArea); StringIDDataLocation = SegmentPointer.FromOffset(StringIDData.Offset, StringArea); FileNameIndexTableLocation = SegmentPointer.FromOffset(FileNameIndexTable.Offset, StringArea); FileNameDataLocation = SegmentPointer.FromOffset(FileNameData.Offset, StringArea); LocaleArea = new FileSegmentGroup(); var rawTableOffset = (int)values.GetInteger("raw table offset"); var rawTableSize = (int)values.GetInteger("raw table size"); RawTable = segmenter.WrapSegment(rawTableOffset, rawTableSize, 1, SegmentResizeOrigin.End); Checksum = values.GetInteger("checksum"); // Set up a bogus partition table Partitions = new Partition[1]; Partitions[0] = new Partition(SegmentPointer.FromOffset(MetaArea.Offset, MetaArea), (uint)MetaArea.Size); }
private void Load(StructureValueCollection values) { Name = values.GetString("name"); Type = (short)values.GetInteger("type"); }
private void Load(StructureValueCollection values) { Path = values.GetString("map path"); }
private void Load(StructureValueCollection values) { Name = values.GetString("name"); Type = (short)values.GetInteger("type"); ExpressionIndex = new DatumIndex(values.GetInteger("expression index")); }
private void Load(StructureValueCollection values, FileSegmenter segmenter) { _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size")); var metaOffset = (int)values.GetInteger("meta offset"); int tagTableSize = (int)values.GetInteger("tag data offset"); int tagDataSize = (int)values.GetInteger("tag data size"); var headSegment = new FileSegment( segmenter.DefineSegment(metaOffset, tagTableSize, 0x1000, SegmentResizeOrigin.Beginning), segmenter); //xbox haxx, we can assume thru the existance of the code-set xbox mask uint metaOffsetMask; FileSegment metaSegment = null; if (values.HasInteger("xbox meta offset mask")) { // store the stock meta size since xbox's size is virtual //todo: figure out how this is calculated instead of doing a hack _saved_meta_size_hack = (uint)values.GetInteger("meta size"); metaOffsetMask = (uint)values.GetInteger("xbox meta offset mask"); metaSegment = new FileSegment( segmenter.DefineSegment(metaOffset + tagTableSize, tagDataSize, 0x4, SegmentResizeOrigin.End), segmenter); } else { metaOffsetMask = (uint)values.GetInteger("meta offset mask"); metaSegment = new FileSegment( segmenter.DefineSegment(metaOffset + tagTableSize, tagDataSize, 0x1000, SegmentResizeOrigin.End), segmenter); } MetaArea = new FileSegmentGroup(new MetaOffsetConverter(headSegment, metaOffsetMask)); IndexHeaderLocation = MetaArea.AddSegment(headSegment); MetaArea.AddSegment(metaSegment); Type = (CacheFileType)values.GetInteger("type"); var headerGroup = new FileSegmentGroup(); headerGroup.AddSegment(segmenter.WrapSegment(0, HeaderSize, 1, SegmentResizeOrigin.None)); StringIDCount = (int)values.GetInteger("string table count"); var sidDataSize = (int)values.GetInteger("string table size"); StringIDData = segmenter.WrapSegment((int)values.GetInteger("string table offset"), sidDataSize, 1, SegmentResizeOrigin.End); StringIDIndexTable = segmenter.WrapSegment((int)values.GetInteger("string index table offset"), StringIDCount * 4, 4, SegmentResizeOrigin.End); if (values.HasInteger("file table count")) { FileNameCount = (int)values.GetInteger("file table count"); var fileDataSize = (int)values.GetInteger("file table size"); FileNameData = segmenter.WrapSegment((int)values.GetInteger("file table offset"), fileDataSize, 1, SegmentResizeOrigin.End); FileNameIndexTable = segmenter.WrapSegment((int)values.GetInteger("file index table offset"), FileNameCount * 4, 4, SegmentResizeOrigin.End); } InternalName = values.GetString("internal name"); ScenarioName = values.GetString("scenario name"); StringArea = new FileSegmentGroup(); if (values.HasInteger("string block offset")) { StringArea.AddSegment(segmenter.WrapSegment((int)values.GetInteger("string block offset"), StringIDCount * 0x80, 0x80, SegmentResizeOrigin.End)); } StringArea.AddSegment(StringIDIndexTable); StringArea.AddSegment(StringIDData); StringIDIndexTableLocation = SegmentPointer.FromOffset(StringIDIndexTable.Offset, StringArea); StringIDDataLocation = SegmentPointer.FromOffset(StringIDData.Offset, StringArea); if (FileNameIndexTable != null) { StringArea.AddSegment(FileNameIndexTable); StringArea.AddSegment(FileNameData); FileNameIndexTableLocation = SegmentPointer.FromOffset(FileNameIndexTable.Offset, StringArea); FileNameDataLocation = SegmentPointer.FromOffset(FileNameData.Offset, StringArea); } int rawTableOffset; int rawTableSize; if (values.HasInteger("raw table offset")) { rawTableOffset = (int)values.GetInteger("raw table offset"); rawTableSize = (int)values.GetInteger("raw table size"); // It is apparently possible to create a cache without a raw table, but -1 gets written as the offset if (rawTableOffset != -1) { RawTable = segmenter.WrapSegment(rawTableOffset, rawTableSize, 0x80, SegmentResizeOrigin.End); } } Checksum = (uint)values.GetInteger("checksum"); // Set up a bogus partition table Partitions = new Partition[1]; Partitions[0] = new Partition(SegmentPointer.FromOffset(MetaArea.Offset, MetaArea), (uint)MetaArea.Size); }
public void LoadSavesFromDevices() { // Do Save Selector Code BackgroundWorker bw = new BackgroundWorker(); bw.DoWork += (o2, args2) => { Dispatcher.Invoke(new Action(delegate { // Setup Pending UI stuff progressPendingRefresh.Visibility = System.Windows.Visibility.Visible; // Close Existing Streams foreach (StartPageViewModel.FATXGameSave save in PageViewModel.FATXGameSaves) { save.Stream.Close(); } // Clear ObservableCollection PageViewModel.FATXGameSaves.Clear(); })); if (_physDrives != null) { foreach (Drive drive in _physDrives) { drive.Close(); } _physDrives = null; } // Get Drives _physDrives = StartHere.GetFATXDrives().ToList(); // Get Saves from said drives foreach (Drive drive in _physDrives) { Folder xboxContent = drive.FolderFromPath("Data\\Content"); foreach (Folder content in xboxContent.Folders()) { if (content.Name.StartsWith("E")) { // We're in a profile, lets go right into a game file foreach (Manager.SupportedGames.SupportedGame supportedGame in Manager.SupportedGame.Games) { string filePath = string.Format("{0}\\Content\\{1}\\{2}\\00000001", "Data", content.Name, supportedGame.TitleID.ToString("X")); if (drive.DirectoryExists(filePath)) { Folder profileGamesaveContent = drive.FolderFromPath(filePath); // Look though the profile folder for a campaign save foreach (CLKsFATXLib.File gamesaveContent in profileGamesaveContent.Files()) { if (gamesaveContent.Name.StartsWith(supportedGame.STFSStartsWith)) { try { // Is a campaign save, woop! // Add to the ObservableCollection and move out! StartPageViewModel.FATXGameSave fatxGamesave = new StartPageViewModel.FATXGameSave(); fatxGamesave.FATXPath = gamesaveContent.FullPath; fatxGamesave.PackageName = gamesaveContent.Name; fatxGamesave.GameName = supportedGame.Name; fatxGamesave.SafeGameName = supportedGame.SafeName; fatxGamesave.SupportedGame = supportedGame; fatxGamesave.FATXDrive = drive; // Check the save isn't already open string USID = Utilities.CreateUniqueSaveIdentification(gamesaveContent.Name, gamesaveContent.FullPath, true); if (!Backend.Settings.OpenedSaves.Contains(USID)) { // Extract gamestate to get data about the save STFSPackage package = new STFSPackage(new X360.IO.DJsIO(gamesaveContent.GetStream(), true), null); FileEntry gamestateHeader = package.GetFile("gamestate.hdr"); string extractionPath = Backend.VariousFunctions.CreateTemporaryFile(Backend.VariousFunctions.GetTemporaryExtractionLocation()); gamestateHeader.Extract(extractionPath); // Create Stream, lol EndianStream endianStream = new EndianStream(new MemoryStream(System.IO.File.ReadAllBytes(extractionPath)), Endian.BigEndian); // Get Header Layout StructureValueCollection saveHeader = StructureReader.ReadStructure(endianStream, supportedGame.GetLayout("header")); fatxGamesave.Stream = endianStream; fatxGamesave.USID = USID; fatxGamesave.MapName = SaveManager.Utilities.GetFriendlyMissionName(saveHeader.GetString("scenario"), (Utilities.HaloGames)Enum.Parse(typeof(Utilities.HaloGames), supportedGame.SafeName)); fatxGamesave.MapScenario = saveHeader.GetString("scenario"); string libertyImagePath = string.Format(@"/Liberty;component/Metro/Images/Games/MapImages/{0}/{1}.jpg", supportedGame.SafeName, saveHeader.GetString("scenario").Substring(saveHeader.GetString("scenario").LastIndexOf('\\') + 1).ToLower()); fatxGamesave.MapImage = libertyImagePath; fatxGamesave.GamerTag = saveHeader.GetString("gamer tag"); fatxGamesave.ServiceTag = saveHeader.GetString("service tag"); Dispatcher.Invoke(new Action(delegate { // Add to ObservableCollection, has to be invoked to do this PageViewModel.FATXGameSaves.Add(fatxGamesave); })); } } catch { } } } } } } } } }; bw.RunWorkerCompleted += (o, args) => { // Setup Pending UI stuff Dispatcher.Invoke(new Action(delegate { progressPendingRefresh.Visibility = System.Windows.Visibility.Collapsed; })); }; bw.RunWorkerAsync(); }
private void Load(StructureValueCollection values, FileSegmenter segmenter) { _eofSegment = segmenter.WrapEOF((int)values.GetInteger("file size")); var metaOffset = (int)values.GetInteger("meta offset"); int metaSize; if (values.HasInteger("tag data offset")) { metaSize = (int)values.GetInteger("tag data offset") + (int)values.GetInteger("tag data size"); } else { metaSize = (int)values.GetInteger("meta size"); } // store the stock meta size since xbox's size is virtual //todo: figure out how this is calculated instead of doing a hack _saved_meta_size_hack = (uint)values.GetInteger("meta size"); var metaSegment = new FileSegment( segmenter.DefineSegment(metaOffset, metaSize, 0x4, SegmentResizeOrigin.Beginning), segmenter); uint metaOffsetMask; if (values.HasInteger("xbox meta offset mask")) { metaOffsetMask = (uint)values.GetInteger("xbox meta offset mask"); } else { metaOffsetMask = (uint)(values.GetInteger("tag table offset") - values.GetInteger("meta header size")); } MetaArea = new FileSegmentGroup(new MetaOffsetConverter(metaSegment, metaOffsetMask)); IndexHeaderLocation = MetaArea.AddSegment(metaSegment); Type = (CacheFileType)values.GetInteger("type"); var headerGroup = new FileSegmentGroup(); headerGroup.AddSegment(segmenter.WrapSegment(0, HeaderSize, 1, SegmentResizeOrigin.None)); //h2 alpha forcing this to be shoved in if (values.HasInteger("string table count")) { StringIDCount = (int)values.GetInteger("string table count"); var sidDataSize = (int)values.GetInteger("string table size"); StringIDData = segmenter.WrapSegment((int)values.GetInteger("string table offset"), sidDataSize, 1, SegmentResizeOrigin.End); StringIDIndexTable = segmenter.WrapSegment((int)values.GetInteger("string index table offset"), StringIDCount * 4, 4, SegmentResizeOrigin.End); StringArea = new FileSegmentGroup(); if (values.HasInteger("string block offset")) { StringArea.AddSegment(segmenter.WrapSegment((int)values.GetInteger("string block offset"), StringIDCount * 0x80, 0x80, SegmentResizeOrigin.End)); } StringArea.AddSegment(StringIDIndexTable); StringArea.AddSegment(StringIDData); StringIDIndexTableLocation = SegmentPointer.FromOffset(StringIDIndexTable.Offset, StringArea); StringIDDataLocation = SegmentPointer.FromOffset(StringIDData.Offset, StringArea); } else { //dummy StringIDCount = 0; StringIDData = _eofSegment; StringIDIndexTable = _eofSegment; } InternalName = values.GetString("internal name"); Checksum = (uint)values.GetInteger("checksum"); // dummy partition Partitions = new Partition[1]; Partitions[0] = new Partition(SegmentPointer.FromOffset(MetaArea.Offset, MetaArea), (uint)MetaArea.Size); }