Beispiel #1
0
        public DdrPs2FileDataTableChunk GetBound(Stream stream)
        {
            var cache       = new CachedStream(stream);
            var cacheReader = new BinaryReader(cache);

            var entryCount = cacheReader.ReadInt32();
            var offsets    = Enumerable.Range(0, entryCount).Select(x => cacheReader.ReadInt32()).ToArray();
            var lengths    = Enumerable.Range(0, entryCount).Select(x => cacheReader.ReadInt32()).ToArray();
            var entries    = offsets.Select((e, i) => (Offset: e, Length: lengths[i])).OrderBy(x => x.Offset).ToArray();
            var max        = entries.Last().Use(x => x.Length + x.Offset);

            cache.Rewind();
            var snapshot = new SnapshotStream(cache);

            snapshot.TryRead(new byte[max], 0, max);
            return(new DdrPs2FileDataTableChunk
            {
                Data = snapshot.ToArray(),
                HasHeaders = false
            });
        }
Beispiel #2
0
        public DdrPs2FileDataTableChunk GetUnbound(Stream stream)
        {
            var cache       = new CachedStream(stream);
            var cacheReader = new BinaryReader(cache);

            using var snapshot = new SnapshotStream(cache);
            var snapshotReader = new BinaryReader(snapshot);
            var firstFile      = snapshotReader.ReadInt32();
            var tableSize      = firstFile / 4 * 4;
            var table          = Enumerable.Range(0, firstFile / 4).Select(_ => snapshotReader.ReadInt32()).ToArray();
            var skip           = firstFile - tableSize;
            int index;

            if (skip > 0)
            {
                snapshotReader.ReadBytes(skip);
            }

            for (index = 1; index < table.Length; index++)
            {
                if (table[index] < table[index - 1])
                {
                    break;
                }
            }

            // Warning: big heckin' hack.
            // We're looking for a TCB table, which puts headers on all the file entries.
            // There's no way to tell easily outside of this function, so...

            var prevPosition = cache.Position;

            cache.Position = table[0];
            var headTest0 = cacheReader.ReadInt32();
            var headTest1 = cacheReader.ReadInt32();
            var headTest2 = cacheReader.ReadInt32();

            var hasHeaders = headTest0 > 0 && headTest1 > 0 && headTest2 > 0 &&
                             headTest2 > headTest1 && headTest1 > headTest0 &&
                             (headTest0 & 0x3) == 0 &&
                             ((headTest0 | headTest1 | headTest2) >> 24) == 0;

            cache.Position = prevPosition;
            var desiredPosition = table[index - 1];

            snapshotReader.ReadBytes((int)(desiredPosition - prevPosition));

            if (hasHeaders)
            {
                snapshotReader.ReadBytes(0xC);
            }

            try
            {
                _bemaniLzDecoder.Decode(snapshot);
            }
            catch (Exception)
            {
                return(null);
            }

            return(new DdrPs2FileDataTableChunk
            {
                Data = snapshot.ToArray(),
                HasHeaders = hasHeaders
            });
        }