private void ReadTagBlock(DataBlock block, uint offset, uint entrySize, int align, bool sort) { // Read the count and pointer SeekToOffset(block, offset); var values = StructureReader.ReadStructure(_reader, _tagBlockLayout); var count = (int)values.GetInteger("entry count"); var pointer = (uint)values.GetInteger("pointer"); long expand = _cacheFile.PointerExpander.Expand(pointer); if (count <= 0 || !_cacheFile.MetaArea.ContainsBlockPointer(expand, (int)(count * entrySize))) { return; } var newBlock = ReadDataBlock(expand, (int)entrySize, count, align, sort); // Now create a fixup for the block var fixup = new DataBlockAddressFixup(pointer, (int)offset + _tagBlockLayout.GetFieldOffset("pointer")); block.AddressFixups.Add(fixup); // Add it to _tagBlocks so it'll be recursed into _tagBlocks.Add(newBlock); }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _tagBlockLayout); var length = (int)values.GetInteger("entry count"); uint pointer = values.GetInteger("pointer"); if (_cache.Engine == EngineType.ThirdGenMCC) { pointer = NewPointerConverter.ConvertToPointer(pointer); } // Make sure the pointer looks valid if (length < 0 || !_cache.MetaArea.ContainsTagBlockPointer(pointer, (int)(length * field.EntrySize))) { length = 0; pointer = 0; } field.Length = length; if (pointer != field.FirstEntryAddress) { field.FirstEntryAddress = pointer; } }
public void VisitReflexive(ReflexiveData field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _tagBlockLayout); var length = (int)values.GetInteger("entry count"); uint pointer = values.GetInteger("pointer"); // Make sure the pointer looks valid if (length < 0 || (_cache.Engine != EngineType.FourthGeneration && !_cache.MetaArea.ContainsBlockPointer(pointer, (int)(length * field.EntrySize))) || (_cache.Engine == EngineType.FourthGeneration && (pointer < 0x40000000 || pointer > 0x50000000))) { if (length != 0 && pointer != 0) { //field.Opacity = 0.5f; MetroMessageBox.Show("Bad Block!", "Block \"" + field.Name + "\", plugin line " + field.PluginLine + " appears to be invalid. The block has been ignored to prevent crashing."); } length = 0; pointer = 0; } field.Length = length; if (pointer != field.FirstEntryAddress) { field.FirstEntryAddress = pointer; } }
public void SaveChanges(IStream stream) { if (!_changed) { return; } var scenarioLayout = _buildInfo.Layouts.GetLayout("scnr"); stream.SeekTo(_scenario.MetaLocation.AsOffset()); var scenarioData = StructureReader.ReadStructure(stream, scenarioLayout); var oldCount = (int)scenarioData.GetInteger("simulation definition table count"); var oldAddress = (uint)scenarioData.GetInteger("simulation definition table address"); long expand = _expander.Expand(oldAddress); var entryLayout = _buildInfo.Layouts.GetLayout("simulation definition table element"); var newTable = _table.Select(SerializeTag); var newAddr = TagBlockWriter.WriteTagBlock(newTable, oldCount, expand, _table.Count, entryLayout, _metaArea, _allocator, stream); uint cont = _expander.Contract(newAddr); scenarioData.SetInteger("simulation definition table count", (uint)_table.Count); scenarioData.SetInteger("simulation definition table address", cont); stream.SeekTo(_scenario.MetaLocation.AsOffset()); StructureWriter.WriteStructure(scenarioData, scenarioLayout, stream); _changed = false; }
private static CompressionState AnalyzeFirstGen(IReader reader, EngineDescription engineInfo, out StructureValueCollection headerValues) { reader.SeekTo(0); var headerLayout = engineInfo.Layouts.GetLayout("header"); headerValues = StructureReader.ReadStructure(reader, headerLayout); //hax headerValues.SetInteger("_header_length_", (ulong)headerLayout.Size); var metaOffset = (int)headerValues.GetInteger("meta offset"); if (metaOffset >= reader.Length) { return(CompressionState.Compressed); } reader.SeekTo(metaOffset); StructureValueCollection tagTableValues = StructureReader.ReadStructure(reader, engineInfo.Layouts.GetLayout("meta header")); if ((uint)tagTableValues.GetInteger("magic") != CharConstant.FromString("tags")) { return(CompressionState.Compressed); } return(CompressionState.Decompressed); }
private FirstGenTagTable LoadTagTable(IReader reader) { reader.SeekTo(MetaArea.Offset); StructureValueCollection values = StructureReader.ReadStructure(reader, _buildInfo.Layouts.GetLayout("meta header")); return(new FirstGenTagTable(reader, values, MetaArea, _buildInfo)); }
private StructureValueCollection LoadHeader(IReader reader) { if (_metaArea == null) { return(null); } reader.SeekTo(_metaArea.Offset); StructureValueCollection result = StructureReader.ReadStructure(reader, _metaHeaderLayout); if ((uint)result.GetInteger("magic") != CharConstant.FromString("tags")) { throw new ArgumentException("Invalid index table header magic. This map could be compressed, try the Compressor in the Tools menu before reporting."); } //see if header values are memory (xbox) or local (everything after) and store the result if needed uint metaMask = (uint)result.GetInteger("tag group table offset") - (uint)_metaHeaderLayout.Size; if (metaMask > 0) { result.SetInteger("meta header mask", metaMask); } return(result); }
public static StructureValueCollection[] ReadReflexive(IReader reader, int count, uint address, StructureLayout entryLayout, FileSegmentGroup metaArea) { if (entryLayout.Size == 0) { throw new ArgumentException("The entry layout must have a size associated with it."); } // Handle null pointers if (count <= 0 || !metaArea.ContainsPointer(address)) { return(new StructureValueCollection[0]); } // Convert the address to an offset and seek to it int offset = metaArea.PointerToOffset(address); reader.SeekTo(offset); // Read the entries var result = new StructureValueCollection[count]; for (int i = 0; i < count; i++) { result[i] = StructureReader.ReadStructure(reader, entryLayout); } return(result); }
private void ReadLocalePointer(IReader reader, out StringID id, out int offset) { StructureValueCollection values = StructureReader.ReadStructure(reader, _pointerLayout); id = new StringID(values.GetInteger("stringid")); offset = (int)values.GetInteger("offset"); }
/*<layout for="compiled effect entry" size="0x30"> * <uint32 name = "effect pointer" offset="0x0" /> * <uint32 name = "beam pointer" offset="0xC" /> * <uint32 name = "contrail pointer" offset="0x18" /> * <uint32 name = "light volume pointer" offset="0x24" /> * </layout> * * <layout for="compiled effect pointer" size="0x14"> * <int32 name = "size" offset="0x0" /> * <uint32 name = "pointer" offset="0xC" /> * </layout> * * <layout for="effect data" size="0x7A0" /> * <layout for="beam data" size="0x740" /> * <layout for="contrail data" size="0x770" /> * <layout for="light volume data" size="0x700" />*/ private void Load(IReader reader) { //might need to tweak once more MCC games come out reader.SeekTo(_scenario.MetaLocation.AsOffset()); var scenarioLayout = _buildInfo.Layouts.GetLayout("scnr"); var scenarioData = StructureReader.ReadStructure(reader, scenarioLayout); var count = (int)scenarioData.GetInteger("compiled effects count"); var address = (uint)scenarioData.GetInteger("compiled effect address"); long expand = _expander.Expand(address); reader.SeekTo(_metaArea.PointerToOffset(expand)); var entryLayout = _buildInfo.Layouts.GetLayout("compiled effect entry"); var pointerReflexive = StructureReader.ReadStructure(reader, entryLayout); var effeAddr = (uint)pointerReflexive.GetInteger("effect pointer"); var beamAddr = (uint)pointerReflexive.GetInteger("beam pointer"); var cntlAddr = (uint)pointerReflexive.GetInteger("contrail pointer"); var ltvlAddr = (uint)pointerReflexive.GetInteger("light volume pointer"); var pointerLayout = _buildInfo.Layouts.GetLayout("compiled effect pointer"); LoadData(reader, EffectStorageType.Effect, _expander.Expand(effeAddr), pointerLayout, "effect data"); LoadData(reader, EffectStorageType.Beam, _expander.Expand(beamAddr), pointerLayout, "beam data"); LoadData(reader, EffectStorageType.Contrail, _expander.Expand(cntlAddr), pointerLayout, "contrail data"); LoadData(reader, EffectStorageType.LightVolume, _expander.Expand(ltvlAddr), pointerLayout, "light volume data"); }
private void LoadHeader(IReader reader, string buildString) { reader.SeekTo(0); StructureValueCollection values = StructureReader.ReadStructure(reader, _buildInfo.Layouts.GetLayout("header")); _header = new ThirdGenHeader(values, _buildInfo, buildString, _segmenter, _expander); }
private SecondGenHeader LoadHeader(IReader reader) { reader.SeekTo(0); StructureValueCollection values = StructureReader.ReadStructure(reader, _buildInfo.Layouts.GetLayout("header")); return(new SecondGenHeader(values, _buildInfo, _segmenter)); }
private static CompressionState AnalyzeSecondGen(IReader reader, EngineDescription engineInfo) { // H2 header is uncompressed, so the cache file needs to be loaded enough to check if the tag table is readable var segmenter = new FileSegmenter(engineInfo.SegmentAlignment); reader.SeekTo(0); StructureValueCollection headerValues = StructureReader.ReadStructure(reader, engineInfo.Layouts.GetLayout("header")); var metaOffset = (int)headerValues.GetInteger("meta offset"); var metaSize = (int)headerValues.GetInteger("meta size"); uint metaOffsetMask = (uint)headerValues.GetInteger("meta offset mask"); var metaSegment = new FileSegment( segmenter.DefineSegment(metaOffset, metaSize, 0x200, SegmentResizeOrigin.Beginning), segmenter); var MetaArea = new FileSegmentGroup(new MetaOffsetConverter(metaSegment, metaOffsetMask)); MetaArea.AddSegment(metaSegment); if (MetaArea.Offset >= reader.Length) { return(CompressionState.Compressed); } reader.SeekTo(MetaArea.Offset); StructureValueCollection tagTableValues = StructureReader.ReadStructure(reader, engineInfo.Layouts.GetLayout("meta header")); if ((uint)tagTableValues.GetInteger("magic") != CharConstant.FromString("tags")) { return(CompressionState.Compressed); } return(CompressionState.Decompressed); }
private SecondGenHeader LoadHeader(IReader reader, EngineDescription buildInfo, string buildString) { reader.SeekTo(0); StructureValueCollection values = StructureReader.ReadStructure(reader, buildInfo.Layouts.GetLayout("header")); return(new SecondGenHeader(values, buildInfo, buildString, _segmenter)); }
private SecondGenTagTable LoadTagTable(IReader reader, EngineDescription buildInfo) { reader.SeekTo(MetaArea.Offset); StructureValueCollection values = StructureReader.ReadStructure(reader, buildInfo.Layouts.GetLayout("meta header")); return(new SecondGenTagTable(reader, values, MetaArea, buildInfo)); }
private void ReadTagReference(DataBlock block, uint offset, bool withClass) { SeekToOffset(block, offset); DatumIndex index; int fixupOffset; bool valid; if (withClass) { // Class info - do a flexible structure read to get the index StructureValueCollection values = StructureReader.ReadStructure(_reader, _tagRefLayout); var classMagic = (int)values.GetInteger("class magic"); index = new DatumIndex(values.GetInteger("datum index")); fixupOffset = (int)offset + _tagRefLayout.GetFieldOffset("datum index"); valid = _cacheFile.Tags.IsValidIndex(index, classMagic); } else { // No tag class - the datum index is at the offset index = new DatumIndex(_reader.ReadUInt32()); fixupOffset = (int)offset; valid = _cacheFile.Tags.IsValidIndex(index); } if (valid) { // Add the tagref fixup to the block var fixup = new DataBlockTagFixup(index, fixupOffset); block.TagFixups.Add(fixup); ReferencedTags.Add(index); } }
private List <ITag> ReadTags(IReader reader, uint tagTableOffset, int numTags, EngineDescription buildInfo, FileSegmentGroup metaArea) { StructureLayout layout = buildInfo.Layouts.GetLayout("tag element"); var result = new List <ITag>(); reader.SeekTo(tagTableOffset); // TODO (Dragon): DUDE long oldpos = reader.Position; reader.SeekTo(metaArea.Offset); uint metafuck = reader.ReadUInt32(); metafuck -= (uint)(tagTableOffset - metaArea.Offset); reader.SeekTo(oldpos); for (int i = 0; i < numTags; i++) { StructureValueCollection values = StructureReader.ReadStructure(reader, layout); // TODO (Dragon): SERIOUSLY // JUST F*****G FIX THE FILE SEGMENTS OH MY GOD if (buildInfo.Version == "02.01.07.4998" || buildInfo.Version == "02.06.28.07902") { ulong omg = values.GetInteger("name offset"); //omg += ((ulong)metaArea.BasePointer - metafuck) - (ulong)metaArea.BasePointer + (ulong)metaArea.Offset; omg += ((ulong)metaArea.BasePointer - metafuck); values.SetInteger("name offset", omg); } result.Add(new FirstGenTag(values, metaArea, _groupsById)); } return(result); }
private List <ITag> ReadTags(IReader reader, uint tagTableOffset, int numTags, EngineDescription buildInfo, FileSegmentGroup metaArea, StructureValueCollection headerValues) { StructureLayout layout = buildInfo.Layouts.GetLayout("tag element"); var result = new List <ITag>(); reader.SeekTo(tagTableOffset); ulong metaOffset = 0; if (headerValues.HasInteger("meta header mask")) { metaOffset = (ulong)metaArea.BasePointer - headerValues.GetInteger("meta header mask"); } for (int i = 0; i < numTags; i++) { StructureValueCollection values = StructureReader.ReadStructure(reader, layout); //h2 alpha/beta store names differently, convert it to something expected if (metaOffset > 0) { ulong nameOffset = values.GetInteger("name offset"); nameOffset += metaOffset; values.SetInteger("name offset", nameOffset); } result.Add(new FirstGenTag(values, metaArea, _groupsById)); } return(result); }
/// <summary> /// Loads the string list. /// </summary> /// <param name="reader">The stream to read from.</param> private void Load(IReader reader) { reader.SeekTo(Tag.MetaLocation.AsOffset()); StructureValueCollection values = StructureReader.ReadStructure(reader, _layout); StructureValueCollection[] rangeValues = values.GetArray("language ranges"); Ranges = rangeValues.Select(v => StringRange.Deserialize(v)).ToArray(); }
public BlamRenderModelPermutation(long addr, BlamCacheFile blamCacheFile, StructureLayout permutationLayout) { blamCacheFile.Reader.SeekTo(addr); StructureValueCollection values = StructureReader.ReadStructure(blamCacheFile.Reader, permutationLayout); Name = blamCacheFile.Get().StringIDs.GetString(new StringID(values.GetInteger("name stringid"))); ModelSection = (Int16)(values.GetInteger("model section")); ModelCount = (Int16)(values.GetInteger("model count")); }
private void Load(IReader reader) { reader.SeekTo(_scenario.MetaLocation.AsOffset()); var scenarioLayout = _buildInfo.Layouts.GetLayout("scnr"); var scenarioData = StructureReader.ReadStructure(reader, scenarioLayout); var count = (int)scenarioData.GetInteger("simulation definition table count"); var address = scenarioData.GetInteger("simulation definition table address"); var entryLayout = _buildInfo.Layouts.GetLayout("simulation definition table entry"); _table = ReflexiveReader.ReadReflexive(reader, count, address, entryLayout, _metaArea).Select((e) => _tags[new DatumIndex(e.GetInteger("datum index"))]).ToList(); }
private StructureValueCollection LoadTag(IReader reader) { reader.SeekTo(_tag.MetaLocation.AsOffset()); if (!_zone) { return(StructureReader.ReadStructure(reader, _buildInfo.Layouts.GetLayout("resource layout table"))); } else { return(StructureReader.ReadStructure(reader, _buildInfo.Layouts.GetLayout("resource layout table alt"))); } }
private FirstGenTagTable LoadTagTable(IReader reader, uint mask) { reader.SeekTo(MetaArea.Offset); StructureValueCollection values = StructureReader.ReadStructure(reader, _buildInfo.Layouts.GetLayout("meta header")); if (mask > 0) { values.SetInteger("meta header mask", mask); } return(new FirstGenTagTable(reader, values, MetaArea, _buildInfo)); }
public void VisitDataRef(DataRef field) { SeekToOffset(field.Offset); StructureValueCollection values = StructureReader.ReadStructure(_reader, _dataRefLayout); var length = (int)values.GetInteger("size"); uint pointer = values.GetInteger("pointer"); if (length > 0) { if (_cache.GetType() == typeof(Blamite.Blam.FourthGen.FourthGenCacheFile)) { pointer = HeaderOffset + (pointer & 0xFFFFFFF); } field.DataAddress = pointer; field.Length = length; // Go to position if (_type == LoadType.Memory) { _reader.SeekTo(pointer); } else { _reader.SeekTo(_cache.MetaArea.PointerToOffset(pointer)); } switch (field.Format) { default: byte[] data = _reader.ReadBlock(field.Length); field.Value = FunctionHelpers.BytesToHexString(data); break; case "unicode": field.Value = _reader.ReadUTF16(field.Length); break; case "asciiz": field.Value = _reader.ReadAscii(field.Length); break; } } else { field.DataAddress = 0; field.Length = 0; field.Value = ""; } }
private static void MapLoadUnitTest() { string targetFile = Core.Util.VisualStudioProvider.TryGetSolutionDirectoryInfo().FullName + "\\" + TARGET_MAP_FILE; using (BlamCacheFile blamCacheFile = new BlamCacheFile(targetFile)) { const int VEHICLE_MODEL_OFFSET = 0x34; ICacheFile cacheFile = blamCacheFile.Get(); IEnumerable <ITag> vehicleTags = cacheFile.Tags.FindTagsByGroup("vehi"); StructureLayout layout = blamCacheFile.BuildInfo.Layouts.GetLayout("tag reference"); foreach (ITag vehicleTag in vehicleTags) { string name = cacheFile.FileNames.GetTagName(vehicleTag); //This is where in the memory region that the map exists a structure for the meta data exists long tagRefPointer = vehicleTag.MetaLocation.AsOffset() + VEHICLE_MODEL_OFFSET; blamCacheFile.Reader.SeekTo(tagRefPointer); StructureValueCollection collection = StructureReader.ReadStructure(blamCacheFile.Reader, layout); //Try to read it //Extract fields ulong groupMagic = collection.GetInteger("tag group magic"); DatumIndex datumIndex = new DatumIndex(collection.GetInteger("datum index")); //Is this a valid datum? bool isValid = cacheFile.Tags.IsValidIndex(datumIndex); ITag vehicleModelTag = cacheFile.Tags[datumIndex]; string vehicleModelName = cacheFile.FileNames.GetTagName(vehicleModelTag); string group = CharConstant.ToString(vehicleModelTag.Group.Magic); if (!TARGET_MODEL.Equals(vehicleModelName)) { continue; } tagRefPointer = vehicleModelTag.MetaLocation.AsOffset(); blamCacheFile.Reader.SeekTo(tagRefPointer); collection = StructureReader.ReadStructure(blamCacheFile.Reader, layout); groupMagic = collection.GetInteger("tag group magic"); datumIndex = new DatumIndex(collection.GetInteger("datum index")); isValid = cacheFile.Tags.IsValidIndex(datumIndex); ITag vehicleRenderModelTag = cacheFile.Tags[datumIndex]; string renderModelTagName = CharConstant.ToString(vehicleRenderModelTag.Group.Magic); BlamRenderModel warthogModel = new BlamRenderModel(vehicleRenderModelTag, blamCacheFile); } } Logger.LogReport("MapLoadUnitTest: Success!"); }
private List <ITag> LoadTags(IReader reader, uint tagTableOffset, int numTags, EngineDescription buildInfo, FileSegmentGroup metaArea) { StructureLayout layout = buildInfo.Layouts.GetLayout("tag element"); var result = new List <ITag>(); reader.SeekTo(tagTableOffset); for (int i = 0; i < numTags; i++) { StructureValueCollection values = StructureReader.ReadStructure(reader, layout); result.Add(new SecondGenTag(values, metaArea, _groupsById)); } return(result); }
private static List <ITagGroup> LoadGroups(IReader reader, uint groupTableOffset, int numGroups, EngineDescription buildInfo) { StructureLayout layout = buildInfo.Layouts.GetLayout("tag group element"); var result = new List <ITagGroup>(); reader.SeekTo(groupTableOffset); for (int i = 0; i < numGroups; i++) { StructureValueCollection values = StructureReader.ReadStructure(reader, layout); result.Add(new SecondGenTagGroup(values)); } return(result); }
private void Load(IReader reader) { reader.SeekTo(_scenario.MetaLocation.AsOffset()); var scenarioLayout = _buildInfo.Layouts.GetLayout("scnr"); var scenarioData = StructureReader.ReadStructure(reader, scenarioLayout); var count = (int)scenarioData.GetInteger("simulation definition table count"); var address = (uint)scenarioData.GetInteger("simulation definition table address"); long expand = _expander.Expand(address); var entryLayout = _buildInfo.Layouts.GetLayout("simulation definition table element"); _table = TagBlockReader.ReadTagBlock(reader, count, expand, entryLayout, _metaArea).Select((e) => _tags[new DatumIndex(e.GetInteger("datum index"))]).ToList(); }
private static List <ITagClass> ReadClasses(IReader reader, uint classTableOffset, int numClasses, EngineDescription buildInfo) { StructureLayout layout = buildInfo.Layouts.GetLayout("class entry"); var result = new List <ITagClass>(); reader.SeekTo(classTableOffset); for (int i = 0; i < numClasses; i++) { StructureValueCollection values = StructureReader.ReadStructure(reader, layout); result.Add(new SecondGenTagClass(values)); } return(result); }
private StructureValueCollection LoadHeader(IReader reader) { //if (_indexHeaderLocation == null) // return null; //reader.SeekTo(_indexHeaderLocation.AsOffset()); reader.SeekTo(0); StructureLayout headerLayout = _buildInfo.Layouts.GetLayout("tags_header"); StructureValueCollection result = StructureReader.ReadStructure(reader, headerLayout); //if (result.GetInteger("magic") != CharConstant.FromString("tags")) // throw new ArgumentException("Invalid index table header magic"); return(result); }