diff --git a/KKdMainLib/A3DA/A3DA.cs b/KKdMainLib/A3DA/A3DA.cs index b9fc907..975f1dd 100644 --- a/KKdMainLib/A3DA/A3DA.cs +++ b/KKdMainLib/A3DA/A3DA.cs @@ -33,6 +33,12 @@ namespace KKdMainLib.A3DA IO = File.OpenWriter(); UsedValues = new Dictionary(); } public int A3DAReader(string file) + { IO = File.OpenReader(file + ".a3da"); return A3DAReader(ref IO); } + + public int A3DAReader(byte[] data) + { IO = File.OpenReader(data ); return A3DAReader(ref IO); } + + private int A3DAReader(ref Stream IO) { name = ""; nameView = ""; @@ -40,7 +46,6 @@ namespace KKdMainLib.A3DA Dict = new Dictionary(); Data = new A3DAData { Header = new PDHead() }; - IO = File.OpenReader(file + ".a3da"); Data.Header.Format = IO.Format = Main.Format.F; Data.Header.Signature = IO.ReadInt32(); if (Data.Header.Signature == 0x41443341) Data.Header = IO.ReadHeader(true); @@ -642,18 +647,18 @@ namespace KKdMainLib.A3DA SOi0 = SO0[i0]; name = "m_objhrc" + d + SOi0 + d; - if (IsX && Data.MObjectHRC[i0].JointOrient != null) + if (IsX && Data.MObjectHRC[SOi0].JointOrient != null) { IO.Write(name + "joint_orient.x=", Data.MObjectHRC[SOi0].JointOrient.X); IO.Write(name + "joint_orient.y=", Data.MObjectHRC[SOi0].JointOrient.Y); IO.Write(name + "joint_orient.z=", Data.MObjectHRC[SOi0].JointOrient.Z); } - if (Data.MObjectHRC[i0].Instance != null) + if (Data.MObjectHRC[SOi0].Instance != null) { nameView = name + "instance" + d; - SO1 = Data.MObjectHRC[i0].Instance.Length.SortWriter(); - for (i1 = 0; i1 < Data.MObjectHRC[i0].Instance.Length; i1++) + SO1 = Data.MObjectHRC[SOi0].Instance.Length.SortWriter(); + for (i1 = 0; i1 < Data.MObjectHRC[SOi0].Instance.Length; i1++) { SOi1 = SO1[i1]; IO.Write(Data.MObjectHRC[SOi0].Instance[SOi1].MT, @@ -677,11 +682,11 @@ namespace KKdMainLib.A3DA IO.Write(Data.MObjectHRC[SOi0].MT, name, A3DC, IsX, 0b10000); IO.Write(name + "name=", Data.MObjectHRC[SOi0].Name); - if (Data.MObjectHRC[i0].Node != null) + if (Data.MObjectHRC[SOi0].Node != null) { nameView = name + "node" + d; - SO1 = Data.MObjectHRC[i0].Node.Length.SortWriter(); - for (i1 = 0; i1 < Data.MObjectHRC[i0].Node.Length; i1++) + SO1 = Data.MObjectHRC[SOi0].Node.Length.SortWriter(); + for (i1 = 0; i1 < Data.MObjectHRC[SOi0].Node.Length; i1++) { SOi1 = SO1[i1]; IO.Write(Data.MObjectHRC[SOi0].Node[SOi1].MT, @@ -815,18 +820,18 @@ namespace KKdMainLib.A3DA name = "objhrc" + d + SOi0 + d; IO.Write(name + "name=", Data.ObjectHRC[SOi0].Name); - if (IsX && Data.ObjectHRC[i0].JointOrient != null) + if (IsX && Data.ObjectHRC[SOi0].JointOrient != null) { IO.Write(name + "joint_orient.x=", Data.ObjectHRC[SOi0].JointOrient.X); IO.Write(name + "joint_orient.y=", Data.ObjectHRC[SOi0].JointOrient.Y); IO.Write(name + "joint_orient.z=", Data.ObjectHRC[SOi0].JointOrient.Z); } - if (Data.ObjectHRC[i0].Node != null) + if (Data.ObjectHRC[SOi0].Node != null) { - SO1 = Data.ObjectHRC[i0].Node.Length.SortWriter(); + SO1 = Data.ObjectHRC[SOi0].Node.Length.SortWriter(); nameView = name + "node" + d; - for (i1 = 0; i1 < Data.ObjectHRC[i0].Node.Length; i1++) + for (i1 = 0; i1 < Data.ObjectHRC[SOi0].Node.Length; i1++) { SOi1 = SO1[i1]; IO.Write(Data.ObjectHRC[SOi0].Node[SOi1].MT, nameView + SOi1 + d, A3DC, IsX, 0b10000); @@ -1014,7 +1019,7 @@ namespace KKdMainLib.A3DA } } - public void A3DCWriter(string file) + public byte[] A3DCWriter(string file = null) { int i0 = 0; int i1 = 0; @@ -1221,7 +1226,8 @@ namespace KKdMainLib.A3DA byte[] A3DAData = IO.ToArray(true); Data.Head = new Header(); - IO = File.OpenWriter(file + ".a3da"); + if (file != null) IO = File.OpenWriter(file + ".a3da"); + else IO = File.OpenWriter(); IO.Position = A3DCStart + 0x40; Data.Head.StringOffset = IO.Position - A3DCStart; @@ -1267,7 +1273,9 @@ namespace KKdMainLib.A3DA IO.WriteEOFC(); } - IO.Close(); + if (file != null) { IO.Close(); return null; } + else return IO.ToArray(true); + } private void Write(ref ModelTransform MT) @@ -1358,15 +1366,18 @@ namespace KKdMainLib.A3DA } public void MsgPackReader(string file, bool JSON) + { + MsgPack MsgPack = file.ReadMPAllAtOnce(JSON); + if (!MsgPack.Element("A3D", out MsgPack A3D)) { MsgPack = MsgPack.New; return; } + MsgPackReader(A3D); + } + + public void MsgPackReader(MsgPack A3D) { int i = 0; int i0 = 0; int i1 = 0; - MsgPack MsgPack = file.ReadMPAllAtOnce(JSON); - - if (!MsgPack.Element("A3D", out MsgPack A3D)) { MsgPack = MsgPack.New; return; } - Data.Header = new PDHead(); MsgPack Temp = MsgPack.New; @@ -1701,7 +1712,10 @@ namespace KKdMainLib.A3DA }; } - public void MsgPackWriter(string file, bool JSON) + public void MsgPackWriter(string file, bool JSON) => + MsgPackWriter().Write(true, file, JSON); + + public MsgPack MsgPackWriter() { int i = 0; int i0 = 0; @@ -1765,7 +1779,7 @@ namespace KKdMainLib.A3DA } if (Data.DOF != null) - A3D.Add(new MsgPack("DOF").Add("Name", Data.DOF.Name).Add("MT", Data.DOF.MT)); + A3D.Add(new MsgPack("DOF").Add("Name", Data.DOF.Name).Add(Data.DOF.MT)); if (Data.Event != null) { @@ -1983,8 +1997,7 @@ namespace KKdMainLib.A3DA .Add("LensGhost", Data.PostProcess.LensGhost) .Add("LensShaft", Data.PostProcess.LensShaft) .Add("Specular" , Data.PostProcess.Specular )); - - A3D.Write(true, file, JSON); + return A3D; } } diff --git a/KKdMainLib/FARC.cs b/KKdMainLib/FARC.cs index c42d1b9..60f1f8f 100644 --- a/KKdMainLib/FARC.cs +++ b/KKdMainLib/FARC.cs @@ -19,6 +19,7 @@ namespace KKdMainLib public Type FARCType; public Farc Signature = Farc.FArC; public string FilePath, DirectoryPath; + public bool HasFiles => Files == null ? false : Files.Length > 0; private bool CBC, FT; @@ -36,21 +37,18 @@ namespace KKdMainLib } public void UnPack(bool SaveToDisk = true) - { - HeaderReader().FileReader(); - if (SaveToDisk) this.SaveToDisk(); - } + { if (HeaderReader()) { FileReader(); if (SaveToDisk) this.SaveToDisk(); } } - private FARC HeaderReader() + public bool HeaderReader() { NewFARC(); - if (!File.Exists(FilePath)) return this; + if (!File.Exists(FilePath)) return false; Stream reader = File.OpenReader(FilePath); DirectoryPath = Path.GetFullPath(FilePath).Replace(Path.GetExtension(FilePath), ""); Signature = (Farc)reader.ReadInt32Endian(true); if (Signature != Farc.FArc && Signature != Farc.FArC && Signature != Farc.FARC) - { reader.Close(); return this; } + { reader.Close(); return false; } int HeaderLength = reader.ReadInt32Endian(true); if (Signature == Farc.FARC) @@ -113,77 +111,76 @@ namespace KKdMainLib } reader.Close(); - return this; + return true; } - private FARC FileReader() + private void FileReader() + { for (int i = 0; i < Files.Length; i++) FileReader(i); } + + public byte[] FileReader(int i) { - if (Files == null) return this; - if (Files.Length < 1) return this; + if (!HasFiles) return null; + if (i >= Files.Length) return null; if (Signature != Farc.FARC) { - for (int i = 0; i < Files.Length; i++) - if (Signature == Farc.FArC) - using (MSIO.MemoryStream memorystream = new MSIO.MemoryStream( - File.ReadAllBytes(FilePath, Files[i].SizeComp, Files[i].Offset))) - { - GZipStream gZipStream = new GZipStream(memorystream, CompressionMode.Decompress); - Files[i].Data = new byte[Files[i].SizeUnc]; - gZipStream.Read(Files[i].Data, 0, Files[i].SizeUnc); - } - else Files[i].Data = File.ReadAllBytes(FilePath, Files[i].SizeUnc, Files[i].Offset); - return this; - } - - for (int i = 0; i < Files.Length; i++) - { - int FileSize = FARCType.HasFlag(Type.ECB) || Files[i].Type.HasFlag(Type.ECB) ? - Files[i].SizeComp.Align(0x10) : Files[i].SizeComp; - MSIO.FileStream stream = new MSIO.FileStream(FilePath, MSIO.FileMode.Open, - MSIO.FileAccess.ReadWrite, MSIO.FileShare.ReadWrite); - stream.Seek(Files[i].Offset, 0); - Files[i].Data = new byte[FileSize]; - - bool Encrypted = false; - if (FARCType.HasFlag(Type.ECB)) - { - if ((FT && Files[i].Type.HasFlag(Type.ECB)) || CBC) + if (Signature == Farc.FArC) + using (MSIO.MemoryStream memorystream = new MSIO.MemoryStream( + File.ReadAllBytes(FilePath, Files[i].SizeComp, Files[i].Offset))) { - using (CryptoStream cryptoStream = new CryptoStream(stream, - GetAes(true, null).CreateDecryptor(), CryptoStreamMode.Read)) - cryptoStream.Read(Files[i].Data, 0, FileSize); - Files[i].Data = SkipData(Files[i].Data, 0x10); + GZipStream gZipStream = new GZipStream(memorystream, CompressionMode.Decompress); + Files[i].Data = new byte[Files[i].SizeUnc]; + gZipStream.Read(Files[i].Data, 0, Files[i].SizeUnc); } - else - using (CryptoStream cryptoStream = new CryptoStream(stream, - GetAes(false, null).CreateDecryptor(), CryptoStreamMode.Read)) - cryptoStream.Read(Files[i].Data, 0, FileSize); - Encrypted = true; - } - - bool Compressed = false; - if (((FT && Files[i].Type.HasFlag(Type.GZip)) || - FARCType.HasFlag(Type.GZip)) && Files[i].SizeUnc > 0) - { - GZipStream gZipStream; - if (Encrypted) { gZipStream = new GZipStream(new MSIO.MemoryStream(Files[i].Data), - CompressionMode.Decompress); stream.Close(); } - else gZipStream = new GZipStream(stream, CompressionMode.Decompress); - byte[] Temp = new byte[Files[i].SizeUnc]; - gZipStream.Read(Temp, 0, Files[i].SizeUnc); - Files[i].Data = Temp; - - Compressed = true; - } - - if (!Encrypted && !Compressed) - { - Files[i].Data = new byte[Files[i].SizeUnc]; - stream.Read(Files[i].Data, 0, Files[i].SizeUnc); - stream.Close(); - } + else Files[i].Data = File.ReadAllBytes(FilePath, Files[i].SizeUnc, Files[i].Offset); + return Files[i].Data; } - return this; + + int FileSize = FARCType.HasFlag(Type.ECB) || Files[i].Type.HasFlag(Type.ECB) ? + Files[i].SizeComp.Align(0x10) : Files[i].SizeComp; + MSIO.FileStream stream = new MSIO.FileStream(FilePath, MSIO.FileMode.Open, + MSIO.FileAccess.ReadWrite, MSIO.FileShare.ReadWrite); + stream.Seek(Files[i].Offset, 0); + Files[i].Data = new byte[FileSize]; + + bool Encrypted = false; + if (FARCType.HasFlag(Type.ECB)) + { + if ((FT && Files[i].Type.HasFlag(Type.ECB)) || CBC) + { + using (CryptoStream cryptoStream = new CryptoStream(stream, + GetAes(true, null).CreateDecryptor(), CryptoStreamMode.Read)) + cryptoStream.Read(Files[i].Data, 0, FileSize); + Files[i].Data = SkipData(Files[i].Data, 0x10); + } + else + using (CryptoStream cryptoStream = new CryptoStream(stream, + GetAes(false, null).CreateDecryptor(), CryptoStreamMode.Read)) + cryptoStream.Read(Files[i].Data, 0, FileSize); + Encrypted = true; + } + + bool Compressed = false; + if (((FT && Files[i].Type.HasFlag(Type.GZip)) || + FARCType.HasFlag(Type.GZip)) && Files[i].SizeUnc > 0) + { + GZipStream gZipStream; + if (Encrypted) { gZipStream = new GZipStream(new MSIO.MemoryStream(Files[i].Data), + CompressionMode.Decompress); stream.Close(); } + else gZipStream = new GZipStream(stream, CompressionMode.Decompress); + byte[] Temp = new byte[Files[i].SizeUnc]; + gZipStream.Read(Temp, 0, Files[i].SizeUnc); + Files[i].Data = Temp; + + Compressed = true; + } + + if (!Encrypted && !Compressed) + { + Files[i].Data = new byte[Files[i].SizeUnc]; + stream.Read(Files[i].Data, 0, Files[i].SizeUnc); + stream.Close(); + } + return Files[i].Data; } private void SaveToDisk() @@ -193,7 +190,8 @@ namespace KKdMainLib MSIO.Directory.CreateDirectory(DirectoryPath); for (int i = 0; i < Files.Length; i++) { - File.WriteAllBytes(Path.Combine(DirectoryPath, Files[i].Name), Files[i].Data); + if (Files[i].Data != null) + File.WriteAllBytes(Path.Combine(DirectoryPath, Files[i].Name), Files[i].Data); Files[i].Data = null; } } @@ -205,7 +203,7 @@ namespace KKdMainLib return SkipData; } - public FARC Pack() + public void Pack() { NewFARC(); string[] files = Directory.GetFiles(DirectoryPath); @@ -213,7 +211,7 @@ namespace KKdMainLib for (int i = 0; i < files.Length; i++) Files[i] = new FARCFile { Name = Path.GetFileName(files[i]), Data = File.ReadAllBytes(files[i]) }; files = null; - return this; + CompressStuff(); } public void CompressStuff() diff --git a/KKdMainLib/Main.cs b/KKdMainLib/Main.cs index ece25a7..71d6191 100644 --- a/KKdMainLib/Main.cs +++ b/KKdMainLib/Main.cs @@ -81,8 +81,8 @@ namespace KKdMainLib Multiselect = true, Title = "Choose file(s) to open:" }; ofd.Filter = GetArgs("All;", false, "*"); - if (filetype == "a3da") ofd.Filter = GetArgs("A3DA", "a3da", "json", "mp") + - GetArgs("A3DA", true, "a3da") + JSON + MsgPack; + if (filetype == "a3da") ofd.Filter = GetArgs("A3DA", "a3da", "farc", "json", "mp") + + GetArgs("A3DA", true, "a3da") + GetArgs("FARC", true, "farc") + JSON + MsgPack; else if (filetype == "bin" ) ofd.Filter = GetArgs("BIN" , "bin", "json", "mp") + BIN + JSON + MsgPack; else if (filetype == "bon" ) ofd.Filter = GetArgs("BON" , "bon", "bin", "json", "mp") + diff --git a/KKdMainLib/Properties/AssemblyInfo.cs b/KKdMainLib/Properties/AssemblyInfo.cs index d033257..f4c7885 100644 --- a/KKdMainLib/Properties/AssemblyInfo.cs +++ b/KKdMainLib/Properties/AssemblyInfo.cs @@ -11,5 +11,5 @@ using System.Runtime.InteropServices; [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: Guid("2BA7EFC6-91D1-8BBC-C487-06C7F36CC789")] -[assembly: AssemblyVersion("0.4.6.2")] -[assembly: AssemblyFileVersion("0.4.6.2")] +[assembly: AssemblyVersion("0.4.6.3")] +[assembly: AssemblyFileVersion("0.4.6.3")] diff --git a/PD_Tool/Properties/AssemblyInfo.cs b/PD_Tool/Properties/AssemblyInfo.cs index 69a2c62..1dc84ac 100644 --- a/PD_Tool/Properties/AssemblyInfo.cs +++ b/PD_Tool/Properties/AssemblyInfo.cs @@ -11,5 +11,5 @@ using System.Runtime.InteropServices; [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: Guid("7B5D5A3A-A6F8-4813-C97D-ACFC98F7397E")] -[assembly: AssemblyVersion("0.4.6.2")] -[assembly: AssemblyFileVersion("0.4.6.2")] +[assembly: AssemblyVersion("0.4.6.3")] +[assembly: AssemblyFileVersion("0.4.6.3")] diff --git a/PD_Tool/classes/Tools/A3D.cs b/PD_Tool/classes/Tools/A3D.cs index 270253a..bb25621 100644 --- a/PD_Tool/classes/Tools/A3D.cs +++ b/PD_Tool/classes/Tools/A3D.cs @@ -1,7 +1,9 @@ using System; using KKdMainLib; using KKdMainLib.IO; +using KKdMainLib.MessagePack; using KKdA3DA = KKdMainLib.A3DA.A3DA; +using KKdFARC = KKdMainLib.FARC; namespace PD_Tool.Tools { @@ -19,6 +21,7 @@ namespace PD_Tool.Tools foreach (string file in FileNames) if (file.EndsWith(".mp" )) { MP = true; break; } else if (file.EndsWith(".json")) { MP = true; break; } + else if (file.EndsWith(".farc")) { MP = true; break; } Main.Format Format = Main.Format.NULL; string format = ""; @@ -50,6 +53,7 @@ namespace PD_Tool.Tools } KKdA3DA A; + int state; foreach (string file in FileNames) { A = new KKdA3DA(); @@ -58,10 +62,38 @@ namespace PD_Tool.Tools ext = ext.ToLower(); Console.Title = "A3DA Converter: " + Path.GetFileNameWithoutExtension(file); - if (ext == ".a3da") + if (ext == ".farc") { - A.A3DAReader (filepath); - A.MsgPackWriter(filepath, JSON); + KKdFARC FARC = new KKdFARC(file); + MsgPack A3DA = MsgPack.Null; + if (FARC.HeaderReader()) + { + if (FARC.HasFiles) + { + byte[] data = null; + for (int i = 0; i < FARC.Files.Length; i++) + { + data = FARC.FileReader(i); + state = A.A3DAReader(data); + if (state == 1) + { + A3DA = A.MsgPackWriter(); + A = new KKdA3DA(); + A.MsgPackReader(A3DA); + A.IO = File.OpenWriter(); + if (format != "1" && format != "3") data = A.A3DCWriter(); + else { A.A3DAWriter(); data = A.IO.ToArray(true); } + FARC.Files[i].Data = data; + } + } + FARC.CompressStuff(); + } + } + } + else if (ext == ".a3da") + { + state = A.A3DAReader(filepath); + if (state == 1) A.MsgPackWriter(filepath, JSON); } else if (ext == ".mp" || ext == ".json") { @@ -71,7 +103,7 @@ namespace PD_Tool.Tools A.Data.Header.Format = Format; if (format != "1" && format != "3") A.A3DCWriter(filepath); - else A.A3DAWriter(); + else { A.A3DAWriter(); A.IO.Close(); } } A = null; }