From a66037f8866e7871fa5a3b70b9c54045f4583d5c Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 26 Jul 2025 16:22:55 +0800 Subject: [PATCH] =?UTF-8?q?improve:=E7=94=A8=E6=88=B7=E4=BD=93=E9=AA=8C?= =?UTF-8?q?=E5=88=86=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Helpers/AutoUpdateHelper.cs | 84 +++++++++++++++++++++++--- Ink Canvas/Helpers/DeviceIdentifier.cs | 62 ++++++++++++------- Ink Canvas/Properties/AssemblyInfo.cs | 4 +- 3 files changed, 119 insertions(+), 31 deletions(-) diff --git a/Ink Canvas/Helpers/AutoUpdateHelper.cs b/Ink Canvas/Helpers/AutoUpdateHelper.cs index 5ba45e18..1c40f70c 100644 --- a/Ink Canvas/Helpers/AutoUpdateHelper.cs +++ b/Ink Canvas/Helpers/AutoUpdateHelper.cs @@ -20,7 +20,7 @@ namespace Ink_Canvas.Helpers { // 定义超时时间为10秒 private static readonly TimeSpan RequestTimeout = TimeSpan.FromSeconds(10); - private static string updatesFolderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "AutoUpdate"); + private static readonly string updatesFolderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "AutoUpdate"); private static string statusFilePath = null; // 线路组结构体(包含版本、下载、日志地址) @@ -395,6 +395,47 @@ namespace Ink_Canvas.Helpers } } + // 通过GitHub API获取指定版本的Release信息 + private static async Task<(string version, string downloadUrl, string releaseNotes, DateTime? releaseTime)> GetGithubReleaseByVersion(string targetVersion, UpdateChannel channel) + { + try + { + string apiUrl = channel == UpdateChannel.Beta + ? "https://api.github.com/repos/InkCanvasForClass/community-beta/releases" + : "https://api.github.com/repos/InkCanvasForClass/community/releases"; + using (var client = new HttpClient()) + { + client.DefaultRequestHeaders.Add("User-Agent", "ICC-CE Auto Updater"); + var response = await client.GetStringAsync(apiUrl); + var releases = JArray.Parse(response); + + foreach (var release in releases) + { + string version = release["tag_name"]?.ToString(); + if (version == targetVersion || version == $"v{targetVersion}" || version == $"V{targetVersion}") + { + string releaseNotes = release["body"]?.ToString(); + string downloadUrl = release["assets"]?.First?["browser_download_url"]?.ToString(); + + // 解析发布时间 + DateTime? releaseTime = null; + if (release["published_at"] != null && DateTime.TryParse(release["published_at"].ToString(), out DateTime parsedTime)) + { + releaseTime = parsedTime; + } + + return (version, downloadUrl, releaseNotes, releaseTime); + } + } + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"AutoUpdate | GitHub Releases API 获取版本 {targetVersion} 失败: {ex.Message}", LogHelper.LogType.Warning); + } + return (null, null, null, null); + } + // 通过GitHub API获取最新Release信息 private static async Task<(string version, string downloadUrl, string releaseNotes, DateTime? releaseTime)> GetLatestGithubRelease(UpdateChannel channel) { @@ -454,17 +495,23 @@ namespace Ink_Canvas.Helpers if (remote > local || alwaysGetRemote) { LogHelper.WriteLogToFile($"AutoUpdate | 通过GitHub Releases API发现新版本: {apiVersion}"); - + // 检查是否应该根据用户优先级推送更新(版本修复功能不受限制) if (!isVersionFix) { DateTime releaseTime = apiReleaseTime ?? DateTime.Now; - bool shouldPush = DeviceIdentifier.ShouldPushUpdate(apiVersion, releaseTime, true); // 明确标记为自动更新 + + // 尝试获取当前版本的发布时间 + DateTime? currentVersionReleaseTime = await GetVersionReleaseTime(localVersion, channel); + + bool shouldPush = DeviceIdentifier.ShouldPushUpdate(apiVersion, releaseTime, true, currentVersionReleaseTime); // 明确标记为自动更新 if (!shouldPush) { var priority = DeviceIdentifier.GetUpdatePriority(); - var daysSinceRelease = (DateTime.Now - releaseTime).TotalDays; - LogHelper.WriteLogToFile($"AutoUpdate | 根据用户优先级({priority}),暂不推送更新 {apiVersion},发布时间: {releaseTime:yyyy-MM-dd HH:mm:ss},已过 {daysSinceRelease:F1} 天"); + var daysBetweenVersions = currentVersionReleaseTime.HasValue + ? (releaseTime - currentVersionReleaseTime.Value).TotalDays + : (DateTime.Now - releaseTime).TotalDays; + LogHelper.WriteLogToFile($"AutoUpdate | 根据用户优先级({priority}),暂不推送更新 {apiVersion},版本间隔: {daysBetweenVersions:F1} 天"); var group = (await GetAvailableLineGroupsOrdered(channel)).FirstOrDefault(); return (null, group, apiReleaseNotes); // 返回null表示不推送 } @@ -506,11 +553,14 @@ namespace Ink_Canvas.Helpers if (remote > local || alwaysGetRemote) { LogHelper.WriteLogToFile($"AutoUpdate | 发现新版本或强制获取: {remoteVersion}"); - + // 检查是否应该根据用户优先级推送更新(版本修复功能不受限制) if (!isVersionFix) { - bool shouldPush = DeviceIdentifier.ShouldPushUpdate(remoteVersion, DateTime.Now, true); // 明确标记为自动更新 + // 尝试获取当前版本的发布时间 + DateTime? currentVersionReleaseTime = await GetVersionReleaseTime(localVersion, channel); + + bool shouldPush = DeviceIdentifier.ShouldPushUpdate(remoteVersion, DateTime.Now, true, currentVersionReleaseTime); // 明确标记为自动更新 if (!shouldPush) { var priority = DeviceIdentifier.GetUpdatePriority(); @@ -1501,6 +1551,26 @@ namespace Ink_Canvas.Helpers } } + /// + /// 获取指定版本的发布时间 + /// + /// 版本号 + /// 更新通道 + /// 版本发布时间,如果获取失败则返回null + public static async Task GetVersionReleaseTime(string version, UpdateChannel channel = UpdateChannel.Release) + { + try + { + var (_, _, _, releaseTime) = await GetGithubReleaseByVersion(version, channel); + return releaseTime; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"AutoUpdate | 获取版本 {version} 发布时间失败: {ex.Message}", LogHelper.LogType.Warning); + return null; + } + } + /// /// 启动手动指定版本的多线路多线程下载并自动安装(用于历史版本回滚等场景) /// diff --git a/Ink Canvas/Helpers/DeviceIdentifier.cs b/Ink Canvas/Helpers/DeviceIdentifier.cs index 4f47f7e6..e1040389 100644 --- a/Ink Canvas/Helpers/DeviceIdentifier.cs +++ b/Ink Canvas/Helpers/DeviceIdentifier.cs @@ -1747,10 +1747,11 @@ namespace Ink_Canvas.Helpers /// 根据优先级决定是否应该推送更新(仅适用于自动更新,版本修复功能不受影响) /// /// 更新版本号 - /// 发布时间 + /// 新版本发布时间 /// 是否为自动更新检查(默认true,false表示版本修复) + /// 当前版本发布时间 /// 是否应该推送更新 - public static bool ShouldPushUpdate(string updateVersion, DateTime releaseTime, bool isAutoUpdate = true) + public static bool ShouldPushUpdate(string updateVersion, DateTime releaseTime, bool isAutoUpdate = true, DateTime? currentVersionReleaseTime = null) { try { @@ -1769,17 +1770,27 @@ namespace Ink_Canvas.Helpers var frequency = GetUsageFrequency(); var stats = LoadUsageStats(); - // 计算发布时间到现在的天数 - var daysSinceRelease = (DateTime.Now - releaseTime).TotalDays; + // 计算版本间的时间差 + double daysBetweenVersions; + if (currentVersionReleaseTime.HasValue) + { + // 使用当前版本发布时间与新版本发布时间的差异 + daysBetweenVersions = (releaseTime - currentVersionReleaseTime.Value).TotalDays; + } + else + { + // 如果没有当前版本发布时间,回退到使用新版本发布时间到现在的天数 + daysBetweenVersions = (DateTime.Now - releaseTime).TotalDays; + } // 计算最近活跃度(最后一次使用距今的天数) var daysSinceLastUse = (DateTime.Now - stats.LastLaunchTime).TotalDays; // 综合判断逻辑(仅适用于自动更新) - var shouldPush = ShouldPushUpdateComprehensive(priority, frequency, daysSinceRelease, daysSinceLastUse, stats, updateType); + var shouldPush = ShouldPushUpdateComprehensive(priority, frequency, daysBetweenVersions, daysSinceLastUse, stats, updateType); LogHelper.WriteLogToFile($"DeviceIdentifier | 自动更新推送判断 - 版本: {updateVersion}, 类型: {updateType}, " + - $"优先级: {priority}, 频率: {frequency}, 发布天数: {daysSinceRelease:F1}, " + + $"优先级: {priority}, 频率: {frequency}, 版本间隔: {daysBetweenVersions:F1}天, " + $"最后使用: {daysSinceLastUse:F1}天前, 结果: {shouldPush}"); return shouldPush; @@ -1844,8 +1855,15 @@ namespace Ink_Canvas.Helpers /// /// 综合时间和使用频率的自动更新推送判断逻辑(不影响版本修复) /// + /// 用户更新优先级 + /// 用户使用频率 + /// 当前版本与新版本之间的天数差异 + /// 距离最后使用的天数 + /// 使用统计数据 + /// 更新类型 + /// 是否应该推送更新 private static bool ShouldPushUpdateComprehensive(UpdatePriority priority, UsageFrequency frequency, - double daysSinceRelease, double daysSinceLastUse, UsageStats stats, UpdateType updateType) + double daysBetweenVersions, double daysSinceLastUse, UsageStats stats, UpdateType updateType) { // 考虑用户的总体使用模式 var isHeavyUser = stats.TotalUsageMinutes > 3000; // 超过50小时的重度用户 @@ -1860,12 +1878,12 @@ namespace Ink_Canvas.Helpers // 热修复和重要更新优先推送 if (updateType == UpdateType.Hotfix) { - return daysSinceRelease >= 1; // 热修复1天后推送 + return daysBetweenVersions >= 1; // 热修复版本间隔1天后推送 } // 但如果是重度用户,仍然要适当推送 var baseDelay = isHeavyUser ? 7 : 14; - return daysSinceRelease >= (baseDelay / urgencyMultiplier); + return daysBetweenVersions >= (baseDelay / urgencyMultiplier); } // 如果用户最近很活跃(3天内使用过) @@ -1880,19 +1898,19 @@ namespace Ink_Canvas.Helpers // 结合使用频率和优先级判断 if (frequency == UsageFrequency.High || isHeavyUser) { - return daysSinceRelease >= Math.Max(0, 1 / urgencyMultiplier); // 高频用户优先推送 + return daysBetweenVersions >= Math.Max(0, 1 / urgencyMultiplier); // 高频用户优先推送 } switch (priority) { case UpdatePriority.High: - return daysSinceRelease >= Math.Max(0, 1 / urgencyMultiplier); + return daysBetweenVersions >= Math.Max(0, 1 / urgencyMultiplier); case UpdatePriority.Medium: - return daysSinceRelease >= Math.Max(1, 2 / urgencyMultiplier); + return daysBetweenVersions >= Math.Max(1, 2 / urgencyMultiplier); case UpdatePriority.Low: - return daysSinceRelease >= Math.Max(2, 3 / urgencyMultiplier); + return daysBetweenVersions >= Math.Max(2, 3 / urgencyMultiplier); } } @@ -1902,25 +1920,25 @@ namespace Ink_Canvas.Helpers // 热修复优先推送 if (updateType == UpdateType.Hotfix) { - return daysSinceRelease >= 1; + return daysBetweenVersions >= 1; } // 频繁用户优先推送 if (isFrequentUser && frequency == UsageFrequency.High) { - return daysSinceRelease >= Math.Max(1, 2 / urgencyMultiplier); + return daysBetweenVersions >= Math.Max(1, 2 / urgencyMultiplier); } switch (priority) { case UpdatePriority.High: - return daysSinceRelease >= Math.Max(1, 2 / urgencyMultiplier); + return daysBetweenVersions >= Math.Max(1, 2 / urgencyMultiplier); case UpdatePriority.Medium: - return daysSinceRelease >= Math.Max(2, 4 / urgencyMultiplier); + return daysBetweenVersions >= Math.Max(2, 4 / urgencyMultiplier); case UpdatePriority.Low: - return daysSinceRelease >= Math.Max(4, 7 / urgencyMultiplier); + return daysBetweenVersions >= Math.Max(4, 7 / urgencyMultiplier); } } @@ -1931,16 +1949,16 @@ namespace Ink_Canvas.Helpers switch (priority) { case UpdatePriority.High: - return daysSinceRelease >= Math.Max(2, 3 * delayMultiplier / urgencyMultiplier); + return daysBetweenVersions >= Math.Max(2, 3 * delayMultiplier / urgencyMultiplier); case UpdatePriority.Medium: - return daysSinceRelease >= Math.Max(4, 7 * delayMultiplier / urgencyMultiplier); + return daysBetweenVersions >= Math.Max(4, 7 * delayMultiplier / urgencyMultiplier); case UpdatePriority.Low: - return daysSinceRelease >= Math.Max(7, 14 * delayMultiplier / urgencyMultiplier); + return daysBetweenVersions >= Math.Max(7, 14 * delayMultiplier / urgencyMultiplier); default: - return daysSinceRelease >= 7; + return daysBetweenVersions >= 7; } } diff --git a/Ink Canvas/Properties/AssemblyInfo.cs b/Ink Canvas/Properties/AssemblyInfo.cs index 35c0f7fb..156b074e 100644 --- a/Ink Canvas/Properties/AssemblyInfo.cs +++ b/Ink Canvas/Properties/AssemblyInfo.cs @@ -49,5 +49,5 @@ using System.Windows; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.7.2.1")] -[assembly: AssemblyFileVersion("1.7.2.1")] +[assembly: AssemblyVersion("1.7.1.14")] +[assembly: AssemblyFileVersion("1.7.1.14")]