Esempio n. 1
0
        public void ReadRawToc(byte[] rawToc)
        {
            containerCount = ByteTools.ReadUInt(rawToc, 0x10);
            if (containerCount > 0xFFFF)
            {
                ByteTools.bigEndian = true;
                containerCount      = ByteTools.ReadUInt(rawToc, 0x10);
            }

            tableOffset = ByteTools.ReadUInt(rawToc, 0x14);
            namesOffset = ByteTools.ReadUInt(rawToc, 0x18);

            string[] entryNames = Encoding.ASCII.GetString(rawToc, (int)namesOffset, (int)(rawToc.Length - namesOffset)).Split(new char[] { (char)0 });

            entries = new tocEntryStruct[entryNames.Length];

            for (int i = 0; i < entries.Length; i++)
            {
                tocEntryStruct newTocEntry = new tocEntryStruct
                {
                    nameChecksum = ByteTools.ReadUInt(rawToc, (int)(tableOffset + i * 24 + 0)),
                    isFolder     = ByteTools.ReadBoolean(rawToc, (int)(tableOffset + i * 24 + 4)),
                    container    = ByteTools.ReadUInt(rawToc, (int)(tableOffset + i * 24 + 8)),
                    offset       = ByteTools.ReadUInt(rawToc, (int)(tableOffset + i * 24 + 12)),
                    length       = ByteTools.ReadUInt(rawToc, (int)tableOffset + i * 24 + 16),
                    name         = entryNames[i]
                };

                entries[i] = newTocEntry;
            }
        }
Esempio n. 2
0
        public static void Unpack(Toc toc, uint tocIndex, string packagePath, string inDirectoryPath, string outDirectoryPath)
        {
            if (abort)
            {
                return;
            }

            tocEntryStruct tocEntry = toc.entries[tocIndex];

            if (tocEntry.isFolder)
            {
                if (tocIndex == 0)
                {
                    outDirectoryPath = JoinPaths(outDirectoryPath, toc.name);
                }
                else
                {
                    packagePath = JoinPaths(packagePath, tocEntry.name);
                }
                Directory.CreateDirectory(JoinPaths(outDirectoryPath, packagePath));
                for (uint i = 0; i < tocEntry.length; i++)
                {
                    Unpack(toc, tocEntry.offset + i, packagePath, inDirectoryPath, outDirectoryPath);
                }
            }
            else
            {
                SetStatusText(JoinPaths(packagePath, tocEntry.name));

                string inFilePath  = string.Format("{0}/{1}.M{2:00}", inDirectoryPath, toc.name, tocEntry.container);
                string outFilePath = JoinPaths(outDirectoryPath, packagePath, Path.GetFileNameWithoutExtension(tocEntry.name));

                CheckFileExists(inFilePath);
                if (abort)
                {
                    return;
                }

                byte[] fileBytes = ExtractFile(inFilePath, tocEntry.offset, tocEntry.length);

                if (Path.GetExtension(tocEntry.name) == ".stz")
                {
                    Stz StzFile = new Stz(Path.GetFileNameWithoutExtension(tocEntry.name), fileBytes);
                    SafeFileWrite(outFilePath + ".dat", StzFile.data[3]);
                    if (!abort)
                    {
                        SafeFileWrite(outFilePath + ".rel", StzFile.data[4]);
                    }
                }
                else
                {
                    SafeFileWrite(outFilePath + Path.GetExtension(tocEntry.name), fileBytes);
                }

                progress += tocEntry.length;
                SetProgressBarValue((int)((100 * progress) / packageSize));
            }
        }
Esempio n. 3
0
        private void PrintToFile(long tocIndex, string currentPath)
        {
            tocEntryStruct tocEntry = entries[tocIndex];

            if (!tocEntry.isFolder)
            {
                textFile.WriteLine("{0}{1}\tM{2:00}\t{3:X}\t{4}\t{5:X}", currentPath, tocEntry.name, tocEntry.container, tocEntry.offset, tocEntry.length, tocEntry.nameChecksum);
            }
            else
            {
                for (int i = 0; i < tocEntry.length; i++)
                {
                    PrintToFile(tocEntry.offset + i, currentPath + tocEntry.name + "/");
                }
            }
        }
Esempio n. 4
0
        public static long GetPackageSize(Toc toc, uint tocIndex)
        {
            tocEntryStruct tocEntry = toc.entries[tocIndex];

            if (tocEntry.isFolder)
            {
                long size = 0;
                for (uint i = 0; i < tocEntry.length; i++)
                {
                    size += GetPackageSize(toc, tocEntry.offset + i);
                }
                return(size);
            }
            else
            {
                return(tocEntry.length);
            }
        }
