Example #1
0
        /// <summary>
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public bool ReadEtoc(EndianReader reader, long offset)
        {
            reader.BaseStream.Seek(offset, SeekOrigin.Begin);

            if (Tools.ReadCString(reader, 4) != "ETOC")
            {
                return(false);
            }

            ReadUtfData(reader);
            EtocPacket = UtfPacket;

            var etocEntry = FileTable.Single(x => x.FileName.ToString() == "ETOC_HDR");

            etocEntry.Encrypted = IsUtfEncrypted;
            etocEntry.FileSize  = EtocPacket.Length;

            using var stream       = new MemoryStream(UtfPacket);
            using var endianReader = new EndianReader(stream, false);

            _files = new Utf();

            if (_files.ReadUtf(endianReader) == false)
            {
                return(false);
            }

            var fileEntries = FileTable.Where(fileEntry => fileEntry.FileType == "FILE").ToList();

            for (var entryIndex = 0; entryIndex < fileEntries.Count; entryIndex++)
            {
                FileTable[entryIndex].LocalDirectory = GetColumnData(_files, entryIndex, "LocalDir");
            }

            return(true);
        }
Example #2
0
        /// <summary>
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="startOffset"></param>
        /// <param name="contentOffset"></param>
        /// <param name="byteAlignment"></param>
        /// <returns></returns>
        public bool ReadItoc(EndianReader reader, ulong startOffset, ulong contentOffset, ushort byteAlignment)
        {
            reader.BaseStream.Seek((long)startOffset, SeekOrigin.Begin);

            if (Tools.ReadCString(reader, 4) != "ITOC")
            {
                reader.Close();
                return(false);
            }

            _files = new Utf();
            ReadUtfData(reader);
            ItocPacket = UtfPacket;

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

            itocEntry.Encrypted = IsUtfEncrypted;
            itocEntry.FileSize  = ItocPacket.Length;

            var stream       = new MemoryStream(UtfPacket);
            var endianReader = new EndianReader(stream, false);

            if (!_files.ReadUtf(endianReader))
            {
                reader.Close();
                return(false);
            }

            endianReader.Close();
            stream.Close();

            var dataL             = (byte[])GetColumnData(_files, 0, "DataL");
            var dataLPosition     = GetColumnPostion(_files, 0, "DataL");
            var dataH             = (byte[])GetColumnData(_files, 0, "DataH");
            var dataHPos          = GetColumnPostion(_files, 0, "DataH");
            var identifiers       = new List <int>();
            var sizeTable         = new Dictionary <int, uint>();
            var sizePositionTable = new Dictionary <int, long>();
            var sizeTypeTable     = new Dictionary <int, Type>();
            var cSizeTable        = new Dictionary <int, uint>();
            var cSizePosTable     = new Dictionary <int, long>();
            var cSizeTypeTable    = new Dictionary <int, Type>();

            if (dataL != null)
            {
                var utfDataL = new Utf();

                using (var streamL = new MemoryStream(dataL))
                    using (var endianReaderL = new EndianReader(streamL, false))
                    {
                        utfDataL.ReadUtf(endianReaderL);
                    }

                for (var rowIndex = 0; rowIndex < utfDataL.RowCount; rowIndex++)
                {
                    var identifier = (ushort)GetColumnData(utfDataL, rowIndex, "Id");

                    sizeTable.Add(identifier, (ushort)GetColumnData(utfDataL, rowIndex, "FileSize"));
                    sizePositionTable.Add(identifier, GetColumnPostion(utfDataL, rowIndex, "FileSize") + dataLPosition);
                    sizeTypeTable.Add(identifier, GetColumnType(utfDataL, rowIndex, "FileSize"));

                    if (GetColumnData(utfDataL, rowIndex, "ExtractSize") != null)
                    {
                        cSizeTable.Add(identifier, (ushort)GetColumnData(utfDataL, rowIndex, "ExtractSize"));
                        cSizePosTable.Add(identifier, GetColumnPostion(utfDataL, rowIndex, "ExtractSize") + dataLPosition);
                        cSizeTypeTable.Add(identifier, GetColumnType(utfDataL, rowIndex, "ExtractSize"));
                    }

                    identifiers.Add(identifier);
                }
            }

            if (dataH != null)
            {
                var utfDataH = new Utf();

                using (var streamH = new MemoryStream(dataH))
                    using (var endianReaderH = new EndianReader(streamH, false))
                    {
                        utfDataH.ReadUtf(endianReaderH);
                    }

                for (var rowIndex = 0; rowIndex < utfDataH.RowCount; rowIndex++)
                {
                    var identifier = (ushort)GetColumnData(utfDataH, rowIndex, "Identifier");

                    sizeTable.Add(identifier, (uint)GetColumnData(utfDataH, rowIndex, "FileSize"));
                    sizePositionTable.Add(identifier, GetColumnPostion(utfDataH, rowIndex, "FileSize") + dataHPos);
                    sizeTypeTable.Add(identifier, GetColumnType(utfDataH, rowIndex, "FileSize"));

                    if (GetColumnData(utfDataH, rowIndex, "ExtractSize") != null)
                    {
                        cSizeTable.Add(identifier, (uint)GetColumnData(utfDataH, rowIndex, "ExtractSize"));
                        cSizePosTable.Add(identifier, GetColumnPostion(utfDataH, rowIndex, "ExtractSize") + dataHPos);
                        cSizeTypeTable.Add(identifier, GetColumnType(utfDataH, rowIndex, "ExtractSize"));
                    }

                    identifiers.Add(identifier);
                }
            }

            var baseOffset = contentOffset;

            foreach (var id in identifiers.OrderBy(identifier => identifier))
            {
                var fileEntry = new FileEntry();

                sizeTable.TryGetValue(id, out var fileSize);
                cSizeTable.TryGetValue(id, out var extractSize);
                fileEntry.TocName          = "ITOC";
                fileEntry.DirectoryName    = null;
                fileEntry.FileName         = id.ToString("D4");
                fileEntry.FileSize         = fileSize;
                fileEntry.FileSizePosition = sizePositionTable[id];
                fileEntry.FileSizeType     = sizeTypeTable[id];

                if (cSizeTable.Count > 0 && cSizeTable.ContainsKey(id))
                {
                    fileEntry.ExtractSize         = extractSize;
                    fileEntry.ExtractSizePosition = cSizePosTable[id];
                    fileEntry.ExtractSizeType     = cSizeTypeTable[id];
                }

                fileEntry.FileType   = "FILE";
                fileEntry.FileOffset = baseOffset;
                fileEntry.Identifier = id;
                fileEntry.UserString = null;
                FileTable.Add(fileEntry);

                if (fileSize % byteAlignment > 0)
                {
                    baseOffset += fileSize + (byteAlignment - fileSize % byteAlignment);
                }
                else
                {
                    baseOffset += fileSize;
                }
            }

            _files = null;
            stream.Close();
            endianReader.Close();

            return(true);
        }
