Example #1
0
        public bool Read(BinaryReader br, PatchHeader header)
        {
            if (br.BaseStream.Position == br.BaseStream.Length)
            {
                return(false);
            }

            byte entryCount = br.ReadByte();

            if (entryCount == 0)
            {
                return(false);
            }

            CKey             = new MD5Hash(br.ReadBytes(header.FileKeySize));
            DecompressedSize = br.ReadUInt40BE();

            Records = new List <PatchRecord>(entryCount);
            for (int i = 0; i < entryCount; i++)
            {
                var entry = new PatchRecord();
                entry.Read(br, header);
                Records.Add(entry);
            }

            return(true);
        }
Example #2
0
 public void Read(BinaryReader br, PatchHeader header)
 {
     EKey             = new MD5Hash(br.ReadBytes(header.FileKeySize));
     DecompressedSize = br.ReadUInt40BE();
     PatchEKey        = new MD5Hash(br.ReadBytes(header.PatchEKeySize));
     PatchSize        = br.ReadUInt32BE();
     Ordinal          = br.ReadByte();
 }
Example #3
0
        private void Read(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (!stream.CanRead || stream.Length <= 1)
            {
                throw new NotSupportedException($"Unable to read PatchFile stream");
            }

            using (var reader = new BinaryReader(stream))
            {
                PatchHeader.Read(reader);

                // read the patch entries
                int  pageSize = 1 << PatchHeader.PageSize;
                long length   = reader.BaseStream.Length;

                foreach (var offset in GetOffsets(reader))
                {
                    reader.BaseStream.Position = offset;

                    // buffer the page then read the entries to minimise file reads
                    using (var ms = new MemoryStream(reader.ReadBytes(pageSize)))
                        using (var br = new BinaryReader(ms))
                        {
                            var block = new PatchEntry();
                            while (block.Read(br, PatchHeader))
                            {
                                _PatchEntries[block.CKey] = block;
                                block = new PatchEntry();
                            }
                        }
                }

                #region Unknown Data

                // Unknown = br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position));

                /*
                 * // the following is unknown entries that comprise of:
                 * // a keysize byte followed by either a CKey or Ekey
                 * // the key type relevant size (decompressed/compressed)
                 * // and optionally an ESpec string
                 * // blocks are always a pair of 112 bytes then 160, Encoding Entry then Content Entry
                 * //
                 * // struct encodin_entry {
                 * //    char _unk0[4]; // always 0
                 * //    char KeySize;
                 * //    char Hash[KeySize];
                 * //    char _unk15[7];
                 * //    uint32_t some_offset;
                 * //
                 * //    // 0x44 CompressedSize;
                 * // }
                 * //
                 * // struct content_entry {
                 * //    char _unk0[4]; // always 0
                 * //    char KeySize;
                 * //    char Hash[KeySize];
                 * //    char _unk15[7];
                 * //    uint32_t some_offset;
                 * //
                 * //    // 0x34 DeompressedSize;
                 * //    // 0x6C partial ESpec   always ends in 0xA0
                 * // }
                 */
                #endregion

                Checksum = stream.MD5Hash();
            }
        }
Example #4
0
 /// <summary>
 /// Creates a new PatchFile
 /// </summary>
 public PatchFile()
 {
     PatchHeader   = new PatchHeader();
     _PatchEntries = new SortedList <MD5Hash, PatchEntry>(new MD5HashComparer());
 }