更多更新渠道的UI改造

This commit is contained in:
辉鸭蛋
2025-06-01 17:22:44 +08:00
parent 0c02808626
commit eed98bf8d5
9 changed files with 372 additions and 33 deletions

View File

@@ -1,2 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=enkanomiya/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/UserDictionary/Words/=enkanomiya/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=mirrorchan/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=steambird/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -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%
}
* {

View File

@@ -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,
}

View File

@@ -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
{
/// <summary>
/// 响应代码https://github.com/MirrorChyan/docs/blob/main/ErrorCode.md
/// </summary>
[JsonPropertyName("code")]
public long Code { get; set; }
/// <summary>
/// 响应数据
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("data")]
public Data Data { get; set; }
/// <summary>
/// 响应信息
/// </summary>
[JsonPropertyName("msg")]
public string Msg { get; set; }
}
/// <summary>
/// 响应数据
/// </summary>
public partial class Data
{
/// <summary>
/// 更新包架构
/// </summary>
[JsonPropertyName("arch")]
public string Arch { get; set; }
/// <summary>
/// CDK过期时间戳
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("cdk_expired_time")]
public double? CdkExpiredTime { get; set; }
/// <summary>
/// 更新频道stable | beta | alpha
/// </summary>
[JsonPropertyName("channel")]
public string Channel { get; set; }
/// <summary>
/// 自定义数据
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("custom_data")]
public string CustomData { get; set; }
/// <summary>
/// 文件大小
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("filesize")]
public long? Filesize { get; set; }
/// <summary>
/// 更新包系统
/// </summary>
[JsonPropertyName("os")]
public string Os { get; set; }
/// <summary>
/// 发版日志
/// </summary>
[JsonPropertyName("release_note")]
public string ReleaseNote { get; set; }
/// <summary>
/// sha256
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("sha256")]
public string Sha256 { get; set; }
/// <summary>
/// 更新包类型incremental | full
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("update_type")]
public string UpdateType { get; set; }
/// <summary>
/// 下载地址
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("url")]
public string Url { get; set; }
/// <summary>
/// 资源版本名称
/// </summary>
[JsonPropertyName("version_name")]
public string VersionName { get; set; }
/// <summary>
/// 资源版本号仅内部使用
/// </summary>
[JsonPropertyName("version_number")]
public long VersionNumber { get; set; }
}
#pragma warning restore CS8618
#pragma warning restore CS8601
#pragma warning restore CS8603

View File

