Added multiple remote proxy sources to RL proxy settings.

This commit is contained in:
ruri
2019-05-26 13:43:50 +02:00
parent 5cd60ed125
commit 0340843980
7 changed files with 340 additions and 90 deletions
-2
View File
@@ -457,7 +457,6 @@ namespace RuriLib
break;
case ParseType.REGEX:
REGEXBEGIN:
try
{
var matches = Regex.Matches(partial, ReplaceValues(regexString, data));
@@ -466,7 +465,6 @@ namespace RuriLib
var output = ReplaceValues(regexOutput, data);
for (var i = 0; i < match.Groups.Count; i++) output = output.Replace("[" + i + "]", match.Groups[i].Value);
list.Add(output);
if (recursive && match.Index + match.Length <= partial.Length) { partial = partial.Substring(match.Index + match.Length); goto REGEXBEGIN; }
}
}
catch { }
+65
View File
@@ -0,0 +1,65 @@
using Extreme.Net;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RuriLib.Models
{
/// <summary>
/// A remote source where proxies can be downloaded and parsed from.
/// </summary>
public class RemoteProxySource
{
/// <summary>
/// Creates a RemoteProxySource given a unique ID.
/// </summary>
/// <param name="id">The unique ID</param>
public RemoteProxySource(int id)
{
Id = id;
}
/// <summary>The unique ID of the RemoteProxySource.</summary>
public int Id { get; set; } = 0;
/// <summary>The Url of the remote source.</summary>
public string Url { get; set; } = "";
/// <summary>The type of downloaded proxies.</summary>
public ProxyType Type { get; set; } = ProxyType.Http;
/// <summary>
/// Whether the proxy type has been initialized.
/// </summary>
[JsonIgnore]
public bool TypeInitialized { get; set; } = false;
/// <summary>The regex pattern to match when parsing proxies from the downloaded page. Must use capture groups.</summary>
// Best Regex = @"((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9]+)";
public string Pattern { get; set; } = @"([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)";
/// <summary>The output format of the groups matched by Regex.</summary>
public string Output { get; set; } = "[1]";
}
/// <summary>
/// The result for async download of proxies from remote sources.
/// </summary>
public class RemoteProxySourceResult
{
/// <summary>Whether the download was successful.</summary>
public bool Successful { get; set; }
/// <summary>The Message of the Exception thrown while downloading or parsing the proxies.</summary>
public string Error { get; set; }
/// <summary>The Url from which the proxies were downloaded from.</summary>
public string Url { get; set; }
/// <summary>The downloaded and parsed proxies.</summary>
public List<CProxy> Proxies { get; set; }
}
}
+74 -40
View File
@@ -11,6 +11,7 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
namespace RuriLib.Runner
@@ -1012,15 +1013,17 @@ namespace RuriLib.Runner
Thread.Sleep(100);
break;
case ProxyReloadSource.API:
try
case ProxyReloadSource.Remote:
List<CProxy> proxies = new List<CProxy>();
Parallel.ForEach(Settings.Proxies.RemoteProxySources, s =>
{
ProxyPool = new ProxyPool(
GetProxiesFromAPI(Settings.Proxies.ReloadPath,
Settings.Proxies.ReloadType,
Settings.Proxies.ParseWithIPRegex), Settings.Proxies.ShuffleOnStart);
}
catch (Exception ex) { RaiseMessageArrived(LogLevel.Error, $"Could not contact the reload API - {ex.Message}", true); }
try
{
proxies.AddRange(GetProxiesFromRemoteSource(s.Url, s.Type, s.Pattern, s.Output));
}
catch (Exception ex) { RaiseMessageArrived(LogLevel.Error, $"Could not contact the reload API - {ex.Message}", true); }
});
ProxyPool = new ProxyPool(proxies, Settings.Proxies.ShuffleOnStart);
break;
case ProxyReloadSource.File:
@@ -1028,8 +1031,7 @@ namespace RuriLib.Runner
{
ProxyPool = new ProxyPool(
GetProxiesFromFile(Settings.Proxies.ReloadPath,
Settings.Proxies.ReloadType,
Settings.Proxies.ParseWithIPRegex), Settings.Proxies.ShuffleOnStart);
Settings.Proxies.ReloadType), Settings.Proxies.ShuffleOnStart);
}
catch (Exception ex) { RaiseMessageArrived(LogLevel.Error, $"Could not read the proxies from file - {ex.Message}", true); }
break;
@@ -1039,62 +1041,94 @@ namespace RuriLib.Runner
}
/// <summary>
/// Loads a list of proxies from an API endpoint.
/// Loads a list of proxies from a remote source.
/// </summary>
/// <param name="url">The URL of the API call</param>
/// <param name="url">The URL of the remote source</param>
/// <param name="type">The type of the proxies</param>
/// <param name="useRegex">Whether to use an IP:PORT regex to extract the proxies from the lines</param>
/// <param name="pattern">The Regex pattern to be used for parsing the proxies</param>
/// <param name="output">The output format of the groups matched by the regex</param>
/// <returns>The list of CProxy objects loaded from the API</returns>
public static List<CProxy> GetProxiesFromAPI(string url, ProxyType type, bool useRegex = false)
public static List<CProxy> GetProxiesFromRemoteSource(string url, ProxyType type, string pattern, string output)
{
var proxies = new List<CProxy>();
HttpRequest req = new HttpRequest();
req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36 OPR/52.0.2871.64";
var resp = req.Get(url).ToString();
if (useRegex)
try
{
var pattern = "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9]+";
var matches = Regex.Matches(resp, pattern);
foreach (Match m in matches)
proxies.Add(new CProxy(m.Value, type));
}
else
{
proxies.AddRange(resp
.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries)
.Select(p => new CProxy(p.Trim(), type)));
foreach (Match match in matches)
{
var result = output;
for (var i = 0; i < match.Groups.Count; i++) result = result.Replace("[" + i + "]", match.Groups[i].Value);
proxies.Add(new CProxy(result, type));
}
}
catch { }
return proxies;
}
/// <summary>
/// Loads a list of proxies from a remote source asynchronously.
/// </summary>
/// <param name="url">The URL of the remote source</param>
/// <param name="type">The type of the proxies</param>
/// <param name="pattern">The Regex pattern to be used for parsing the proxies</param>
/// <param name="output">The output format of the groups matched by the regex</param>
/// <returns>The list of CProxy objects loaded from the API</returns>
public async static Task<RemoteProxySourceResult> GetProxiesFromRemoteSourceAsync(string url, ProxyType type, string pattern, string output)
{
var proxies = new List<CProxy>();
try
{
HttpRequest req = new HttpRequest();
req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36 OPR/52.0.2871.64";
var resp = (await req.GetAsync(url)).ToString();
var matches = Regex.Matches(resp, pattern);
foreach (Match match in matches)
{
var result = output;
for (var i = 0; i < match.Groups.Count; i++) result = result.Replace("[" + i + "]", match.Groups[i].Value);
proxies.Add(new CProxy(result, type));
}
}
catch (Exception ex)
{
return new RemoteProxySourceResult()
{
Successful = false,
Error = ex.Message,
Url = url,
Proxies = new List<CProxy>()
};
}
return new RemoteProxySourceResult()
{
Successful = true,
Error = "",
Url = url,
Proxies = proxies
};
}
/// <summary>
/// Loads a list of proxies from a file.
/// </summary>
/// <param name="fileName">The file containing the proxies, one per line</param>
/// <param name="type">The type of the proxies</param>
/// <param name="useRegex">Whether to use an IP:PORT regex to extract the proxies from the lines</param>
/// <returns>The list of CProxy objects loaded from the file</returns>
public static List<CProxy> GetProxiesFromFile(string fileName, ProxyType type, bool useRegex = false)
public static List<CProxy> GetProxiesFromFile(string fileName, ProxyType type)
{
var lines = File.ReadAllLines(fileName);
var proxies = new List<CProxy>();
if (useRegex)
{
var pattern = "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9]+";
foreach(var line in lines)
{
var match = Regex.Match(line, pattern);
if (match.Success)
proxies.Add(new CProxy(match.Value, type));
}
}
else
{
proxies.AddRange(lines.Select(l => new CProxy(l, type)));
}
proxies.AddRange(lines.Select(l => new CProxy(l, type)));
return proxies;
}
+1
View File
@@ -145,6 +145,7 @@
<Compile Include="LoliScript\Writer\BlockWriter.cs" />
<Compile Include="Models\DataPool.cs" />
<Compile Include="Models\ProxyPool.cs" />
<Compile Include="Models\RemoteProxySource.cs" />
<Compile Include="Runner\AbortableBackgroundWorker.cs">
<SubType>Component</SubType>
</Compile>
@@ -1,5 +1,8 @@
using Extreme.Net;
using RuriLib.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
namespace RuriLib.ViewModels
@@ -13,8 +16,8 @@ namespace RuriLib.ViewModels
Manager,
/// <summary>A file on the disk.</summary>
File,
/// <summary>An online API.</summary>
API
/// <summary>A remote API or website.</summary>
Remote
}
/// <summary>
@@ -50,21 +53,12 @@ namespace RuriLib.ViewModels
public ProxyReloadSource ReloadSource { get { return reloadSource; } set { reloadSource = value; OnPropertyChanged(); } }
private string reloadPath = "";
/// <summary>The API URL or the file path on disk.</summary>
/// <summary>The file path on disk.</summary>
public string ReloadPath { get { return reloadPath; } set { reloadPath = value; OnPropertyChanged(); } }
private ProxyType reloadType = ProxyType.Http;
/// <summary>The Type of the proxies to load.</summary>
public ProxyType ReloadType { get { return reloadType; } set { reloadType = value; OnPropertyChanged(); } }
private bool parseWithIPRegex = false;
/// <summary>
/// <para>Whether to use an IP:PORT regex to extract the proxies from the source.</para>
/// <para>The regex will match proxies of the form 127.0.0.1:8888.</para>
/// <para>This is useful for example when the server returns proxies in a HTML, XML or JSON format and not one proxy per line.</para>
/// <para>This is also useful when the server returns proxies with unix-like line endings.</para>
/// </summary>
public bool ParseWithIPRegex { get { return parseWithIPRegex; } set { parseWithIPRegex = value; OnPropertyChanged(); } }
#endregion
#region Cloudflare
@@ -91,6 +85,30 @@ namespace RuriLib.ViewModels
public string[] GlobalRetryKeys { get { return globalRetryKeys; } set { globalRetryKeys = value; OnPropertyChanged(); } }
#endregion
#region Remote Proxy Sources
/// <summary>The sources where proxies are downloaded and parsed from.</summary>
public ObservableCollection<RemoteProxySource> RemoteProxySources { get; set; } = new ObservableCollection<RemoteProxySource>();
/// <summary>
/// Removes a RemoteProxySource given its id.
/// </summary>
/// <param name="id">The id of the RemoteProxySource</param>
public void RemoveRemoteProxySourceById(int id)
{
RemoteProxySources.Remove(GetRemoteProxySourceById(id));
}
/// <summary>
/// Gets a RemoteProxySource given its id.
/// </summary>
/// <param name="id">The id of the RemoteProxySource</param>
/// <returns>The wanted RemoteProxySource. Null if not found.</returns>
public RemoteProxySource GetRemoteProxySourceById(int id)
{
return RemoteProxySources.FirstOrDefault(s => s.Id == id);
}
#endregion
/// <summary>
/// Resets the properties to their default value.
/// </summary>