Exemple #1
0
        /// <summary>
        /// Gets a command Action from a command line.
        /// </summary>
        internal static Action Parse(string line, LSGlobals ls)
        {
            // Trim the line
            var input = line.Trim();

            // Return an exception if the line is empty
            if (input == string.Empty)
            {
                throw new ArgumentNullException();
            }

            var label = LineParser.ParseToken(ref input, TokenType.Label, false);

            // Parse the identifier
            var identifier = "";

            try
            {
                identifier = LineParser.ParseToken(ref input, TokenType.Parameter, true);
            }
            catch
            {
                throw new ArgumentException("Missing identifier");
            }

            return((CommandName)Enum.Parse(typeof(CommandName), identifier, true) switch
            {
                CommandName.PRINT => new Action(() => ls.BotData.Logger.Log(BlockBase.ReplaceValues(input, ls), LogColors.White)),
                CommandName.SET => SetParser.Parse(input, ls),
                CommandName.DELETE => DeleteParser.Parse(input, ls),
                // TODO: Readd this
                // CommandName.MOUSEACTION => MouseActionParser.Parse(input, ls),
                _ => throw new ArgumentException($"Invalid identifier '{identifier}'"),
            });
Exemple #2
0
 /// <summary>
 /// Parses a literal value from a line.
 /// </summary>
 /// <param name="input">The reference to the line of code</param>
 /// <param name="label">Debug information about the expected literal</param>
 /// <param name="replace">Whether to perform variable replacement in the literal</param>
 /// <returns>The literal without the leading and trailing double quotes</returns>
 public static string ParseLiteral(ref string input, string label, bool replace = false, LSGlobals ls = null)
 {
     try
     {
         return(replace
             ? BlockBase.ReplaceValues(ParseToken(ref input, TokenType.Literal, true), ls)
             : ParseToken(ref input, TokenType.Literal, true));
     }
     catch
     {
         throw new ArgumentException($"Expected Literal value for '{label}'");
     }
 }
        /// <summary>
        /// Gets a command Action from a command line.
        /// </summary>
        /// <param name="line">The command line</param>
        /// <param name="data">The BotData needed for variable replacement</param>
        /// <returns>The Action that needs to be executed</returns>
        public static Action Parse(string line, BotData data)
        {
            // Trim the line
            var input = line.Trim();

            // Return an exception if the line is empty
            if (input == string.Empty)
            {
                throw new ArgumentNullException();
            }

            var label = LineParser.ParseToken(ref input, TokenType.Label, false);

            // Parse the identifier
            var identifier = "";

            try { identifier = LineParser.ParseToken(ref input, TokenType.Parameter, true); }
            catch { throw new ArgumentException("Missing identifier"); }

            switch ((CommandName)Enum.Parse(typeof(CommandName), identifier, true))
            {
            case CommandName.PRINT:
                return(new Action(() => data.Log(new LogEntry(BlockBase.ReplaceValues(input, data), Colors.White))));

            case CommandName.SET:
                return(SetParser.Parse(input, data));

            case CommandName.DELETE:
                return(DeleteParser.Parse(input, data));

            case CommandName.MOUSEACTION:
                return(MouseActionParser.Parse(input, data));

            case CommandName.STOP:
                return(new Action(() =>
                {
                    data.Worker?.CancelAsync();
                    data.Log(new LogEntry("Stoped!", Colors.OrangeRed));
                }));

            case CommandName.ForceStop:
                return(new Action(() =>
                {
                    data.Worker?.Abort();
                    data.Log(new LogEntry("Force Stoped!", Colors.OrangeRed));
                }));

            default:
                throw new ArgumentException($"Invalid identifier '{identifier}'");
            }
        }
 /// <summary>
 /// Parses a literal value from a line.
 /// </summary>
 /// <param name="input">The reference to the line of code</param>
 /// <param name="label">Debug information about the expected literal</param>
 /// <param name="replace">Whether to perform variable replacement in the literal</param>
 /// <param name="data">The BotData needed for variable replacement</param>
 /// <returns>The literal without the leading and trailing double quotes</returns>
 public static string ParseLiteral(ref string input, string label, bool replace = false, BotData data = null)
 {
     try {
         if (replace)
         {
             return(BlockBase.ReplaceValues(ParseToken(ref input, TokenType.Literal, true), data));
         }
         else
         {
             return(ParseToken(ref input, TokenType.Literal, true));
         }
     }
     catch { throw new ArgumentException($"Expected Literal value for '{label}'"); }
 }
Exemple #5
0
        /// <summary>
        /// Replaces the values and verifies if a condition is true or false.
        /// </summary>
        /// <param name="kcCond">The keycheck condition struct</param>
        /// <param name="data">The BotData used for variable replacement</param>
        /// <returns>Whether the comparison is verified or not.</returns>
        public static bool ReplaceAndVerify(KeycheckCondition kcCond, BotData data)
        {
            var style    = NumberStyles.Number | NumberStyles.AllowCurrencySymbol; // Needed when comparing values with a currency symbol
            var provider = new CultureInfo("en-US");
            var L        = BlockBase.ReplaceValuesRecursive(kcCond.Left, data);    // The left-hand term can accept recursive values like <LIST[*]>
            var r        = BlockBase.ReplaceValues(kcCond.Right, data);            // The right-hand term cannot

            switch (kcCond.Comparer)
            {
            case Comparer.EqualTo:
                return(L.Any(l => l == r));

            case Comparer.NotEqualTo:
                return(L.Any(l => l != r));

            case Comparer.GreaterThan:
                return(L.Any(l => decimal.Parse(l.Replace(',', '.'), style, provider) > decimal.Parse(r.Replace(',', '.'), style, provider)));

            case Comparer.GreaterOrEqual:
                return(L.Any(l => decimal.Parse(l.Replace(',', '.'), style, provider) >= decimal.Parse(r.Replace(',', '.'), style, provider)));

            case Comparer.LessThan:
                return(L.Any(l => decimal.Parse(l.Replace(',', '.'), style, provider) < decimal.Parse(r.Replace(',', '.'), style, provider)));

            case Comparer.LessThanOrEqual:
                return(L.Any(l => decimal.Parse(l.Replace(',', '.'), style, provider) <= decimal.Parse(r.Replace(',', '.'), style, provider)));

            case Comparer.Contains:
                return(L.Any(l => l.Contains(r)));

            case Comparer.DoesNotContain:
                return(L.Any(l => !l.Contains(r)));

            case Comparer.Exists:
                return(L.Any(l => l != kcCond.Left));    // Returns true if any replacement took place

            case Comparer.DoesNotExist:
                return(L.All(l => l == kcCond.Left));    // Returns true if no replacement took place

            case Comparer.MatchesRegex:
                return(L.Any(l => Regex.Match(l, r).Success));

            case Comparer.DoesNotMatchRegex:
                return(L.Any(l => !Regex.Match(l, r).Success));

            default:
                return(false);
            }
        }
Exemple #6
0
        /// <summary>
        /// Checks all the Keys in the KeyChain.
        /// </summary>
        /// <param name="data">The BotData used for variable replacement</param>
        /// <returns>Whether the KeyChain was triggered or not</returns>
        public bool CheckKeys(BotData data)
        {
            switch (Mode)
            {
            case KeychainMode.OR:
                foreach (var key in Keys)
                {
                    if (key.CheckKey(data))
                    {
                        data.Log(new LogEntry(string.Format("Found 'OR' Key {0} {1} {2}",
                                                            BlockBase.TruncatePretty(BlockBase.ReplaceValues(key.LeftTerm, data), 20),
                                                            key.Comparer.ToString(),
                                                            BlockBase.ReplaceValues(key.RightTerm, data)),
                                              Colors.White));
                        return(true);
                    }
                }
                return(false);

            case KeychainMode.AND:
                foreach (var key in Keys)
                {
                    if (!key.CheckKey(data))
                    {
                        return(false);
                    }
                    else
                    {
                        data.Log(new LogEntry(string.Format("Found 'AND' Key {0} {1} {2}",
                                                            BlockBase.TruncatePretty(BlockBase.ReplaceValues(key.LeftTerm, data), 20),
                                                            key.Comparer.ToString(),
                                                            BlockBase.ReplaceValues(key.RightTerm, data)),
                                              Colors.White));
                    }
                }
                return(true);
            }
            return(false);
        }
Exemple #7
0
        public override void Process(BotData data)
        {
            base.Process(data);
            string        email         = BlockBase.ReplaceValues(this.Email, data);
            string        password      = BlockBase.ReplaceValues(this.Password, data);
            MegaApiClient megaApiClient = new MegaApiClient();

            try
            {
                megaApiClient.Login(email, password);
                bool flag = !megaApiClient.IsLoggedIn;
                if (flag)
                {
                    throw new Exception();
                }
                IEnumerator <INode> enumerator = megaApiClient.GetNodes().GetEnumerator();
                List <string>       list       = new List <string>();
                int num = 0;
                while (enumerator.MoveNext() && num < this.MaxFilesCaptured)
                {
                    bool flag2 = enumerator.Current.Name != null;
                    if (flag2)
                    {
                        list.Add(enumerator.Current.Name);
                        num++;
                    }
                }
                IAccountInformation accountInformation = megaApiClient.GetAccountInformation();
                BlockBase.InsertVariable(data, this.IsCapture, accountInformation.UsedQuota.ToString(), "USEDQUOTA", "", "", false, false);
                BlockBase.InsertVariable(data, this.IsCapture, accountInformation.TotalQuota.ToString(), "TOTALQUOTA", "", "", false, false);
                BlockBase.InsertVariable(data, this.IsCapture, list, this.VariableName, "", "", false, false);
                data.Status = RuriLib.BotStatus.SUCCESS;
            }
            catch (Exception ex)
            {
                data.Log(ex.Message);
                data.Status = RuriLib.BotStatus.FAIL;
            }
        }
Exemple #8
0
        /// <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, string jsFilePath = "")
        {
            // Set the console output to stringwriter
            var sw = new StringWriter();

            Console.SetOut(sw);
            Console.SetError(sw);

            jsFilePath = BlockBase.ReplaceValues(jsFilePath, data);

            if (jsFilePath != string.Empty && File.Exists(jsFilePath))
            {
                script += File.ReadAllText(jsFilePath);
            }

            // Parse variables to get out
            List <string> outVarList = new List <string>();

            if (outputs != string.Empty)
            {
                try { outVarList = outputs.Split(',').Select(x => x.Trim()).ToList(); }
                catch { }
            }

            var start = DateTime.Now;

            try
            {
                switch (language)
                {
                case ScriptingLanguage.JavaScript:

                    var taskExecuteJs = Task.Run(() =>
                    {
                        object jsRetValue  = null;
                        bool disposeEngine = false;

                        JavascriptContext context = null;

                        if (disposeEngine = data.JsEngine == null)
                        {
                            context = new JavascriptContext();
                            JsEngine.SetParameter(context, data);
                        }
                        else
                        {
                            context = data.JsEngine.GetOrCreateEngine(data);
                        }

                        // Execute JS
                        try
                        {
                            jsRetValue = context.Run(script);
                        }
                        catch (JavascriptException ex)
                        {
                            throw new Exception($"Executing js error {ex.Message}\nline: {ex.Line}\nStart column:{ex.StartColumn}");
                        }

                        // Print results to log
                        data.Log(new LogEntry($"DEBUG LOG: {sw}", Colors.White));

                        // Get variables out
                        data.Log(new LogEntry($"Parsing {outVarList.Count} variables", Colors.White));
                        foreach (var name in outVarList)
                        {
                            try
                            {
                                //Add it to the variables and print info
                                var value   = context.GetParameter(name);
                                var isArray = value.GetType().IsArray || value is string[] || value.GetType().Name.Contains("Dictionary");
                                if (isArray)
                                {
                                    try { data.Variables.Set(new CVar(name, CVar.VarType.List, (List <string>)value)); } catch (Exception ex) { data.Log(new LogEntry("[SET VARS] ERROR: " + ex.Message, Colors.Yellow)); }
                                }
                                else
                                {
                                    data.Variables.Set(new CVar(name, CVar.VarType.Single, value.ToString()));
                                }

                                data.Log(new LogEntry($"SET VARIABLE {name} WITH VALUE {value}", Colors.Yellow));
                            }
                            catch { data.Log(new LogEntry($"COULD NOT FIND VARIABLE {name}", Colors.Tomato)); }
                        }
                        if (disposeEngine)
                        {
                            context.Dispose();
                        }

                        //Print other info
                        if (jsRetValue != null && !jsRetValue.GetType().Name.Contains("Dictionary"))
                        {
                            data.Log(new LogEntry($"Return value: {jsRetValue}", Colors.White));
                        }
                    });
                    taskExecuteJs.Wait();
                    taskExecuteJs.Dispose();

                    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 data.Variables.All)
                    {
                        try { scope.SetVariable(variable.Name, variable.Value); } catch { }
                    }

                    // Execute it
                    var result = code.Execute(scope);
                    //var result = pyengine.Execute(script, scope);

                    // Print the logs
                    data.Log(new LogEntry($"DEBUG LOG: {sw}", Colors.White));

                    // Get variables out
                    data.Log(new LogEntry($"Parsing {outVarList.Count} variables", Colors.White));
                    foreach (var name in outVarList)
                    {
                        try
                        {
                            // Add it to the variables and print info
                            var value = scope.GetVariable(name);
                            data.Variables.Set(new CVar(name, (value.GetType() == typeof(string[])) ? CVar.VarType.List : CVar.VarType.Single, value.ToString()));
                            data.Log(new LogEntry($"SET VARIABLE {name} WITH VALUE {value}", Colors.Yellow));
                        }
                        catch { data.Log(new LogEntry($"COULD NOT FIND VARIABLE {name}", Colors.Tomato)); }
                    }

                    // Print other info
                    if (result != null)
                    {
                        data.Log(new LogEntry($"Completion value: {result}", Colors.White));
                    }

                    break;

                default:
                    break;
                }

                data.Log(new LogEntry($"Execution completed in {(DateTime.Now - start).TotalSeconds} seconds", Colors.GreenYellow));
            }
            catch (Exception e)
            {
                data.Log(new LogEntry($"[ERROR] INFO: {e.Message}", Colors.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);
            }
        }
Exemple #9
0
        /// <summary>
        /// Gets the Action that needs to be executed.
        /// </summary>
        /// <param name="line">The data line to parse</param>
        /// <param name="data">The BotData needed for variable replacement</param>
        /// <returns>The Action to execute</returns>
        public static Action Parse(string line, BotData data)
        {
            var input = line.Trim();
            var field = LineParser.ParseToken(ref input, TokenType.Parameter, true).ToUpper();

            return(new Action(() =>
            {
                switch (field)
                {
                case "SOURCE":
                    data.ResponseSource = LineParser.ParseLiteral(ref input, "SOURCE", true, data);
                    break;

                case "STATUS":
                    data.Status = (BotStatus)LineParser.ParseEnum(ref input, "STATUS", typeof(BotStatus));
                    if (data.Status == BotStatus.CUSTOM)
                    {
                        data.CustomStatus = LineParser.ParseLiteral(ref input, "CUSTOM STATUS");
                    }
                    break;

                case "RESPONSECODE":
                    data.ResponseCode = LineParser.ParseInt(ref input, "RESPONSECODE").ToString();
                    break;

                case "COOKIE":
                    var name = LineParser.ParseLiteral(ref input, "NAME", true, data);
                    data.Cookies.Add(name, LineParser.ParseLiteral(ref input, "VALUE", true, data));
                    break;

                case "ADDRESS":
                    data.Address = LineParser.ParseLiteral(ref input, "ADDRESS", true, data);
                    break;

                case "USEPROXY":
                    var use = LineParser.ParseToken(ref input, TokenType.Parameter, true).ToUpper();
                    if (use == "TRUE")
                    {
                        data.UseProxies = true;
                    }
                    else if (use == "FALSE")
                    {
                        data.UseProxies = false;
                    }
                    break;

                case "PROXY":
                    var prox = LineParser.ParseLiteral(ref input, "PROXY", true, data);
                    data.Proxy = new CProxy(BlockBase.ReplaceValues(prox, data), data.Proxy == null ? ProxyType.Http : data.Proxy.Type);
                    break;

                case "PROXYTYPE":
                    data.Proxy.Type = (ProxyType)LineParser.ParseEnum(ref input, "PROXYTYPE", typeof(ProxyType));
                    break;

                case "DATA":
                    data.Data = new CData(LineParser.ParseLiteral(ref input, "DATA", true, data), new WordlistType());
                    break;

                case "VAR":
                    {
                        var cVar = new CVar(
                            LineParser.ParseLiteral(ref input, "NAME", true, data),
                            LineParser.ParseLiteral(ref input, "VALUE", true, data),
                            false
                            );
                        try
                        {
                            cVar.Hidden = LineParser.ParseToken(ref input, TokenType.Parameter, false)
                                          .ToBoolean();
                        }
                        catch { }
                        data.Variables.Set(cVar);
                    }
                    break;

                case "CAP":
                    {
                        var cVar = new CVar(
                            LineParser.ParseLiteral(ref input, "NAME", true, data),
                            LineParser.ParseLiteral(ref input, "VALUE", true, data),
                            true
                            );
                        try
                        {
                            cVar.Hidden = LineParser.ParseToken(ref input, TokenType.Parameter, false)
                                          .ToBoolean();
                        }
                        catch { }
                        data.Variables.Set(cVar);
                    }
                    break;

                case "GVAR":
                    try
                    {
                        var cVar = new CVar(
                            LineParser.ParseLiteral(ref input, "NAME", true, data),
                            LineParser.ParseLiteral(ref input, "VALUE", true, data),
                            false
                            );
                        try
                        {
                            cVar.Hidden = LineParser.ParseToken(ref input, TokenType.Parameter, false)
                                          .ToBoolean();
                        }
                        catch { }
                        data.GlobalVariables.Set(cVar);
                    }
                    catch { }
                    break;

                case "NEWGVAR":
                    try
                    {
                        var cVar = new CVar(
                            LineParser.ParseLiteral(ref input, "NAME", true, data),
                            LineParser.ParseLiteral(ref input, "VALUE", true, data),
                            false
                            );
                        try
                        {
                            cVar.Hidden = LineParser.ParseToken(ref input, TokenType.Parameter, false)
                                          .ToBoolean();
                        }
                        catch { }
                        data.GlobalVariables.SetNew(cVar);
                    }
                    catch { }
                    break;

                case "GCOOKIES":
                    data.GlobalCookies.Clear();
                    foreach (var cookie in data.Cookies)
                    {
                        data.GlobalCookies.Add(cookie.Key, cookie.Value);
                    }
                    break;

                default:
                    throw new ArgumentException($"Invalid identifier {field}");
                }

                data.Log(new LogEntry($"SET command executed on field {field}", Colors.White));
            }));
        }
        /// <summary>
        /// Gets the Action that needs to be executed.
        /// </summary>
        /// <param name="line">The data line to parse</param>
        /// <param name="data">The BotData needed for variable replacement</param>
        /// <returns>The Action to execute</returns>
        public static Action Parse(string line, BotData data)
        {
            // Trim the line
            var input = line.Trim();

            // Initialize the action chain
            Actions actions = null;

            try
            {
                actions = new Actions(data.Driver);
            }
            catch { throw new Exception("No Browser initialized!"); }

            // Build it
            var         offsetX = 0;
            var         offsetY = 0;
            var         point1X = 0;
            var         point1Y = 0;
            var         point2X = 0;
            var         point2Y = 0;
            var         key     = "";
            var         gravity = 1;
            var         wind    = 1;
            var         qty     = 0;
            IWebElement elem1   = null;
            IWebElement elem2   = null;
            Line        newLine = null;

            while (input != string.Empty)
            {
                var parsed = LineParser.ParseToken(ref input, TokenType.Parameter, true).ToUpper();
                switch (parsed)
                {
                case "SPAWN":
                    // Spawn a div in a certain position so you can hook to it later via id
                    if (LineParser.Lookahead(ref input) == TokenType.Integer)
                    {
                        point1X = LineParser.ParseInt(ref input, "X");
                        point1Y = LineParser.ParseInt(ref input, "Y");
                    }
                    else if (LineParser.Lookahead(ref input) == TokenType.Literal)
                    {
                        point1X = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "X"), data));
                        point1Y = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "Y"), data));
                    }
                    SpawnDiv(data.Driver, point1X, point1Y, LineParser.ParseLiteral(ref input, "ID"));
                    break;

                case "CLICK":
                    if (!LineParser.CheckIdentifier(ref input, "ELEMENT"))
                    {
                        actions.Click();
                    }
                    else
                    {
                        actions.Click(ParseElement(ref input, data));
                    }
                    break;

                case "CLICKANDHOLD":
                    if (!LineParser.CheckIdentifier(ref input, "ELEMENT"))
                    {
                        actions.ClickAndHold();
                    }
                    else
                    {
                        actions.ClickAndHold(ParseElement(ref input, data));
                    }
                    break;

                case "RIGHTCLICK":
                    if (!LineParser.CheckIdentifier(ref input, "ELEMENT"))
                    {
                        actions.ContextClick();
                    }
                    else
                    {
                        actions.ContextClick(ParseElement(ref input, data));
                    }
                    break;

                case "DOUBLECLICK":
                    if (!LineParser.CheckIdentifier(ref input, "ELEMENT"))
                    {
                        actions.DoubleClick();
                    }
                    else
                    {
                        actions.DoubleClick(ParseElement(ref input, data));
                    }
                    break;

                case "DRAGANDDROP":
                    elem1 = ParseElement(ref input, data);
                    LineParser.ParseToken(ref input, TokenType.Arrow, true);
                    elem2 = ParseElement(ref input, data);
                    actions.DragAndDrop(elem1, elem2);
                    break;

                case "DRAGANDDROPWITHOFFSET":
                    if (LineParser.Lookahead(ref input) == TokenType.Integer)
                    {
                        offsetX = LineParser.ParseInt(ref input, "OFFSET X");
                        offsetY = LineParser.ParseInt(ref input, "OFFSET Y");
                    }
                    else if (LineParser.Lookahead(ref input) == TokenType.Literal)
                    {
                        offsetX = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "OFFSET X"), data));
                        offsetY = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "OFFSET Y"), data));
                    }
                    actions.DragAndDropToOffset(ParseElement(ref input, data), offsetX, offsetY);
                    break;

                case "KEYDOWN":
                    key = LineParser.ParseLiteral(ref input, "KEY", true, data);
                    if (!LineParser.CheckIdentifier(ref input, "ELEMENT"))
                    {
                        actions.KeyDown(key);
                    }
                    else
                    {
                        actions.KeyDown(ParseElement(ref input, data), key);
                    }
                    break;

                case "KEYUP":
                    key = LineParser.ParseLiteral(ref input, "KEY", true, data);
                    if (!LineParser.CheckIdentifier(ref input, "ELEMENT"))
                    {
                        actions.KeyUp(key);
                    }
                    else
                    {
                        actions.KeyUp(ParseElement(ref input, data), key);
                    }
                    break;

                case "MOVEBY":
                    if (LineParser.Lookahead(ref input) == TokenType.Integer)
                    {
                        offsetX = LineParser.ParseInt(ref input, "OFFSET X");
                        offsetY = LineParser.ParseInt(ref input, "OFFSET Y");
                    }
                    else if (LineParser.Lookahead(ref input) == TokenType.Literal)
                    {
                        offsetX = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "OFFSET X"), data));
                        offsetY = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "OFFSET Y"), data));
                    }
                    actions.MoveByOffset(offsetX, offsetY);
                    break;

                case "MOVETO":
                    actions.MoveToElement(ParseElement(ref input, data));
                    break;

                case "RELEASE":
                    if (!LineParser.CheckIdentifier(ref input, "ELEMENT"))
                    {
                        actions.Release();
                    }
                    else
                    {
                        actions.Release(ParseElement(ref input, data));
                    }
                    break;

                case "SENDKEYS":
                    key = LineParser.ParseLiteral(ref input, "KEY", true, data);
                    if (!LineParser.CheckIdentifier(ref input, "ELEMENT"))
                    {
                        actions.SendKeys(key);
                    }
                    else
                    {
                        actions.SendKeys(ParseElement(ref input, data), key);
                    }
                    break;

                case "DRAWPOINTS":
                    offsetX = LineParser.ParseInt(ref input, "MAX WIDTH");
                    offsetY = LineParser.ParseInt(ref input, "MAX HEIGHT");
                    var    amount    = LineParser.ParseInt(ref input, "AMOUNT");
                    Random rand      = new Random();
                    var    previousx = 0;
                    var    previousy = 0;
                    // Move to the first point
                    actions.MoveToElement(data.Driver.FindElementByTagName("body"), point1X, point1Y);
                    List <Point> points = new List <Point>();
                    for (int i = 0; i < amount; i++)
                    {
                        var x = rand.Next(0, offsetX);
                        var y = rand.Next(0, offsetY);
                        actions.MoveByOffset(x - previousx, y - previousy);
                        previousx = x;
                        previousy = y;
                        points.Add(new Point(x, y));
                    }
                    if (data.GlobalSettings.Selenium.DrawMouseMovement)
                    {
                        DrawRedDots(data.Driver, points.ToArray(), 5);
                    }
                    break;

                case "DRAWLINE":
                    // DRAWLINE 10 10 -> 20 20
                    if (LineParser.Lookahead(ref input) == TokenType.Integer)
                    {
                        point1X = LineParser.ParseInt(ref input, "X1");
                        point1Y = LineParser.ParseInt(ref input, "Y1");
                        LineParser.ParseToken(ref input, TokenType.Arrow, true);
                        point2X = LineParser.ParseInt(ref input, "X2");
                        point2Y = LineParser.ParseInt(ref input, "Y2");
                    }
                    // DRAWLINE "10" "20" -> "<MY_X>" "<MY_Y>"
                    else if (LineParser.Lookahead(ref input) == TokenType.Literal)
                    {
                        point1X = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "X1"), data));
                        point1Y = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "Y1"), data));
                        LineParser.ParseToken(ref input, TokenType.Arrow, true);
                        point2X = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "X2"), data));
                        point2Y = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "Y2"), data));
                    }
                    else
                    {
                        elem1   = ParseElement(ref input, data);
                        point1X = elem1.Location.X;
                        point1Y = elem1.Location.Y;
                        LineParser.ParseToken(ref input, TokenType.Arrow, true);
                        elem2   = ParseElement(ref input, data);
                        point2X = elem2.Location.X;
                        point2Y = elem2.Location.Y;
                    }
                    LineParser.EnsureIdentifier(ref input, ":");
                    qty = LineParser.ParseInt(ref input, "QUANTITY");
                    // Move to the first point
                    actions.MoveToElement(data.Driver.FindElementByTagName("body"), point1X, point1Y);
                    newLine = new Line(new Point(point1X, point1Y), new Point(point2X, point2Y));
                    if (data.GlobalSettings.Selenium.DrawMouseMovement)
                    {
                        DrawRedDots(data.Driver, newLine.getPoints(qty), 5);
                    }
                    foreach (var p in newLine.getOffsets(qty))
                    {
                        actions.MoveByOffset(p.X, p.Y);
                    }
                    break;

                case "DRAWLINEHUMAN":
                    // DRAWLINEHUMAN 10 10 -> 20 20
                    if (LineParser.Lookahead(ref input) == TokenType.Integer)
                    {
                        point1X = LineParser.ParseInt(ref input, "X1");
                        point1Y = LineParser.ParseInt(ref input, "Y1");
                        LineParser.ParseToken(ref input, TokenType.Arrow, true);
                        point2X = LineParser.ParseInt(ref input, "X2");
                        point2Y = LineParser.ParseInt(ref input, "Y2");
                    }
                    // DRAWLINEHUMAN "10" "20" -> "<MY_X>" "<MY_Y>"
                    else if (LineParser.Lookahead(ref input) == TokenType.Literal)
                    {
                        point1X = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "X1"), data));
                        point1Y = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "Y1"), data));
                        LineParser.ParseToken(ref input, TokenType.Arrow, true);
                        point2X = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "X2"), data));
                        point2Y = int.Parse(BlockBase.ReplaceValues(LineParser.ParseLiteral(ref input, "Y2"), data));
                    }
                    else
                    {
                        elem1   = ParseElement(ref input, data);
                        point1X = elem1.Location.X;
                        point1Y = elem1.Location.Y;
                        LineParser.ParseToken(ref input, TokenType.Arrow, true);
                        elem2   = ParseElement(ref input, data);
                        point2X = elem2.Location.X;
                        point2Y = elem2.Location.Y;
                    }
                    LineParser.EnsureIdentifier(ref input, ":");
                    qty = LineParser.ParseInt(ref input, "QUANTITY");
                    if (LineParser.Lookahead(ref input) == TokenType.Integer)
                    {
                        gravity = LineParser.ParseInt(ref input, "GRAVITY");
                        wind    = LineParser.ParseInt(ref input, "WIND");
                    }
                    // Move to the first point
                    actions.MoveToElement(data.Driver.FindElementByTagName("body"), point1X, point1Y);
                    newLine = new Line(new Point(point1X, point1Y), new Point(point2X, point2Y));
                    var array    = newLine.HumanWindMouse(point1X, point1Y, point2X, point2Y, gravity, wind, 1);
                    var shrinked = ShrinkArray(array, qty);
                    if (data.GlobalSettings.Selenium.DrawMouseMovement)
                    {
                        DrawRedDots(data.Driver, shrinked, 5);
                    }
                    foreach (var p in GetOffsets(shrinked))
                    {
                        actions.MoveByOffset(p.X, p.Y);
                    }
                    break;
                }
            }

            return(new Action(() =>
            {
                actions.Build();
                actions.Perform();
                data.Log(new LogEntry("Executed Mouse Actions", Colors.White));
            }));
        }