コード例 #1
0
ファイル: ArchiveEngine.cs プロジェクト: lucgomoliv/uPCK
        private void _Unpack(string path)
        {
            string dir = $"{path}.files";

            if (Directory.Exists(dir))
            {
                form.UpdateProgress(form.Controls["lblProgress"], "Removing Existing Directory");
                Directory.Delete(dir, true);
            }
            Directory.CreateDirectory(dir);
            PCKStream stream = new PCKStream(path);

            stream.Seek(-4, SeekOrigin.End);
            version = stream.ReadInt16();
            events  = new CountdownEvent(GetFilesCount(stream));
            IEnumerator <PCKFileEntry> enumerator;

            //Select wich version to read
            if (version == 3)
            {
                enumerator = ReadFileV3(stream).GetEnumerator();
            }
            else
            {
                enumerator = ReadFileV2(stream).GetEnumerator();
            }
            while (enumerator.MoveNext())
            {
                string p = Path.Combine(dir, Path.GetDirectoryName(enumerator.Current.Path));
                if (!Directory.Exists(p))
                {
                    Directory.CreateDirectory(p);
                }
                form.UpdateProgress(form.Controls["lblProgress"],
                                    $"Unpacking " +
                                    $"{(form.Controls["progBar"] as ProgressBar).Value}" +
                                    $"/{(form.Controls["progBar"] as ProgressBar).Maximum}: " +
                                    $"{ enumerator.Current.Path }");
                stream.Seek(enumerator.Current.Offset, SeekOrigin.Begin);
                byte[] file = stream.ReadBytes(enumerator.Current.CompressedSize);
                ThreadPool.QueueUserWorkItem(x => {
                    byte[] buffer      = (x as object[])[0] as byte[];
                    PCKFileEntry entry = (x as object[])[1] as PCKFileEntry;
                    File.WriteAllBytes(Path.Combine(dir, entry.Path), buffer.Length < entry.Size ? PCKZlib.Decompress(buffer, entry.Size) : buffer);
                    events.Signal();
                }, new object[] { file, enumerator.Current });
                form.UpdateProgressBar(form.Controls["progBar"], "value", ((ProgressBar)form.Controls["progBar"]).Value + 1);
            }
            form.UpdateProgress(form.Controls["lblProgress"], "WaitThreads");
            events.Wait();
            stream.Dispose();
            form.UpdateProgressBar(form.Controls["progBar"], "value", 0);
            form.UpdateProgress(form.Controls["lblProgress"], "Ready");
        }
コード例 #2
0
ファイル: ArchiveEngine.cs プロジェクト: lucgomoliv/uPCK
 public byte[] ReadFile(PCKStream stream, PCKFileEntry file)
 {
     stream.Seek(file.Offset, SeekOrigin.Begin);
     byte[] bytes = stream.ReadBytes(file.CompressedSize);
     return(file.CompressedSize < file.Size ? PCKZlib.Decompress(bytes, file.Size) : bytes);
 }
コード例 #3
0
ファイル: ArchiveEngine.cs プロジェクト: lucgomoliv/uPCK
        public void _Compress(string dir)
        {
            string pck = dir.Replace(".files", "");

            if (File.Exists(pck))
            {
                File.Delete(pck);
            }
            if (File.Exists(pck.Replace(".pck", ".pkx")))
            {
                File.Delete(pck.Replace(".pck", ".pkx"));
            }
            form.UpdateProgress(form.Controls["lblProgress"], "Listing the files");
            string[]  files  = Directory.GetFiles(dir, "*", SearchOption.AllDirectories);
            PCKStream stream = new PCKStream(pck);

            stream.WriteInt32(stream.key.FSIG_1);
            stream.WriteInt32(0);
            stream.WriteInt32(stream.key.FSIG_2);
            form.UpdateProgressBar(form.Controls["progBar"], "max", files.Length);
            MemoryStream FileTable = new MemoryStream();

            events = new CountdownEvent(files.Length);
            ManualResetEvent[] mres = new ManualResetEvent[files.Length];
            for (int i = 0; i < files.Length; i++)
            {
                mres[i] = new ManualResetEvent(false);
                ThreadPool.QueueUserWorkItem(x => {
                    int pos             = (int)x;
                    string file         = files[pos].Replace(dir, "").Replace("/", "\\").Remove(0, 1);
                    byte[] decompressed = File.ReadAllBytes(Path.Combine(dir, files[pos]));
                    byte[] compressed   = PCKZlib.Compress(decompressed, compressionLevel);
                    var entry           = new PCKFileEntry()
                    {
                        Path           = file,
                        Offset         = (uint)stream.Position,
                        Size           = decompressed.Length,
                        CompressedSize = compressed.Length
                    };
                    byte[] buffer = entry.Write(compressionLevel);
                    lock (FileTable)
                    {
                        FileTable.Write(BitConverter.GetBytes(buffer.Length ^ stream.key.KEY_1), 0, 4);
                        FileTable.Write(BitConverter.GetBytes(buffer.Length ^ stream.key.KEY_2), 0, 4);
                        FileTable.Write(buffer, 0, buffer.Length);
                    }
                    if (pos > 0)
                    {
                        mres[pos - 1].WaitOne();
                    }
                    stream.WriteBytes(compressed);
                    form.UpdateProgressBar(form.Controls["progBar"], "value", pos);
                    form.UpdateProgress(form.Controls["lblProgress"], "Compressing " +
                                        ((ProgressBar)form.Controls["progBar"]).Value + "/" +
                                        ((ProgressBar)form.Controls["progBar"]).Maximum + " : " + file);
                    mres[pos].Set();
                    events.Signal();
                }, i);
            }
            form.UpdateProgress(form.Controls["lblProgress"], "Waiting Threads to Finish");
            events.Wait();
            long FileTableOffset = stream.Position;

            stream.WriteBytes(FileTable.ToArray());
            stream.WriteInt32(stream.key.ASIG_1);                                                  //4
            stream.WriteInt16(2);                                                                  //2
            stream.WriteInt16(2);                                                                  //2
            stream.WriteUInt32((uint)(FileTableOffset ^ stream.key.KEY_1));                        //4
            stream.WriteInt32(0);                                                                  //4
            stream.WriteBytes(Encoding.Default.GetBytes("Angelica File Package, Perfect World.")); //37
            byte[] nuller = new byte[215];
            stream.WriteBytes(nuller);                                                             //215 - 268
            stream.WriteInt32(stream.key.ASIG_2);                                                  //4
            stream.WriteInt32(files.Length);                                                       //4
            stream.WriteInt16(2);                                                                  //2
            stream.WriteInt16(2);                                                                  //2
            stream.Seek(4, SeekOrigin.Begin);
            stream.WriteUInt32((uint)stream.GetLenght());
            stream.Dispose();
            form.UpdateProgressBar(form.Controls["progBar"], "value", 0);
            form.UpdateProgress(form.Controls["lblProgress"], "Ready");
        }