Example #1
0
 /// <summary>
 /// Instantiates a new instance of <see cref="CpkFileInfo"/>.
 /// </summary>
 /// <param name="obfuscated"></param>
 /// <param name="fileLength"></param>
 /// <param name="compressedLength"></param>
 public CpkFileInfo(Stream fileData, CpkRow row, bool obfuscated, long fileLength, long compressedLength)
 {
     _fileData        = fileData;
     Row              = row;
     Obfuscated       = obfuscated;
     FileLength       = fileLength;
     CompressedLength = compressedLength;
     Compressed       = FileLength != CompressedLength;
 }
Example #2
0
        /// <summary>
        /// Instantiates a new <see cref="CpkTable"/> from an input <see cref="Stream"/>.
        /// </summary>
        /// <param name="input"></param>
        public CpkTable(Stream input)
        {
            using (var br = new BinaryReaderX(input, true))
            {
                // Read in the table header.
                Header       = br.ReadType <CpkTableHeader>();
                br.ByteOrder = ByteOrder.BigEndian;

                // Handle obfuscated UTF table
                if (br.PeekString() != "@UTF")
                {
                    UtfObfuscation = true;

                    // Decrypt the UTF table
                    _tableStream = new BinaryReaderX(new MemoryStream(UtfTools.XorUtf(br.ReadBytes(Header.PacketSize))), true, ByteOrder.BigEndian);

                    // Read the table info.
                    TableInfo = _tableStream.ReadType <CpkTableInfo>();

                    // Replace the stream with a new SubStream into the decrypted data.
                    _tableStream = new BinaryReaderX(new SubStream(_tableStream.BaseStream, 0x8, TableInfo.TableSize), true, ByteOrder.BigEndian);
                }
                else
                {
                    // Read the table info.
                    TableInfo = br.ReadType <CpkTableInfo>();

                    // Create a sub stream of the entire table.
                    _tableStream = new BinaryReaderX(new SubStream(br.BaseStream, 0x18, TableInfo.TableSize), true, ByteOrder.BigEndian);
                }

                // Move forward to right after TableInfo
                _tableStream.BaseStream.Position += 0x18;

                // Make sure the data isn't bogus.
                if (Header.PacketSize - 0x8 != TableInfo.TableSize)
                {
                    throw new FormatException("The packet size doesn't match the table size. The file might be corrupt, encrypted or it is not a CPK.");
                }
                if (Header.PacketSize > 100 * 1024 * 1024)
                {
                    throw new FormatException("The packet size is too big. The file might be corrupt, encrypted or it is not a CPK.");
                }

                // Create sub streams for the string data and binary data.
                _stringStream = new BinaryReaderX(new SubStream(_tableStream.BaseStream, TableInfo.StringsOffset, TableInfo.TableSize - TableInfo.StringsOffset), true, ByteOrder.BigEndian);
                _binaryStream = new BinaryReaderX(new SubStream(_tableStream.BaseStream, TableInfo.BinaryOffset, TableInfo.TableSize - TableInfo.BinaryOffset), true, ByteOrder.BigEndian);

                // Read in the table name.
                Name = ReadString(TableInfo.NameOffset);

                // Read in the columns.
                var columns = new List <CpkColumnInfo>();
                for (var i = 0; i < TableInfo.ColumnCount; i++)
                {
                    var flags  = _tableStream.ReadByte();
                    var column = new CpkColumnInfo
                    {
                        Name    = ReadString(_tableStream.ReadInt32()),
                        Storage = (CpkColumnStorage)(flags & 0xF0),
                        Type    = (CpkDataType)(flags & 0x0F)
                    };
                    columns.Add(column);

                    if (column.Storage == CpkColumnStorage.Const)
                    {
                        column.Value = ReadValue(column.Type);
                    }
                    if (column.Storage == CpkColumnStorage.Zero)
                    {
                        column.Value = ZeroValue(column.Type);
                    }
                }
                Columns = columns;

                // Read in the values.
                _tableStream.BaseStream.Position = TableInfo.ValuesOffset;
                Rows = new List <CpkRow>();
                for (var i = 0; i < TableInfo.RowCount; i++)
                {
                    var row = new CpkRow(Columns);

                    foreach (var column in Columns)
                    {
                        if (column.Storage == CpkColumnStorage.Const || column.Storage == CpkColumnStorage.Zero)
                        {
                            row[column.Name].Value = column.Value.Value;
                        }
                        else if (column.Storage == CpkColumnStorage.Row)
                        {
                            row[column.Name].Value = ReadValue(column.Type).Value;
                        }
                    }

                    Rows.Add(row);
                }
            }
        }