public void TestDullahanPsb() { var resPath = Path.Combine(Environment.CurrentDirectory, @"..\..\Res"); //var path = Path.Combine(resPath, "e-mote38_KRKR-pure.psb"); //var path = Path.Combine(resPath, "HD愛子a_春服.psb"); //var path2 = Path.Combine(resPath, "HD愛子a_春服-pure.psb"); //var path = Path.Combine(resPath, "akira_guide.psb"); //var path2 = Path.Combine(resPath, "akira_guide-pure.psb"); //var path = Path.Combine(resPath, "dx_真闇_裸_impure.psb"); //var path2 = Path.Combine(resPath, "dx_真闇_裸-pure.psb"); //var path = Path.Combine(resPath, "emote396-win.psb"); //var path2 = Path.Combine(resPath, "emote396-win.pure.psb"); var path = Path.Combine(resPath, "ca01_l_body_1.psz.psb"); var path2 = Path.Combine(resPath, "ca01_l_body_1-pure.psb"); var psb = PSB.DullahanLoad(new FileStream(path, FileMode.Open), 64); var p2 = new PsbFile(path2); var offset1 = psb.Header.OffsetChunkData; var offset2 = p2.Header.OffsetChunkData; Assert.AreEqual(offset1, offset2); var obj = psb.Objects.First(); //if (psb.Platform == PsbSpec.krkr) //{ // psb.SwitchSpec(PsbSpec.win); //} //psb.Merge(); //var r = psb.Resources[0].Data.Length; //File.WriteAllBytes("Dullahan.psb", psb.Build()); }
public void TestMmioAndDullhanContent() { var resPath = Path.Combine(Environment.CurrentDirectory, @"..\..\Res"); var path = Path.Combine(resPath, "00_pro02.txt.scn"); var path2 = Path.Combine(resPath, "00_pro02.txt.scn.json"); //var path = Path.Combine(resPath, "akira_guide.psb"); //var path2 = Path.Combine(resPath, "akira_guide.psb.json"); //var psb = new PSB(path); var psb = PSB.DullahanLoad(path); var r = PsbDecompiler.Decompile(psb).Equals(File.ReadAllText(path2)); }
/// <summary> /// Decompile Pure PSB as Json /// </summary> /// <param name="path"></param> /// <param name="psb"></param> /// <param name="context"></param> /// <param name="psbType"></param> /// <returns></returns> public static string Decompile(string path, out PSB psb, Dictionary <string, object> context = null, PsbType psbType = PsbType.PSB) { using var fs = File.OpenRead(path); var ctx = FreeMount.CreateContext(context); string type = null; Stream stream = fs; using var ms = ctx.OpenFromShell(fs, ref type); if (ms != null) { ctx.Context[Consts.Context_PsbShellType] = type; fs.Dispose(); stream = ms; } try { psb = new PSB(stream, false); } catch (PsbBadFormatException e) when(e.Reason == PsbBadFormatReason.Header || e.Reason == PsbBadFormatReason.Array || e.Reason == PsbBadFormatReason.Body) //maybe encrypted { stream.Position = 0; uint?key = null; if (ctx.Context.ContainsKey(Consts.Context_CryptKey)) { key = ctx.Context[Consts.Context_CryptKey] as uint?; } else { key = ctx.GetKey(stream); } stream.Position = 0; if (key != null) //try use key { try { using (var mms = new MemoryStream((int)stream.Length)) { PsbFile.Encode(key.Value, EncodeMode.Decrypt, EncodePosition.Auto, stream, mms); stream.Dispose(); psb = new PSB(mms); ctx.Context[Consts.Context_CryptKey] = key; } } catch { throw e; } } else //key = null { if (e.Reason == PsbBadFormatReason.Header || e.Reason == PsbBadFormatReason.Array) //now try Dullahan loading { psb = PSB.DullahanLoad(stream); } else { throw; } } } if (psbType != PsbType.PSB) { psb.Type = psbType; } return(Decompile(psb)); }