Example #1
0
        public byte[] DecompressLegacyCRI(byte[] input, int USize)
        {
            byte[] result;// = new byte[USize];

            MemoryStream ms = new MemoryStream(input);
            EndianReader br = new EndianReader(ms, true);

            br.BaseStream.Seek(8, SeekOrigin.Begin); // Skip CRILAYLA
            int uncompressed_size          = br.ReadInt32();
            int uncompressed_header_offset = br.ReadInt32();

            result = new byte[uncompressed_size + 0x100];

            // do some error checks here.........

            // copy uncompressed 0x100 header to start of file
            Array.Copy(input, uncompressed_header_offset + 0x10, result, 0, 0x100);

            int  input_end = input.Length - 0x100 - 1;
            int  input_offset = input_end;
            int  output_end = 0x100 + uncompressed_size - 1;
            byte bit_pool = 0;
            int  bits_left = 0, bytes_output = 0;

            int[] vle_lens = new int[4] {
                2, 3, 5, 8
            };

            while (bytes_output < uncompressed_size)
            {
                if (get_next_bits(input, ref input_offset, ref bit_pool, ref bits_left, 1) > 0)
                {
                    int backreference_offset = output_end - bytes_output + get_next_bits(input, ref input_offset, ref bit_pool, ref bits_left, 13) + 3;
                    int backreference_length = 3;
                    int vle_level;

                    for (vle_level = 0; vle_level < vle_lens.Length; vle_level++)
                    {
                        int this_level = get_next_bits(input, ref input_offset, ref bit_pool, ref bits_left, vle_lens[vle_level]);
                        backreference_length += this_level;
                        if (this_level != ((1 << vle_lens[vle_level]) - 1))
                        {
                            break;
                        }
                    }

                    if (vle_level == vle_lens.Length)
                    {
                        int this_level;
                        do
                        {
                            this_level            = get_next_bits(input, ref input_offset, ref bit_pool, ref bits_left, 8);
                            backreference_length += this_level;
                        } while (this_level == 255);
                    }

                    for (int i = 0; i < backreference_length; i++)
                    {
                        result[output_end - bytes_output] = result[backreference_offset--];
                        bytes_output++;
                    }
                }
                else
                {
                    // verbatim byte
                    result[output_end - bytes_output] = (byte)get_next_bits(input, ref input_offset, ref bit_pool, ref bits_left, 8);
                    bytes_output++;
                }
            }

            br.Close();
            ms.Close();

            return(result);
        }
Example #2
0
        /// <summary>
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public bool ReadUtf(EndianReader reader)
        {
            var offset = reader.BaseStream.Position + 8;

            if (Tools.ReadCString(reader, 4) != "@UTF")
            {
                return(false);
            }

            Columns        = new List <Column>();
            TableSize      = reader.ReadInt32();
            RowsOffset     = reader.ReadInt32();
            StringsOffset  = reader.ReadInt32();
            DataOffset     = reader.ReadInt32();
            DataOffset    += offset;
            RowsOffset    += offset;
            StringsOffset += offset;
            TableName      = reader.ReadInt32();
            ColumnCount    = reader.ReadInt16();
            RowLength      = reader.ReadInt16();
            RowCount       = reader.ReadInt32();

            for (var position = 0; position < ColumnCount; position++)
            {
                var column = new Column
                {
                    Flags = reader.ReadByte()
                };

                if (column.Flags == 0)
                {
                    reader.BaseStream.Seek(3, SeekOrigin.Current);
                    column.Flags = reader.ReadByte();
                }

                column.Name = Tools.ReadCString(reader, -1, reader.ReadInt32() + StringsOffset);
                Columns.Add(column);
            }

            Rows = new List <List <Row> >();

            for (var rowIndex = 0; rowIndex < RowCount; rowIndex++)
            {
                reader.BaseStream.Seek(RowsOffset + rowIndex * RowLength, SeekOrigin.Begin);

                var entries = new List <Row>();

                for (var columnIndex = 0; columnIndex < ColumnCount; columnIndex++)
                {
                    var row = new Row();

                    switch ((ColumnFlags)Columns[columnIndex].Flags & ColumnFlags.StorageMask)
                    {
                    case ColumnFlags.StorageNone:
                        entries.Add(row);
                        continue;

                    case ColumnFlags.StorageZero:
                        entries.Add(row);
                        continue;

                    case ColumnFlags.StorageConstant:
                        entries.Add(row);
                        continue;
                    }

                    row.Position = reader.BaseStream.Position;
                    row.Type     = Columns[columnIndex].Flags & (int)ColumnFlags.TypeMask;

                    switch (row.Type)
                    {
                    case 0x00:
                    case 0x01:
                        row.Uint8 = reader.ReadByte();
                        break;

                    case 0x02:
                    case 0x03:
                        row.Uint16 = reader.ReadUInt16();
                        break;

                    case 0x04:
                    case 0x05:
                        row.Uint32 = reader.ReadUInt32();
                        break;

                    case 0x06:
                    case 0x07:
                        row.Uint64 = reader.ReadUInt64();
                        break;

                    case 0x08:
                        row.Ufloat = reader.ReadSingle();
                        break;

                    case 0x0A:
                        row.Str = Tools.ReadCString(reader, -1, reader.ReadInt32() + StringsOffset);
                        break;

                    case 0x0B:
                        row.Position = reader.ReadInt32() + DataOffset;
                        row.Data     = Tools.GetData(reader, row.Position, reader.ReadInt32());
                        break;

                    default:
                        continue;
                    }

                    entries.Add(row);
                }

                Rows.Add(entries);
            }

            return(true);
        }
