/// <summary> /// Runs a script with a different language inside the LoliScript. /// </summary> /// <param name="script">The script as a string with linebreaks</param> /// <param name="language">The language of the script</param> /// <param name="outputs">The variables that should be extracted from the script's scope and set into the BotData local variables</param> /// <param name="data">The BotData needed for variable replacement</param> private void RunScript(string script, ScriptingLanguage language, string outputs, BotData data) { // Set the console output to stringwriter var sw = new StringWriter(); Console.SetOut(sw); Console.SetError(sw); // Parse variables to get out var outVarList = new List <string>(); if (outputs != string.Empty) { try { outVarList = outputs.Split(',').Select(x => x.Trim()).ToList(); } catch { } } var start = DateTime.Now; var variableList = BlockBase.GetVariables(data); try { switch (language) { case ScriptingLanguage.JavaScript: // Redefine log() function var jsengine = new Engine().SetValue("log", new Action <object>(Console.WriteLine)); // Add in all the variables foreach (var variable in variableList.Variables) { try { switch (variable.Type) { case VariableType.ListOfStrings: jsengine.SetValue(variable.Name, variable.AsListOfStrings().ToArray()); break; default: jsengine.SetValue(variable.Name, variable.AsString()); break; } } catch { } } // Execute JS jsengine.Execute(script); // Print results to log data.Logger.Log($"DEBUG LOG: {sw}", LogColors.White); // Get variables out data.Logger.Log($"Parsing {outVarList.Count} variables", LogColors.White); foreach (var name in outVarList) { try { // Add it to the variables and print info var value = jsengine.Global.GetProperty(name).Value; var isArray = value.IsArray(); if (isArray) { variableList.Set(new ListOfStringsVariable(value.TryCast <List <string> >()) { Name = name }); } else { variableList.Set(new StringVariable(value.ToString()) { Name = name }); } data.Logger.Log($"SET VARIABLE {name} WITH VALUE {value}", LogColors.Yellow); } catch { data.Logger.Log($"COULD NOT FIND VARIABLE {name}", LogColors.Tomato); } } // Print other info if (jsengine.GetCompletionValue() != null) { data.Logger.Log($"Completion value: {jsengine.GetCompletionValue()}", LogColors.White); } break; case ScriptingLanguage.IronPython: // Initialize the engine var runtime = Python.CreateRuntime(); var pyengine = runtime.GetEngine("py"); PythonCompilerOptions pco = (PythonCompilerOptions)pyengine.GetCompilerOptions(); pco.Module &= ~ModuleOptions.Optimized; //var pyengine = Python.CreateEngine(); var scope = pyengine.CreateScope(); var code = pyengine.CreateScriptSourceFromString(script); // Add in all the variables foreach (var variable in variableList.Variables) { try { scope.SetVariable(variable.Name, variable.AsObject()); } catch { } } // Execute it var result = code.Execute(scope); //var result = pyengine.Execute(script, scope); // Print the logs data.Logger.Log($"DEBUG LOG: {sw}", LogColors.White); // Get variables out data.Logger.Log($"Parsing {outVarList.Count} variables", LogColors.White); foreach (var name in outVarList) { try { // Add it to the variables and print info var value = scope.GetVariable(name); if (value.GetType() == typeof(string[])) { variableList.Set(new ListOfStringsVariable(value.ToList()) { Name = name }); } else { variableList.Set(new StringVariable(value.ToString()) { Name = name }); } data.Logger.Log($"SET VARIABLE {name} WITH VALUE {value}", LogColors.Yellow); } catch { data.Logger.Log($"COULD NOT FIND VARIABLE {name}", LogColors.Tomato); } } // Print other info if (result != null) { data.Logger.Log($"Completion value: {result}", LogColors.White); } break; default: break; } data.Logger.Log($"Execution completed in {(DateTime.Now - start).TotalSeconds} seconds", LogColors.GreenYellow); } catch (Exception e) { data.Logger.Log($"[ERROR] INFO: {e.Message}", LogColors.White); } finally { var standardOutput = new StreamWriter(Console.OpenStandardOutput()); var standardError = new StreamWriter(Console.OpenStandardError()); standardOutput.AutoFlush = true; standardError.AutoFlush = true; Console.SetOut(standardOutput); Console.SetError(standardError); } }
/// <summary> /// Gets the Action that needs to be executed. /// </summary> static internal Action Parse(string line, LSGlobals ls) { var data = ls.BotData; var input = line.Trim(); var field = LineParser.ParseToken(ref input, TokenType.Parameter, true).ToUpper(); return(new Action(() => { switch (field) { case "SOURCE": data.SOURCE = LineParser.ParseLiteral(ref input, "SOURCE", true, ls); break; case "STATUS": data.STATUS = LineParser.ParseToken(ref input, TokenType.Parameter, true); // E.g. user wrote SET STATUS CUSTOM "TEST" if (data.STATUS == "CUSTOM" && !string.IsNullOrEmpty(input)) { data.STATUS = LineParser.ParseLiteral(ref input, "CUSTOM STATUS"); } break; case "RESPONSECODE": data.RESPONSECODE = LineParser.ParseInt(ref input, "RESPONSECODE"); break; case "COOKIE": var name = LineParser.ParseLiteral(ref input, "NAME", true, ls); data.COOKIES.Add(name, LineParser.ParseLiteral(ref input, "VALUE", true, ls)); break; case "ADDRESS": data.ADDRESS = LineParser.ParseLiteral(ref input, "ADDRESS", true, ls); break; case "USEPROXY": var use = LineParser.ParseToken(ref input, TokenType.Parameter, true).ToUpper(); if (use == "TRUE") { data.UseProxy = true; } else if (use == "FALSE") { data.UseProxy = false; } break; case "PROXY": var prox = LineParser.ParseLiteral(ref input, "PROXY", true, ls); data.Proxy = Proxy.Parse(prox); break; case "PROXYTYPE": data.Proxy.Type = (ProxyType)LineParser.ParseEnum(ref input, "PROXYTYPE", typeof(ProxyType)); break; case "DATA": data.Line.Data = LineParser.ParseLiteral(ref input, "DATA", true, ls); break; case "VAR": var varName = LineParser.ParseLiteral(ref input, "NAME", true, ls); var varValue = LineParser.ParseLiteral(ref input, "VALUE", true, ls); BlockBase.GetVariables(data).Set(new StringVariable(varValue) { Name = varName }); break; case "CAP": var capName = LineParser.ParseLiteral(ref input, "NAME", true, ls); var capValue = LineParser.ParseLiteral(ref input, "VALUE", true, ls); BlockBase.GetVariables(data).Set(new StringVariable(capValue) { Name = capName }); data.MarkForCapture(capName); break; case "GVAR": try { var globalVarName = LineParser.ParseLiteral(ref input, "NAME", true, ls); var globalVarValue = LineParser.ParseLiteral(ref input, "VALUE", true, ls); ls.Globals.Set(new StringVariable(globalVarValue) { Name = globalVarName }); } catch { } break; case "NEWGVAR": try { var globalVarName = LineParser.ParseLiteral(ref input, "NAME", true, ls); var globalVarValue = LineParser.ParseLiteral(ref input, "VALUE", true, ls); ls.Globals.SetIfNew(new StringVariable(globalVarValue) { Name = globalVarName }); } catch { } break; case "GCOOKIES": ls.GlobalCookies.Clear(); foreach (var cookie in data.COOKIES) { ls.GlobalCookies.Add(cookie.Key, cookie.Value); } break; default: throw new ArgumentException($"Invalid identifier {field}"); } data.Logger.Log($"SET command executed on field {field}", LogColors.White); })); }
/// <summary> /// Gets the Action that needs to be executed. /// </summary> static internal Action Parse(string line, LSGlobals ls) { var data = ls.BotData; var input = line.Trim(); var field = LineParser.ParseToken(ref input, TokenType.Parameter, true).ToUpper(); return(new Action(() => { var name = ""; var comparer = Comparer.EqualTo; switch (field) { case "COOKIE": if (LineParser.Lookahead(ref input) == TokenType.Parameter) { comparer = (Comparer)LineParser.ParseEnum(ref input, "TYPE", typeof(Comparer)); } name = LineParser.ParseLiteral(ref input, "NAME"); for (var i = 0; i < data.COOKIES.Count; i++) { var curr = data.COOKIES.ToList()[i].Key; if (Condition.ReplaceAndVerify(curr, comparer, name, ls)) { data.COOKIES.Remove(curr); } } break; case "VAR": if (LineParser.Lookahead(ref input) == TokenType.Parameter) { comparer = (Comparer)LineParser.ParseEnum(ref input, "TYPE", typeof(Comparer)); } name = LineParser.ParseLiteral(ref input, "NAME"); BlockBase.GetVariables(data).RemoveAll(comparer, name, ls); break; case "GVAR": if (LineParser.Lookahead(ref input) == TokenType.Parameter) { comparer = (Comparer)LineParser.ParseEnum(ref input, "TYPE", typeof(Comparer)); } name = LineParser.ParseLiteral(ref input, "NAME"); try { ls.Globals.RemoveAll(comparer, name, ls); } catch { } break; default: throw new ArgumentException($"Invalid identifier {field}"); } data.Logger.Log($"DELETE command executed on field {field}", LogColors.White); })); }