feat: 添加 CDK 到期时间显示

This commit is contained in:
uye
2025-09-09 16:01:26 +08:00
parent 0b469d1913
commit 31a16b84fe
14 changed files with 165 additions and 0 deletions

View File

@@ -218,6 +218,7 @@ namespace MaaWpfGui.Constants
public const string UpdateSource = "VersionUpdate.ResourceUpdateSource";
public const string ForceGithubGlobalSource = "VersionUpdate.UpdateSource.ForceGithubGlobalSource";
public const string MirrorChyanCdk = "VersionUpdate.ResourceUpdateSource.MirrorChyanCdk";
public const string MirrorChyanCdkExpiredTime = "VersionUpdate.UpdateSource.MirrorChyanCdkExpired";
public const string StartupUpdateCheck = "VersionUpdate.StartupUpdateCheck";
public const string UpdateAutoCheck = "VersionUpdate.ScheduledUpdateCheck";
public const string ResourceApi = "VersionUpdate.ResourceApi";

View File

@@ -0,0 +1,55 @@
// <copyright file="ResourceReferenceHelper.cs" company="MaaAssistantArknights">
// Part of the MaaWpfGui project, maintained by the MaaAssistantArknights team (Maa Team)
// Copyright (C) 2021-2025 MaaAssistantArknights Contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License v3.0 only as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
// </copyright>
using System.Windows;
using System.Windows.Controls;
namespace MaaWpfGui.Extensions.UIBehaviors
{
public static class ResourceReferenceHelper
{
public static readonly DependencyProperty ForegroundResourceKeyProperty =
DependencyProperty.RegisterAttached(
"ForegroundResourceKey",
typeof(string),
typeof(ResourceReferenceHelper),
new PropertyMetadata(null, (d, e) =>
{
if (d is FrameworkElement fe && e.NewValue is string key)
{
fe.SetResourceReference(Control.ForegroundProperty, key);
}
}));
public static void SetForegroundResourceKey(DependencyObject d, string value) => d.SetValue(ForegroundResourceKeyProperty, value);
public static string GetForegroundResourceKey(DependencyObject d) => (string)d.GetValue(ForegroundResourceKeyProperty);
public static readonly DependencyProperty BackgroundResourceKeyProperty =
DependencyProperty.RegisterAttached(
"BackgroundResourceKey",
typeof(string),
typeof(ResourceReferenceHelper),
new PropertyMetadata(null, (d, e) =>
{
if (d is FrameworkElement fe && e.NewValue is string key)
{
fe.SetResourceReference(Control.BackgroundProperty, key);
}
}));
public static void SetBackgroundResourceKey(DependencyObject d, string value) => d.SetValue(BackgroundResourceKeyProperty, value);
public static string GetBackgroundResourceKey(DependencyObject d) => (string)d.GetValue(BackgroundResourceKeyProperty);
}
}

View File

@@ -116,6 +116,25 @@ namespace MaaWpfGui.Helper
return defaultValue;
}
public static int GetGlobalValue(string key, int defaultValue)
{
var value = GetGlobalValue(key, defaultValue.ToString());
return int.TryParse(value, out var result) ? result : defaultValue;
}
public static bool GetGlobalValue(string key, bool defaultValue)
{
var value = GetGlobalValue(key, defaultValue.ToString());
return bool.TryParse(value, out var result) ? result : defaultValue;
}
public static TOut GetGlobalValue<TOut>(string key, TOut defaultValue)
where TOut : struct, Enum
{
var value = GetGlobalValue(key, defaultValue.ToString());
return Enum.TryParse<TOut>(value, out var result) ? result : defaultValue;
}
/// <summary>
/// Set a configuration value
/// </summary>

View File

