[#] 修复QQNT插件更新前对代理地址没有正确测速的问题

This commit is contained in:
辉鸭蛋 2024-11-07 00:27:14 +08:00
parent 25532df301
commit 7cbb8939e1
3 changed files with 73 additions and 34 deletions

View File

@ -31,17 +31,17 @@ namespace RevokeMsgPatcher.Forms
// 添加代理 URL 到下拉菜单 // 添加代理 URL 到下拉菜单
foreach (var proxy in ProxySpeedTester.ProxyUrls) foreach (var proxy in ProxySpeedTester.ProxyUrls)
{ {
cboGithubProxy.Items.Add(proxy); cboGithubProxy.Items.Add(proxy.Replace("{0}",""));
} }
// 异步测试代理速度并设置默认选项 // 异步测试代理速度并设置默认选项
Task.Run(async () => Task.Run(async () =>
{ {
var fastestProxy = await ProxySpeedTester.GetFastestProxyAsync(); var fastestProxy = await ProxySpeedTester.GetFastestProxyAsync(ProxySpeedTester.TargetUrl);
Debug.WriteLine(fastestProxy); Debug.WriteLine(fastestProxy.Item1);
if (!string.IsNullOrEmpty(fastestProxy)) if (!string.IsNullOrEmpty(fastestProxy.Item1))
{ {
cboGithubProxy.Invoke(new Action(() => cboGithubProxy.SelectedItem = fastestProxy)); cboGithubProxy.Invoke(new Action(() => cboGithubProxy.SelectedItem = fastestProxy.Item1));
} }
}); });
} }

View File

