Ejemplo n.º 1
0
        /// <summary>
        ///     Initialize table with decryption constants
        /// </summary>
        /// <param name="data"></param>
        /// <param name="game"></param>
        /// <param name="flags"></param>
        /// <param name="truth"></param>
        /// <param name="multiplier"></param>
        /// <param name="divisor"></param>
        public PKGTBL(Span <byte> data, string game, IDTableFlags flags, byte[] truth, ulong multiplier, ulong divisor)
        {
            if (flags != IDTableFlags.None)
            {
                var size = BinaryPrimitives.ReadUInt32LittleEndian(data);
                data = Read(data.Slice(4), game, (uint)data.Length - 4, size, flags, truth, multiplier, divisor);
            }

            Buffer = new Memory <byte>(data.ToArray());
            if (data.GetDataType() == DataType.PackageInfo)
            {
                PackageInfo = new PKGINFO(data);
                // There's extra shit that I can't parse yet because the format is highly dependent on arbitrary values.
                Header = new IDTableHeader
                {
                    Offset = PackageInfo.Resource.Pointers[1] + PackageInfo.InfoTable.Header.TextPointer + SizeHelper.SizeOf <BTIFHeader>()
                };
                Entries = PackageInfo.InfoTable.Entries.Select(x => new IDTableEntry
                {
                    PathOffset         = x.NameOffset,
                    OriginalPathOffset = -1,
                    Flags            = x.Flags,
                    UniqueId         = x.Checksum,
                    CompressedSize   = x.CompressedSize,
                    DecompressedSize = x.DecompressedSize,
                    Padding1         = PackageInfo.InfoTable.UnknownBuffer[x.UnknownIndex],
                    Padding2         = PackageInfo.InfoTable.UnknownBuffer[x.UnknownIndex + 1]
                }).ToArray();
            }
            else
            {
                Header  = MemoryMarshal.Read <IDTableHeader>(data);
                Entries = MemoryMarshal.Cast <byte, IDTableEntry>(data.Slice(Header.Offset, Header.Count * SizeHelper.SizeOf <IDTableEntry>())).ToArray();
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Read a file with decryption constants
        /// </summary>
        /// <param name="file"></param>
        /// <param name="game"></param>
        /// <param name="compressedSize"></param>
        /// <param name="size"></param>
        /// <param name="flags"></param>
        /// <param name="truth"></param>
        /// <param name="multiplier"></param>
        /// <param name="divisor"></param>
        /// <returns></returns>
        public static Span <byte> Read(Span <byte> file, string game, uint compressedSize, uint size, IDTableFlags flags, byte[] truth, ulong multiplier, ulong divisor)
        {
            if (compressedSize > file.Length)
            {
                Logger.Warn("PKGINFO", "Compressed Size is larger than actual file! The package info might have drifted from the saved files. Please verify game data!");
            }

            if (game == "VenusVacation" && file.IsKnown())
            {
                return(file);
            }

            if (flags.HasFlag(IDTableFlags.Encrypted) && (game != "VenusVacation" || flags.HasFlag(IDTableFlags.Compressed)))
            {
                var key = XOREncryption.Xor(size, truth, multiplier, divisor);
                file = XOREncryption.Crypt(file, key);
            }

            // ReSharper disable once InvertIf
            if (flags.HasFlag(IDTableFlags.Compressed) && file[4] == 0x78)
            {
                try
                {
                    var decompressedData = Stream8000Compression.Decompress(file, new CompressionOptions {
                        Length = size
                    });
                    if (decompressedData.Length != 0)
                    {
                        file = decompressedData;
                    }
                }
                catch (Exception e)
                {
                    Logger.Error("PKGINFO", e);
                }
            }

            return(file);
        }