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; }
private void ReadUTFData(EndianReader br) { isUtfEncrypted = false; br.IsLittleEndian = true; unk1 = br.ReadInt32(); utf_size = br.ReadInt64(); utf_packet = br.ReadBytes((int)utf_size); if (utf_packet[0] != 0x40 && utf_packet[1] != 0x55 && utf_packet[2] != 0x54 && utf_packet[3] != 0x46) //@UTF { utf_packet = DecryptUTF(utf_packet); isUtfEncrypted = true; } br.IsLittleEndian = false; }
public byte[] DecompressCRILAYLA(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; }