@ -127,11 +127,11 @@ namespace RevokeMsgPatcher.Model
} }
} }
public async Task<string> GetRemoteVersion(string proxyUrl = null) public async Task<string> GetRemoteVersion(string proxyUrl)
{ {
using (var client = new HttpClient()) using (var client = new HttpClient())
{ {
var url = string.IsNullOrEmpty(proxyUrl) ? VersionJsonUrl : proxyUrl + "/" + VersionJsonUrl; var url = FormatUrl(proxyUrl, VersionJsonUrl);
var response = await client.GetAsync(url); var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
@ -144,6 +144,30 @@ namespace RevokeMsgPatcher.Model
} }
} }
private string FormatUrl(string proxyUrl, string target)
{
if (string.IsNullOrEmpty(proxyUrl))
{
return target;
}
else
{
if (proxyUrl.Contains("{0}"))
{
return string.Format(proxyUrl, target);
}
else
{
if (!proxyUrl.EndsWith("/"))
{
proxyUrl += "/";
}
return proxyUrl + target;
}
}
}
public async Task CheckAndUpdate(string proxyUrl = null) public async Task CheckAndUpdate(string proxyUrl = null)
{ {
try try
@ -161,7 +185,7 @@ namespace RevokeMsgPatcher.Model
UpdateStatus($"存在新版本{remoteVersion},正在下载..."); UpdateStatus($"存在新版本{remoteVersion},正在下载...");
Debug.WriteLine("发现新版本,正在下载..."); Debug.WriteLine("发现新版本,正在下载...");
var url = DownloadUrl.Replace("#{version}", remoteVersion); var url = DownloadUrl.Replace("#{version}", remoteVersion);
url = string.IsNullOrEmpty(proxyUrl) ? url : proxyUrl + "/" + url; url = FormatUrl(proxyUrl, url);
string downloadedFilePath = await DownloadLatestPackage(url, Path.Combine(Application.StartupPath, "Public/Download")); string downloadedFilePath = await DownloadLatestPackage(url, Path.Combine(Application.StartupPath, "Public/Download"));
Debug.WriteLine("下载到:" + downloadedFilePath); Debug.WriteLine("下载到:" + downloadedFilePath);
UpdateStatus($"下载成功,解压中..."); UpdateStatus($"下载成功,解压中...");

View File

@ -9,60 +9,75 @@ namespace RevokeMsgPatcher.Utils
{ {
public class ProxySpeedTester public class ProxySpeedTester
{ {
private static readonly string TargetUrl = "https://raw.githubusercontent.com/LiteLoaderQQNT/LiteLoaderQQNT/refs/heads/main/package.json"; public static readonly string TargetUrl = "https://raw.githubusercontent.com/LiteLoaderQQNT/LiteLoaderQQNT/refs/heads/main/package.json";
private static readonly HttpClient _httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(5) }; private static readonly HttpClient _httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(5) };
public static readonly List<string> ProxyUrls = new List<string>() public static readonly List<string> ProxyUrls = new List<string>()
{ {
"https://mirror.ghproxy.com", "{0}",
"https://hub.gitmirror.com", "https://mirror.ghproxy.com/{0}",
"https://ghproxy.cc", "https://hub.gitmirror.com/{0}",
"https://www.ghproxy.cc", "https://ghproxy.cc/{0}",
"https://ghproxy.cn", "https://www.ghproxy.cc/{0}",
"https://ghproxy.net", "https://ghproxy.cn/{0}",
"https://ghproxy.net/{0}"
}; };
public static async Task<string> GetFastestProxyAsync() /// <summary>
/// 获得最快的代理地址
/// </summary>
/// <param name="target"></param>
/// <returns>最快的代理地址,结果</returns>
public static async Task<Tuple<string, string>> GetFastestProxyAsync(string target)
{ {
return await GetFastestProxyAsync(ProxyUrls); return await GetFastestProxyAsync(ProxyUrls, target);
} }
public static async Task<string> GetFastestProxyAsync(List<string> proxyAddresses) public static async Task<Tuple<string, string>> GetFastestProxyAsync(List<string> proxyAddresses, string target)
{ {
var tasks = new List<Task<string>>(); var tasks = new List<Task<Tuple<string, string, bool>>>(); // 修改为包含成功标志的元组
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
foreach (var proxy in proxyAddresses) foreach (var proxy in proxyAddresses)
{ {
tasks.Add(TestProxyAsync(proxy, cts.Token)); // 如果目标地址为空且代理地址为默认地址,则跳过
if (string.IsNullOrEmpty(target) && proxy == "{0}")
{
continue;
}
tasks.Add(TestProxyAsync(proxy, target, cts.Token));
} }
var firstCompletedTask = await Task.WhenAny(tasks); while (tasks.Count > 0)
cts.Cancel(); // 取消所有其他请求 {
var firstCompletedTask = await Task.WhenAny(tasks);
tasks.Remove(firstCompletedTask);
try var result = await firstCompletedTask;
{ if (result.Item3) // 检查是否成功
return await firstCompletedTask; // 返回第一个完成的代理地址 {
} cts.Cancel(); // 取消所有其他请求
catch (OperationCanceledException) return new Tuple<string, string>(result.Item1, result.Item2); // 返回第一个成功的代理地址
{ }
return null; // 如果第一个任务被取消,返回 null
} }
return new Tuple<string, string>(string.Empty, string.Empty); // 如果没有成功的结果,返回空
} }
private static async Task<string> TestProxyAsync(string proxyAddress, CancellationToken cancellationToken) private static async Task<Tuple<string, string, bool>> TestProxyAsync(string proxyAddress, string target, CancellationToken cancellationToken)
{ {
try try
{ {
// 模拟代理测试请求 // 模拟代理测试请求
var response = await _httpClient.GetAsync(proxyAddress, cancellationToken); var response = await _httpClient.GetAsync(string.Format(proxyAddress, target), cancellationToken);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
return proxyAddress; return new Tuple<string, string, bool>(proxyAddress.Replace("{0}", ""), await response.Content.ReadAsStringAsync(), true);
} }
catch (Exception) catch (Exception e)
{ {
return null; return new Tuple<string, string, bool>(proxyAddress.Replace("{0}", ""), e.Message, false);
} }
} }
} }