Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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());
        }