Beispiel #1
0
        //作者:Wetor
        //时间:2019.7.25
        public static void Pack(string file)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            string out_file = Path.Combine(Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(file));
            string in_dir   = out_file + "_unpacked" + Path.DirectorySeparatorChar;

            out_file += ".out";
            Stream       header     = new StreamReader(file).BaseStream;
            PAKHeader    pak_header = new PAKHeader();
            StructReader Reader     = new StructReader(header, Encoding: Encoding.GetEncoding(coding));

            Reader.ReadStruct(ref pak_header);

            BinaryWriter bw       = new BinaryWriter(File.Open(out_file, FileMode.Create));
            long         save_pos = Reader.BaseStream.Position;

            Reader.Seek(0, SeekOrigin.Begin);
            bw.Write(Reader.ReadBytes((int)Reader.BaseStream.Length));//复制文件头信息
            Reader.Seek(save_pos, SeekOrigin.Begin);


            //从保存的文件头中读取文件名等信息
            while (Reader.PeekInt() != pak_header.HeaderLength / pak_header.BlockSize)
            {
                Reader.Seek(0x4, SeekOrigin.Current);
            }

            bool Named = (pak_header.Flags & (uint)PackgetFlags.NamedFiles) != 0;

            string[] Names = new string[pak_header.FileCount];
            if (Named)
            {
                long Off = Reader.BaseStream.Position;
                Reader.Seek(-0x4, SeekOrigin.Current);
                Reader.Seek(Reader.ReadUInt32(), SeekOrigin.Begin);

                for (uint i = 0; i < Names.Length; i++)
                {
                    List <byte> strArr = new List <byte> {
                    };
                    byte tmp           = Reader.ReadByte();
                    while (tmp != 0x00)
                    {
                        strArr.Add(tmp);
                        tmp = Reader.ReadByte();
                    }
                    Names[i] = Encoding.GetEncoding(coding).GetString(strArr.ToArray());
                    int ID = 1;
                    for (int j = 0; j < i; j++)
                    {
                        if (Names[j] == Names[i])
                        {
                            ID++;
                        }
                    }
                    if (ID > 1)
                    {
                        Names[i] += "." + ID.ToString();
                    }
                }
                Reader.Seek(Off, SeekOrigin.Begin);
            }
            else
            {
                for (uint i = 0; i < Names.Length; i++)
                {
                    Names[i] = i.ToString("X8");
                }
            }
            //写入文件

            for (uint i = 0; i < pak_header.FileCount; i++)
            {
                Entry out_file_info;
                out_file_info.Offset  = (uint)(bw.BaseStream.Position / pak_header.BlockSize);
                out_file_info.Content = File.Open(in_dir + Names[i], FileMode.Open);
                out_file_info.Length  = (uint)out_file_info.Content.Length;

                out_file_info.Content.CopyTo(bw.BaseStream);
                save_pos = bw.BaseStream.Position;
                bw.Seek((int)Reader.BaseStream.Position, SeekOrigin.Begin);
                bw.Write(BitConverter.GetBytes(out_file_info.Offset));
                bw.Write(BitConverter.GetBytes(out_file_info.Length));
                bw.Seek((int)save_pos, SeekOrigin.Begin);
                if (i == pak_header.FileCount - 1)
                {
                    while (bw.BaseStream.Position % pak_header.BlockSize != 0)
                    {
                        bw.Write((byte)0x00);
                    }
                }
                else if (save_pos % pak_header.BlockSize != 0)
                {
                    bw.Seek((int)(pak_header.BlockSize - (save_pos % pak_header.BlockSize)), SeekOrigin.Current);
                }


                Reader.Seek(0x08, SeekOrigin.Current);
                Console.WriteLine("{0:X} {1} {2}", out_file_info.Offset, Names[i], out_file_info.Length);
                //AppendArray(ref Files, File);
            }

            bw.Close();
            Reader.Close();
            header.Close();
        }
Beispiel #2
0
        public static Entry[] Unpack(Stream Packget, out uint data_pos)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            var          Files  = new Entry[0];
            PAKHeader    Header = new PAKHeader();
            StructReader Reader = new StructReader(Packget, Encoding: Encoding.GetEncoding(coding));

            Reader.ReadStruct(ref Header);
            Reader.Seek(0x24, SeekOrigin.Begin);
            data_pos = Header.HeaderLength;
            //Search for the First Offset
            while (Reader.PeekInt() != Header.HeaderLength / Header.BlockSize)
            {
                Reader.Seek(0x4, SeekOrigin.Current);
            }


            bool Named = (Header.Flags & (uint)PackgetFlags.NamedFiles) != 0;

            string[] Names = new string[Header.FileCount];
            if (Named)
            {
                long Off = Reader.BaseStream.Position;
                Reader.Seek(-0x4, SeekOrigin.Current);
                Reader.Seek(Reader.ReadUInt32(), SeekOrigin.Begin);

                for (uint i = 0; i < Names.Length; i++)
                {
                    List <byte> strArr = new List <byte> {
                    };
                    byte tmp           = Reader.ReadByte();
                    while (tmp != 0x00)
                    {
                        strArr.Add(tmp);
                        tmp = Reader.ReadByte();
                    }

                    Names[i] = Encoding.GetEncoding(coding).GetString(strArr.ToArray());
                    //Console.WriteLine("{0}  {1}", Names[i], i);
                    //Names[i] = Reader.ReadString(StringStyle.CString);
                }
                Reader.Seek(Off, SeekOrigin.Begin);
            }
            else
            {
                for (uint i = 0; i < Names.Length; i++)
                {
                    Names[i] = i.ToString("X8");
                }
            }


            for (uint i = 0; i < Header.FileCount; i++)
            {
                var File = new Entry();
                Reader.ReadStruct(ref File);

                File.Offset  *= Header.BlockSize;
                File.FileName = Names[Files.LongLength];
                File.Content  = new VirtStream(Packget, File.Offset, File.Length);

                AppendArray(ref Files, File);
            }
            return(Files);
        }