Example #3
0
        public bool ReadCPK(string sPath)
        {
            if (File.Exists(sPath))
            {
                uint   Files;
                ushort Align;

                EndianReader br = new EndianReader(File.OpenRead(sPath), true);
                MemoryStream ms;
                EndianReader utfr;

                if (tools.ReadCString(br, 4) != "CPK ")
                {
                    br.Close();
                    return(false);
                }

                ReadUTFData(br);

                CPK_packet = utf_packet;

                FileEntry CPAK_entry = new FileEntry
                {
                    FileName      = "CPK_HDR",
                    FileOffsetPos = br.BaseStream.Position + 0x10,
                    FileSize      = CPK_packet.Length,
                    Encrypted     = isUtfEncrypted,
                    FileType      = "CPK"
                };

                FileTable.Add(CPAK_entry);

                ms   = new MemoryStream(utf_packet);
                utfr = new EndianReader(ms, false);

                utf = new UTF(tools);
                if (!utf.ReadUTF(utfr))
                {
                    br.Close();
                    return(false);
                }

                utfr.Close();
                ms.Close();

                cpkdata = new Dictionary <string, object>();

                try
                {
                    for (int i = 0; i < utf.columns.Count; i++)
                    {
                        cpkdata.Add(utf.columns[i].name, utf.rows[0].rows[i].GetValue());
                    }
                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.ToString());
                    Console.WriteLine(ex.ToString());
                }

                TocOffset = (ulong)GetColumsData2(utf, 0, "TocOffset", 3);
                long TocOffsetPos = GetColumnPostion(utf, 0, "TocOffset");

                EtocOffset = (ulong)GetColumsData2(utf, 0, "EtocOffset", 3);
                long ETocOffsetPos = GetColumnPostion(utf, 0, "EtocOffset");

                ItocOffset = (ulong)GetColumsData2(utf, 0, "ItocOffset", 3);
                long ITocOffsetPos = GetColumnPostion(utf, 0, "ItocOffset");

                GtocOffset = (ulong)GetColumsData2(utf, 0, "GtocOffset", 3);
                long GTocOffsetPos = GetColumnPostion(utf, 0, "GtocOffset");

                ContentOffset = (ulong)GetColumsData2(utf, 0, "ContentOffset", 3);
                long ContentOffsetPos = GetColumnPostion(utf, 0, "ContentOffset");
                FileTable.Add(CreateFileEntry("CONTENT_OFFSET", ContentOffset, typeof(ulong), ContentOffsetPos, "CPK", "CONTENT", false));

                Files = (uint)GetColumsData2(utf, 0, "Files", 2);
                Align = (ushort)GetColumsData2(utf, 0, "Align", 1);

                if (TocOffset != 0xFFFFFFFFFFFFFFFF)
                {
                    FileEntry entry = CreateFileEntry("TOC_HDR", TocOffset, typeof(ulong), TocOffsetPos, "CPK", "HDR", false);
                    FileTable.Add(entry);

                    if (!ReadTOC(br, TocOffset, ContentOffset))
                    {
                        return(false);
                    }
                }

                if (EtocOffset != 0xFFFFFFFFFFFFFFFF)
                {
                    FileEntry entry = CreateFileEntry("ETOC_HDR", EtocOffset, typeof(ulong), ETocOffsetPos, "CPK", "HDR", false);
                    FileTable.Add(entry);

                    if (!ReadETOC(br, EtocOffset))
                    {
                        return(false);
                    }
                }

                if (ItocOffset != 0xFFFFFFFFFFFFFFFF)
                {
                    //FileEntry ITOC_entry = new FileEntry {
                    //    FileName = "ITOC_HDR",
                    //    FileOffset = ItocOffset, FileOffsetType = typeof(ulong), FileOffsetPos = ITocOffsetPos,
                    //    TOCName = "CPK",
                    //    FileType = "FILE", Encrypted = true,
                    //};

                    FileEntry entry = CreateFileEntry("ITOC_HDR", ItocOffset, typeof(ulong), ITocOffsetPos, "CPK", "HDR", false);
                    FileTable.Add(entry);

                    if (!ReadITOC(br, ItocOffset, ContentOffset, Align))
                    {
                        return(false);
                    }
                }

                if (GtocOffset != 0xFFFFFFFFFFFFFFFF)
                {
                    FileEntry entry = CreateFileEntry("GTOC_HDR", GtocOffset, typeof(ulong), GTocOffsetPos, "CPK", "HDR", false);
                    FileTable.Add(entry);

                    if (!ReadGTOC(br, GtocOffset))
                    {
                        return(false);
                    }
                }

                br.Close();

                // at this point, we should have all needed file info

                //utf = null;
                files = null;
                return(true);
            }
            return(false);
        }