@@ -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();
}
/// <summary>
/// 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<string> GetLatestVersionAsync()
private async Task<string> GetLatestVersionAsync(UpdateOption option)
{
if (option.Channel == UpdateChannel.Stable)
{
return await UpdateFromOss();
}
else
{
return await UpdateFromMirrorChan(option);
}
}
/// <summary>
/// 文档
/// https://apifox.com/apidoc/shared/ffdc8453-597d-4ba6-bd3c-5e375c10c789
/// </summary>
/// <param name="option"></param>
/// <returns></returns>
private async Task<string> 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<string, string>
{
{ "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<LatestResponse>(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<string> 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<Dictionary<string, object>>(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
</html>
""";
}
}
}

View File

@@ -1078,7 +1078,7 @@
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,20,0"
Command="{Binding OpenKeyBindingsWindowCommand}"
Command="{Binding CheckUpdateCommand}"
Content="检查更新" />
</Grid>
</ui:CardExpander.Header>
@@ -1099,15 +1099,40 @@
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="测试版非常不稳定,请谨慎选择更新!"
Text="测试版非常不稳定,请谨慎选择更新!"
TextWrapping="Wrap" />
<ui:Button Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
Command="{Binding OpenKeyBindingsWindowCommand}"
Command="{Binding CheckUpdateAlphaCommand}"
Content="测试版检查更新" />
</Grid>
<Grid Margin="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<emoji:TextBlock Grid.Row="0"
Grid.Column="0"
Text="直接从 Github 获取最新测试版"
TextWrapping="Wrap" />
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="【测试版】非常不稳定,请谨慎选择更新!"
TextWrapping="Wrap" />
<ui:Button Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
Margin="0,0,36,0"
Command="{Binding GotoGithubActionCommand}"
Content="访问 Github" />
</Grid>
</StackPanel>
</ui:CardExpander>

View File

@@ -47,12 +47,12 @@
<ui:TextBlock Grid.Row="0"
Grid.Column="0"
FontTypography="Body"
Text="Steambird"
Text="默认更新服务器"
TextWrapping="Wrap" />
<ui:TextBlock Grid.Row="1"
Grid.Column="0"
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
Text="普通用户可通过 Steambird 渠道直接更新(默认更新渠道)"
Text="普通用户可点此直接更新"
TextWrapping="Wrap" />
</Grid>
</ui:CardControl.Header>
@@ -61,7 +61,7 @@
Appearance="Success"
Icon="{ui:SymbolIcon ArrowDownload24}"
Content="立即更新"
Command="{Binding UpdateCommand}" />
Command="{Binding UpdateFromSteambirdCommand}" />
</StackPanel>
</ui:CardControl>
<ui:CardControl Margin="0,0,0,8">
@@ -87,14 +87,14 @@
</ui:CardControl.Header>
<StackPanel Orientation="Horizontal">
<ui:Button
Appearance="Primary"
Appearance="Success"
Icon="{ui:SymbolIcon TicketDiagonal24}"
Content="输入CDK更新"
Command="{Binding OneKeyExecuteCommand}" />
Content="立即更新"
Command="{Binding UpdateFromMirrorchanCommand}" />
</StackPanel>
</ui:CardControl>
<ui:CardControl Margin="0,0,0,8">
<!--<ui:CardControl Margin="0,0,0,8">
<ui:CardControl.Icon>
<ui:FontIcon Glyph="&#xf0c2;" Style="{StaticResource FaFontIconStyle}" />
</ui:CardControl.Icon>
@@ -122,7 +122,7 @@
Content="唤起胡桃"
Command="{Binding OneKeyExecuteCommand}" />
</StackPanel>
</ui:CardControl>
</ui:CardControl>-->
</StackPanel>
<!-- 原有按钮区域 -->
<ui:Grid Grid.Row="3"

View File

@@ -2,8 +2,11 @@
using CommunityToolkit.Mvvm.Input;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.Model;
using Wpf.Ui.Controls;
@@ -14,14 +17,15 @@ public partial class CheckUpdateWindow : FluentWindow
{
public Func<object, CheckUpdateWindowButton, Task>? UserInteraction = null!;
[ObservableProperty]
private bool showUpdateStatus = false;
[ObservableProperty] private bool showUpdateStatus = false;
[ObservableProperty]
private string updateStatusMessage = string.Empty;
[ObservableProperty] private string updateStatusMessage = string.Empty;
private UpdateOption _option;
public CheckUpdateWindow(UpdateOption option)
{
_option = option ?? throw new ArgumentNullException(nameof(option));
DataContext = this;
InitializeComponent();
@@ -30,6 +34,11 @@ public partial class CheckUpdateWindow : FluentWindow
IgnoreButton.Visibility = Visibility.Collapsed;
}
if (option.Channel == UpdateChannel.Alpha)
{
WebpagePanel.Visibility = Visibility.Collapsed;
}
Closing += OnClosing;
}
@@ -73,6 +82,49 @@ public partial class CheckUpdateWindow : FluentWindow
}
}
[RelayCommand]
private async Task UpdateFromSteambirdAsync()
{
await RunUpdaterAsync("-I");
}
[RelayCommand]
private async Task UpdateFromMirrorchanAsync()
{
if (_option.Channel == UpdateChannel.Stable)
{
await RunUpdaterAsync("--source mirrorc");
}
else
{
await RunUpdaterAsync("--source mirrorc-alpha");
}
}
/// <summary>
/// --source mirrorc
/// --source mirrorc-alpha
/// --source github
/// --dfs-extras {"hutao-token": "...."}
/// </summary>
private async Task RunUpdaterAsync(string parameters)
{
// 唤起更新程序
string updaterExePath = Global.Absolute("BetterGI.update.exe");
if (!File.Exists(updaterExePath))
{
await MessageBox.ErrorAsync("更新程序不存在,请选择其他更新方式!");
return;
}
// 启动
Process.Start(updaterExePath, parameters);
// 退出程序
Application.Current.Shutdown();
}
[RelayCommand]
private async Task IgnoreAsync()
{

View File

@@ -9,6 +9,7 @@ using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using Windows.System;
using BetterGenshinImpact.Core.Config;
using BetterGenshinImpact.Core.Recognition.OCR;
using BetterGenshinImpact.Core.Script;
@@ -16,6 +17,7 @@ using BetterGenshinImpact.GameTask;
using BetterGenshinImpact.GameTask.AutoTrackPath;
using BetterGenshinImpact.GameTask.Common.Element.Assets;
using BetterGenshinImpact.Helpers;
using BetterGenshinImpact.Model;
using BetterGenshinImpact.Service.Interface;
using BetterGenshinImpact.Service.Notification;
using BetterGenshinImpact.View.Converters;
@@ -260,4 +262,30 @@ public partial class CommonSettingsPageViewModel : ViewModel
{
await OcrFactory.ChangeCulture(type.Key);
}
[RelayCommand]
private async Task CheckUpdateAsync()
{
await App.GetService<IUpdateService>()!.CheckUpdateAsync(new UpdateOption
{
Trigger = UpdateTrigger.Manual,
Channel = UpdateChannel.Stable
});
}
[RelayCommand]
private async Task CheckUpdateAlphaAsync()
{
await App.GetService<IUpdateService>()!.CheckUpdateAsync(new UpdateOption
{
Trigger = UpdateTrigger.Manual,
Channel = UpdateChannel.Alpha
});
}
[RelayCommand]
private async Task GotoGithubActionAsync()
{
await Launcher.LaunchUriAsync(new Uri("https://github.com/babalae/better-genshin-impact/actions/workflows/publish.yml"));
}
}