private void Read(Stream stream) { // don't use using{}, we want to maintain the stream open. reader/writers will automatically close the stream when done in an using. var reader = new EndianReader(stream, EndianFormat.LittleEndian); stream.Position = 0; var addresses = new List <uint>(); var sizes = new List <uint>(); var dataContext = new DataSerializationContext(reader); var deserializer = new TagDeserializer(Version); Header = deserializer.Deserialize <ResourceCacheHaloOnlineHeader>(dataContext); reader.SeekTo(Header.ResourceTableOffset); // read all resource offsets if (Header.ResourceCount == 0) { return; } for (var i = 0; i < Header.ResourceCount; i++) { var address = reader.ReadUInt32(); if (!addresses.Contains(address) && (address != uint.MaxValue)) { addresses.Add(address); } Resources.Add(new Resource { Offset = address }); } // compute chunk sizes addresses.Sort((a, b) => a.CompareTo(b)); for (var i = 0; i < addresses.Count - 1; i++) { sizes.Add(addresses[i + 1] - addresses[i]); } sizes.Add(Header.ResourceTableOffset - addresses.Last()); foreach (var resource in Resources) { if (resource.Offset == uint.MaxValue) { continue; } resource.ChunkSize = sizes[addresses.IndexOf(resource.Offset)]; } }
public ResourceCacheHaloOnline(CacheVersion version) { Version = version; Resources = new List <Resource>(); Header = new ResourceCacheHaloOnlineHeader { ResourceTableOffset = 0x20, CreationTime = 0x01D0631BCC92931B }; }
private void CreateEmptyResourceCache(Stream stream) { Header = new ResourceCacheHaloOnlineHeader { ResourceTableOffset = 0x20, CreationTime = 0x01D0631BCC92931B }; stream.Position = 0; var writer = new EndianWriter(stream, EndianFormat.LittleEndian); var dataContext = new DataSerializationContext(writer); var serializer = new TagSerializer(CacheVersion.HaloOnline106708); serializer.Serialize(dataContext, Header); stream.Position = 0; }