Example #4
0
        public bool ReadITOC(EndianReader br, ulong startoffset, ulong ContentOffset, ushort Align)
        {
            br.BaseStream.Seek((long)startoffset, SeekOrigin.Begin);

            if (tools.ReadCString(br, 4) != "ITOC")
            {
                br.Close();
                return(false);
            }

            ReadUTFData(br);

            ITOC_packet = utf_packet;

            FileEntry itoc_entry = FileTable.Where(x => x.FileName.ToString() == "ITOC_HDR").Single();

            itoc_entry.Encrypted = isUtfEncrypted;
            itoc_entry.FileSize  = ITOC_packet.Length;

            MemoryStream ms   = new MemoryStream(utf_packet);
            EndianReader utfr = new EndianReader(ms, false);

            files = new UTF(tools);
            if (!files.ReadUTF(utfr))
            {
                br.Close();
                return(false);
            }

            utfr.Close();
            ms.Close();

            //uint FilesL = (uint)GetColumnData(files, 0, "FilesL");
            //uint FilesH = (uint)GetColumnData(files, 0, "FilesH");
            byte[] DataL    = (byte[])GetColumnData(files, 0, "DataL");
            long   DataLPos = GetColumnPostion(files, 0, "DataL");

            byte[] DataH    = (byte[])GetColumnData(files, 0, "DataH");
            long   DataHPos = GetColumnPostion(files, 0, "DataH");

            //MemoryStream ms;
            //EndianReader ir;
            UTF utfDataL, utfDataH;
            Dictionary <int, uint> SizeTable, CSizeTable;
            Dictionary <int, long> SizePosTable, CSizePosTable;
            Dictionary <int, Type> SizeTypeTable, CSizeTypeTable;

            List <int> IDs = new List <int>();

            SizeTable     = new Dictionary <int, uint>();
            SizePosTable  = new Dictionary <int, long>();
            SizeTypeTable = new Dictionary <int, Type>();

            CSizeTable     = new Dictionary <int, uint>();
            CSizePosTable  = new Dictionary <int, long>();
            CSizeTypeTable = new Dictionary <int, Type>();

            ushort ID, size1;
            uint   size2;
            long   pos;
            Type   type;

            if (DataL != null)
            {
                ms       = new MemoryStream(DataL);
                utfr     = new EndianReader(ms, false);
                utfDataL = new UTF(tools);
                utfDataL.ReadUTF(utfr);

                for (int i = 0; i < utfDataL.num_rows; i++)
                {
                    ID    = (ushort)GetColumnData(utfDataL, i, "ID");
                    size1 = (ushort)GetColumnData(utfDataL, i, "FileSize");
                    SizeTable.Add((int)ID, (uint)size1);

                    pos = GetColumnPostion(utfDataL, i, "FileSize");
                    SizePosTable.Add((int)ID, pos + DataLPos);

                    type = GetColumnType(utfDataL, i, "FileSize");
                    SizeTypeTable.Add((int)ID, type);

                    if ((GetColumnData(utfDataL, i, "ExtractSize")) != null)
                    {
                        size1 = (ushort)GetColumnData(utfDataL, i, "ExtractSize");
                        CSizeTable.Add((int)ID, (uint)size1);

                        pos = GetColumnPostion(utfDataL, i, "ExtractSize");
                        CSizePosTable.Add((int)ID, pos + DataLPos);

                        type = GetColumnType(utfDataL, i, "ExtractSize");
                        CSizeTypeTable.Add((int)ID, type);
                    }

                    IDs.Add(ID);
                }
            }

            if (DataH != null)
            {
                ms       = new MemoryStream(DataH);
                utfr     = new EndianReader(ms, false);
                utfDataH = new UTF(tools);
                utfDataH.ReadUTF(utfr);

                for (int i = 0; i < utfDataH.num_rows; i++)
                {
                    ID    = (ushort)GetColumnData(utfDataH, i, "ID");
                    size2 = (uint)GetColumnData(utfDataH, i, "FileSize");
                    SizeTable.Add(ID, size2);

                    pos = GetColumnPostion(utfDataH, i, "FileSize");
                    SizePosTable.Add((int)ID, pos + DataHPos);

                    type = GetColumnType(utfDataH, i, "FileSize");
                    SizeTypeTable.Add((int)ID, type);

                    if ((GetColumnData(utfDataH, i, "ExtractSize")) != null)
                    {
                        size2 = (uint)GetColumnData(utfDataH, i, "ExtractSize");
                        CSizeTable.Add(ID, size2);

                        pos = GetColumnPostion(utfDataH, i, "ExtractSize");
                        CSizePosTable.Add((int)ID, pos + DataHPos);

                        type = GetColumnType(utfDataH, i, "ExtractSize");
                        CSizeTypeTable.Add((int)ID, type);
                    }

                    IDs.Add(ID);
                }
            }

            FileEntry temp;
            //int id = 0;
            uint  value = 0, value2 = 0;
            ulong baseoffset = ContentOffset;

            // Seems ITOC can mix up the IDs..... but they'll alwaysy be in order...
            IDs = IDs.OrderBy(x => x).ToList();


            for (int i = 0; i < IDs.Count; i++)
            {
                int id = IDs[i];

                temp = new FileEntry();
                SizeTable.TryGetValue(id, out value);
                CSizeTable.TryGetValue(id, out value2);

                temp.TOCName = "ITOC";

                temp.DirName  = null;
                temp.FileName = id.ToString() + ".bin";

                temp.FileSize     = value;
                temp.FileSizePos  = SizePosTable[id];
                temp.FileSizeType = SizeTypeTable[id];

                if (CSizeTable.Count > 0 && CSizeTable.ContainsKey(id))
                {
                    temp.ExtractSize     = value2;
                    temp.ExtractSizePos  = CSizePosTable[id];
                    temp.ExtractSizeType = CSizeTypeTable[id];
                }

                temp.FileType = "FILE";


                temp.FileOffset = baseoffset;
                temp.ID         = id;
                temp.UserString = null;

                FileTable.Add(temp);

                if ((value % Align) > 0)
                {
                    baseoffset += value + (Align - (value % Align));
                }
                else
                {
                    baseoffset += value;
                }


                //id++;
            }

            files    = null;
            utfDataL = null;
            utfDataH = null;

            ms.Close();
            utfr.Close();


            return(true);
        }
