public void FromStreamTest() { using (var fileStream = File.OpenRead("TestResources\\Version3BigEndian.bf")) { var script = FlowScriptBinary.FromStream(fileStream, BinaryFormatVersion.Version3BigEndian); Assert.IsNotNull(script); Assert.AreEqual(BinaryFormatVersion.Version3BigEndian, script.FormatVersion); } }
public FieldLocalData(string directoryPath, int major, int minor) : this() { var fieldPak = LoadFieldPak(directoryPath, major, minor, "f{0:D3}_{1:D3}.pac"); var fieldNpcPak = LoadFieldPak(directoryPath, major, minor, "fnpc{0:D3}_{1:D3}.pac"); DefaultCamera = TryLoadFile(fieldPak, $"data/f{major:D3}_{minor:D3}.CMR", stream => new CmrBinary(stream, true)); // Load layers for (int layerIndex = 0; true; layerIndex++) { var layer = new FieldLayer(); layer.ObjectPlacement = TryLoadFile(fieldPak, $"data/f{major:D3}_{minor:D3}_{layerIndex:D2}.FBN", stream => new FbnBinary(stream, true)); layer.HitTable = TryLoadFile(fieldPak, $"hit/f{major:D3}_{minor:D3}_{layerIndex:D2}.HTB", stream => new HtbBinary(stream, true)); layer.HitScript = TryLoadFile(fieldPak, $"hit/fhit_{major:D3}_{minor:D3}_{layerIndex:D2}.bf", stream => FlowScriptBinary.FromStream(stream, true)); layer.NpcScript = TryLoadFile(fieldNpcPak, $"npc/fnpc{major:D3}_{minor:D3}_{layerIndex:D2}.bf", stream => FlowScriptBinary.FromStream(stream, true)); //layer.Fnt = TryLoadFile( fieldNpcPak, $"npc/fnt{major:D3}_{minor:D3}_{layerIndex:D2}.bf", stream => new FntBinary( stream, true ) ); //layer.Fpt = TryLoadFile( fieldNpcPak, $"npc/fpt{major:D3}_{minor:D3}_{layerIndex:D2}.bf", stream => new FptBinary( stream, true ) ); if (layer.ObjectPlacement == null && layer.HitTable == null && layer.HitScript == null && layer.NpcScript == null && layer.Fnt == null && layer.Fpt == null) { // Layer was empty, so assume there are no more layers break; } Layers.Add(layer); } //for ( int i = 1; i < 9; i++ ) // Pcds[ i ] = TryLoadFile( fieldPak, $"data/f{major:D3}_{minor:D3}_{i:D3}.PCD", stream => new PcdBinary( stream, true ) ); //Fpa = TryLoadFile( fieldPak, $"data/f{major:D3}_{minor:D3}.FPA", stream => new FpaBinary( stream, true ) ); //Culling = TryLoadFile( fieldPak, $"culling/f{major:D3}_{minor:D3}.CHD", stream => new ChdBinary( stream, true ) ); //Enemies = TryLoadFile( fieldPak, $"enemy/f{major:D3}_{minor:D3}.FEL", stream => new FelBinary( stream, true ) ); InitScript = TryLoadFile(fieldPak, $"init/fini_{major:D3}_{minor:D3}.bf", stream => FlowScriptBinary.FromStream(stream, true)); //Map = TryLoadFile( fieldPak, $"map/d{major:D3}_{minor:D3}.map", stream => new MapBinary( stream, true ) ); //Objects = TryLoadFile( fieldPak, $"map/d{major:D3}_{minor:D3}.OBL", stream => new OblBinary( stream, true ) ); ObjectHitTable = TryLoadFile(fieldPak, $"object_hit/f{major:D3}_{minor:D3}.HTB", stream => new HtbBinary(stream, true)); ObjectHitScript = TryLoadFile(fieldPak, $"object_hit/fhit{major:D3}_{minor:D3}.bf", stream => FlowScriptBinary.FromStream(stream, true)); //Sht = TryLoadFile( fieldPak, $"sht/f{major:D3}_{minor:D3}.SHT", stream => new ShtBinary( stream, true ) ); //Tbl = TryLoadFile( fieldPak, $"fext{major:D3}_{minor:D3}.tbl", stream => new TblBinary( stream, true ) ); AddUncategorizedFiles(fieldPak, UncategorizedFiles); if (fieldNpcPak != null) { AddUncategorizedFiles(fieldNpcPak, UncategorizedNpcFiles); } }
static void ExtractMessageScript(string file, Stream stream, string parentArchiveFile) { string prettyFileName; if (parentArchiveFile == null) { prettyFileName = file.Remove(0, DirectoryPath.Length); } else { prettyFileName = Path.Combine(parentArchiveFile, file); } // print some useful info if (parentArchiveFile == null) { Console.WriteLine($"Processing file: {prettyFileName}"); } else { Console.WriteLine($"Processing archive file: {prettyFileName}"); } // extract script MessageScript script = null; string fileExtension = Path.GetExtension(file); // Check if it is a plain message script file if (fileExtension.Equals(".bmd", StringComparison.InvariantCultureIgnoreCase)) { script = MessageScript.FromStream(stream, FormatVersion.Detect, Encoding, true); } // Check if it is a flow script file that can maybe contain a message script else if (fileExtension.Equals(".bf", StringComparison.InvariantCultureIgnoreCase)) { var flowScriptBinary = FlowScriptBinary.FromStream(stream, true); if (flowScriptBinary.MessageScriptSection != null) { script = MessageScript.FromBinary(flowScriptBinary.MessageScriptSection, FormatVersion.Detect, Encoding); } else { return; } } if (script != null) { // We have found a script, yay! Console.WriteLine("Writing message script to file..."); if (UseDecompiler) { WriteMessageScriptWithDecompiler(prettyFileName, script); } else { WriteMessageScript(prettyFileName, script); } } else { // Try to open the file as an archive if (!Archive.TryOpenArchive(stream, out var archive)) { // If we can't open the file as an archive, try brute force scanning if it is enabled if (EnableBruteforceScanning && (BruteforceExclusionList == null || BruteforceExclusionList != null && !BruteforceExclusionList.Any(x => x.Equals(fileExtension, StringComparison.InvariantCultureIgnoreCase))) && (BruteforceInclusionList == null || BruteforceInclusionList != null && BruteforceInclusionList.Any(x => x.Equals(fileExtension, StringComparison.InvariantCultureIgnoreCase))) ) { Console.WriteLine($"Bruteforce scanning..."); var scanCancel = new CancellationTokenSource(); var scanTask = Task.Factory.StartNew(() => ScanForMessageScripts(prettyFileName, stream, scanCancel.Token)); while (!scanTask.IsCompleted) { // Don't want to block, so wait for key to be available if (Console.KeyAvailable) { // Blocking is fine after this point var key = Console.ReadKey(true); if (key.Key == ConsoleKey.S) { Console.WriteLine("Do you want to skip scanning this file? Y/N"); if (Console.ReadKey(true).Key == ConsoleKey.Y) { scanCancel.Cancel(); Console.WriteLine("Do you want to add this file extension to the list of excluded files? Y/N"); if (Console.ReadKey(true).Key == ConsoleKey.Y) { if (BruteforceExclusionList == null) { BruteforceExclusionList = new List <string>(); } BruteforceExclusionList.Add(Path.GetExtension(prettyFileName)); } } } } } } } else { foreach (var entry in archive) { ExtractMessageScript(entry, archive.OpenFile(entry), prettyFileName); } } } }
/// <summary> /// Creates a <see cref="FlowScript"/> by loading it from a stream in the specified format version. /// </summary> /// <param name="stream">Data stream.</param> /// <param name="version">Format version the loader should use.</param> /// <returns>A <see cref="FlowScript"/> instance.</returns> public static FlowScript FromStream(Stream stream, Encoding encoding, FormatVersion version, bool leaveOpen) { FlowScriptBinary binary = FlowScriptBinary.FromStream(stream, (BinaryFormatVersion)version, leaveOpen); return(FromBinary(binary, encoding)); }