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);
        }
示例#2
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());
        }