diff --git a/BetterGenshinImpact.sln.DotSettings b/BetterGenshinImpact.sln.DotSettings
index 46e57701..0cf4b727 100644
--- a/BetterGenshinImpact.sln.DotSettings
+++ b/BetterGenshinImpact.sln.DotSettings
@@ -1,2 +1,4 @@
- True
\ No newline at end of file
+ True
+ True
+ True
\ No newline at end of file
diff --git a/BetterGenshinImpact/Assets/Strings/md2html.html b/BetterGenshinImpact/Assets/Strings/md2html.html
index f559099d..429babf3 100644
--- a/BetterGenshinImpact/Assets/Strings/md2html.html
+++ b/BetterGenshinImpact/Assets/Strings/md2html.html
@@ -18,14 +18,10 @@
::-webkit-scrollbar-thumb:hover {
background: #555;
}
- .body {
- background-color: #202020;
- color: #e6edf3;
- }
.markdown-body {
margin: 0;
padding: 8px;
- background-color: #202020;
+ background-color: #202020 !important;
height: 100%
}
* {
diff --git a/BetterGenshinImpact/Model/UpdateOption.cs b/BetterGenshinImpact/Model/UpdateOption.cs
index eb68bf53..ba899fa7 100644
--- a/BetterGenshinImpact/Model/UpdateOption.cs
+++ b/BetterGenshinImpact/Model/UpdateOption.cs
@@ -3,6 +3,10 @@
public sealed class UpdateOption
{
public UpdateTrigger Trigger { get; set; } = default;
+
+ public UpdateChannel Channel { get; set; } = UpdateChannel.Stable;
+
+ public string? MirrorChanCdk { get; set; }
}
public enum UpdateTrigger
@@ -10,3 +14,10 @@ public enum UpdateTrigger
Auto,
Manual,
}
+
+
+public enum UpdateChannel
+{
+ Stable,
+ Alpha,
+}
\ No newline at end of file
diff --git a/BetterGenshinImpact/Service/Model/Mirrorchan/LatestResponse.cs b/BetterGenshinImpact/Service/Model/Mirrorchan/LatestResponse.cs
new file mode 100644
index 00000000..88d4ec11
--- /dev/null
+++ b/BetterGenshinImpact/Service/Model/Mirrorchan/LatestResponse.cs
@@ -0,0 +1,117 @@
+using System.Text.Json.Serialization;
+
+namespace BetterGenshinImpact.Service.Model.Mirrorchan;
+
+#nullable enable
+#pragma warning disable CS8618
+#pragma warning disable CS8601
+#pragma warning disable CS8603
+public partial class LatestResponse
+{
+ ///
+ /// 响应代码,https://github.com/MirrorChyan/docs/blob/main/ErrorCode.md
+ ///
+ [JsonPropertyName("code")]
+ public long Code { get; set; }
+
+ ///
+ /// 响应数据
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("data")]
+ public Data Data { get; set; }
+
+ ///
+ /// 响应信息
+ ///
+ [JsonPropertyName("msg")]
+ public string Msg { get; set; }
+}
+
+///
+/// 响应数据
+///
+public partial class Data
+{
+ ///
+ /// 更新包架构
+ ///
+ [JsonPropertyName("arch")]
+ public string Arch { get; set; }
+
+ ///
+ /// CDK过期时间戳
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("cdk_expired_time")]
+ public double? CdkExpiredTime { get; set; }
+
+ ///
+ /// 更新频道,stable | beta | alpha
+ ///
+ [JsonPropertyName("channel")]
+ public string Channel { get; set; }
+
+ ///
+ /// 自定义数据
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("custom_data")]
+ public string CustomData { get; set; }
+
+ ///
+ /// 文件大小
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("filesize")]
+ public long? Filesize { get; set; }
+
+ ///
+ /// 更新包系统
+ ///
+ [JsonPropertyName("os")]
+ public string Os { get; set; }
+
+ ///
+ /// 发版日志
+ ///
+ [JsonPropertyName("release_note")]
+ public string ReleaseNote { get; set; }
+
+ ///
+ /// sha256
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("sha256")]
+ public string Sha256 { get; set; }
+
+ ///
+ /// 更新包类型,incremental | full
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("update_type")]
+ public string UpdateType { get; set; }
+
+ ///
+ /// 下载地址
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [JsonPropertyName("url")]
+ public string Url { get; set; }
+
+ ///
+ /// 资源版本名称
+ ///
+ [JsonPropertyName("version_name")]
+ public string VersionName { get; set; }
+
+ ///
+ /// 资源版本号仅内部使用
+ ///
+ [JsonPropertyName("version_number")]
+ public long VersionNumber { get; set; }
+}
+
+#pragma warning restore CS8618
+#pragma warning restore CS8601
+#pragma warning restore CS8603
\ No newline at end of file
diff --git a/BetterGenshinImpact/Service/UpdateService.cs b/BetterGenshinImpact/Service/UpdateService.cs
index e5cf9d9c..9a473db8 100644
--- a/BetterGenshinImpact/Service/UpdateService.cs
+++ b/BetterGenshinImpact/Service/UpdateService.cs
@@ -10,6 +10,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
+using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
@@ -18,6 +19,8 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
+using BetterGenshinImpact.Service.Model.Mirrorchan;
+using Wpf.Ui.Violeta.Controls;
namespace BetterGenshinImpact.Service;
@@ -37,7 +40,7 @@ public class UpdateService : IUpdateService
_configService = configService;
Config = _configService.Get();
}
-
+
///
/// Please call me in main thread
@@ -50,13 +53,13 @@ public class UpdateService : IUpdateService
#if DEBUG && false
return;
#endif
- string newVersion = await GetLatestVersionAsync();
+ string newVersion = await GetLatestVersionAsync(option);
if (string.IsNullOrWhiteSpace(newVersion))
{
return;
}
-
+
// ---- 如果是调试模式且手动的检查更新的情况下,强制打开更新窗口 -----
// 方便调试窗口
if (RuntimeHelper.IsDebuggerAttached && option.Trigger == UpdateTrigger.Manual)
@@ -72,7 +75,7 @@ public class UpdateService : IUpdateService
{
await MessageBox.InformationAsync("当前已是最新版本!");
}
-
+
return;
}
@@ -87,7 +90,8 @@ public class UpdateService : IUpdateService
}
catch (Exception e)
{
- Debug.WriteLine("获取最新版本信息失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
+ Debug.WriteLine("获取最新版本信息失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" +
+ Environment.NewLine + e.Message);
_logger.LogWarning("获取 BetterGI 最新版本信息失败");
}
}
@@ -122,12 +126,12 @@ public class UpdateService : IUpdateService
await MessageBox.ErrorAsync("更新程序不存在,请选择其他更新方式!");
return;
}
+
// 启动
Process.Start(updaterExePath, "-I");
-
+
// 退出程序
Application.Current.Shutdown();
-
}
break;
@@ -144,11 +148,112 @@ public class UpdateService : IUpdateService
}
};
- win.NavigateToHtml(await GetReleaseMarkdownHtmlAsync());
+ if (option.Channel == UpdateChannel.Stable)
+ {
+ win.NavigateToHtml(await GetReleaseMarkdownHtmlAsync());
+ }
+
win.ShowDialog();
}
- private async Task GetLatestVersionAsync()
+ private async Task GetLatestVersionAsync(UpdateOption option)
+ {
+ if (option.Channel == UpdateChannel.Stable)
+ {
+ return await UpdateFromOss();
+ }
+ else
+ {
+ return await UpdateFromMirrorChan(option);
+ }
+ }
+
+ ///
+ /// 文档
+ /// https://apifox.com/apidoc/shared/ffdc8453-597d-4ba6-bd3c-5e375c10c789
+ ///
+ ///
+ ///
+ private async Task UpdateFromMirrorChan(UpdateOption option)
+ {
+ if (string.IsNullOrWhiteSpace(option.MirrorChanCdk))
+ {
+ Toast.Warning("Mirror酱源更新检查失败,未设置CDK");
+ return string.Empty;
+ }
+
+ try
+ {
+ const string url = "https://mirrorchyan.com/api/resources/BGI/latest";
+ var queryParams = new Dictionary
+ {
+ { "cdk", option.MirrorChanCdk },
+ { "user_agent", "BetterGI" },
+ { "os", "win" },
+ { "arch", "x64" },
+ { "channel", "alpha" }
+ };
+
+ using var httpClient = new HttpClient();
+
+ var finalUrl = $"{url}?{string.Join("&", queryParams.Select(x => $"{x.Key}={x.Value}"))}";
+ var response = await httpClient.GetFromJsonAsync(finalUrl);
+
+ if (response != null)
+ {
+ if (response.Code == 0)
+ {
+ return response.Data.VersionName;
+ }
+ else if (response.Code < 0)
+ {
+ Toast.Error(
+ $"Mirror酱源更新检查失败,意料之外的严重错误,请及时联系 Mirror 酱的技术支持处理\n,错误代码:{response.Code},错误信息:{response.Msg}");
+ return string.Empty;
+ }
+ else
+ {
+ ToastError(response);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ _logger.LogDebug(e, "Mirror源更新检查失败");
+ }
+
+ return string.Empty;
+ }
+
+ private static void ToastError(LatestResponse response)
+ {
+ if (response.Code == 7001)
+ {
+ Toast.Warning("Mirror酱 CDK 已过期,请重新获取CDK");
+ }
+ else if (response.Code == 7002)
+ {
+ Toast.Warning("Mirror酱 CDK 错误!");
+ }
+ else if (response.Code == 7003)
+ {
+ Toast.Warning("Mirror酱 CDK 今日下载次数已达上限");
+ }
+ else if (response.Code == 7004)
+ {
+ Toast.Warning("Mirror酱 CDK 类型和待下载的资源不匹配");
+ }
+ else if (response.Code == 7005)
+ {
+ Toast.Warning("Mirror酱 CDK 已被封禁");
+ }
+ else
+ {
+ Toast.Warning($"Mirror酱源更新检查失败,错误信息:{response.Msg}");
+ }
+ }
+
+ private async Task UpdateFromOss()
{
try
{
@@ -181,7 +286,9 @@ public class UpdateService : IUpdateService
{
using HttpClient httpClient = new();
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
- string jsonString = await httpClient.GetStringAsync("https://api.github.com/repos/babalae/better-genshin-impact/releases/latest");
+ string jsonString =
+ await httpClient.GetStringAsync(
+ "https://api.github.com/repos/babalae/better-genshin-impact/releases/latest");
var jsonDict = JsonConvert.DeserializeObject>(jsonString);
if (jsonDict != null)
@@ -191,7 +298,8 @@ public class UpdateService : IUpdateService
string md = $"# {name}{new string('\n', 2)}{body}";
md = WebUtility.HtmlEncode(md);
- string md2html = ResourceHelper.GetString($"pack://application:,,,/Assets/Strings/md2html.html", Encoding.UTF8);
+ string md2html = ResourceHelper.GetString($"pack://application:,,,/Assets/Strings/md2html.html",
+ Encoding.UTF8);
var html = md2html.Replace("{{content}}", md);
return html;
@@ -240,4 +348,4 @@ public class UpdateService : IUpdateService