Exemplo n.º 1
0
        // Taken from CriPakTools - see adknowledgements
        private void ReplaceCPKFiles(string sourceCPK, string targetCPK, Dictionary <string, string> batchFileList)
        {
            CPK cpk = new CPK(new Tools());

            cpk.ReadCPK(sourceCPK, ActiveEncodings.currentEncoding);

            BinaryReader oldFile      = new BinaryReader(File.OpenRead(sourceCPK));
            bool         bUseCompress = false; // this could cause problems later if access to compressed files is needed

            FileInfo fi = new FileInfo(sourceCPK);

            string outputName = targetCPK;

            BinaryWriter newCPK = new BinaryWriter(File.OpenWrite(outputName));

            List <FileEntry> entries = cpk.FileTable.OrderBy(x => x.FileOffset).ToList();

            Tools tool = new Tools();

            for (int i = 0; i < entries.Count; i++)
            {
                if (entries[i].FileType != "CONTENT")
                {
                    if (entries[i].FileType == "FILE")
                    {
                        // I'm too lazy to figure out how to update the ContextOffset position so this works :)
                        if ((ulong)newCPK.BaseStream.Position < cpk.ContentOffset)
                        {
                            ulong padLength = cpk.ContentOffset - (ulong)newCPK.BaseStream.Position;
                            for (ulong z = 0; z < padLength; z++)
                            {
                                newCPK.Write((byte)0);
                            }
                        }
                    }

                    string currentName = ((entries[i].DirName != null) ? entries[i].DirName + "/" : "") + entries[i].FileName;

                    if (!currentName.Contains("/"))
                    {
                        currentName = "/" + currentName;
                    }

                    if (!batchFileList.Keys.Contains(currentName.ToString()))
                    //如果不在表中,复制原始数据
                    {
                        oldFile.BaseStream.Seek((long)entries[i].FileOffset, SeekOrigin.Begin);

                        entries[i].FileOffset = (ulong)newCPK.BaseStream.Position;

                        if (entries[i].FileName.ToString() == "ETOC_HDR")
                        {
                            cpk.EtocOffset = entries[i].FileOffset;
                            Console.WriteLine("Fix ETOC_OFFSET to {0:x8}", cpk.EtocOffset);
                        }

                        cpk.UpdateFileEntry(entries[i]);

                        byte[] chunk = oldFile.ReadBytes(Int32.Parse(entries[i].FileSize.ToString()));
                        newCPK.Write(chunk);

                        if ((newCPK.BaseStream.Position % 0x800) > 0 && i < entries.Count - 1)
                        {
                            long cur_pos = newCPK.BaseStream.Position;
                            for (int j = 0; j < (0x800 - (cur_pos % 0x800)); j++)
                            {
                                newCPK.Write((byte)0);
                            }
                        }
                    }
                    else
                    {
                        string replace_with = batchFileList[currentName.ToString()];
                        //Got patch file name
                        Console.WriteLine("Patching: {0}", currentName.ToString());

                        byte[] newbie = File.ReadAllBytes(replace_with);
                        entries[i].FileOffset = (ulong)newCPK.BaseStream.Position;
                        int o_ext_size = Int32.Parse((entries[i].ExtractSize).ToString());
                        int o_com_size = Int32.Parse((entries[i].FileSize).ToString());
                        if ((o_com_size < o_ext_size) && entries[i].FileType == "FILE" && bUseCompress == true)
                        {
                            // is compressed
                            Console.Write("Compressing data:{0:x8}", newbie.Length);

                            byte[] dest_comp = cpk.CompressCRILAYLA(newbie);

                            entries[i].FileSize    = Convert.ChangeType(dest_comp.Length, entries[i].FileSizeType);
                            entries[i].ExtractSize = Convert.ChangeType(newbie.Length, entries[i].FileSizeType);
                            cpk.UpdateFileEntry(entries[i]);
                            newCPK.Write(dest_comp);
                            Console.Write(">> {0:x8}\r\n", dest_comp.Length);
                        }

                        else
                        {
                            Console.Write("Storing data:{0:x8}\r\n", newbie.Length);
                            entries[i].FileSize    = Convert.ChangeType(newbie.Length, entries[i].FileSizeType);
                            entries[i].ExtractSize = Convert.ChangeType(newbie.Length, entries[i].FileSizeType);
                            cpk.UpdateFileEntry(entries[i]);
                            newCPK.Write(newbie);
                        }


                        if ((newCPK.BaseStream.Position % 0x800) > 0 && i < entries.Count - 1)
                        {
                            long cur_pos = newCPK.BaseStream.Position;
                            for (int j = 0; j < (0x800 - (cur_pos % 0x800)); j++)
                            {
                                newCPK.Write((byte)0);
                            }
                        }
                    }
                }
                else
                {
                    // Content is special.... just update the position
                    cpk.UpdateFileEntry(entries[i]);
                }
            }

            cpk.WriteCPK(newCPK);
            cpk.WriteITOC(newCPK);
            cpk.WriteTOC(newCPK);
            cpk.WriteETOC(newCPK, cpk.EtocOffset);
            cpk.WriteGTOC(newCPK);

            newCPK.Close();
            oldFile.Close();
        }
