Example #1
0
        public void Run()
        {
            input += "\\";
            String header = input + "HEADER.data";

            FileInfo fileInfo;
            String   searchedName;

            using (FileStream fs = new FileStream(header, FileMode.Open, FileAccess.Read))
                using (BinaryReader headerStream = new BinaryReader(fs))
                {
                    this.StatusText = "Reading structure...";
                    OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);

                    CPTRStruct  cptrData = new CPTRStruct();
                    DPTRStruct  ptrData  = new DPTRStruct(headerStream);
                    PKRStruct[] table    = ptrData.Files;

                    this.TotalFiles      = (int)table.Length;
                    this.CurrentProgress = 0;

                    OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);

                    int    pkrOffset = 16;
                    byte[] compressedContainer;
                    byte[] ending = { 0, 0, 255, 255 };

                    byte[] bytes;

                    bytes = PKRStruct.Magic;
                    this.SaveData(ref bytes, outputPkr);

                    bytes = new byte[12];
                    this.SaveData(ref bytes, outputPkr);

                    bytes = null;

                    for (int i = 0; i < table.Length; ++i)
                    {
                        this.CurrentProgress = i;
                        OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);
                        if (ptrData.Filenames.ElementAtOrDefault(table[i].NameID) != null)
                        {
                            this.StatusText = "Importing: " + ptrData.Filenames[table[i].NameID];
                            OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);

                            searchedName = input + ptrData.Filenames[table[i].NameID];
                            fileInfo     = new FileInfo(searchedName);

                            if (fileInfo.Extension.Equals(".lanb") && new FileInfo(searchedName + ".txt").Exists)
                            {
                                this.StatusText = "Converting text data from: " + searchedName + ".txt";
                                this.ImportLanb(fileInfo.FullName, searchedName + ".txt");
                            }
                            else if (fileInfo.Name.Equals("48.dat") && new FileInfo(searchedName + ".xml").Exists)
                            {
                                this.StatusText = "Converting font map from: " + searchedName + ".txt";
                                this.ImportFontMap(fileInfo.FullName, searchedName + ".xml");
                            }

                            compressedContainer = this.GetFileData(searchedName);

                            table[i].Offset           = pkrOffset;
                            table[i].CompressedSize   = compressedContainer.Length;
                            table[i].DecompressedSize = (int)fileInfo.Length;

                            this.SaveData(ref compressedContainer, outputPkr);

                            if (table[i].CompressedSize != table[i].DecompressedSize)
                            {
                                this.SaveData(ref ending, outputPkr);
                            }
                            pkrOffset += table[i].CompressedSize;

                            compressedContainer = null;
                        }
                    }

                    // Create new ptr
                    this.StatusText = "Creating new PTR file";
                    OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);
                    using (FileStream ptrStream = new FileStream(outputPtr, FileMode.Append, FileAccess.Write))
                        using (BinaryWriter ptrWriter = new BinaryWriter(ptrStream))
                        {
                            ptrWriter.Write(ptrData.FilesCount);
                            ptrWriter.Write(ptrData.Unknown2);
                            ptrWriter.Write(ptrData.Unknown3);
                            ptrWriter.Write(ptrData.Unknown4);
                            ptrWriter.Write(ptrData.Unknown5);

                            for (int i = 0; i < ptrData.UnknownDataset1.Length; ++i)
                            {
                                ptrWriter.Write(ptrData.UnknownDataset1[i]);
                            }

                            for (int i = 0; i < ptrData.UnknownDataset2.Length; ++i)
                            {
                                ptrWriter.Write(ptrData.UnknownDataset2[i]);
                            }

                            ptrWriter.Write(ptrData.NamesLength);
                            ptrWriter.Write(ptrData.NamesCount);

                            ptrWriter.Write(Encoding.UTF8.GetBytes(String.Join("\0", ptrData.Filenames)));

                            for (int i = 0; i < table.Length; ++i)
                            {
                                ptrWriter.Write(table[i].NameID);

                                ptrWriter.Write(table[i].Offset);

                                ptrWriter.Write(table[i].CompressedSize);
                                ptrWriter.Write(table[i].DecompressedSize);
                            }

                            ptrWriter.Write(ptrData.Someshit);
                        }

                    // new PKR hash
                    this.StatusText = "Calculate new PKR hash";
                    OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);
                    byte[] PkrHashData = new byte[0x8000];
                    using (FileStream pkrfs = new FileStream(outputPkr, FileMode.Open, FileAccess.Read))
                        using (BinaryReader pkrbr = new BinaryReader(pkrfs))
                        {
                            pkrbr.BaseStream.Seek(16, SeekOrigin.Begin);
                            PkrHashData = pkrbr.ReadBytes(PkrHashData.Length);
                        }

                    byte[] MD5PkrHash  = this.MD5hash(PkrHashData);
                    int    MD5FinalPkr = 0;
                    for (int i = 0; i < MD5PkrHash.Length; i += 4)
                    {
                        MD5FinalPkr = MD5FinalPkr ^ BitConverter.ToInt32(MD5PkrHash.Skip(i).Take(4).ToArray(), 0);
                    }

                    // new PTR hash
                    this.StatusText = "Calculate new PTR hash";
                    OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);
                    byte[] MD5PtrHash  = this.MD5hash(File.ReadAllBytes(outputPtr));
                    int    MD5FinalPtr = 0;
                    for (int i = 0; i < MD5PtrHash.Length; i += 4)
                    {
                        MD5FinalPtr = MD5FinalPtr ^ BitConverter.ToInt32(MD5PtrHash.Skip(i).Take(4).ToArray(), 0);
                    }

                    cptrData.DecompressedSize = cptrData.CryptSize((int)(new FileInfo(outputPtr).Length));
                    cptrData.PkrChecksum      = MD5FinalPkr;
                    cptrData.PtrChecksum      = MD5FinalPtr;

                    byte[] compressedPTR = this.Compress(outputPtr);

                    using (FileStream compressedFS = new FileStream(outputPtr, FileMode.Create, FileAccess.Write))
                        using (BinaryWriter cPTR = new BinaryWriter(compressedFS))
                        {
                            cPTR.Write(cptrData.DecompressedSize);
                            cPTR.Write(cptrData.Version);
                            cPTR.Write(cptrData.PkrChecksum);
                            cPTR.Write(cptrData.PtrChecksum);

                            cPTR.Write(compressedPTR);
                            cPTR.Write(ending);
                        }

                    compressedPTR = null;

                    GC.Collect();
                    GC.WaitForPendingFinalizers();

                    this.StatusText      = "Done";
                    this.CurrentProgress = this.TotalFiles;
                    OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);
                }
        }