Example #5
0
        public bool ReadUTF(EndianReader br)
        {
            long offset = br.BaseStream.Position;

            if (tools.ReadCString(br, 4) != "@UTF")
            {
                return(false);
            }

            table_size     = br.ReadInt32();
            rows_offset    = br.ReadInt32();
            strings_offset = br.ReadInt32();
            data_offset    = br.ReadInt32();

            // CPK Header & UTF Header are ignored, so add 8 to each offset
            rows_offset    += (offset + 8);
            strings_offset += (offset + 8);
            data_offset    += (offset + 8);

            table_name  = br.ReadInt32();
            num_columns = br.ReadInt16();
            row_length  = br.ReadInt16();
            num_rows    = br.ReadInt32();

            //read Columns
            columns = new List <COLUMN>();
            COLUMN column;

            for (int i = 0; i < num_columns; i++)
            {
                column       = new COLUMN();
                column.flags = br.ReadByte();
                if (column.flags == 0)
                {
                    br.BaseStream.Seek(3, SeekOrigin.Current);
                    column.flags = br.ReadByte();
                }

                column.name = tools.ReadCString(br, -1, (long)(br.ReadInt32() + strings_offset));
                columns.Add(column);
            }

            //read Rows

            rows = new List <ROWS>();
            ROWS current_entry;
            ROW  current_row;
            int  storage_flag;

            for (int j = 0; j < num_rows; j++)
            {
                br.BaseStream.Seek(rows_offset + (j * row_length), SeekOrigin.Begin);

                current_entry = new ROWS();

                for (int i = 0; i < num_columns; i++)
                {
                    current_row = new ROW();

                    storage_flag = (columns[i].flags & (int)COLUMN_FLAGS.STORAGE_MASK);

                    if (storage_flag == (int)COLUMN_FLAGS.STORAGE_NONE) // 0x00
                    {
                        current_entry.rows.Add(current_row);
                        continue;
                    }

                    if (storage_flag == (int)COLUMN_FLAGS.STORAGE_ZERO) // 0x10
                    {
                        current_entry.rows.Add(current_row);
                        continue;
                    }

                    if (storage_flag == (int)COLUMN_FLAGS.STORAGE_CONSTANT) // 0x30
                    {
                        current_entry.rows.Add(current_row);
                        continue;
                    }

                    // 0x50

                    current_row.type = columns[i].flags & (int)COLUMN_FLAGS.TYPE_MASK;

                    current_row.position = br.BaseStream.Position;

                    switch (current_row.type)
                    {
                    case 0:
                    case 1:
                        current_row.uint8 = br.ReadByte();
                        break;

                    case 2:
                    case 3:
                        current_row.uint16 = br.ReadUInt16();
                        break;

                    case 4:
                    case 5:
                        current_row.uint32 = br.ReadUInt32();
                        break;

                    case 6:
                    case 7:
                        current_row.uint64 = br.ReadUInt64();
                        break;

                    case 8:
                        current_row.ufloat = br.ReadSingle();
                        break;

                    case 0xA:
                        current_row.str = tools.ReadCString(br, -1, br.ReadInt32() + strings_offset);
                        break;

                    case 0xB:
                        long position = br.ReadInt32() + data_offset;
                        current_row.position = position;
                        current_row.data     = tools.GetData(br, position, br.ReadInt32());
                        break;

                    default: throw new NotImplementedException();
                    }


                    current_entry.rows.Add(current_row);
                }

                rows.Add(current_entry);
            }

            return(true);
        }
