private CacheHeader(Stream stream) { using (var binaryReader = new BinaryReader(stream, Encoding.Default, true)) { // read the fourcc tag and throw on incorrect value HeadFourCC = binaryReader.ReadTagClass(); if (HeadFourCC != (TagClass)"head") { throw new InvalidDataException(); } EngineVersion = binaryReader.ReadInt32(); FileSize = binaryReader.ReadInt32(); stream.Seek(4, SeekOrigin.Current); // Check the BuildVersion then return to the last stream position stream.Seek(0x11C, SeekOrigin.Current); var test = Encoding.ASCII.GetString(binaryReader.ReadBytes(32)).Trim(Char.MinValue); Version = test == @"11081.07.04.30.0934.main" ? HaloVersion.PC_RETAIL : HaloVersion.XBOX_RETAIL; stream.Seek(-0x13C, SeekOrigin.Current); IndexInfo = IndexInfoStruct.DeserializeFrom(stream); // move the stream past some unused/zeroed bytes if (Version == HaloVersion.PC_RETAIL) { SharedInfoStruct.DeserializeFrom(stream); } stream.Seek(32 + 224, SeekOrigin.Current); // read the build string and remove the trailing null bytes BuildString = Encoding.ASCII.GetString(binaryReader.ReadBytes(32)).Trim(Char.MinValue); // read the map type (ie: singleplayer, multiplayer, shared, singleplayershared, mainmenu). Type = (MapType)binaryReader.ReadInt32(); stream.Seek(28, SeekOrigin.Current); StringsInfo = StringsInfoStruct.DeserializeFrom(stream); stream.Seek(36, SeekOrigin.Current); // read the name string and remove the trailing null bytes Name = Encoding.ASCII.GetString(binaryReader.ReadBytes(32)).Trim(Char.MinValue); stream.Seek(4, SeekOrigin.Current); // read the scenario string and remove the trailing null bytes Scenario = Encoding.ASCII.GetString(binaryReader.ReadBytes(128)).Trim(Char.MinValue); stream.Seek(128, SeekOrigin.Current); stream.Seek(4, SeekOrigin.Current); PathsInfo = PathsInfoStruct.DeserializeFrom(stream); if (Version == HaloVersion.PC_RETAIL) { UnknownInfo = UnknownInfoStruct.DeserializeFrom(stream); } Checksum = binaryReader.ReadInt32(); // seek the last 4 bytes before the end of the header stream.Seek(2044 - (int)stream.Position, SeekOrigin.Current); FootFourCC = binaryReader.ReadTagClass(); } }
private StringsInfoStruct GenerateStringsTable(Stream outputStream) { var info = new StringsInfoStruct { StringCount = Strings.Length, Strings128TableAddress = outputStream.Align(512) }; GenerateStrings128(outputStream); info.StringIndexAddress = outputStream.Align(512); GenerateTableIndex(outputStream, Strings); info.StringTableAddress = outputStream.Align(512); GenerateStringEntries(outputStream, Strings); info.StringTableLength = ( int )outputStream.Position - info.StringTableAddress; outputStream.Align(512); return(info); }