/// <summary> /// Creates a new RTDX FARC archive /// </summary> /// <returns> /// Usage: refarc InputDirectory/ File.bin /// </returns> private static Task Refarc(Queue <string> arguments, ConsoleContext context) { var inputDiretcory = arguments.Dequeue(); var outputFile = arguments.Dequeue(); var farc = Farc.FromDirectory(inputDiretcory, PhysicalFileSystem.Instance); File.WriteAllBytes(outputFile, farc.ToByteArray()); return(Task.CompletedTask); }
/// <summary> /// Extracts an RTDX FARC archive /// </summary> /// <returns> /// Usage: unfarc File.bin OutputDirectory/ /// </returns> private static async Task Unfarc(Queue <string> arguments, ConsoleContext context) { var filename = arguments.Dequeue(); var outputDirectory = arguments.Dequeue(); if (!File.Exists(filename)) { throw new FileNotFoundException("Unable to find FARC at the given path", filename); } var farc = new Farc(File.ReadAllBytes(filename)); await farc.Extract(outputDirectory, PhysicalFileSystem.Instance); }
public void Pack(Farc signature = Farc.FArC) { NewFARC(); string[] files = Directory.GetFiles(DirectoryPath); Files.Capacity = files.Length; for (int i = 0; i < files.Length; i++) { Files.Add(new FARCFile { Name = Path.GetFileName(files[i]), Data = File.ReadAllBytes(files[i]) }); } files = null; Signature = signature; Save(); }
public void Pack(Farc Signature = Farc.FArC) { NewFARC(); string[] files = Directory.GetFiles(DirectoryPath); Files = new FARCFile[files.Length]; for (int i = 0; i < files.Length; i++) { Files[i] = new FARCFile { Name = Path.GetFileName(files[i]), Data = File.ReadAllBytes(files[i]) } } ; files = null; this.Signature = Signature; Save(); }
static void Main(string[] args) { //ChangeStarters(); //return; var basePath = @"D:\01003D200BAA2000"; var natureDiagnosis = JsonConvert.DeserializeObject <NDConverterSharedData.DataStore>(File.ReadAllText(basePath + @"\romfs\Data\StreamingAssets\data\nature_diagnosis\diagnosis.json")); //var actorDataInfoPath = basePath + @"\romfs\Data\StreamingAssets\native_data\pokemon\pokemon_actor_data_info.bin"; //var actorDataInfo = new PokemonActorDataInfo(File.ReadAllBytes(actorDataInfoPath)); var graphicsDatabasePath = basePath + @"\romfs\Data\StreamingAssets\native_data\pokemon_graphics_database.bin"; var graphicsDatabase = new PokemonGraphicsDatabase(File.ReadAllBytes(graphicsDatabasePath)); var nsoPath = basePath + @"\exefs\main"; IMainExecutable nso = MainExecutable.LoadFromNso(File.ReadAllBytes(nsoPath)); var fixedPokemonPath = basePath + @"\romfs\Data\StreamingAssets\native_data\dungeon\fixed_pokemon.bin"; IFixedPokemon fixedPokemon = new FixedPokemon(File.ReadAllBytes(fixedPokemonPath)); var messageBinPath = basePath + @"\romfs\Data\StreamingAssets\native_data\message_us.bin"; var messageBin = new Farc(File.ReadAllBytes(messageBinPath)); var common = new MessageBinEntry(messageBin.GetFile("common.bin")); ICommonStrings commonStrings = new CommonStrings(common); IStarterQueries starterQueries = new StarterQueries(commonStrings, nso, natureDiagnosis, fixedPokemon); Console.WriteLine("Starters:"); var starters = starterQueries.GetStarters(); foreach (var starter in starters) { Console.WriteLine(starter.PokemonName); } Console.WriteLine("Press any key to exit"); Console.ReadLine(); }
private FARC HeaderReader() { NewFARC(); Console.Title = "FARC Extractor - Archive: " + Path.GetFileName(FilePath); if (!File.Exists(FilePath)) { Console.WriteLine("File {0} doesn't exist.", Path.GetFileName(FilePath)); return(this); } 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) { Console.WriteLine("Unknown signature"); reader.Close(); return(this); } int HeaderLength = reader.ReadInt32Endian(true); if (Signature == Farc.FARC) { FARCType = (Type)reader.ReadInt32Endian(true); reader.ReadInt32(); int FARCMode = reader.ReadInt32Endian(true); FT = FARCMode == 0x10; CBC = FARCMode != 0x10 && FARCMode != 0x40; if (CBC && FARCType.HasFlag(Type.ECB)) { reader.Close(); byte[] Header = new byte[HeaderLength - 0x08]; MSIO.FileStream stream = new MSIO.FileStream(FilePath, MSIO.FileMode.Open, MSIO.FileAccess.ReadWrite, MSIO.FileShare.ReadWrite) { Position = 0x10 }; using (CryptoStream cryptoStream = new CryptoStream(stream, GetAes(true, null).CreateDecryptor(), CryptoStreamMode.Read)) cryptoStream.Read(Header, 0x00, HeaderLength - 0x08); Header = SkipData(Header, 0x10); reader = File.OpenReader(Header); FARCMode = reader.ReadInt32Endian(true); FT = FARCMode == 0x10; } } if (Signature == Farc.FARC) { if (reader.ReadInt32Endian(true) == 1) { Files = new FARCFile[reader.ReadInt32Endian(true)]; } } reader.ReadInt32(); if (Files == null) { int Count = 0; long Position = reader.LongPosition; while (reader.LongPosition < HeaderLength) { reader.NullTerminated(); reader.ReadInt32(); if (Signature != Farc.FArc) { reader.ReadInt32(); } reader.ReadInt32(); if (Signature == Farc.FARC && FT) { reader.ReadInt32(); } Count++; } reader.LongPosition = Position; Files = new FARCFile[Count]; } for (int i = 0; i < Files.Length; i++) { Files[i].Name = reader.NullTerminatedUTF8(); Files[i].Offset = reader.ReadInt32Endian(true); if (Signature != Farc.FArc) { Files[i].SizeComp = reader.ReadInt32Endian(true); } Files[i].SizeUnc = reader.ReadInt32Endian(true); if (Signature == Farc.FARC && FT) { Files[i].Type = (Type)reader.ReadInt32Endian(true); } } reader.Close(); return(this); }
public void Pack() { NewFARC(); string[] files = Directory.GetFiles(DirectoryPath); Files = new FARCFile[files.Length]; for (int i = 0; i < files.Length; i++) { Files[i] = new FARCFile { Name = files[i] }; string ext = Path.GetExtension(files[i]).ToLower(); if (ext == ".a3da" || ext == ".diva" || ext == ".vag") { Signature = Farc.FArc; } } files = null; Stream writer = File.OpenWriter(DirectoryPath + ".farc", true); writer.WriteEndian((int)Signature, true); Stream HeaderWriter = File.OpenWriter(); if (Signature == Farc.FArc) { HeaderWriter.WriteEndian(0x20, true); } else if (Signature == Farc.FArC) { HeaderWriter.WriteEndian(0x10, true); } else if (Signature == Farc.FARC) { HeaderWriter.WriteEndian((int)FARCType, true); HeaderWriter.Write(0x00); HeaderWriter.WriteEndian(0x40, true); HeaderWriter.Write(0x00); } int HeaderPartLength = Signature == Farc.FArc ? 0x09 : 0x0D; for (int i = 0; i < Files.Length; i++) { HeaderWriter.Length += Path.GetFileName(Files[i].Name).Length + HeaderPartLength; } writer.WriteEndian(HeaderWriter.Length, true); writer.Write(HeaderWriter.ToArray(true)); HeaderWriter = null; int Align = writer.Position.Align(0x10) - writer.Position; for (int i1 = 0; i1 < Align; i1++) { if (Signature == Farc.FArc) { writer.WriteByte(0x00); } else { writer.WriteByte(0x78); } } for (int i = 0; i < Files.Length; i++) { CompressStuff(i, ref Files, ref writer); } if (Signature == Farc.FARC) { writer.Position = 0x1C; } else { writer.Position = 0x0C; } for (int i = 0; i < Files.Length; i++) { writer.Write(Path.GetFileName(Files[i].Name) + "\0"); writer.WriteEndian(Files[i].Offset, true); if (Signature != Farc.FArc) { writer.WriteEndian(Files[i].SizeComp, true); } writer.WriteEndian(Files[i].SizeUnc, true); } writer.Close(); }
public void UnPack(string file, bool SaveToDisk) { Files = null; Signature = Farc.FArC; FT = false; Console.Title = "PD_Tool: FARC Extractor - Archive: " + Path.GetFileName(file); if (File.Exists(file)) { KKtIO reader = KKtIO.OpenReader(file); string directory = Path.GetFullPath(file).Replace(Path.GetExtension(file), ""); Signature = (Farc)reader.ReadInt32Endian(true); if (Signature == Farc.FARC) { Directory.CreateDirectory(directory); int HeaderLenght = reader.ReadInt32Endian(true); int Mode = reader.ReadInt32Endian(true); reader.ReadUInt32(); bool GZip = (Mode & 2) == 2; bool ECB = (Mode & 4) == 4; int FARCType = reader.ReadInt32Endian(true); FT = FARCType == 0x10; bool CBC = !FT && FARCType != 0x40; if (ECB && CBC) { byte[] Header = new byte[HeaderLenght - 0x08]; FT = true; reader.Close(); FileStream stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.Seek(0x10, 0); using (CryptoStream cryptoStream = new CryptoStream(stream, GetAes(true, null).CreateDecryptor(), CryptoStreamMode.Read)) cryptoStream.Read(Header, 0x00, HeaderLenght - 0x08); Header = SkipData(Header, 0x10); KKtIO CBCreader = new KKtIO(new MemoryStream(Header)); CBCreader.BaseStream.Seek(0, 0); FARCType = CBCreader.ReadInt32Endian(true); FT = FARCType == 0x10; if (CBCreader.ReadInt32Endian(true) == 1) { Files = new FARCFile[CBCreader.ReadInt32Endian(true)]; } CBCreader.ReadUInt32(); HeaderReader(HeaderLenght, ref Files, ref CBCreader); CBCreader.Close(); } else { if (reader.ReadInt32Endian(true) == 1) { Files = new FARCFile[reader.ReadInt32Endian(true)]; } reader.ReadUInt32(); HeaderReader(HeaderLenght, ref Files, ref reader); reader.Close(); } for (int i = 0; i < Files.Length; i++) { int FileSize = ECB || Files[i].ECB ? (int)Main. Align(Files[i].SizeComp, 0x10) : Files[i].SizeComp; FileStream stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.Seek(Files[i].Offset, 0); Files[i].Data = new byte[FileSize]; bool Encrypted = false; if (ECB) { if ((FT && Files[i].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; bool LocalGZip = (FT && Files[i].GZip) || GZip && Files[i].SizeUnc != 0; if (LocalGZip) { GZipStream gZipStream; if (Encrypted) { gZipStream = new GZipStream(new MemoryStream( Files[i].Data), CompressionMode.Decompress); stream.Close(); } else { gZipStream = new GZipStream(stream, CompressionMode.Decompress); } Files[i].Data = new byte[Files[i].SizeUnc]; gZipStream.Read(Files[i].Data, 0, Files[i].SizeUnc); Compressed = true; } if (!Encrypted && !Compressed) { Files[i].Data = new byte[Files[i].SizeUnc]; stream.Read(Files[i].Data, 0, Files[i].SizeUnc); stream.Close(); } if (SaveToDisk) { KKtIO writer = KKtIO.OpenWriter(Path.Combine(directory, Files[i].Name), true); writer.Write(Files[i].Data); writer.Close(); Files[i].Data = null; } } } else if (Signature == Farc.FArC) { Directory.CreateDirectory(directory); int HeaderLength = reader.ReadInt32Endian(true); reader.ReadUInt32(); HeaderReader(HeaderLength, ref Files, ref reader); reader.Close(); for (int i = 0; i < Files.Length; i++) { FileStream stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.Seek(Files[i].Offset, 0); Files[i].Data = new byte[Files[i].SizeComp]; stream.Read(Files[i].Data, 0, Files[i].SizeComp); stream.Close(); using (MemoryStream memorystream = new MemoryStream(Files[i].Data)) { GZipStream gZipStream = new GZipStream(memorystream, CompressionMode.Decompress); Files[i].Data = new byte[Files[i].SizeUnc]; gZipStream.Read(Files[i].Data, 0, Files[i].SizeUnc); } KKtIO writer = KKtIO.OpenWriter(Path.Combine(directory, Files[i].Name), true); writer.Write(Files[i].Data); writer.Close(); Files[i].Data = null; } } else if (Signature == Farc.FArc) { Directory.CreateDirectory(directory); int HeaderLength = reader.ReadInt32Endian(true); reader.ReadUInt32(); HeaderReader(HeaderLength, ref Files, ref reader); for (int i = 0; i < Files.Length; i++) { FileStream stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); stream.Seek(Files[i].Offset, 0); Files[i].Data = new byte[Files[i].SizeUnc]; stream.Read(Files[i].Data, 0, Files[i].SizeUnc); stream.Close(); KKtIO writer = KKtIO.OpenWriter(Path.Combine(directory, Files[i].Name), true); writer.Write(Files[i].Data); writer.Close(); Files[i].Data = null; } } else { Console.WriteLine("Unknown signature"); reader.Close(); } } else { Console.WriteLine("File {0} doesn't exist.", Path.GetFileName(file)); } Console.Clear(); Console.Title = "PD_Tool: FARC Extractor"; }
public void Pack(string file) { Files = null; FT = false; string[] files = Directory.GetFiles(file); Files = new FARCFile[files.Length]; for (int i = 0; i < files.Length; i++) { Files[i] = new FARCFile { Name = files[i] }; string ext = Path.GetExtension(files[i]).ToLower(); if (ext == ".a3da" || ext == ".mot" || ext == ".vag") { Signature = Farc.FArc; } } files = null; KKtIO writer = KKtIO.OpenWriter(file + ".farc", true); if (Signature == Farc.FArc) { writer.Write(Text.ToASCII("FArc")); } else if (Signature == Farc.FArC) { writer.Write(Text.ToASCII("FArC")); } else { writer.Write(Text.ToASCII("FARC")); } KKtIO HeaderWriter = new KKtIO(new MemoryStream()); for (int i = 0; i < 3; i++) { HeaderWriter.Write((byte)0x00); } if (Signature == Farc.FArc) { HeaderWriter.Write((byte)0x20); } else if (Signature == Farc.FArC) { HeaderWriter.Write((byte)0x10); } else if (Signature == Farc.FARC) { HeaderWriter.Write((byte)0x06); for (int i = 0; i < 7; i++) { HeaderWriter.Write((byte)0x00); } HeaderWriter.Write((byte)0x40); for (int i = 0; i < 8; i++) { HeaderWriter.Write((byte)0x00); } } for (int i = 0; i < Files.Length; i++) { for (int i1 = 0; i1 < Path.GetFileName(Files[i].Name).Length + (Signature == Farc.FArc ? 0x09 : 0x0D); i1++) { HeaderWriter.Write((byte)0x00); } } writer.WriteEndian((uint)HeaderWriter.Length, true); writer.Write(HeaderWriter.ToArray()); HeaderWriter = null; int Align = (int)Main.Align(writer.Position, 0x10) - (int)writer.Position; for (int i1 = 0; i1 < Align; i1++) { if (Signature == Farc.FArc) { writer.Write((byte)0x00); } else { writer.Write((byte)0x78); } } for (int i = 0; i < Files.Length; i++) { CompressStuff(i, ref Files, ref writer); } if (Signature == Farc.FARC) { writer.Seek(0x1C, 0); } else { writer.Seek(0x0C, 0); } for (int i = 0; i < Files.Length; i++) { writer.Write(Text.ToUTF8(Path.GetFileName(Files[i].Name) + "\0")); writer.WriteEndian(Files[i].Offset, true); if (Signature != Farc.FArc) { writer.WriteEndian(Files[i].SizeComp, true); } writer.WriteEndian(Files[i].SizeUnc, true); } writer.Close(); }
public void Save() { for (int i = 0; i < Files.Length; i++) { string ext = Path.GetExtension(Files[i].Name).ToLower(); if (ext == ".a3da" || ext == ".diva" || ext == ".drs" || ext == ".dve" || ext == ".vag") { Signature = Farc.FArc; break; } } Stream writer = File.OpenWriter(DirectoryPath + ".farc", true); writer.WriteEndian((int)Signature, true); Stream HeaderWriter = File.OpenWriter(); if (Signature == Farc.FArc) { HeaderWriter.WriteEndian(0x20, true); } else if (Signature == Farc.FArC) { HeaderWriter.WriteEndian(0x10, true); } else if (Signature == Farc.FARC) { HeaderWriter.WriteEndian((int)FARCType, true); HeaderWriter.Write(0x00); HeaderWriter.WriteEndian(0x40, true); HeaderWriter.Write(0x00); } int HeaderPartLength = Signature == Farc.FArc ? 0x09 : 0x0D; for (int i = 0; i < Files.Length; i++) { HeaderWriter.Length += Path.GetFileName(Files[i].Name).Length + HeaderPartLength; } writer.WriteEndian(HeaderWriter.Length, true); writer.Write(HeaderWriter.ToArray(true)); HeaderWriter = null; int Align = writer.Position.Align(0x10) - writer.Position; for (int i1 = 0; i1 < Align; i1++) { writer.WriteByte((byte)(Signature == Farc.FArc ? 0x00 : 0x78)); } for (int i = 0; i < Files.Length; i++) { CompressStuff(i, ref Files, ref writer); } writer.Position = Signature == Farc.FARC ? 0x1C : 0x0C; for (int i = 0; i < Files.Length; i++) { writer.Write(Path.GetFileName(Files[i].Name) + "\0"); writer.WriteEndian(Files[i].Offset, true); if (Signature != Farc.FArc) { writer.WriteEndian(Files[i].SizeComp, true); } writer.WriteEndian(Files[i].SizeUnc, true); } writer.Close(); }
public bool HeaderReader() { NewFARC(); if (!File.Exists(FilePath)) { return(false); } Stream reader = File.OpenReader(FilePath); DirectoryPath = Path.GetFullPath(FilePath).Replace(Path.GetExtension(FilePath), ""); Signature = (Farc)reader.RI32E(true); if (Signature != Farc.FArc && Signature != Farc.FArC && Signature != Farc.FARC) { reader.Dispose(); return(false); } int headerLength = reader.RI32E(true); if (Signature == Farc.FARC) { FARCType = (Type)reader.RI32E(true); reader.RI32(); int farcMode = reader.RI32E(true); ft = farcMode == 0x10; cbc = farcMode != 0x10 && farcMode != 0x40; if (cbc && (FARCType & Type.ECB) != 0) { reader.Dispose(); byte[] header = new byte[headerLength - 0x08]; MSIO.FileStream stream = new MSIO.FileStream(FilePath, MSIO.FileMode.Open, MSIO.FileAccess.ReadWrite, MSIO.FileShare.ReadWrite) { Position = 0x10 }; using (AesManaged aes = GetAes(true, null)) using (CryptoStream cryptoStream = new CryptoStream(stream, aes.CreateDecryptor(), CryptoStreamMode.Read)) cryptoStream.Read(header, 0x00, headerLength - 0x08); header = SkipData(header, 0x10); reader = File.OpenReader(header); farcMode = reader.RI32E(true); ft = farcMode == 0x10; } } if (Signature == Farc.FARC) { if (reader.RI32E(true) == 1) { Files.Capacity = reader.RI32E(true); } } reader.RI32(); if (Files.Capacity == 0) { int Count = 0; long Position = reader.PI64; while (reader.PI64 < headerLength) { reader.NT(); reader.RI32(); if (Signature != Farc.FArc) { reader.RI32(); } reader.RI32(); if (Signature == Farc.FARC && ft) { reader.RI32(); } Count++; } reader.PI64 = Position; Files.Capacity = Count; } for (int i = 0; i < Files.Capacity; i++) { FARCFile file = default; file.Name = reader.NTUTF8(); file.Offset = reader.RI32E(true); if (Signature != Farc.FArc) { file.SizeComp = reader.RI32E(true); } file.SizeUnc = reader.RI32E(true); if (Signature == Farc.FARC && ft) { file.Type = (Type)reader.RI32E(true); } Files.Add(file); } reader.Dispose(); return(true); }
public void Save() { if (!HasFiles) { return; } for (int i = 0; i < Files.Count; i++) { string ext = Path.GetExtension(Files[i].Name).ToLower(); if (ext == ".a3da" || ext == ".diva" || ext == ".vag") { Signature = Farc.FArc; break; } } Stream writer = File.OpenWriter(DirectoryPath + ".farc", true); writer.WE((int)Signature, true); using (Stream headerWriter = File.OpenWriter()) { if (Signature == Farc.FArc) { headerWriter.WE(0x20, true); } else if (Signature == Farc.FArC) { headerWriter.WE(0x10, true); } else if (Signature == Farc.FARC) { headerWriter.WE((int)FARCType, true); headerWriter.W(0x00); headerWriter.WE(0x40, true); headerWriter.W(0x00); } int HeaderPartLength = Signature == Farc.FArc ? 0x09 : 0x0D; for (int i = 0; i < Files.Count; i++) { headerWriter.L += Path.GetFileName(Files[i].Name).Length + HeaderPartLength + 1; } writer.WE(headerWriter.L, true); writer.W(headerWriter.ToArray(true)); } int align = writer.P.A(0x10) - writer.P; for (int i1 = 0; i1 < align; i1++) { writer.W((byte)(Signature == Farc.FArc ? 0x00 : 0x78)); } for (int i = 0; i < Files.Count; i++) { CompressStuff(i, ref writer); } writer.P = Signature == Farc.FARC ? 0x1C : 0x0C; for (int i = 0; i < Files.Count; i++) { FARCFile file = Files[i]; writer.W(Path.GetFileName(file.Name) + "\0"); writer.WE(file.Offset, true); if (Signature != Farc.FArc) { writer.WE(file.SizeComp, true); } writer.WE(file.SizeUnc, true); } writer.Dispose(); }