Ejemplo n.º 1
0
 protected int LastValidWord(Row row)
 {
     var comments = row.ToList().Where(w => w.Text.StartsWith("//"));
     if (comments.Count() > 0) {
         if (comments.Last().Index > 0) {
             for (int i = (comments.Last().Index - 1); i > 0; i--) {
                 if (row[i].Text != " " && row[i].Text != "\t") { return i + 1; }
             }
         }
         return comments.Last().Index;
     }
     return row.Count;
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Parses the row.
        /// </summary>
        /// <param name="row">The row.</param>
        /// <returns></returns>
        public ScriptLine ParseRow(Row row, ScriptFile file)
        {
            try {
                var lastindex = LastValidWord(row);
                var words = row.ToList().Where(w => w.Index < lastindex).ToList();

                //Primary Validation
                if (words.Count == 0) { return new ScriptLine(null, row.Index, row.Text, file); }
                if (words.First().Text.StartsWith("/")) { return new ScriptLine(null, row.Index, row.Text, file); }
                if (IsEmptyRow(row)) { return new ScriptLine(null, row.Index, row.Text, file); }
                if (row.Text.StartsWith("#endsection")) { return new ScriptLine(null, row.Index, row.Text, file); }

                //Section Validation
                if (row.Text.StartsWith("#section")) {
                    var sectionName = row.Text.Replace("#section", "").TrimStart(' ').TrimEnd(' ');
                    if (!ScriptSections.Contains(sectionName)) {
                        ScriptSections.Add(sectionName);
                        return new ScriptLine(null, row.Index, row.Text, file);
                    }
                    else { SetError(row, "Duplicated section name."); return null; }
                }

                //Syntax Validation
                if (words.Count < 3) { SetError(row, "Invalid expression."); return null; }
                if (words[1].Text != "(") { SetError(row, "Invalid expression."); return null; }
                if (words.Last().Text != ")") { SetError(row, "Invalid expression."); return null; }

                //Brackets Validation.
                if (CountChars(row.Text, '(') != CountChars(row.Text, ')')) { SetError(row, "You forgot to use the char ')' to close a function. Or otherwise used unnecessarily."); return null; }
                if (CountChars(row.Text, '[') != CountChars(row.Text, ']')) { SetError(row, "You forgot to use the char ']' to close a player property. Or otherwise used unnecessarily."); return null; }
                if (CountChars(row.Text, '{') != CountChars(row.Text, '}')) { SetError(row, "You forgot to use the char '}' to close a custom item. Or otherwise used unnecessarily."); return null; }
                if (CountChars(row.Text, '\"') % 2 != 0) { SetError(row, "You forgot to use the char '\"' to close a text expression. Or otherwise used unnecessarily."); return null; }

                //Null argument validation.
                if (row.Text.IndexOf("((") > -1) { SetError(row, "Invalid expression '(('."); return null; }
                if (row.Text.IndexOf("[[") > -1) { SetError(row, "Invalid expression '[['."); return null; }
                if (row.Text.IndexOf("{{") > -1) { SetError(row, "Invalid expression '{{'."); return null; }
                if (row.Text.IndexOf("[]") > -1) { SetError(row, "Invalid expression '[['."); return null; }
                if (row.Text.IndexOf("{}") > -1) { SetError(row, "Invalid expression '{{'."); return null; }
                if (row.Text.IndexOf(",,") > -1) { SetError(row, "Invalid expression ',,'."); return null; }

                //Function Validation
                if (ScriptActions.ContainsKey(words.First().Text)) {
                    var action = ScriptActions[words.First().Text];
                    var actionline = new ScriptLine(action, row.Index, row.Text, file);
                    var args = RemoveArgumentSpaces(GetFunctionArgument(row.Text).Split(new[] { ',' }));

                    //Argument Validation.
                    if ((action.Params == null || action.Params.Length > 0) && args.Length > 0) {
                        if (args.Length == 0) { SetError(row, "This function does not require arguments."); return null; }
                    }
                    if (action.Params != null && action.Params.Length > 0) {
                        if (args.Length == 0) { SetError(row, "This function requires one or more arguments."); return null; }
                        if (args.Length != action.Params.Length) { SetError(row, "Invalid number of arguments."); return null; }
                        actionline.Args = new string[args.Length];
                        for (int i = 0; i < args.Length; i++) {

                            #region "[rgn] String Argument Valdation "
                            if (action.Params[i].NeedQuotes && args[i].Contains("+")) {
                                var subparams = args[i].Split(new[] { '+' }, StringSplitOptions.RemoveEmptyEntries);
                                foreach (var sp in subparams) {
                                    if (sp.StartsWith("getparam")) {
                                        var spargs = GetFunctionArguments(sp);
                                        if (spargs.Length != 2) {
                                            SetError(row, "Invalid number of arguments to funcion getparam.");
                                            return null;
                                        }
                                        if (!GetParams.ContainsKey(spargs[0])) { GetParams.Add(spargs[0], row); }
                                    }
                                }
                            }
                            else if (!args[i].StartsWith("\"") && action.Params[i].NeedQuotes) {
                                if (!args[i].StartsWith("getparam") && !args[i].StartsWith("getvalue")) {
                                    SetError(row, string.Format("The argument \"{0}\" of this function must be inside quotes. Ex. \"...\"", i.ToString()));
                                    return null;
                                }
                            }
                            actionline.Args[i] = args[i];
                            #endregion
                        }
                    }

                    //Waypoint Validation.
                    if (actionline.FunctionText.ToLower() == "goto") {
                        var wp = new LocationKeyword();
                        if (wp.Parse(GetFunctionArgument(row.Text))) {
                            ScriptWayPoints.Add(row, wp);
                        }
                        else { SetError(row, "Invalid waypoint declaration."); }
                    }

                    //Parameter Validation
                    if (actionline.FunctionText.ToLower() == "setparam") {
                        var paramkey = actionline.Args[0].ToString().TrimStart(new[] { '"' }).TrimEnd(new[] { '"' });
                        var paramvalue = actionline.Args[1].ToString().TrimStart(new[] { '"' }).TrimEnd(new[] { '"' });
                        if (!ScriptParams.ContainsKey(paramkey)) { ScriptParams.Add(paramkey, paramvalue); }
                    }
                    foreach (var word in words) {
                        if (word.Text == "getparam") {
                            if (!ScriptParams.ContainsKey(row[word.Index + 3].Text)) {
                                SetError(row[word.Index + 3], string.Format("The parameter \"{0}\" was not found. You must call setparam(\"{0}\", value) before use it.", row[word.Index + 3].Text));
                                return null;
                            }
                            else { if (!GetParams.ContainsKey(row[word.Index + 3].Text)) { GetParams.Add(row[word.Index + 3].Text, row); } }
                        }
                        else if (word.Text == "gotoline") {
                            if (row[word.Index + 2].Text.ToInt32() >= Document.Lines.Length) {
                                SetError(word, string.Format("This script does not have the line \"{0}\".", row[word.Index + 2].Text));
                                return null;
                            }
                        }
                        else if (word.Text == "gotosection") {
                            if (!row.Document.Text.Contains(string.Format("#section {0}", row[word.Index + 2].Text))) {
                                SetError(row[word.Index + 2], string.Format("This script does not contains a section named \"{0}\".", row[word.Index + 2].Text));
                                return null;
                            }
                        }
                        else if (word.Text == "[") {
                            if (PlayerProperties.FindByInputText(row[word.Index + 1].Text.Trim().ToUpper()) == null) {
                                SetError(row[word.Index + 1], string.Format("The player property \"{0}\" does not exist.", row[word.Index + 1].Text));
                                return null;
                            }
                        }
                        else if (word.Text == "{") {
                            if (CustomItems.FindByInputText(row[word.Index + 1].Text.Trim().ToUpper()) == null) {
                                SetError(row[word.Index + 1], string.Format("The custom item \"{0}\" does not exist.", row[word.Index + 1].Text));
                                return null;
                            }
                        }
                    }
                    return actionline;
                }
                SetError(words.First(), string.Format("The function \"{0}\" does not exist.", words.First().Text)); return null;
            }
            catch (Exception ex) {
                SetWarning(row, string.Format("Could not parse the row number \"{0}\"", row.Index + 1));
                SetError(row, string.Format("Details: {0}", ex.Message));
                return null;
            }
        }