@@ -170,6 +170,12 @@ namespace MaaWpfGui.Models
return (CheckUpdateRetT.UnknownError, null, null);
}
var mirrorChyanCdkExpired = data["data"]?["cdk_expired_time"]?.ToObject<int?>() ?? null;
if (mirrorChyanCdkExpired.HasValue)
{
SettingsViewModel.VersionUpdateSettings.MirrorChyanCdkExpiredTime = mirrorChyanCdkExpired.Value;
}
var errorCode = data["code"]?.ToObject<MirrorChyanErrorCode>() ?? MirrorChyanErrorCode.Undivided;
if (errorCode != MirrorChyanErrorCode.Success)
{

View File

@@ -321,6 +321,7 @@ You can cancel this popup by clicking the 「{key=Settings} - {key=IssueReport}
<system:String x:Key="MirrorChyanCdkInvalid">The CDK is invalid. Please check if the input is correct.</system:String>
<system:String x:Key="MirrorChyanCdkQuotaExhausted">The CDK has reached the maximum download limit for today. Please try again tomorrow.</system:String>
<system:String x:Key="MirrorChyanCdkMismatched">The CDK type does not match the resource to be downloaded. Please check the CDK's applicable scope.</system:String>
<system:String x:Key="MirrorChyanCdkRemainingDays">CDK expires in {0} days.</system:String>
<system:String x:Key="NewVersionFoundTitle">New Version Found</system:String>
<system:String x:Key="NewVersionFoundDescDownloadingWithGlobalSource">\nDownloading from 「{key=GlobalSource}」...</system:String>
<system:String x:Key="NewVersionFoundDescDownloadingWithMirrorChyan">\nDownloading from 「{key=MirrorChyan}」...</system:String>

View File

@@ -321,6 +321,7 @@
<system:String x:Key="MirrorChyanCdkInvalid">CDK が無効です。入力が正しいか確認してください。</system:String>
<system:String x:Key="MirrorChyanCdkQuotaExhausted">CDK の本日のダウンロード回数が上限に達しました。明日もう一度お試しください。</system:String>
<system:String x:Key="MirrorChyanCdkMismatched">CDK の種類がダウンロード対象のリソースと一致しません。CDK の適用範囲を確認してください。</system:String>
<system:String x:Key="MirrorChyanCdkRemainingDays">CDK の有効期限は残り {0} 日です。</system:String>
<system:String x:Key="NewVersionFoundTitle">新しいバージョンが見つかりました</system:String>
<system:String x:Key="NewVersionFoundDescDownloadingWithGlobalSource">「{key=GlobalSource}」からダウンロード中...</system:String>
<system:String x:Key="NewVersionFoundDescDownloadingWithMirrorChyan">「{key=MirrorChyan}」からダウンロード中...</system:String>

View File

@@ -320,6 +320,7 @@
<system:String x:Key="MirrorChyanCdkInvalid">CDK가 유효하지 않습니다. 입력값이 올바른지 확인해 주세요.</system:String>
<system:String x:Key="MirrorChyanCdkQuotaExhausted">해당 CDK의 일일 다운로드 횟수가 제한에 도달했습니다. 내일 다시 시도해 주세요.</system:String>
<system:String x:Key="MirrorChyanCdkMismatched">CDK 유형이 다운로드할 리소스와 일치하지 않습니다. CDK의 적용 범위를 확인해 주세요.</system:String>
<system:String x:Key="MirrorChyanCdkRemainingDays">CDK 만료까지 {0}일 남았습니다.</system:String>
<system:String x:Key="NewVersionFoundTitle">새로운 버전 확인</system:String>
<system:String x:Key="NewVersionFoundDescDownloadingWithGlobalSource">「{key=GlobalSource}」 에서 다운로드 중...</system:String>
<system:String x:Key="NewVersionFoundDescDownloadingWithMirrorChyan">「{key=MirrorChyan}」 에서 다운로드 중...</system:String>

View File

@@ -321,6 +321,7 @@
<system:String x:Key="MirrorChyanCdkInvalid">CDK 无效,请检查输入是否正确。</system:String>
<system:String x:Key="MirrorChyanCdkQuotaExhausted">CDK 今日下载次数已达上限,请明日再试。</system:String>
<system:String x:Key="MirrorChyanCdkMismatched">CDK 类型与待下载的资源不匹配,请检查 CDK 适用范围。</system:String>
<system:String x:Key="MirrorChyanCdkRemainingDays">CDK 还剩 {0} 天到期。</system:String>
<system:String x:Key="NewVersionFoundTitle">检测到新版本</system:String>
<system:String x:Key="NewVersionFoundDescDownloadingWithGlobalSource">正在使用 「{key=GlobalSource}」 下载……</system:String>
<system:String x:Key="NewVersionFoundDescDownloadingWithMirrorChyan">正在使用 「{key=MirrorChyan}」 下载……</system:String>

View File

@@ -319,6 +319,7 @@
<system:String x:Key="MirrorChyanCdkInvalid">CDK 無效,請檢查輸入是否正確。</system:String>
<system:String x:Key="MirrorChyanCdkQuotaExhausted">CDK 今日下載次數已達上限,請明日再試。</system:String>
<system:String x:Key="MirrorChyanCdkMismatched">CDK 類型與待下載的資源不匹配,請檢查 CDK 適用範圍。</system:String>
<system:String x:Key="MirrorChyanCdkRemainingDays">CDK 還剩 {0} 天到期。</system:String>
<system:String x:Key="NewVersionFoundTitle">檢測到新版本</system:String>
<system:String x:Key="NewVersionFoundDescDownloadingWithGlobalSource">正在使用 「{key=GlobalSource}」 下載…</system:String>
<system:String x:Key="NewVersionFoundDescDownloadingWithMirrorChyan">正在使用 「{key=MirrorChyan}」 下載…</system:String>

View File

@@ -69,6 +69,7 @@
<SolidColorBrush x:Key="MdXamlHyperlinkClicked" Color="#e45649" />
<!-- UiLogColor -->
<SolidColorBrush x:Key="SuccessLogBrush" Color="#90EE90" />
<SolidColorBrush x:Key="ErrorLogBrush" Color="Red" />
<SolidColorBrush x:Key="WarningLogBrush" Color="Goldenrod" />
<SolidColorBrush x:Key="InfoLogBrush" Color="#00C8C8" />

View File

@@ -51,6 +51,7 @@
<!-- UiLogColor -->
<SolidColorBrush x:Key="SuccessLogBrush" Color="Green" />
<SolidColorBrush x:Key="ErrorLogBrush" Color="DarkRed" />
<SolidColorBrush x:Key="WarningLogBrush" Color="DarkGoldenrod" />
<SolidColorBrush x:Key="InfoLogBrush" Color="DarkCyan" />

View File

@@ -1019,6 +1019,12 @@ public class VersionUpdateViewModel : Screen
return CheckUpdateRetT.UnknownError;
}
var mirrorChyanCdkExpired = data["data"]?["cdk_expired_time"]?.ToObject<int?>() ?? null;
if (mirrorChyanCdkExpired.HasValue)
{
SettingsViewModel.VersionUpdateSettings.MirrorChyanCdkExpiredTime = mirrorChyanCdkExpired.Value;
}
var errorCode = data["code"]?.ToObject<MirrorChyanErrorCode>() ?? MirrorChyanErrorCode.Undivided;
if (errorCode != MirrorChyanErrorCode.Success)
{

View File

@@ -20,6 +20,8 @@ using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using JetBrains.Annotations;
using MaaWpfGui.Constants;
using MaaWpfGui.Extensions;
@@ -28,6 +30,7 @@ using MaaWpfGui.Main;
using MaaWpfGui.Models;
using MaaWpfGui.Properties;
using MaaWpfGui.Services;
using MaaWpfGui.Utilities;
using MaaWpfGui.Utilities.ValueType;
using MaaWpfGui.ViewModels.UI;
using Newtonsoft.Json;
@@ -314,6 +317,67 @@ public class VersionUpdateSettingsUserControlModel : PropertyChangedBase
}
}
// 时间戳
private int _mirrorChyanCdkExpiredTime = ConfigurationHelper.GetGlobalValue(ConfigurationKeys.MirrorChyanCdkExpiredTime, 0);
public int MirrorChyanCdkExpiredTime
{
get => _mirrorChyanCdkExpiredTime;
set
{
if (!SetAndNotify(ref _mirrorChyanCdkExpiredTime, value))
{
return;
}
ConfigurationHelper.SetGlobalValue(ConfigurationKeys.MirrorChyanCdkExpiredTime, value.ToString());
}
}
[PropertyDependsOn(nameof(MirrorChyanCdkExpiredTime))]
public DateTime MirrorChyanCdkExpiredDateTime => DateTimeOffset.FromUnixTimeSeconds(MirrorChyanCdkExpiredTime).DateTime.ToLocalTime();
/// <summary>
/// Gets 剩余时间
/// </summary>
public TimeSpan MirrorChyanCdkRemaining => MirrorChyanCdkExpiredDateTime - DateTime.Now;
/// <summary>
/// Gets a value indicating whether 是否已过期
/// </summary>
public bool IsMirrorChyanCdkExpired => MirrorChyanCdkRemaining.TotalSeconds <= 0;
/// <summary>
/// Gets 显示用的剩余时间提示
/// </summary>
public string MirrorChyanCdkRemainingText =>
IsMirrorChyanCdkExpired
? LocalizationHelper.GetString("MirrorChyanCdkExpired")
: string.Format(LocalizationHelper.GetString("MirrorChyanCdkRemainingDays"),
MirrorChyanCdkRemaining.TotalDays.ToString("F1"));
/// <summary>
/// Gets uI 显示用颜色
/// </summary>
[PropertyDependsOn(nameof(MirrorChyanCdkExpiredTime))]
public string MirrorChyanCdkRemainingBrush
{
get
{
if (IsMirrorChyanCdkExpired)
{
return UiLogColor.Error;
}
if (MirrorChyanCdkRemaining.TotalDays <= 7)
{
return UiLogColor.Warning;
}
return UiLogColor.Success;
}
}
private bool _startupUpdateCheck = Convert.ToBoolean(ConfigurationHelper.GetGlobalValue(ConfigurationKeys.StartupUpdateCheck, bool.TrueString));
// UI 绑定的方法

View File

@@ -10,6 +10,7 @@
xmlns:helper="clr-namespace:MaaWpfGui.Helper"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:uiBehaviors="clr-namespace:MaaWpfGui.Extensions.UIBehaviors"
xmlns:viewModels="clr-namespace:MaaWpfGui.ViewModels.UserControl.Settings"
d:Background="White"
d:DataContext="{d:DesignInstance {x:Type viewModels:VersionUpdateSettingsUserControlModel}}"
@@ -138,6 +139,12 @@
Command="{s:Action MirrorChyanCdkCopy}"
Content="{DynamicResource Copy}" />
</Grid>
<controls:TextBlock
MaxWidth="150"
Margin="0,5,0,0"
uiBehaviors:ResourceReferenceHelper.ForegroundResourceKey="{Binding MirrorChyanCdkRemainingBrush}"
Text="{Binding MirrorChyanCdkRemainingText}"
TextWrapping="Wrap" />
</StackPanel>
<controls:TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
<Hyperlink