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