Example #2
0
        public void Run()
        {
            output += "\\";
            String header = output + "HEADER.data";

            FileInfo file = new FileInfo(output);

            Directory.CreateDirectory(file.DirectoryName);

            using (FileStream fs = new FileStream(input, FileMode.Open, FileAccess.Read))
                using (BinaryReader data = new BinaryReader(fs))
                {
                    this.StatusText = "Getting PTR structure...";
                    OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);

                    CPTRStruct cptr = new CPTRStruct(data);

                    byte[] compessedData       = data.ReadBytes((int)(data.BaseStream.Length - 0x10));
                    byte[] decompressedPTRData = this.DecompressData(ref compessedData);

                    using (BufferedStream stream = new BufferedStream(new FileStream(header, FileMode.Create, FileAccess.Write)))
                    {
                        stream.Write(decompressedPTRData, 0, decompressedPTRData.Length);
                    }

                    using (BinaryReader ptrData = new BinaryReader(new FileStream(header, FileMode.Open, FileAccess.Read)))
                    {
                        DPTRStruct  ptr   = new DPTRStruct(ptrData);
                        PKRStruct[] table = ptr.Files;

                        this.TotalFiles      = (int)ptr.FilesCount;
                        this.CurrentProgress = 0;
                        OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);

                        using (FileStream pkrFS = new FileStream(pkrFile, FileMode.Open, FileAccess.Read))
                            using (BinaryReader pkr = new BinaryReader(pkrFS))
                            {
                                byte[]   pkrData;
                                string   outputFile;
                                FileInfo extractedFile;

                                for (int i = 0; i < ptr.FilesCount; ++i)
                                {
                                    this.CurrentProgress = i;
                                    OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);

                                    pkr.BaseStream.Seek(table[i].Offset, SeekOrigin.Begin);

                                    if (ptr.Filenames.ElementAtOrDefault(table[i].NameID) != null)
                                    {
                                        this.StatusText = "Extracting: " + ptr.Filenames[table[i].NameID];
                                        OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);

                                        outputFile = output + ptr.Filenames[table[i].NameID];
                                        pkrData    = pkr.ReadBytes(table[i].CompressedSize);

                                        if (table[i].CompressedSize != table[i].DecompressedSize)
                                        {
                                            pkrData = this.DecompressData(ref pkrData);
                                        }

                                        extractedFile = new FileInfo(outputFile);

                                        this.SaveData(ref pkrData, outputFile);

                                        pkrData = null;

                                        // File extension is lanb -> convert it.
                                        if (extractedFile.Extension.Equals(".lanb"))
                                        {
                                            this.StatusText = "Converting text file: " + ptr.Filenames[table[i].NameID];

                                            using (FileStream lanbFS = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
                                                using (BinaryReader lanbReader = new BinaryReader(lanbFS))
                                                {
                                                    LABNStruct lanbData = new LABNStruct(lanbReader);

                                                    using (StreamWriter lanbWriter = new StreamWriter(outputFile + ".txt"))
                                                    {
                                                        for (int j = 0; j < lanbData.StringCount; ++j)
                                                        {
                                                            lanbWriter.WriteLine(lanbData.RowsName[j]);
                                                            lanbWriter.WriteLine(lanbData.RowsText[j]);
                                                        }
                                                    }
                                                }
                                        }
                                        // File name is 48.dat -> convert to xml map. (some games 64_df.dat)
                                        else if (extractedFile.Name.Equals("48.dat"))
                                        {
                                            this.StatusText = "Converting font map: " + ptr.Filenames[table[i].NameID];

                                            using (FileStream idfFS = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
                                                using (BinaryReader idfReader = new BinaryReader(idfFS))
                                                {
                                                    IDFStruct       idfData   = new IDFStruct(idfReader);
                                                    IDFCharStruct[] charsData = idfData.CharsData;

                                                    using (StreamWriter lanbWriter = new StreamWriter(outputFile + ".xml"))
                                                    {
                                                        lanbWriter.WriteLine("<GeneralData " +
                                                                             "chars=\"" + idfData.CharsCount +
                                                                             "\" param1=\"" + idfData.Unknown1 +
                                                                             "\" param2=\"" + idfData.Unknown2 +
                                                                             "\" param3=\"" + idfData.Unknown3 + "\" />"
                                                                             );

                                                        for (int j = 0; j < charsData.Length; ++j)
                                                        {
                                                            lanbWriter.WriteLine("<Char " +
                                                                                 "id=\"" + charsData[j].CharID +
                                                                                 "\" x=\"" + charsData[j].LeftTopX +
                                                                                 "\" y=\"" + charsData[j].LeftTopY +
                                                                                 "\" width=\"" + charsData[j].Width +
                                                                                 "\" height=\"" + charsData[j].Height +
                                                                                 "\" bearingX=\"" + charsData[j].BearingX +
                                                                                 "\" bearingY=\"" + charsData[j].BearingY +
                                                                                 "\" advanceX=\"" + charsData[j].AdvanceX +
                                                                                 "\" advanceY=\"" + charsData[j].AdvanceY + "\" />"
                                                                                 );
                                                        }
                                                    }
                                                }
                                        }
                                    }
                                }
                            }
                    }
                }

            GC.Collect();
            GC.WaitForPendingFinalizers();

            this.StatusText      = "Done";
            this.CurrentProgress = this.TotalFiles;
            OnProgressUpdate?.Invoke(this.CurrentProgress, this.TotalFiles, this.StatusText);
        }