Пример #1
0
        public bool ReadUTF(EndianReader br)
        {
            var 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();

            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();

            columns = new List <COLUMN>();
            COLUMN column;

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

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

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

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

                current_entry = new ROWS();

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

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

                    switch (storage_flag)
                    {
                    case (int)COLUMN_FLAGS.STORAGE_NONE:
                        current_entry.rows.Add(current_row);
                        continue;

                    case (int)COLUMN_FLAGS.STORAGE_ZERO:
                        current_entry.rows.Add(current_row);
                        continue;

                    case (int)COLUMN_FLAGS.STORAGE_CONSTANT:
                        current_entry.rows.Add(current_row);
                        continue;
                    }


                    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:
                        var 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);
        }
Пример #2
0
        public byte[] DecompressCRILAYLA(byte[] input, int USize)
        {
            byte[] result;

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

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

            result = new byte[uncompressed_size + 0x100];

            Array.Copy(input, uncompressed_header_offset + 0x10, result, 0, 0x100);

            var  input_end = input.Length - 0x100 - 1;
            var  input_offset = input_end;
            var  output_end = 0x100 + uncompressed_size - 1;
            byte bit_pool = 0;
            int  bits_left = 0, bytes_output = 0;
            var  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)
                {
                    var backreference_offset = output_end - bytes_output +
                                               get_next_bits(input, ref input_offset, ref bit_pool, ref bits_left, 13) +
                                               3;
                    var 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 (var i = 0; i < backreference_length; i++)
                    {
                        result[output_end - bytes_output] = result[backreference_offset--];
                        bytes_output++;
                    }
                }
                else
                {
                    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);
        }
Пример #3
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;

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

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

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

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

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

            var DataL    = (byte[])GetColumnData(files, 0, "DataL");
            var DataLPos = GetColumnPostion(files, 0, "DataL");

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

            UTF utfDataL, utfDataH;
            Dictionary <int, uint> SizeTable, CSizeTable;
            Dictionary <int, long> SizePosTable, CSizePosTable;
            Dictionary <int, Type> SizeTypeTable, CSizeTypeTable;

            var 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 (var i = 0; i < utfDataL.num_rows; i++)
                {
                    ID    = (ushort)GetColumnData(utfDataL, i, "ID");
                    size1 = (ushort)GetColumnData(utfDataL, i, "FileSize");
                    SizeTable.Add(ID, size1);

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

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

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

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

                        type = GetColumnType(utfDataL, i, "ExtractSize");
                        CSizeTypeTable.Add(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 (var 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(ID, pos + DataHPos);

                    type = GetColumnType(utfDataH, i, "FileSize");
                    SizeTypeTable.Add(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(ID, pos + DataHPos);

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

                    IDs.Add(ID);
                }
            }

            FileEntry temp;
            uint      value = 0, value2 = 0;
            var       baseoffset = ContentOffset;

            IDs = IDs.OrderBy(x => x).ToList();


            foreach (var id in IDs)
            {
                temp = new FileEntry();
                SizeTable.TryGetValue(id, out value);
                CSizeTable.TryGetValue(id, out value2);

                temp.TOCName = "ITOC";

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

                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;
                }
            }

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

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


            return(true);
        }
Пример #4
0
        public bool ReadCPK(string sPath)
        {
            if (!File.Exists(sPath))
            {
                return(false);
            }
            uint   Files;
            ushort Align;

            var          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;

            var 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 (var i = 0; i < utf.columns.Count; i++)
                {
                    cpkdata.Add(utf.columns[i].name, utf.rows[0].rows[i].GetValue());
                }
            }
            catch (Exception)
            {
                //ignore
            }

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

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

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

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

            ContentOffset = (ulong)GetColumsData2(utf, 0, "ContentOffset", 3);
            var 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)
            {
                var entry = CreateFileEntry("TOC_HDR", TocOffset, typeof(ulong), TocOffsetPos, "CPK", "HDR", false);
                FileTable.Add(entry);

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

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

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

            if (ItocOffset != 0xFFFFFFFFFFFFFFFF)
            {
                var 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)
            {
                var entry = CreateFileEntry("GTOC_HDR", GtocOffset, typeof(ulong), GTocOffsetPos, "CPK", "HDR",
                                            false);
                FileTable.Add(entry);

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

            br.Close();

            files = null;
            return(true);
        }
Пример #5
0
        public bool ReadTOC(EndianReader br, ulong TocOffset, ulong ContentOffset)
        {
            ulong add_offset = 0;

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

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

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

            ReadUTFData(br);

            TOC_packet = utf_packet;

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

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

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

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

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

            FileEntry temp;

            for (var i = 0; i < files.num_rows; i++)
            {
                temp = new FileEntry
                {
                    TOCName         = "TOC",
                    DirName         = GetColumnData(files, i, "DirName"),
                    FileName        = GetColumnData(files, i, "FileName"),
                    FileSize        = GetColumnData(files, i, "FileSize"),
                    FileSizePos     = GetColumnPostion(files, i, "FileSize"),
                    FileSizeType    = GetColumnType(files, i, "FileSize"),
                    ExtractSize     = GetColumnData(files, i, "ExtractSize"),
                    ExtractSizePos  = GetColumnPostion(files, i, "ExtractSize"),
                    ExtractSizeType = GetColumnType(files, i, "ExtractSize"),
                    FileOffset      = (ulong)GetColumnData(files, i, "FileOffset") + add_offset,
                    FileOffsetPos   = GetColumnPostion(files, i, "FileOffset"),
                    FileOffsetType  = GetColumnType(files, i, "FileOffset"),
                    FileType        = "FILE",
                    Offset          = add_offset,
                    ID         = GetColumnData(files, i, "ID"),
                    UserString = GetColumnData(files, i, "UserString")
                };

                FileTable.Add(temp);
            }

            files = null;

            return(true);
        }