Example #3
0
        /// <summary>
        /// </summary>
        /// <param name="cpkFilename"></param>
        public Cpk(string cpkFilename)
        {
            IsUtfEncrypted = false;

            if (!File.Exists(cpkFilename))
            {
                throw new FileNotFoundException(cpkFilename);
            }

            var reader = new EndianReader(File.OpenRead(cpkFilename), true);

            if (Tools.ReadCString(reader, 4) != "CPK ")
            {
                reader.Close();
                throw new Exception();
            }

            Utf = new Utf();
            ReadUtfData(reader);
            CpkPacket = UtfPacket;

            var cpakEntry = new FileEntry
            {
                FileType           = "CPK",
                FileName           = "CPK_HDR",
                Encrypted          = IsUtfEncrypted,
                FileSize           = CpkPacket.Length,
                FileOffsetPosition = reader.BaseStream.Position + 0x10
            };

            FileTable = new List <FileEntry>
            {
                cpakEntry
            };

            using (var stream = new MemoryStream(UtfPacket))
                using (var utfReader = new EndianReader(stream, false))
                {
                    if (!Utf.ReadUtf(utfReader))
                    {
                        reader.Close();
                        throw new Exception();
                    }
                }

            CpkData = new Dictionary <string, object>();

            for (var columnIndex = 0; columnIndex < Utf.Columns.Count; columnIndex++)
            {
                CpkData.Add(Utf.Columns[columnIndex].Name, Utf.Rows[0][columnIndex].GetValue());
            }

            TocOffset     = (ulong)GetColumsData2(Utf, 0, "tocOffset", 3);
            EtocOffset    = (ulong)GetColumsData2(Utf, 0, "EtocOffset", 3);
            GtocOffset    = (ulong)GetColumsData2(Utf, 0, "GtocOffset", 3);
            ItocOffset    = (ulong)GetColumsData2(Utf, 0, "ItocOffset", 3);
            ContentOffset = (ulong)GetColumsData2(Utf, 0, "contentOffset", 3);

            var tocOffset     = GetColumnPostion(Utf, 0, "tocOffset");
            var eTocOffset    = GetColumnPostion(Utf, 0, "EtocOffset");
            var itocOffset    = GetColumnPostion(Utf, 0, "ItocOffset");
            var gtocOffset    = GetColumnPostion(Utf, 0, "GtocOffset");
            var contentOffset = GetColumnPostion(Utf, 0, "contentOffset");

            FileTable.Add(CreateFileEntry("CONTENT_OFFSET", ContentOffset, typeof(ulong), contentOffset, "CPK", "CONTENT", false));

            if (TocOffset != 0xFFFFFFFFFFFFFFFF)
            {
                FileTable.Add(CreateFileEntry("TOC_HDR", TocOffset, typeof(ulong), tocOffset, "CPK", "HDR", false));
                ReadToc(reader, TocOffset, ContentOffset);
            }

            if (EtocOffset != 0xFFFFFFFFFFFFFFFF)
            {
                FileTable.Add(CreateFileEntry("ETOC_HDR", EtocOffset, typeof(ulong), eTocOffset, "CPK", "HDR", false));
                ReadEtoc(reader, (long)EtocOffset);
            }

            if (ItocOffset != 0xFFFFFFFFFFFFFFFF)
            {
                FileTable.Add(CreateFileEntry("ITOC_HDR", ItocOffset, typeof(ulong), itocOffset, "CPK", "HDR", false));
                ReadItoc(reader, ItocOffset, ContentOffset, (ushort)GetColumsData2(Utf, 0, "Align", 1));
            }

            if (GtocOffset != 0xFFFFFFFFFFFFFFFF)
            {
                FileTable.Add(CreateFileEntry("GTOC_HDR", GtocOffset, typeof(ulong), gtocOffset, "CPK", "HDR", false));
                ReadGtoc(reader, (long)GtocOffset);
            }

            reader.Close();
            _files = null;
        }
