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 DumpPsb(string psbPath, bool writeDebug, IPsbFilter filter = null) { using (FileStream fs = File.OpenRead(psbPath)) using (StreamWriter debugWriter = writeDebug ? File.CreateText(psbPath + ".debug.txt") : null) using (PsbReader psbReader = new PsbReader(fs, filter, debugWriter)) { Newtonsoft.Json.Linq.JToken root; try { root = psbReader.Root; } catch (Exception ex) { Console.WriteLine("Error parsing PSB"); Console.WriteLine("Current position: 0x{0:x8}", fs.Position); Console.WriteLine(ex); if (writeDebug && filter != null) { using (FileStream dcStream = File.Create(psbPath + ".decrypted")) { psbReader.DumpDecryptedStream(dcStream); } } return; } using (StreamWriter sw = File.CreateText(psbPath + ".json")) using (JsonTextWriter jtw = new JsonTextWriter(sw) { Formatting = Formatting.Indented }) { root.WriteTo(jtw); } if (psbReader.StreamCache.Count > 0 || psbReader.BStreamCache.Count > 0) { string streamsDirPath = psbPath + ".streams"; Directory.CreateDirectory(streamsDirPath); foreach (var js in psbReader.StreamCache) { File.WriteAllBytes(Path.Combine(streamsDirPath, "stream_" + js.Key), js.Value.BinaryData); } foreach (var js in psbReader.BStreamCache) { File.WriteAllBytes(Path.Combine(streamsDirPath, "bstream_" + js.Key), js.Value.BinaryData); } } } }
static void Main(string[] args) { if (args.Length != 1) System.Environment.Exit(0); string FileName = args[0]; var FileStreamReader = new FileStream(FileName, FileMode.Open); var PsbReaderHandle = new PsbReader(FileStreamReader); if(PsbReaderHandle.Parse(PsbOpener.KnownKeys[0])) { List<Entry> TextureDir = PsbReaderHandle.GetTextures(); foreach (TexEntry Entry in TextureDir) { byte[] buffer = new byte[Entry.Size]; long FileCur = FileStreamReader.Position; Console.WriteLine("Texture Name:{0}", Entry.Name); FileStreamReader.Position = Entry.Offset; PsbTextureFormat ImageBuilder = new PsbTextureFormat(); ImageMetaData metaData = ImageBuilder.ReadMetaData(Entry); ImageData Graph = ImageBuilder.Read(FileStreamReader, metaData); Bitmap bmp = BitmapSourceToBitmap(Graph.Bitmap); bmp.LockBits(new Rectangle(System.Drawing.Point.Empty, bmp.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); string FileOutName = Entry.Name + ".bmp"; bmp.Save(FileOutName); FileStreamReader.Position = FileCur; } Console.WriteLine("Emote Dumper: Extract OK!"); Thread.Sleep(2000); } else { MessageBox.Show("Not Supported Version!!\nMaybe you need a new private key", "Emote Dumper .Net Version"); System.Environment.Exit(0); } }
public static void MigrateSaves(int sourceSize, int destinationSize, string lunarPath = null) { using (ScpClient scp = new ScpClient("169.254.215.100", "root", "5A7213")) { scp.Connect(); MemoryStream settingsDataStream = new MemoryStream(); scp.Download("/usr/game/save/data_008_0000.bin", settingsDataStream); MemoryStream settingsMetaStream = new MemoryStream(); scp.Download("/usr/game/save/meta_008_0000.bin", settingsMetaStream); byte[] settingsData = new byte[settingsDataStream.Length]; settingsDataStream.Position = 0; settingsDataStream.Read(settingsData, 0, settingsData.Length); SystemData originalSave = SystemData.FromByteArray(settingsData, sourceSize); SystemData migratedSave = new SystemData(destinationSize); migratedSave.Base_Settings = originalSave.Base_Settings; migratedSave.Work_Trial = originalSave.Work_Trial; int savesToCopy = Math.Min(sourceSize, destinationSize); for (int i = 0; i < savesToCopy; i++) { migratedSave.Setting_Games[i] = originalSave.Setting_Games[i]; migratedSave.Sram_Data[i] = originalSave.Sram_Data[i]; } byte[] migratedData = migratedSave.ToByteArray(); using (MemoryStream saveFile = new MemoryStream(migratedData)) { scp.Upload(saveFile, "/usr/game/save/data_008_0000.bin"); if (!string.IsNullOrEmpty(lunarPath)) { File.WriteAllBytes($@"{lunarPath}\data_008_0000.bin", migratedData); } } settingsMetaStream.Position = 0; using (PsbReader psbReader = new PsbReader(settingsMetaStream)) { JToken meta = psbReader.Root; meta["FileSize"] = migratedData.Length; meta["OriginalSize"] = migratedData.Length; (meta["Digest"] as JStream).BinaryData = MD5.Create().ComputeHash(migratedData); PsbWriter psbWriter = new PsbWriter(meta, null); psbWriter.Version = psbReader.Version; using (MemoryStream metaFile = new MemoryStream()) { psbWriter.Write(metaFile, null); metaFile.Position = 0; scp.Upload(metaFile, "/usr/game/save/meta_008_0000.bin"); if (!string.IsNullOrEmpty(lunarPath)) { byte[] metaData = new byte[metaFile.Length]; metaFile.Position = 0; metaFile.Read(metaData, 0, metaData.Length); File.WriteAllBytes($@"{lunarPath}\meta_008_0000.bin", metaData); } } } } }