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"); }
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); }
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"); }