Example #6
0
        public bool ReadTOC(EndianReader br, ulong TocOffset, ulong ContentOffset)
        {
            ulong fTocOffset = TocOffset;
            ulong add_offset = 0;

            if (fTocOffset > (ulong)0x800)
            {
                fTocOffset = (ulong)0x800;
            }


            if (ContentOffset < 0)
            {
                add_offset = fTocOffset;
            }
            else
            {
                if (TocOffset < 0)
                {
                    add_offset = ContentOffset;
                }
                else
                {
                    if (ContentOffset < fTocOffset)
                    {
                        add_offset = ContentOffset;
                    }
                    else
                    {
                        add_offset = fTocOffset;
                    }
                }
            }

            br.BaseStream.Seek((long)TocOffset, SeekOrigin.Begin);

            if (tools.ReadCString(br, 4) != "TOC ")
            {
                br.Close();
                return(false);
            }

            ReadUTFData(br);

            // Store unencrypted TOC
            TOC_packet = utf_packet;

            FileEntry toc_entry = FileTable.Where(x => x.FileName.ToString() == "TOC_HDR").Single();

            toc_entry.Encrypted = isUtfEncrypted;
            toc_entry.FileSize  = TOC_packet.Length;

            MemoryStream ms   = new MemoryStream(utf_packet);
            EndianReader utfr = new EndianReader(ms, false);

            files = new UTF(tools);
            if (!files.ReadUTF(utfr))
            {
                br.Close();
                return(false);
            }

            utfr.Close();
            ms.Close();

            FileEntry temp;

            for (int i = 0; i < files.num_rows; i++)
            {
                temp = new FileEntry();

                temp.TOCName = "TOC";

                temp.DirName  = GetColumnData(files, i, "DirName");
                temp.FileName = GetColumnData(files, i, "FileName");

                temp.FileSize     = GetColumnData(files, i, "FileSize");
                temp.FileSizePos  = GetColumnPostion(files, i, "FileSize");
                temp.FileSizeType = GetColumnType(files, i, "FileSize");

                temp.ExtractSize     = GetColumnData(files, i, "ExtractSize");
                temp.ExtractSizePos  = GetColumnPostion(files, i, "ExtractSize");
                temp.ExtractSizeType = GetColumnType(files, i, "ExtractSize");

                temp.FileOffset     = ((ulong)GetColumnData(files, i, "FileOffset") + (ulong)add_offset);
                temp.FileOffsetPos  = GetColumnPostion(files, i, "FileOffset");
                temp.FileOffsetType = GetColumnType(files, i, "FileOffset");

                temp.FileType = "FILE";

                temp.Offset = add_offset;

                temp.ID         = GetColumnData(files, i, "ID");
                temp.UserString = GetColumnData(files, i, "UserString");

                FileTable.Add(temp);
            }
            files = null;

            return(true);
        }
Example #7
0
        /// <summary>
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public byte[] DecompressCrilayla(byte[] buffer, int length)
        {
            var stream       = new MemoryStream(buffer);
            var endianReader = new EndianReader(stream, true);

            endianReader.BaseStream.Seek(8, SeekOrigin.Begin);

            var uncompressedLength       = endianReader.ReadInt32();
            var uncompressedHeaderOffset = endianReader.ReadInt32();
            var result = new byte[uncompressedLength + 0x100];

            Array.Copy(buffer, uncompressedHeaderOffset + 0x10, result, 0, 0x100);

            var  bitsLeft    = 0;
            var  bytesOutput = 0;
            var  inputEnd    = buffer.Length - 0x100 - 1;
            var  inputOffset = inputEnd;
            var  outputEnd   = 0x100 + uncompressedLength - 1;
            byte bitPool     = 0;

            var vleLens = new[] { 2, 3, 5, 8 };

            while (bytesOutput < uncompressedLength)
            {
                if (RetrieveNextBits(buffer, ref inputOffset, ref bitPool, ref bitsLeft, 1) > 0)
                {
                    var backreferenceOffset = outputEnd - bytesOutput + RetrieveNextBits(buffer, ref inputOffset, ref bitPool, ref bitsLeft, 13) + 3;
                    var backreferenceLength = 3;

                    int vleLevel;

                    for (vleLevel = 0; vleLevel < vleLens.Length; vleLevel++)
                    {
                        int thisLevel = RetrieveNextBits(buffer, ref inputOffset, ref bitPool, ref bitsLeft, vleLens[vleLevel]);

                        backreferenceLength += thisLevel;

                        if (thisLevel != (1 << vleLens[vleLevel]) - 1)
                        {
                            break;
                        }
                    }

                    if (vleLevel == vleLens.Length)
                    {
                        int thisLevel;

                        do
                        {
                            thisLevel            = RetrieveNextBits(buffer, ref inputOffset, ref bitPool, ref bitsLeft, 8);
                            backreferenceLength += thisLevel;
                        } while (thisLevel == 255);
                    }

                    for (var index = 0; index < backreferenceLength; index++)
                    {
                        result[outputEnd - bytesOutput] = result[backreferenceOffset--];
                        bytesOutput++;
                    }
                }
                else
                {
                    result[outputEnd - bytesOutput] = (byte)RetrieveNextBits(buffer, ref inputOffset, ref bitPool, ref bitsLeft, 8);
                    bytesOutput++;
                }
            }

            endianReader.Close();
            stream.Close();

            return(result);
        }
