/// <summary> /// Initializes a new instance of the <see cref="ScriptRunner"/> class. /// </summary> /// <param name="file">The file.</param> /// <param name="client">The client.</param> public ScriptRunner(ScriptFile file, TibiaClient tibiaClient) { this.File = file; this.File.ScriptInfo.TibiaClient = tibiaClient; this.TibiaClient = tibiaClient; foreach (var row in File.Rows) { row.OnActionComplete += row_OnActionComplete; row.SetupRow(tibiaClient); } }
/// <summary> /// Initializes a new instance of the <see cref="ScriptFileEventArgs"/> class. /// </summary> /// <param name="file">The file.</param> public ScriptFileEventArgs(ScriptFile file) { this.Script = file; }
/// <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; } }
protected ScriptFile GetFileInfo() { var res = new ScriptFile(); var text = Editor.Document.Text; res.Title = GetTextInsidePatern(text, "<Title>", "</Title>"); res.Author = GetTextInsidePatern(text, "<Author>", "</Author>"); res.About = GetTextInsidePatern(text, "<About>", "</About>"); res.TibiaVersion = GetTextInsidePatern(text, "<Tibia>", "</Tibia>"); res.ReleaseDate = GetTextInsidePatern(text, "<Date>", "</Date>"); res.Notes = GetTextInsidePatern(text, "<Notes>", "</Notes>"); res.Rows = new List<ScriptLine>(); return res; }
/// <summary> /// Checks the script warnings. /// </summary> public void CheckScriptWarnings(ScriptFile file) { //File Verificaton AddOutput("Checking script information..."); if (file.Title == string.Empty) { SetWarning("This script does not have a Title."); } if (file.TibiaVersion == string.Empty) { SetWarning("This script does not specifies a tibia version."); } if (file.Author == string.Empty) { SetWarning("This script does not have a Author."); } //Section Verification AddOutput("Checking script sections..."); if (ScriptSections.Count == 0) { SetWarning("This script contains no sections."); } //Params Verification AddOutput("Checking script parameters..."); foreach (var param in SetParams) { if (!GetParams.ContainsKey(param.Key)) { //check for getparam in string constants. SetWarning(param.Value, string.Format("The parameter {0} is never used.", param.Key)); } } //Waypoint Validation AddOutput("Checking script waypoints..."); if (ScriptWayPoints.Count > 0) { var lastwp = ScriptWayPoints.First(); foreach (var waypoint in ScriptWayPoints) { var wp = waypoint; if (lastwp.Key.Index != wp.Key.Index) { var distx = wp.Value.X - lastwp.Value.X; if (distx < 0) { distx = distx * -1; } var disty = wp.Value.Y - lastwp.Value.Y; if (disty < 0) { disty = disty * -1; } if (distx > 25 || disty > 25) { SetWarning(waypoint.Key, "The distance from the last waypoint is to large."); SetWarning("Try to use waypoints closest to themselves."); } else if (distx == 0 && disty == 0) { if (wp.Value.Z == lastwp.Value.Z && (wp.Key.Index - lastwp.Key.Index) == 1) { SetWarning(waypoint.Key, "This waypoint is duplicated."); } } } lastwp = wp; } } else { SetWarning("This script does not contains waypoints."); } }