Example #1
0
        private CPKBuildObject FilterCPKFile(FileLocationMeta file, string sourceDirectoryPath, string targetDirectoryPath)
        {
            var cpkFile  = new CPK(new Tools()); // this function gets a bit confusings since file, cpkFile and embeddedFile are all thrown around - i will need to fix that
            var filePath = Path.Combine(sourceDirectoryPath, file.subPath, file.fileName);

            if (!cpkFile.ReadCPK(filePath, ActiveEncodings.currentEncoding))
            {
                string errorMessage = string.Format("Unknown error while attempting to open {0}.", filePath);
                MessageBox.Show(errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); // this could be replaced with a custom form that allows the user to skip all errors or a simple "errors while opening X files" after the files are done being read. though, the later option would require a small restructuring of the code.
                Environment.Exit(1);
            }

            int realFileCount = 0;

            foreach (var embeddedFile in cpkFile.FileTable)
            {
                if (embeddedFile.FileType.ToString() == "FILE")
                {
                    realFileCount += 1;
                }
            }

            if (realFileCount == 0)
            {
                string errorMessage = string.Format("CPK file {0} was empty.", filePath); // i am not sure this should be a fatal error - i will attempt to come back to it once i have a more complete picture of how the build system works and thus have a better idea of how to handle such an eventuality
                MessageBox.Show(errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(1);
            }

            CPKBuildObject cpkBuildInstructions = new CPKBuildObject();

            string originalFileLocation = Path.Combine(ProjectFolder.extractedISODir, file.subPath, file.fileName);

            cpkBuildInstructions.SetOriginalFileLocation(originalFileLocation);
            string targetFileLocation = Path.Combine(ProjectFolder.repackedGameFilesDir, file.subPath, file.fileName);

            cpkBuildInstructions.SetTargetFileLocation(targetFileLocation);


            if (realFileCount > 1) // if there is more than one file in the CPK we move the files within it to their own directory
            {
                string newSubDir  = Path.GetFileNameWithoutExtension(file.fileName);
                string newSubPath = Path.Combine(file.subPath, newSubDir);
                file.subPath = newSubPath;
            }

            foreach (var embeddedFile in cpkFile.FileTable)
            {
                var cpkMeta = new CPKEmbeddedFileMeta();

                if (embeddedFile.FileType != "FILE")
                {
                    continue; // skip headers etc.
                }

                if (FileParser.IsParseable(embeddedFile.FileName.ToString())) // use this to determine whether to unpack or not, not save location
                {
                    file.switchPath = editableDirectory;
                }
                else
                {
                    file.switchPath = rawDirectory;
                }

                string targetFileAbsolutePath = Path.Combine(targetDirectoryPath, ProjectFolder.unpackedGameFilesDir, file.subPath, embeddedFile.FileName.ToString());
                DirectoryGuard.CheckDirectory(targetFileAbsolutePath);

                byte[] fileAsBytes = GrabCPKData(filePath, embeddedFile);

                if (DebugSettings.ATTEMPT_DECOMPRESSION)
                {
                    if (fileAsBytes.Length >= 8) // 8 = length of "CRILAYLA"
                    {
                        byte[] crilaylaCheck = new byte[8];
                        Array.Copy(fileAsBytes, 0, crilaylaCheck, 0, 8);
                        string crilaylaString = Encoding.ASCII.GetString(crilaylaCheck);

                        if (crilaylaString == "CRILAYLA")
                        {
                            byte[] decompressedBytes = cpkFile.DecompressCRILAYLA(fileAsBytes, fileAsBytes.Length);
                            fileAsBytes = decompressedBytes;
                        }
                    }
                }

                if (DebugSettings.ALLOW_FILE_WRITES)
                {
                    FileStream   fs = new FileStream(targetFileAbsolutePath, FileMode.Create);
                    BinaryWriter bw = new BinaryWriter(fs);

                    bw.Write(fileAsBytes);

                    bw.Close();
                    fs.Close();
                }

                if (DebugSettings.COPY_UNPACKED_FILES)
                {
                    string secondTargetPath = Path.Combine(targetDirectoryPath, ProjectFolder.reassembledGameFilesDir, file.subPath, embeddedFile.FileName.ToString());
                    DirectoryGuard.CheckDirectory(secondTargetPath);

                    FileStream   fs = new FileStream(secondTargetPath, FileMode.Create);
                    BinaryWriter bw = new BinaryWriter(fs);

                    bw.Write(fileAsBytes);

                    bw.Close();
                    fs.Close();
                }

                string relativeFilePath = Path.Combine(file.subPath, embeddedFile.FileName.ToString());
                uint   fileID           = (uint)embeddedFile.ID;

                cpkMeta.filePath      = Path.Combine(ProjectFolder.reassembledGameFilesDir, relativeFilePath);
                cpkMeta.fileName      = embeddedFile.FileName.ToString();
                cpkMeta.checksumType  = Checksum.MD5;
                cpkMeta.checksumValue = Checksums.GetMD5(fileAsBytes);
                cpkMeta.ID            = fileID;

                cpkBuildInstructions.AddFile(fileID, cpkMeta);
            }

            cpkBuildInstructions.SerializeToDisk(Path.Combine(targetDirectoryPath, ProjectFolder.buildScriptsDir));

            return(cpkBuildInstructions);
        }
Example #2
0
        public static void RebuildCPKs(object sender, EventArgs e)
        {
            BackgroundWorker worker    = null;
            DoWorkEventArgs  eventArgs = null;

            if (sender is BackgroundWorker)
            {
                worker    = sender as BackgroundWorker;
                eventArgs = e as DoWorkEventArgs;
            }
            else
            {
                worker = null;
            }

            string buildDir = Path.Combine(rootDir, buildScriptsDir);

            if (!Directory.Exists(buildDir))
            {
                string errorMessage = string.Format("Could not find build scripts directory at {0}.", buildDir);
                MessageBox.Show(errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                eventArgs.Result = false;
            }

            string[] fileList = Directory.GetFiles(buildDir);

            int counter = 0;

            foreach (var file in fileList)
            {
                counter++;

                if (worker != null)
                {
                    double progress = ((double)counter / (double)fileList.Length) * 100;

                    worker.ReportProgress((int)progress);

                    Thread.Sleep(3); // these are aeshetic sleeps, there to make the progress bar grow steadily so the user doesn't think something might have went wrong
                }

                if (worker != null)
                {
                    if (worker.WorkerSupportsCancellation && worker.CancellationPending)
                    {
                        eventArgs.Result = false;
                        MessageBox.Show("Rebuild CPKs cancelled");
                        return;
                    }
                }

                if (file.EndsWith(".cpk.yaml"))
                {
                    if (file.EndsWith("movie-movie.cpk.yaml")) // doesn't work for some reason - manually blacklisting
                    {
                        continue;
                    }
                    CPKBuildObject cpk = new CPKBuildObject();
                    if (!cpk.BuildCPK(file))
                    {
                        eventArgs.Result = false;
                    }
                }
            }

            Thread.Sleep(1000); // this is another aesthetic sleep, ensuring the the progress bar does not disappear before the user can see it completing

            using (System.IO.StreamWriter logFile = new System.IO.StreamWriter(buildDir + Path.DirectorySeparatorChar + "build.log", true))
            {
                CPKBuildObject.changedCPKs.ForEach(changedCPK => logFile.WriteLine(changedCPK));
            }

            eventArgs.Result = true;
        }