Example #4
0
        /// <summary>
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="tocOffset"></param>
        /// <param name="contentOffset"></param>
        /// <returns></returns>
        public bool ReadToc(EndianReader reader, ulong tocOffset, ulong contentOffset)
        {
            var addOffset = tocOffset;

            if (contentOffset < tocOffset)
            {
                addOffset = contentOffset;
            }


            reader.BaseStream.Seek((long)tocOffset, SeekOrigin.Begin);

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

            ReadUtfData(reader);
            TocPacket = UtfPacket;

            var tocEntry = FileTable.Single(entry => entry.FileName.ToString() == "TOC_HDR");

            _files             = new Utf();
            tocEntry.Encrypted = IsUtfEncrypted;
            tocEntry.FileSize  = TocPacket.Length;

            using (var stream = new MemoryStream(UtfPacket))
                using (var endianReader = new EndianReader(stream, false))
                {
                    if (_files.ReadUtf(endianReader) == false)
                    {
                        reader.Close();
                        return(false);
                    }
                }

            for (var index = 0; index < _files.RowCount; index++)
            {
                FileTable.Add(new FileEntry
                {
                    TocName             = "TOC",
                    FileType            = "FILE",
                    Offset              = addOffset,
                    DirectoryName       = GetColumnData(_files, index, "DirName"),
                    FileName            = GetColumnData(_files, index, "FileName"),
                    FileSize            = GetColumnData(_files, index, "FileSize"),
                    FileSizePosition    = GetColumnPostion(_files, index, "FileSize"),
                    FileSizeType        = GetColumnType(_files, index, "FileSize"),
                    ExtractSize         = GetColumnData(_files, index, "ExtractSize"),
                    ExtractSizePosition = GetColumnPostion(_files, index, "ExtractSize"),
                    ExtractSizeType     = GetColumnType(_files, index, "ExtractSize"),
                    FileOffset          = (ulong)GetColumnData(_files, index, "FileOffset") + addOffset,
                    FileOffsetPosition  = GetColumnPostion(_files, index, "FileOffset"),
                    FileOffsetType      = GetColumnType(_files, index, "FileOffset"),
                    Identifier          = GetColumnData(_files, index, "Identifier"),
                    UserString          = GetColumnData(_files, index, "UserString")
                });
            }

            _files = null;

            return(true);
        }