Example #8
0
        /// <summary>
        /// </summary>
        /// <param name="cpkFilename"></param>
        public Cpk(string cpkFilename)
        {
            IsUtfEncrypted = false;

            if (!File.Exists(cpkFilename))
            {
                throw new FileNotFoundException(cpkFilename);
            }

            var reader = new EndianReader(File.OpenRead(cpkFilename), true);

            if (Tools.ReadCString(reader, 4) != "CPK ")
            {
                reader.Close();
                throw new Exception();
            }

            Utf = new Utf();
            ReadUtfData(reader);
            CpkPacket = UtfPacket;

            var cpakEntry = new FileEntry
            {
                FileType           = "CPK",
                FileName           = "CPK_HDR",
                Encrypted          = IsUtfEncrypted,
                FileSize           = CpkPacket.Length,
                FileOffsetPosition = reader.BaseStream.Position + 0x10
            };

            FileTable = new List <FileEntry>
            {
                cpakEntry
            };

            using (var stream = new MemoryStream(UtfPacket))
                using (var utfReader = new EndianReader(stream, false))
                {
                    if (!Utf.ReadUtf(utfReader))
                    {
                        reader.Close();
                        throw new Exception();
                    }
                }

            CpkData = new Dictionary <string, object>();

            for (var columnIndex = 0; columnIndex < Utf.Columns.Count; columnIndex++)
            {
                CpkData.Add(Utf.Columns[columnIndex].Name, Utf.Rows[0][columnIndex].GetValue());
            }

            TocOffset     = (ulong)GetColumsData2(Utf, 0, "tocOffset", 3);
            EtocOffset    = (ulong)GetColumsData2(Utf, 0, "EtocOffset", 3);
            GtocOffset    = (ulong)GetColumsData2(Utf, 0, "GtocOffset", 3);
            ItocOffset    = (ulong)GetColumsData2(Utf, 0, "ItocOffset", 3);
            ContentOffset = (ulong)GetColumsData2(Utf, 0, "contentOffset", 3);

            var tocOffset     = GetColumnPostion(Utf, 0, "tocOffset");
            var eTocOffset    = GetColumnPostion(Utf, 0, "EtocOffset");
            var itocOffset    = GetColumnPostion(Utf, 0, "ItocOffset");
            var gtocOffset    = GetColumnPostion(Utf, 0, "GtocOffset");
            var contentOffset = GetColumnPostion(Utf, 0, "contentOffset");

            FileTable.Add(CreateFileEntry("CONTENT_OFFSET", ContentOffset, typeof(ulong), contentOffset, "CPK", "CONTENT", false));

            if (TocOffset != 0xFFFFFFFFFFFFFFFF)
            {
                FileTable.Add(CreateFileEntry("TOC_HDR", TocOffset, typeof(ulong), tocOffset, "CPK", "HDR", false));
                ReadToc(reader, TocOffset, ContentOffset);
            }

            if (EtocOffset != 0xFFFFFFFFFFFFFFFF)
            {
                FileTable.Add(CreateFileEntry("ETOC_HDR", EtocOffset, typeof(ulong), eTocOffset, "CPK", "HDR", false));
                ReadEtoc(reader, (long)EtocOffset);
            }

            if (ItocOffset != 0xFFFFFFFFFFFFFFFF)
            {
                FileTable.Add(CreateFileEntry("ITOC_HDR", ItocOffset, typeof(ulong), itocOffset, "CPK", "HDR", false));
                ReadItoc(reader, ItocOffset, ContentOffset, (ushort)GetColumsData2(Utf, 0, "Align", 1));
            }

            if (GtocOffset != 0xFFFFFFFFFFFFFFFF)
            {
                FileTable.Add(CreateFileEntry("GTOC_HDR", GtocOffset, typeof(ulong), gtocOffset, "CPK", "HDR", false));
                ReadGtoc(reader, (long)GtocOffset);
            }

            reader.Close();
            _files = null;
        }
