Beispiel #1
0
        /// <summary>
        /// Replaces variables recursively, expanding lists or dictionaries with jolly indices.
        /// </summary>
        public static List <string> ReplaceValuesRecursive(string original, LSGlobals ls)
        {
            var data      = ls.BotData;
            var globals   = ls.Globals;
            var toReplace = new List <string>();

            // Regex parse the syntax <LIST[*]>
            var matches   = Regex.Matches(original, @"<([^\[]*)\[\*\]>");
            var variables = new List <ListOfStringsVariable>();

            foreach (Match m in matches)
            {
                var name = m.Groups[1].Value;

                // Retrieve the variable
                var variable = GetVariables(data).Get(name);

                // If it's null, try to get it from the global variables
                if (variable == null)
                {
                    variable = globals.Get(name);

                    // If still null, there's nothing to replace, skip it
                    if (variable == null)
                    {
                        continue;
                    }
                }

                // Make sure it's a List of strings and add it to the list
                if (variable is ListOfStringsVariable list)
                {
                    variables.Add(list);
                }
            }

            // If there's no corresponding variable, just readd the input string and proceed with normal replacement
            if (variables.Count > 0)
            {
                // Example: we have 3 lists of sizes 3, 7 and 5. We need to take 7
                var max = variables.Max(v => v.AsListOfStrings().Count);

                for (var i = 0; i < max; i++)
                {
                    var replaced = original;

                    foreach (var variable in variables)
                    {
                        var list = variable.AsListOfStrings();
                        replaced = list.Count > i?replaced.Replace($"<{variable.Name}[*]>", list[i]) : replaced.Replace($"<{variable.Name}[*]>", "NULL");
                    }

                    toReplace.Add(replaced);
                }
                goto END;
            }

            // Regex parse the syntax <DICT(*)> (wildcard key -> returns list of all values)
            var match = Regex.Match(original, @"<([^\(]*)\(\*\)>");

            if (match.Success)
            {
                var full = match.Groups[0].Value;
                var name = match.Groups[1].Value;

                // Retrieve the dictionary
                var dict = GetVariables(data).Get <DictionaryOfStringsVariable>(name);

                if (dict == null)
                {
                    dict = globals.Get <DictionaryOfStringsVariable>(name);
                }

                // If there's no corresponding variable, just readd the input string and proceed with normal replacement
                if (dict == null)
                {
                    toReplace.Add(original);
                }
                else
                {
                    foreach (var item in dict.AsDictionaryOfStrings())
                    {
                        toReplace.Add(original.Replace(full, item.Value));
                    }
                }
                goto END;
            }

            // Regex parse the syntax <DICT{*}> (wildcard value -> returns list of all keys)
            match = Regex.Match(original, @"<([^\{]*)\{\*\}>");

            if (match.Success)
            {
                var full = match.Groups[0].Value;
                var name = match.Groups[1].Value;

                // Retrieve the dictionary
                var dict = GetVariables(data).Get <DictionaryOfStringsVariable>(name);

                if (dict == null)
                {
                    if (name == "COOKIES")
                    {
                        dict = new DictionaryOfStringsVariable(data.COOKIES)
                        {
                            Name = name
                        };
                    }
                    else if (name == "HEADERS")
                    {
                        dict = new DictionaryOfStringsVariable(data.HEADERS)
                        {
                            Name = name
                        };
                    }
                    else
                    {
                        dict = globals.Get <DictionaryOfStringsVariable>(name);
                    }
                }

                // If there's no corresponding variable, just readd the input string and proceed with normal replacement
                if (dict == null)
                {
                    toReplace.Add(original);
                }
                else
                {
                    foreach (var item in dict.AsDictionaryOfStrings())
                    {
                        toReplace.Add(original.Replace(full, item.Key));
                    }
                }
                goto END;
            }

            // If no other match was a success, it means there's no recursive value and we simply add the input to the list
            toReplace.Add(original);

END:
            // Now for each item in the list, do the normal replacement and return the replaced list of strings
            return(toReplace.Select(i => (string)ReplaceValues(i, ls)).ToList());
        }
