private bool TryDecompileScript(FlowScript flowScript, out CompilationUnit compilationUnit) { // Evaluate script if (!TryEvaluateScript(flowScript, out var evaluationResult)) { LogError("Failed to evaluate script"); compilationUnit = null; return(false); } if (!TryDecompileScriptInternal(evaluationResult, out compilationUnit)) { LogError("Failed to decompile script"); compilationUnit = null; return(false); } return(true); }
public bool TryDecompile(FlowScript flowScript, string filepath) { mFilePath = Path.GetFullPath(filepath); LogInfo($"FlowScript output path set to {mFilePath}"); if (MessageScriptFilePath == null) { MessageScriptFilePath = Path.ChangeExtension(mFilePath, "msg"); } LogInfo($"MessageScript output path set to {MessageScriptFilePath}"); if (flowScript.MessageScript != null) { // Disambiguate message script dialog names so that the decompilation won't fail DisambiguateMessageScriptDialogNames(flowScript.MessageScript); if (DecompileMessageScript) { // Decompile embedded message script LogInfo("Writing decompiled MessageScript to file"); using (var messageScriptDecompiler = new MessageScriptDecompiler(new FileTextWriter(MessageScriptFilePath))) { messageScriptDecompiler.Library = Library; messageScriptDecompiler.Decompile(flowScript.MessageScript); } } } // Decompile to decompilation unit if (!TryDecompile(flowScript, out var compilationUnit)) { return(false); } // Write out the decompilation unit LogInfo("Writing decompiled FlowScript to file"); var writer = new CompilationUnitWriter(); writer.Write(compilationUnit, filepath); return(true); }
FlowScript CheckInstance() { if (flowScript == currentInstance) { return(currentInstance); } FlowScript instance = null; if (!instances.TryGetValue(flowScript, out instance)) { instance = Graph.Clone <FlowScript>(flowScript); instances[flowScript] = instance; } instance.agent = graphAgent; instance.blackboard = graphBlackboard; flowScript = instance; return(instance); }
private static bool TryDoFlowScriptDecompilation() { // Load binary file Logger.Info("Loading binary FlowScript file..."); FlowScript flowScript = null; var encoding = MessageScriptEncoding; var format = GetFlowScriptFormatVersion(); if (!TryPerformAction("Failed to load flow script from file", () => flowScript = FlowScript.FromFile(InputFilePath, encoding, format))) { return(false); } Logger.Info("Decompiling FlowScript..."); var decompiler = new FlowScriptDecompiler(); decompiler.SumBits = FlowScriptSumBits; decompiler.AddListener(Listener); if (LibraryName != null) { var library = LibraryLookup.GetLibrary(LibraryName); if (library == null) { Logger.Error("Invalid library name specified"); return(false); } decompiler.Library = library; } if (!decompiler.TryDecompile(flowScript, OutputFilePath)) { Logger.Error("Failed to decompile FlowScript"); return(false); } return(true); }
protected override Status OnExecute(Component agent, IBlackboard blackboard) { if (flowScript == null) { return(Status.Failure); } if (status == Status.Resting) { currentInstance = CheckInstance(); status = Status.Running; currentInstance.StartGraph(agent, blackboard, false, OnFlowScriptFinished); } if (status == Status.Running) { currentInstance.UpdateGraph(); } return(status); }
static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine($"Missing filename"); return; } MessageScript msg = null; var filePath = args[0]; if (filePath.EndsWith("bf", StringComparison.InvariantCultureIgnoreCase)) { msg = FlowScript.FromFile(filePath).MessageScript; } else if (filePath.EndsWith("bmd")) { msg = MessageScript.FromFile(args[0]); } else if (filePath.EndsWith("msg")) { var msgCompiler = new MessageScriptCompiler(AtlusScriptLibrary.MessageScriptLanguage.FormatVersion.Version1); msg = msgCompiler.Compile(File.OpenText(filePath)); } else { Console.WriteLine("Can't detect input type (unknown extension)"); return; } using (var writer = File.CreateText($"{Path.GetFileNameWithoutExtension( args[ 0 ] )}_ids.txt")) { for (var i = 0; i < msg.Dialogs.Count; i++) { var dialog = msg.Dialogs[i]; writer.WriteLine($"{i}\t\t{dialog.Name}"); } } }
private static IEnumerable <(FlowScript, string)> FindFlowScripts(string file, Archive archive = null, string archiveFilePath = null) { if (file.EndsWith("bf", StringComparison.InvariantCultureIgnoreCase)) { if (archive == null) { yield return(FlowScript.FromFile(file, sEncoding), file); } else { yield return(FlowScript.FromStream(archive.OpenFile(file), sEncoding), Path.Combine(archiveFilePath, file)); } } else if (archive == null ? Archive.TryOpenArchive(File.OpenRead(file), out var subArchive) : Archive.TryOpenArchive(archive.OpenFile(file), out subArchive)) { foreach (string entry in subArchive) { foreach (var script in FindFlowScripts(entry, subArchive, archive == null ? file : Path.Combine(archiveFilePath, file))) { yield return(script); } } } }
bool IsInstance(FlowScript fs) { return(instances.Values.Contains(fs)); }
private static bool TryDoFlowScriptCompilation() { Logger.Info("Compiling FlowScript..."); // Get format verson var version = GetFlowScriptFormatVersion(); if (version == FormatVersion.Unknown) { Logger.Error("Invalid FlowScript file format specified"); return(false); } // Compile source var compiler = new FlowScriptCompiler(version); compiler.AddListener(Listener); compiler.Encoding = MessageScriptEncoding; compiler.EnableProcedureTracing = FlowScriptEnableProcedureTracing; compiler.EnableProcedureCallTracing = FlowScriptEnableProcedureCallTracing; compiler.EnableFunctionCallTracing = FlowScriptEnableFunctionCallTracing; compiler.EnableStackCookie = FlowScriptEnableStackCookie; compiler.ProcedureHookMode = FlowScriptEnableProcedureHook ? ProcedureHookMode.ImportedOnly : ProcedureHookMode.None; if (LibraryName != null) { var library = LibraryLookup.GetLibrary(LibraryName); if (library == null) { Logger.Error("Invalid library name specified"); return(false); } compiler.Library = library; } FlowScript flowScript = null; var success = false; using (var file = File.Open(InputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { try { success = compiler.TryCompile(file, out flowScript); } catch (UnsupportedCharacterException e) { Logger.Error($"Character '{e.Character}' not supported by encoding '{e.EncodingName}'"); } if (!success) { Logger.Error("One or more errors occured during compilation!"); return(false); } } // Write binary Logger.Info("Writing binary to file..."); return(TryPerformAction("An error occured while saving the file.", () => flowScript.ToFile(OutputFilePath))); }
public void FromFile_ShouldThrowInvalidDataException_InvalidFileFormatBig() { Assert.ThrowsException <InvalidDataException>(() => FlowScript.FromFile("TestResources\\dummy_big.bin", null, FormatVersion.Unknown)); }
public void ToBinary_ContentsShouldMatchThatOfSourceBinary_Version3BigEndian() { var binaryIn = FlowScriptBinary.FromFile("TestResources\\Version3BigEndian.bf"); var script = FlowScript.FromBinary(binaryIn); var binaryOut = script.ToBinary(); // Compare headers Assert.AreEqual(binaryIn.Header.FileType, binaryOut.Header.FileType); Assert.AreEqual(binaryIn.Header.Compressed, binaryOut.Header.Compressed); Assert.AreEqual(binaryIn.Header.UserId, binaryOut.Header.UserId); Assert.AreEqual(binaryIn.Header.FileSize, binaryOut.Header.FileSize); Assert.IsTrue(binaryIn.Header.Magic.SequenceEqual(binaryOut.Header.Magic)); Assert.AreEqual(binaryIn.Header.Field0C, binaryOut.Header.Field0C); Assert.AreEqual(binaryIn.Header.SectionCount, binaryOut.Header.SectionCount); Assert.AreEqual(binaryIn.Header.LocalIntVariableCount, binaryOut.Header.LocalIntVariableCount); Assert.AreEqual(binaryIn.Header.LocalFloatVariableCount, binaryOut.Header.LocalFloatVariableCount); Assert.AreEqual(binaryIn.Header.Endianness, binaryOut.Header.Endianness); Assert.AreEqual(binaryIn.Header.Field1A, binaryOut.Header.Field1A); Assert.AreEqual(binaryIn.Header.Padding, binaryOut.Header.Padding); // Compare section headers for (int i = 0; i < binaryIn.SectionHeaders.Count; i++) { Assert.AreEqual(binaryIn.SectionHeaders[i].SectionType, binaryOut.SectionHeaders[i].SectionType); Assert.AreEqual(binaryIn.SectionHeaders[i].ElementSize, binaryOut.SectionHeaders[i].ElementSize); Assert.AreEqual(binaryIn.SectionHeaders[i].ElementCount, binaryOut.SectionHeaders[i].ElementCount); Assert.AreEqual(binaryIn.SectionHeaders[i].FirstElementAddress, binaryOut.SectionHeaders[i].FirstElementAddress); } // Compare labels for (int i = 0; i < binaryIn.ProcedureLabelSection.Count; i++) { Assert.AreEqual(binaryIn.ProcedureLabelSection[i].Name, binaryOut.ProcedureLabelSection[i].Name); Assert.AreEqual(binaryIn.ProcedureLabelSection[i].InstructionIndex, binaryOut.ProcedureLabelSection[i].InstructionIndex); Assert.AreEqual(binaryIn.ProcedureLabelSection[i].Reserved, binaryOut.ProcedureLabelSection[i].Reserved); } for (int i = 0; i < binaryIn.JumpLabelSection.Count; i++) { Assert.AreEqual(binaryIn.JumpLabelSection[i].Name, binaryOut.JumpLabelSection[i].Name); Assert.AreEqual(binaryIn.JumpLabelSection[i].InstructionIndex, binaryOut.JumpLabelSection[i].InstructionIndex); Assert.AreEqual(binaryIn.JumpLabelSection[i].Reserved, binaryOut.JumpLabelSection[i].Reserved); } // Compare instructions for (int i = 0; i < binaryIn.TextSection.Count; i++) { var inInstruction = binaryIn.TextSection[i]; var outInstruction = binaryOut.TextSection[i]; Assert.AreEqual(inInstruction.Opcode, outInstruction.Opcode); if (inInstruction.Opcode == Opcode.PUSHI || inInstruction.Opcode == Opcode.PUSHF) { ++i; continue; } if (inInstruction.Opcode == Opcode.IF || inInstruction.Opcode == Opcode.GOTO) { Assert.AreEqual(binaryIn.JumpLabelSection[inInstruction.OperandShort].Name, binaryOut.JumpLabelSection[outInstruction.OperandShort].Name); } else { Assert.AreEqual(inInstruction.OperandShort, outInstruction.OperandShort); } } // Compare message script //Assert.IsTrue(binaryIn.MessageScriptSection.SequenceEqual(binaryOut.MessageScriptSection)); // Compare strings Assert.IsTrue(binaryIn.StringSection.SequenceEqual(binaryOut.StringSection)); }