Example #9
0
        /// <summary>
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="startOffset"></param>
        /// <param name="contentOffset"></param>
        /// <param name="byteAlignment"></param>
        /// <returns></returns>
        public bool ReadItoc(EndianReader reader, ulong startOffset, ulong contentOffset, ushort byteAlignment)
        {
            reader.BaseStream.Seek((long)startOffset, SeekOrigin.Begin);

            if (Tools.ReadCString(reader, 4) != "ITOC")
            {
                reader.Close();
                return(false);
            }

            _files = new Utf();
            ReadUtfData(reader);
            ItocPacket = UtfPacket;

            var itocEntry = FileTable.Single(x => x.FileName.ToString() == "ITOC_HDR");

            itocEntry.Encrypted = IsUtfEncrypted;
            itocEntry.FileSize  = ItocPacket.Length;

            var stream       = new MemoryStream(UtfPacket);
            var endianReader = new EndianReader(stream, false);

            if (!_files.ReadUtf(endianReader))
            {
                reader.Close();
                return(false);
            }

            endianReader.Close();
            stream.Close();

            var dataL             = (byte[])GetColumnData(_files, 0, "DataL");
            var dataLPosition     = GetColumnPostion(_files, 0, "DataL");
            var dataH             = (byte[])GetColumnData(_files, 0, "DataH");
            var dataHPos          = GetColumnPostion(_files, 0, "DataH");
            var identifiers       = new List <int>();
            var sizeTable         = new Dictionary <int, uint>();
            var sizePositionTable = new Dictionary <int, long>();
            var sizeTypeTable     = new Dictionary <int, Type>();
            var cSizeTable        = new Dictionary <int, uint>();
            var cSizePosTable     = new Dictionary <int, long>();
            var cSizeTypeTable    = new Dictionary <int, Type>();

            if (dataL != null)
            {
                var utfDataL = new Utf();

                using (var streamL = new MemoryStream(dataL))
                    using (var endianReaderL = new EndianReader(streamL, false))
                    {
                        utfDataL.ReadUtf(endianReaderL);
                    }

                for (var rowIndex = 0; rowIndex < utfDataL.RowCount; rowIndex++)
                {
                    var identifier = (ushort)GetColumnData(utfDataL, rowIndex, "Id");

                    sizeTable.Add(identifier, (ushort)GetColumnData(utfDataL, rowIndex, "FileSize"));
                    sizePositionTable.Add(identifier, GetColumnPostion(utfDataL, rowIndex, "FileSize") + dataLPosition);
                    sizeTypeTable.Add(identifier, GetColumnType(utfDataL, rowIndex, "FileSize"));

                    if (GetColumnData(utfDataL, rowIndex, "ExtractSize") != null)
                    {
                        cSizeTable.Add(identifier, (ushort)GetColumnData(utfDataL, rowIndex, "ExtractSize"));
                        cSizePosTable.Add(identifier, GetColumnPostion(utfDataL, rowIndex, "ExtractSize") + dataLPosition);
                        cSizeTypeTable.Add(identifier, GetColumnType(utfDataL, rowIndex, "ExtractSize"));
                    }

                    identifiers.Add(identifier);
                }
            }

            if (dataH != null)
            {
                var utfDataH = new Utf();

                using (var streamH = new MemoryStream(dataH))
                    using (var endianReaderH = new EndianReader(streamH, false))
                    {
                        utfDataH.ReadUtf(endianReaderH);
                    }

                for (var rowIndex = 0; rowIndex < utfDataH.RowCount; rowIndex++)
                {
                    var identifier = (ushort)GetColumnData(utfDataH, rowIndex, "Identifier");

                    sizeTable.Add(identifier, (uint)GetColumnData(utfDataH, rowIndex, "FileSize"));
                    sizePositionTable.Add(identifier, GetColumnPostion(utfDataH, rowIndex, "FileSize") + dataHPos);
                    sizeTypeTable.Add(identifier, GetColumnType(utfDataH, rowIndex, "FileSize"));

                    if (GetColumnData(utfDataH, rowIndex, "ExtractSize") != null)
                    {
                        cSizeTable.Add(identifier, (uint)GetColumnData(utfDataH, rowIndex, "ExtractSize"));
                        cSizePosTable.Add(identifier, GetColumnPostion(utfDataH, rowIndex, "ExtractSize") + dataHPos);
                        cSizeTypeTable.Add(identifier, GetColumnType(utfDataH, rowIndex, "ExtractSize"));
                    }

                    identifiers.Add(identifier);
                }
            }

            var baseOffset = contentOffset;

            foreach (var id in identifiers.OrderBy(identifier => identifier))
            {
                var fileEntry = new FileEntry();

                sizeTable.TryGetValue(id, out var fileSize);
                cSizeTable.TryGetValue(id, out var extractSize);
                fileEntry.TocName          = "ITOC";
                fileEntry.DirectoryName    = null;
                fileEntry.FileName         = id.ToString("D4");
                fileEntry.FileSize         = fileSize;
                fileEntry.FileSizePosition = sizePositionTable[id];
                fileEntry.FileSizeType     = sizeTypeTable[id];

                if (cSizeTable.Count > 0 && cSizeTable.ContainsKey(id))
                {
                    fileEntry.ExtractSize         = extractSize;
                    fileEntry.ExtractSizePosition = cSizePosTable[id];
                    fileEntry.ExtractSizeType     = cSizeTypeTable[id];
                }

                fileEntry.FileType   = "FILE";
                fileEntry.FileOffset = baseOffset;
                fileEntry.Identifier = id;
                fileEntry.UserString = null;
                FileTable.Add(fileEntry);

                if (fileSize % byteAlignment > 0)
                {
                    baseOffset += fileSize + (byteAlignment - fileSize % byteAlignment);
                }
                else
                {
                    baseOffset += fileSize;
                }
            }

            _files = null;
            stream.Close();
            endianReader.Close();

            return(true);
        }
Example #10
0
        /// <summary>
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="tocOffset"></param>
        /// <param name="contentOffset"></param>
        /// <returns></returns>
        public bool ReadToc(EndianReader reader, ulong tocOffset, ulong contentOffset)
        {
            var addOffset = tocOffset;

            if (contentOffset < tocOffset)
            {
                addOffset = contentOffset;
            }


            reader.BaseStream.Seek((long)tocOffset, SeekOrigin.Begin);

            if (Tools.ReadCString(reader, 4) != "TOC ")
            {
                reader.Close();
                return(false);
            }

            ReadUtfData(reader);
            TocPacket = UtfPacket;

            var tocEntry = FileTable.Single(entry => entry.FileName.ToString() == "TOC_HDR");

            _files             = new Utf();
            tocEntry.Encrypted = IsUtfEncrypted;
            tocEntry.FileSize  = TocPacket.Length;

            using (var stream = new MemoryStream(UtfPacket))
                using (var endianReader = new EndianReader(stream, false))
                {
                    if (_files.ReadUtf(endianReader) == false)
                    {
                        reader.Close();
                        return(false);
                    }
                }

            for (var index = 0; index < _files.RowCount; index++)
            {
                FileTable.Add(new FileEntry
                {
                    TocName             = "TOC",
                    FileType            = "FILE",
                    Offset              = addOffset,
                    DirectoryName       = GetColumnData(_files, index, "DirName"),
                    FileName            = GetColumnData(_files, index, "FileName"),
                    FileSize            = GetColumnData(_files, index, "FileSize"),
                    FileSizePosition    = GetColumnPostion(_files, index, "FileSize"),
                    FileSizeType        = GetColumnType(_files, index, "FileSize"),
                    ExtractSize         = GetColumnData(_files, index, "ExtractSize"),
                    ExtractSizePosition = GetColumnPostion(_files, index, "ExtractSize"),
                    ExtractSizeType     = GetColumnType(_files, index, "ExtractSize"),
                    FileOffset          = (ulong)GetColumnData(_files, index, "FileOffset") + addOffset,
                    FileOffsetPosition  = GetColumnPostion(_files, index, "FileOffset"),
                    FileOffsetType      = GetColumnType(_files, index, "FileOffset"),
                    Identifier          = GetColumnData(_files, index, "Identifier"),
                    UserString          = GetColumnData(_files, index, "UserString")
                });
            }

            _files = null;

            return(true);
        }
