mirror of
https://github.com/openbullet/openbullet.git
synced 2023-10-21 07:33:42 -05:00
First commit - OpenBullet 1.0.0
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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; } }
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()}"; } }
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>";
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user