First commit - OpenBullet 1.0.0

This commit is contained in:
ruri
2019-03-31 12:18:26 +02:00
parent 1a0775b648
commit 422079782d
296 changed files with 31668 additions and 0 deletions
+223
View File
@@ -0,0 +1,223 @@
using Extreme.Net;
using OpenQA.Selenium.Remote;
using RuriLib.Models;
using RuriLib.ViewModels;
using System;
using System.Collections.Generic;
using System.Net.Security;
using System.Net.Sockets;
using System.Windows.Media;
namespace RuriLib
{
/// <summary>
/// The status of the Bot. While the status is NONE or SUCCESS the Bot keeps checking the script until the end, otherwise it stops.
/// </summary>
public enum BotStatus
{
/// <summary>The initial status of the bot. If a bot ends its execution with this stauts, the data line will be registered as ToCheck.</summary>
NONE,
/// <summary>Something wrong happened while processing a block.</summary>
ERROR,
/// <summary>The data line will be registered as a Hit.</summary>
SUCCESS,
/// <summary>The data line will be registered as a fail.</summary>
FAIL,
/// <summary>The data line will be retried and the proxy will be banned.</summary>
BAN,
/// <summary>The data line will be retried.</summary>
RETRY,
/// <summary>The data line will be registered as a Custom.</summary>
CUSTOM
}
/// <summary>
/// Class that holds all the variables needed for checking a single data line.
/// </summary>
public class BotData
{
/// <summary>A random number generator that methods can refer to, in order to avoid the generation of the same random number if executed in rapid succession.</summary>
public Random rand = new Random();
/// <summary>The Status of the Bot.</summary>
public BotStatus Status { get; set; }
/// <summary>The Custom Status name in case the Status was set to Custom.</summary>
public string CustomStatus = "CUSTOM";
/// <summary>The Status of the Bot as a string.</summary>
public string StatusString { get { return Status == BotStatus.CUSTOM ? CustomStatus : Status.ToString(); } }
/// <summary>The id of the current Bot.</summary>
public int BotNumber { get; set; }
/// <summary>The captcha service currently being used.</summary>
public CaptchaServices.CaptchaService CaptchaService { get; set; }
/// <summary>The selenium webdriver currently being used.</summary>
public RemoteWebDriver Driver { get; set; }
/// <summary>Whether the browser is open or not.</summary>
public bool BrowserOpen { get; set; }
/// <summary>The TCP Client used for TCP blocks.</summary>
public TcpClient TCPClient { get; set; }
/// <summary>The NET Stream used for TCP blocks with unencrypted connection.</summary>
public NetworkStream NETStream { get; set; }
/// <summary>The SSL Stream used for TCP blocks with encrypted connection.</summary>
public SslStream SSLStream { get; set; }
/// <summary>Whether to use SSL for the current TCPClient.</summary>
public bool TCPSSL { get; set; } = true;
/// <summary>The wrapped data line that needs to be checked.</summary>
public CData Data { get; set; }
/// <summary>The proxy currently being used (null if none).</summary>
public CProxy Proxy { get; set; }
/// <summary>Whether we should use proxies or not.</summary>
public bool UseProxies { get; set; }
/// <summary>The Global RuriLib settings valid for any Config.</summary>
public RLSettingsViewModel GlobalSettings { get; set; }
/// <summary>The settings for the current Config.</summary>
public ConfigSettings ConfigSettings { get; set; }
/// <summary>The remaining balance on the captcha service account.</summary>
public double Balance { get; set; }
/// <summary>The paths of the Screenshots saved by selenium.</summary>
public List<string> Screenshots { get; set; }
#region Response
/// <summary>The return Address of the HttpResponse.</summary>
public string Address {
get { return Variables.Get("ADDRESS").Value; }
set { Variables.SetHidden("ADDRESS", value); }
}
/// <summary>The HTTP code of the HttpResponse.</summary>
public string ResponseCode
{
get { return Variables.Get("RESPONSECODE").Value; }
set { Variables.SetHidden("RESPONSECODE", value); }
}
/// <summary>The dictionary of headers of the HttpResponse.</summary>
public Dictionary<string, string> ResponseHeaders
{
get { return Variables.Get("HEADERS").Value; }
set { Variables.SetHidden("HEADERS", value); }
}
/// <summary>The dictionary of cookies of the HttpResponse.</summary>
public Dictionary<string, string> Cookies
{
get { return Variables.Get("COOKIES").Value; }
set { Variables.SetHidden("COOKIES", value); }
}
/// <summary>The source of the HttpResponse.</summary>
public string ResponseSource
{
get { return Variables.Get("SOURCE").Value; }
set { Variables.SetHidden("SOURCE", value); }
}
#endregion
// Variables and capture
/// <summary>The local variables of the Bot.</summary>
public VariableList Variables { get; set; }
/// <summary>The global variables shared between all the Bots. They can be accessed or set by any bot.</summary>
public VariableList GlobalVariables { get; set; }
/// <summary>The global cookies shared between all the Bots. They are set in the local cookie jar at the start of the check.</summary>
public Dictionary<string, string> GlobalCookies { get; set; }
// Log
/// <summary>The detailed log of the last block that was run.</summary>
public List<LogEntry> LogBuffer { get; set; }
/// <summary>Whether this object is being used for a Debugger or for the Runner.</summary>
public bool IsDebug { get; set; }
/// <summary>
/// Creates a BotData object given some parameters.
/// </summary>
/// <param name="globalSettings">The global RuriLib settings</param>
/// <param name="configSettings">The settings for the current Config</param>
/// <param name="data">The wrapped data line to check</param>
/// <param name="proxy">The proxy to use (set to null if none)</param>
/// <param name="useProxies">Whether to use the proxy for requests</param>
/// <param name="botNumber">The number of the bot that is creating this object</param>
/// <param name="isDebug">Whether this object is created from a Debugger or from a Runner</param>
public BotData(RLSettingsViewModel globalSettings, ConfigSettings configSettings, CData data, CProxy proxy, bool useProxies, int botNumber = 0, bool isDebug = true)
{
Data = data;
Proxy = proxy;
UseProxies = useProxies;
Status = BotStatus.NONE;
BotNumber = BotNumber;
GlobalSettings = globalSettings;
ConfigSettings = configSettings;
Balance = 0;
Screenshots = new List<string>();
Variables = new VariableList();
// Populate the Variables list with hidden variables
Address = "";
ResponseCode = "0";
ResponseSource = "";
Cookies = new Dictionary<string, string>();
ResponseHeaders = new Dictionary<string, string>();
try { foreach (var v in Data.GetVariables()) Variables.Set(v); } catch { }
GlobalVariables = new VariableList();
GlobalCookies = new CookieDictionary();
LogBuffer = new List<LogEntry>();
Driver = null;
BrowserOpen = false;
IsDebug = isDebug;
BotNumber = botNumber;
}
/// <summary>
/// Adds a new LogEntry to the LogBuffer.
/// </summary>
/// <param name="entry">The LogEntry to add</param>
public void Log(LogEntry entry)
{
if (GlobalSettings.General.EnableBotLog || IsDebug)
LogBuffer.Add(entry);
}
/// <summary>
/// Adds multiple new LogEntry objects to the LogBuffer.
/// </summary>
/// <param name="list">The list of log entries to add</param>
public void LogRange(List<LogEntry> list)
{
if (GlobalSettings.General.EnableBotLog || IsDebug)
LogBuffer.AddRange(list);
}
/// <summary>
/// Logs an empty line to the LogBuffer.
/// </summary>
public void LogNewLine()
{
LogBuffer.Add(new LogEntry("", Colors.White));
}
}
}
+123
View File
@@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace RuriLib.Models
{
/// <summary>
/// Represents a data line that needs to be checked.
/// </summary>
public class CData
{
/// <summary>The actual content of the line.</summary>
public string Data { get; set; }
/// <summary>The WordlistType of the Wordlist the line belongs to.</summary>
public WordlistType Type { get; set; }
/// <summary>Whether the data line respects the regex verification.</summary>
public bool IsValid
{
get
{
if (Type.Verify) return Regex.Match(Data, Type.Regex).Success;
else return true;
}
}
/// <summary>
/// Creates a CData object given a data line and the WordlistType.
/// </summary>
/// <param name="data">The data line</param>
/// <param name="type">The WordlistType of the Wordlist the data line belongs to</param>
public CData(string data, WordlistType type)
{
Data = data;
Type = type;
}
/// <summary>
/// Gets all the variables that need to be set after slicing the data line.
/// </summary>
/// <returns>The variables that need to be set inside the Bot's VariableList</returns>
public List<CVar> GetVariables()
{
return Data
.Split(new string[] { Type.Separator }, StringSplitOptions.None)
.Zip(Type.Slices, (k, v) => new { k, v })
.Select(x => new CVar(x.v, x.k, false, true))
.ToList();
}
/// <summary>
/// Checks if the data line respects all the data rules present in a Config.
/// </summary>
/// <param name="rules">The list of rules of the Config</param>
/// <returns>Whether the data line respects the rules</returns>
public bool RespectsRules(List<DataRule> rules)
{
var valid = true;
var variables = GetVariables();
foreach(var rule in rules)
{
try
{
var slice = (string)variables.FirstOrDefault(v => v.Name == rule.SliceName).Value;
switch (rule.RuleType)
{
case RuleType.MinLength:
valid = slice.Length >= int.Parse(rule.RuleString);
break;
case RuleType.MaxLength:
valid = slice.Length <= int.Parse(rule.RuleString);
break;
case RuleType.MustContain:
valid = CheckContains(slice, rule.RuleString);
break;
case RuleType.MustNotContain:
valid = !CheckContains(slice, rule.RuleString);
break;
}
}
catch { }
}
return valid;
}
/// <summary>
/// Checks if a data line contains certain characters.
/// </summary>
/// <param name="input">The data line</param>
/// <param name="what">The characters to search. Defaults are Lowercase, Uppercase, Digit, Symbol. Custom character sets can be created by concatenating the characters in a single string (e.g. ABCDEF)</param>
/// <returns></returns>
private static bool CheckContains(string input, string what)
{
switch (what)
{
case "Lowercase":
return input.Any(c => char.IsLower(c));
case "Uppercase":
return input.Any(c => char.IsUpper(c));
case "Digit":
return input.Any(c => char.IsDigit(c));
case "Symbol":
return input.Any(c => char.IsSymbol(c));
default:
foreach(var c in what.ToCharArray())
{
if (input.Contains(c)) return true;
}
return false;
}
}
}
}
+259
View File
@@ -0,0 +1,259 @@
using Extreme.Net;
using LiteDB;
using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace RuriLib.Models
{
/// <summary>
/// The Status of a CProxy.
/// </summary>
public enum Status
{
/// <summary>The proxy is not assigned to any bot.</summary>
AVAILABLE,
/// <summary>The proxy is assigned to at least 1 bot.</summary>
BUSY,
/// <summary>The proxy didn't accept the connection.</summary>
BAD,
/// <summary>The proxy was banned.</summary>
BANNED
}
/// <summary>
/// The Working Status of a CProxy.
/// </summary>
public enum ProxyWorking
{
/// <summary>The proxy is working fine.</summary>
YES,
/// <summary>The proxy is down or not accepting connections.</summary>
NO,
/// <summary>The proxy was not tested.</summary>
UNTESTED
}
/// <summary>
/// A proxy that supports http(s) and socks4/4a/5 protocols, authorization and chaining.
/// </summary>
public class CProxy
{
/// <summary>Needed for NoSQL storage.</summary>
public Guid Id { get; set; }
/// <summary>The unparsed proxy string.</summary>
public string Proxy { get; set; } = "";
/// <summary>The username used for authentication (empty if none).</summary>
public string Username { get; set; } = "";
/// <summary>The password used for authentication (empty if none).</summary>
public string Password { get; set; } = "";
/// <summary>The type of proxy.</summary>
public ProxyType Type { get; set; } = ProxyType.Http;
/// <summary>The country of the proxy's ip.</summary>
public string Country { get; set; } = "";
/// <summary>The response delay of the proxy.</summary>
public int Ping { get; set; } = 0;
/// <summary>The next proxy object in a Proxy Chain.</summary>
public CProxy Next { get; set; } = null;
/// <summary>When the proxy was last used.</summary>
public DateTime LastUsed { get; set; } = new DateTime(1970, 1, 1);
/// <summary>When the proxy was last checked.</summary>
public DateTime LastChecked { get; set; } = new DateTime(1970, 1, 1);
/// <summary>The Working Status of the proxy.</summary>
public ProxyWorking Working { get; set; } = ProxyWorking.UNTESTED;
/// <summary>Whether the proxy has a successor in the Proxy Chain.</summary>
[BsonIgnore]
public bool HasNext { get { return Next != null; } }
/// <summary>The number of times the proxy was used for a check.</summary>
[BsonIgnore]
public int Uses { get; set; } = 0;
/// <summary>The number of bots the proxy is hooked to.</summary>
[BsonIgnore]
public int Hooked { get; set; } = 0;
/// <summary>The clearance cookie from Cloudflare.</summary>
[BsonIgnore]
public string Clearance { get; set; } = "";
/// <summary>The cfduid cookie from Cloudflare.</summary>
[BsonIgnore]
public string Cfduid { get; set; } = "";
/// <summary>The status of the proxy.</summary>
[BsonIgnore]
public Status Status { get; set; } = Status.AVAILABLE;
/// <summary>Needed for NoSQL deserialization.</summary>
public CProxy() { }
/// <summary>
/// Creates a proxy given a string and a proxy type.
/// </summary>
/// <param name="proxy">The unparsed proxy string</param>
/// <param name="type">The proxy type</param>
public CProxy(string proxy, ProxyType type)
{
Proxy = proxy;
Type = type;
}
/// <summary>
/// Parses a CProxy object from an advanced string. Supports Proxy Chains.
/// </summary>
/// <param name="proxy">The string to parse the proxy from</param>
/// <returns>The parsed CProxy object</returns>
public CProxy Parse(string proxy)
{
// Take the first proxy of the chain
var chain = proxy.Split(new string[] { "->" }, 2, StringSplitOptions.None);
var current = chain[0];
// If the type was specified, parse it and remove it from the string
if (current.StartsWith("("))
{
var groups = Regex.Match(current, @"^\((.*)\)(.*)").Groups;
Enum.TryParse<ProxyType>(groups[1].Value, true, out var type);
Type = type;
current = current.Replace($"({groups[1].Value})", "");
}
// Split the host:port:user:pass portion and set the first two
var fields = current.Split(':');
Proxy = $"{fields[0]}:{fields[1]}";
// Set the other two if they are present
if (fields.Count() > 2)
{
Username = fields[2];
Password = fields[3];
}
// If the chain is not finished, set the next proxy by parsing recursively
if (chain.Count() > 1)
{
Next = (new CProxy()).Parse(chain[1]);
}
// Finally return this proxy
return this;
}
/// <summary>
/// Gets the ProxyClient related to the specific proxy type.
/// </summary>
/// <returns>The ProxyClient to be used in a HttpRequest</returns>
public ProxyClient GetClient()
{
if (HasNext)
{
ChainProxyClient cpc = new ChainProxyClient();
var current = this;
while (current != null)
{
switch (current.Type)
{
case ProxyType.Http:
cpc.AddHttpProxy(current.Proxy);
break;
case ProxyType.Socks4:
cpc.AddSocks4Proxy(current.Proxy);
break;
case ProxyType.Socks4a:
cpc.AddSocks4aProxy(current.Proxy);
break;
case ProxyType.Socks5:
cpc.AddSocks5Proxy(current.Proxy);
break;
}
current = current.Next;
}
return cpc;
}
else
{
switch (Type)
{
case ProxyType.Http:
return HttpProxyClient.Parse(Proxy);
case ProxyType.Socks4:
return Socks4ProxyClient.Parse(Proxy);
case ProxyType.Socks4a:
return Socks4aProxyClient.Parse(Proxy);
case ProxyType.Socks5:
return Socks5ProxyClient.Parse(Proxy);
default:
return null;
}
}
}
/// <summary>The Host string parsed from the proxy.</summary>
[BsonIgnore]
public string Host
{
get
{
try { return Proxy.Split(':').First(); }
catch { return ""; }
}
}
/// <summary>The Port string parsed from the proxy.</summary>
[BsonIgnore]
public string Port
{
get
{
try { return Proxy.Split(':').Last(); }
catch { return ""; }
}
}
/// <summary>Whether the proxy is a valid numeric proxy.</summary>
[BsonIgnore]
public bool IsValidNumeric {
get {
return !(
Host == "" ||
Port == "" ||
Port.Any(c => !char.IsDigit(c)) ||
Host.Split('.').Count() != 4 ||
!IsNumeric
);
}
}
/// <summary>Whether the proxy is numeric.</summary>
[BsonIgnore]
public bool IsNumeric { get { return !Host.Split('.').Any(x => x.Any(c => !char.IsDigit(c))); } }
/// <summary>How long ago the proxy was used.</summary>
[BsonIgnore]
public TimeSpan UsedAgo { get { return DateTime.Now - LastUsed; } }
}
}
+169
View File
@@ -0,0 +1,169 @@
using System.Collections.Generic;
using System.Linq;
namespace RuriLib.Models
{
/// <summary>
/// Represents a variable.
/// </summary>
public class CVar
{
/// <summary>
/// The type of variable.
/// </summary>
public enum VarType
{
/// <summary>Holds a single string as value.</summary>
Single,
/// <summary>Holds a list of strings as value.</summary>
List,
/// <summary>Holds a dictionary of strings as value.</summary>
Dictionary
}
/// <summary>The variable name.</summary>
public string Name { get; set; }
/// <summary>The dynamic variable value.</summary>
public dynamic Value { get; set; }
/// <summary>Whether the variable is used for the final capture.</summary>
public bool IsCapture { get; set; }
/// <summary>The variable type (it determines which type of value is expected).</summary>
public VarType Type { get; set; }
/// <summary>Whether the variable is hidden and shouldn't be displayed to the user.</summary>
public bool Hidden { get; set; }
// Constructors
/// <summary>Needed for NoSQL deserialization.</summary>
public CVar() { }
/// <summary>
/// Creates a variable of type Single.
/// </summary>
/// <param name="name">The variable name</param>
/// <param name="value">The variable value as a single string</param>
/// <param name="isCapture">Whether the variable is marked as Capture</param>
/// <param name="hidden">Whether the variable is hidden</param>
public CVar(string name, string value, bool isCapture = false, bool hidden = false)
{
Name = name;
Value = value;
IsCapture = isCapture;
Type = VarType.Single;
Hidden = hidden;
}
/// <summary>
/// Creates a variable of type List.
/// </summary>
/// <param name="name">The variable name</param>
/// <param name="value">The variable value as a list of strings</param>
/// <param name="isCapture">Whether the variable is marked as Capture</param>
/// <param name="hidden">Whether the variable is hidden</param>
public CVar(string name, List<string> value, bool isCapture = false, bool hidden = false)
{
Name = name;
Value = value;
IsCapture = isCapture;
Type = VarType.List;
Hidden = hidden;
}
/// <summary>
/// Creates a variable of type Dictionary.
/// </summary>
/// <param name="name">The variable name</param>
/// <param name="value">The variable value as a dictionary of strings</param>
/// <param name="isCapture">Whether the variable is marked as Capture</param>
/// <param name="hidden">Whether the variable is hidden</param>
public CVar(string name, Dictionary<string, string> value, bool isCapture = false, bool hidden = false)
{
Name = name;
Value = value;
IsCapture = isCapture;
Type = VarType.Dictionary;
Hidden = hidden;
}
/// <summary>
/// Creates a variable of a given type.
/// </summary>
/// <param name="name">The variable name</param>
/// <param name="type">The variable type</param>
/// <param name="value">The dynamic variable value</param>
/// <param name="isCapture">Whether the variable is marked as Capture</param>
/// <param name="hidden">Whether the variable is hidden</param>
public CVar(string name, VarType type, dynamic value, bool isCapture = false, bool hidden = false)
{
Name = name;
Value = value;
IsCapture = isCapture;
Type = type;
Hidden = hidden;
}
/// <summary>
/// Outputs a string from a variable.
/// </summary>
/// <returns>The formatted value of the value as a single string</returns>
public override string ToString()
{
switch (Type)
{
case VarType.Single:
return Value;
case VarType.List:
return "[" + string.Join(", ", (List<string>)Value) + "]";
case VarType.Dictionary:
return "{" + string.Join(", ", ((Dictionary<string, string>)Value).Select(d => "(" + d.Key + ", " + d.Value + ")")) + "}";
default:
return base.ToString();
}
}
/// <summary>
/// Gets an item from a List variable.
/// </summary>
/// <param name="index">The index of the item</param>
/// <returns>The item of the List variable's value</returns>
public string GetListItem(int index)
{
if (Type != VarType.List) return null;
var list = Value as List<string>;
if (index > list.Count - 1 || index < 0) return null;
return list[index];
}
/// <summary>
/// Gets an item from a Dictionary Key.
/// </summary>
/// <param name="key">The key of the dictionary entry</param>
/// <returns>The value of the Dictionary variable's entry</returns>
public string GetDictValue(string key)
{
var dict = Value as Dictionary<string, string>;
if (dict.ContainsKey(key)) return dict.First(d => d.Key == key).Value;
else return dict.FirstOrDefault(d => d.Key.Contains(key)).Value;
}
/// <summary>
/// Gets an item from a Dictionary Value.
/// </summary>
/// <param name="value">The value of the dictionary entry</param>
/// <returns>The key of the Dictionary variable's entry</returns>
public string GetDictKey(string value)
{
var dict = Value as Dictionary<string, string>;
if (dict.ContainsValue(value)) return dict.First(d => d.Value == value).Key;
else return dict.FirstOrDefault(d => d.Value.Contains(value)).Key;
}
}
}
+54
View File
@@ -0,0 +1,54 @@
using Newtonsoft.Json;
using RuriLib.ViewModels;
using System.Collections.Generic;
using System.Linq;
using RuriLib.LS;
using System.Text.RegularExpressions;
using System;
namespace RuriLib
{
/// <summary>
/// Represents a configuration in RuriLib.
/// </summary>
public class Config : ViewModelBase
{
/// <summary>
/// Creates a Config given the settings and the script.
/// </summary>
/// <param name="settings">The settings of the Config</param>
/// <param name="script">The LoliScript script of the Config</param>
public Config(ConfigSettings settings, string script)
{
Settings = settings;
Script = script;
}
/// <summary>The settings of the Config.</summary>
public ConfigSettings Settings { get; set; }
/// <summary>The LoliScript script of the Config.</summary>
public string Script { get; set; }
/// <summary>Whether Selenium is being used in any of the blocks of the Config.</summary>
public bool SeleniumPresent { get { return Script.Contains("NAVIGATE") || Script.Contains("BROWSERACTION") || Script.Contains("ELEMENTACTION") || Script.Contains("EXECUTEJS") || Script.Contains("MOUSEACTION"); } }
/// <summary>Whether a possibly dangerous JavaScript or IronPython script is present in the Config.</summary>
public bool DangerousScriptPresent { get { return Script.ToUpper().Contains("BEGIN SCRIPT"); } }
/// <summary>Whether captcha solving blocks are present in the Config.</summary>
public bool CaptchasNeeded { get { return Script.Contains("CAPTCHA"); } }
/// <summary>Whether bypasscf blocks are present in the Config.</summary>
public bool HasCFBypass { get { return Script.Contains("BYPASSCF"); } }
/// <summary>The amount of blocks of the Config.</summary>
public int BlocksAmount { get { return Script.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Where(l => BlockParser.IsBlock(l)).Count(); } }
/// <summary>The joined representation of the allowed WordlistTypes.</summary>
public string AllowedWordlists { get { return $"{Settings.AllowedWordlist1} | {Settings.AllowedWordlist2}"; } }
/// <summary>The pretty representation of the time when the Config was last modified.</summary>
public string LastModifiedString { get { return $"{Settings.LastModified.ToShortDateString()} {Settings.LastModified.ToShortTimeString()}"; } }
}
}
+153
View File
@@ -0,0 +1,153 @@
using RuriLib.Models;
using RuriLib.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace RuriLib
{
/// <summary>
/// Contains all the settings of a Config.
/// </summary>
public class ConfigSettings : ViewModelBase
{
#region General
private string name = "";
/// <summary>The name of the Config.</summary>
public string Name { get { return name; } set { name = value; OnPropertyChanged(); } }
private int suggestedBots = 1;
/// <summary>The suggested amount of Bots that should be used with the config.</summary>
public int SuggestedBots { get { return suggestedBots; } set { suggestedBots = value; OnPropertyChanged(); } }
private DateTime lastModified = DateTime.Now;
/// <summary>When the Config was last modified.</summary>
public DateTime LastModified { get { return lastModified; } set { lastModified = value; OnPropertyChanged(); } }
private string additionalInfo = "";
/// <summary>Additional information on the Config usage.</summary>
public string AdditionalInfo { get { return additionalInfo; } set { additionalInfo = value; OnPropertyChanged(); } }
private string author = "";
/// <summary>The name of the Author of the Config.</summary>
public string Author { get { return author; } set { author = value; OnPropertyChanged(); } }
private string version = "1.0.0";
/// <summary>The version of RuriLib the Config was made with.</summary>
public string Version { get { return version; } set { version = value; OnPropertyChanged(); } }
#endregion
#region Requests
private bool ignoreResponseErrors = false;
/// <summary>Whether to proceed if an HTTP request fails instead of giving the ERROR status.</summary>
public bool IgnoreResponseErrors { get { return ignoreResponseErrors; } set { ignoreResponseErrors = value; OnPropertyChanged(); } }
#endregion
#region Proxy
private bool needsProxies = false;
/// <summary>Whether the Config needs proxies to work (the Runner can override this).</summary>
public bool NeedsProxies { get { return needsProxies; } set { needsProxies = value; OnPropertyChanged(); } }
private bool onlySocks = false;
/// <summary>Whether only SOCKS proxies should be used.</summary>
public bool OnlySocks { get { return onlySocks; } set { onlySocks = value; OnPropertyChanged(); } }
private bool onlySsl = false;
/// <summary>Whether only SSL proxies should be used.</summary>
public bool OnlySsl { get { return onlySsl; } set { onlySsl = value; OnPropertyChanged(); } }
private int maxProxyUses = 0;
/// <summary>The maximum amount of times a proxy can be used before being banned by the Runner (0 for infinite).</summary>
public int MaxProxyUses { get { return maxProxyUses; } set { maxProxyUses = value; OnPropertyChanged(); } }
#endregion
#region Data
private string allowedWordlist1 = "";
/// <summary>The name of the first allowed WordlistType.</summary>
public string AllowedWordlist1 { get { return allowedWordlist1; } set { allowedWordlist1 = value; OnPropertyChanged(); } }
private string allowedWordlist2 = "";
/// <summary>The name of the second allowed WordlistType.</summary>
public string AllowedWordlist2 { get { return allowedWordlist2; } set { allowedWordlist2 = value; OnPropertyChanged(); } }
/// <summary>The collection of data rules that check if a data line is valid.</summary>
public ObservableCollection<DataRule> DataRules { get; set; } = new ObservableCollection<DataRule>();
#endregion
#region Inputs
/// <summary>The collection of custom inputs that the Runner asks to the user upon start.</summary>
public ObservableCollection<CustomInput> CustomInputs { get; set; } = new ObservableCollection<CustomInput>();
#endregion
#region Selenium
private bool forceHeadless = false;
/// <summary>Whether to override the default choice of the user and force headless mode.</summary>
public bool ForceHeadless { get { return forceHeadless; } set { forceHeadless = value; OnPropertyChanged(); } }
private bool alwaysOpen = false;
/// <summary>Whether to always open a browser at the start of the checking process (if not already open).</summary>
public bool AlwaysOpen { get { return alwaysOpen; } set { alwaysOpen = value; OnPropertyChanged(); } }
private bool alwaysQuit = false;
/// <summary>Whether to always quit the browser and dispose of the WebDriver at the end of the checking process (if any browser is open).</summary>
public bool AlwaysQuit { get { return alwaysQuit; } set { alwaysQuit = value; OnPropertyChanged(); } }
private bool disableNotifications = false;
/// <summary>Whether to disable notifications the lock the page and make it impossible to proceed.</summary>
public bool DisableNotifications { get { return disableNotifications; } set { disableNotifications = value; OnPropertyChanged(); } }
private string customUserAgent = "";
/// <summary>The custom User-Agent header that should be used for every request of the browser.</summary>
public string CustomUserAgent { get { return customUserAgent; } set { customUserAgent = value; OnPropertyChanged(); } }
private bool randomUA = false;
/// <summary>Whether to choose a random User-Agent header when opening a browser instance.</summary>
public bool RandomUA { get { return randomUA; } set { randomUA = value; OnPropertyChanged(); } }
private string customCMDArgs = "";
/// <summary>The custom command line arguments that are sent when running the executable file.</summary>
public string CustomCMDArgs { get { return customCMDArgs; } set { customCMDArgs = value; OnPropertyChanged(); } }
#endregion
#region Methods
/// <summary>
/// Removes a DataRule given its id.
/// </summary>
/// <param name="id">The unique id of the DataRule</param>
public void RemoveDataRuleById(int id)
{
DataRules.Remove(GetDataRuleById(id));
}
/// <summary>
/// Gets a DataRule given its id.
/// </summary>
/// <param name="id">The unique id of the DataRule</param>
/// <returns>The DataRule</returns>
public DataRule GetDataRuleById(int id)
{
return DataRules.FirstOrDefault(r => r.Id == id);
}
/// <summary>
/// Removes a CustomInput given its id.
/// </summary>
/// <param name="id">The unique id of the CustomInput</param>
public void RemoveCustomInputById(int id)
{
CustomInputs.Remove(GetCustomInputById(id));
}
/// <summary>
/// Gets a CustomInput given its id.
/// </summary>
/// <param name="id">The unique id of the CustomInput</param>
/// <returns>The CustomInput</returns>
public CustomInput GetCustomInputById(int id)
{
return CustomInputs.FirstOrDefault(c => c.Id == id);
}
#endregion
}
}
+31
View File
@@ -0,0 +1,31 @@
using Newtonsoft.Json;
using System;
namespace RuriLib.ViewModels
{
/// <summary>
/// A custom input that is required to the user before the Config is started.
/// </summary>
public class CustomInput : ViewModelBase
{
private string description = "";
/// <summary>The description of what the user needs to enter.</summary>
public string Description { get { return description; } set { description = value; OnPropertyChanged(); } }
private string variableName = "";
/// <summary>The name of the variable to create basing on the value provided by the user.</summary>
public string VariableName { get { return variableName; } set { variableName = value; OnPropertyChanged(); } }
/// <summary>The id of the Custom Input.</summary>
public int Id { get; set; }
/// <summary>
/// Creates a CustomInput given an id.
/// </summary>
/// <param name="id">A unique id</param>
public CustomInput(int id)
{
Id = id;
}
}
}
+16
View File
@@ -0,0 +1,16 @@
using System.Windows.Media;
namespace RuriLib.Models
{
/// <summary>
/// A KeyChain that can be customized in name and color.
/// </summary>
public class CustomKeychain
{
/// <summary>The name of the KeyChain.</summary>
public string Name { get; set; } = "CUSTOM";
/// <summary>The color of the KeyChain.</summary>
public Color Color { get; set; } = Colors.OrangeRed;
}
}
+55
View File
@@ -0,0 +1,55 @@
using RuriLib.ViewModels;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RuriLib.Models
{
/// <summary>
/// The pool where data lines are taken from.
/// </summary>
public class DataPool : ViewModelBase
{
/// <summary>The IEnumerable of all available data lines.</summary>
public IEnumerable<string> List { get; }
/// <summary>The total number of lines.</summary>
public int Size { get; set; }
/// <summary>
/// Creates a DataPool given an IEnumerable and counts the amount of lines.
/// </summary>
/// <param name="list">The IEnumerable to pick lines from</param>
public DataPool(IEnumerable<string> list)
{
List = list;
Size = List.Count();
}
/// <summary>
/// Creates a DataPool by loading lines from a file.
/// </summary>
/// <param name="fileName">The name of the file to load data lines from</param>
public DataPool(string fileName)
{
List = File.ReadLines(fileName);
Size = List.Count();
}
/// <summary>
/// Creates a DataPool by generating all the possible combinations of a string.
/// </summary>
/// <param name="charSet">The allowed character set (one after the other like in the string "abcdef")</param>
/// <param name="length">The length of the output combinations</param>
public DataPool(string charSet, int length)
{
List = charSet.Select(x => x.ToString());
for (int i = 0; i < length; i++)
List = List.SelectMany(x => charSet, (x, y) => x + y);
Size = (int)Math.Pow(charSet.Length, length);
}
}
}
+66
View File
@@ -0,0 +1,66 @@
using Newtonsoft.Json;
using RuriLib.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RuriLib.Models
{
/// <summary>
/// The condition for which a Rule is tested.
/// </summary>
public enum RuleType
{
/// <summary>The slice must contain the given characters.</summary>
MustContain,
/// <summary>The slice must not contain the given characters.</summary>
MustNotContain,
/// <summary>The slice's length must be greater or equal to a given number.</summary>
MinLength,
/// <summary>The slice's length must be smaller or equal to a given number.</summary>
MaxLength
}
/// <summary>
/// Represents a rule that the data line must respect in order to be valid for a given Config.
/// </summary>
public class DataRule : ViewModelBase
{
private string sliceName = "";
/// <summary>The name of the specific slice (defined in the WordlistType) this rule refers to.</summary>
public string SliceName { get { return sliceName; } set { sliceName = value; OnPropertyChanged(); } }
private RuleType ruleType = RuleType.MustContain;
/// <summary>The type of the rule.</summary>
public RuleType RuleType { get { return ruleType; } set { ruleType = value; OnPropertyChanged(); } }
private string ruleString = "Lowercase";
/// <summary>The characters to search in the sliced value. Defaults are Lowercase, Uppercase, Digit, Symbol. Custom character sets can be created by concatenating the characters in a single string (e.g. ABCDEF).</summary>
public string RuleString { get { return ruleString; } set { ruleString = value; OnPropertyChanged(); } }
/// <summary>The id of the rule.</summary>
public int Id { get; set; }
/// <summary>Whether the type has been initialized. Used in the View.</summary>
[JsonIgnore]
public bool TypeInitialized { get; set; } = false;
/// <summary>Whether the right-hand term has been initialized. Used in the View.</summary>
[JsonIgnore]
public bool StringInitialized { get; set; } = false;
/// <summary>
/// Creates a DataRule given an id.
/// </summary>
/// <param name="id">The unique id of the rule</param>
public DataRule(int id)
{
Id = id;
}
}
}
+60
View File
@@ -0,0 +1,60 @@
using System.Collections.Generic;
using System.Linq;
namespace RuriLib.Models
{
/// <summary>
/// Settings for customizeable data types used in the library.
/// </summary>
public class EnvironmentSettings
{
/// <summary>List of custom Wordlist Types.</summary>
public List<WordlistType> WordlistTypes { get; set; } = new List<WordlistType>();
/// <summary>List of custom KeyChain Types.</summary>
public List<CustomKeychain> CustomKeychains { get; set; } = new List<CustomKeychain>();
/// <summary>List of custom Export Formats.</summary>
public List<ExportFormat> ExportFormats { get; set; } = new List<ExportFormat>();
/// <summary>
/// Gets the names of all Wordlist Types.
/// </summary>
/// <returns>The list of all the names of custom Wordlist Types</returns>
public List<string> GetWordlistTypeNames()
{
return WordlistTypes.Select(w => w.Name).ToList();
}
/// <summary>
/// Gets the names of all Custom KeyChains.
/// </summary>
/// <returns>The list of all the names of custom KeyChain types</returns>
public List<string> GetCustomKeychainNames()
{
return CustomKeychains.Select(c => c.Name).ToList();
}
/// <summary>
/// Gets a Custom KeyChain given its name.
/// </summary>
/// <param name="name">The name of the Custom KeyChain</param>
/// <returns>The CustomKeychain object if found, a default one if not</returns>
public CustomKeychain GetCustomKeychain(string name)
{
try { return CustomKeychains.First(w => w.Name == name); }
catch { return new CustomKeychain(); }
}
/// <summary>
/// Gets a Wordlist Type given its name.
/// </summary>
/// <param name="name">The name of the Wordlist Type</param>
/// <returns>The WordlistType object if found, a default one if not</returns>
public WordlistType GetWordlistType(string name)
{
try { return WordlistTypes.FirstOrDefault(w => w.Name == name); }
catch { return new WordlistType(); }
}
}
}
+17
View File
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RuriLib.Models
{
/// <summary>
/// The export format for saving a Hit as a formatted string.
/// </summary>
public class ExportFormat
{
/// <summary>The format of the desired string.</summary>
public string Format { get; set; } = "<DATA>";
}
}
+87
View File
@@ -0,0 +1,87 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RuriLib.Models
{
/// <summary>
/// Represents the outcome of a successful check, used as Data Type in a Database.
/// </summary>
public class Hit
{
/// <summary>Needed for NoSQL storage.</summary>
public Guid Id { get; set; }
/// <summary>The data line that was used.</summary>
public string Data { get; set; }
/// <summary>The list of all variables marked as Capture.</summary>
public VariableList CapturedData { get; set; }
/// <summary>The list of all variables marked as Capture as a chained string.</summary>
[JsonIgnore]
public string CapturedString { get { return CapturedData.ToCaptureString(); } }
/// <summary>The proxy that was used.</summary>
public string Proxy { get; set; }
/// <summary>The timestamp of when the Hit was found.</summary>
public DateTime Date { get; set; }
/// <summary>The type of Hit.</summary>
public string Type { get; set; }
/// <summary>The name of the Config that was used.</summary>
public string ConfigName { get; set; }
/// <summary>The name of the Wordlist that was used.</summary>
public string WordlistName { get; set; }
/// <summary>Needed for NoSQL deserialization.</summary>
public Hit() { }
/// <summary>
/// Creates a Hit given its details.
/// </summary>
/// <param name="data">The data line used</param>
/// <param name="capturedData">The VariableList of all captured data</param>
/// <param name="proxy">The proxy used</param>
/// <param name="type">The type of the Hit</param>
/// <param name="configName">The Config's name</param>
/// <param name="wordlistName">The Wordlist's name</param>
public Hit(string data, VariableList capturedData, string proxy, string type, string configName, string wordlistName)
{
Data = data;
CapturedData = capturedData;
Proxy = proxy;
Date = DateTime.Now;
Type = type;
ConfigName = configName;
WordlistName = wordlistName;
}
/// <summary>
/// Outputs the Hit details in a given format.
/// </summary>
/// <param name="format">The format in which variables should be replaced</param>
/// <returns>The formatted string with all variables replaced</returns>
public string ToFormattedString(string format)
{
StringBuilder sb = new StringBuilder(format)
.Replace("<DATA>", Data)
.Replace("<PROXY>", Proxy)
.Replace("<DATE>", Date.ToLongDateString() + " " + Date.ToLongTimeString())
.Replace("<CONFIG>", ConfigName)
.Replace("<WORDLIST>", WordlistName)
.Replace("<TYPE>", Type)
.Replace("<CAPTURE>", CapturedData.ToCaptureString());
foreach(var cap in CapturedData.All)
sb.Replace("<" + cap.Name + ">", cap.ToString());
return sb.ToString();
}
}
}
+32
View File
@@ -0,0 +1,32 @@
using RuriLib.ViewModels;
namespace RuriLib.Models
{
/// <summary>
/// Represents a Key in a KeyChain.
/// </summary>
public class Key : ViewModelBase
{
private string leftTerm = "<SOURCE>";
/// <summary>The left-hand term for the comparison.</summary>
public string LeftTerm { get { return leftTerm; } set { leftTerm = value; OnPropertyChanged(); } }
private Condition condition = Condition.Contains;
/// <summary>The condition of the comparison.</summary>
public Condition Condition { get { return condition; } set { condition = value; OnPropertyChanged(); } }
private string rightTerm = "";
/// <summary>The right-hand term of the comparison.</summary>
public string RightTerm { get { return rightTerm; } set { rightTerm = value; OnPropertyChanged(); } }
/// <summary>
/// Checks the comparison between left and right member.
/// </summary>
/// <param name="data">The BotData used for variable replacement.</param>
/// <returns>Whether the comparison is valid</returns>
public bool CheckKey(BotData data)
{
return ConditionChecker.Verify(LeftTerm, Condition, RightTerm, data);
}
}
}
+101
View File
@@ -0,0 +1,101 @@
using RuriLib.Models;
using RuriLib.ViewModels;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Media;
namespace RuriLib.Models
{
/// <summary>
/// Represents a set of keys that can be checked in a OR/AND fashion and modifies the status of the BotData if successful.
/// </summary>
public class KeyChain : ViewModelBase
{
/// <summary>The returned status upon a successful check of the keys. If no KeyChain was valid, the original status won't be changed.</summary>
public enum KeychainType
{
/// <summary>Sets a SUCCESS status in the bot.</summary>
Success,
/// <summary>Sets a FAIL status in the bot.</summary>
Failure,
/// <summary>Sets a BAN status in the bot.</summary>
Ban,
/// <summary>Sets a RETRY status in the bot.</summary>
Retry,
/// <summary>Sets a CUSTOM status in the bot.</summary>
Custom
}
/// <summary>The mode in which the keys should be checked.</summary>
public enum KeychainMode
{
/// <summary>Trigger the KeyChain if ANY Key is valid.</summary>
OR,
/// <summary>Trigger the KeyChain if ALL the Keys are valid.</summary>
AND
}
private KeychainType type = KeychainType.Success;
/// <summary>The type of the KeyChain.</summary>
public KeychainType Type { get { return type; } set { type = value; OnPropertyChanged(); } }
private KeychainMode mode = KeychainMode.OR;
/// <summary>The mode of the KeyChain.</summary>
public KeychainMode Mode { get { return mode; } set { mode = value; OnPropertyChanged(); } }
private string customType = "CUSTOM";
/// <summary>The type of the KeyChain in case Custom is selected.</summary>
public string CustomType { get { return customType; } set { customType = value; OnPropertyChanged(); } }
/// <summary>The collection of Keys in the KeyChain.</summary>
public ObservableCollection<Key> Keys { get; set; } = new ObservableCollection<Key>();
/// <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.Condition.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.Condition.ToString(),
BlockBase.ReplaceValues(key.RightTerm, data)),
Colors.White));
}
}
return true;
}
return false;
}
}
}
+91
View File
@@ -0,0 +1,91 @@
using RuriLib.ViewModels;
using System;
using System.Windows.Media;
namespace RuriLib
{
/// <summary>
/// How critical a log entry is.
/// </summary>
public enum LogLevel
{
/// <summary>An informational message.</summary>
Info,
/// <summary>A warning message.</summary>
Warning,
/// <summary>An error message.</summary>
Error
}
/// <summary>
/// A single entry in the log of the application.
/// </summary>
public class LogEntry : ViewModelBase
{
private string logString = "";
/// <summary>The logged message.</summary>
public string LogString { get { return logString; } set { logString = value; OnPropertyChanged(); } }
private Color logColor = Colors.White;
/// <summary>The color of the logged entry.</summary>
public Color LogColor { get { return logColor; } set { logColor = value; OnPropertyChanged(); } }
private DateTime logTime = DateTime.Now;
/// <summary>The timestamp of the logged entry.</summary>
public DateTime LogTime { get { return logTime; } set { logTime = value; OnPropertyChanged(); } }
private LogLevel logLevel = LogLevel.Info;
/// <summary>The level of the logged entry.</summary>
public LogLevel LogLevel { get { return logLevel; } set { logLevel = value; OnPropertyChanged(); } }
private string logComponent = "";
/// <summary>The component that logged the entry.</summary>
public string LogComponent { get { return logComponent; } set { logComponent = value; OnPropertyChanged(); } }
/// <summary>
/// <para>Creates a Log Entry given a message and a color.</para>
/// <para>This constructor is used to generate entries for the Bot Log.</para>
/// <para>The level is Info and the component is an empty string.</para>
/// </summary>
/// <param name="logString">The message to log</param>
/// <param name="logColor">The color of the message</param>
public LogEntry(string logString, Color logColor)
{
LogString = logString;
LogColor = logColor;
LogTime = DateTime.Now;
}
/// <summary>
/// <para>Creates a Log Entry given a component, a message and a level.</para>
/// <para>This constructor is used for logging messages coming from components of the View.</para>
/// </summary>
/// <param name="logComponent">The Component that is logging the entry</param>
/// <param name="logString">The message to log</param>
/// <param name="logLevel">The level of the log</param>
public LogEntry(string logComponent, string logString, LogLevel logLevel)
{
LogString = logString;
LogTime = DateTime.Now;
LogLevel = logLevel;
LogComponent = logComponent;
switch (LogLevel)
{
case LogLevel.Info:
LogColor = Colors.White;
break;
case LogLevel.Warning:
LogColor = Colors.Gold;
break;
case LogLevel.Error:
LogColor = Colors.Tomato;
break;
}
}
}
}
+130
View File
@@ -0,0 +1,130 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace RuriLib.Models
{
/// <summary>
/// Class that manages a pool of proxies.
/// </summary>
public class ProxyPool
{
/// <summary>The full list of proxies in the pool.</summary>
public List<CProxy> Proxies { get; } = new List<CProxy>();
/// <summary>The list of Alive proxies (AVAILABLE or BUSY).</summary>
public List<CProxy> Alive { get { return Proxies.Where(p => p.Status == Status.AVAILABLE || p.Status == Status.BUSY).ToList(); } }
/// <summary>The list of Available proxies.</summary>
public List<CProxy> Available { get { return Proxies.Where(p => p.Status == Status.AVAILABLE).ToList(); } }
/// <summary>The list of Banned proxies.</summary>
public List<CProxy> Banned { get { return Proxies.Where(p => p.Status == Status.BANNED).ToList(); } }
/// <summary>The list of Bad proxies.</summary>
public List<CProxy> Bad { get { return Proxies.Where(p => p.Status == Status.BAD).ToList(); } }
/// <summary>
/// <para>Whether the proxy list is locked or not.</para>
/// <para>It prevents multiple bots from choosing the same proxy simultaneously, regardless of the fact that concurrent usage may be disabled.</para>
/// </summary>
private bool Locked { get; set; } = false;
/// <summary>
/// Initializes the proxy pool given a collection of string to be parsed as proxies and their type.
/// </summary>
/// <param name="proxies">The collection of strings to parse the proxies from</param>
/// <param name="type">The type of the proxies</param>
public ProxyPool(IEnumerable<string> proxies, Extreme.Net.ProxyType type)
{
Proxies = proxies.Select(p => new CProxy(p, type)).ToList();
}
/// <summary>
/// <para>Initializes the proxy pool given a collection of CProxy objects.</para>
/// <para>The proxies will be first cloned and then stored in the list.</para>
/// <para>They will also be unbanned to make sure there are no leftovers from previous checks.</para>
/// </summary>
/// <param name="proxies">The list of CProxy objects to be cloned and added to the list</param>
public ProxyPool(List<CProxy> proxies)
{
// We clone the list, since we don't want to target to the same objects that are in the Proxy Manager
// If we don't do this, a ban on a runner instance would cause a ban on all the other instances as well!
Proxies = IOManager.CloneProxies(proxies);
// Now that the list is cloned, we make sure that no proxy is already banned
UnbanAll();
}
/// <summary>
/// Clears the Clearance and Cfduid cookies set by Cloudflare.
/// </summary>
public void ClearCF()
{
foreach (var proxy in Proxies)
{
proxy.Clearance = "";
proxy.Cfduid = "";
}
}
/// <summary>
/// Sets all the BANNED and BAD proxies status to AVAILABLE and resets their Uses. It also clears the Cloudflare cookies.
/// </summary>
public void UnbanAll()
{
foreach (var proxy in Proxies)
{
if (proxy.Status == Status.BANNED || proxy.Status == Status.BAD)
{
proxy.Status = Status.AVAILABLE;
proxy.Hooked = 0;
proxy.Uses = 0;
}
}
ClearCF();
}
/// <summary>
/// Tries to return the first available proxy from the list.
/// </summary>
/// <param name="evenBusy">Whether to include proxies that are being used by other bots</param>
/// <param name="maxUses">The maximum uses of a proxy, after which it will be banned (0 for infinite)</param>
/// <param name="neverBan">Whether a proxy can ever be banned</param>
/// <returns>The first available proxy respecting the conditions or null</returns>
public CProxy GetProxy(bool evenBusy, int maxUses, bool neverBan = false)
{
while (Locked) Thread.Sleep(10);
CProxy proxy;
Locked = true;
if (evenBusy)
{
if (maxUses == 0) proxy = Alive.FirstOrDefault();
else proxy = Alive.Where(p => p.Uses < maxUses).FirstOrDefault();
}
else
{
if (maxUses == 0) proxy = Available.FirstOrDefault();
else proxy = Available.Where(p => p.Uses < maxUses).FirstOrDefault();
}
if (proxy != null)
{
if (maxUses > 0 && proxy.Uses > maxUses && !neverBan)
{
proxy.Status = Status.BANNED;
Locked = false;
return null;
}
else
{
proxy.Status = Status.BUSY;
proxy.Hooked++;
}
}
Locked = false;
return proxy;
}
}
}
+38
View File
@@ -0,0 +1,38 @@
using System;
namespace RuriLib.Models
{
/// <summary>
/// A record that, given a Config's name and a Wordlist's location, returns how many data lines have already been checked.
/// </summary>
public class Record
{
/// <summary>Needed for NoSQL storage.</summary>
public Guid Id { get; set; }
/// <summary>The name of the Config.</summary>
public string ConfigName { get; set; }
/// <summary>The location on disk of the Wordlist.</summary>
public string WordlistLocation { get; set; }
/// <summary>How many data lines were already checked.</summary>
public int Checkpoint { get; set; }
/// <summary>Needed for NoSQL deserialization.</summary>
public Record() { }
/// <summary>
/// Creates a Record to be stored in the Database.
/// </summary>
/// <param name="configName">The name of the Config used in the check</param>
/// <param name="wordlistLocation">The location on disk of the Wordlist used in the check</param>
/// <param name="checkpoint">The amount of data lines checked when creating the record</param>
public Record(string configName, string wordlistLocation, int checkpoint)
{
ConfigName = configName;
WordlistLocation = wordlistLocation;
Checkpoint = checkpoint;
}
}
}
+66
View File
@@ -0,0 +1,66 @@
using RuriLib.ViewModels;
using System;
using System.Collections.Generic;
namespace RuriLib.Models
{
/// <summary>
/// Represents the outcome of a check which can be represented in a list and can give information on the details of the check.
/// </summary>
public class ValidData : ViewModelBase
{
private string data;
/// <summary>The data line that was checked.</summary>
public string Data { get { return data; } set { data = value; OnPropertyChanged(); } }
private string proxy;
/// <summary>The proxy that was used for the check.</summary>
public string Proxy { get { return proxy; } set { proxy = value; OnPropertyChanged(); } }
private BotStatus result;
/// <summary>The result of the check.</summary>
public BotStatus Result { get { return result; } set { result = value; OnPropertyChanged(); } }
private string capturedData;
/// <summary>The data captured during the check.</summary>
public string CapturedData { get { return capturedData; } set { capturedData = value; OnPropertyChanged(); } }
private int unixDate;
/// <summary>The unix timestamp of the check completion.</summary>
public int UnixDate { get { return unixDate; } set { unixDate = value; OnPropertyChanged(); OnPropertyChanged(); } }
/// <summary>The timestamp of the check completion as a formatted date.</summary>
public string Timestamp { get { return (new DateTime(1970, 1, 1)).AddSeconds(UnixDate).ToShortDateString(); } }
/// <summary>The timestamp of the check completion as a DateTime object.</summary>
public DateTime Time { get { return (new DateTime(1970, 1, 1)).AddSeconds(UnixDate); } }
private string source;
/// <summary>The contents of the last page's source code at the end of the check.</summary>
public string Source { get { return source; } set { source = value; OnPropertyChanged(); } }
private List<LogEntry> log;
/// <summary>The entire log with the details of the check.</summary>
public List<LogEntry> Log { get { return log; } set { log = value; OnPropertyChanged(); } }
/// <summary>
/// Creates a ValidData object after a valid check.
/// </summary>
/// <param name="data">The data line that was used in the check</param>
/// <param name="proxy">The proxy that was used for the check (empty string if none)</param>
/// <param name="result">The result of the check</param>
/// <param name="capturedData">The data captured during the check</param>
/// <param name="source">The last page source code of the check</param>
/// <param name="log">The detailed log of the check</param>
public ValidData(string data, string proxy, BotStatus result, string capturedData, string source, List<LogEntry> log)
{
Data = data;
Proxy = proxy;
Result = result;
CapturedData = capturedData;
UnixDate = (int)Math.Round((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
Source = source;
Log = log;
}
}
}
+188
View File
@@ -0,0 +1,188 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
namespace RuriLib.Models
{
/// <summary>
/// Class that allows to easily manage a list of CVar objects.
/// </summary>
public class VariableList
{
/// <summary>The whole list of variables.</summary>
public List<CVar> All { get; set; }
/// <summary>The list of all variables marked as Capture.</summary>
[JsonIgnore]
public List<CVar> Captures { get { return All.Where(v => v.IsCapture && !v.Hidden).ToList(); } }
/// <summary>The list of all variables of type Single.</summary>
[JsonIgnore]
public List<CVar> Singles { get { return All.Where(v => v.Type == CVar.VarType.Single).ToList(); } }
/// <summary>The list of all variables of type List.</summary>
[JsonIgnore]
public List<CVar> Lists { get { return All.Where(v => v.Type == CVar.VarType.List).ToList(); } }
/// <summary>The list of all variables of type Dictionary.</summary>
[JsonIgnore]
public List<CVar> Dictionaries { get { return All.Where(v => v.Type == CVar.VarType.Dictionary).ToList(); } }
/// <summary>
/// Standard constructor that initializes an empty variable list.
/// </summary>
public VariableList()
{
All = new List<CVar>();
}
/// <summary>
/// Initializes a variable list starting from an existing list of variables.
/// </summary>
/// <param name="list">The list of variables.</param>
public VariableList(List<CVar> list)
{
All = list;
}
/// <summary>
/// Gets a variable given its name.
/// </summary>
/// <param name="name">The name of the variable</param>
/// <returns>The variable or null if it wasn't found.</returns>
public CVar Get(string name)
{
return All.FirstOrDefault(v => v.Name == name);
}
/// <summary>
/// Gets a variable given its name and type.
/// </summary>
/// <param name="name">The name of the variable</param>
/// <param name="type">The type of the variable</param>
/// <returns>The variable or null if it wasn't found.</returns>
public CVar Get(string name, CVar.VarType type)
{
return All.FirstOrDefault(v => v.Name == name && v.Type == type);
}
/// <summary>
/// Helper method that gets the value of a variable of type Single.
/// </summary>
/// <param name="name">The name of the Single variable</param>
/// <returns>The string value or null if it wasn't found.</returns>
public string GetSingle(string name)
{
try { return (string)Get(name, CVar.VarType.Single).Value; }
catch { return null; }
}
/// <summary>
/// Helper method that gets the value of a variable of type List.
/// </summary>
/// <param name="name">The name of the List variable</param>
/// <returns>The list of strings value or null if it wasn't found.</returns>
public List<string> GetList(string name)
{
try { return (List<string>)Get(name, CVar.VarType.List).Value; }
catch { return null; }
}
/// <summary>
/// Helper method that gets the value of a variable of type Dictionary.
/// </summary>
/// <param name="name">The name of the Dictionary variable</param>
/// <returns>The dictionary value or null if it wasn't found.</returns>
public Dictionary<string,string> GetDictionary(string name)
{
try { return (Dictionary<string, string>)Get(name, CVar.VarType.Dictionary).Value; }
catch { return null; }
}
/// <summary>
/// Helper method that checks if a variable exists given its name.
/// </summary>
/// <param name="name">The name of the variable</param>
/// <returns>True if the variable exists</returns>
public bool VariableExists(string name)
{
return All.Any(v => v.Name == name);
}
/// <summary>
/// Helper method that checks if a variable exists given its name and type.
/// </summary>
/// <param name="name">The name of the variable</param>
/// <param name="type">The type of the variable</param>
/// <returns>True if the variable exists and matches the given type</returns>
public bool VariableExists(string name, CVar.VarType type)
{
return All.Any(v => v.Name == name && v.Type == type);
}
/// <summary>
/// Adds a CVar object to the variable list.
/// </summary>
/// <param name="variable">The CVar object to add</param>
public void Set(CVar variable)
{
// First of all remove any old variable with the same name
Remove(variable.Name);
// Then add the new one
All.Add(variable);
}
/// <summary>
/// Adds a hidden CVar object to the variable list.
/// </summary>
/// <param name="name">The name of the variable to add</param>
/// <param name="value">The value of the variable to add</param>
public void SetHidden(string name, dynamic value)
{
if (All.Any(v => v.Name == name && v.Hidden))
All.FirstOrDefault(v => v.Name == name && v.Hidden).Value = value;
else
All.Add(new CVar(name, value, false, true));
}
/// <summary>
/// Adds a CVar object to the variable list only if no other variable with the same name exists.
/// </summary>
/// <param name="variable">The CVar object to add</param>
public void SetNew(CVar variable)
{
if (!VariableExists(variable.Name)) Set(variable);
}
/// <summary>
/// Removes a non-hidden variable given its name.
/// </summary>
/// <param name="name">The name of the variable to remove</param>
public void Remove(string name)
{
All.RemoveAll(v => v.Name == name && !v.Hidden);
}
/// <summary>
/// <para>Removes all non-hidden variables if their name matches a condition.</para>
/// <para>The name of the variables in the list are the left-hand term of the comparison.</para>
/// </summary>
/// <param name="cond">The condition type</param>
/// <param name="name">The right-hand term of the comparison</param>
/// <param name="data">The BotData object used for variable replacement</param>
public void Remove(Condition cond, string name, BotData data)
{
All.RemoveAll(v => ConditionChecker.Verify(v.Name, cond, name, data) && !v.Hidden);
}
/// <summary>
/// Generates a string where all the variables marked as Capture are printed in an organized fashion.
/// </summary>
/// <returns>The chained capture string.</returns>
public string ToCaptureString()
{
return string.Join(" | ", Captures.Select(c => c.Name + " = " + c.ToString()));
}
}
}
+58
View File
@@ -0,0 +1,58 @@
using System;
using System.IO;
using System.Linq;
namespace RuriLib.Models
{
/// <summary>
/// Represents a file as a source of input data that needs to be tested against a Config by the Runner.
/// </summary>
public class Wordlist
{
/// <summary>Needed for NoSQL storage.</summary>
public Guid Id { get; set; }
/// <summary>The name of the Wordlist.</summary>
public string Name { get; set; }
/// <summary>The path where the file is stored on disk.</summary>
public string Path { get; set; }
/// <summary>The WordlistType as a string (since the WordlistTypes in the Environment file are editable).</summary>
public string Type { get; set; }
/// <summary>The purpose for which the Wordlist should be used.</summary>
public string Purpose { get; set; }
/// <summary>The total number of data lines of the file.</summary>
public int Total { get; set; }
/// <summary>Needed for NoSQL deserialization.</summary>
public Wordlist() { }
/// <summary>
/// Creates an instance of a Wordlist.
/// </summary>
/// <param name="name">The name of the Wordlist</param>
/// <param name="path">The path to the file on disk</param>
/// <param name="type">The WordlistType as a string</param>
/// <param name="purpose">The purpose of the Wordlist</param>
/// <param name="countLines">Whether to enumerate the total number of data lines in the Wordlist</param>
public Wordlist(string name, string path, string type, string purpose, bool countLines = true)
{
Name = name;
Path = path;
Type = type;
Purpose = purpose;
Total = 0;
if (countLines)
{
try
{
Total = File.ReadLines(path).Count();
}
catch { }
}
}
}
}
+28
View File
@@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace RuriLib.Models
{
/// <summary>
/// Class that represents a type of Wordlist with rules to check the validity and to slice the data given a separator.
/// </summary>
public class WordlistType
{
/// <summary>Whether to check if the regex successfully matches the input data.</summary>
public bool Verify { get; set; } = false;
/// <summary>The regular expression that validates the input data.</summary>
public string Regex { get; set; } = "^.*$";
/// <summary>The name of the Wordlist Type.</summary>
public string Name { get; set; } = "Default";
/// <summary>The separator used for slicing the input data into a list of strings.</summary>
public string Separator { get; set; } = ":";
/// <summary>
/// <para>The list of variable names of the slices that will be created from the input data.</para>
/// <para>Each slice should be used to generate a pair of values with a variable name and a value taken from the split input data.</para>
/// </summary>
public List<string> Slices { get; set; } = new List<string>();
}
}