public bool ReadETOC(EndianBinaryReader br, ulong startoffset) { br.BaseStream.Seek((long)startoffset, SeekOrigin.Begin); if (Tools.ReadCString(br, 4) != "ETOC") { br.Close(); return(false); } ReadUTFData(br); ETOCPacket = UTFPacket; CPKEntry etocEntry = FileTable.Where(x => x.FileName.ToString() == "ETOC_HDR").Single(); etocEntry.Encrypted = IsUtfEncrypted; etocEntry.FileSize = ETOCPacket.Length; MemoryStream ms = new MemoryStream(UTFPacket); EndianBinaryReader utfr = new EndianBinaryReader(ms, Endian.BigEndian); Files = new UTF(); if (!Files.ReadUTF(utfr)) { br.Close(); return(false); } utfr.Close(); ms.Close(); List <CPKEntry> fileEntries = FileTable.Where(x => x.FileType == "FILE").ToList(); for (int i = 0; i < fileEntries.Count; i++) { FileTable[i].LocalDir = GetColumnData(Files, i, "LocalDir"); FileTable[i].UpdateDateTime = (ulong)GetColumnData(Files, i, "UpdateDateTime"); } return(true); }
protected override void OnOpen(EndianBinaryReader reader) { uint files; ushort align; MemoryStream ms; EndianBinaryReader utfr; if (Encoding.ASCII.GetString(reader.ReadBytes(4)) != "CPK ") { throw new NotImplementedException("Invalid CPK header"); } ReadUTFData(reader); CPKPacket = UTFPacket; CPKEntry CPAK_entry = new CPKEntry { FileName = "CPK_HDR", FileOffsetPos = reader.BaseStream.Position + 0x10, FileSize = CPKPacket.Length, Encrypted = IsUtfEncrypted, FileType = "CPK" }; FileTable.Add(CPAK_entry); ms = new MemoryStream(UTFPacket); utfr = new EndianBinaryReader(ms, Endian.BigEndian); UTF = new UTF(); if (!UTF.ReadUTF(utfr)) { throw new NotSupportedException("Invalid UTF header in CPK file"); } utfr.Close(); ms.Close(); CPKData = new Dictionary <string, object>(); for (int i = 0; i < UTF.Columns.Count; i++) { CPKData.Add(UTF.Columns[i].name, UTF.Rows[0].rows[i].GetValue()); } 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)); FileTable.Add(new CPKEntry { FileName = "CONTENT_OFFSET", FileOffset = ContentOffset, FileOffsetType = typeof(ulong), FileOffsetPos = contentOffsetPos, TOCName = "CPK", FileType = "CONTENT", Encrypted = false }); files = (uint)GetColumsData2(UTF, 0, "Files", 2); align = (ushort)GetColumsData2(UTF, 0, "Align", 1); if (TocOffset != 0xFFFFFFFFFFFFFFFF) { CPKEntry entry = new CPKEntry { FileName = "TOC_HDR", FileOffset = TocOffset, FileOffsetType = typeof(ulong), FileOffsetPos = tocOffsetPos, TOCName = "CPK", FileType = "HDR", Encrypted = false }; FileTable.Add(entry); if (!ReadTOC(reader, TocOffset, ContentOffset)) { throw new NotSupportedException("Error reading TOC from CPK file"); } } if (EtocOffset != 0xFFFFFFFFFFFFFFFF) { CPKEntry entry = new CPKEntry { FileName = "ETOC_HDR", FileOffset = EtocOffset, FileOffsetType = typeof(ulong), FileOffsetPos = eTocOffsetPos, TOCName = "CPK", FileType = "HDR", Encrypted = false }; FileTable.Add(entry); if (!ReadETOC(reader, EtocOffset)) { throw new NotSupportedException("Error reading ETOC from CPK file"); } } if (ItocOffset != 0xFFFFFFFFFFFFFFFF) { //FileEntry ITOC_entry = new FileEntry { // FileName = "ITOC_HDR", // FileOffset = ItocOffset, FileOffsetType = typeof(ulong), FileOffsetPos = ITocOffsetPos, // TOCName = "CPK", // FileType = "FILE", Encrypted = true, //}; CPKEntry entry = new CPKEntry { FileName = "ITOC_HDR", FileOffset = ItocOffset, FileOffsetType = typeof(ulong), FileOffsetPos = iTocOffsetPos, TOCName = "CPK", FileType = "HDR", Encrypted = false }; FileTable.Add(entry); if (!ReadITOC(reader, ItocOffset, ContentOffset, align)) { throw new NotSupportedException("Error reading ITOC from CPK file"); } } if (GtocOffset != 0xFFFFFFFFFFFFFFFF) { CPKEntry entry = new CPKEntry { FileName = "GTOC_HDR", FileOffset = GtocOffset, FileOffsetType = typeof(ulong), FileOffsetPos = gTocOffsetPos, TOCName = "CPK", FileType = "HDR", Encrypted = false }; FileTable.Add(entry); if (!ReadGTOC(reader, GtocOffset)) { throw new NotSupportedException("Error reading GTOC from CPK file"); } } // to get to the real files quickly AllFiles = FileTable.Where(x => x.FileType == "FILE").ToArray(); }
public bool ReadITOC(EndianBinaryReader 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); ITOCPacket = UTFPacket; CPKEntry itocEntry = FileTable.Where(x => x.FileName.ToString() == "ITOC_HDR").Single(); itocEntry.Encrypted = IsUtfEncrypted; itocEntry.FileSize = ITOCPacket.Length; MemoryStream ms = new MemoryStream(UTFPacket); EndianBinaryReader utfr = new EndianBinaryReader(ms, Endian.BigEndian); Files = new UTF(); 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"); 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 EndianBinaryReader(ms, Endian.BigEndian); utfDataL = new UTF(); utfDataL.ReadUTF(utfr); for (int i = 0; i < utfDataL.NumRows; 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 EndianBinaryReader(ms, Endian.BigEndian); utfDataH = new UTF(); utfDataH.ReadUTF(utfr); for (int i = 0; i < utfDataH.NumRows; 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); } } CPKEntry 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 CPKEntry(); 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; } //id++; } Files = null; utfDataL = null; utfDataH = null; ms.Close(); utfr.Close(); return(true); }
public bool ReadTOC(EndianBinaryReader br, ulong tocOffset, ulong contentOffset) { ulong addOffset = 0; if (contentOffset < 0) { addOffset = tocOffset; } else { if (tocOffset < 0) { addOffset = contentOffset; } else { if (contentOffset < tocOffset) { addOffset = contentOffset; } else { addOffset = tocOffset; } } } br.BaseStream.Seek((long)tocOffset, SeekOrigin.Begin); if (Tools.ReadCString(br, 4) != "TOC ") { br.Close(); return(false); } ReadUTFData(br); // Store unencrypted TOC TOCPacket = UTFPacket; CPKEntry tocEntry = FileTable.Where(x => x.FileName.ToString() == "TOC_HDR").Single(); tocEntry.Encrypted = IsUtfEncrypted; tocEntry.FileSize = TOCPacket.Length; MemoryStream ms = new MemoryStream(UTFPacket); EndianBinaryReader utfr = new EndianBinaryReader(ms, Endian.BigEndian); Files = new UTF(); if (!Files.ReadUTF(utfr)) { br.Close(); return(false); } utfr.Close(); ms.Close(); CPKEntry temp; for (int i = 0; i < Files.NumRows; i++) { temp = new CPKEntry(); 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)addOffset); temp.FileOffsetPos = GetColumnPostion(Files, i, "FileOffset"); temp.FileOffsetType = GetColumnType(Files, i, "FileOffset"); temp.FileType = "FILE"; temp.Offset = addOffset; temp.ID = GetColumnData(Files, i, "ID"); temp.UserString = GetColumnData(Files, i, "UserString"); FileTable.Add(temp); } Files = null; return(true); }