Esempio n. 5
0
        public byte[] CreateRawToc()
        {
            int nameStringLength = entries.Length - 1;

            foreach (tocEntryStruct tocEntry in entries)
            {
                nameStringLength += tocEntry.name.Length;
            }

            byte[] rawToc = new byte[namesOffset + nameStringLength];
            ByteTools.WriteBytes(rawToc, 0, tocIdentifier);
            ByteTools.WriteUInt(rawToc, 0x10, containerCount);
            ByteTools.WriteUInt(rawToc, 0x14, tableOffset);
            ByteTools.WriteUInt(rawToc, 0x18, namesOffset);

            string namesString = "";

            for (int i = 0; i < entries.Length; i++)
            {
                tocEntryStruct tocEntry = entries[i];
                ByteTools.WriteUInt(rawToc, tableOffset + i * 24 + 0, tocEntry.nameChecksum);
                ByteTools.WriteUInt(rawToc, tableOffset + i * 24 + 4, tocEntry.isFolder ? 1u : 0u);
                ByteTools.WriteUInt(rawToc, tableOffset + i * 24 + 8, tocEntry.container);
                ByteTools.WriteUInt(rawToc, tableOffset + i * 24 + 12, tocEntry.offset);
                ByteTools.WriteUInt(rawToc, tableOffset + i * 24 + 16, tocEntry.length);
                ByteTools.WriteUInt(rawToc, tableOffset + i * 24 + 20, (uint)(namesString.Length));

                namesString += tocEntry.name;
                if (i < entries.Length - 1)
                {
                    namesString += (char)0;
                }
                ;
            }

            ByteTools.WriteString(rawToc, namesOffset, namesString);

            return(rawToc);
        }
Esempio n. 6
0
        public static uint Pack(Toc toc, uint tocIndex, uint tocOffset, DirectoryInfo currentInDirectory, string outDirectoryPath)
        {
            if (abort)
            {
                return(0);
            }

            DirectoryInfo[] subDirectories = currentInDirectory.GetDirectories();
            FileInfo[]      files          = currentInDirectory.GetFiles();
            uint            itemCount      = (uint)(subDirectories.Length + files.Length);

            tocEntryStruct tocEntry = new tocEntryStruct()
            {
                isFolder = true,
                length   = itemCount,
                offset   = tocOffset
            };

            if (tocIndex == 0)
            {
                tocEntry.name         = "";
                tocEntry.nameChecksum = 0;
                tocEntry.container    = uint.MaxValue;
            }
            else
            {
                tocEntry.name         = currentInDirectory.Name;
                tocEntry.nameChecksum = CryptTools.GetNameChecksum(currentInDirectory.Name);
            }

            toc.entries[tocIndex] = tocEntry;

            uint i = 0;

            foreach (DirectoryInfo subDirectory in subDirectories)
            {
                itemCount += Pack(toc, tocOffset + i, tocOffset + itemCount, subDirectory, outDirectoryPath);
                toc.entries[tocOffset + i].container = tocIndex;
                i++;
            }
            foreach (FileInfo file in files)
            {
                SetStatusText(file.FullName.Substring(inDirectoryPathLength, file.FullName.Length - inDirectoryPathLength));

                string outFilePath = JoinPaths(outDirectoryPath, string.Format("{0}.M{1:00}", toc.name, toc.containerCount - 1));
                if (toc.containerCount == 0 || (new FileInfo(outFilePath).Length) + file.Length > uint.MaxValue)
                {
                    toc.containerCount++;
                    outFilePath = JoinPaths(outDirectoryPath, string.Format("{0}.M{1:00}", toc.name, toc.containerCount - 1));

                    SafeFileWrite(outFilePath, new byte[0]);
                    if (abort)
                    {
                        return(0);
                    }
                }

                byte[] fileBytes  = File.ReadAllBytes(file.FullName);
                string inFilePath = file.FullName;

                toc.entries[tocOffset + i] = new tocEntryStruct()
                {
                    isFolder     = false,
                    length       = (uint)file.Length,
                    name         = Path.GetFileName(inFilePath),
                    nameChecksum = CryptTools.GetNameChecksum(Path.GetFileName(inFilePath)),
                    offset       = (uint)(new FileInfo(outFilePath).Length),
                    container    = toc.containerCount - 1
                };

                AppendFile(outFilePath, fileBytes);

                progress += file.Length;
                SetProgressBarValue((int)((100 * progress) / packageSize));
                i++;
            }

            return(itemCount);
        }