public static void UnpackFiles(string psbPath, string outputPath, MArchivePacker maPacker = null) { // Figure out what file we've been given if (Path.GetExtension(psbPath).ToLower() == ".bin") { psbPath = Path.ChangeExtension(psbPath, ".psb"); } // No PSB, try .psb.m if (!File.Exists(psbPath)) { psbPath += ".m"; } if (Path.GetExtension(psbPath).ToLower() == ".m") { // Decompress .m file if (maPacker == null) { throw new ArgumentNullException(nameof(maPacker)); } maPacker.DecompressFile(psbPath, true); psbPath = Path.ChangeExtension(psbPath, null); } ArchiveV1 arch; using (FileStream fs = File.OpenRead(psbPath)) using (PsbReader reader = new PsbReader(fs)) { var root = reader.Root; arch = root.ToObject <ArchiveV1>(); } if (arch.ObjectType != "archive" || arch.Version != 1.0) { throw new InvalidDataException("PSB file is not an archive."); } using (FileStream fs = File.OpenRead(Path.ChangeExtension(psbPath, ".bin"))) { foreach (var file in arch.FileInfo) { Console.WriteLine($"Extracting {file.Key}"); string outPath = Path.Combine(outputPath, file.Key); Directory.CreateDirectory(Path.GetDirectoryName(outPath)); using (FileStream ofs = File.Create(outPath)) { fs.Seek(file.Value[0], SeekOrigin.Begin); Utils.CopyStream(fs, ofs, file.Value[1]); } } } }
public static void Build(string folderPath, string outputPath, MArchivePacker maPacker = null, IPsbFilter filter = null) { using (FileStream packStream = File.Create(outputPath + ".bin")) using (FileStream psbStream = File.Create(outputPath + ".psb")) { ArchiveV1 archive = new ArchiveV1(); archive.ObjectType = "archive"; archive.Version = 1.0f; archive.FileInfo = new Dictionary <string, List <int> >(); folderPath = Path.GetFullPath(folderPath); foreach (var file in Directory.GetFiles(folderPath, "*", SearchOption.AllDirectories)) { string key = file.Replace(folderPath, string.Empty).TrimStart('/', '\\'); Console.WriteLine($"Packing {key}"); var targetLength = (packStream.Position + ALIGNMENT - 1) / ALIGNMENT * ALIGNMENT; byte[] alignBytes = new byte[targetLength - packStream.Length]; packStream.Write(alignBytes, 0, alignBytes.Length); var currPos = packStream.Position; using (FileStream fs = File.OpenRead(file)) { fs.CopyTo(packStream); archive.FileInfo.Add(key.Replace('\\', '/'), new List <int>() { (int)currPos, (int)fs.Length }); } } JToken root = JToken.FromObject(archive); PsbWriter writer = new PsbWriter(root, null) { Version = 3 }; writer.Write(psbStream, filter); } if (maPacker != null) { maPacker.CompressFile(outputPath + ".psb"); } }