Example #11
0
        public bool ReadCPK(string sPath)
        {
            if (File.Exists(sPath))
            {
                uint   Files;
                ushort Align;
                cName = sPath;
                EndianReader br = new EndianReader(File.OpenRead(sPath), true);
                MemoryStream ms;
                EndianReader utfr;

                if (Tools.ReadCString(br, 4) != "CPK ")
                {
                    br.Close();
                    return(false);
                }

                ReadUTFData(br);

                CPK_packet = utf_packet;


                FileEntry CPAK_entry = new FileEntry
                {
                    FileName      = "CPK_HDR",
                    FileOffsetPos = br.BaseStream.Position + 0x10,
                    FileSize      = CPK_packet.Length,
                    Encrypted     = isUtfEncrypted,
                    FileType      = "CPK"
                };

                FileTable.Add(CPAK_entry);

                ms   = new MemoryStream(utf_packet);
                utfr = new EndianReader(ms, false);

                utf = new UTF();
                if (!utf.ReadUTF(utfr))
                {
                    br.Close();
                    return(false);
                }

                utfr.Close();
                ms.Close();



                TocOffset = (ulong)GetColumsData(utf, 0, "TocOffset", 3);
                long TocOffsetPos = GetColumnPostion(utf, 0, "TocOffset");

                EtocOffset = (ulong)GetColumsData(utf, 0, "EtocOffset", 3);
                long ETocOffsetPos = GetColumnPostion(utf, 0, "EtocOffset");

                ItocOffset = (ulong)GetColumsData(utf, 0, "ItocOffset", 3);
                long ITocOffsetPos = GetColumnPostion(utf, 0, "ItocOffset");

                GtocOffset = (ulong)GetColumsData(utf, 0, "GtocOffset", 3);
                long GTocOffsetPos = GetColumnPostion(utf, 0, "GtocOffset");

                ContentOffset = (ulong)GetColumsData(utf, 0, "ContentOffset", 3);
                long ContentOffsetPos = GetColumnPostion(utf, 0, "ContentOffset");
                FileTable.Add(CreateFileEntry("CONTENT_OFFSET", ContentOffset, typeof(ulong), ContentOffsetPos, "CPK", "CONTENT", false));

                Files = (uint)GetColumsData(utf, 0, "Files", 2);
                Align = (ushort)GetColumsData(utf, 0, "Align", 1);

                if (TocOffset != 0xFFFFFFFFFFFFFFFF)
                {
                    FileEntry entry = CreateFileEntry("TOC_HDR", TocOffset, typeof(ulong), TocOffsetPos, "CPK", "HDR", false);
                    FileTable.Add(entry);

                    if (!ReadTOC(br, TocOffset, ContentOffset))
                    {
                        return(false);
                    }
                }

                if (EtocOffset != 0xFFFFFFFFFFFFFFFF)
                {
                    FileEntry entry = CreateFileEntry("ETOC_HDR", EtocOffset, typeof(ulong), ETocOffsetPos, "CPK", "HDR", false);
                    FileTable.Add(entry);

                    if (!ReadETOC(br, EtocOffset))
                    {
                        return(false);
                    }
                }

                if (ItocOffset != 0xFFFFFFFFFFFFFFFF)
                {
                    //FileEntry ITOC_entry = new FileEntry {
                    //    FileName = "ITOC_HDR",
                    //    FileOffset = ItocOffset, FileOffsetType = typeof(ulong), FileOffsetPos = ITocOffsetPos,
                    //    TOCName = "CPK",
                    //    FileType = "FILE", Encrypted = true,
                    //};

                    FileEntry entry = CreateFileEntry("ITOC_HDR", ItocOffset, typeof(ulong), ITocOffsetPos, "CPK", "HDR", false);
                    FileTable.Add(entry);

                    if (!ReadITOC(br, ItocOffset, ContentOffset, Align))
                    {
                        return(false);
                    }
                }

                if (GtocOffset != 0xFFFFFFFFFFFFFFFF)
                {
                    FileEntry entry = CreateFileEntry("GTOC_HDR", GtocOffset, typeof(ulong), GTocOffsetPos, "CPK", "HDR", false);
                    FileTable.Add(entry);

                    if (!ReadGTOC(br, GtocOffset))
                    {
                        return(false);
                    }
                }

                br.Close();

                // at this point, we should have all needed file info

                //utf = null;
                files = null;
                return(true);
            }
            return(false);
        }