Beispiel #2
0
        /// <inheritdoc />
        public override async Task Process(LSGlobals ls)
        {
            var data = ls.BotData;
            await base.Process(ls);

            var      replacedInput = ReplaceValues(InputString, ls);
            var      variablesList = GetVariables(data);
            Variable variableToAdd = null;
            var      logColor      = IsCapture ? LogColors.Tomato : LogColors.Yellow;

            switch (Group)
            {
            case UtilityGroup.List:
                var list  = variablesList.Get <ListOfStringsVariable>(ListName)?.AsListOfStrings();
                var list2 = variablesList.Get <ListOfStringsVariable>(SecondListName)?.AsListOfStrings();
                var item  = ReplaceValues(ListItem, ls);
                var index = int.Parse(ReplaceValues(ListIndex, ls));

                switch (ListAction)
                {
                case ListAction.Create:
                    variableToAdd = new ListOfStringsVariable(new List <string>());
                    break;

                case ListAction.Length:
                    variableToAdd = new StringVariable(list.Count.ToString());
                    break;

                case ListAction.Join:
                    variableToAdd = new StringVariable(string.Join(Separator, list));
                    break;

                case ListAction.Sort:
                    var sorted = list.Select(e => e).ToList();         // Clone the list so we don't edit the original one

                    if (Numeric)
                    {
                        var nums = sorted.Select(e => double.Parse(e, CultureInfo.InvariantCulture)).ToList();
                        nums.Sort();
                        sorted = nums.Select(e => e.ToString()).ToList();
                    }
                    else
                    {
                        sorted.Sort();
                    }

                    if (!Ascending)
                    {
                        sorted.Reverse();
                    }

                    variableToAdd = new ListOfStringsVariable(sorted);
                    break;

                case ListAction.Concat:
                    variableToAdd = new ListOfStringsVariable(list.Concat(list2).ToList());
                    break;

                case ListAction.Zip:
                    variableToAdd = new ListOfStringsVariable(list.Zip(list2, (a, b) => a + b).ToList());
                    break;

                case ListAction.Map:
                    variableToAdd = new DictionaryOfStringsVariable(list.Zip(list2, (k, v) => new { k, v }).ToDictionary(x => x.k, x => x.v));
                    break;

                case ListAction.Add:
                    // Handle negative indices
                    index = index switch
                    {
                        0 => 0,
                        < 0 => index + list.Count,
                        _ => index
                    };
                    list.Insert(index, item);
                    break;

                case ListAction.Remove:
                    // Handle negative indices
                    index = index switch
                    {
                        0 => 0,
                        < 0 => index + list.Count,
                        _ => index
                    };
                    list.RemoveAt(index);
                    break;

                case ListAction.RemoveValues:
                    variableToAdd = new ListOfStringsVariable(list.Where(l => !Condition.Verify(new KeycheckCondition
                    {
                        Left     = ReplaceValues(l, ls),
                        Comparer = ListElementComparer,
                        Right    = ListComparisonTerm
                    })).ToList());
                    break;

                case ListAction.RemoveDuplicates:
                    variableToAdd = new ListOfStringsVariable(list.Distinct().ToList());
                    break;

                case ListAction.Random:
                    variableToAdd = new StringVariable(list[data.Random.Next(list.Count)]);
                    break;

                case ListAction.Shuffle:
                    // This makes a copy of the original list
                    var listCopy = new List <string>(list);
                    listCopy.Shuffle(data.Random);
                    variableToAdd = new ListOfStringsVariable(listCopy);
                    break;

                default:
                    break;
                }
                data.Logger.Log($"Executed action {ListAction} on list {ListName}", logColor);
                break;

            case UtilityGroup.Variable:
                string single = variablesList.Get <StringVariable>(VarName).AsString();
                switch (VarAction)
                {
                case VarAction.Split:
                    variableToAdd = new ListOfStringsVariable(single.Split(new string[]
                                                                           { ReplaceValues(SplitSeparator, ls) }, StringSplitOptions.None).ToList());
                    break;
                }
                data.Logger.Log($"Executed action {VarAction} on variable {VarName}", logColor);
                break;

            case UtilityGroup.Conversion:
                var conversionInputBytes = replacedInput.ConvertFrom(ConversionFrom);
                var conversionResult     = conversionInputBytes.ConvertTo(ConversionTo);
                variableToAdd = new StringVariable(conversionResult);
                data.Logger.Log($"Executed conversion {ConversionFrom} to {ConversionTo} on input {replacedInput} with outcome {conversionResult}", logColor);
                break;

            case UtilityGroup.File:
                var file = ReplaceValues(FilePath, ls);
                FileUtils.ThrowIfNotInCWD(file);

                switch (FileAction)
                {
                case FileAction.Exists:
                    variableToAdd = new StringVariable(File.Exists(file).ToString());
                    break;

                case FileAction.Read:
                    lock (FileLocker.GetHandle(file))
                        variableToAdd = new StringVariable(File.ReadAllText(file));
                    break;

                case FileAction.ReadLines:
                    lock (FileLocker.GetHandle(file))
                        variableToAdd = new ListOfStringsVariable(File.ReadAllLines(file).ToList());
                    break;

                case FileAction.Write:
                    FileUtils.CreatePath(file);
                    lock (FileLocker.GetHandle(file))
                        File.WriteAllText(file, replacedInput.Unescape());
                    break;

                case FileAction.WriteLines:
                    FileUtils.CreatePath(file);
                    lock (FileLocker.GetHandle(file))
                        File.WriteAllLines(file, ReplaceValuesRecursive(InputString, ls).Select(i => i.Unescape()));
                    break;

                case FileAction.Append:
                    FileUtils.CreatePath(file);
                    lock (FileLocker.GetHandle(file))
                        File.AppendAllText(file, replacedInput.Unescape());
                    break;

                case FileAction.AppendLines:
                    FileUtils.CreatePath(file);
                    lock (FileLocker.GetHandle(file))
                        File.AppendAllLines(file, ReplaceValuesRecursive(InputString, ls).Select(i => i.Unescape()));
                    break;

                case FileAction.Copy:
                    var fileCopyLocation = ReplaceValues(InputString, ls);
                    FileUtils.ThrowIfNotInCWD(fileCopyLocation);
                    FileUtils.CreatePath(fileCopyLocation);
                    lock (FileLocker.GetHandle(file))
                        lock (FileLocker.GetHandle(fileCopyLocation))
                            File.Copy(file, fileCopyLocation);
                    break;

                case FileAction.Move:
                    var fileMoveLocation = ReplaceValues(InputString, ls);
                    FileUtils.ThrowIfNotInCWD(fileMoveLocation);
                    FileUtils.CreatePath(fileMoveLocation);
                    lock (FileLocker.GetHandle(file))
                        lock (FileLocker.GetHandle(fileMoveLocation))
                            File.Move(file, fileMoveLocation);
                    break;

                case FileAction.Delete:
                    // No deletion if the file is in use (DB/OpenBullet.db cannot be deleted but instead DB/OpenBullet-BackupCopy.db)
                    // If another process is just reading the file it will be deleted
                    lock (FileLocker.GetHandle(file))
                        File.Delete(file);
                    break;
                }

                data.Logger.Log($"Executed action {FileAction} on file {file}", logColor);
                break;

            case UtilityGroup.Folder:
                var folder = ReplaceValues(FolderPath, ls);
                FileUtils.ThrowIfNotInCWD(folder);

                switch (FolderAction)
                {
                case FolderAction.Exists:
                    variableToAdd = new StringVariable(Directory.Exists(folder).ToString());
                    break;

                case FolderAction.Create:
                    variableToAdd = new StringVariable(Directory.CreateDirectory(folder).ToString());
                    break;

                case FolderAction.Delete:
                    Directory.Delete(folder, true);
                    break;
                }

                data.Logger.Log($"Executed action {FolderAction} on folder {folder}", logColor);
                break;

            default:
                break;
            }

            if (variableToAdd is not null)
            {
                variableToAdd.Name             = VariableName;
                variableToAdd.MarkedForCapture = IsCapture;
                variablesList.Set(variableToAdd);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Replaces variables in a given input string.
        /// </summary>
        public static string ReplaceValues(string original, LSGlobals ls)
        {
            if (original == null)
            {
                return(string.Empty);
            }

            var data    = ls.BotData;
            var globals = ls.Globals;

            if (!original.Contains("<") && !original.Contains(">"))
            {
                return(original);
            }

            var previous = "";
            var output   = original;

            do
            {
                previous = output;

                // Replace all the fixed quantities
                output = output.Replace("<INPUT>", data.Line.Data);
                output = output.Replace("<STATUS>", data.STATUS);
                output = output.Replace("<SOURCE>", data.SOURCE);
                output = output.Replace("<COOKIES>", data.COOKIES.AsString());
                output = output.Replace("<HEADERS>", data.HEADERS.AsString());
                output = output.Replace("<RESPONSECODE>", data.RESPONSECODE.AsString());
                output = output.Replace("<ADDRESS>", data.ADDRESS);
                output = output.Replace("<RETRIES>", data.Line.Retries.ToString());

                var lastCaptchaInfo = data.TryGetObject <CaptchaInfo>("lastCaptchaInfo");
                if (lastCaptchaInfo is not null)
                {
                    output = output.Replace("<CAPTCHAID>", lastCaptchaInfo.Id.ToString());
                }

                // TODO: Readd this
                // output = output.Replace("<BOTNUM>", data.BotNumber.ToString());

                if (data.Proxy != null)
                {
                    output = output.Replace("<PROXY>", data.Proxy.ToString());
                }

                // Get all the inner (max. 1 level of nesting) variables
                var matches = Regex.Matches(output, @"<([^<>]*)>");

                foreach (Match match in matches)
                {
                    var full = match.Groups[0].Value;
                    var m    = match.Groups[1].Value;

                    // Parse the variable name
                    var name = Regex.Match(m, @"^[^\[\{\(]*").Value;

                    // Try to get the variable (first local, then global, then if none was found go to the next iteration)
                    // We don't throw an error here because it could be some HTML or XML code e.g. <br> that triggers this, and we dont' want to spam the user with unneeded errors
                    var v = GetVariables(data).Get(name);

                    if (v == null)
                    {
                        if (name == "COOKIES")
                        {
                            v = new DictionaryOfStringsVariable(data.COOKIES)
                            {
                                Name = name
                            };
                        }
                        else if (name == "HEADERS")
                        {
                            v = new DictionaryOfStringsVariable(data.HEADERS)
                            {
                                Name = name
                            };
                        }
                        else
                        {
                            v = globals.Get(name);
                        }
                    }

                    if (v == null)
                    {
                        continue;
                    }

                    // Parse the arguments
                    var args = m.Replace(name, "");

                    switch (v)
                    {
                    case StringVariable:
                        output = output.Replace(full, v.AsString());
                        break;

                    case ListOfStringsVariable:

                        // If it's just the list name, replace it with its string representation
                        if (string.IsNullOrEmpty(args))
                        {
                            output = output.Replace(full, v.AsString());
                            break;
                        }

                        var index = 0;
                        int.TryParse(ParseArguments(args, '[', ']')[0], out index);
                        var item = GetListItem(v.AsListOfStrings(), index);     // Can return null

                        if (item != null)
                        {
                            output = output.Replace(full, item);
                        }
                        break;

                    case DictionaryOfStringsVariable:

                        var dict = v.AsDictionaryOfStrings();

                        if (args.Contains("(") && args.Contains(")"))
                        {
                            var key = ParseArguments(args, '(', ')')[0];

                            if (dict.ContainsKey(key))
                            {
                                output = output.Replace(full, dict[key]);
                            }
                        }
                        else if (args.Contains("{") && args.Contains("}"))
                        {
                            var value = ParseArguments(args, '{', '}')[0];

                            if (dict.ContainsValue(value))
                            {
                                output = output.Replace(full, dict.First(kvp => kvp.Value == value).Key);
                            }
                        }
                        else     // If it's just the dictionary name, replace it with its string representation
                        {
                            output = output.Replace(full, v.AsString());
                            break;
                        }
                        break;
                    }
                }
            }while (original.Contains("<") && original.Contains(">") && output != previous);

            return(output);
        }