예제 #1
0
파일: CPK.cs 프로젝트: wchristian/Scarlet
        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);
        }
예제 #2
0
파일: CPK.cs 프로젝트: wchristian/Scarlet
        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();
        }
예제 #3
0
파일: CPK.cs 프로젝트: wchristian/Scarlet
        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);
        }
예제 #4
0
파일: CPK.cs 프로젝트: wchristian/Scarlet
        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);
        }