internal static int Export(CompileOptions options) { YarnSpinnerConsole.CheckFileList(options.files, YarnSpinnerConsole.ALLOWED_EXTENSIONS); foreach (var file in options.files) { var dialogue = YarnSpinnerConsole.CreateDialogueForUtilities(); // Load and compile the program try { // First, we need to ensure that this file compiles. dialogue.LoadFile(file); } catch { YarnSpinnerConsole.Warn(string.Format("Skipping file {0} due to compilation errors.", file)); continue; } // Convert the program into BSON var compiledProgram = dialogue.GetCompiledProgram(options.format); var outputPath = System.IO.Path.ChangeExtension(file, "yarn.bytes"); try { System.IO.File.WriteAllBytes(outputPath, compiledProgram); } catch (Exception e) { YarnSpinnerConsole.Error(string.Format("Error writing {0}: {1}", outputPath, e.Message)); } } return(0); }
static internal int ConvertFormat(ConvertFormatOptions options) { YarnSpinnerConsole.CheckFileList(options.files, YarnSpinnerConsole.ALLOWED_EXTENSIONS); if (options.convertToYarn) { return(ConvertToYarn(options)); } var processName = System.IO.Path.GetFileName(Environment.GetCommandLineArgs()[0]); YarnSpinnerConsole.Error(string.Format(CultureInfo.CurrentCulture, "You must specify a destination format. Run '{0} help convert' to learn more.", processName)); return(1); }
static void ConvertNodesInFile(ConvertFormatOptions options, string file, string fileExtension, ConvertNodesToText convert) { var d = new Dialogue(null); var text = File.ReadAllText(file); IEnumerable <Loader.NodeInfo> nodes; try { nodes = d.loader.GetNodesFromText(text, Loader.GetFormatFromFileName(file)); } catch (FormatException e) { YarnSpinnerConsole.Error(e.Message); return; } var serialisedText = convert(nodes); var destinationDirectory = options.outputDirectory; if (destinationDirectory == null) { destinationDirectory = Path.GetDirectoryName(file); } var fileName = Path.GetFileName(file); // ChangeExtension thinks that the file "Foo.yarn.txt" has the extension "txt", so // to simplify things, just lop that extension off right away if it's there fileName = fileName.Replace(".yarn.txt", ""); // change the filename's extension fileName = Path.ChangeExtension(fileName, fileExtension); // figure out where we're writing this file var destinationFilePath = Path.Combine(destinationDirectory, fileName); File.WriteAllText(destinationFilePath, serialisedText); if (options.verbose) { YarnSpinnerConsole.Note("Wrote " + destinationFilePath); } }
static internal int GenerateTables(GenerateTableOptions options) { YarnSpinnerConsole.CheckFileList(options.files, YarnSpinnerConsole.ALLOWED_EXTENSIONS); if (options.verbose && options.onlyUseTag != null) { YarnSpinnerConsole.Note(string.Format(CultureInfo.CurrentCulture, "Only using lines from nodes tagged \"{0}\"", options.onlyUseTag)); } bool linesWereUntagged = false; foreach (var file in options.files) { var dialogue = YarnSpinnerConsole.CreateDialogueForUtilities(); dialogue.LoadFile(file); var stringTable = dialogue.GetStringTable(); var emittedStringTable = new Dictionary <string, string> (); var anyLinesAreUntagged = false; foreach (var entry in stringTable) { // If options.onlyUseTag is set, we skip all lines in nodes that // don't have that tag. if (options.onlyUseTag != null) { // Find the tags for the node that this string is in LineInfo stringInfo; try { stringInfo = dialogue.program.lineInfo[entry.Key]; } catch (KeyNotFoundException) { YarnSpinnerConsole.Error(string.Format(CultureInfo.CurrentCulture, "{0}: lineInfo table does not contain an entry for line {1} (\"{2}\")", file, entry.Key, entry.Value)); return(1); } Node node; try { node = dialogue.program.nodes[stringInfo.nodeName]; } catch (KeyNotFoundException) { YarnSpinnerConsole.Error(string.Format(CultureInfo.CurrentCulture, "{0}: Line {1}'s lineInfo claims that the line originates in node {2}, but this node is not present in this program.", file, entry.Key, stringInfo.nodeName)); return(1); } var tags = node.tags; // If the tags don't include the one we're looking for, // skip this line if (tags.FindIndex(i => i == options.onlyUseTag) == -1) { continue; } } if (entry.Key.StartsWith("line:", StringComparison.InvariantCulture) == false) { anyLinesAreUntagged = true; } else { emittedStringTable [entry.Key] = entry.Value; } } if (anyLinesAreUntagged) { YarnSpinnerConsole.Warn(string.Format(CultureInfo.CurrentCulture, "Untagged lines in {0}", file)); linesWereUntagged = true; } // Generate the CSV using (var w = new System.IO.StringWriter()) { using (var csv = new CsvWriter(w)) { csv.WriteHeader <LocalisedLine>(); foreach (var entry in emittedStringTable) { var l = new LocalisedLine(); l.LineCode = entry.Key; l.LineText = entry.Value; l.Comment = ""; csv.WriteRecord(l); } var dir = System.IO.Path.GetDirectoryName(file); var fileName = System.IO.Path.GetFileNameWithoutExtension(file); fileName += "_lines.csv"; var filePath = System.IO.Path.Combine(dir, fileName); System.IO.File.WriteAllText(filePath, w.ToString()); if (options.verbose) { YarnSpinnerConsole.Note("Wrote " + filePath); } } } } if (linesWereUntagged) { YarnSpinnerConsole.Warn("Some lines were not tagged, so they weren't added to the " + "string file. Use this tool's 'generate' action to add them."); } return(0); }
static string ConvertNodesToYarnText(IEnumerable <Loader.NodeInfo> nodes) { var sb = new System.Text.StringBuilder(); var properties = typeof(Loader.NodeInfo).GetProperties(); foreach (var node in nodes) { foreach (var property in properties) { // ignore the body attribute if (property.Name == "body") { continue; } // piggy-back off the JsonIgnoreAttribute to sense items that should not be serialised if (property.GetCustomAttributes(typeof(JsonIgnoreAttribute), false).Length > 0) { continue; } var field = property.Name; string value; var propertyType = property.PropertyType; if (propertyType.IsAssignableFrom(typeof(string))) { value = (string)property.GetValue(node, null); // avoid storing nulls when we could store the empty string instead if (value == null) { value = ""; } } else if (propertyType.IsAssignableFrom(typeof(int))) { value = ((int)property.GetValue(node, null)).ToString(); } else if (propertyType.IsAssignableFrom(typeof(Loader.NodeInfo.Position))) { var position = (Loader.NodeInfo.Position)property.GetValue(node, null); value = string.Format("{0},{1}", position.x, position.y); } else { YarnSpinnerConsole.Error(string.Format("Internal error: Node {0}'s property {1} has unsupported type {2}", node.title, property.Name, propertyType.FullName)); // will never be run, but prevents the compiler being mean about us not returning a value throw new Exception(); } var header = string.Format("{0}: {1}", field, value); sb.AppendLine(header); } // now write the body sb.AppendLine("---"); sb.AppendLine(node.body); sb.AppendLine("==="); } return(sb.ToString()); }