// should form a binary tree, can't have more than 2 children public MathNode(UberNode parent, string scriptInput, OpType opType) : base(parent, scriptInput) { Children.Add(null); Children.Add(null); OpTypeVal = opType; }
public UberNode(UberNode parent, string scriptInput) { if (parent != null) { this.Parent = parent; } ScriptString = scriptInput; }
public UberNode(UberNode parent, string scriptInput) { if (parent != null) { this.Parent = parent; } ScriptString = scriptInput; }
public UberNode(UberNode parent, string scriptInput, int lineNumber) { if (parent != null) { this.Parent = parent; } LineNumber = lineNumber; ScriptString = scriptInput; }
public UberNode(UberNode parent, string scriptInput, int lineNumber) { if (parent != null) { this.Parent = parent; } LineNumber = lineNumber; ScriptString = scriptInput; }
private Object GetReturnObject(UberNode node, TriggerObject trigObject) { if (node is RootNode) { // it's a spawn node, execute it return(((RootNode)Children[1]).SpawnAndReturnObject(ProcessResult.None, trigObject)); } if (node is MathTree) { return(((MathTree)Children[1]).Calculate(trigObject)); } throw new UberScriptException( "Line " + LineNumber + ": " + ScriptString + "\nStatement node did not have MathTree second child!"); }
public UberNode PrevSibling() { if (Parent == null) { return(null); } UberNode prevSibling = null; foreach (UberNode sibling in Parent.Children) { if (sibling == this) { return(prevSibling); } prevSibling = sibling; } return(null); }
public ConditionalNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public StatementNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public StatementNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public TriggerNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public UserDefinedFunctionExectueNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public ContinueNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public RootNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public ListAccessNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public PauseNode(UberNode parent, string scriptInput, double pause) : base(parent, scriptInput) { PauseMS = pause; }
public ForLoopNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public ListAccessNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public ForLoopNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public virtual bool Execute(TriggerObject trigObject, bool triggersOnly, UberNode pauseNode = null) { if (!Enabled || Deleted) return false; if (AttachedTo != null && AttachedTo.Deleted) { Delete(); return false; } trigObject.Script = this; // true IF there was a trigger override bool returnOverride = false; try { returnOverride = ParsedScripts.TryExecuteScript(ScriptFile, trigObject, RootNodeIndeces, triggersOnly); } catch (UberScriptException e) { if (m_SendDebugMessageTo != null && !m_SendDebugMessageTo.Deleted) { m_SendDebugMessageTo.SendMessage(36, "Error Executing script file: " + ScriptFile); Exception innerMostException = e; m_SendDebugMessageTo.SendMessage(36, e.Message); int level = 0; while (true) { if (innerMostException.InnerException == null) break; level++; innerMostException = innerMostException.InnerException; string msg = ""; for (int i = 0; i < level; i++) { msg += "--"; } msg += ">" + innerMostException.Message; m_SendDebugMessageTo.SendMessage(36, msg); } } if (ParsedScripts.DebugLevel >= (int)ParsedScripts.DebugLevels.ScriptDebugMessages) { Console.WriteLine("Error Executing script file: " + ScriptFile); Exception innerMostException = e; Console.WriteLine(e.Message); int level = 0; while (true) { if (innerMostException.InnerException == null) break; level++; innerMostException = innerMostException.InnerException; for (int i = 0; i < level; i++) { Console.Write("\t"); } Console.WriteLine(innerMostException.Message); } if (ParsedScripts.DebugLevel >= (int)ParsedScripts.DebugLevels.ScriptDebugMessagesAndStackTrace) Console.WriteLine(innerMostException.StackTrace); } } catch (Exception general) { if (m_SendDebugMessageTo != null && !m_SendDebugMessageTo.Deleted) { m_SendDebugMessageTo.SendMessage(36, "GENERAL UNCAUGHT ERROR Executing script file: " + ScriptFile); m_SendDebugMessageTo.SendMessage(36, general.Message); } Console.WriteLine("Error Executing script file: " + ScriptFile); Console.WriteLine("GENERAL UNCAUGHT ERROR: this should never happen!"); Console.WriteLine(general.Message); Console.WriteLine(general.StackTrace); } return returnOverride; }
public ListAccessNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public SpawnEntryNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public BreakNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public BreakNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public MathNode(UberNode parent, string scriptInput, OpType opType, TreePriority priority) : this(parent, scriptInput, opType) { Priority = priority; }
public UserDefinedFunctionNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public MathNode(UberNode parent, string scriptInput, OpType opType, TreePriority priority, Object value) : this(parent, scriptInput, opType, priority) { Value = value; }
public ReturnNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public MathTree(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public ListAccessNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public MathTree(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public SpawnGroupNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public ArgumentNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
private Object GetReturnObject(UberNode node, TriggerObject trigObject) { if (node is RootNode) { // it's a spawn node, execute it return ((RootNode)Children[1]).SpawnAndReturnObject(ProcessResult.None, trigObject); } if (node is MathTree) { return ((MathTree)Children[1]).Calculate(trigObject); } throw new UberScriptException( "Line " + LineNumber + ": " + ScriptString + "\nStatement node did not have MathTree second child!"); }
public SequenceNode(UberNode parent, string scriptInput, int stage) : base(parent, scriptInput) { Stage = stage; }
public ConditionalNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public MathTree(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public static RootNode ParseFileContents(string[] lines, string fileName) { CurrentFileBeingParsed = fileName; // ERROR HANDLING OUTSIDE OF THIS FUNCTION var balanceStack = new Stack <UberNode>(); RootNode root = new RootNode(null, null); RootNode currentRoot = root; // spawn nodes are root nodes UberNode current = root; UberNode prev = null; int currentLineNumber = 0; int openCurlyBraces = 0; var cleanedStrings = new List <CleanLine>(); foreach (string line in lines) { //Console.WriteLine(line); currentLineNumber++; StringBuilder sb = new StringBuilder(); string cleanedLine = line.Trim(); if (cleanedLine.StartsWith("//")) { continue; } bool insideQuotation = false; bool justEscapedBackslash = false; bool possibleComment = false; int forLoopRemainingSemiColons = 0; for (int i = 0; i < cleanedLine.Length; i++) { if (cleanedLine[i] == '\t') { continue; // always remove tabs... not allowed even in strings.. } if (cleanedLine[i] == '\\') { if (!insideQuotation) { throw new UberScriptException( String.Format( "Parse: unexpected escape token '\\' in '{0}' at line {1}:\n{2}", fileName, currentLineNumber, cleanedLine)); } if (!justEscapedBackslash) { if (i > 0 && cleanedLine[i - 1] == '\\') { justEscapedBackslash = true; } } else { justEscapedBackslash = false; } sb.Append('\\'); // keep the double backslash in there regardless (it is handled in MathTree.ParseOperand) continue; } if (cleanedLine[i] == '"') { if (!(i > 0 && cleanedLine[i - 1] == '\\' && !justEscapedBackslash)) { insideQuotation = !insideQuotation; } sb.Append("\""); // add \" to the string continue; } justEscapedBackslash = false; // make sure to reset this if you have gotten to this point if (insideQuotation) { sb.Append(cleanedLine[i]); continue; } if (cleanedLine[i] == '/') { if (possibleComment) { sb.Remove(sb.Length - 1, 1); // remove the previously added / character break; } possibleComment = true; sb.Append('/'); continue; } possibleComment = false; if (cleanedLine[i] == ' ' || cleanedLine[i] == '\t') { continue; } // handle lines with multiple delimiters (e.g. orc { name = "Bob"; } ) if (cleanedLine[i] == '{' || cleanedLine[i] == '}') { // check if unbalanced if (cleanedLine[i] == '{') { openCurlyBraces++; } else { openCurlyBraces--; } if (openCurlyBraces < 0) { throw new UberScriptException( String.Format( "Parse: brace mismatch detected in '{0}' at line {1}:\n{2}", fileName, currentLineNumber, cleanedLine)); } // add everything before the { or } (if there is anything) if (i > 0) { cleanedStrings.Add(new CleanLine(currentLineNumber, sb.ToString())); } cleanedStrings.Add(new CleanLine(currentLineNumber, cleanedLine[i].ToString(CultureInfo.InvariantCulture))); // add { or } on separate "line" (it's processed as a line) cleanedLine = cleanedLine.Substring(i + 1); i = -1; sb.Clear(); continue; } if (cleanedLine[i] == ';') { if (cleanedLine.Length == i + 1) { break; } // we are at the end of the loop, ignore lines ending in semicolon string stringPreviousToSemiColon = sb.ToString(); if (stringPreviousToSemiColon.Contains("for")) { if (stringPreviousToSemiColon.Contains("foreach(")) { forLoopRemainingSemiColons += 1; } else if (stringPreviousToSemiColon.Contains("for(")) // for loop has 2 semicolons { forLoopRemainingSemiColons += 2; } } if (forLoopRemainingSemiColons == 0) { // we have encountered a statement-separating semi-colon! // add everything before the { or } (if there is anything) if (i > 0) { cleanedStrings.Add(new CleanLine(currentLineNumber, sb.ToString())); } cleanedLine = cleanedLine.Substring(i + 1); i = -1; sb.Clear(); continue; } forLoopRemainingSemiColons--; } sb.Append(cleanedLine[i]); } cleanedLine = sb.ToString(); if (!String.IsNullOrWhiteSpace(cleanedLine) && !cleanedLine.StartsWith("//")) { cleanedStrings.Add(new CleanLine(currentLineNumber, sb.ToString())); } } foreach (CleanLine cleanedString in cleanedStrings) { // i have to use this CleanLine object to keep track of line numbers // in spite of {, }, and ; characters splitting the lines up! currentLineNumber = cleanedString.LineNumber; string cleanedLine = cleanedString.Value; if (cleanedLine == "" || cleanedLine.StartsWith("//")) { continue; } if (cleanedLine == "{") { balanceStack.Push(current); if (prev != null) { current = prev; } continue; } if (cleanedLine == "}") { if (balanceStack.Count > 0) { current = balanceStack.Pop(); if (current is RootNode) { // likely we have finished procesinto a spawn nodes (ChildRoots) // and therefore need to go back to the spawn node's root // so triggers are correctly assigned to it currentRoot = current.GetRootNode; } continue; } throw new UberScriptException( String.Format( "Parse: brace mismatch detected in '{0}' at line {1}:\n{2}", fileName, currentLineNumber, cleanedLine)); } // remove ending ";" characters (doesn't matter if you end with ; or not) // CANNOT do more than one statement on a line, though. // determine which type of node it is string lowerCase = cleanedLine.ToLower(); if (UberScriptTriggers.HasTrigger(lowerCase)) { prev = new TriggerNode(current, lowerCase); //Console.WriteLine(current + "->" + prev); currentRoot.TriggerNodes.Add(prev as TriggerNode); } else if (char.IsDigit(cleanedLine[0])) // must be a sequence node { int stage; if (!Int32.TryParse(cleanedLine, out stage)) { throw new UberScriptException( String.Format( "Parse: incorrect sequence format, integer expected at line {0}:\n{1}", currentLineNumber, cleanedLine)); } prev = new SequenceNode(current, cleanedLine, stage); } else if (cleanedLine.StartsWith("foreach")) { /* * objs.moblist = GETNEARBYMOBS(TRIGMOB(),5) * * foreach(objs.mob ; objs.moblist) * { * } */ prev = new ForEachNode(current, cleanedLine, currentLineNumber); } else if (cleanedLine.StartsWith("for")) { /* * for(ints.i = 0; ints.i < TRIGMOB().hits; ints.i = ints.i + 1) * { * } */ prev = new ForLoopNode(current, cleanedLine, currentLineNumber); } else if (cleanedLine.StartsWith("if") || cleanedLine.StartsWith("elif") || cleanedLine.StartsWith("else") || cleanedLine.StartsWith("elseif")) { prev = new ConditionalNode(current, cleanedLine, currentLineNumber); //Console.WriteLine(current + "->" + prev); } else if (cleanedLine.StartsWith("return")) { prev = new ReturnNode(current, cleanedLine); if (cleanedLine == "returnoverride") { ((ReturnNode)prev).Override = true; } } else { switch (cleanedLine) { case "break": { // check whether it has a foreach / for ancestor UberNode testParent = current; bool foundForNodeAncestor = false; while (testParent != null) { if (testParent is ForEachNode || testParent is ForLoopNode) { foundForNodeAncestor = true; break; } testParent = testParent.Parent; } if (!foundForNodeAncestor) { throw new UberScriptException( String.Format("Parse: unexpected 'break' statement at line {0}:\n{1}", currentLineNumber, cleanedLine)); } prev = new BreakNode(current, cleanedLine); } break; case "continue": { // check whether it has a foreach / for ancestor UberNode testParent = current; bool foundForNodeAncestor = false; while (testParent != null) { if (testParent is ForEachNode || testParent is ForLoopNode) { foundForNodeAncestor = true; break; } testParent = testParent.Parent; } if (!foundForNodeAncestor) { throw new UberScriptException( String.Format("Parse: unexpected 'continue' statement at line {0}:\n{1}", currentLineNumber, cleanedLine)); } prev = new ContinueNode(current, cleanedLine); } break; default: { if (cleanedLine.StartsWith("pause")) { double pauseDuration; if (!Double.TryParse(cleanedLine.Substring(5), out pauseDuration)) { pauseDuration = 0; } prev = new PauseNode(current, cleanedLine, pauseDuration); } else if (cleanedLine.StartsWith("function")) { prev = new UserDefinedFunctionNode(current, lowerCase); //Console.WriteLine(current + "->" + prev); root.UserDefinedFunctionNodes.Add(prev as UserDefinedFunctionNode); } /* * else if (cleanedLine.StartsWith("spawngroup")) * { * prev = new SpawnGroupNode * } * else if (cleanedLine.StartsWith("spawnregion")) * { * * } * else if (cleanedLine.StartsWith("spawnentry")) * { * * } */ else { int equalCount = 0; //char beforeChar = '\0'; int numOpenParentheses = 0; bool inQuotes = false; for (int i = 0; i < cleanedLine.Length; i++) { if (!inQuotes) { if (cleanedLine[i] == '=' && numOpenParentheses == 0) { equalCount++; } else { switch (cleanedLine[i]) { case '(': numOpenParentheses++; break; case ')': { numOpenParentheses--; if (numOpenParentheses < 0) { throw new UberScriptException( String.Format( "Parse: parentheses mismatch detected in '{0}' at line {1}:\n{2}", fileName, currentLineNumber, cleanedLine)); } } break; } } } if (cleanedLine[i] != '"') { continue; } inQuotes = !inQuotes; // assume that it's not an escaped quotation // determine if it is an escaped quotation (and that there aren't escaped backslashes preceding it) for (int ix = i - 1; ix >= 0 && cleanedLine[ix] == '\\'; ix--) { inQuotes = !inQuotes; // for each backslash behind, unescape or escape accordingly } } if (equalCount == 1) // it's a statement node { prev = new StatementNode(current, cleanedLine, currentLineNumber); //Console.WriteLine(current + "->" + prev); if (((StatementNode)prev).ContainsSpawnNode) { // global_objs.test = orc // { // name = goober // } prev.LineNumber = currentLineNumber; // we "continue" here so we set this later current.Children.Add(prev); // we "continue" here so we don't add it later //Console.WriteLine(current + "->" + prev + "... adding spawn node to statement node!"); prev = prev.Children[1]; // should contain a spawn node currentRoot.ChildRoots.Add(prev as RootNode); currentRoot = prev as RootNode; // spawn node become the new root node continue; } } else if (UberScriptFunctions.IsFunctionString(cleanedLine)) { prev = new FunctionNode(current, cleanedLine, currentLineNumber); //Console.WriteLine(current + "->" + prev); } else if (UserDefinedFunctionNode.GetUserDefinedFunctionString(cleanedLine, root) != null) { prev = new UserDefinedFunctionExectueNode(current, cleanedLine, currentLineNumber); ((UserDefinedFunctionExectueNode)prev).UserDefinedFunction = UserDefinedFunctionNode.GetUserDefinedFunctionString(cleanedLine, root); } else { // the string might have commas (indicating a spawn type with a constructor accepting arguments // such as "static,100" int commaIndex = cleanedLine.IndexOf(','); Type spawnType = ScriptCompiler.FindTypeByName(commaIndex > 0 ? cleanedLine.Substring(0, commaIndex) : cleanedLine); if (spawnType != null && typeof(Mobile).IsAssignableFrom(spawnType) || typeof(Item).IsAssignableFrom(spawnType)) { prev = new RootNode(current, cleanedLine); // keep a list of child root nodes so that spawned creatures that have triggers // specific to them can correctly point to the right place in the script e.g. // troll // { // onDeath // { // orc // { // onDeath // { // ... // } // } // } // } // --> trigger nodes are only added to their closest root node currentRoot.ChildRoots.Add(prev as RootNode); //Console.WriteLine(current + "->" + prev); currentRoot = prev as RootNode; // spawn node become the new root node } else { throw new UberScriptException( String.Format("Parse: could not parse node at line {0}:\n{1}", currentLineNumber, cleanedLine)); } } } } break; } } current.Children.Add(prev); prev.LineNumber = currentLineNumber; // used for debugging purposes } if (balanceStack.Count > 0) { throw new UberScriptException( String.Format("Parse: brace mismatch detected in '{0}' at line {1}", fileName, currentLineNumber)); } return(root); }
public MathTree(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public SpawnEntryNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public SpawnGroupNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public virtual bool Execute(TriggerObject trigObject, bool triggersOnly, UberNode pauseNode = null) { if (!Enabled || Deleted) { return(false); } if (AttachedTo != null && AttachedTo.Deleted) { Delete(); return(false); } trigObject.Script = this; // true IF there was a trigger override bool returnOverride = false; try { returnOverride = ParsedScripts.TryExecuteScript(ScriptFile, trigObject, RootNodeIndeces, triggersOnly); } catch (UberScriptException e) { if (m_SendDebugMessageTo != null && !m_SendDebugMessageTo.Deleted) { m_SendDebugMessageTo.SendMessage(36, "Error Executing script file: " + ScriptFile); Exception innerMostException = e; m_SendDebugMessageTo.SendMessage(36, e.Message); int level = 0; while (true) { if (innerMostException.InnerException == null) { break; } level++; innerMostException = innerMostException.InnerException; string msg = ""; for (int i = 0; i < level; i++) { msg += "--"; } msg += ">" + innerMostException.Message; m_SendDebugMessageTo.SendMessage(36, msg); } } if (ParsedScripts.DebugLevel >= (int)ParsedScripts.DebugLevels.ScriptDebugMessages) { Console.WriteLine("Error Executing script file: " + ScriptFile); Exception innerMostException = e; Console.WriteLine(e.Message); int level = 0; while (true) { if (innerMostException.InnerException == null) { break; } level++; innerMostException = innerMostException.InnerException; for (int i = 0; i < level; i++) { Console.Write("\t"); } Console.WriteLine(innerMostException.Message); } if (ParsedScripts.DebugLevel >= (int)ParsedScripts.DebugLevels.ScriptDebugMessagesAndStackTrace) { Console.WriteLine(innerMostException.StackTrace); } } } catch (Exception general) { if (m_SendDebugMessageTo != null && !m_SendDebugMessageTo.Deleted) { m_SendDebugMessageTo.SendMessage(36, "GENERAL UNCAUGHT ERROR Executing script file: " + ScriptFile); m_SendDebugMessageTo.SendMessage(36, general.Message); } Console.WriteLine("Error Executing script file: " + ScriptFile); Console.WriteLine("GENERAL UNCAUGHT ERROR: this should never happen!"); Console.WriteLine(general.Message); Console.WriteLine(general.StackTrace); } return(returnOverride); }
public TriggerNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public FunctionNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public ConditionalNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public UserDefinedFunctionNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public SpawnEntryNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public PauseNode(UberNode parent, string scriptInput, double pause) : base(parent, scriptInput) { PauseMS = pause; }
public FunctionNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public ReturnNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public UserDefinedFunctionExectueNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public ContinueNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public ReturnNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public SequenceNode(UberNode parent, string scriptInput, int stage) : base(parent, scriptInput) { Stage = stage; }
public ForEachNode(UberNode parent, string scriptInput) : base(parent, scriptInput) { }
public ConditionalNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public ForEachNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public SpawnEntryNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }
public StatementNode(UberNode parent, string scriptInput, int lineNumber) : base(parent, scriptInput, lineNumber) { }