Пример #1
0
        /// <summary>
        /// 解压到路径。
        /// </summary>
        /// <param name="InFile">文件路径</param>
        /// <param name="OutDirectory">解压路径</param>
        public static void Unpack(string InFile, string OutDirectory)
        {
            using (FileStream pak = File.OpenRead(InFile))
            {
                if (PakUtils.CheckMagic(pak, "GsPack4 abc"))
                {
                    if (OutDirectory == null || OutDirectory.Length == 0)
                    {
                        OutDirectory = Path.GetFileName(InFile);
                    }
                    Directory.CreateDirectory(OutDirectory);

                    Pak_Header pak_header = PakUtils.ToStruct <Pak_Header>(pak);

                    pak.Seek(pak_header.index_offset, SeekOrigin.Begin);
                    byte[] pak_compress = new byte[pak_header.index_length];
                    pak.Read(pak_compress, 0, pak_compress.Length);
                    byte[] pak_decompress = PakUtils.LZSS.Decompress(pak_compress);

                    Pak_Entry[] pak_entries = PakUtils.ToStructArray <Pak_Entry>(pak_decompress);
                    for (int i = 0; i < pak_entries.Length; i++)
                    {
                        Pak_Entry pak_entry = pak_entries[i];

                        pak.Seek(pak_header.data_offset, SeekOrigin.Begin);
                        pak.Seek(pak_entry.offset, SeekOrigin.Current);
                        byte[] data = new byte[pak_entry.length];
                        pak.Read(data, 0, (int)pak_entry.length);

                        using (MemoryStream data_stream = new MemoryStream(data))
                        {
                            if (PakUtils.CheckMagic(data_stream, "Scw4.x"))
                            {
                                UnpackScw4(OutDirectory, pak_entry, data_stream);
                            }
                            else
                            {
                                // TODO 处理图片文件
                            }
                        }
                    }
                }
                else
                {
                    throw new PakException.MagicMissMatching(Path.GetFileName(InFile));
                }
            }
        }
Пример #2
0
        private static void UnpackScw4(string OutDirectory, Pak_Entry pak_entry, MemoryStream data_stream)
        {
            //解压缩
            Scw_Header scw4_header = PakUtils.ToStruct <Scw_Header>(data_stream);

            byte[] scw_compress = new byte[scw4_header.comprlen];
            data_stream.Read(scw_compress, 0, scw_compress.Length);

            if (scw4_header.is_compr == -1)
            {
                for (int i = 0; i < scw_compress.Length; i++)
                {
                    scw_compress[i] ^= Convert.ToByte(i & 0xFF);
                }
            }

            byte[] scw_decompress = PakUtils.LZSS.Decompress(scw_compress);

            using (MemoryStream decompress_stream = new MemoryStream(scw_decompress))
            {
                string directory = Path.Combine(OutDirectory, pak_entry.name);
                Directory.CreateDirectory(directory);

                int size = Marshal.SizeOf(typeof(Scw4_Entry));

                byte[] instruction_table = new byte[scw4_header.instruction_table_entries * size];
                decompress_stream.Read(instruction_table, 0, instruction_table.Length);
                File.WriteAllBytes(Path.Combine(directory, "instruction_table.bin"), instruction_table);
                Scw4_Entry[] instruction_entries = PakUtils.ToStructArray <Scw4_Entry>(instruction_table);


                byte[] script_table = new byte[scw4_header.string_table_entries * size];
                decompress_stream.Read(script_table, 0, script_table.Length);
                Scw4_Entry[] script_entries = PakUtils.ToStructArray <Scw4_Entry>(script_table);

                byte[] method_table = new byte[scw4_header.unknown_table_entries * size];
                decompress_stream.Read(method_table, 0, method_table.Length);
                File.WriteAllBytes(Path.Combine(directory, "method_table.bin"), method_table);
                Scw4_Entry[] method_entries = PakUtils.ToStructArray <Scw4_Entry>(method_table);

                using (BinaryWriter writer = new BinaryWriter(File.Open(Path.Combine(directory, "instruction.bin"), FileMode.Create)))
                {
                    foreach (Scw4_Entry scw_entry in instruction_entries)
                    {
                        byte[] data = new byte[scw_entry.length];
                        decompress_stream.Read(data, 0, data.Length);
                        writer.Write(data);
                    }
                }

                using (StreamWriter writer = new StreamWriter(Path.Combine(OutDirectory, pak_entry.name + ".txt"), false, Encoding.GetEncoding("GB2312")))
                //using (StreamWriter writer = new StreamWriter(Path.Combine(directory, "script.txt"), false, Encoding.GetEncoding("GB2312")))
                {
                    foreach (Scw4_Entry scw_entry in script_entries)
                    {
                        byte[] data = new byte[scw_entry.length];
                        decompress_stream.Read(data, 0, data.Length);

                        string text = Encoding.GetEncoding("Shift_JIS").GetString(data);
                        writer.WriteLine($":{text}");
                        writer.WriteLine($":{text}");
                        writer.WriteLine();
                    }
                }
                using (BinaryWriter writer = new BinaryWriter(File.Open(Path.Combine(directory, "method.bin"), FileMode.Create)))
                {
                    long   length = decompress_stream.Length - decompress_stream.Position;
                    byte[] data   = new byte[length];
                    decompress_stream.Read(data, 0, data.Length);
                    writer.Write(data);
                }
            }
        }