public GMAHeader ReadHeader() { BaseStream.Seek(0, SeekOrigin.Begin); // Magic constant "GMAD" byte[] magicConstant = ReadBytes(4); if (Encoding.ASCII.GetString(magicConstant) != "GMAD") { throw new Exception("Invalid file type"); } byte gmaVersion = ReadByte(); if (gmaVersion > 3) { throw new Exception("Unsupported GMA version " + gmaVersion); } GMAHeader header = new GMAHeader { SteamID = ReadUInt64(), Timestamp = ReadInt64(), RequiredContent = ReadNullTerminatedString(), Name = ReadNullTerminatedString(), Description = ReadNullTerminatedString(), Author = ReadNullTerminatedString(), Version = ReadInt32() }; List <GMAFileHeader> files = new List <GMAFileHeader>(); long curOffset = 0; while (ReadUInt32() > 0) { GMAFileHeader curFile = new GMAFileHeader { Path = ReadNullTerminatedString(), Size = ReadInt64(), CRC = ReadUInt32(), FileNumber = files.Count, Offset = curOffset }; curOffset += curFile.Size; files.Add(curFile); } header.DataStart = BaseStream.Position; header.Files = files.ToArray(); return(header); }
public byte[] GetFileData(int fileNumber) { if (_fileDataCache.ContainsKey(fileNumber)) { return(_fileDataCache[fileNumber]); } GMAFileHeader file = Files.Single(f => f.FileNumber == fileNumber); _reader.BaseStream.Seek(_header.DataStart + file.Offset, SeekOrigin.Begin); byte[] data = _reader.ReadBytes((int)file.Size); uint computedCRC = CRC32(data); if (file.CRC != computedCRC) { throw new CRCMismatchException($"CRC mismatch for {file.Path}"); } _fileDataCache[fileNumber] = data; return(data); }
public GMAFileHeader[] GetModelFiles(GMAFileHeader model) { string path = model.Path.Substring(0, model.Path.Length - 4); return(Files.Where(f => f.Path.StartsWith(path, StringComparison.InvariantCultureIgnoreCase)).ToArray()); }