private void PackPckg(string inputPath, string outputPath) { var entries = new List <PathEntry>(); var pckg = new PckgFile(); // Searching for archives... var inputPaths = new List <string>(); inputPaths.AddRange(Directory.GetFiles(inputPath, "*", SearchOption.TopDirectoryOnly)); foreach (var path in inputPaths) { string name = Path.GetFileNameWithoutExtension(path); ulong hash = 0; if (Helpers.IsHexString(name)) { hash = Helpers.HexLiteral2Unsigned(name); } else { hash = FileFormats.Hashing.FNV64.Hash(name); } entries.Add(new PathEntry() { NameHash = hash, Offset = 0, Unk1 = 0, Size = 0, Size2 = 0, Widgth = 0, Heigth = 0, Unk2 = 0, Path = path, }); } uint headerSize = (uint)PckgFile.EstimateHeaderSize(entries.Count); long firstOffset = entries.Count * 32 + headerSize; long localOffset = firstOffset; Stream data = File.Create(outputPath); int percents = 0; int current = 0; int total = entries.Count; foreach (var entry in entries) { current++; // verbose if (InvokeRequired == true) { Invoke((MethodInvoker) delegate { progressBar1.Value = percents; resultLabel.Text = "Pack \"" + entry.Path + "\""; }); } using (var input = File.OpenRead(entry.Path)) { var length = (uint)input.Length; data.Seek(localOffset, SeekOrigin.Begin); data.WriteFromStream(input, length); ushort height = 0; ushort width = 0; input.Seek(0L, SeekOrigin.Begin); if (input.Length >= 16 && input.ReadValueU32() == 542327876) { input.Seek(0x0c, SeekOrigin.Begin); height = input.ReadValueU16(); input.Seek(0x10, SeekOrigin.Begin); width = input.ReadValueU16(); } entry.Size = length; entry.Size2 = length; entry.Offset = (uint)localOffset; entry.Widgth = width; entry.Heigth = height; pckg.Entries.Add(entry); localOffset += length; } percents = ((current + 1) * 100) / total; } if (data != null) { data.Close(); } using (var output = File.OpenWrite(outputPath)) { pckg.Serialize(output); } if (InvokeRequired == true) { Invoke((MethodInvoker) delegate { progressBar1.Value = 0; resultLabel.Text = "Done \"" + outputPath + "\""; buttonPack.Enabled = true; buttonUnpack.Enabled = true; }); } }
private void UnpackPckg(string inputPath, string outputPath) { var pckg = new PckgFile(); using (var input = File.OpenRead(inputPath)) { pckg.Deserialize(input); } Directory.CreateDirectory(outputPath); Stream data = File.OpenRead(inputPath); int percents = 0; int current = 0; int total = pckg.Entries.Count; foreach (var entry in pckg.Entries.OrderBy(e => e.Offset)) { current++; long entryOffset = entry.Offset; // detect type string extension; { var guess = new byte[64]; int read = 0; if (entry.Size > 0) { data.Seek(entryOffset, SeekOrigin.Begin); read = data.Read(guess, 0, (int)Math.Min(entry.Size, guess.Length)); } extension = Helpers.ExtensionsDetect(guess, Math.Min(guess.Length, read)); } // string name = "0x" + entry.NameHash.ToString("X16"); string name = entry.NameHash.ToString("X16"); name = Path.ChangeExtension(name, "." + extension); var entryPath = Path.Combine(outputPath, name); // Directory.CreateDirectory(Path.GetDirectoryName(entryPath)); using (var output = File.Create(entryPath)) { if (entry.Size > 0) { data.Seek(entryOffset, SeekOrigin.Begin); output.WriteFromStream(data, entry.Size); } } // verbose if (InvokeRequired == true) { Invoke((MethodInvoker) delegate { progressBar1.Value = percents; resultLabel.Text = entryPath; }); } percents = ((current + 1) * 100) / total; } if (data != null) { data.Close(); } if (InvokeRequired == true) { Invoke((MethodInvoker) delegate { progressBar1.Value = 0; resultLabel.Text = "Done"; buttonUnpack.Enabled = true; buttonPack.Enabled = true; }); } }