Exemplo n.º 2
0
        private void PatchCPK(object t)
        {
            string msg;
            string cpkDir         = ((actionCPK)t).cpkDir;
            string patchDir       = ((actionCPK)t).patchDir;
            bool   bForceCompress = ((actionCPK)t).bForceCompress;
            Dictionary <string, string> batch_file_list = ((actionCPK)t).batch_file_list;
            CPK          cpk        = myPackage.cpk;
            BinaryReader oldFile    = new BinaryReader(File.OpenRead(myPackage.cpk_name));
            string       outputName = cpkDir;

            BinaryWriter newCPK = new BinaryWriter(File.OpenWrite(outputName));

            List <FileEntry> entries = cpk.FileTable.OrderBy(x => x.FileOffset).ToList();

            Tools tool = new Tools();

            int  id;
            bool bFileRepeated = Tools.CheckListRedundant(entries);

            for (int i = 0; i < entries.Count; i++)
            {
                this.UI_SetProgess((float)i / (float)entries.Count * 100f);
                if (entries[i].FileType != "CONTENT")
                {
                    if (entries[i].FileType == "FILE")
                    {
                        // I'm too lazy to figure out how to update the ContextOffset position so this works :)
                        if ((ulong)newCPK.BaseStream.Position < cpk.ContentOffset)
                        {
                            ulong padLength = cpk.ContentOffset - (ulong)newCPK.BaseStream.Position;
                            for (ulong z = 0; z < padLength; z++)
                            {
                                newCPK.Write((byte)0);
                            }
                        }
                    }

                    id = Convert.ToInt32(entries[i].ID);
                    string currentName;

                    if (id > 0 && bFileRepeated)
                    {
                        currentName = (((entries[i].DirName != null) ?
                                        entries[i].DirName + "/" : "") + string.Format("[{0}]", id.ToString()) + entries[i].FileName);
                    }
                    else
                    {
                        currentName = ((entries[i].DirName != null) ? entries[i].DirName + "/" : "") + entries[i].FileName;
                    }



                    if (!currentName.Contains("/"))
                    {
                        currentName = "/" + currentName;
                    }
                    Debug.Print("Got File:" + currentName.ToString());

                    if (!batch_file_list.Keys.Contains(currentName.ToString()))
                    //如果不在表中,复制原始数据
                    {
                        oldFile.BaseStream.Seek((long)entries[i].FileOffset, SeekOrigin.Begin);

                        entries[i].FileOffset = (ulong)newCPK.BaseStream.Position;

                        if (entries[i].FileName.ToString() == "ETOC_HDR")
                        {
                            cpk.EtocOffset = entries[i].FileOffset;

                            Debug.Print("Fix ETOC_OFFSET to {0:x8}", cpk.EtocOffset);
                        }

                        cpk.UpdateFileEntry(entries[i]);

                        byte[] chunk = oldFile.ReadBytes(Int32.Parse(entries[i].FileSize.ToString()));
                        newCPK.Write(chunk);

                        if ((newCPK.BaseStream.Position % 0x800) > 0 && i < entries.Count - 1)
                        {
                            long cur_pos = newCPK.BaseStream.Position;
                            for (int j = 0; j < (0x800 - (cur_pos % 0x800)); j++)
                            {
                                newCPK.Write((byte)0);
                            }
                        }
                    }
                    else
                    {
                        string replace_with = batch_file_list[currentName.ToString()];
                        //Got patch file name
                        msg = string.Format("Patching: {0}", currentName.ToString());

                        this.UI_SetTextBlock(msg);
                        Debug.Print(msg);

                        byte[] newbie = File.ReadAllBytes(replace_with);
                        entries[i].FileOffset = (ulong)newCPK.BaseStream.Position;
                        int o_ext_size = Int32.Parse((entries[i].ExtractSize).ToString());
                        int o_com_size = Int32.Parse((entries[i].FileSize).ToString());
                        if ((o_com_size < o_ext_size) && entries[i].FileType == "FILE" && bForceCompress == true)
                        {
                            // is compressed
                            msg = string.Format("Compressing data:{0:x8}", newbie.Length);
                            this.UI_SetTextBlock(msg);
                            Console.Write(msg);

                            byte[] dest_comp = cpk.CompressCRILAYLA(newbie);

                            entries[i].FileSize    = Convert.ChangeType(dest_comp.Length, entries[i].FileSizeType);
                            entries[i].ExtractSize = Convert.ChangeType(newbie.Length, entries[i].FileSizeType);
                            cpk.UpdateFileEntry(entries[i]);
                            newCPK.Write(dest_comp);
                            msg = string.Format(">> {0:x8}\r\n", dest_comp.Length);
                            this.UI_SetTextBlock(msg);
                            Console.Write(msg);
                        }

                        else
                        {
                            msg = string.Format("Storing data:{0:x8}\r\n", newbie.Length);
                            this.UI_SetTextBlock(msg);
                            Console.Write(msg);

                            entries[i].FileSize    = Convert.ChangeType(newbie.Length, entries[i].FileSizeType);
                            entries[i].ExtractSize = Convert.ChangeType(newbie.Length, entries[i].FileSizeType);
                            cpk.UpdateFileEntry(entries[i]);
                            newCPK.Write(newbie);
                        }


                        if ((newCPK.BaseStream.Position % 0x800) > 0 && i < entries.Count - 1)
                        {
                            long cur_pos = newCPK.BaseStream.Position;
                            for (int j = 0; j < (0x800 - (cur_pos % 0x800)); j++)
                            {
                                newCPK.Write((byte)0);
                            }
                        }
                    }
                }
                else
                {
                    // Content is special.... just update the position
                    cpk.UpdateFileEntry(entries[i]);
                }
            }

            cpk.WriteCPK(newCPK);
            msg = string.Format("Writing TOC....");
            this.UI_SetTextBlock(msg);
            Console.WriteLine(msg);

            cpk.WriteITOC(newCPK);
            cpk.WriteTOC(newCPK);
            cpk.WriteETOC(newCPK, cpk.EtocOffset);
            cpk.WriteGTOC(newCPK);

            newCPK.Close();
            oldFile.Close();
            msg = string.Format("Saving CPK to {0}....", outputName);
            this.UI_SetTextBlock(msg);
            Console.WriteLine(msg);

            MessageBox.Show("CPK Patched.");
            this.UI_SetProgess(0f);
        }