From a6fc3aac7649f8a196abe6456d9a9ac5afe40a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 8 Jan 2025 01:21:56 +0800 Subject: [PATCH 01/81] Update README.md --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 45254fb9..e8eb228f 100644 --- a/README.md +++ b/README.md @@ -20,21 +20,28 @@ BetterGI · 更好的原神, 一个基于计算机视觉技术,意图让原神变的更好的项目。 ## 功能 +* 实时任务 * [自动拾取](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E6%8B%BE%E5%8F%96):遇到可交互/拾取内容时自动按 F,支持黑白名单配置 * [自动剧情](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E5%89%A7%E6%83%85):快速点击过剧情、自动选择选项、自动提交物品、关闭弹出书页等 * 与凯瑟琳对话时有橙色选项会 [自动领取「每日委托」奖励](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E9%A2%86%E5%8F%96%E3%80%8E%E6%AF%8F%E6%97%A5%E5%A7%94%E6%89%98%E3%80%8F%E5%A5%96%E5%8A%B1)、[自动重新派遣](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E9%87%8D%E6%96%B0%E6%B4%BE%E9%81%A3) * [自动邀约](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E9%82%80%E7%BA%A6):自动剧情开启的情况下此功能才会生效,自动选择邀约选项 + * [快速传送](http://bgi.huiyadan.com/feats/domain.html):在地图上点击传送点,或者点击后出现的列表中存在传送点,会自动点击传送点并传送 * [全自动钓鱼](https://bgi.huiyadan.com/doc.html#%E5%85%A8%E8%87%AA%E5%8A%A8%E9%92%93%E9%B1%BC):AI 识别自动抛竿,鱼上钩时自动收杆,并自动完成钓鱼进度 * [自动烹饪](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E7%83%B9%E9%A5%AA):自动在完美区域完成食物烹饪,暂不支持“仙跳墙” +* 独立任务 * [全自动七圣召唤](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E4%B8%83%E5%9C%A3%E5%8F%AC%E5%94%A4):帮助你轻松完成七圣召唤角色邀请、每周来客挑战等 PVE 内容 * [自动伐木](http://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E4%BC%90%E6%9C%A8):自动 Z 键使用「王树瑞佑」,利用上下线可以刷新木材的原理,挂机刷满一背包的木材 * [自动战斗](http://bgi.huiyadan.com/feats/domain.html):编写战斗脚本,让队伍按照你的策略进行自动战斗 * [自动秘境](http://bgi.huiyadan.com/feats/domain.html):全自动秘境挂机刷体力,自动循环进入秘境开启钥匙、战斗、走到古树并领取奖励 - * [快速传送](http://bgi.huiyadan.com/feats/domain.html):在地图上点击传送点,或者点击后出现的列表中存在传送点,会自动点击传送点并传送 + * [自定音游](https://bgi.huiyadan.com/feats/task/music.html):全自动秘境挂机刷体力,自动循环进入秘境开启钥匙、战斗、走到古树并领取奖励 +* 全自动 + * 一条龙 + * +* 操控辅助 * [那维莱特转圈](https://bgi.huiyadan.com/doc.html#%E9%82%A3%E7%BB%B4%E8%8E%B1%E7%89%B9-%E8%BD%AC%E5%9C%88%E5%9C%88):设置快捷键后,长按可以不断水平旋转视角(当然你也可以用来转草神) * [快速圣遗物强化](https://bgi.huiyadan.com/doc.html#%E5%9C%A3%E9%81%97%E7%89%A9%E4%B8%80%E9%94%AE%E5%BC%BA%E5%8C%96):通过快速切换“详情”、“强化”页跳过圣遗物强化结果展示,快速+20 * [商店一键购买](https://bgi.huiyadan.com/doc.html#%E5%9C%A3%E9%81%97%E7%89%A9%E4%B8%80%E9%94%AE%E5%BC%BA%E5%8C%96):可以快速以满数量购买商店中的物品,适合快速清空活动兑换,尘歌壶商店兑换等 - * [**……**](https://bgi.huiyadan.com/feat.html) +* [**……**](https://bgi.huiyadan.com/doc.html)
From 50513613ded813544def90fcef43cac706b87d4e Mon Sep 17 00:00:00 2001 From: Scarlet Date: Tue, 21 Jan 2025 22:22:27 -0600 Subject: [PATCH 02/81] feature: notification-based webhook --- .../GameTask/AutoDomain/AutoDomainTask.cs | 16 ++-- .../AutoGeniusInvokation/Model/Duel.cs | 12 ++- .../GameTask/AutoSkip/AutoTrackTask.cs | 2 - BetterGenshinImpact/GameTask/TaskRunner.cs | 27 ++++-- .../Builder/DomainNotificationBuilder.cs | 15 ++++ .../GeniusInvocationNotificationBuilder.cs | 15 ++++ .../Builder/INotificationBuilder.cs | 87 +++++++++++++++++++ .../Builder/INotificationDataBuilder.cs | 8 -- .../Builder/LifecycleNotificationBuilder.cs | 13 --- .../Builder/ScriptNotificationBuilder.cs | 14 +++ .../Builder/TaskNotificationBuilder.cs | 83 +----------------- .../Builder/TestNotificationBuilder.cs | 7 ++ .../Notification/Model/Base/DomainDetails.cs | 9 ++ .../Model/Base/GeniusInvocationDetails.cs | 9 ++ .../Notification/Model/Base/ScriptDetails.cs | 8 ++ .../Notification/Model/Base/TaskDetails.cs | 10 +++ .../Model/DomainNotificationData.cs | 11 +++ .../Model/Enum/NotificationAction.cs | 5 +- .../Model/Enum/NotificationConclusion.cs | 2 +- .../Model/Enum/NotificationEvent.cs | 8 +- .../Notification/Model/Event/BaseEvent.cs | 21 +++++ .../Notification/Model/Event/DomainEvent.cs | 8 ++ .../Model/Event/GeniusInvocationEvent.cs | 8 ++ .../Notification/Model/Event/ScriptEvent.cs | 9 ++ .../Notification/Model/Event/TaskEvent.cs | 8 ++ .../Model/GeniusInvocationNotificationData.cs | 11 +++ .../Notification/Model/INotificationData.cs | 15 +++- .../Model/LifecycleNotificationData.cs | 15 ---- .../Model/ScriptNotificationData.cs | 11 +++ .../Model/TaskNotificationData.cs | 17 +--- .../Model/TestNotificationData.cs | 11 +++ .../Notification/NotificationConfig.cs | 6 ++ .../Notification/NotificationHelper.cs | 56 +++++++++--- .../Notification/NotificationService.cs | 4 +- .../Service/Notifier/NotifierManager.cs | 3 +- BetterGenshinImpact/Service/ScriptService.cs | 16 ++++ .../View/Pages/CommonSettingsPage.xaml | 25 ++++++ 37 files changed, 432 insertions(+), 173 deletions(-) create mode 100644 BetterGenshinImpact/Service/Notification/Builder/DomainNotificationBuilder.cs create mode 100644 BetterGenshinImpact/Service/Notification/Builder/GeniusInvocationNotificationBuilder.cs create mode 100644 BetterGenshinImpact/Service/Notification/Builder/INotificationBuilder.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Builder/INotificationDataBuilder.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Builder/LifecycleNotificationBuilder.cs create mode 100644 BetterGenshinImpact/Service/Notification/Builder/ScriptNotificationBuilder.cs create mode 100644 BetterGenshinImpact/Service/Notification/Builder/TestNotificationBuilder.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/Base/DomainDetails.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/Base/GeniusInvocationDetails.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/Base/ScriptDetails.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/Base/TaskDetails.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/DomainNotificationData.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/Event/BaseEvent.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/Event/DomainEvent.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/Event/GeniusInvocationEvent.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/Event/ScriptEvent.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/Event/TaskEvent.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/GeniusInvocationNotificationData.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Model/LifecycleNotificationData.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/ScriptNotificationData.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/TestNotificationData.cs diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs index 0ebd0030..37b44a64 100644 --- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs +++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs @@ -53,6 +53,8 @@ public class AutoDomainTask : ISoloTask private CancellationToken _ct; + private readonly DomainNotificationBuilderFactory NBFactory = new(); + public AutoDomainTask(AutoDomainParam taskParam) { _taskParam = taskParam; @@ -72,9 +74,10 @@ public class AutoDomainTask : ISoloTask public async Task Start(CancellationToken ct) { _ct = ct; - + Init(); - NotificationHelper.SendTaskNotificationWithScreenshotUsing(b => b.Domain().Started().Build()); // TODO: 通知后续需要删除迁移 + // TODO: 使用exception逻辑让started必有对应的completed + NotificationHelper.Notify(NBFactory.CreateWithDomain(_taskParam).Started().Build()); // 3次复活重试 for (int i = 0; i < 3; i++) @@ -162,11 +165,10 @@ public class AutoDomainTask : ISoloTask Logger.LogInformation("体力已经耗尽,结束自动秘境"); } - NotificationHelper.SendTaskNotificationWithScreenshotUsing(b => b.Domain().Success().Build()); + NotificationHelper.Notify(NBFactory.CreateWithDomain(_taskParam).Success().Build()); break; } - - NotificationHelper.SendTaskNotificationWithScreenshotUsing(b => b.Domain().Progress().Build()); + NotificationHelper.Notify(NBFactory.CreateWithDomain(_taskParam).InProgress().Build()); } } @@ -299,9 +301,9 @@ public class AutoDomainTask : ISoloTask Logger.LogInformation("自动秘境:{Text}", "进入秘境"); // 秘境开门动画 5s await Delay(5000, _ct); - } + } else - { + { await Delay(800, _ct); } } diff --git a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs index 0ec4bc4a..34efc9c6 100644 --- a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs +++ b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs @@ -50,6 +50,8 @@ public class Duel private int _keqingECount = 0; + private readonly GeniusInvocationNotificationBuilderFactory NBFactory = new(); + public async Task RunAsync(CancellationToken ct) { await Task.Run(() => { Run(ct); }, ct); @@ -62,7 +64,7 @@ public class Duel { AutoGeniusInvokationAssets.DestroyInstance(); - NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Started().Build()); // TODO 需要移动 + NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Started().Build()); GeniusInvokationControl.GetInstance().Init(ct); // 对局准备 选择初始手牌 @@ -288,13 +290,14 @@ public class Duel } catch (TaskCanceledException ex) { - NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Cancelled().Build()); + NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Exception(ex.Message).Build()); + NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Failure().Build()); throw; } catch (NormalEndException ex) { _logger.LogInformation("对局结束"); - NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Success().Build()); + NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Success().Build()); throw; } catch (System.Exception ex) @@ -303,7 +306,8 @@ public class Duel { _logger.LogError(ex.StackTrace); } - NotificationHelper.SendTaskNotificationUsing(b => b.GeniusInvocation().Failure().Build()); + NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Exception(ex.Message).Build()); + NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Failure().Build()); throw; } } diff --git a/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs b/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs index 913df4ae..3d1cc4f1 100644 --- a/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs +++ b/BetterGenshinImpact/GameTask/AutoSkip/AutoTrackTask.cs @@ -63,13 +63,11 @@ public class AutoTrackTask(AutoTrackParam param) : BaseIndependentTask catch (NormalEndException e) { Logger.LogInformation("自动追踪中断:" + e.Message); - // NotificationHelper.SendTaskNotificationWithScreenshotUsing(b => b.Domain().Cancelled().Build()); } catch (Exception e) { Logger.LogError(e.Message); Logger.LogDebug(e.StackTrace); - // NotificationHelper.SendTaskNotificationWithScreenshotUsing(b => b.Domain().Failure().Build()); } finally { diff --git a/BetterGenshinImpact/GameTask/TaskRunner.cs b/BetterGenshinImpact/GameTask/TaskRunner.cs index f0902164..39f9f8e2 100644 --- a/BetterGenshinImpact/GameTask/TaskRunner.cs +++ b/BetterGenshinImpact/GameTask/TaskRunner.cs @@ -11,6 +11,8 @@ using BetterGenshinImpact.Helpers; using Wpf.Ui.Violeta.Controls; using static BetterGenshinImpact.GameTask.Common.TaskControl; using BetterGenshinImpact.Service; +using BetterGenshinImpact.Service.Notification; +using BetterGenshinImpact.Service.Notification.Model.Base; namespace BetterGenshinImpact.GameTask; @@ -25,6 +27,8 @@ public class TaskRunner private readonly string _name = string.Empty; + private readonly TaskNotificationBuilderFactory NBFactory = new(); + public TaskRunner() { } @@ -42,6 +46,7 @@ public class TaskRunner public async Task RunCurrentAsync(Func action) { // 加锁 + TaskDetails taskDetails = new(); var hasLock = await TaskSemaphore.WaitAsync(0); if (!hasLock) { @@ -49,6 +54,8 @@ public class TaskRunner return; } + bool isSuccess = false; + NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Started().Build()); try { _logger.LogInformation("→ {Text}", _name + "任务启动!"); @@ -57,17 +64,17 @@ public class TaskRunner Init(); // 发送运行任务通知 - SendNotification(); CancellationContext.Instance.Set(); RunnerContext.Instance.Clear(); await action(); + isSuccess = true; } catch (NormalEndException e) { + NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Exception("任务中断:" + e.Message).Build()); _logger.LogInformation("任务中断:{Msg}", e.Message); - SendNotification(); if (RunnerContext.Instance.IsContinuousRunGroup) { // 连续执行时,抛出异常,终止执行 @@ -77,7 +84,7 @@ public class TaskRunner catch (TaskCanceledException e) { _logger.LogInformation("任务中断:{Msg}", "任务被取消"); - SendNotification(); + NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Exception("任务被取消").Build()); if (RunnerContext.Instance.IsContinuousRunGroup) { // 连续执行时,抛出异常,终止执行 @@ -88,13 +95,20 @@ public class TaskRunner { _logger.LogError(e.Message); _logger.LogDebug(e.StackTrace); - SendNotification(); + NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Exception(e.Message).Build()); } finally { End(); _logger.LogInformation("→ {Text}", _name + "任务结束"); - SendNotification(); + if (isSuccess) + { + NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Success().Build()); + } + else + { + NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Failure().Build()); + } CancellationContext.Instance.Clear(); RunnerContext.Instance.Clear(); @@ -190,7 +204,4 @@ public class TaskRunner } } - public void SendNotification() - { - } } diff --git a/BetterGenshinImpact/Service/Notification/Builder/DomainNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/DomainNotificationBuilder.cs new file mode 100644 index 00000000..2d630342 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Builder/DomainNotificationBuilder.cs @@ -0,0 +1,15 @@ +using BetterGenshinImpact.GameTask.AutoDomain; +using BetterGenshinImpact.Service.Notification.Model; +using BetterGenshinImpact.Service.Notification.Model.Base; + +namespace BetterGenshinImpact.Service.Notification.Builder; + +public class DomainNotificationBuilder : INotificationBuilder +{ + public DomainNotificationBuilder WithDomain(AutoDomainParam domain) + { + _notificationData.Domain = domain; + return this; + } +} + diff --git a/BetterGenshinImpact/Service/Notification/Builder/GeniusInvocationNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/GeniusInvocationNotificationBuilder.cs new file mode 100644 index 00000000..0dbc94ee --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Builder/GeniusInvocationNotificationBuilder.cs @@ -0,0 +1,15 @@ +using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Model; +using BetterGenshinImpact.Service.Notification.Model; +using BetterGenshinImpact.Service.Notification.Model.Base; + +namespace BetterGenshinImpact.Service.Notification.Builder; + +public class GeniusInvocationNotificationBuilder : INotificationBuilder +{ + public GeniusInvocationNotificationBuilder WithGeniusInvocation(Duel geniusInvocation) + { + _notificationData.GeniusInvocation = geniusInvocation; + return this; + } +} + diff --git a/BetterGenshinImpact/Service/Notification/Builder/INotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/INotificationBuilder.cs new file mode 100644 index 00000000..79eef09c --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Builder/INotificationBuilder.cs @@ -0,0 +1,87 @@ +using BetterGenshinImpact.Service.Notification.Model; +using BetterGenshinImpact.Service.Notification.Model.Enum; +using System.Drawing; + +namespace BetterGenshinImpact.Service.Notification.Builder; + +public abstract class INotificationBuilder + where TBuilder : INotificationBuilder + where TNotificationData : INotificationData, new() +{ + protected readonly TNotificationData _notificationData = new(); + + protected TBuilder Self => (TBuilder)this; + + public TBuilder WithEvent(NotificationEvent notificationEvent) + { + _notificationData.Event = notificationEvent; + return Self; + } + + public TBuilder WithAction(NotificationAction action) + { + _notificationData.Action = action; + return Self; + } + + public TBuilder WithConclusion(NotificationConclusion? conclusion) + { + _notificationData.Conclusion = conclusion; + return Self; + } + + public TBuilder Started() + { + return WithAction(NotificationAction.Started); + } + + private TBuilder Completed() // 一个completed任务,需要携带conclusion,故不暴露 + { + return WithAction(NotificationAction.Completed); + } + + public TBuilder Success() + { + return Completed() + .WithConclusion(NotificationConclusion.Success); + } + public TBuilder PartialSuccess() + { + return Completed() + .WithConclusion(NotificationConclusion.PartialSuccess); + } + + public TBuilder Failure() + { + return Completed() + .WithConclusion(NotificationConclusion.Failure); + } + + public TBuilder Exception(string message) + { + return WithAction(NotificationAction.Exception) + .WithMessage(message); + } + + public TBuilder InProgress() + { + return WithAction(NotificationAction.InProgress); + } + + public TBuilder WithScreenshot(Image? screenshot) + { + _notificationData.Screenshot = screenshot; + return Self; + } + + public TBuilder WithMessage(string message) + { + _notificationData.Message = message; + return Self; + } + + public TNotificationData Build() + { + return _notificationData; + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Builder/INotificationDataBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/INotificationDataBuilder.cs deleted file mode 100644 index c1e916a0..00000000 --- a/BetterGenshinImpact/Service/Notification/Builder/INotificationDataBuilder.cs +++ /dev/null @@ -1,8 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Model; - -namespace BetterGenshinImpact.Service.Notification.Builder; - -public interface INotificationDataBuilder where TNotificationData : INotificationData -{ - TNotificationData Build(); -} diff --git a/BetterGenshinImpact/Service/Notification/Builder/LifecycleNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/LifecycleNotificationBuilder.cs deleted file mode 100644 index ba2a2fab..00000000 --- a/BetterGenshinImpact/Service/Notification/Builder/LifecycleNotificationBuilder.cs +++ /dev/null @@ -1,13 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Model; - -namespace BetterGenshinImpact.Service.Notification.Builder; - -public class LifecycleNotificationBuilder : INotificationDataBuilder -{ - private readonly LifecycleNotificationData _notificationData = new(); - - public LifecycleNotificationData Build() - { - return _notificationData; - } -} diff --git a/BetterGenshinImpact/Service/Notification/Builder/ScriptNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/ScriptNotificationBuilder.cs new file mode 100644 index 00000000..83d6c506 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Builder/ScriptNotificationBuilder.cs @@ -0,0 +1,14 @@ +using BetterGenshinImpact.Core.Script.Group; +using BetterGenshinImpact.Service.Notification.Model; +using BetterGenshinImpact.Service.Notification.Model.Base; + +namespace BetterGenshinImpact.Service.Notification.Builder; + +public class ScriptNotificationBuilder : INotificationBuilder +{ + public ScriptNotificationBuilder WithScript(ScriptGroupProject script) + { + _notificationData.Script = script; + return this; + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Builder/TaskNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/TaskNotificationBuilder.cs index 7eb48277..3cea8d4c 100644 --- a/BetterGenshinImpact/Service/Notification/Builder/TaskNotificationBuilder.cs +++ b/BetterGenshinImpact/Service/Notification/Builder/TaskNotificationBuilder.cs @@ -1,88 +1,13 @@ using BetterGenshinImpact.Service.Notification.Model; -using BetterGenshinImpact.Service.Notification.Model.Enum; -using System.Drawing; +using BetterGenshinImpact.Service.Notification.Model.Base; namespace BetterGenshinImpact.Service.Notification.Builder; -public class TaskNotificationBuilder : INotificationDataBuilder +public class TaskNotificationBuilder : INotificationBuilder { - private readonly TaskNotificationData _notificationData = new(); - - public TaskNotificationBuilder WithEvent(NotificationEvent notificationEvent) - { - _notificationData.Event = notificationEvent; - return this; - } - - public TaskNotificationBuilder WithAction(NotificationAction notificationAction) - { - _notificationData.Action = notificationAction; - return this; - } - - public TaskNotificationBuilder WithConclusion(NotificationConclusion? conclusion) - { - _notificationData.Conclusion = conclusion; - return this; - } - - public TaskNotificationBuilder GeniusInvocation() - { - return WithEvent(NotificationEvent.GeniusInvocation); - } - - public TaskNotificationBuilder Domain() - { - return WithEvent(NotificationEvent.Domain); - } - - public TaskNotificationBuilder Started() - { - return WithAction(NotificationAction.Started); - } - - public TaskNotificationBuilder Completed() - { - return WithAction(NotificationAction.Completed); - } - - public TaskNotificationBuilder Progress() - { - return WithAction(NotificationAction.Progress); - } - - public TaskNotificationBuilder Success() - { - return WithAction(NotificationAction.Completed) - .WithConclusion(NotificationConclusion.Success); - } - - public TaskNotificationBuilder Failure() - { - return WithAction(NotificationAction.Completed) - .WithConclusion(NotificationConclusion.Failure); - } - - public TaskNotificationBuilder Cancelled() - { - return WithAction(NotificationAction.Completed) - .WithConclusion(NotificationConclusion.Cancelled); - } - - public TaskNotificationBuilder WithScreenshot(Image? screenshot) - { - _notificationData.Screenshot = screenshot; - return this; - } - - public TaskNotificationBuilder AddTask(object task) + public TaskNotificationBuilder WithTask(TaskDetails task) { _notificationData.Task = task; return this; } - - public TaskNotificationData Build() - { - return _notificationData; - } -} +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Builder/TestNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/TestNotificationBuilder.cs new file mode 100644 index 00000000..121c8648 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Builder/TestNotificationBuilder.cs @@ -0,0 +1,7 @@ +using BetterGenshinImpact.Service.Notification.Model; + +namespace BetterGenshinImpact.Service.Notification.Builder; + +public class TestNotificationBuilder : INotificationBuilder +{ +} diff --git a/BetterGenshinImpact/Service/Notification/Model/Base/DomainDetails.cs b/BetterGenshinImpact/Service/Notification/Model/Base/DomainDetails.cs new file mode 100644 index 00000000..e1652052 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/Base/DomainDetails.cs @@ -0,0 +1,9 @@ +namespace BetterGenshinImpact.Service.Notification.Model.Base; + +// TODO: 需要制定标准 (currently not referenced) +public class DomainDetails +{ + public string DomainName { get; set; } = string.Empty; + public int RunCount { get; set; } + public string RewardStatus { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Base/GeniusInvocationDetails.cs b/BetterGenshinImpact/Service/Notification/Model/Base/GeniusInvocationDetails.cs new file mode 100644 index 00000000..542c0162 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/Base/GeniusInvocationDetails.cs @@ -0,0 +1,9 @@ +namespace BetterGenshinImpact.Service.Notification.Model.Base; + +// TODO: 需要制定标准 (currently not referenced) +public class GeniusInvocationDetails +{ + public string GameState { get; set; } = string.Empty; + public int RoundNumber { get; set; } + public string OpponentName { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Base/ScriptDetails.cs b/BetterGenshinImpact/Service/Notification/Model/Base/ScriptDetails.cs new file mode 100644 index 00000000..be91c330 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/Base/ScriptDetails.cs @@ -0,0 +1,8 @@ +namespace BetterGenshinImpact.Service.Notification.Model.Base; + +// TODO: 需要制定标准 (currently not referenced) +public class ScriptDetails +{ + public string ScriptName { get; set; } = string.Empty; + public string ScriptPath { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Base/TaskDetails.cs b/BetterGenshinImpact/Service/Notification/Model/Base/TaskDetails.cs new file mode 100644 index 00000000..6ae08668 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/Base/TaskDetails.cs @@ -0,0 +1,10 @@ +using System; + +namespace BetterGenshinImpact.Service.Notification.Model.Base; + +// TODO: 需要制定标准,目前瞎写的 +public class TaskDetails +{ + public Guid Id { get; set; } = Guid.NewGuid(); + public DateTime StartTime { get; set; } = DateTime.Now; +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/DomainNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/DomainNotificationData.cs new file mode 100644 index 00000000..99851082 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/DomainNotificationData.cs @@ -0,0 +1,11 @@ +using BetterGenshinImpact.GameTask.AutoDomain; +using BetterGenshinImpact.Service.Notification.Model.Base; +using BetterGenshinImpact.Service.Notification.Model.Enum; +using System.Text.Json.Serialization; + +namespace BetterGenshinImpact.Service.Notification.Model; + +public class DomainNotificationData : INotificationData +{ + public AutoDomainParam? Domain { get; set; } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs index 21c0fba3..3df23915 100644 --- a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs +++ b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs @@ -1,8 +1,11 @@ namespace BetterGenshinImpact.Service.Notification.Model.Enum; +// 希望一个Started对应且只能对应一个Completed +// 但enforce这个是否必要? public enum NotificationAction { Started, Completed, - Progress + InProgress, + Exception, } diff --git a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationConclusion.cs b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationConclusion.cs index b978165b..83bf5bbd 100644 --- a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationConclusion.cs +++ b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationConclusion.cs @@ -4,5 +4,5 @@ public enum NotificationConclusion { Success, Failure, - Cancelled + PartialSuccess, // 还没想好怎么用,先放在这里 } diff --git a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs index dd3d3fe1..a27313ab 100644 --- a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs +++ b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs @@ -2,7 +2,9 @@ public enum NotificationEvent { - Test, - GeniusInvocation, - Domain + Test, //测试 + GeniusInvocation, //七圣召唤 + Domain, //副本 + Script, //路径追踪脚本 + Task, //宏观上的任务 } diff --git a/BetterGenshinImpact/Service/Notification/Model/Event/BaseEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Event/BaseEvent.cs new file mode 100644 index 00000000..bba6515b --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/Event/BaseEvent.cs @@ -0,0 +1,21 @@ +using BetterGenshinImpact.Service.Notification.Converter; +using BetterGenshinImpact.Service.Notification.Model.Enum; +using System.Drawing; +using System.Text.Json.Serialization; + +namespace BetterGenshinImpact.Service.Notification.Model.Event; + +public abstract class BaseEvent +{ + [JsonConverter(typeof(JsonStringEnumConverter))] + public NotificationEvent EventType { get; set; } + + [JsonConverter(typeof(JsonStringEnumConverter))] + public NotificationAction Action { get; set; } + + [JsonConverter(typeof(JsonStringEnumConverter))] + public NotificationConclusion? Conclusion { get; set; } + + [JsonConverter(typeof(ImageToBase64Converter))] + public Image? Screenshot { get; set; } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Event/DomainEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Event/DomainEvent.cs new file mode 100644 index 00000000..271a143c --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/Event/DomainEvent.cs @@ -0,0 +1,8 @@ +using BetterGenshinImpact.Service.Notification.Model.Base; + +namespace BetterGenshinImpact.Service.Notification.Model.Event; + +public class DomainEvent : BaseEvent +{ + public DomainDetails? Domain { get; set; } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Event/GeniusInvocationEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Event/GeniusInvocationEvent.cs new file mode 100644 index 00000000..772a2380 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/Event/GeniusInvocationEvent.cs @@ -0,0 +1,8 @@ +using BetterGenshinImpact.Service.Notification.Model.Base; + +namespace BetterGenshinImpact.Service.Notification.Model.Event; + +public class GeniusInvocationEvent : BaseEvent +{ + public GeniusInvocationDetails? GeniusInvocation { get; set; } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Event/ScriptEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Event/ScriptEvent.cs new file mode 100644 index 00000000..a4d30615 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/Event/ScriptEvent.cs @@ -0,0 +1,9 @@ +using BetterGenshinImpact.Core.Script.Group; +using BetterGenshinImpact.Service.Notification.Model.Base; + +namespace BetterGenshinImpact.Service.Notification.Model.Event; + +public class ScriptEvent : BaseEvent +{ + public ScriptGroupProject? Script { get; set; } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Event/TaskEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Event/TaskEvent.cs new file mode 100644 index 00000000..7e70bff3 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/Event/TaskEvent.cs @@ -0,0 +1,8 @@ +using BetterGenshinImpact.Service.Notification.Model.Base; + +namespace BetterGenshinImpact.Service.Notification.Model.Event; + +public class TaskEvent : BaseEvent +{ + public TaskDetails? Task { get; set; } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/GeniusInvocationNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/GeniusInvocationNotificationData.cs new file mode 100644 index 00000000..1a9e94e0 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/GeniusInvocationNotificationData.cs @@ -0,0 +1,11 @@ +using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Model; +using BetterGenshinImpact.Service.Notification.Model.Base; +using BetterGenshinImpact.Service.Notification.Model.Enum; +using System.Text.Json.Serialization; + +namespace BetterGenshinImpact.Service.Notification.Model; + +public class GeniusInvocationNotificationData : INotificationData +{ + public Duel? GeniusInvocation { get; set; } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs index 94f80910..cbbbbec6 100644 --- a/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs +++ b/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs @@ -1,10 +1,23 @@ using BetterGenshinImpact.Service.Notification.Model.Enum; using System.Text.Json.Serialization; +using System.Drawing; +using BetterGenshinImpact.Service.Notification.Converter; namespace BetterGenshinImpact.Service.Notification.Model; -public interface INotificationData +public abstract class INotificationData { [JsonConverter(typeof(JsonStringEnumConverter))] public NotificationEvent Event { get; set; } + + [JsonConverter(typeof(JsonStringEnumConverter))] + public NotificationAction Action { get; set; } + + [JsonConverter(typeof(JsonStringEnumConverter))] + public NotificationConclusion? Conclusion { get; set; } + + [JsonConverter(typeof(ImageToBase64Converter))] + public Image? Screenshot { get; set; } + + public string? Message { get; set; } } diff --git a/BetterGenshinImpact/Service/Notification/Model/LifecycleNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/LifecycleNotificationData.cs deleted file mode 100644 index 84c20a98..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/LifecycleNotificationData.cs +++ /dev/null @@ -1,15 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Model.Enum; -using System.Text.Json.Serialization; - -namespace BetterGenshinImpact.Service.Notification.Model; - -public record LifecycleNotificationData : INotificationData -{ - [JsonConverter(typeof(JsonStringEnumConverter))] - public NotificationEvent Event { get; set; } - - public static LifecycleNotificationData Test() - { - return new LifecycleNotificationData() { Event = NotificationEvent.Test }; - } -} diff --git a/BetterGenshinImpact/Service/Notification/Model/ScriptNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/ScriptNotificationData.cs new file mode 100644 index 00000000..37577268 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/ScriptNotificationData.cs @@ -0,0 +1,11 @@ +using BetterGenshinImpact.Core.Script.Group; +using BetterGenshinImpact.Service.Notification.Model.Base; +using BetterGenshinImpact.Service.Notification.Model.Enum; +using System.Text.Json.Serialization; + +namespace BetterGenshinImpact.Service.Notification.Model; + +public class ScriptNotificationData : INotificationData +{ + public ScriptGroupProject? Script { get; set; } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/TaskNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/TaskNotificationData.cs index ccce1d08..66e3520f 100644 --- a/BetterGenshinImpact/Service/Notification/Model/TaskNotificationData.cs +++ b/BetterGenshinImpact/Service/Notification/Model/TaskNotificationData.cs @@ -2,22 +2,11 @@ using BetterGenshinImpact.Service.Notification.Model.Enum; using System.Drawing; using System.Text.Json.Serialization; +using BetterGenshinImpact.Service.Notification.Model.Base; namespace BetterGenshinImpact.Service.Notification.Model; -public record TaskNotificationData : INotificationData +public class TaskNotificationData : INotificationData { - [JsonConverter(typeof(JsonStringEnumConverter))] - public NotificationEvent Event { get; set; } - - [JsonConverter(typeof(JsonStringEnumConverter))] - public NotificationAction Action { get; set; } - - [JsonConverter(typeof(JsonStringEnumConverter))] - public NotificationConclusion? Conclusion { get; set; } - - [JsonConverter(typeof(ImageToBase64Converter))] - public Image? Screenshot { get; set; } - - public object? Task { get; set; } + public TaskDetails? Task { get; set; } } diff --git a/BetterGenshinImpact/Service/Notification/Model/TestNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/TestNotificationData.cs new file mode 100644 index 00000000..387d83ce --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/TestNotificationData.cs @@ -0,0 +1,11 @@ +using BetterGenshinImpact.Service.Notification.Converter; +using BetterGenshinImpact.Service.Notification.Model.Enum; +using System.Drawing; +using System.Text.Json.Serialization; +using BetterGenshinImpact.Service.Notification.Model.Base; + +namespace BetterGenshinImpact.Service.Notification.Model; + +public class TestNotificationData : INotificationData +{ +} diff --git a/BetterGenshinImpact/Service/Notification/NotificationConfig.cs b/BetterGenshinImpact/Service/Notification/NotificationConfig.cs index 280b62de..f8826963 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationConfig.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationConfig.cs @@ -20,4 +20,10 @@ public partial class NotificationConfig : ObservableObject /// [ObservableProperty] private string _webhookEndpoint = string.Empty; + + /// + /// 是否包含截图 + /// + [ObservableProperty] + private bool _includeScreenShot = false; } diff --git a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs index 11b07598..5c556ba2 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs @@ -1,8 +1,13 @@ -using BetterGenshinImpact.GameTask.Common; +using System.Drawing; +using BetterGenshinImpact.Core.Config; +using BetterGenshinImpact.Core.Script.Group; +using BetterGenshinImpact.GameTask.AutoDomain; +using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Model; +using BetterGenshinImpact.GameTask.Common; using BetterGenshinImpact.Service.Notification.Builder; using BetterGenshinImpact.Service.Notification.Model; -using System; -using System.Drawing; +using BetterGenshinImpact.Service.Notification.Model.Base; +using BetterGenshinImpact.Service.Notification.Model.Enum; namespace BetterGenshinImpact.Service.Notification; @@ -10,19 +15,44 @@ public class NotificationHelper { public static void Notify(INotificationData notificationData) { + if (NotificationService.Instance().Config.NotificationConfig.IncludeScreenShot)// TODO: 这个获取方式是否合理? + { + var screenShot = (Bitmap)TaskControl.CaptureToRectArea().SrcBitmap.Clone(); + notificationData.Screenshot = screenShot; + } NotificationService.Instance().NotifyAllNotifiers(notificationData); } +} - public static void SendTaskNotificationUsing(Func builderFunc) +public class ScriptNotificationBuilderFactory +{ + public ScriptNotificationBuilder CreateWithScript(ScriptGroupProject script) { - var builder = new TaskNotificationBuilder(); - Notify(builderFunc(builder)); - } - - public static void SendTaskNotificationWithScreenshotUsing(Func builderFunc) - { - var builder = new TaskNotificationBuilder(); - var screenShot = (Bitmap)TaskControl.CaptureToRectArea().SrcBitmap.Clone(); - Notify(builderFunc(builder.WithScreenshot(screenShot))); + return new ScriptNotificationBuilder().WithEvent(NotificationEvent.Script).WithScript(script); } } + +public class TaskNotificationBuilderFactory +{ + public TaskNotificationBuilder CreateWithTask(TaskDetails task) + { + return new TaskNotificationBuilder().WithEvent(NotificationEvent.Task).WithTask(task); + } +} + +public class GeniusInvocationNotificationBuilderFactory +{ + public GeniusInvocationNotificationBuilder CreateWithGeniusInvocation(Duel geniusInvocation) + { + return new GeniusInvocationNotificationBuilder().WithEvent(NotificationEvent.GeniusInvocation).WithGeniusInvocation(geniusInvocation); + } +} + +public class DomainNotificationBuilderFactory +{ + public DomainNotificationBuilder CreateWithDomain(AutoDomainParam domain) + { + return new DomainNotificationBuilder().WithEvent(NotificationEvent.Domain).WithDomain(domain); + } +} + diff --git a/BetterGenshinImpact/Service/Notification/NotificationService.cs b/BetterGenshinImpact/Service/Notification/NotificationService.cs index 94da9bd1..bec2b048 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationService.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationService.cs @@ -20,7 +20,7 @@ public class NotificationService : IHostedService private static readonly HttpClient _httpClient = new(); private readonly NotifierManager _notifierManager; - private AllConfig Config { get; set; } + public AllConfig Config { get; set; } //TODO:除了public以外还能怎么获取这个Config? public NotificationService(IConfigService configService, NotifierManager notifierManager) { @@ -83,7 +83,7 @@ public class NotificationService : IHostedService { return NotificationTestResult.Error("通知类型未启用"); } - await notifier.SendNotificationAsync(TransformData(LifecycleNotificationData.Test())); + await notifier.SendNotificationAsync(TransformData(new TestNotificationData())); return NotificationTestResult.Success(); } catch (NotifierException ex) diff --git a/BetterGenshinImpact/Service/Notifier/NotifierManager.cs b/BetterGenshinImpact/Service/Notifier/NotifierManager.cs index cf8e632f..50034109 100644 --- a/BetterGenshinImpact/Service/Notifier/NotifierManager.cs +++ b/BetterGenshinImpact/Service/Notifier/NotifierManager.cs @@ -46,8 +46,7 @@ public class NotifierManager } catch (System.Exception ex) { - Logger.LogError("{name} 通知发送失败", notifier.Name); - Debug.WriteLine(ex); + Logger.LogWarning("{name} 通知发送失败: {ex}", notifier.Name, ex.Message); } } diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index 02acc783..9e5cb523 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -15,6 +15,7 @@ using System.Threading.Tasks; using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception; using BetterGenshinImpact.GameTask.Common; using BetterGenshinImpact.GameTask.Common.BgiVision; +using BetterGenshinImpact.Service.Notification; namespace BetterGenshinImpact.Service; @@ -22,6 +23,7 @@ public partial class ScriptService : IScriptService { private readonly ILogger _logger = App.GetLogger(); + private readonly ScriptNotificationBuilderFactory NBFactory = new(); public async Task RunMulti(IEnumerable projectList, string? groupName = null) { groupName ??= "默认"; @@ -73,8 +75,10 @@ public partial class ScriptService : IScriptService for (var i = 0; i < project.RunNum; i++) { + bool isSuccess = false; try { + NotificationHelper.Notify(NBFactory.CreateWithScript(project).Started().Build()); if (hasTimer) { TaskTriggerDispatcher.Instance().ClearTriggers(); @@ -85,20 +89,24 @@ public partial class ScriptService : IScriptService stopwatch.Reset(); stopwatch.Start(); await ExecuteProject(project); + isSuccess = true; } catch (NormalEndException e) { + NotificationHelper.Notify(NBFactory.CreateWithScript(project).Exception(e.Message).Build()); throw; } catch (TaskCanceledException e) { _logger.LogInformation("取消执行配置组: {Msg}", e.Message); + NotificationHelper.Notify(NBFactory.CreateWithScript(project).Exception("取消执行配置组: " + e.Message).Build()); throw; } catch (Exception e) { _logger.LogDebug(e, "执行脚本时发生异常"); _logger.LogError("执行脚本时发生异常: {Msg}", e.Message); + NotificationHelper.Notify(NBFactory.CreateWithScript(project).Exception("执行脚本时发生异常: " + e.Message).Build()); } finally { @@ -108,6 +116,14 @@ public partial class ScriptService : IScriptService _logger.LogInformation("→ 脚本执行结束: {Name}, 耗时: {Minutes}分{Seconds:0.000}秒", project.Name, elapsedTime.Hours * 60 + elapsedTime.Minutes, elapsedTime.TotalSeconds % 60); _logger.LogInformation("------------------------------"); + if (isSuccess) + { + NotificationHelper.Notify(NBFactory.CreateWithScript(project).Success().Build()); + } + else + { + NotificationHelper.Notify(NBFactory.CreateWithScript(project).Failure().Build()); + } } await Task.Delay(2000); diff --git a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml index 4465f2b9..a1919e35 100644 --- a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml @@ -530,6 +530,31 @@ Text="{Binding WebhookStatus}" TextWrapping="Wrap" /> + + + + + + + + + + + + + From ec7ecbf9e0ace516164b9427ccb752b35818f790 Mon Sep 17 00:00:00 2001 From: Scarlet Date: Tue, 21 Jan 2025 22:54:51 -0600 Subject: [PATCH 03/81] remove unused references --- .../Notification/Model/Event/BaseEvent.cs | 21 ------------------- .../Notification/Model/Event/DomainEvent.cs | 8 ------- .../Model/Event/GeniusInvocationEvent.cs | 8 ------- .../Notification/Model/Event/ScriptEvent.cs | 9 -------- .../Notification/Model/Event/TaskEvent.cs | 8 ------- 5 files changed, 54 deletions(-) delete mode 100644 BetterGenshinImpact/Service/Notification/Model/Event/BaseEvent.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Model/Event/DomainEvent.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Model/Event/GeniusInvocationEvent.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Model/Event/ScriptEvent.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Model/Event/TaskEvent.cs diff --git a/BetterGenshinImpact/Service/Notification/Model/Event/BaseEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Event/BaseEvent.cs deleted file mode 100644 index bba6515b..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/Event/BaseEvent.cs +++ /dev/null @@ -1,21 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Converter; -using BetterGenshinImpact.Service.Notification.Model.Enum; -using System.Drawing; -using System.Text.Json.Serialization; - -namespace BetterGenshinImpact.Service.Notification.Model.Event; - -public abstract class BaseEvent -{ - [JsonConverter(typeof(JsonStringEnumConverter))] - public NotificationEvent EventType { get; set; } - - [JsonConverter(typeof(JsonStringEnumConverter))] - public NotificationAction Action { get; set; } - - [JsonConverter(typeof(JsonStringEnumConverter))] - public NotificationConclusion? Conclusion { get; set; } - - [JsonConverter(typeof(ImageToBase64Converter))] - public Image? Screenshot { get; set; } -} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Event/DomainEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Event/DomainEvent.cs deleted file mode 100644 index 271a143c..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/Event/DomainEvent.cs +++ /dev/null @@ -1,8 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Model.Base; - -namespace BetterGenshinImpact.Service.Notification.Model.Event; - -public class DomainEvent : BaseEvent -{ - public DomainDetails? Domain { get; set; } -} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Event/GeniusInvocationEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Event/GeniusInvocationEvent.cs deleted file mode 100644 index 772a2380..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/Event/GeniusInvocationEvent.cs +++ /dev/null @@ -1,8 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Model.Base; - -namespace BetterGenshinImpact.Service.Notification.Model.Event; - -public class GeniusInvocationEvent : BaseEvent -{ - public GeniusInvocationDetails? GeniusInvocation { get; set; } -} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Event/ScriptEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Event/ScriptEvent.cs deleted file mode 100644 index a4d30615..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/Event/ScriptEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using BetterGenshinImpact.Core.Script.Group; -using BetterGenshinImpact.Service.Notification.Model.Base; - -namespace BetterGenshinImpact.Service.Notification.Model.Event; - -public class ScriptEvent : BaseEvent -{ - public ScriptGroupProject? Script { get; set; } -} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Event/TaskEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Event/TaskEvent.cs deleted file mode 100644 index 7e70bff3..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/Event/TaskEvent.cs +++ /dev/null @@ -1,8 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Model.Base; - -namespace BetterGenshinImpact.Service.Notification.Model.Event; - -public class TaskEvent : BaseEvent -{ - public TaskDetails? Task { get; set; } -} \ No newline at end of file From 2181e74a30b11b2660a0989a3480b103073fb238 Mon Sep 17 00:00:00 2001 From: Scarlet Date: Tue, 21 Jan 2025 23:42:31 -0600 Subject: [PATCH 04/81] feat: unify factories; allow creating from actual params to instantiate a builder --- .../GameTask/AutoDomain/AutoDomainTask.cs | 8 +++----- .../AutoGeniusInvokation/Model/Duel.cs | 14 ++++++------- BetterGenshinImpact/GameTask/TaskRunner.cs | 15 ++++++-------- .../Notification/NotificationHelper.cs | 20 +++++-------------- BetterGenshinImpact/Service/ScriptService.cs | 13 ++++++------ 5 files changed, 26 insertions(+), 44 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs index 37b44a64..a5e14018 100644 --- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs +++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs @@ -53,8 +53,6 @@ public class AutoDomainTask : ISoloTask private CancellationToken _ct; - private readonly DomainNotificationBuilderFactory NBFactory = new(); - public AutoDomainTask(AutoDomainParam taskParam) { _taskParam = taskParam; @@ -77,7 +75,7 @@ public class AutoDomainTask : ISoloTask Init(); // TODO: 使用exception逻辑让started必有对应的completed - NotificationHelper.Notify(NBFactory.CreateWithDomain(_taskParam).Started().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(_taskParam).Started().Build()); // 3次复活重试 for (int i = 0; i < 3; i++) @@ -165,10 +163,10 @@ public class AutoDomainTask : ISoloTask Logger.LogInformation("体力已经耗尽,结束自动秘境"); } - NotificationHelper.Notify(NBFactory.CreateWithDomain(_taskParam).Success().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(_taskParam).Success().Build()); break; } - NotificationHelper.Notify(NBFactory.CreateWithDomain(_taskParam).InProgress().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(_taskParam).InProgress().Build()); } } diff --git a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs index 34efc9c6..4d0358c4 100644 --- a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs +++ b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs @@ -50,8 +50,6 @@ public class Duel private int _keqingECount = 0; - private readonly GeniusInvocationNotificationBuilderFactory NBFactory = new(); - public async Task RunAsync(CancellationToken ct) { await Task.Run(() => { Run(ct); }, ct); @@ -64,7 +62,7 @@ public class Duel { AutoGeniusInvokationAssets.DestroyInstance(); - NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Started().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Started().Build()); GeniusInvokationControl.GetInstance().Init(ct); // 对局准备 选择初始手牌 @@ -290,14 +288,14 @@ public class Duel } catch (TaskCanceledException ex) { - NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Exception(ex.Message).Build()); - NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Failure().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Exception(ex.Message).Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Failure().Build()); throw; } catch (NormalEndException ex) { _logger.LogInformation("对局结束"); - NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Success().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Success().Build()); throw; } catch (System.Exception ex) @@ -306,8 +304,8 @@ public class Duel { _logger.LogError(ex.StackTrace); } - NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Exception(ex.Message).Build()); - NotificationHelper.Notify(NBFactory.CreateWithGeniusInvocation(this).Failure().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Exception(ex.Message).Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Failure().Build()); throw; } } diff --git a/BetterGenshinImpact/GameTask/TaskRunner.cs b/BetterGenshinImpact/GameTask/TaskRunner.cs index 39f9f8e2..54d0d67d 100644 --- a/BetterGenshinImpact/GameTask/TaskRunner.cs +++ b/BetterGenshinImpact/GameTask/TaskRunner.cs @@ -27,8 +27,6 @@ public class TaskRunner private readonly string _name = string.Empty; - private readonly TaskNotificationBuilderFactory NBFactory = new(); - public TaskRunner() { } @@ -53,9 +51,8 @@ public class TaskRunner _logger.LogError("任务启动失败:当前存在正在运行中的独立任务,请不要重复执行任务!"); return; } - bool isSuccess = false; - NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Started().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Started().Build()); try { _logger.LogInformation("→ {Text}", _name + "任务启动!"); @@ -73,7 +70,7 @@ public class TaskRunner } catch (NormalEndException e) { - NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Exception("任务中断:" + e.Message).Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Exception("任务中断:" + e.Message).Build()); _logger.LogInformation("任务中断:{Msg}", e.Message); if (RunnerContext.Instance.IsContinuousRunGroup) { @@ -84,7 +81,7 @@ public class TaskRunner catch (TaskCanceledException e) { _logger.LogInformation("任务中断:{Msg}", "任务被取消"); - NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Exception("任务被取消").Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Exception("任务被取消").Build()); if (RunnerContext.Instance.IsContinuousRunGroup) { // 连续执行时,抛出异常,终止执行 @@ -95,7 +92,7 @@ public class TaskRunner { _logger.LogError(e.Message); _logger.LogDebug(e.StackTrace); - NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Exception(e.Message).Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Exception(e.Message).Build()); } finally { @@ -103,11 +100,11 @@ public class TaskRunner _logger.LogInformation("→ {Text}", _name + "任务结束"); if (isSuccess) { - NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Success().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Success().Build()); } else { - NotificationHelper.Notify(NBFactory.CreateWithTask(taskDetails).Failure().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Failure().Build()); } CancellationContext.Instance.Clear(); diff --git a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs index 5c556ba2..3168dbfa 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs @@ -24,35 +24,25 @@ public class NotificationHelper } } -public class ScriptNotificationBuilderFactory +public class NotificationBuilderFactory { - public ScriptNotificationBuilder CreateWithScript(ScriptGroupProject script) + public static ScriptNotificationBuilder CreateWith(ScriptGroupProject script) { return new ScriptNotificationBuilder().WithEvent(NotificationEvent.Script).WithScript(script); } -} -public class TaskNotificationBuilderFactory -{ - public TaskNotificationBuilder CreateWithTask(TaskDetails task) + public static TaskNotificationBuilder CreateWith(TaskDetails task) { return new TaskNotificationBuilder().WithEvent(NotificationEvent.Task).WithTask(task); } -} -public class GeniusInvocationNotificationBuilderFactory -{ - public GeniusInvocationNotificationBuilder CreateWithGeniusInvocation(Duel geniusInvocation) + public static GeniusInvocationNotificationBuilder CreateWith(Duel geniusInvocation) { return new GeniusInvocationNotificationBuilder().WithEvent(NotificationEvent.GeniusInvocation).WithGeniusInvocation(geniusInvocation); } -} -public class DomainNotificationBuilderFactory -{ - public DomainNotificationBuilder CreateWithDomain(AutoDomainParam domain) + public static DomainNotificationBuilder CreateWith(AutoDomainParam domain) { return new DomainNotificationBuilder().WithEvent(NotificationEvent.Domain).WithDomain(domain); } } - diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index 9e5cb523..f7e35fdb 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -23,7 +23,6 @@ public partial class ScriptService : IScriptService { private readonly ILogger _logger = App.GetLogger(); - private readonly ScriptNotificationBuilderFactory NBFactory = new(); public async Task RunMulti(IEnumerable projectList, string? groupName = null) { groupName ??= "默认"; @@ -78,7 +77,7 @@ public partial class ScriptService : IScriptService bool isSuccess = false; try { - NotificationHelper.Notify(NBFactory.CreateWithScript(project).Started().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Started().Build()); if (hasTimer) { TaskTriggerDispatcher.Instance().ClearTriggers(); @@ -93,20 +92,20 @@ public partial class ScriptService : IScriptService } catch (NormalEndException e) { - NotificationHelper.Notify(NBFactory.CreateWithScript(project).Exception(e.Message).Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Exception(e.Message).Build()); throw; } catch (TaskCanceledException e) { _logger.LogInformation("取消执行配置组: {Msg}", e.Message); - NotificationHelper.Notify(NBFactory.CreateWithScript(project).Exception("取消执行配置组: " + e.Message).Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Exception("取消执行配置组: " + e.Message).Build()); throw; } catch (Exception e) { _logger.LogDebug(e, "执行脚本时发生异常"); _logger.LogError("执行脚本时发生异常: {Msg}", e.Message); - NotificationHelper.Notify(NBFactory.CreateWithScript(project).Exception("执行脚本时发生异常: " + e.Message).Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Exception("执行脚本时发生异常: " + e.Message).Build()); } finally { @@ -118,11 +117,11 @@ public partial class ScriptService : IScriptService _logger.LogInformation("------------------------------"); if (isSuccess) { - NotificationHelper.Notify(NBFactory.CreateWithScript(project).Success().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Success().Build()); } else { - NotificationHelper.Notify(NBFactory.CreateWithScript(project).Failure().Build()); + NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Failure().Build()); } } From cb84ae36d01ea2c21b2df84d91acb33fe9b32146 Mon Sep 17 00:00:00 2001 From: Scarlet Date: Wed, 22 Jan 2025 12:34:42 -0600 Subject: [PATCH 05/81] feat: integrate send() method into notification to allow for shorter call --- .../GameTask/AutoDomain/AutoDomainTask.cs | 6 +++--- .../GameTask/AutoGeniusInvokation/Model/Duel.cs | 12 ++++++------ BetterGenshinImpact/GameTask/TaskRunner.cs | 12 ++++++------ .../Service/Notification/Model/INotificationData.cs | 5 +++++ BetterGenshinImpact/Service/ScriptService.cs | 12 ++++++------ 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs index a5e14018..fc503547 100644 --- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs +++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs @@ -75,7 +75,7 @@ public class AutoDomainTask : ISoloTask Init(); // TODO: 使用exception逻辑让started必有对应的completed - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(_taskParam).Started().Build()); + NotificationBuilderFactory.CreateWith(_taskParam).Started().Build().Send(); // 3次复活重试 for (int i = 0; i < 3; i++) @@ -163,10 +163,10 @@ public class AutoDomainTask : ISoloTask Logger.LogInformation("体力已经耗尽,结束自动秘境"); } - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(_taskParam).Success().Build()); + NotificationBuilderFactory.CreateWith(_taskParam).Success().Build().Send(); break; } - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(_taskParam).InProgress().Build()); + NotificationBuilderFactory.CreateWith(_taskParam).InProgress().Build().Send(); } } diff --git a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs index 4d0358c4..813b46be 100644 --- a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs +++ b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs @@ -62,7 +62,7 @@ public class Duel { AutoGeniusInvokationAssets.DestroyInstance(); - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Started().Build()); + NotificationBuilderFactory.CreateWith(this).Started().Build().Send(); GeniusInvokationControl.GetInstance().Init(ct); // 对局准备 选择初始手牌 @@ -288,14 +288,14 @@ public class Duel } catch (TaskCanceledException ex) { - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Exception(ex.Message).Build()); - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Failure().Build()); + NotificationBuilderFactory.CreateWith(this).Exception(ex.Message).Build().Send(); + NotificationBuilderFactory.CreateWith(this).Failure().Build().Send(); throw; } catch (NormalEndException ex) { _logger.LogInformation("对局结束"); - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Success().Build()); + NotificationBuilderFactory.CreateWith(this).Success().Build().Send(); throw; } catch (System.Exception ex) @@ -304,8 +304,8 @@ public class Duel { _logger.LogError(ex.StackTrace); } - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Exception(ex.Message).Build()); - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(this).Failure().Build()); + NotificationBuilderFactory.CreateWith(this).Exception(ex.Message).Build().Send(); + NotificationBuilderFactory.CreateWith(this).Failure().Build().Send(); throw; } } diff --git a/BetterGenshinImpact/GameTask/TaskRunner.cs b/BetterGenshinImpact/GameTask/TaskRunner.cs index 54d0d67d..dac387d4 100644 --- a/BetterGenshinImpact/GameTask/TaskRunner.cs +++ b/BetterGenshinImpact/GameTask/TaskRunner.cs @@ -52,7 +52,7 @@ public class TaskRunner return; } bool isSuccess = false; - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Started().Build()); + NotificationBuilderFactory.CreateWith(taskDetails).Started().Build().Send(); try { _logger.LogInformation("→ {Text}", _name + "任务启动!"); @@ -70,7 +70,7 @@ public class TaskRunner } catch (NormalEndException e) { - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Exception("任务中断:" + e.Message).Build()); + NotificationBuilderFactory.CreateWith(taskDetails).Exception("任务中断:" + e.Message).Build().Send(); _logger.LogInformation("任务中断:{Msg}", e.Message); if (RunnerContext.Instance.IsContinuousRunGroup) { @@ -81,7 +81,7 @@ public class TaskRunner catch (TaskCanceledException e) { _logger.LogInformation("任务中断:{Msg}", "任务被取消"); - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Exception("任务被取消").Build()); + NotificationBuilderFactory.CreateWith(taskDetails).Exception("任务被取消").Build().Send(); if (RunnerContext.Instance.IsContinuousRunGroup) { // 连续执行时,抛出异常,终止执行 @@ -92,7 +92,7 @@ public class TaskRunner { _logger.LogError(e.Message); _logger.LogDebug(e.StackTrace); - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Exception(e.Message).Build()); + NotificationBuilderFactory.CreateWith(taskDetails).Exception(e.Message).Build().Send(); } finally { @@ -100,11 +100,11 @@ public class TaskRunner _logger.LogInformation("→ {Text}", _name + "任务结束"); if (isSuccess) { - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Success().Build()); + NotificationBuilderFactory.CreateWith(taskDetails).Success().Build().Send(); } else { - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(taskDetails).Failure().Build()); + NotificationBuilderFactory.CreateWith(taskDetails).Failure().Build().Send(); } CancellationContext.Instance.Clear(); diff --git a/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs index cbbbbec6..7a53734e 100644 --- a/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs +++ b/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs @@ -20,4 +20,9 @@ public abstract class INotificationData public Image? Screenshot { get; set; } public string? Message { get; set; } + + public void Send() + { + NotificationHelper.Notify(this); + } } diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index f7e35fdb..d9d3355a 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -77,7 +77,7 @@ public partial class ScriptService : IScriptService bool isSuccess = false; try { - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Started().Build()); + NotificationBuilderFactory.CreateWith(project).Started().Build().Send(); if (hasTimer) { TaskTriggerDispatcher.Instance().ClearTriggers(); @@ -92,20 +92,20 @@ public partial class ScriptService : IScriptService } catch (NormalEndException e) { - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Exception(e.Message).Build()); + NotificationBuilderFactory.CreateWith(project).Exception(e.Message).Build().Send(); throw; } catch (TaskCanceledException e) { _logger.LogInformation("取消执行配置组: {Msg}", e.Message); - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Exception("取消执行配置组: " + e.Message).Build()); + NotificationBuilderFactory.CreateWith(project).Exception("取消执行配置组: " + e.Message).Build().Send(); throw; } catch (Exception e) { _logger.LogDebug(e, "执行脚本时发生异常"); _logger.LogError("执行脚本时发生异常: {Msg}", e.Message); - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Exception("执行脚本时发生异常: " + e.Message).Build()); + NotificationBuilderFactory.CreateWith(project).Exception("执行脚本时发生异常: " + e.Message).Build().Send(); } finally { @@ -117,11 +117,11 @@ public partial class ScriptService : IScriptService _logger.LogInformation("------------------------------"); if (isSuccess) { - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Success().Build()); + NotificationBuilderFactory.CreateWith(project).Success().Build().Send(); } else { - NotificationHelper.Notify(NotificationBuilderFactory.CreateWith(project).Failure().Build()); + NotificationBuilderFactory.CreateWith(project).Failure().Build().Send(); } } From f7779af01b1829cc2146a1b0e7e8f6cfc80a38a5 Mon Sep 17 00:00:00 2001 From: zjl Date: Thu, 23 Jan 2025 22:53:59 +0800 Subject: [PATCH 06/81] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E5=88=86=E6=9E=90=E4=B8=80=E4=BA=9B=E5=AD=97=E6=AE=B5=E4=B8=BA?= =?UTF-8?q?0=E6=97=B6=E6=98=BE=E7=A4=BA=E4=B8=BA=E7=A9=BA=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E5=BC=82=E5=B8=B8=E6=83=85=E5=86=B5?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=EF=BC=88=E5=A4=8D=E6=B4=BB=E3=80=81=E9=87=8D?= =?UTF-8?q?=E8=AF=95=E3=80=81=E4=BC=A0=E9=80=81=E5=A4=B1=E8=B4=A5=E3=80=81?= =?UTF-8?q?=E6=88=98=E6=96=97=E8=B6=85=E6=97=B6=EF=BC=89=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/LogParse/LogParse.cs | 83 +++++++++++++++++-- .../GameTask/LogParse/LogParseConfig.cs | 1 + .../GameTask/LogParse/MoraStatistics.cs | 7 +- .../ViewModel/Pages/ScriptControlViewModel.cs | 16 +++- 4 files changed, 97 insertions(+), 10 deletions(-) diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs index 83ef540e..0286e277 100644 --- a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs +++ b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs @@ -102,6 +102,33 @@ namespace LogParse if (configTask != null) { + + //前往七天神像复活 + if (logstr.EndsWith("前往七天神像复活")) + { + configTask.Fault.ReviveCount++; + } + //传送失败,重试 n 次 + result = parseBgiLine($@"传送失败,重试 (\d+) 次", logstr); + if (result.Item1) + { + configTask.Fault.TeleportFailCount = int.Parse(result.Item2[1]); + + } + //战斗超时结束 + if (logstr == "战斗超时结束") + { + configTask.Fault.BattleTimeoutCount ++; + } + + //重试一次路线或放弃此路线! + if (logstr.EndsWith("重试一次路线或放弃此路线!")) + { + configTask.Fault.ReviveCount++; + } + + + if (logstr.StartsWith("→ 脚本执行结束: \"" + configTask.Name + "\"")) { configTask.EndDate = parsePreDataTime(logLines, i - 1, logrq); @@ -182,6 +209,8 @@ namespace LogParse //配置人物列表xxx.json public List ConfigTaskList { get; } = new(); + + public class ConfigTask { public string Name { get; set; } @@ -204,6 +233,21 @@ namespace LogParse Picks[val] = Picks[val] + 1; } + public FaultScenario Fault { get; set; } = new(); + + public class FaultScenario + { + //复活次数 + public int ReviveCount { get; set; } = 0; + //传送失败次数 + public int TeleportFailCount { get; set; } = 0; + //重试次数 + public int RetryCount { get; set; } = 0; + //战斗超时 + public int BattleTimeoutCount { get; set; } = 0; + + } + } } @@ -307,7 +351,24 @@ namespace LogParse return customDayStart; } - public static string GenerHtmlByConfigGroupEntity(List configGroups, GameInfo gameInfo) + public static string FormatNumberWithStyle(int a, int b=3) + { + if (a== 0) + { + return ""; + } + // Determine the style based on the condition + string colorStyle = a >= b ? "color:red;" : string.Empty; + + // Return the formatted HTML string + return $"{a}"; + } + public static string GetNumberOrEmptyString(int number) + { + // 如果数字为0,返回空字符串,否则返回数字的字符串形式 + return number == 0 ? string.Empty : number.ToString(); + } + public static string GenerHtmlByConfigGroupEntity(List configGroups, GameInfo gameInfo,LogParseConfig.ScriptGroupLogParseConfig scriptGroupLogParseConfig) { (string name, Func value)[] colConfigs = [ @@ -316,20 +377,28 @@ namespace LogParse (name: "结束日期", value: task => task.EndDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? ""), (name: "耗时", value: task => ConvertSecondsToTime((task.EndDate - task.StartDate)?.TotalSeconds ?? 0)) ]; - - + List<(string name, Func value)> colConfigList = new(); + colConfigList.AddRange(colConfigs); + if (scriptGroupLogParseConfig.FaultStatsSwitch) + { + colConfigList.Add((name: "复活次数", value: task => FormatNumberWithStyle(task.Fault.ReviveCount))); + colConfigList.Add((name: "重试次数", value: task => FormatNumberWithStyle(task.Fault.RetryCount))); + colConfigList.Add((name: "战斗超时次数", value: task => FormatNumberWithStyle(task.Fault.BattleTimeoutCount))); + colConfigList.Add((name: "传送失败次数", value: task => FormatNumberWithStyle(task.Fault.TeleportFailCount))); + } + (string name, Func value)[] msColConfigs = [ - (name: "日期", value: ms => ms.Name), (name: "小怪", value: ms => ms.SmallMonsterStatistics.ToString()), + (name: "日期", value: ms => ms.Name), (name: "小怪", value: ms => GetNumberOrEmptyString(ms.SmallMonsterStatistics)), (name: "最后小怪日期", value: ms => ms.LastSmallTime), - (name: "精英", value: ms => ms.EliteGameStatistics.ToString()), + (name: "精英", value: ms => GetNumberOrEmptyString(ms.EliteGameStatistics)), (name: "精英详细", value: ms => ms.EliteDetails), (name: "最后精英日期", value: ms => ms.LastEliteTime), (name: "总计锄地摩拉", value: ms => ms.TotalMoraKillingMonstersMora.ToString()), (name: "突发事件获取摩拉", value: ms => ms.EmergencyBonus) ]; //锄地部分新曾字段 - (string name, Func value)[] col2Configs=[..msColConfigs.ToList().Where(item=>item.name!="日期" && item.name!="最后小怪日期" && item.name!="最后精英日期"), + (string name, Func value)[] col2Configs=[..msColConfigs.ToList().Where(item=>item.name!="日期" && item.name!="最后小怪日期" && item.name!="最后精英日期" && item.name!="突发事件获取摩拉"), (name: "摩拉(每秒)", value: ms => (ms.TotalMoraKillingMonstersMora/(ms.StatisticsEnd-ms.StatisticsStart)?.TotalSeconds ?? 0).ToString("F2")), ]; @@ -344,7 +413,7 @@ namespace LogParse actionItems = TravelsDiaryDetailManager.loadAllActionItems(gameInfo, configGroups); } - return GenerHtmlByConfigGroupEntity(configGroups, "日志分析", colConfigs,col2Configs, actionItems, msColConfigs); + return GenerHtmlByConfigGroupEntity(configGroups, "日志分析", colConfigList.ToArray(),col2Configs, actionItems, msColConfigs); } public static string ConcatenateStrings(string a, string b) { diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs b/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs index 7588ab5d..63a9004a 100644 --- a/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs +++ b/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs @@ -14,5 +14,6 @@ public partial class LogParseConfig : ObservableObject [ObservableProperty] private string _rangeValue = "CurrentConfig"; [ObservableProperty] private string _dayRangeValue = "7"; [ObservableProperty] private bool _hoeingStatsSwitch = false; + [ObservableProperty] private bool _faultStatsSwitch = false; } } \ No newline at end of file diff --git a/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs b/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs index ae62e5ea..843039bd 100644 --- a/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs +++ b/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs @@ -31,7 +31,12 @@ namespace LogParse { var ls = this.ActionItems.Where(item => item.ActionId == 28).ToList(); var count = ls.Count(); - return ls.Sum(item=>item.Num)+((count==0 || count>=10)?"":$"({count}/10)"); + if (count == 0) + { + return ""; + } + + return ls.Sum(item=>item.Num)+(count>=10?"":$"({count}/10)"); } } diff --git a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs index c1bf7ab8..2d522250 100644 --- a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs @@ -11,6 +11,7 @@ using System.Text.Json; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using System.Windows.Controls.Primitives; using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.Core.Script; using BetterGenshinImpact.Core.Script.Group; @@ -174,6 +175,16 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware dayRangeComboBox.SelectedValuePath = "Value"; // 绑定的值 dayRangeComboBox.SelectedIndex = 0; stackPanel.Children.Add(dayRangeComboBox); + + // 开关控件:ToggleButton 或 CheckBox + CheckBox faultStatsSwitch = new CheckBox + { + Content = "异常情况统计", + VerticalAlignment = VerticalAlignment.Center + }; + stackPanel.Children.Add(faultStatsSwitch); + + // 开关控件:ToggleButton 或 CheckBox @@ -245,7 +256,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware dayRangeComboBox.SelectedValue = sgpc.DayRangeValue; cookieTextBox.Text = config.Cookie; hoeingStatsSwitch.IsChecked = sgpc.HoeingStatsSwitch; - + faultStatsSwitch.IsChecked = sgpc.FaultStatsSwitch; MessageBoxResult result = await uiMessageBox.ShowDialogAsync(); @@ -259,6 +270,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware sgpc.DayRangeValue=dayRangeValue; sgpc.RangeValue = rangeValue; sgpc.HoeingStatsSwitch = hoeingStatsSwitch.IsChecked ?? false; + sgpc.FaultStatsSwitch = faultStatsSwitch.IsChecked ?? false; config.Cookie = cookieValue; config.ScriptGroupLogDictionary[_selectedScriptGroup.Name]=sgpc; @@ -343,7 +355,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware configGroupEntities.Reverse(); //realGameInfo //小怪摩拉统计 - win.NavigateToHtml(LogParse.LogParse.GenerHtmlByConfigGroupEntity(configGroupEntities,hoeingStats ? realGameInfo : null)); + win.NavigateToHtml(LogParse.LogParse.GenerHtmlByConfigGroupEntity(configGroupEntities,hoeingStats ? realGameInfo : null,sgpc)); win.ShowDialog(); } From 07efcbde4f6830976ee63fd6c54d6907d6d5ccfd Mon Sep 17 00:00:00 2001 From: zjl Date: Thu, 23 Jan 2025 22:58:38 +0800 Subject: [PATCH 07/81] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E8=B5=8B=E5=80=BC=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BetterGenshinImpact/GameTask/LogParse/LogParse.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs index 0286e277..c76ad3be 100644 --- a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs +++ b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs @@ -124,7 +124,7 @@ namespace LogParse //重试一次路线或放弃此路线! if (logstr.EndsWith("重试一次路线或放弃此路线!")) { - configTask.Fault.ReviveCount++; + configTask.Fault.RetryCount++; } From d70ed4314afe28256683a0f675afdbc1875160aa Mon Sep 17 00:00:00 2001 From: zjl Date: Thu, 23 Jan 2025 23:04:58 +0800 Subject: [PATCH 08/81] =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=88=86=E6=9E=90?= =?UTF-8?q?=E8=A1=A8=E6=A0=BC=EF=BC=8C=E4=BD=BF=E9=9A=94=E8=A1=8C=E9=A2=9C?= =?UTF-8?q?=E8=89=B2=E6=A0=B7=E5=BC=8F=E4=B8=8D=E4=B8=80=E6=A0=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BetterGenshinImpact/GameTask/LogParse/LogParse.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs index c76ad3be..b2ceb51b 100644 --- a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs +++ b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs @@ -442,6 +442,8 @@ namespace LogParse html.AppendLine(" table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }"); html.AppendLine(" th, td { border: 1px solid black; padding: 8px; text-align: left; }"); html.AppendLine(" th { background-color: #f2f2f2; }"); + html.AppendLine(" tr:nth-child(odd) { background-color: #eaeaea; /* 奇数行颜色 */ }"); + html.AppendLine(" tr:nth-child(even) { background-color: #f9f9f9; /* 偶数行颜色 */}"); html.AppendLine(" "); html.AppendLine(""); html.AppendLine(""); From 7c620429c325f8495f50cfb99688a66cc1374891 Mon Sep 17 00:00:00 2001 From: zjl Date: Fri, 24 Jan 2025 19:19:09 +0800 Subject: [PATCH 09/81] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E9=94=84?= =?UTF-8?q?=E5=9C=B0=E5=BB=B6=E6=97=B6=EF=BC=8C=E9=80=9A=E8=BF=87=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=BB=B6=E6=97=B6=E7=9B=B8=E5=AF=B9=E7=B2=BE=E7=A1=AE?= =?UTF-8?q?=E7=9A=84=E6=98=BE=E7=A4=BA=E6=80=AA=E7=89=A9=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/LogParse/LogParse.cs | 29 ++++++++++++++- .../GameTask/LogParse/LogParseConfig.cs | 1 + .../ViewModel/Pages/ScriptControlViewModel.cs | 35 ++++++++++++++++++- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs index b2ceb51b..fcf60d15 100644 --- a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs +++ b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs @@ -368,6 +368,24 @@ namespace LogParse // 如果数字为0,返回空字符串,否则返回数字的字符串形式 return number == 0 ? string.Empty : number.ToString(); } + public static string SubtractFiveSeconds(string inputTime,int seconds) + { + try + { + // 将输入的字符串解析为 DateTime + DateTime parsedTime = DateTime.ParseExact(inputTime, "yyyy-MM-dd HH:mm:ss", null); + + // 减去 5 秒 + DateTime resultTime = parsedTime.AddSeconds(-seconds); + + // 转换回指定格式的字符串并返回 + return resultTime.ToString("yyyy-MM-dd HH:mm:ss"); + } + catch (FormatException) + { + return "Invalid input time format. Please use 'yyyy-MM-dd HH:mm:ss'."; + } + } public static string GenerHtmlByConfigGroupEntity(List configGroups, GameInfo gameInfo,LogParseConfig.ScriptGroupLogParseConfig scriptGroupLogParseConfig) { (string name, Func value)[] colConfigs = @@ -409,8 +427,17 @@ namespace LogParse List actionItems = new(); if (gameInfo != null) { - actionItems = TravelsDiaryDetailManager.loadAllActionItems(gameInfo, configGroups); + int hoeingDelay; + if (int.TryParse(scriptGroupLogParseConfig.HoeingDelay, out hoeingDelay)) + { + foreach (var actionItem in actionItems) + { + actionItem.Time = SubtractFiveSeconds(actionItem.Time,hoeingDelay); + Console.WriteLine(); + } + } + } return GenerHtmlByConfigGroupEntity(configGroups, "日志分析", colConfigList.ToArray(),col2Configs, actionItems, msColConfigs); diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs b/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs index 63a9004a..688a01ff 100644 --- a/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs +++ b/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs @@ -15,5 +15,6 @@ public partial class LogParseConfig : ObservableObject [ObservableProperty] private string _dayRangeValue = "7"; [ObservableProperty] private bool _hoeingStatsSwitch = false; [ObservableProperty] private bool _faultStatsSwitch = false; + [ObservableProperty] private string _hoeingDelay= "0"; } } \ No newline at end of file diff --git a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs index 2d522250..0fd06377 100644 --- a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs @@ -223,9 +223,39 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware secondRow.Children.Add(questionButton); + StackPanel threeRow = new StackPanel + { + Orientation = Orientation.Horizontal, + Margin = new Thickness(0, 0, 0, 10) + }; + + // 创建一个 TextBlock + TextBlock hoeingDelayBlock = new TextBlock + { + Text = "锄地延时(秒):", + VerticalAlignment = VerticalAlignment.Center, + FontSize = 16, + Margin = new Thickness(0, 0, 10, 0) + }; + + + TextBox hoeingDelayTextBox = new TextBox + { + Width = 100, + FontSize = 16, + VerticalContentAlignment = VerticalAlignment.Center + }; + + threeRow.Children.Add(hoeingDelayBlock); + threeRow.Children.Add(hoeingDelayTextBox); + + + + + // 将第二行添加到 StackPanel stackPanel.Children.Add(secondRow); - + stackPanel.Children.Add(threeRow); //PrimaryButtonText var uiMessageBox = new Wpf.Ui.Controls.MessageBox { @@ -257,6 +287,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware cookieTextBox.Text = config.Cookie; hoeingStatsSwitch.IsChecked = sgpc.HoeingStatsSwitch; faultStatsSwitch.IsChecked = sgpc.FaultStatsSwitch; + hoeingDelayTextBox.Text = sgpc.HoeingDelay; MessageBoxResult result = await uiMessageBox.ShowDialogAsync(); @@ -271,6 +302,8 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware sgpc.RangeValue = rangeValue; sgpc.HoeingStatsSwitch = hoeingStatsSwitch.IsChecked ?? false; sgpc.FaultStatsSwitch = faultStatsSwitch.IsChecked ?? false; + sgpc.HoeingDelay = hoeingDelayTextBox.Text; + config.Cookie = cookieValue; config.ScriptGroupLogDictionary[_selectedScriptGroup.Name]=sgpc; From 39b7176b4d6006ce6e26c3c51f4731154d858642 Mon Sep 17 00:00:00 2001 From: zjl Date: Fri, 24 Jan 2025 19:20:47 +0800 Subject: [PATCH 10/81] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=8D=E5=BF=85?= =?UTF-8?q?=E8=A6=81=E7=9A=84=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BetterGenshinImpact/GameTask/LogParse/LogParse.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs index fcf60d15..d5b4b058 100644 --- a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs +++ b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs @@ -434,7 +434,6 @@ namespace LogParse foreach (var actionItem in actionItems) { actionItem.Time = SubtractFiveSeconds(actionItem.Time,hoeingDelay); - Console.WriteLine(); } } From d0f985408ea579c8230392c878300954d8ca6dec Mon Sep 17 00:00:00 2001 From: zjl Date: Sat, 25 Jan 2025 22:29:37 +0800 Subject: [PATCH 11/81] =?UTF-8?q?=E8=B0=83=E5=BA=A6=E5=99=A8=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=EF=BC=8C=E5=A2=9E=E5=8A=A0=20=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=80=92=E5=BA=8F=E6=8E=92=E5=88=97=E5=8A=9F=E8=83=BD=E3=80=82?= =?UTF-8?q?=E8=B0=83=E5=BA=A6=E5=99=A8=E9=85=8D=E7=BD=AE=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E2=80=9C=E4=B8=8D=E5=9C=A8=E6=9F=90=E6=97=B6=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E2=80=9D=EF=BC=8C=E5=BD=93=E6=89=A7=E8=A1=8C=E5=AE=8C=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E8=B7=AF=E7=BA=BF=E5=90=8E=EF=BC=8C=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E4=B8=BA=E5=BD=93=E5=89=8D=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E9=97=B4=EF=BC=88=E8=8C=83=E5=9B=B4=EF=BC=9A?= =?UTF-8?q?0-23=EF=BC=89=EF=BC=8C=E5=88=99=E6=AD=A4=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E8=BF=BD=E8=B8=AA=E4=BB=BB=E5=8A=A1=E5=90=8E=E7=BB=AD=E9=83=BD?= =?UTF-8?q?=E5=B0=86=E9=83=BD=E8=B7=B3=E8=BF=87=EF=BC=8C=E9=80=82=E7=94=A8?= =?UTF-8?q?=E4=BA=8E=E8=BF=9E=E7=BB=AD=E6=89=A7=E8=A1=8C=E7=9A=84=E5=85=9C?= =?UTF-8?q?=E5=BA=95=E4=BB=BB=E5=8A=A1=EF=BC=8C=E4=BE=8B=E5=A6=82=E6=83=B3?= =?UTF-8?q?=E9=80=9A=E5=AE=B5=E6=8C=82=E6=9C=BA=EF=BC=8C=E5=B9=B6=E4=B8=94?= =?UTF-8?q?=E5=9C=A84=E7=82=B9=E5=90=8E=EF=BC=8C=E5=BC=80=E5=A7=8B?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E6=96=B0=E7=9A=84=E4=BB=BB=E5=8A=A1=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Core/Config/PathingPartyConfig.cs | 4 +++ BetterGenshinImpact/Service/ScriptService.cs | 33 +++++++++++++++++++ .../View/Pages/ScriptControlPage.xaml | 1 + .../Pages/View/ScriptGroupConfigView.xaml | 26 +++++++++++++++ .../ViewModel/Pages/ScriptControlViewModel.cs | 11 ++++++- 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/BetterGenshinImpact/Core/Config/PathingPartyConfig.cs b/BetterGenshinImpact/Core/Config/PathingPartyConfig.cs index a753eae5..47e0a059 100644 --- a/BetterGenshinImpact/Core/Config/PathingPartyConfig.cs +++ b/BetterGenshinImpact/Core/Config/PathingPartyConfig.cs @@ -69,6 +69,10 @@ public partial class PathingPartyConfig : ObservableObject [ObservableProperty] private bool _soloTaskUseFightEnabled = false; + //不在某时执行 + [ObservableProperty] + private string _skipDuring = ""; + // 使用小道具的间隔时间 [ObservableProperty] private int _useGadgetIntervalMs = 0; diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index 02acc783..1fa3787c 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -21,7 +21,24 @@ namespace BetterGenshinImpact.Service; public partial class ScriptService : IScriptService { private readonly ILogger _logger = App.GetLogger(); + private static bool IsCurrentHourEqual(string input) + { + // 尝试将输入字符串转换为整数 + if (int.TryParse(input, out int hour)) + { + // 验证小时是否在合法范围内(0-23) + if (hour >= 0 && hour <= 23) + { + // 获取当前小时数 + int currentHour = DateTime.Now.Hour; + // 判断是否相等 + return currentHour == hour; + } + } + // 如果输入非数字或不合法,返回 false + return false; + } public async Task RunMulti(IEnumerable projectList, string? groupName = null) { groupName ??= "默认"; @@ -59,6 +76,13 @@ public partial class ScriptService : IScriptService foreach (var project in list) { + + if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + { + _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); + continue; + } + if (project.Status != "Enabled") { _logger.LogInformation("脚本 {Name} 状态为禁用,跳过执行", project.Name); @@ -85,6 +109,14 @@ public partial class ScriptService : IScriptService stopwatch.Reset(); stopwatch.Start(); await ExecuteProject(project); + + //多次执行时及时中断 + if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + { + _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); + break; + } + } catch (NormalEndException e) { @@ -175,6 +207,7 @@ public partial class ScriptService : IScriptService private async Task ExecuteProject(ScriptGroupProject project) { + if (project.Type == "Javascript") { if (project.Project == null) diff --git a/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml b/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml index 21912df1..1c5b8769 100644 --- a/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml +++ b/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml @@ -217,6 +217,7 @@ + diff --git a/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml b/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml index 970e8715..fe9cf668 100644 --- a/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml +++ b/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml @@ -282,6 +282,32 @@ IsChecked="{Binding PathingConfig.SoloTaskUseFightEnabled, Mode=TwoWay}" /> + + + + + + + + + + + + + projects = new(); + projects.AddRange(SelectedScriptGroup?.Projects.Reverse()); + SelectedScriptGroup.Projects.Clear(); + projects.ForEach(item=>SelectedScriptGroup.Projects.Add(item)); + WriteScriptGroup(SelectedScriptGroup); + } [RelayCommand] public void OnCopyScriptGroup(ScriptGroup? item) From e97e04f9dbf9ba92a831e11e5f736cead23d2450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sat, 25 Jan 2025 23:03:50 +0800 Subject: [PATCH 12/81] =?UTF-8?q?auto=20music:=20more=20config=20=E5=8D=83?= =?UTF-8?q?=E9=9F=B3=E9=9B=85=E9=9B=86=E6=94=AF=E6=8C=81=E6=9B=B4=E5=A4=9A?= =?UTF-8?q?=E7=9A=84=E5=8F=82=E6=95=B0=E6=8E=A7=E5=88=B6=EF=BC=8C=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E6=96=87=E6=A1=88=E5=92=8C=E7=95=8C=E9=9D=A2=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/AutoMusicGame/AutoAlbumTask.cs | 74 ++++++++++++++----- .../AutoMusicGame/AutoMusicGameConfig.cs | 4 + .../View/Pages/TaskSettingsPage.xaml | 33 ++++++++- 3 files changed, 88 insertions(+), 23 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs b/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs index 883712c6..5284db78 100644 --- a/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs +++ b/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs @@ -1,7 +1,10 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; +using BetterGenshinImpact.Core.Recognition; +using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception; using BetterGenshinImpact.GameTask.AutoMusicGame.Assets; using BetterGenshinImpact.GameTask.Common.BgiVision; using BetterGenshinImpact.GameTask.Model.Area; @@ -27,6 +30,10 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask Logger.LogInformation("开始自动演奏整个专辑未完成的音乐"); await StartOneAlbum(ct); } + catch (NormalEndException e) + { + Logger.LogError("手动取消任务 - {Msg}", e.Message); + } catch (Exception e) { Logger.LogError("自动音乐专辑任务异常:{Msg}", e.Message); @@ -35,10 +42,20 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask public async Task StartOneAlbum(CancellationToken ct) { - using var iconRa = CaptureToRectArea().Find(AutoMusicAssets.Instance.UiLeftTopAlbumIcon); + using var ra1 = CaptureToRectArea(); + using var iconRa = ra1.Find(AutoMusicAssets.Instance.UiLeftTopAlbumIcon); if (!iconRa.IsExist()) { - throw new Exception("当前未处于专辑界面,请在专辑界面运行本任务"); + throw new Exception("当前未处于主题专辑界面,请在专辑界面运行本任务。注意全部歌曲列表页面无法运行本任务!"); + } + else + { + // OCR 后再次判断,区分是否是全部歌曲页面 + var ocrRes = ra1.DeriveCrop(iconRa.Right, iconRa.Top, ra1.Width * 0.16, iconRa.Height).FindMulti(RecognitionObject.OcrThis); + if (ocrRes.Any(region => region.Text.Contains("全部"))) + { + throw new Exception("当前在全部歌曲页面,此页面无法运行本任务。请返回到主界面选择专辑列表中以国家为主题的专辑页!"); + } } var musicLevel = TaskContext.Instance().Config.AutoMusicGameConfig.MusicLevel; @@ -46,13 +63,14 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask { musicLevel = "传说"; } + Logger.LogInformation("自动音游乐曲难度等级:{Text}", musicLevel); - + // 遍历4个难度等级 var defaultDifficultyLevels = new[] { ("普通", 480, 600, AutoMusicAssets.Instance.MusicCanorusLevel1), - ("困难", 800, 600, AutoMusicAssets.Instance.MusicCanorusLevel2), + ("困难", 800, 600, AutoMusicAssets.Instance.MusicCanorusLevel2), ("大师", 1150, 600, AutoMusicAssets.Instance.MusicCanorusLevel3), ("传说", 1400, 600, AutoMusicAssets.Instance.MusicCanorusLevel4) }; @@ -66,34 +84,52 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask foreach (var (difficultyName, xPos, yPos, canorusAsset) in difficultyLevels) { Logger.LogInformation("开始演奏{Difficulty}难度的乐曲", difficultyName); - + // 每个难度12首曲子 for (int i = 0; i < 13; i++) { - using var canoraRa = CaptureToRectArea().Find(canorusAsset); - if (canoraRa.IsExist()) + if (TaskContext.Instance().Config.AutoMusicGameConfig.MustCanorusLevel) { - Logger.LogInformation("乐曲{Num} - {Difficulty}级别:已完成【大音天籁】,切换下一首", i + 1, difficultyName); - GameCaptureRegion.GameRegion1080PPosClick(310, 220); - await Delay(800, ct); - continue; + using var canoraRa = CaptureToRectArea().Find(canorusAsset); + if (canoraRa.IsExist()) + { + Logger.LogInformation("乐曲{Num} - {Difficulty}级别:已完成【大音天籁】,切换下一首", i + 1, difficultyName); + GameCaptureRegion.GameRegion1080PPosClick(310, 220); + await Delay(800, ct); + continue; + } + + Logger.LogInformation("第{Num}首{Difficulty}难度的乐曲:{Message}", i + 1, difficultyName, "没有完成【大音天籁】"); + } + else + { + using var doneRa = CaptureToRectArea().Find(AutoMusicAssets.Instance.AlbumMusicComplate); + if (doneRa.IsExist()) + { + Logger.LogInformation("当前乐曲{Num}所有奖励已领取,切换下一首", i + 1); + GameCaptureRegion.GameRegion1080PPosClick(310, 220); + await Delay(800, ct); + continue; + } + + Logger.LogInformation("当前乐曲{Num}存在未领取奖励,前往演奏", i + 1); } - Logger.LogInformation("第{Num}首{Difficulty}难度的乐曲:{Message}", i + 1, difficultyName, "没有完成【大音天籁】"); - + + // 点击确认按钮 Bv.ClickWhiteConfirmButton(CaptureToRectArea()); await Delay(800, ct); - + // 选择难度 GameCaptureRegion.GameRegion1080PPosClick(xPos, yPos); await Delay(200, ct); - + // 开始演奏 Bv.ClickWhiteConfirmButton(CaptureToRectArea()); await Delay(500, ct); - using var cts = new CancellationTokenSource(); + var cts = new CancellationTokenSource(); ct.Register(cts.Cancel); // 演奏结束检查任务 @@ -118,16 +154,16 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask // 等待任意一个任务完成 await Task.WhenAny(checkTask, musicTask); await cts.CancelAsync(); - + Logger.LogInformation("第{Num}首{Difficulty}难度乐曲演奏完成", i + 1, difficultyName); await Delay(2000, ct); - + await Bv.WaitUntilFound(AutoMusicAssets.Instance.UiLeftTopAlbumIcon, ct); Logger.LogDebug("切换到下一首乐曲"); GameCaptureRegion.GameRegion1080PPosClick(310, 220); await Delay(800, ct); } - + Logger.LogInformation("完成{Difficulty}难度所有乐曲的演奏", difficultyName); } diff --git a/BetterGenshinImpact/GameTask/AutoMusicGame/AutoMusicGameConfig.cs b/BetterGenshinImpact/GameTask/AutoMusicGame/AutoMusicGameConfig.cs index d7083ed5..4a1acd2f 100644 --- a/BetterGenshinImpact/GameTask/AutoMusicGame/AutoMusicGameConfig.cs +++ b/BetterGenshinImpact/GameTask/AutoMusicGame/AutoMusicGameConfig.cs @@ -11,6 +11,10 @@ namespace BetterGenshinImpact.GameTask.AutoMusicGame; [Serializable] public partial class AutoMusicGameConfig : ObservableObject { + // 自动达到大音天籁的级别 + [ObservableProperty] + private bool _mustCanorusLevel = false; + // 乐曲级别 [ObservableProperty] private string _musicLevel = ""; diff --git a/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml b/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml index a3bb2eb8..3644a2b3 100644 --- a/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/TaskSettingsPage.xaml @@ -1287,7 +1287,7 @@ - - + @@ -1350,12 +1350,37 @@ + + + + + + + + + + + + + Date: Sat, 25 Jan 2025 23:36:24 +0800 Subject: [PATCH 13/81] fix solo task run --- BetterGenshinImpact/GameTask/TaskRunner.cs | 5 ++- BetterGenshinImpact/Service/ScriptService.cs | 40 +++++++++++--------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/BetterGenshinImpact/GameTask/TaskRunner.cs b/BetterGenshinImpact/GameTask/TaskRunner.cs index f0902164..5b62d463 100644 --- a/BetterGenshinImpact/GameTask/TaskRunner.cs +++ b/BetterGenshinImpact/GameTask/TaskRunner.cs @@ -7,6 +7,8 @@ using Microsoft.Extensions.Logging; using System; using System.Threading; using System.Threading.Tasks; +using BetterGenshinImpact.GameTask.AutoGeniusInvokation; +using BetterGenshinImpact.GameTask.AutoMusicGame; using BetterGenshinImpact.Helpers; using Wpf.Ui.Violeta.Controls; using static BetterGenshinImpact.GameTask.Common.TaskControl; @@ -120,7 +122,8 @@ public class TaskRunner public async Task RunSoloTaskAsync(ISoloTask soloTask) { // 没启动的时候先启动 - await ScriptService.StartGameTask(); + bool waitForMainUi = soloTask.Name != "自动七圣召唤" && !soloTask.Name.Contains("自动音游"); + await ScriptService.StartGameTask(waitForMainUi); await Task.Run(() => RunCurrentAsync(async () => await soloTask.Start(CancellationContext.Instance.Cts.Token))); } diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index 02acc783..69b1ca29 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -218,7 +218,7 @@ public partial class ScriptService : IScriptService private static partial Regex DispatcherAddTimerRegex(); - public static async Task StartGameTask() + public static async Task StartGameTask(bool waitForMainUi = true) { // 没启动时候,启动截图器 var homePageViewModel = App.GetService(); @@ -226,29 +226,33 @@ public partial class ScriptService : IScriptService { await homePageViewModel.OnStartTriggerAsync(); - await Task.Run(() => + if (waitForMainUi) { - var first = true; - while (true) + await Task.Run(() => { - if (!homePageViewModel.TaskDispatcherEnabled || !TaskContext.Instance().IsInitialized) + var first = true; + while (true) { - continue; - } + if (!homePageViewModel.TaskDispatcherEnabled || !TaskContext.Instance().IsInitialized) + { + continue; + } - var content = TaskControl.CaptureToRectArea(); - if (Bv.IsInMainUi(content) || Bv.IsInAnyClosableUi(content)) - { - return; - } + var content = TaskControl.CaptureToRectArea(); + if (Bv.IsInMainUi(content) || Bv.IsInAnyClosableUi(content)) + { + return; + } - if (first) - { - first = false; - TaskControl.Logger.LogInformation("当前不在游戏主界面,等待进入主界面后执行任务..."); + if (first) + { + first = false; + TaskControl.Logger.LogInformation("当前不在游戏主界面,等待进入主界面后执行任务..."); + TaskControl.Logger.LogInformation("如果你已经在游戏内的其他界面,请自行退出当前界面(ESC),使当前任务能够继续运行!"); + } } - } - }); + }); + } } } } \ No newline at end of file From 718db28e51a8d8f32340c32994e905a6952483a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sat, 25 Jan 2025 23:48:14 +0800 Subject: [PATCH 14/81] update ui icon --- BetterGenshinImpact/View/Pages/OneDragonFlowPage.xaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BetterGenshinImpact/View/Pages/OneDragonFlowPage.xaml b/BetterGenshinImpact/View/Pages/OneDragonFlowPage.xaml index 37924e5c..a5b38020 100644 --- a/BetterGenshinImpact/View/Pages/OneDragonFlowPage.xaml +++ b/BetterGenshinImpact/View/Pages/OneDragonFlowPage.xaml @@ -473,7 +473,7 @@ - + @@ -541,7 +541,7 @@ - + From 218029b2e6072f51a5c82b23e67fa263cd872594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sat, 25 Jan 2025 23:53:15 +0800 Subject: [PATCH 15/81] 0.39.7 --- BetterGenshinImpact/BetterGenshinImpact.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj index 6edc2fa6..2805db08 100644 --- a/BetterGenshinImpact/BetterGenshinImpact.csproj +++ b/BetterGenshinImpact/BetterGenshinImpact.csproj @@ -10,7 +10,7 @@ true Assets\Images\logo.ico BetterGI - 0.39.6 + 0.39.7 x64 embedded From 9ba3447ab1f652d4d80dc22beae3e6b7c83621ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sun, 26 Jan 2025 00:20:01 +0800 Subject: [PATCH 16/81] =?UTF-8?q?modify=20the=20position=20of=20the=20UI?= =?UTF-8?q?=20for=20map=20teleportation=20settings=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=9C=B0=E5=9B=BE=E4=BC=A0=E9=80=81=E8=AE=BE=E7=BD=AEui?= =?UTF-8?q?=E7=9A=84=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/AutoTrackPath/TpConfig.cs | 54 +++--- .../View/Pages/CommonSettingsPage.xaml | 162 ++++++++++++++++++ .../View/Pages/TriggerSettingsPage.xaml | 160 +---------------- 3 files changed, 193 insertions(+), 183 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs index 5187dd84..a084fcba 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs @@ -1,5 +1,6 @@ using CommunityToolkit.Mvvm.ComponentModel; using System; +using System.Text.Json.Serialization; namespace BetterGenshinImpact.GameTask.AutoTrackPath; @@ -12,44 +13,49 @@ public partial class TpConfig : ObservableObject private int _mapZoomOutDistance = 2000; // 地图缩小的最小距离,单位:像素 [ObservableProperty] - private int _mapZoomInDistance = 400; // 地图放大的最大距离,单位:像素 - - [ObservableProperty] - private int _stepIntervalMilliseconds = 20; // 鼠标移动时间间隔,单位:ms - - [ObservableProperty] - private double _maxZoomLevel = 5.0; // 最大缩放等级 + private int _mapZoomInDistance = 400; // 地图放大的最大距离,单位:像素 [ObservableProperty] - private double _minZoomLevel = 1.7; // 最小缩放等级 - + private int _stepIntervalMilliseconds = 20; // 鼠标移动时间间隔,单位:ms + [ObservableProperty] - private double _reviveStatueOfTheSevenPointX = 2296.4; // 七天神像点位X坐标 - + private double _maxZoomLevel = 5.0; // 最大缩放等级 + [ObservableProperty] - private double _reviveStatueOfTheSevenPointY = -824.4; // 七天神像点位Y坐标 - + private double _minZoomLevel = 1.7; // 最小缩放等级 + [ObservableProperty] + private double _reviveStatueOfTheSevenPointX = 2296.4; // 七天神像点位X坐标 + + [ObservableProperty] + private double _reviveStatueOfTheSevenPointY = -824.4; // 七天神像点位Y坐标 + + [ObservableProperty] + [property: JsonIgnore] private int _zoomOutButtonY = 654; // y-coordinate for zoom-out button - + [ObservableProperty] - private int _zoomInButtonY = 428; // y-coordinate for zoom-in button - + [property: JsonIgnore] + private int _zoomInButtonY = 428; // y-coordinate for zoom-in button + [ObservableProperty] + [property: JsonIgnore] private int _zoomButtonX = 49; // x-coordinate for zoom button - + [ObservableProperty] + [property: JsonIgnore] private int _zoomStartY = 453; // y-coordinate for zoom start - + [ObservableProperty] + [property: JsonIgnore] private int _zoomEndY = 628; // y-coordinate for zoom end - - [ObservableProperty] + + [ObservableProperty] private double _tolerance = 200; // 允许的移动误差 - - [ObservableProperty] + + [ObservableProperty] private int _maxIterations = 30; // 移动最大次数 - - [ObservableProperty] + + [ObservableProperty] private int _maxMouseMove = 300; // 单次移动最大距离 } \ No newline at end of file diff --git a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml index 4465f2b9..e0fcc698 100644 --- a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml @@ -533,6 +533,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + From 8c45a02deb8aeac8098761377862299d28cab83a Mon Sep 17 00:00:00 2001 From: mfkvfhpdx Date: Sun, 26 Jan 2025 11:17:19 +0800 Subject: [PATCH 17/81] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E5=88=86=E6=9E=90=E4=B8=80=E4=BA=9B=E5=AD=97=E6=AE=B5=E4=B8=BA?= =?UTF-8?q?0=E6=97=B6=E6=98=BE=E7=A4=BA=E4=B8=BA=E7=A9=BA=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E5=BC=82=E5=B8=B8=E6=83=85=E5=86=B5?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=EF=BC=88=E5=A4=8D=E6=B4=BB=E3=80=81=E9=87=8D?= =?UTF-8?q?=E8=AF=95=E3=80=81=E4=BC=A0=E9=80=81=E5=A4=B1=E8=B4=A5=E3=80=81?= =?UTF-8?q?=E6=88=98=E6=96=97=E8=B6=85=E6=97=B6=EF=BC=89=E3=80=82=20(#1056?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 调整日志分析一些字段为0时显示为空,增加了异常情况统计(复活、重试、传送失败、战斗超时)。 * 修正一个赋值错误 * 日志分析表格,使隔行颜色样式不一样 * 增加了锄地延时,通过控制延时相对精确的显示怪物数量 * 删除不必要的输出 * 调度器任务,增加 任务倒序排列功能。调度器配置增加“不在某时执行”,当执行完一个路线后,如果时间为当前配置的时间(范围:0-23),则此路径追踪任务后续都将都跳过,适用于连续执行的兜底任务,例如想通宵挂机,并且在4点后,开始执行新的任务。 --- .../Core/Config/PathingPartyConfig.cs | 4 + .../GameTask/LogParse/LogParse.cs | 113 ++++++++++++++++-- .../GameTask/LogParse/LogParseConfig.cs | 2 + .../GameTask/LogParse/MoraStatistics.cs | 7 +- BetterGenshinImpact/Service/ScriptService.cs | 33 +++++ .../View/Pages/ScriptControlPage.xaml | 1 + .../Pages/View/ScriptGroupConfigView.xaml | 26 ++++ .../ViewModel/Pages/ScriptControlViewModel.cs | 62 +++++++++- 8 files changed, 235 insertions(+), 13 deletions(-) diff --git a/BetterGenshinImpact/Core/Config/PathingPartyConfig.cs b/BetterGenshinImpact/Core/Config/PathingPartyConfig.cs index a753eae5..47e0a059 100644 --- a/BetterGenshinImpact/Core/Config/PathingPartyConfig.cs +++ b/BetterGenshinImpact/Core/Config/PathingPartyConfig.cs @@ -69,6 +69,10 @@ public partial class PathingPartyConfig : ObservableObject [ObservableProperty] private bool _soloTaskUseFightEnabled = false; + //不在某时执行 + [ObservableProperty] + private string _skipDuring = ""; + // 使用小道具的间隔时间 [ObservableProperty] private int _useGadgetIntervalMs = 0; diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs index 83ef540e..d5b4b058 100644 --- a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs +++ b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs @@ -102,6 +102,33 @@ namespace LogParse if (configTask != null) { + + //前往七天神像复活 + if (logstr.EndsWith("前往七天神像复活")) + { + configTask.Fault.ReviveCount++; + } + //传送失败,重试 n 次 + result = parseBgiLine($@"传送失败,重试 (\d+) 次", logstr); + if (result.Item1) + { + configTask.Fault.TeleportFailCount = int.Parse(result.Item2[1]); + + } + //战斗超时结束 + if (logstr == "战斗超时结束") + { + configTask.Fault.BattleTimeoutCount ++; + } + + //重试一次路线或放弃此路线! + if (logstr.EndsWith("重试一次路线或放弃此路线!")) + { + configTask.Fault.RetryCount++; + } + + + if (logstr.StartsWith("→ 脚本执行结束: \"" + configTask.Name + "\"")) { configTask.EndDate = parsePreDataTime(logLines, i - 1, logrq); @@ -182,6 +209,8 @@ namespace LogParse //配置人物列表xxx.json public List ConfigTaskList { get; } = new(); + + public class ConfigTask { public string Name { get; set; } @@ -204,6 +233,21 @@ namespace LogParse Picks[val] = Picks[val] + 1; } + public FaultScenario Fault { get; set; } = new(); + + public class FaultScenario + { + //复活次数 + public int ReviveCount { get; set; } = 0; + //传送失败次数 + public int TeleportFailCount { get; set; } = 0; + //重试次数 + public int RetryCount { get; set; } = 0; + //战斗超时 + public int BattleTimeoutCount { get; set; } = 0; + + } + } } @@ -307,7 +351,42 @@ namespace LogParse return customDayStart; } - public static string GenerHtmlByConfigGroupEntity(List configGroups, GameInfo gameInfo) + public static string FormatNumberWithStyle(int a, int b=3) + { + if (a== 0) + { + return ""; + } + // Determine the style based on the condition + string colorStyle = a >= b ? "color:red;" : string.Empty; + + // Return the formatted HTML string + return $"{a}"; + } + public static string GetNumberOrEmptyString(int number) + { + // 如果数字为0,返回空字符串,否则返回数字的字符串形式 + return number == 0 ? string.Empty : number.ToString(); + } + public static string SubtractFiveSeconds(string inputTime,int seconds) + { + try + { + // 将输入的字符串解析为 DateTime + DateTime parsedTime = DateTime.ParseExact(inputTime, "yyyy-MM-dd HH:mm:ss", null); + + // 减去 5 秒 + DateTime resultTime = parsedTime.AddSeconds(-seconds); + + // 转换回指定格式的字符串并返回 + return resultTime.ToString("yyyy-MM-dd HH:mm:ss"); + } + catch (FormatException) + { + return "Invalid input time format. Please use 'yyyy-MM-dd HH:mm:ss'."; + } + } + public static string GenerHtmlByConfigGroupEntity(List configGroups, GameInfo gameInfo,LogParseConfig.ScriptGroupLogParseConfig scriptGroupLogParseConfig) { (string name, Func value)[] colConfigs = [ @@ -316,20 +395,28 @@ namespace LogParse (name: "结束日期", value: task => task.EndDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? ""), (name: "耗时", value: task => ConvertSecondsToTime((task.EndDate - task.StartDate)?.TotalSeconds ?? 0)) ]; - - + List<(string name, Func value)> colConfigList = new(); + colConfigList.AddRange(colConfigs); + if (scriptGroupLogParseConfig.FaultStatsSwitch) + { + colConfigList.Add((name: "复活次数", value: task => FormatNumberWithStyle(task.Fault.ReviveCount))); + colConfigList.Add((name: "重试次数", value: task => FormatNumberWithStyle(task.Fault.RetryCount))); + colConfigList.Add((name: "战斗超时次数", value: task => FormatNumberWithStyle(task.Fault.BattleTimeoutCount))); + colConfigList.Add((name: "传送失败次数", value: task => FormatNumberWithStyle(task.Fault.TeleportFailCount))); + } + (string name, Func value)[] msColConfigs = [ - (name: "日期", value: ms => ms.Name), (name: "小怪", value: ms => ms.SmallMonsterStatistics.ToString()), + (name: "日期", value: ms => ms.Name), (name: "小怪", value: ms => GetNumberOrEmptyString(ms.SmallMonsterStatistics)), (name: "最后小怪日期", value: ms => ms.LastSmallTime), - (name: "精英", value: ms => ms.EliteGameStatistics.ToString()), + (name: "精英", value: ms => GetNumberOrEmptyString(ms.EliteGameStatistics)), (name: "精英详细", value: ms => ms.EliteDetails), (name: "最后精英日期", value: ms => ms.LastEliteTime), (name: "总计锄地摩拉", value: ms => ms.TotalMoraKillingMonstersMora.ToString()), (name: "突发事件获取摩拉", value: ms => ms.EmergencyBonus) ]; //锄地部分新曾字段 - (string name, Func value)[] col2Configs=[..msColConfigs.ToList().Where(item=>item.name!="日期" && item.name!="最后小怪日期" && item.name!="最后精英日期"), + (string name, Func value)[] col2Configs=[..msColConfigs.ToList().Where(item=>item.name!="日期" && item.name!="最后小怪日期" && item.name!="最后精英日期" && item.name!="突发事件获取摩拉"), (name: "摩拉(每秒)", value: ms => (ms.TotalMoraKillingMonstersMora/(ms.StatisticsEnd-ms.StatisticsStart)?.TotalSeconds ?? 0).ToString("F2")), ]; @@ -340,11 +427,19 @@ namespace LogParse List actionItems = new(); if (gameInfo != null) { - actionItems = TravelsDiaryDetailManager.loadAllActionItems(gameInfo, configGroups); + int hoeingDelay; + if (int.TryParse(scriptGroupLogParseConfig.HoeingDelay, out hoeingDelay)) + { + foreach (var actionItem in actionItems) + { + actionItem.Time = SubtractFiveSeconds(actionItem.Time,hoeingDelay); + } + } + } - return GenerHtmlByConfigGroupEntity(configGroups, "日志分析", colConfigs,col2Configs, actionItems, msColConfigs); + return GenerHtmlByConfigGroupEntity(configGroups, "日志分析", colConfigList.ToArray(),col2Configs, actionItems, msColConfigs); } public static string ConcatenateStrings(string a, string b) { @@ -373,6 +468,8 @@ namespace LogParse html.AppendLine(" table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }"); html.AppendLine(" th, td { border: 1px solid black; padding: 8px; text-align: left; }"); html.AppendLine(" th { background-color: #f2f2f2; }"); + html.AppendLine(" tr:nth-child(odd) { background-color: #eaeaea; /* 奇数行颜色 */ }"); + html.AppendLine(" tr:nth-child(even) { background-color: #f9f9f9; /* 偶数行颜色 */}"); html.AppendLine(" "); html.AppendLine(""); html.AppendLine(""); diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs b/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs index 7588ab5d..688a01ff 100644 --- a/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs +++ b/BetterGenshinImpact/GameTask/LogParse/LogParseConfig.cs @@ -14,5 +14,7 @@ public partial class LogParseConfig : ObservableObject [ObservableProperty] private string _rangeValue = "CurrentConfig"; [ObservableProperty] private string _dayRangeValue = "7"; [ObservableProperty] private bool _hoeingStatsSwitch = false; + [ObservableProperty] private bool _faultStatsSwitch = false; + [ObservableProperty] private string _hoeingDelay= "0"; } } \ No newline at end of file diff --git a/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs b/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs index ae62e5ea..843039bd 100644 --- a/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs +++ b/BetterGenshinImpact/GameTask/LogParse/MoraStatistics.cs @@ -31,7 +31,12 @@ namespace LogParse { var ls = this.ActionItems.Where(item => item.ActionId == 28).ToList(); var count = ls.Count(); - return ls.Sum(item=>item.Num)+((count==0 || count>=10)?"":$"({count}/10)"); + if (count == 0) + { + return ""; + } + + return ls.Sum(item=>item.Num)+(count>=10?"":$"({count}/10)"); } } diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index 69b1ca29..f3e9b10a 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -21,7 +21,24 @@ namespace BetterGenshinImpact.Service; public partial class ScriptService : IScriptService { private readonly ILogger _logger = App.GetLogger(); + private static bool IsCurrentHourEqual(string input) + { + // 尝试将输入字符串转换为整数 + if (int.TryParse(input, out int hour)) + { + // 验证小时是否在合法范围内(0-23) + if (hour >= 0 && hour <= 23) + { + // 获取当前小时数 + int currentHour = DateTime.Now.Hour; + // 判断是否相等 + return currentHour == hour; + } + } + // 如果输入非数字或不合法,返回 false + return false; + } public async Task RunMulti(IEnumerable projectList, string? groupName = null) { groupName ??= "默认"; @@ -59,6 +76,13 @@ public partial class ScriptService : IScriptService foreach (var project in list) { + + if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + { + _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); + continue; + } + if (project.Status != "Enabled") { _logger.LogInformation("脚本 {Name} 状态为禁用,跳过执行", project.Name); @@ -85,6 +109,14 @@ public partial class ScriptService : IScriptService stopwatch.Reset(); stopwatch.Start(); await ExecuteProject(project); + + //多次执行时及时中断 + if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + { + _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); + break; + } + } catch (NormalEndException e) { @@ -175,6 +207,7 @@ public partial class ScriptService : IScriptService private async Task ExecuteProject(ScriptGroupProject project) { + if (project.Type == "Javascript") { if (project.Project == null) diff --git a/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml b/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml index 21912df1..1c5b8769 100644 --- a/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml +++ b/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml @@ -217,6 +217,7 @@ + diff --git a/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml b/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml index 970e8715..fe9cf668 100644 --- a/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml +++ b/BetterGenshinImpact/View/Pages/View/ScriptGroupConfigView.xaml @@ -282,6 +282,32 @@ IsChecked="{Binding PathingConfig.SoloTaskUseFightEnabled, Mode=TwoWay}" /> + + + + + + + + + + + + + projects = new(); + projects.AddRange(SelectedScriptGroup?.Projects.Reverse()); + SelectedScriptGroup.Projects.Clear(); + projects.ForEach(item=>SelectedScriptGroup.Projects.Add(item)); + WriteScriptGroup(SelectedScriptGroup); + } [RelayCommand] public void OnCopyScriptGroup(ScriptGroup? item) From bd72e6420d0e7f8f112f509b02e5ffc26737e2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sun, 26 Jan 2025 12:55:57 +0800 Subject: [PATCH 18/81] fist run old version clear --- .../ViewModel/MainWindowViewModel.cs | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs index dcbb3988..ef9e1895 100644 --- a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs +++ b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs @@ -102,12 +102,12 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel { // 预热OCR await OcrPreheating(); - + if (Environment.GetCommandLineArgs().Length > 1) { return; } - + // 自动处理目录配置 await Patch1(); @@ -158,19 +158,26 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel */ private async Task Patch1() { - if (Directory.Exists(Global.Absolute("BetterGI")) - // && File.Exists(Global.Absolute("BetterGI/BetterGI.exe")) - && Directory.Exists(Global.Absolute("BetterGI/User")) + var embeddedPath = Global.Absolute("BetterGI"); + var embeddedUserPath = Global.Absolute("BetterGI/User"); + var exePath = Global.Absolute("BetterGI/BetterGI.exe"); + if (Directory.Exists(embeddedPath) + && File.Exists(exePath) + && Directory.Exists(embeddedUserPath) ) { - var res = await MessageBox.ShowAsync("检测到旧的 BetterGI 配置,是否迁移配置并清理旧目录?", "BetterGI", System.Windows.MessageBoxButton.YesNo, MessageBoxImage.Question); - if (res == System.Windows.MessageBoxResult.Yes) + var fileVersionInfo = FileVersionInfo.GetVersionInfo(exePath); + // 低版本才需要迁移 + if (fileVersionInfo.FileVersion != null && !Global.IsNewVersion(fileVersionInfo.FileVersion)) { - var dir = Global.Absolute("BetterGI/User"); - // 迁移配置,拷贝整个目录并覆盖 - DirectoryHelper.CopyDirectory(dir, Global.Absolute("User")); - // 删除旧目录 - DirectoryHelper.DeleteDirectoryRecursively(Global.Absolute("BetterGI")); + var res = await MessageBox.ShowAsync("检测到旧的 BetterGI 配置,是否迁移配置并清理旧目录?", "BetterGI", System.Windows.MessageBoxButton.YesNo, MessageBoxImage.Question); + if (res == System.Windows.MessageBoxResult.Yes) + { + // 迁移配置,拷贝整个目录并覆盖 + DirectoryHelper.CopyDirectory(embeddedUserPath, Global.Absolute("User")); + // 删除旧目录 + DirectoryHelper.DeleteReadOnlyDirectory(embeddedPath); + } } } } From f0baf74dc871bc30c260c6329515a8ba17376994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sun, 26 Jan 2025 14:02:17 +0800 Subject: [PATCH 19/81] 0.40.0 --- BetterGenshinImpact/BetterGenshinImpact.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj index 2805db08..9e81a682 100644 --- a/BetterGenshinImpact/BetterGenshinImpact.csproj +++ b/BetterGenshinImpact/BetterGenshinImpact.csproj @@ -10,7 +10,7 @@ true Assets\Images\logo.ico BetterGI - 0.39.7 + 0.40.0 x64 embedded From af0a869c7099ce62949ec160d637ec267c5fa877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sun, 26 Jan 2025 17:09:19 +0800 Subject: [PATCH 20/81] shutdown when user config migrate --- BetterGenshinImpact/ViewModel/MainWindowViewModel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs index ef9e1895..2ba43d9c 100644 --- a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs +++ b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs @@ -177,6 +177,8 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel DirectoryHelper.CopyDirectory(embeddedUserPath, Global.Absolute("User")); // 删除旧目录 DirectoryHelper.DeleteReadOnlyDirectory(embeddedPath); + await MessageBox.InformationAsync("迁移配置成功, 软件将自动退出,请手动重新启动 BetterGI!"); + Application.Current.Shutdown(); } } } From 10cb31af5742ed3000d1ee489ae6dea757db8dc0 Mon Sep 17 00:00:00 2001 From: zjl Date: Sun, 26 Jan 2025 18:46:42 +0800 Subject: [PATCH 21/81] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E5=BD=93=E6=88=98?= =?UTF-8?q?=E6=96=97=E8=84=9A=E6=9C=AC=E4=B8=AD=E4=BA=BA=E5=91=98=E4=B8=8D?= =?UTF-8?q?=E5=9C=A8=E9=98=9F=E4=BC=8D=E6=98=AF=E5=BC=95=E5=8F=91=E7=9A=84?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/AutoFight/AutoFightTask.cs | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs index 16ab96c9..20a50084 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs @@ -249,21 +249,30 @@ public class AutoFightTask : ISoloTask if (lastFightName != command.Name && actionSchedulerByCd.TryGetValue(command.Name,out skillCd)) { var avatar = combatScenes.Avatars.FirstOrDefault(a => a.Name == command.Name); - if (skillCd < 0) + if (avatar!=null) { - skillCd = FindMax([avatar.SkillCd,avatar.SkillHoldCd]); - } - var dif=(DateTime.UtcNow - avatar.LastSkillTime); - //当技能未冷却时,跳过此次出招 - if ((DateTime.UtcNow -avatar.LastSkillTime).TotalSeconds < skillCd) - { - if (skipFightName != command.Name) + if (skillCd < 0) { - Logger.LogInformation($"{command.Name}cd冷却为{skillCd}秒,剩余{skillCd-dif.TotalSeconds}秒,跳过此次行动"); + skillCd = FindMax([avatar.SkillCd,avatar.SkillHoldCd]); } - skipFightName = command.Name; + var dif=(DateTime.UtcNow - avatar.LastSkillTime); + //当技能未冷却时,跳过此次出招 + if ((DateTime.UtcNow -avatar.LastSkillTime).TotalSeconds < skillCd) + { + if (skipFightName != command.Name) + { + Logger.LogInformation($"{command.Name}cd冷却为{skillCd}秒,剩余{skillCd-dif.TotalSeconds}秒,跳过此次行动"); + } + skipFightName = command.Name; + continue; + } + } + else + { + Logger.LogInformation($"{command.Name}未在队伍中找到,跳过此次出手!"); continue; } + } From 0468854ac58934fc43b55d119a446b6bc5b88188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sun, 26 Jan 2025 18:47:35 +0800 Subject: [PATCH 22/81] fix auto fight NPE --- BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs index 16ab96c9..4c5ad732 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs @@ -248,7 +248,11 @@ public class AutoFightTask : ISoloTask double skillCd; if (lastFightName != command.Name && actionSchedulerByCd.TryGetValue(command.Name,out skillCd)) { - var avatar = combatScenes.Avatars.FirstOrDefault(a => a.Name == command.Name); + var avatar = combatScenes.SelectAvatar(command.Name); + if (avatar == null) + { + continue; + } if (skillCd < 0) { skillCd = FindMax([avatar.SkillCd,avatar.SkillHoldCd]); From 54e062d4907d93afe348a32ad2b03850dda6c15b Mon Sep 17 00:00:00 2001 From: zjl Date: Sun, 26 Jan 2025 18:48:28 +0800 Subject: [PATCH 23/81] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E4=B8=8A=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/AutoFight/AutoFightTask.cs | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs index 20a50084..16ab96c9 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs @@ -249,30 +249,21 @@ public class AutoFightTask : ISoloTask if (lastFightName != command.Name && actionSchedulerByCd.TryGetValue(command.Name,out skillCd)) { var avatar = combatScenes.Avatars.FirstOrDefault(a => a.Name == command.Name); - if (avatar!=null) + if (skillCd < 0) { - if (skillCd < 0) - { - skillCd = FindMax([avatar.SkillCd,avatar.SkillHoldCd]); - } - var dif=(DateTime.UtcNow - avatar.LastSkillTime); - //当技能未冷却时,跳过此次出招 - if ((DateTime.UtcNow -avatar.LastSkillTime).TotalSeconds < skillCd) - { - if (skipFightName != command.Name) - { - Logger.LogInformation($"{command.Name}cd冷却为{skillCd}秒,剩余{skillCd-dif.TotalSeconds}秒,跳过此次行动"); - } - skipFightName = command.Name; - continue; - } + skillCd = FindMax([avatar.SkillCd,avatar.SkillHoldCd]); } - else + var dif=(DateTime.UtcNow - avatar.LastSkillTime); + //当技能未冷却时,跳过此次出招 + if ((DateTime.UtcNow -avatar.LastSkillTime).TotalSeconds < skillCd) { - Logger.LogInformation($"{command.Name}未在队伍中找到,跳过此次出手!"); + if (skipFightName != command.Name) + { + Logger.LogInformation($"{command.Name}cd冷却为{skillCd}秒,剩余{skillCd-dif.TotalSeconds}秒,跳过此次行动"); + } + skipFightName = command.Name; continue; } - } From edaf5ac443f00338c303999450441c8a5c3a1107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=A6?= Date: Sun, 26 Jan 2025 21:35:20 +0800 Subject: [PATCH 24/81] more pick black item --- BetterGenshinImpact/User/pick_black_lists.json | 1 + 1 file changed, 1 insertion(+) diff --git a/BetterGenshinImpact/User/pick_black_lists.json b/BetterGenshinImpact/User/pick_black_lists.json index f123f4e7..ca35443b 100644 --- a/BetterGenshinImpact/User/pick_black_lists.json +++ b/BetterGenshinImpact/User/pick_black_lists.json @@ -324,6 +324,7 @@ "百晓", "伍德", "蓝川丞", + "蓝砚", "松本", "甘乐", "卯师傅", From 945085c34c28deab1d53af682e69443a5bb9223e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sun, 26 Jan 2025 23:10:17 +0800 Subject: [PATCH 25/81] typo --- BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml index e0fcc698..189ac0d2 100644 --- a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml @@ -559,7 +559,7 @@ From 489d13dbcf605843acf8550fe97d67032c289a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sun, 26 Jan 2025 23:48:13 +0800 Subject: [PATCH 26/81] =?UTF-8?q?add=20=E8=93=9D=E7=A0=9A=20in=20Elemental?= =?UTF-8?q?CollectAvatarConfigs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/AutoPathing/Handler/ElementalCollectHandler.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/BetterGenshinImpact/GameTask/AutoPathing/Handler/ElementalCollectHandler.cs b/BetterGenshinImpact/GameTask/AutoPathing/Handler/ElementalCollectHandler.cs index c8bf9d33..8e576430 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/Handler/ElementalCollectHandler.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/Handler/ElementalCollectHandler.cs @@ -112,6 +112,7 @@ public class ElementalCollectAvatarConfigs new ElementalCollectAvatar("鹿野院平藏", ElementalType.Anemo, true, true), new ElementalCollectAvatar("流浪者", ElementalType.Anemo, true, false), new ElementalCollectAvatar("闲云", ElementalType.Anemo, true, false), + new ElementalCollectAvatar("蓝砚", ElementalType.Anemo, true, false), new ElementalCollectAvatar("枫原万叶", ElementalType.Anemo, false, true), new ElementalCollectAvatar("珐露珊", ElementalType.Anemo, false, true), new ElementalCollectAvatar("琳妮特", ElementalType.Anemo, false, true), From 8d4038d2e894a261c258d4edf7bd1334828e4c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 27 Jan 2025 08:03:16 +0800 Subject: [PATCH 27/81] new appveyor build --- Build/setup_build_for_appveyor.cmd | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Build/setup_build_for_appveyor.cmd b/Build/setup_build_for_appveyor.cmd index 9170c40f..78d811f4 100644 --- a/Build/setup_build_for_appveyor.cmd +++ b/Build/setup_build_for_appveyor.cmd @@ -34,16 +34,5 @@ copy /y publish.7z .\MicaSetup\Resources\Setups\publish.7z if exist "%zipFile%" ( del /f /q "%zipfile%" ) rename publish.7z %archiveFile% -@echo [build uninst using vs2022] -msbuild MicaSetup\MicaSetup.Uninst.csproj /t:Rebuild /p:Configuration=Release /p:DeployOnBuild=true /p:PublishProfile=FolderProfile /restore - -@echo [build setup using vs2022] -copy /y .\MicaSetup\bin\Release\net472\MicaSetup.exe .\MicaSetup\Resources\Setups\Uninst.exe -msbuild MicaSetup\MicaSetup.csproj /t:Build /p:Configuration=Release /p:DeployOnBuild=true /p:PublishProfile=FolderProfile /restore - -@echo [finish] -del /f /q MicaSetup.exe -copy /y .\MicaSetup\bin\Release\net472\MicaSetup.exe .\ -rename MicaSetup.exe %setupFile% rd /s /q dist\BetterGI From 3019d1aefa81376fb9718b9e2710a0949bd78774 Mon Sep 17 00:00:00 2001 From: zjl Date: Mon, 27 Jan 2025 08:14:14 +0800 Subject: [PATCH 28/81] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E5=BC=95=E5=8F=91=E7=A9=BA=E6=8C=87=E9=92=88?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BetterGenshinImpact/Service/ScriptService.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index f3e9b10a..6f46bc06 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -76,12 +76,15 @@ public partial class ScriptService : IScriptService foreach (var project in list) { - - if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + if (project.GroupInfo != null) { - _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); - continue; + if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + { + _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); + continue; + } } + if (project.Status != "Enabled") { From e30e9195398606f223816e27048ec4f62c315b38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 27 Jan 2025 08:14:23 +0800 Subject: [PATCH 29/81] fix NullReferenceException #1063 --- BetterGenshinImpact/Service/ScriptService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index f3e9b10a..3c9c4a69 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -27,7 +27,7 @@ public partial class ScriptService : IScriptService if (int.TryParse(input, out int hour)) { // 验证小时是否在合法范围内(0-23) - if (hour >= 0 && hour <= 23) + if (hour is >= 0 and <= 23) { // 获取当前小时数 int currentHour = DateTime.Now.Hour; @@ -77,7 +77,7 @@ public partial class ScriptService : IScriptService foreach (var project in list) { - if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + if (project.GroupInfo is { Config.PathingConfig.Enabled: true } && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) { _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); continue; @@ -111,7 +111,7 @@ public partial class ScriptService : IScriptService await ExecuteProject(project); //多次执行时及时中断 - if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + if (project.GroupInfo is { Config.PathingConfig.Enabled: true } && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) { _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); break; From bdaace9c8b3273e52c42abd81954b29424a4bddc Mon Sep 17 00:00:00 2001 From: zjl Date: Mon, 27 Jan 2025 08:14:14 +0800 Subject: [PATCH 30/81] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E5=BC=95=E5=8F=91=E7=A9=BA=E6=8C=87=E9=92=88?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BetterGenshinImpact/Service/ScriptService.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index f3e9b10a..8e5f7356 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -76,12 +76,13 @@ public partial class ScriptService : IScriptService foreach (var project in list) { - - if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + + if (project.GroupInfo!=null && project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) { _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); continue; } + if (project.Status != "Enabled") { @@ -109,9 +110,9 @@ public partial class ScriptService : IScriptService stopwatch.Reset(); stopwatch.Start(); await ExecuteProject(project); - + //多次执行时及时中断 - if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + if (project.GroupInfo!=null && project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) { _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); break; From 9de4fd4dfa5bdc996592b997936055a516706958 Mon Sep 17 00:00:00 2001 From: zjl Date: Mon, 27 Jan 2025 08:17:41 +0800 Subject: [PATCH 31/81] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E4=BB=A3=E7=A0=81=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BetterGenshinImpact/Service/ScriptService.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index 8e5f7356..f3e9b10a 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -76,13 +76,12 @@ public partial class ScriptService : IScriptService foreach (var project in list) { - - if (project.GroupInfo!=null && project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + + if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) { _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); continue; } - if (project.Status != "Enabled") { @@ -110,9 +109,9 @@ public partial class ScriptService : IScriptService stopwatch.Reset(); stopwatch.Start(); await ExecuteProject(project); - + //多次执行时及时中断 - if (project.GroupInfo!=null && project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) + if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) { _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); break; From 8fdc664400dcfd66e98cfef30a0b859ba65842d2 Mon Sep 17 00:00:00 2001 From: zjl Date: Mon, 27 Jan 2025 08:42:33 +0800 Subject: [PATCH 32/81] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BetterGenshinImpact/Service/ScriptService.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index 6f46bc06..f3e9b10a 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -76,15 +76,12 @@ public partial class ScriptService : IScriptService foreach (var project in list) { - if (project.GroupInfo != null) + + if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) { - if (project.GroupInfo.Config.PathingConfig.Enabled && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) - { - _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); - continue; - } + _logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!"); + continue; } - if (project.Status != "Enabled") { From 3ce54801c6bc38a79ff16902d9d4581e5b1c83bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 27 Jan 2025 09:22:11 +0800 Subject: [PATCH 33/81] notify icon: check update --- BetterGenshinImpact/Service/UpdateService.cs | 28 +++++-------- .../View/Windows/CheckUpdateWindow.xaml | 3 +- .../View/Windows/CheckUpdateWindow.xaml.cs | 11 ++++- .../ViewModel/NotifyIconViewModel.cs | 41 ++++--------------- 4 files changed, 28 insertions(+), 55 deletions(-) diff --git a/BetterGenshinImpact/Service/UpdateService.cs b/BetterGenshinImpact/Service/UpdateService.cs index a483ccff..34575838 100644 --- a/BetterGenshinImpact/Service/UpdateService.cs +++ b/BetterGenshinImpact/Service/UpdateService.cs @@ -26,7 +26,6 @@ public class UpdateService : IUpdateService private readonly ILogger _logger; private readonly IConfigService _configService; - private const string HashUrl = "https://raw.githubusercontent.com/bettergi/bettergi-installation-data/refs/heads/main/hash.json"; private const string NoticeUrl = "https://hui-config.oss-cn-hangzhou.aliyuncs.com/bgi/notice.json"; private const string DownloadPageUrl = "https://bgi.huiyadan.com/download.html"; @@ -61,16 +60,22 @@ public class UpdateService : IUpdateService if (!Global.IsNewVersion(newVersion)) { + if (option.Trigger == UpdateTrigger.Manual) + { + await MessageBox.InformationAsync("当前已是最新版本!"); + } + return; } if (!string.IsNullOrEmpty(Config.NotShowNewVersionNoticeEndVersion) - && !Global.IsNewVersion(Config.NotShowNewVersionNoticeEndVersion, newVersion)) + && !Global.IsNewVersion(Config.NotShowNewVersionNoticeEndVersion, newVersion) + && option.Trigger == UpdateTrigger.Auto) { return; } - CheckUpdateWindow win = new() + CheckUpdateWindow win = new(option) { Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner, @@ -78,7 +83,6 @@ public class UpdateService : IUpdateService UserInteraction = async (sender, button) => { CheckUpdateWindow win = (CheckUpdateWindow)sender; - CancellationTokenSource? tokenSource = new(); switch (button) { @@ -114,20 +118,8 @@ public class UpdateService : IUpdateService break; case CheckUpdateWindow.CheckUpdateWindowButton.Cancel: - if (tokenSource != null) - { - if (MessageBox.Question("正在更新中,确定要取消更新吗?") == MessageBoxResult.Yes) - { - win.ShowUpdateStatus = false; - tokenSource?.Cancel(); - win.Close(); - } - } - else - { - win.ShowUpdateStatus = false; - win.Close(); - } + win.ShowUpdateStatus = false; + win.Close(); break; } } diff --git a/BetterGenshinImpact/View/Windows/CheckUpdateWindow.xaml b/BetterGenshinImpact/View/Windows/CheckUpdateWindow.xaml index 77e1e868..6c984825 100644 --- a/BetterGenshinImpact/View/Windows/CheckUpdateWindow.xaml +++ b/BetterGenshinImpact/View/Windows/CheckUpdateWindow.xaml @@ -51,7 +51,8 @@ Appearance="Success" Command="{Binding UpdateCommand}" Content="立即更新" /> - ()!.CheckUpdateAsync(new UpdateOption { - using var httpClient = new HttpClient(); - 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"); - var jsonDict = JsonConvert.DeserializeObject>(jsonString); - - if (jsonDict != null) - { - string? name = jsonDict["name"] as string; - string? body = jsonDict["body"] as string; - string md = $"# {name}{new string('\n', 2)}{body}"; - - md = WebUtility.HtmlEncode(md); - string md2html = ResourceHelper.GetString($"pack://application:,,,/Assets/Strings/md2html.html", Encoding.UTF8); - var html = md2html.Replace("{{content}}", md); - - WebpageWindow win = new() - { - Title = "更新日志", - Width = 800, - Height = 600, - Owner = Application.Current.MainWindow, - WindowStartupLocation = WindowStartupLocation.CenterOwner - }; - - win.NavigateToHtml(html); - win.ShowDialog(); - } - } - catch (Exception e) - { - _ = e; - } + Trigger = UpdateTrigger.Manual + }); } } @@ -100,6 +72,7 @@ file static class WindowBacktray { window.Visibility = Visibility.Visible; } + if (window.WindowState == WindowState.Minimized) { nint hWnd = new WindowInteropHelper(Application.Current.MainWindow).Handle; @@ -107,4 +80,4 @@ file static class WindowBacktray } } } -} +} \ No newline at end of file From 3fea7963ce8965f887181e3d92f97f544a937f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 27 Jan 2025 10:44:19 +0800 Subject: [PATCH 34/81] Update README.md --- README.md | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index e8eb228f..c81e0091 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@

- +
- BetterGI + BetterGI

babalae%2Fbetter-genshin-impact | Trendshift
@@ -21,27 +21,27 @@ BetterGI · 更好的原神, 一个基于计算机视觉技术,意图让原 ## 功能 * 实时任务 - * [自动拾取](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E6%8B%BE%E5%8F%96):遇到可交互/拾取内容时自动按 F,支持黑白名单配置 - * [自动剧情](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E5%89%A7%E6%83%85):快速点击过剧情、自动选择选项、自动提交物品、关闭弹出书页等 - * 与凯瑟琳对话时有橙色选项会 [自动领取「每日委托」奖励](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E9%A2%86%E5%8F%96%E3%80%8E%E6%AF%8F%E6%97%A5%E5%A7%94%E6%89%98%E3%80%8F%E5%A5%96%E5%8A%B1)、[自动重新派遣](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E9%87%8D%E6%96%B0%E6%B4%BE%E9%81%A3) - * [自动邀约](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E9%82%80%E7%BA%A6):自动剧情开启的情况下此功能才会生效,自动选择邀约选项 - * [快速传送](http://bgi.huiyadan.com/feats/domain.html):在地图上点击传送点,或者点击后出现的列表中存在传送点,会自动点击传送点并传送 - * [全自动钓鱼](https://bgi.huiyadan.com/doc.html#%E5%85%A8%E8%87%AA%E5%8A%A8%E9%92%93%E9%B1%BC):AI 识别自动抛竿,鱼上钩时自动收杆,并自动完成钓鱼进度 - * [自动烹饪](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E7%83%B9%E9%A5%AA):自动在完美区域完成食物烹饪,暂不支持“仙跳墙” + * [自动拾取](https://bettergi.com/doc.html#%E8%87%AA%E5%8A%A8%E6%8B%BE%E5%8F%96):遇到可交互/拾取内容时自动按 F,支持黑白名单配置 + * [自动剧情](https://bettergi.com/doc.html#%E8%87%AA%E5%8A%A8%E5%89%A7%E6%83%85):快速点击过剧情、自动选择选项、自动提交物品、关闭弹出书页等 + * 与凯瑟琳对话时有橙色选项会 [自动领取「每日委托」奖励](https://bettergi.com/doc.html#%E8%87%AA%E5%8A%A8%E9%A2%86%E5%8F%96%E3%80%8E%E6%AF%8F%E6%97%A5%E5%A7%94%E6%89%98%E3%80%8F%E5%A5%96%E5%8A%B1)、[自动重新派遣](https://bettergi.com/doc.html#%E8%87%AA%E5%8A%A8%E9%87%8D%E6%96%B0%E6%B4%BE%E9%81%A3) + * [自动邀约](https://bettergi.com/doc.html#%E8%87%AA%E5%8A%A8%E9%82%80%E7%BA%A6):自动剧情开启的情况下此功能才会生效,自动选择邀约选项 + * [快速传送](http://bettergi.com/feats/domain.html):在地图上点击传送点,或者点击后出现的列表中存在传送点,会自动点击传送点并传送 + * [全自动钓鱼](https://bettergi.com/doc.html#%E5%85%A8%E8%87%AA%E5%8A%A8%E9%92%93%E9%B1%BC):AI 识别自动抛竿,鱼上钩时自动收杆,并自动完成钓鱼进度 + * [自动烹饪](https://bettergi.com/doc.html#%E8%87%AA%E5%8A%A8%E7%83%B9%E9%A5%AA):自动在完美区域完成食物烹饪,暂不支持“仙跳墙” * 独立任务 - * [全自动七圣召唤](https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E4%B8%83%E5%9C%A3%E5%8F%AC%E5%94%A4):帮助你轻松完成七圣召唤角色邀请、每周来客挑战等 PVE 内容 - * [自动伐木](http://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E4%BC%90%E6%9C%A8):自动 Z 键使用「王树瑞佑」,利用上下线可以刷新木材的原理,挂机刷满一背包的木材 - * [自动战斗](http://bgi.huiyadan.com/feats/domain.html):编写战斗脚本,让队伍按照你的策略进行自动战斗 - * [自动秘境](http://bgi.huiyadan.com/feats/domain.html):全自动秘境挂机刷体力,自动循环进入秘境开启钥匙、战斗、走到古树并领取奖励 - * [自定音游](https://bgi.huiyadan.com/feats/task/music.html):全自动秘境挂机刷体力,自动循环进入秘境开启钥匙、战斗、走到古树并领取奖励 + * [全自动七圣召唤](https://bettergi.com/doc.html#%E8%87%AA%E5%8A%A8%E4%B8%83%E5%9C%A3%E5%8F%AC%E5%94%A4):帮助你轻松完成七圣召唤角色邀请、每周来客挑战等 PVE 内容 + * [自动伐木](http://bettergi.com/doc.html#%E8%87%AA%E5%8A%A8%E4%BC%90%E6%9C%A8):自动 Z 键使用「王树瑞佑」,利用上下线可以刷新木材的原理,挂机刷满一背包的木材 + * [自动秘境](http://bettergi.com/feats/domain.html):全自动秘境挂机刷体力,自动循环进入秘境开启钥匙、战斗、走到古树并领取奖励 + * [自动音游](https://bettergi.com/feats/task/music.html):一键自动完成千音雅集的专辑,快速获取成就 * 全自动 - * 一条龙 - * + * [一条龙](https://github.com/babalae/better-genshin-impact/issues/846):一键完成日常(使用历练点),并领取奖励 + * [自动采集/挖矿/锄地](https://bettergi.com/feats/autos/pathing.html):通过左上角小地图的识别,完成自动采集、挖矿、锄地等功能 + * [键鼠录制](https://bettergi.com/feats/autos/kmscript.html):可以录制回放当前的键鼠操作,建议配合调度器使用 * 操控辅助 - * [那维莱特转圈](https://bgi.huiyadan.com/doc.html#%E9%82%A3%E7%BB%B4%E8%8E%B1%E7%89%B9-%E8%BD%AC%E5%9C%88%E5%9C%88):设置快捷键后,长按可以不断水平旋转视角(当然你也可以用来转草神) - * [快速圣遗物强化](https://bgi.huiyadan.com/doc.html#%E5%9C%A3%E9%81%97%E7%89%A9%E4%B8%80%E9%94%AE%E5%BC%BA%E5%8C%96):通过快速切换“详情”、“强化”页跳过圣遗物强化结果展示,快速+20 - * [商店一键购买](https://bgi.huiyadan.com/doc.html#%E5%9C%A3%E9%81%97%E7%89%A9%E4%B8%80%E9%94%AE%E5%BC%BA%E5%8C%96):可以快速以满数量购买商店中的物品,适合快速清空活动兑换,尘歌壶商店兑换等 -* [**……**](https://bgi.huiyadan.com/doc.html) + * [那维莱特转圈](https://bettergi.com/doc.html#%E9%82%A3%E7%BB%B4%E8%8E%B1%E7%89%B9-%E8%BD%AC%E5%9C%88%E5%9C%88):设置快捷键后,长按可以不断水平旋转视角(当然你也可以用来转草神) + * [快速圣遗物强化](https://bettergi.com/doc.html#%E5%9C%A3%E9%81%97%E7%89%A9%E4%B8%80%E9%94%AE%E5%BC%BA%E5%8C%96):通过快速切换“详情”、“强化”页跳过圣遗物强化结果展示,快速+20 + * [商店一键购买](https://bettergi.com/doc.html#%E5%9C%A3%E9%81%97%E7%89%A9%E4%B8%80%E9%94%AE%E5%BC%BA%E5%8C%96):可以快速以满数量购买商店中的物品,适合快速清空活动兑换,尘歌壶商店兑换等 +* [**……**](https://bettergi.com/doc.html)
@@ -58,9 +58,9 @@ BetterGI · 更好的原神, 一个基于计算机视觉技术,意图让原 > [!NOTE] > 下载地址:[⚡Github 下载](https://github.com/babalae/better-genshin-impact/releases) > -> 不知道下载哪个?第一次使用?请看:[快速上手](https://bgi.huiyadan.com/quickstart.html) , 遇到问题请先看:[常见问题](https://bgi.huiyadan.com/faq.html) +> 不知道下载哪个?第一次使用?请看:[快速上手](https://bettergi.com/quickstart.html) , 遇到问题请先看:[常见问题](https://bettergi.com/faq.html) -最新编译版本(无地图特征数据)可以从自动构建中获取: [![Build status](https://ci.appveyor.com/api/projects/status/cklcy1oj9u66ul4j)](https://ci.appveyor.com/project/huiyadanli/better-genshin-impact/build/artifacts) +最新编译版本可以从自动构建中获取: [![](https://github.com/babalae/bettergi-publish/actions/workflows/publish.yml/badge.svg)](https://github.com/babalae/bettergi-publish/actions) ## 使用方法 由于图像识别比较吃性能,低配置电脑可能无法正常使用部分功能。 @@ -79,16 +79,16 @@ BetterGI · 更好的原神, 一个基于计算机视觉技术,意图让原 **打开软件以后,在“启动”页选择好截图方式,点击启动按钮就可以享受 BetterGI 带来的便利了!** -详细使用指南请看:[快速上手](https://bgi.huiyadan.com/quickstart.html) +详细使用指南请看:[快速上手](https://bettergi.com/quickstart.html) -具体功能效果与使用方式见:[文档](https://bgi.huiyadan.com/doc.html) +具体功能效果与使用方式见:[文档](https://bettergi.com/doc.html) ## FAQ * 为什么需要管理员权限? * 因为游戏是以管理员权限启动的,软件不以管理员权限启动的话没有权限模拟鼠标点击。 * 会不会封号? * 理论上不会被封。 **BetterGI 不会做出任何修改游戏文件、读写游戏内存等任何危害游戏本体的行为,单纯依靠视觉算法和模拟操作实现。** 但是mhy是自由的,用户条款上明确说明第三方软件/模拟操作是封号理由之一。当前方案还是存在被检测的可能。只能说请低调使用,请不要跳脸官方。 -* [更多常见问题...](https://bgi.huiyadan.com/faq.html) +* [更多常见问题...](https://bettergi.com/faq.html) ## 致谢 @@ -101,6 +101,7 @@ BetterGI · 更好的原神, 一个基于计算机视觉技术,意图让原 * [genshin_impact_assistant](https://github.com/infstellar/genshin_impact_assistant) * [HutaoFisher](https://github.com/myHuTao-qwq/HutaoFisher) * [minimap](https://github.com/tignioj/minimap) +* [kachina-installer](https://github.com/YuehaiTeam/kachina-installer) 另外特别感谢 [@Lightczx](https://github.com/Lightczx) 和 [@emako](https://github.com/emako) 对本项目的指导与贡献 From 2d0a7b5da85d1cb1d4f28aa212b43ab8274cd6f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 27 Jan 2025 13:56:27 +0800 Subject: [PATCH 35/81] typo --- BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs b/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs index 7d4c26a0..c3ea2ca6 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs @@ -168,7 +168,7 @@ public class CombatScenes : IDisposable if (result.TopClass.Confidence < 0.51) { Cv2.ImWrite(@"log\avatar_side_classify_error.png", src.ToMat()); - throw new Exception($"无法识别第{index}位角色,置信度{result.TopClass.Confidence:F1},结果:{result.TopClass.Name.Name}。请重新阅读了文档中的《快速上手》!"); + throw new Exception($"无法识别第{index}位角色,置信度{result.TopClass.Confidence:F1},结果:{result.TopClass.Name.Name}。请重新阅读 BetterGI 文档中的《快速上手》!"); } } else @@ -176,7 +176,7 @@ public class CombatScenes : IDisposable if (result.TopClass.Confidence < 0.7) { Cv2.ImWrite(@"log\avatar_side_classify_error.png", src.ToMat()); - throw new Exception($"无法识别第{index}位角色,置信度{result.TopClass.Confidence:F1},结果:{result.TopClass.Name.Name}。请重新阅读了文档中的《快速上手》!"); + throw new Exception($"无法识别第{index}位角色,置信度{result.TopClass.Confidence:F1},结果:{result.TopClass.Name.Name}。请重新阅读 BetterGI 文档中的《快速上手》!"); } } From 6a14a8c342090e0ebc181129c8e8b602ee1cdcb6 Mon Sep 17 00:00:00 2001 From: zjl Date: Mon, 27 Jan 2025 15:14:28 +0800 Subject: [PATCH 36/81] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E5=87=A0?= =?UTF-8?q?=E4=B8=AAwarning=E8=AD=A6=E5=91=8A=E7=9A=84=E5=9C=B0=E6=96=B9?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E8=B7=AF=E5=BE=84=E8=BF=BD=E8=B8=AA?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=97=B6=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=8E=92?= =?UTF-8?q?=E9=99=A4=E5=B7=B2=E9=80=89=E6=8B=A9=E7=9B=AE=E5=BD=95=E7=9A=84?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E6=9D=A1=E4=BB=B6=EF=BC=8C=E8=B0=83=E5=BA=A6?= =?UTF-8?q?=E5=99=A8=E4=BB=BB=E5=8A=A1=E5=8F=B3=E9=94=AE=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=96=87=E4=BB=B6=E5=A4=B9=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/LogParse/LogParse.cs | 2 +- .../Helpers/Ui/FileTreeNodeHelper.cs | 104 ++++++++++++- .../View/Pages/ScriptControlPage.xaml | 16 ++ .../ViewModel/Pages/ScriptControlViewModel.cs | 138 +++++++++++++----- 4 files changed, 225 insertions(+), 35 deletions(-) diff --git a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs index d5b4b058..ad3e83b1 100644 --- a/BetterGenshinImpact/GameTask/LogParse/LogParse.cs +++ b/BetterGenshinImpact/GameTask/LogParse/LogParse.cs @@ -386,7 +386,7 @@ namespace LogParse return "Invalid input time format. Please use 'yyyy-MM-dd HH:mm:ss'."; } } - public static string GenerHtmlByConfigGroupEntity(List configGroups, GameInfo gameInfo,LogParseConfig.ScriptGroupLogParseConfig scriptGroupLogParseConfig) + public static string GenerHtmlByConfigGroupEntity(List configGroups, GameInfo? gameInfo,LogParseConfig.ScriptGroupLogParseConfig scriptGroupLogParseConfig) { (string name, Func value)[] colConfigs = [ diff --git a/BetterGenshinImpact/Helpers/Ui/FileTreeNodeHelper.cs b/BetterGenshinImpact/Helpers/Ui/FileTreeNodeHelper.cs index 574cc437..554fe52c 100644 --- a/BetterGenshinImpact/Helpers/Ui/FileTreeNodeHelper.cs +++ b/BetterGenshinImpact/Helpers/Ui/FileTreeNodeHelper.cs @@ -1,4 +1,7 @@ -using BetterGenshinImpact.Model; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using BetterGenshinImpact.Model; using System.IO; using System.Linq; @@ -54,4 +57,103 @@ public class FileTreeNodeHelper parentNode.Children.Add(fileNode); } } + + /// + /// 根据路径过滤树形结构,排除指定路径的节点 + /// + /// 节点数据类型 + /// 树形结构的根节点集合 + /// 要排除的路径集合 + /// 过滤后的树形结构 + public static ObservableCollection> FilterTree( + ObservableCollection> nodes, + List folderNames) + { + // 递归过滤节点 + ObservableCollection> FilterNodes(ObservableCollection> inputNodes, List paths) + { + var filteredNodes = new ObservableCollection>(); + + foreach (var node in inputNodes) + { + // 获取当前层需要排除的路径 + var matchedPaths = paths + .Where(path => IsPathMatch(node.FileName ??"", path)) + .Select(path => GetRemainingPath(node.FileName ?? "" , path)) + .Where(remainingPath => remainingPath != null) + .ToList(); + + // 如果当前路径完全匹配,跳过当前节点 + if (matchedPaths.Any(path => path == "")) + { + continue; + } + + // 递归对子节点过滤 + node.Children = FilterNodes(node.Children, matchedPaths); + + // 添加过滤后的节点 + filteredNodes.Add(node); + } + + return filteredNodes; + } + + return FilterNodes(nodes, folderNames); + } + + /// + /// 判断文件路径是否匹配多级路径的前缀 + /// + /// 当前节点路径 + /// 目标路径 + /// 是否匹配 + private static bool IsPathMatch(string fileName, string path) + { + // 匹配路径是否以指定前缀开始,路径分隔符对齐 + return path.StartsWith(fileName, StringComparison.OrdinalIgnoreCase) + && (path.Length == fileName.Length || path[fileName.Length] == '\\'); + } + + /// + /// 获取路径中去掉当前节点后的剩余路径 + /// + /// 当前节点路径 + /// 完整路径 + /// 剩余路径,如果不匹配返回 null + private static string? GetRemainingPath(string fileName, string path) + { + if (IsPathMatch(fileName, path)) + { + return path.Length > fileName.Length ? path.Substring(fileName.Length + 1) : ""; + } + return null; + } + public static ObservableCollection> FilterEmptyNodes(ObservableCollection> nodes) + { + // 递归过滤节点 + ObservableCollection> Filter(ObservableCollection> inputNodes) + { + var filteredNodes = new ObservableCollection>(); + + foreach (var node in inputNodes) + { + // 递归处理子节点 + node.Children = Filter(node.Children); + + // 如果是目录并且没有子节点,跳过当前节点 + if (node.IsDirectory && !node.Children.Any()) + { + continue; + } + + // 其他情况保留节点 + filteredNodes.Add(node); + } + + return filteredNodes; + } + + return Filter(nodes); + } } diff --git a/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml b/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml index 1c5b8769..6c615f85 100644 --- a/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml +++ b/BetterGenshinImpact/View/Pages/ScriptControlPage.xaml @@ -331,6 +331,22 @@ + + + + + diff --git a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs index 83979c9f..1ef7337d 100644 --- a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs @@ -11,7 +11,6 @@ using System.Text.Json; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; -using System.Windows.Controls.Primitives; using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.Core.Script; using BetterGenshinImpact.Core.Script.Group; @@ -30,6 +29,7 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using LogParse; using Microsoft.Extensions.Logging; +using SharpCompress; using Wpf.Ui; using Wpf.Ui.Controls; using Wpf.Ui.Violeta.Controls; @@ -107,25 +107,32 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware [RelayCommand] private void ClearTasks() { + if (SelectedScriptGroup == null) + { + return; + } SelectedScriptGroup.Projects.Clear(); WriteScriptGroup(SelectedScriptGroup); } [RelayCommand] private async Task OpenLogParse() { - - GameInfo gameInfo = null; + if (SelectedScriptGroup == null) + { + return; + } + GameInfo? gameInfo = null; var config = LogParse.LogParse.LoadConfig(); if (!string.IsNullOrEmpty(config.Cookie)) { config.CookieDictionary.TryGetValue(config.Cookie, out gameInfo); } - LogParseConfig.ScriptGroupLogParseConfig sgpc; - if (!config.ScriptGroupLogDictionary.TryGetValue(_selectedScriptGroup.Name,out sgpc)) + LogParseConfig.ScriptGroupLogParseConfig? sgpc; + if (!config.ScriptGroupLogDictionary.TryGetValue(SelectedScriptGroup.Name,out sgpc)) { sgpc=new LogParseConfig.ScriptGroupLogParseConfig(); } - + // 创建 StackPanel var stackPanel = new StackPanel @@ -265,9 +272,9 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware PrimaryButtonText = "确定", Owner = Application.Current.MainWindow, }; - questionButton.Click += (sender, args) => - { + void OnQuestionButtonOnClick(object sender, RoutedEventArgs args) + { WebpageWindow cookieWin = new() { Title = "日志分析", @@ -278,8 +285,9 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware }; cookieWin.NavigateToHtml(TravelsDiaryDetailManager.generHtmlMessage()); cookieWin.Show(); + } - }; + questionButton.Click += OnQuestionButtonOnClick; //对象赋值 rangeComboBox.SelectedValue = sgpc.RangeValue; @@ -305,7 +313,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware sgpc.HoeingDelay = hoeingDelayTextBox.Text; config.Cookie = cookieValue; - config.ScriptGroupLogDictionary[_selectedScriptGroup.Name]=sgpc; + config.ScriptGroupLogDictionary[SelectedScriptGroup.Name]=sgpc; LogParse.LogParse.WriteConfigFile(config); @@ -339,7 +347,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware Toast.Warning("未填写cookie,此次将不启用锄地统计!"); } //真正存储的gameinfo - GameInfo realGameInfo = gameInfo; + GameInfo? realGameInfo = gameInfo; //统计锄地开关打开,并且不为cookie不为空 if ((hoeingStatsSwitch.IsChecked ?? false) && !string.IsNullOrEmpty(cookieValue)) { @@ -350,7 +358,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware Toast.Success($"米游社数据获取成功,开始进行解析,请耐心等待!"); } - catch (Exception e) + catch (Exception) { if (realGameInfo!=null) { @@ -378,7 +386,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware var configGroupEntities = LogParse.LogParse.ParseFile(fs); if (rangeValue == "CurrentConfig") { //Toast.Success(_selectedScriptGroup.Name); - configGroupEntities =configGroupEntities.Where(item => _selectedScriptGroup.Name == item.Name).ToList(); + configGroupEntities =configGroupEntities.Where(item => SelectedScriptGroup.Name == item.Name).ToList(); } if (configGroupEntities.Count == 0) { @@ -414,11 +422,11 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware ScriptRepoUpdater.Instance.OpenLocalRepoInWebView(); } [RelayCommand] - private async Task UpdateTasks() + private void UpdateTasks() { List projects = new(); List oldProjects = new(); - oldProjects.AddRange(SelectedScriptGroup?.Projects); + oldProjects.AddRange(SelectedScriptGroup?.Projects ?? []); var oldcount = oldProjects.Count; List folderNames = new(); foreach (var project in oldProjects) @@ -451,25 +459,25 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware } } - SelectedScriptGroup.Projects.Clear(); + SelectedScriptGroup?.Projects.Clear(); foreach (var scriptGroupProject in projects) { SelectedScriptGroup?.AddProject(scriptGroupProject); } Toast.Success($"增加了{projects.Count - oldcount}个路径追踪任务"); - WriteScriptGroup(SelectedScriptGroup); - + if (SelectedScriptGroup != null) WriteScriptGroup(SelectedScriptGroup); } [RelayCommand] private void ReverseTaskOrder() { + List projects = new(); - projects.AddRange(SelectedScriptGroup?.Projects.Reverse()); - SelectedScriptGroup.Projects.Clear(); - projects.ForEach(item=>SelectedScriptGroup.Projects.Add(item)); - WriteScriptGroup(SelectedScriptGroup); + projects.AddRange(SelectedScriptGroup?.Projects.Reverse() ?? []); + SelectedScriptGroup?.Projects.Clear(); + projects.ForEach(item=>SelectedScriptGroup?.Projects.Add(item)); + if (SelectedScriptGroup != null) WriteScriptGroup(SelectedScriptGroup); } [RelayCommand] @@ -498,8 +506,12 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware else { var newScriptGroup =JsonSerializer.Deserialize(JsonSerializer.Serialize(item)) ; - newScriptGroup.Name = str; - ScriptGroups.Add(newScriptGroup); + if (newScriptGroup != null) + { + newScriptGroup.Name = str; + ScriptGroups.Add(newScriptGroup); + } + //WriteScriptGroup(newScriptGroup); } } @@ -628,12 +640,26 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware private ScrollViewer CreatePathingScriptSelectionPanel(IEnumerable> list) { var stackPanel = new StackPanel(); + CheckBox excludeCheckBox = new CheckBox + { + Content = "排除已选择过的目录", + VerticalAlignment = VerticalAlignment.Center, + }; + stackPanel.Children.Add(excludeCheckBox); + var filterTextBox = new TextBox { Margin = new Thickness(0, 0, 0, 10), - PlaceholderText = "输入筛选条件..." + PlaceholderText = "输入筛选条件...", + }; + filterTextBox.TextChanged += delegate + { + ApplyFilter(stackPanel, list, filterTextBox.Text, excludeCheckBox.IsChecked); + }; + excludeCheckBox.Click += delegate + { + ApplyFilter(stackPanel, list, filterTextBox.Text, excludeCheckBox.IsChecked); }; - filterTextBox.TextChanged += (s, e) => ApplyFilter(stackPanel, list, filterTextBox.Text); stackPanel.Children.Add(filterTextBox); AddNodesToPanel(stackPanel, list, 0, filterTextBox.Text); @@ -647,14 +673,50 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware return scrollViewer; } - private void ApplyFilter(StackPanel parentPanel, IEnumerable> nodes, string filter) + private void ApplyFilter(StackPanel parentPanel, IEnumerable> nodes, string filter,bool? excludeSelectedFolder = false) { - if (parentPanel.Children.Count > 0 && parentPanel.Children[0] is TextBox filterTextBox) + if (parentPanel.Children.Count > 0) + { + List removeElements = new List(); + foreach (UIElement parentPanelChild in parentPanel.Children) + { + if (parentPanelChild is FrameworkElement frameworkElement && frameworkElement.Name.StartsWith("dynamic_")) + { + removeElements.Add(frameworkElement); + } + + } + removeElements.ForEach(parentPanel.Children.Remove); + } + + if (excludeSelectedFolder ?? false) + { + + List skipFolderNames = SelectedScriptGroup?.Projects.ToList().Select(item=>item.FolderName).Distinct().ToList() ?? []; + //复制Nodes + string jsonString = JsonSerializer.Serialize(nodes); + var copiedNodes = JsonSerializer.Deserialize>>(jsonString); + if (copiedNodes!=null) + { + //路径过滤 + copiedNodes = FileTreeNodeHelper.FilterTree(copiedNodes, skipFolderNames); + copiedNodes = FileTreeNodeHelper.FilterEmptyNodes(copiedNodes); + AddNodesToPanel(parentPanel, copiedNodes, 0,filter); + } + + } + else + { + AddNodesToPanel(parentPanel, nodes, 0,filter); + } + + + /*if (parentPanel.Children.Count > 0 && parentPanel.Children[1] is TextBox filterTextBox) { parentPanel.Children.Clear(); parentPanel.Children.Add(filterTextBox); // 保留筛选框 AddNodesToPanel(parentPanel, nodes, 0, filter); - } + }*/ } private void AddNodesToPanel(StackPanel parentPanel, IEnumerable> nodes, int depth, string filter) @@ -671,6 +733,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware Content = node.FileName, Tag = node.FilePath, Margin = new Thickness(depth * 30, 0, 0, 0) // 根据深度计算Margin + ,Name = "dynamic_"+Guid.NewGuid().ToString().Replace("-","_") }; if (node.IsDirectory) @@ -683,6 +746,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware Header = checkBox, Content = childPanel, IsExpanded = false // 默认不展开 + ,Name = "dynamic_"+Guid.NewGuid().ToString().Replace("-","_") }; checkBox.Checked += (s, e) => SetChildCheckBoxesState(childPanel, true); @@ -793,7 +857,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware [RelayCommand] private void AddNextFlag(ScriptGroupProject? item) { - if (item == null) + if (item == null || SelectedScriptGroup == null) { return; } @@ -805,8 +869,8 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware nextScheduledTask.Remove(nst); } - nextScheduledTask.Add((SelectedScriptGroup?.Name, item.Index, item.FolderName, item.Name)); - foreach (var item1 in SelectedScriptGroup.Projects) + nextScheduledTask.Add((SelectedScriptGroup?.Name ?? "", item.Index, item.FolderName, item.Name)); + foreach (var item1 in SelectedScriptGroup?.Projects ?? []) { item1.NextFlag = false; } @@ -878,7 +942,15 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware Toast.Warning("只有JS脚本才有自定义配置"); } } - + [RelayCommand] + public void OnDeleteScriptByFolder(ScriptGroupProject? item) + { + if (item == null) + { + return; + } + SelectedScriptGroup?.Projects.ToList().Where(item2=>item2.FolderName == item.FolderName).ForEach(OnDeleteScript); + } [RelayCommand] public void OnDeleteScript(ScriptGroupProject? item) { From 6c16296b1b51d055d5f38983d52f52e0bbc59004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 27 Jan 2025 20:13:53 +0800 Subject: [PATCH 37/81] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20notify=20config=20?= =?UTF-8?q?=E7=9A=84=E8=8E=B7=E5=8F=96=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Notification/NotificationHelper.cs | 3 ++- .../Service/Notification/NotificationService.cs | 11 +++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs index 3168dbfa..c097b6d7 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs @@ -1,6 +1,7 @@ using System.Drawing; using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.Core.Script.Group; +using BetterGenshinImpact.GameTask; using BetterGenshinImpact.GameTask.AutoDomain; using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Model; using BetterGenshinImpact.GameTask.Common; @@ -15,7 +16,7 @@ public class NotificationHelper { public static void Notify(INotificationData notificationData) { - if (NotificationService.Instance().Config.NotificationConfig.IncludeScreenShot)// TODO: 这个获取方式是否合理? + if (TaskContext.Instance().Config.NotificationConfig.IncludeScreenShot) { var screenShot = (Bitmap)TaskControl.CaptureToRectArea().SrcBitmap.Clone(); notificationData.Screenshot = screenShot; diff --git a/BetterGenshinImpact/Service/Notification/NotificationService.cs b/BetterGenshinImpact/Service/Notification/NotificationService.cs index bec2b048..4d5221cb 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationService.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationService.cs @@ -11,6 +11,7 @@ using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using BetterGenshinImpact.GameTask; namespace BetterGenshinImpact.Service.Notification; @@ -18,13 +19,11 @@ public class NotificationService : IHostedService { private static NotificationService? _instance; - private static readonly HttpClient _httpClient = new(); + private static readonly HttpClient NotifyHttpClient = new(); private readonly NotifierManager _notifierManager; - public AllConfig Config { get; set; } //TODO:除了public以外还能怎么获取这个Config? - public NotificationService(IConfigService configService, NotifierManager notifierManager) + public NotificationService(NotifierManager notifierManager) { - Config = configService.Get(); _notifierManager = notifierManager; _instance = this; InitializeNotifiers(); @@ -62,9 +61,9 @@ public class NotificationService : IHostedService private void InitializeNotifiers() { - if (Config.NotificationConfig.WebhookEnabled) + if (TaskContext.Instance().Config.NotificationConfig.WebhookEnabled) { - _notifierManager.RegisterNotifier(new WebhookNotifier(_httpClient, Config.NotificationConfig.WebhookEndpoint)); + _notifierManager.RegisterNotifier(new WebhookNotifier(NotifyHttpClient, TaskContext.Instance().Config.NotificationConfig.WebhookEndpoint)); } } From 670bb3adad8163683c9a5167054cb371a821b83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 27 Jan 2025 20:47:17 +0800 Subject: [PATCH 38/81] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8C=96=E6=96=B9=E5=BC=8F=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Notification/NotificationService.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/BetterGenshinImpact/Service/Notification/NotificationService.cs b/BetterGenshinImpact/Service/Notification/NotificationService.cs index 4d5221cb..d9b5f590 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationService.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationService.cs @@ -12,6 +12,7 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; using BetterGenshinImpact.GameTask; +using BetterGenshinImpact.Service.Notification.Model.Enum; namespace BetterGenshinImpact.Service.Notification; @@ -53,7 +54,7 @@ public class NotificationService : IHostedService // using object type here so it serializes the interface correctly var serializedData = JsonSerializer.Serialize(notificationData, new JsonSerializerOptions { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, }); return new StringContent(serializedData, Encoding.UTF8, "application/json"); @@ -82,7 +83,13 @@ public class NotificationService : IHostedService { return NotificationTestResult.Error("通知类型未启用"); } - await notifier.SendNotificationAsync(TransformData(new TestNotificationData())); + await notifier.SendNotificationAsync(TransformData(new TestNotificationData + { + Event = NotificationEvent.Test, + Action = NotificationAction.Started, + Conclusion = NotificationConclusion.Success, + Message = "测试通知" + })); return NotificationTestResult.Success(); } catch (NotifierException ex) From ce7c88f8e883ca75745ba2e63d6c905a894cc90a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=8B=E4=BA=91?= Date: Tue, 28 Jan 2025 02:38:26 +0800 Subject: [PATCH 39/81] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E4=B8=B4=E8=BF=91?= =?UTF-8?q?=E4=BC=A0=E9=80=81=E7=82=B9=E7=9A=84=E8=B7=9D=E7=A6=BB=E7=A1=AE?= =?UTF-8?q?=E5=AE=9A=E5=9C=B0=E5=9B=BE=E7=BC=A9=E6=94=BE=EF=BC=8C=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E7=BC=A9=E6=94=BE=E7=AD=89=E7=BA=A7=E7=A1=AE=E5=AE=9A?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E5=89=A9=E4=BD=99=E7=9A=84=E8=B7=9D=E7=A6=BB?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/AutoTrackPath/TpConfig.cs | 7 +- .../GameTask/AutoTrackPath/TpTask.cs | 146 +++++++++++++----- 2 files changed, 114 insertions(+), 39 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs index a084fcba..52715dc5 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpConfig.cs @@ -10,7 +10,7 @@ public partial class TpConfig : ObservableObject private bool _mapZoomEnabled = true; // 地图缩放开关 [ObservableProperty] - private int _mapZoomOutDistance = 2000; // 地图缩小的最小距离,单位:像素 + private int _mapZoomOutDistance = 1000; // 地图缩小的最小距离,单位:像素 [ObservableProperty] private int _mapZoomInDistance = 400; // 地图放大的最大距离,单位:像素 @@ -22,7 +22,7 @@ public partial class TpConfig : ObservableObject private double _maxZoomLevel = 5.0; // 最大缩放等级 [ObservableProperty] - private double _minZoomLevel = 1.7; // 最小缩放等级 + private double _minZoomLevel = 2.0; // 最小缩放等级 [ObservableProperty] private double _reviveStatueOfTheSevenPointX = 2296.4; // 七天神像点位X坐标 @@ -58,4 +58,7 @@ public partial class TpConfig : ObservableObject [ObservableProperty] private int _maxMouseMove = 300; // 单次移动最大距离 + + [ObservableProperty] + private double _mapScaleFactor = 2.661; // 游戏坐标和 mapZoomLevel=1 时的像素比例因子。 } \ No newline at end of file diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs index bce6d9e9..39cadcd5 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; @@ -21,6 +22,7 @@ using Microsoft.Extensions.Logging; using OpenCvSharp; using Vanara.PInvoke; using static BetterGenshinImpact.GameTask.Common.TaskControl; +using Log = Serilog.Log; namespace BetterGenshinImpact.GameTask.AutoTrackPath; @@ -62,29 +64,47 @@ public class TpTask(CancellationToken ct) /// 强制以当前的tpX,tpY坐标进行自动传送 private async Task<(double, double)> TpOnce(double tpX, double tpY, bool force = false) { - var (x, y) = (tpX, tpY); - - string? country = null; - if (!force) - { - // 获取最近的传送点位置 - (x, y, country) = GetRecentlyTpPoint(tpX, tpY); - Logger.LogDebug("({TpX},{TpY}) 最近的传送点位置 ({X},{Y})", $"{tpX:F1}", $"{tpY:F1}", $"{x:F1}", $"{y:F1}"); - } + // 传送前的计算准备 + var nTpPoints = GetNearestNTpPoints(tpX, tpY, 2); + var (x, y) = force ? (tpX, tpY) : (nTpPoints[0].x, nTpPoints[0].y); + var country = force ? null : nTpPoints[0].country; + double disBetweenTpPoints = Math.Sqrt((nTpPoints[0].x - nTpPoints[1].x) * (nTpPoints[0].x - nTpPoints[1].x) + + (nTpPoints[0].y - nTpPoints[1].y) * (nTpPoints[0].y - nTpPoints[1].y)); + double minZoomLevel = Math.Max(disBetweenTpPoints / 20, 1); + // 计算传送点位置离哪个地图切换后的中心点最近,切换到该地图 await SwitchRecentlyCountryMap(x, y, country); - + double zoomLevel = GetBigMapZoomLevel(CaptureToRectArea()); if (_tpConfig.MapZoomEnabled) { - double zoomLevel = GetBigMapZoomLevel(CaptureToRectArea()); if (zoomLevel > 4.5) { // 显示传送锚点和秘境的缩放等级 await AdjustMapZoomLevel(zoomLevel, 4.5); + zoomLevel = 4.5; Logger.LogInformation("当前缩放等级过大,调整为 {zoomLevel:0.00}", 4.5); } } + if (zoomLevel > minZoomLevel) + { + if (_tpConfig.MapZoomEnabled) + { + Logger.LogInformation("目标传送点有相近传送点,到目标传送点附近将缩放到{zoomLevel:0.00}", minZoomLevel); + await MoveMapTo(x, y, minZoomLevel); + await Delay(300, ct); // 等待地图移动完成 + } + else + { + Logger.LogInformation("目标传送点有相近传送点,可能传送失败。如果失败请到设置-大地图地图传送设置开启地图缩放。"); + // TODO 部分无法区分点位强制缩放 即使没有zoomEnabled。 + // await AdjustMapZoomLevel(zoomLevel, minZoomLevel); // 临时修改缩放 + // await Delay(300, ct); // 等待缩放修改完成 + await MoveMapTo(x, y); // 移动地图 + await Delay(300, ct); // 等待地图移动完成 + // await AdjustMapZoomLevel(minZoomLevel, zoomLevel); // 恢复修改的缩放 + } + } var bigMapInAllMapRect = GetBigMapRect(); while (!IsPointInBigMapWindow(bigMapInAllMapRect, x, y)) // 左上角 350x400也属于禁止点击区域 { @@ -238,11 +258,12 @@ public class TpTask(CancellationToken ct) /// /// 目标x坐标 /// 目标y坐标 - - private async Task MoveMapTo(double x, double y) + /// 到达目标点的最小缩放等级,只在 MapZoomEnabled 为 True 生效 + private async Task MoveMapTo(double x, double y, double minZoomLevel = 2) { // 获取当前地图中心点并计算到目标传送点的初始偏移 // await AdjustMapZoomLevel(mapZoomLevel); + minZoomLevel = Math.Min(minZoomLevel, _tpConfig.MinZoomLevel); var bigMapCenterPoint = GetPositionFromBigMap(); // 初始中心 var newBigMapCenterPoint = bigMapCenterPoint; var (xOffset, yOffset) = (x - bigMapCenterPoint.X, y - bigMapCenterPoint.Y); @@ -271,49 +292,66 @@ public class TpTask(CancellationToken ct) // 本次移动的距离 double diffMapX = Math.Abs(newBigMapCenterPoint.X - bigMapCenterPoint.X); double diffMapY = Math.Abs(newBigMapCenterPoint.Y - bigMapCenterPoint.Y); - double moveDistance = Math.Sqrt(diffMapX * diffMapX + diffMapY * diffMapY); - if (moveDistance > 10) // 移动距离大于10认为本次移动成功 { (xOffset, yOffset) = (x - newBigMapCenterPoint.X, y - newBigMapCenterPoint.Y); // 更新目标偏移量 - totalMoveMouseX = Math.Abs(moveMouseX * xOffset / diffMapX); - totalMoveMouseY = Math.Abs(moveMouseY * yOffset / diffMapY); + // totalMoveMouseX = Math.Abs(moveMouseX * xOffset / diffMapX); + // totalMoveMouseY = Math.Abs(moveMouseY * yOffset / diffMapY); + double currentZoomLevel = GetBigMapZoomLevel(CaptureToRectArea()); + totalMoveMouseX = _tpConfig.MapScaleFactor * Math.Abs(xOffset) / currentZoomLevel; + totalMoveMouseY = _tpConfig.MapScaleFactor * Math.Abs(yOffset) / currentZoomLevel; double mouseDistance = Math.Sqrt(totalMoveMouseX * totalMoveMouseX + totalMoveMouseY * totalMoveMouseY); if (_tpConfig.MapZoomEnabled) { // 调整地图缩放 // mapZoomLevel<5 才显示传送锚点和秘境; mapZoomLevel>1.7 可以避免点错传送锚点 - double currentZoomLevel = GetBigMapZoomLevel(CaptureToRectArea()); + currentZoomLevel = GetBigMapZoomLevel(CaptureToRectArea()); double oldZoomLevel = currentZoomLevel; while (mouseDistance > _tpConfig.MapZoomOutDistance || mouseDistance < _tpConfig.MapZoomInDistance) { - bool zoomOut = mouseDistance > _tpConfig.MapZoomOutDistance; bool zoomIn = mouseDistance < _tpConfig.MapZoomInDistance; - if (zoomOut && currentZoomLevel < _tpConfig.MaxZoomLevel - 1.0 - || zoomIn && currentZoomLevel > _tpConfig.MinZoomLevel + 1.0) + if (zoomIn) { - await AdjustMapZoomLevel(zoomIn); - await Delay(50, ct); - currentZoomLevel = GetBigMapZoomLevel(CaptureToRectArea()); - totalMoveMouseX *= oldZoomLevel / currentZoomLevel; - totalMoveMouseY *= oldZoomLevel / currentZoomLevel; - mouseDistance *= oldZoomLevel / currentZoomLevel; - oldZoomLevel = currentZoomLevel; - } - else - { - double targetZoom = zoomIn ? _tpConfig.MinZoomLevel : _tpConfig.MaxZoomLevel; - // 考虑调整和识别误差,所以相差0.05就不再调整。 - if (currentZoomLevel > _tpConfig.MaxZoomLevel - 0.05 || currentZoomLevel < _tpConfig.MinZoomLevel + 0.05) + if (currentZoomLevel > _tpConfig.MinZoomLevel + 1.0) + { + await AdjustMapZoomLevel(zoomIn); + await Delay(50, ct); + } + else if(currentZoomLevel < minZoomLevel + 0.05) { break; } - await AdjustMapZoomLevel(currentZoomLevel, targetZoom); - break; + else + { + await AdjustMapZoomLevel(currentZoomLevel, minZoomLevel); + break; + } } + else + { + if (currentZoomLevel < _tpConfig.MaxZoomLevel - 1.0) + { + await AdjustMapZoomLevel(zoomIn); + await Delay(50, ct); + } + else if (currentZoomLevel > _tpConfig.MaxZoomLevel - 0.05) + { + break; + } + else + { + await AdjustMapZoomLevel(currentZoomLevel, _tpConfig.MaxZoomLevel); + break; + } + } + currentZoomLevel = GetBigMapZoomLevel(CaptureToRectArea()); + totalMoveMouseX *= oldZoomLevel / currentZoomLevel; + totalMoveMouseY *= oldZoomLevel / currentZoomLevel; + mouseDistance *= oldZoomLevel / currentZoomLevel; + oldZoomLevel = currentZoomLevel; } } @@ -448,7 +486,6 @@ public class TpTask(CancellationToken ct) GlobalMethod.LeftButtonUp(); } - public Point2f GetPositionFromBigMap() { return GetBigMapCenterPoint(); @@ -529,6 +566,7 @@ public class TpTask(CancellationToken ct) /// /// /// + [Obsolete] public (double x, double y, string? country) GetRecentlyTpPoint(double x, double y) { double recentX = 0; @@ -548,6 +586,40 @@ public class TpTask(CancellationToken ct) } return (recentX, recentY, country); } + + /// + /// 获取最接近的N个传送点坐标和所处区域 + /// + /// + /// + /// 获取最近的 n 个传送点 + /// + public List<(double x, double y, string? country)> GetNearestNTpPoints(double x, double y, int n = 1) + { + // 检查 n 的合法性 + if (n < 1) + { + throw new ArgumentException("The value of n must be greater than or equal to 1.", nameof(n)); + } + + // 按距离排序并选择前 n 个点 + var sortedTpPositions = MapLazyAssets.Instance.TpPositions + .Select(tpPosition => new + { + tpPosition.X, + tpPosition.Y, + tpPosition.Country, + Distance = Math.Sqrt(Math.Pow(tpPosition.X - x, 2) + Math.Pow(tpPosition.Y - y, 2)) + }) + .OrderBy(tp => tp.Distance) + .Take(n) // 取前 n 个点 + .ToList(); + + // 将结果转换为 List<(x, y, country)> + return sortedTpPositions + .Select(tp => (tp.X, tp.Y, tp.Country)) + .ToList(); + } public async Task SwitchRecentlyCountryMap(double x, double y, string? forceCountry = null) { From 4196f05f2185828e6d9f32bf0df305b78b4d919d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Tue, 28 Jan 2025 08:49:24 +0800 Subject: [PATCH 40/81] replace HttpContent with another data structure --- .../Notification/NotificationService.cs | 16 +++----------- .../Service/Notifier/Interface/INotifier.cs | 4 ++-- .../Service/Notifier/NotifierManager.cs | 15 +++++++------ .../Service/Notifier/WebhookNotifier.cs | 21 ++++++++++++++++--- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/BetterGenshinImpact/Service/Notification/NotificationService.cs b/BetterGenshinImpact/Service/Notification/NotificationService.cs index d9b5f590..4e62ce91 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationService.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationService.cs @@ -49,16 +49,6 @@ public class NotificationService : IHostedService return Task.CompletedTask; } - private StringContent TransformData(INotificationData notificationData) - { - // using object type here so it serializes the interface correctly - var serializedData = JsonSerializer.Serialize(notificationData, new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, - }); - - return new StringContent(serializedData, Encoding.UTF8, "application/json"); - } private void InitializeNotifiers() { @@ -83,13 +73,13 @@ public class NotificationService : IHostedService { return NotificationTestResult.Error("通知类型未启用"); } - await notifier.SendNotificationAsync(TransformData(new TestNotificationData + await notifier.SendNotificationAsync(new TestNotificationData { Event = NotificationEvent.Test, Action = NotificationAction.Started, Conclusion = NotificationConclusion.Success, Message = "测试通知" - })); + }); return NotificationTestResult.Success(); } catch (NotifierException ex) @@ -100,7 +90,7 @@ public class NotificationService : IHostedService public async Task NotifyAllNotifiersAsync(INotificationData notificationData) { - await _notifierManager.SendNotificationToAllAsync(TransformData(notificationData)); + await _notifierManager.SendNotificationToAllAsync(notificationData); } public void NotifyAllNotifiers(INotificationData notificationData) diff --git a/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs b/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs index abda991a..b705cdd5 100644 --- a/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs @@ -1,5 +1,6 @@ using System.Net.Http; using System.Threading.Tasks; +using BetterGenshinImpact.Service.Notification.Model; namespace BetterGenshinImpact.Service.Notifier.Interface; @@ -7,6 +8,5 @@ public interface INotifier { string Name { get; } - // TODO: replace HttpContent with another data structure - Task SendNotificationAsync(HttpContent content); + Task SendNotificationAsync(INotificationData content); } diff --git a/BetterGenshinImpact/Service/Notifier/NotifierManager.cs b/BetterGenshinImpact/Service/Notifier/NotifierManager.cs index 50034109..da1a344c 100644 --- a/BetterGenshinImpact/Service/Notifier/NotifierManager.cs +++ b/BetterGenshinImpact/Service/Notifier/NotifierManager.cs @@ -1,10 +1,9 @@ using BetterGenshinImpact.Service.Notifier.Interface; using Microsoft.Extensions.Logging; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using System.Net.Http; using System.Threading.Tasks; +using BetterGenshinImpact.Service.Notification.Model; namespace BetterGenshinImpact.Service.Notifier; @@ -38,11 +37,11 @@ public class NotifierManager return _notifiers.FirstOrDefault(o => o is T); } - public async Task SendNotificationAsync(INotifier notifier, HttpContent httpContent) + public async Task SendNotificationAsync(INotifier notifier, INotificationData content) { try { - await notifier.SendNotificationAsync(httpContent); + await notifier.SendNotificationAsync(content); } catch (System.Exception ex) { @@ -50,18 +49,18 @@ public class NotifierManager } } - public async Task SendNotificationAsync(HttpContent httpContent) where T : INotifier + public async Task SendNotificationAsync(INotificationData content) where T : INotifier { var notifier = _notifiers.FirstOrDefault(o => o is T); if (notifier != null) { - await SendNotificationAsync(notifier, httpContent); + await SendNotificationAsync(notifier, content); } } - public async Task SendNotificationToAllAsync(HttpContent httpContent) + public async Task SendNotificationToAllAsync(INotificationData content) { - await Task.WhenAll(_notifiers.Select(notifier => SendNotificationAsync(notifier, httpContent))); + await Task.WhenAll(_notifiers.Select(notifier => SendNotificationAsync(notifier, content))); } } diff --git a/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs b/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs index 07331f91..93f73a90 100644 --- a/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs @@ -1,7 +1,10 @@ using BetterGenshinImpact.Service.Notifier.Exception; using BetterGenshinImpact.Service.Notifier.Interface; using System.Net.Http; +using System.Text; +using System.Text.Json; using System.Threading.Tasks; +using BetterGenshinImpact.Service.Notification.Model; namespace BetterGenshinImpact.Service.Notifier; @@ -19,11 +22,11 @@ public class WebhookNotifier : INotifier Endpoint = endpoint; } - public async Task SendNotificationAsync(HttpContent content) + public async Task SendNotificationAsync(INotificationData content) { try { - var response = await _httpClient.PostAsync(Endpoint, content); + var response = await _httpClient.PostAsync(Endpoint, TransformData(content)); if (!response.IsSuccessStatusCode) { @@ -39,4 +42,16 @@ public class WebhookNotifier : INotifier throw new NotifierException($"Error sending webhook: {ex.Message}"); } } -} + + + private StringContent TransformData(INotificationData notificationData) + { + // using object type here so it serializes the interface correctly + var serializedData = JsonSerializer.Serialize(notificationData, new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, + }); + + return new StringContent(serializedData, Encoding.UTF8, "application/json"); + } +} \ No newline at end of file From 3e114ad3588e349d8d603e24ca3c8c08642ff47e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Tue, 28 Jan 2025 13:12:14 +0800 Subject: [PATCH 41/81] =?UTF-8?q?=E6=B7=BB=E5=8A=A0windows=E9=80=9A?= =?UTF-8?q?=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BetterGenshinImpact/App.xaml.cs | 2 + .../BetterGenshinImpact.csproj | 1 + BetterGenshinImpact/Helpers/TempManager.cs | 26 ++++++++ .../Notification/NotificationConfig.cs | 7 +++ .../Notification/NotificationService.cs | 11 +++- .../Service/Notifier/Interface/INotifier.cs | 2 +- .../Service/Notifier/NotifierManager.cs | 2 +- .../Service/Notifier/WebhookNotifier.cs | 12 ++-- .../Service/Notifier/WindowsUwpNotifier.cs | 40 ++++++++++++ .../View/Pages/CommonSettingsPage.xaml | 63 ++++++++++++++++++- .../ViewModel/MainWindowViewModel.cs | 3 + .../Pages/CommonSettingsPageViewModel.cs | 33 +++++++--- 12 files changed, 184 insertions(+), 18 deletions(-) create mode 100644 BetterGenshinImpact/Helpers/TempManager.cs create mode 100644 BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs diff --git a/BetterGenshinImpact/App.xaml.cs b/BetterGenshinImpact/App.xaml.cs index 8b5fb7dc..24a268b6 100644 --- a/BetterGenshinImpact/App.xaml.cs +++ b/BetterGenshinImpact/App.xaml.cs @@ -185,6 +185,8 @@ public partial class App : Application protected override async void OnExit(ExitEventArgs e) { base.OnExit(e); + + TempManager.CleanUp(); await _host.StopAsync(); _host.Dispose(); diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj index 9e81a682..b138ab2d 100644 --- a/BetterGenshinImpact/BetterGenshinImpact.csproj +++ b/BetterGenshinImpact/BetterGenshinImpact.csproj @@ -47,6 +47,7 @@ + diff --git a/BetterGenshinImpact/Helpers/TempManager.cs b/BetterGenshinImpact/Helpers/TempManager.cs new file mode 100644 index 00000000..25ae16f2 --- /dev/null +++ b/BetterGenshinImpact/Helpers/TempManager.cs @@ -0,0 +1,26 @@ +using System; +using System.IO; +using BetterGenshinImpact.Core.Config; + +namespace BetterGenshinImpact.Helpers; + +public class TempManager +{ + public static readonly string TempDirectory = Global.Absolute("User/Temp"); + static TempManager() + { + Directory.CreateDirectory(TempDirectory); + } + + public static void CleanUp() + { + try + { + DirectoryHelper.DeleteDirectoryRecursively(TempDirectory); + } + catch + { + // Suppress any exceptions to avoid exposing errors + } + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/NotificationConfig.cs b/BetterGenshinImpact/Service/Notification/NotificationConfig.cs index f8826963..1da20fe9 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationConfig.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationConfig.cs @@ -26,4 +26,11 @@ public partial class NotificationConfig : ObservableObject /// [ObservableProperty] private bool _includeScreenShot = false; + + /// + /// windows uwp 通知是否启用 + /// + [ObservableProperty] + private bool _windowsUwpNotificationEnabled = false; + } diff --git a/BetterGenshinImpact/Service/Notification/NotificationService.cs b/BetterGenshinImpact/Service/Notification/NotificationService.cs index 4e62ce91..98942c0f 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationService.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationService.cs @@ -6,11 +6,13 @@ using BetterGenshinImpact.Service.Notifier.Exception; using BetterGenshinImpact.Service.Notifier.Interface; using Microsoft.Extensions.Hosting; using System; +using System.Drawing; using System.Net.Http; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using System.Windows.Media.Imaging; using BetterGenshinImpact.GameTask; using BetterGenshinImpact.Service.Notification.Model.Enum; @@ -56,6 +58,10 @@ public class NotificationService : IHostedService { _notifierManager.RegisterNotifier(new WebhookNotifier(NotifyHttpClient, TaskContext.Instance().Config.NotificationConfig.WebhookEndpoint)); } + if (TaskContext.Instance().Config.NotificationConfig.WindowsUwpNotificationEnabled) + { + _notifierManager.RegisterNotifier(new WindowsUwpNotifier()); + } } public void RefreshNotifiers() @@ -73,12 +79,13 @@ public class NotificationService : IHostedService { return NotificationTestResult.Error("通知类型未启用"); } - await notifier.SendNotificationAsync(new TestNotificationData + await notifier.SendAsync(new TestNotificationData { Event = NotificationEvent.Test, Action = NotificationAction.Started, Conclusion = NotificationConclusion.Success, - Message = "测试通知" + Message = "测试通知", + // Screenshot = }); return NotificationTestResult.Success(); } diff --git a/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs b/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs index b705cdd5..d4023bc3 100644 --- a/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs @@ -8,5 +8,5 @@ public interface INotifier { string Name { get; } - Task SendNotificationAsync(INotificationData content); + Task SendAsync(INotificationData data); } diff --git a/BetterGenshinImpact/Service/Notifier/NotifierManager.cs b/BetterGenshinImpact/Service/Notifier/NotifierManager.cs index da1a344c..17e4e42a 100644 --- a/BetterGenshinImpact/Service/Notifier/NotifierManager.cs +++ b/BetterGenshinImpact/Service/Notifier/NotifierManager.cs @@ -41,7 +41,7 @@ public class NotifierManager { try { - await notifier.SendNotificationAsync(content); + await notifier.SendAsync(content); } catch (System.Exception ex) { diff --git a/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs b/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs index 93f73a90..8600dcf4 100644 --- a/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs @@ -15,6 +15,11 @@ public class WebhookNotifier : INotifier public string Endpoint { get; set; } private readonly HttpClient _httpClient; + + private readonly JsonSerializerOptions _jsonSerializerOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, + }; public WebhookNotifier(HttpClient httpClient, string endpoint = "") { @@ -22,7 +27,7 @@ public class WebhookNotifier : INotifier Endpoint = endpoint; } - public async Task SendNotificationAsync(INotificationData content) + public async Task SendAsync(INotificationData content) { try { @@ -47,10 +52,7 @@ public class WebhookNotifier : INotifier private StringContent TransformData(INotificationData notificationData) { // using object type here so it serializes the interface correctly - var serializedData = JsonSerializer.Serialize(notificationData, new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, - }); + var serializedData = JsonSerializer.Serialize(notificationData, _jsonSerializerOptions); return new StringContent(serializedData, Encoding.UTF8, "application/json"); } diff --git a/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs b/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs new file mode 100644 index 00000000..e151e714 --- /dev/null +++ b/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs @@ -0,0 +1,40 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using BetterGenshinImpact.Helpers; +using BetterGenshinImpact.Service.Notification.Model; +using BetterGenshinImpact.Service.Notifier.Interface; +using Microsoft.Toolkit.Uwp.Notifications; + +namespace BetterGenshinImpact.Service.Notifier; + +public class WindowsUwpNotifier : INotifier +{ + public string Name => "Windows通知"; + + public Task SendAsync(INotificationData data) + { + var toastBuilder = new ToastContentBuilder() + .AddHeader("BetterGI", "BetterGI", "action=click"); + + if (data.Screenshot != null) + { + string uniqueFileName = $"notification_image_{Guid.NewGuid()}.png"; + string imagePath = Path.Combine(TempManager.TempDirectory, uniqueFileName); + data.Screenshot.Save(imagePath, System.Drawing.Imaging.ImageFormat.Png); + toastBuilder.AddHeroImage(new Uri(imagePath)); + } + + if (!string.IsNullOrEmpty(data.Message)) + { + toastBuilder.AddText(data.Message); + } + + toastBuilder.Show(toast => + { + toast.Group = data.Event.ToString(); + toast.ExpirationTime = DateTime.Now.AddHours(12); + }); + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml index a9e0f1ef..75959825 100644 --- a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml @@ -453,7 +453,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (this, "RefreshSettings", new object(), "重新计算控件位置")); } - + [RelayCommand] private void OnSwitchMaskEnabled() { @@ -106,7 +109,7 @@ public partial class CommonSettingsPageViewModel : ObservableObject, INavigation Process.Start("explorer.exe", path); } - + [RelayCommand] private async Task OnTestWebhook() { @@ -119,4 +122,18 @@ public partial class CommonSettingsPageViewModel : ObservableObject, INavigation IsLoading = false; } -} + + [RelayCommand] + private async Task OnTestWindowsUwpNotification() + { + var res = await _notificationService.TestNotifierAsync(); + if(res.IsSuccess) + { + Toast.Success(res.Message); + } + else + { + Toast.Error(res.Message); + } + } +} \ No newline at end of file From e42c886bbe988fe2c4fa0a088eab517502da1da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Tue, 28 Jan 2025 16:23:43 +0800 Subject: [PATCH 42/81] fix domain tp --- .../GameTask/AutoTrackPath/TpTask.cs | 77 ++++++++++++------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs index 39cadcd5..efbb2347 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs @@ -14,6 +14,7 @@ using BetterGenshinImpact.GameTask.Common; using BetterGenshinImpact.GameTask.Common.BgiVision; using BetterGenshinImpact.GameTask.Common.Element.Assets; using BetterGenshinImpact.GameTask.Common.Exceptions; +using BetterGenshinImpact.GameTask.Common.Job; using BetterGenshinImpact.GameTask.Common.Map; using BetterGenshinImpact.GameTask.Model.Area; using BetterGenshinImpact.GameTask.QuickTeleport.Assets; @@ -35,7 +36,7 @@ public class TpTask(CancellationToken ct) private readonly Rect _captureRect = TaskContext.Instance().SystemInfo.ScaleMax1080PCaptureRect; private readonly double _zoomOutMax1080PRatio = TaskContext.Instance().SystemInfo.ZoomOutMax1080PRatio; private readonly TpConfig _tpConfig = TaskContext.Instance().Config.TpConfig; - + /// /// 传送到须弥七天神像 /// @@ -54,8 +55,10 @@ public class TpTask(CancellationToken ct) await AdjustMapZoomLevel(currentZoomLevel, 3); } } + await Tp(_tpConfig.ReviveStatueOfTheSevenPointX, _tpConfig.ReviveStatueOfTheSevenPointY); } + /// /// 通过大地图传送到指定坐标最近的传送点,然后移动到指定坐标 /// @@ -64,12 +67,15 @@ public class TpTask(CancellationToken ct) /// 强制以当前的tpX,tpY坐标进行自动传送 private async Task<(double, double)> TpOnce(double tpX, double tpY, bool force = false) { + // 先确认在地图界面 + await CheckInBigMapUi(); + // 传送前的计算准备 var nTpPoints = GetNearestNTpPoints(tpX, tpY, 2); var (x, y) = force ? (tpX, tpY) : (nTpPoints[0].x, nTpPoints[0].y); var country = force ? null : nTpPoints[0].country; double disBetweenTpPoints = Math.Sqrt((nTpPoints[0].x - nTpPoints[1].x) * (nTpPoints[0].x - nTpPoints[1].x) - + (nTpPoints[0].y - nTpPoints[1].y) * (nTpPoints[0].y - nTpPoints[1].y)); + + (nTpPoints[0].y - nTpPoints[1].y) * (nTpPoints[0].y - nTpPoints[1].y)); double minZoomLevel = Math.Max(disBetweenTpPoints / 20, 1); @@ -86,6 +92,7 @@ public class TpTask(CancellationToken ct) Logger.LogInformation("当前缩放等级过大,调整为 {zoomLevel:0.00}", 4.5); } } + if (zoomLevel > minZoomLevel) { if (_tpConfig.MapZoomEnabled) @@ -105,6 +112,7 @@ public class TpTask(CancellationToken ct) // await AdjustMapZoomLevel(minZoomLevel, zoomLevel); // 恢复修改的缩放 } } + var bigMapInAllMapRect = GetBigMapRect(); while (!IsPointInBigMapWindow(bigMapInAllMapRect, x, y)) // 左上角 350x400也属于禁止点击区域 { @@ -193,25 +201,24 @@ public class TpTask(CancellationToken ct) } private async Task CheckInBigMapUi() + { + // 尝试打开地图失败后,先回到主界面后再次尝试打开地图 + if (await TryToOpenBigMapUi()) + { + await new ReturnMainUiTask().Start(ct); + await TryToOpenBigMapUi(); + } + } + + /// + /// 尝试打开地图界面 + /// + private async Task TryToOpenBigMapUi() { // M 打开地图识别当前位置,中心点为当前位置 var ra1 = CaptureToRectArea(); if (!Bv.IsInBigMapUi(ra1)) { - // 不在主界面的情况下,先回到主界面 - if (!Bv.IsInMainUi(ra1)) - { - for (int i = 0; i < 5; i++) - { - Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_ESCAPE); - await Delay(1000, ct); - ra1 = CaptureToRectArea(); - if (Bv.IsInMainUi(ra1)) - { - break; - } - } - } Simulation.SendInput.SimulateAction(GIActions.OpenMap); await Delay(1000, ct); for (int i = 0; i < 3; i++) @@ -221,12 +228,23 @@ public class TpTask(CancellationToken ct) { await Delay(500, ct); } + else + { + return true; + } } } + else + { + return true; + } + + return false; } + + public async Task<(double, double)> Tp(double tpX, double tpY, bool force = false) { - await CheckInBigMapUi(); for (var i = 0; i < 3; i++) { try @@ -243,7 +261,6 @@ public class TpTask(CancellationToken ct) } catch (Exception e) { - await CheckInBigMapUi(); Logger.LogError("传送失败,重试 {I} 次", i + 1); Logger.LogDebug(e, "传送失败,重试 {I} 次", i + 1); } @@ -264,7 +281,7 @@ public class TpTask(CancellationToken ct) // 获取当前地图中心点并计算到目标传送点的初始偏移 // await AdjustMapZoomLevel(mapZoomLevel); minZoomLevel = Math.Min(minZoomLevel, _tpConfig.MinZoomLevel); - var bigMapCenterPoint = GetPositionFromBigMap(); // 初始中心 + var bigMapCenterPoint = GetPositionFromBigMap(); // 初始中心 var newBigMapCenterPoint = bigMapCenterPoint; var (xOffset, yOffset) = (x - bigMapCenterPoint.X, y - bigMapCenterPoint.Y); int moveMouseX = 100 * Math.Sign(xOffset); @@ -285,10 +302,11 @@ public class TpTask(CancellationToken ct) { Logger.LogWarning("中心点识别失败,尝试预测移动的距离。"); newBigMapCenterPoint = new Point2f( - (float)(bigMapCenterPoint.X + xOffset * moveMouseX / totalMoveMouseX), - (float)(bigMapCenterPoint.Y + yOffset * moveMouseY / totalMoveMouseY) + (float)(bigMapCenterPoint.X + xOffset * moveMouseX / totalMoveMouseX), + (float)(bigMapCenterPoint.Y + yOffset * moveMouseY / totalMoveMouseY) ); // 利用移动鼠标的距离获取新的中心 } + // 本次移动的距离 double diffMapX = Math.Abs(newBigMapCenterPoint.X - bigMapCenterPoint.X); double diffMapY = Math.Abs(newBigMapCenterPoint.Y - bigMapCenterPoint.Y); @@ -312,7 +330,7 @@ public class TpTask(CancellationToken ct) while (mouseDistance > _tpConfig.MapZoomOutDistance || mouseDistance < _tpConfig.MapZoomInDistance) { - bool zoomIn = mouseDistance < _tpConfig.MapZoomInDistance; + bool zoomIn = mouseDistance < _tpConfig.MapZoomInDistance; if (zoomIn) { if (currentZoomLevel > _tpConfig.MinZoomLevel + 1.0) @@ -320,7 +338,7 @@ public class TpTask(CancellationToken ct) await AdjustMapZoomLevel(zoomIn); await Delay(50, ct); } - else if(currentZoomLevel < minZoomLevel + 0.05) + else if (currentZoomLevel < minZoomLevel + 0.05) { break; } @@ -347,6 +365,7 @@ public class TpTask(CancellationToken ct) break; } } + currentZoomLevel = GetBigMapZoomLevel(CaptureToRectArea()); totalMoveMouseX *= oldZoomLevel / currentZoomLevel; totalMoveMouseY *= oldZoomLevel / currentZoomLevel; @@ -361,7 +380,7 @@ public class TpTask(CancellationToken ct) Logger.LogInformation("移动 {I} 次鼠标后,已经接近目标点,不再移动地图。", iteration + 1); break; } - + moveMouseX = (int)Math.Min(totalMoveMouseX, _tpConfig.MaxMouseMove * totalMoveMouseX / mouseDistance) * Math.Sign(xOffset); moveMouseY = (int)Math.Min(totalMoveMouseY, _tpConfig.MaxMouseMove * totalMoveMouseY / mouseDistance) * Math.Sign(yOffset); double moveMouseLength = Math.Sqrt(moveMouseX * moveMouseX + moveMouseY * moveMouseY); @@ -411,7 +430,7 @@ public class TpTask(CancellationToken ct) await Delay(50, ct); } - + /// /// 调整地图的缩放等级(整数缩放级别)。 /// @@ -475,7 +494,7 @@ public class TpTask(CancellationToken ct) // 随机起点以避免地图移动无效 GameCaptureRegion.GameRegionMove((rect, _) => (rect.Width / 2d + Random.Shared.Next(-rect.Width / 6, rect.Width / 6), - rect.Height / 2d + Random.Shared.Next(-rect.Height / 6, rect.Height / 6))); + rect.Height / 2d + Random.Shared.Next(-rect.Height / 6, rect.Height / 6))); GlobalMethod.LeftButtonDown(); for (var i = 0; i < steps; i++) @@ -483,6 +502,7 @@ public class TpTask(CancellationToken ct) GlobalMethod.MoveMouseBy(stepX[i], stepY[i]); await Delay(_tpConfig.StepIntervalMilliseconds, ct); } + GlobalMethod.LeftButtonUp(); } @@ -584,9 +604,10 @@ public class TpTask(CancellationToken ct) country = tpPosition.Country; } } + return (recentX, recentY, country); } - + /// /// 获取最接近的N个传送点坐标和所处区域 /// @@ -812,4 +833,4 @@ public class TpTask(CancellationToken ct) // 1~6 的缩放等级 return (-5 * s) + 6; } -} +} \ No newline at end of file From efde38439d027ba4548412e016bae331196a10f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 29 Jan 2025 08:12:32 +0800 Subject: [PATCH 43/81] tp exception --- BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs index efbb2347..9e756e6c 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs @@ -206,7 +206,10 @@ public class TpTask(CancellationToken ct) if (await TryToOpenBigMapUi()) { await new ReturnMainUiTask().Start(ct); - await TryToOpenBigMapUi(); + if (!await TryToOpenBigMapUi()) + { + throw new RetryException("尝试打开大地图失败,请确认你的打开地图按键是否是 M 键?"); + } } } @@ -233,13 +236,12 @@ public class TpTask(CancellationToken ct) return true; } } + return false; } else { return true; } - - return false; } From 8b52aea9a39638548cb8264aa1350b0949499afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 29 Jan 2025 08:12:48 +0800 Subject: [PATCH 44/81] ui dispatcher --- .../ViewModel/Pages/TaskSettingsPageViewModel.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs index 361e1b6f..3b6dfa77 100644 --- a/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs @@ -22,6 +22,7 @@ using System.Threading.Tasks; using Windows.System; using BetterGenshinImpact.GameTask.Common.Element.Assets; using BetterGenshinImpact.GameTask.Model.Enum; +using BetterGenshinImpact.Helpers; using Wpf.Ui; using Wpf.Ui.Controls; using Wpf.Ui.Violeta.Controls; @@ -98,10 +99,10 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw [ObservableProperty] private List _domainNameList; - + public static List ArtifactSalvageStarList = ["4", "3", "2", "1"]; - [ObservableProperty] + [ObservableProperty] private List _autoMusicLevelList = ["传说", "大师", "困难", "普通", "所有"]; [ObservableProperty] @@ -249,7 +250,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw { if (string.IsNullOrEmpty(Config.AutoFightConfig.StrategyName)) { - Toast.Warning("请先在【独立任务——自动战斗】下拉列表配置中选择战斗策略!"); + UIDispatcherHelper.Invoke(() => { Toast.Warning("请先在【独立任务——自动战斗】下拉列表配置中选择战斗策略!"); }); path = string.Empty; return true; } @@ -262,7 +263,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw if (!File.Exists(path) && !Directory.Exists(path)) { - Toast.Error("当前选择的自动战斗策略文件不存在"); + UIDispatcherHelper.Invoke(() => { Toast.Error("当前选择的自动战斗策略文件不存在"); }); return true; } From b130351d8d8724cb8191ed101c7b65526790608e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 29 Jan 2025 08:41:11 +0800 Subject: [PATCH 45/81] bgi.huiyadan.com -> bettergi.com --- BetterGenshinImpact/Service/UpdateService.cs | 2 +- .../ViewModel/MainWindowViewModel.cs | 6 +++--- .../ViewModel/Pages/HomePageViewModel.cs | 2 +- .../ViewModel/Pages/JsListViewModel.cs | 2 +- .../ViewModel/Pages/KeyMouseRecordPageViewModel.cs | 2 +- .../ViewModel/Pages/MacroSettingsPageViewModel.cs | 2 +- .../ViewModel/Pages/MapPathingViewModel.cs | 2 +- .../ViewModel/Pages/ScriptControlViewModel.cs | 2 +- .../ViewModel/Pages/TaskSettingsPageViewModel.cs | 14 +++++++------- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/BetterGenshinImpact/Service/UpdateService.cs b/BetterGenshinImpact/Service/UpdateService.cs index 34575838..c3c88bd8 100644 --- a/BetterGenshinImpact/Service/UpdateService.cs +++ b/BetterGenshinImpact/Service/UpdateService.cs @@ -27,7 +27,7 @@ public class UpdateService : IUpdateService private readonly IConfigService _configService; private const string NoticeUrl = "https://hui-config.oss-cn-hangzhou.aliyuncs.com/bgi/notice.json"; - private const string DownloadPageUrl = "https://bgi.huiyadan.com/download.html"; + private const string DownloadPageUrl = "https://bettergi.com/download.html"; public AllConfig Config { get; set; } diff --git a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs index 2ba43d9c..76b19b63 100644 --- a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs +++ b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs @@ -198,11 +198,11 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel catch (Exception e) { Console.WriteLine(e); - _logger.LogError("PaddleOcr预热异常,解决方案:https://bgi.huiyadan.com/faq.html:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message); + _logger.LogError("PaddleOcr预热异常,解决方案:https://bettergi.com/faq.html:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message); var innerException = e.InnerException; if (innerException != null) { - _logger.LogError("PaddleOcr预热内部异常,解决方案:https://bgi.huiyadan.com/faq.html:" + innerException.Source + "\r\n--" + Environment.NewLine + innerException.StackTrace + "\r\n---" + Environment.NewLine + innerException.Message); + _logger.LogError("PaddleOcr预热内部异常,解决方案:https://bettergi.com/faq.html:" + innerException.Source + "\r\n--" + Environment.NewLine + innerException.StackTrace + "\r\n---" + Environment.NewLine + innerException.Message); throw innerException; } else @@ -214,7 +214,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel } catch (Exception e) { - MessageBox.Warning("PaddleOcr预热失败,解决方案:https://bgi.huiyadan.com/faq.html," + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message); + MessageBox.Warning("PaddleOcr预热失败,解决方案:https://bettergi.com/faq.html," + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message); } } } \ No newline at end of file diff --git a/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs index bad11fd6..ebc50e88 100644 --- a/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs @@ -300,7 +300,7 @@ public partial class HomePageViewModel : ObservableObject, INavigationAware, IVi [RelayCommand] public void OnGoToWikiUrl() { - Process.Start(new ProcessStartInfo("https://bgi.huiyadan.com/doc.html") { UseShellExecute = true }); + Process.Start(new ProcessStartInfo("https://bettergi.com/doc.html") { UseShellExecute = true }); } [RelayCommand] diff --git a/BetterGenshinImpact/ViewModel/Pages/JsListViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/JsListViewModel.cs index 74d6552d..ffab9822 100644 --- a/BetterGenshinImpact/ViewModel/Pages/JsListViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/JsListViewModel.cs @@ -118,7 +118,7 @@ public partial class JsListViewModel : ObservableObject, INavigationAware, IView [RelayCommand] public void OnGoToJsScriptUrl() { - Process.Start(new ProcessStartInfo("https://bgi.huiyadan.com/feats/autos/jsscript.html") { UseShellExecute = true }); + Process.Start(new ProcessStartInfo("https://bettergi.com/feats/autos/jsscript.html") { UseShellExecute = true }); } [RelayCommand] diff --git a/BetterGenshinImpact/ViewModel/Pages/KeyMouseRecordPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/KeyMouseRecordPageViewModel.cs index b2c39aec..cecf68fd 100644 --- a/BetterGenshinImpact/ViewModel/Pages/KeyMouseRecordPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/KeyMouseRecordPageViewModel.cs @@ -229,7 +229,7 @@ public partial class KeyMouseRecordPageViewModel : ObservableObject, INavigation [RelayCommand] public void OnGoToKmScriptUrl() { - Process.Start(new ProcessStartInfo("https://bgi.huiyadan.com/feats/autos/kmscript.html") { UseShellExecute = true }); + Process.Start(new ProcessStartInfo("https://bettergi.com/feats/autos/kmscript.html") { UseShellExecute = true }); } [RelayCommand] diff --git a/BetterGenshinImpact/ViewModel/Pages/MacroSettingsPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/MacroSettingsPageViewModel.cs index 1df4a56a..d28fc063 100644 --- a/BetterGenshinImpact/ViewModel/Pages/MacroSettingsPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/MacroSettingsPageViewModel.cs @@ -49,6 +49,6 @@ public partial class MacroSettingsPageViewModel : ObservableObject, INavigationA [RelayCommand] public void OnGoToOneKeyMacroUrl() { - Process.Start(new ProcessStartInfo("https://bgi.huiyadan.com/feats/macro/onem.html") { UseShellExecute = true }); + Process.Start(new ProcessStartInfo("https://bettergi.com/feats/macro/onem.html") { UseShellExecute = true }); } } diff --git a/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs index 4fd46302..42ad2a8f 100644 --- a/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/MapPathingViewModel.cs @@ -171,7 +171,7 @@ public partial class MapPathingViewModel : ObservableObject, INavigationAware, I [RelayCommand] public void OnGoToPathingUrl() { - Process.Start(new ProcessStartInfo("https://bgi.huiyadan.com/feats/autos/pathing.html") { UseShellExecute = true }); + Process.Start(new ProcessStartInfo("https://bettergi.com/feats/autos/pathing.html") { UseShellExecute = true }); } [RelayCommand] diff --git a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs index 83979c9f..98406c43 100644 --- a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs @@ -1063,7 +1063,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware [RelayCommand] public void OnGoToScriptGroupUrl() { - Process.Start(new ProcessStartInfo("https://bgi.huiyadan.com/feats/autos/dispatcher.html") { UseShellExecute = true }); + Process.Start(new ProcessStartInfo("https://bettergi.com/feats/autos/dispatcher.html") { UseShellExecute = true }); } [RelayCommand] diff --git a/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs index 3b6dfa77..e9a0ffd0 100644 --- a/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs @@ -192,7 +192,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw [RelayCommand] public async Task OnGoToAutoGeniusInvokationUrlAsync() { - await Launcher.LaunchUriAsync(new Uri("https://bgi.huiyadan.com/feats/task/tcg.html")); + await Launcher.LaunchUriAsync(new Uri("https://bettergi.com/feats/task/tcg.html")); } [RelayCommand] @@ -207,7 +207,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw [RelayCommand] public async Task OnGoToAutoWoodUrlAsync() { - await Launcher.LaunchUriAsync(new Uri("https://bgi.huiyadan.com/feats/task/felling.html")); + await Launcher.LaunchUriAsync(new Uri("https://bettergi.com/feats/task/felling.html")); } [RelayCommand] @@ -229,7 +229,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw [RelayCommand] public async Task OnGoToAutoFightUrlAsync() { - await Launcher.LaunchUriAsync(new Uri("https://bgi.huiyadan.com/feats/task/domain.html")); + await Launcher.LaunchUriAsync(new Uri("https://bettergi.com/feats/task/domain.html")); } [RelayCommand] @@ -273,7 +273,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw [RelayCommand] public async Task OnGoToAutoDomainUrlAsync() { - await Launcher.LaunchUriAsync(new Uri("https://bgi.huiyadan.com/feats/task/domain.html")); + await Launcher.LaunchUriAsync(new Uri("https://bettergi.com/feats/task/domain.html")); } [RelayCommand] @@ -314,7 +314,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw [RelayCommand] public async Task OnGoToAutoTrackUrlAsync() { - await Launcher.LaunchUriAsync(new Uri("https://bgi.huiyadan.com/feats/task/track.html")); + await Launcher.LaunchUriAsync(new Uri("https://bettergi.com/feats/task/track.html")); } [Obsolete] @@ -349,7 +349,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw [RelayCommand] public async Task OnGoToAutoTrackPathUrlAsync() { - await Launcher.LaunchUriAsync(new Uri("https://bgi.huiyadan.com/feats/task/track.html")); + await Launcher.LaunchUriAsync(new Uri("https://bettergi.com/feats/task/track.html")); } [RelayCommand] @@ -364,7 +364,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw [RelayCommand] public async Task OnGoToAutoMusicGameUrlAsync() { - await Launcher.LaunchUriAsync(new Uri("https://bgi.huiyadan.com/feats/task/music.html")); + await Launcher.LaunchUriAsync(new Uri("https://bettergi.com/feats/task/music.html")); } [RelayCommand] From 47d88e67c9f663948778ff904a8f4bd2120f489f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 29 Jan 2025 14:34:07 +0800 Subject: [PATCH 46/81] opt --- .../Common/Job/ChooseTalkOptionTask.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs b/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs index 44565148..c2ed78d2 100644 --- a/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs +++ b/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs @@ -44,7 +44,7 @@ public partial class ChooseTalkOptionTask return TalkOptionRes.NotFound; } - await Task.Delay(200, ct); + await Task.Delay(500, ct); for (var i = 0; i < skipTimes; i++) // 重试3次 { @@ -71,7 +71,7 @@ public partial class ChooseTalkOptionTask } ClickOcrRegion(optionRa); - await Task.Delay(200, ct); + await Task.Delay(300, ct); return TalkOptionRes.FoundAndClick; } } @@ -209,6 +209,21 @@ public partial class ChooseTalkOptionTask return false; } + + private bool IsOrangeOption2(Mat textMat) + { + // 只提取橙色 + using var bMat = OpenCvCommonHelper.Threshold(textMat, new Scalar(200, 165, 45), new Scalar(255, 205, 55)); + var whiteCount = OpenCvCommonHelper.CountGrayMatColor(bMat, 255); + var rate = whiteCount * 1.0 / (bMat.Width * bMat.Height); + Debug.WriteLine($"识别到橙色文字区域占比:{rate}"); + if (rate > 0.06) + { + return true; + } + + return false; + } } public enum TalkOptionRes From 67df9f298a811ab37ad4bfd725129560885a6d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 29 Jan 2025 15:03:37 +0800 Subject: [PATCH 47/81] =?UTF-8?q?if=20it=20is=20a=20target=20waypoint=20ty?= =?UTF-8?q?pe,=20it=20will=20continue=20to=20approach=20the=20target=20aft?= =?UTF-8?q?er=20a=20falling=20attack=20=E5=A6=82=E6=9E=9C=E6=98=AFtarget?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E7=82=B9=E7=B1=BB=E5=9E=8B=EF=BC=8C=E4=B8=8B?= =?UTF-8?q?=E8=90=BD=E6=94=BB=E5=87=BB=E5=90=8E=E4=BC=9A=E7=BB=A7=E7=BB=AD?= =?UTF-8?q?=E9=9D=A0=E8=BF=91=E7=9B=AE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/AutoPathing/PathExecutor.cs | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs index 82e56065..2ce61c41 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs @@ -143,7 +143,7 @@ public class PathExecutor { return; } - + InitializePathing(task); // 转换、按传送点分割路径 var waypointsList = ConvertWaypointsForTrack(task.Positions); @@ -154,13 +154,13 @@ public class PathExecutor foreach (var waypoints in waypointsList) // 按传送点分割的路径 { CurWaypoints = (waypointsList.FindIndex(wps => wps == waypoints), waypoints); - + for (var i = 0; i < RetryTimes; i++) { try { await ResolveAnomalies(); // 异常场景处理 - foreach (var waypoint in waypoints) // 一条路径 + foreach (var waypoint in waypoints) // 一条路径 { CurWaypoint = (waypoints.FindIndex(wps => wps == waypoint), waypoint); TryCloseSkipOtherOperations(); @@ -181,9 +181,12 @@ public class PathExecutor // Path不用走得很近,Target需要接近,但都需要先移动到对应位置 await MoveTo(waypoint); + await BeforeMoveCloseToTarget(waypoint); + if (waypoint.Type == WaypointType.Target.Code // 除了 fight mining stop_flying 之外的 action 都需要接近 || (!string.IsNullOrEmpty(waypoint.Action) + && waypoint.Action != ActionEnum.StopFlying.Code && waypoint.Action != ActionEnum.NahidaCollect.Code && waypoint.Action != ActionEnum.Fight.Code && waypoint.Action != ActionEnum.CombatScript.Code @@ -810,14 +813,6 @@ public class PathExecutor var position = await GetPosition(screen); var targetOrientation = Navigation.GetTargetOrientation(waypoint, position); Logger.LogInformation("精确接近目标点,位置({x2},{y2})", $"{waypoint.GameX:F1}", $"{waypoint.GameY:F1}"); - if (waypoint.MoveMode == MoveModeEnum.Fly.Code && waypoint.Action == ActionEnum.StopFlying.Code) - { - //下落攻击接近目的地 - Logger.LogInformation("动作:下落攻击"); - Simulation.SendInput.SimulateAction(GIActions.NormalAttack); - await Delay(1000, ct); - return; - } await _rotateTask.WaitUntilRotatedTo(targetOrientation, 2); var stepsTaken = 0; @@ -858,6 +853,17 @@ public class PathExecutor } private async Task BeforeMoveToTarget(WaypointForTrack waypoint) + { + if (waypoint.MoveMode == MoveModeEnum.Fly.Code && waypoint.Action == ActionEnum.StopFlying.Code) + { + //下落攻击接近目的地 + Logger.LogInformation("动作:下落攻击"); + Simulation.SendInput.SimulateAction(GIActions.NormalAttack); + await Delay(1000, ct); + } + } + + private async Task BeforeMoveCloseToTarget(WaypointForTrack waypoint) { if (waypoint.Action == ActionEnum.UpDownGrabLeaf.Code) { From 9694919759d5152a5815753848e3fb646eeaac26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 29 Jan 2025 16:17:52 +0800 Subject: [PATCH 48/81] new orange option judge --- .../Simple/HsvTestWindow.cs | 2 +- .../Common/Job/ChooseTalkOptionTask.cs | 30 ++++--------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs b/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs index 8af9eef6..94274491 100644 --- a/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs +++ b/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs @@ -61,7 +61,7 @@ internal class HsvTestWindow Cv2.CreateTrackbar("High S", _windowDetectionName, ref _highS, MaxValue, on_high_S_thresh_trackbar); Cv2.CreateTrackbar("Low V", _windowDetectionName, ref _lowV, MaxValue, on_low_V_thresh_trackbar); Cv2.CreateTrackbar("High V", _windowDetectionName, ref _highV, MaxValue, on_high_V_thresh_trackbar); - var frame = Cv2.ImRead(@"E:\HuiTask\更好的原神\自动秘境\自动战斗\队伍识别\bsz1.png", ImreadModes.Color); + var frame = Cv2.ImRead(@"D:\HuiPrograming\Projects\CSharp\MiHoYo\BetterGenshinImpact\BetterGenshinImpact\bin\x64\Debug\net8.0-windows10.0.22621.0\log\textMat1.png", ImreadModes.Color); Mat frameHsv = new Mat(); // Convert from BGR to HSV colorspace Cv2.CvtColor(frame, frameHsv, ColorConversionCodes.BGR2HSV); diff --git a/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs b/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs index c2ed78d2..0930f991 100644 --- a/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs +++ b/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs @@ -198,31 +198,13 @@ public partial class ChooseTalkOptionTask private bool IsOrangeOption(Mat textMat) { // 只提取橙色 - using var bMat = OpenCvCommonHelper.Threshold(textMat, new Scalar(200, 165, 45), new Scalar(255, 205, 55)); - var whiteCount = OpenCvCommonHelper.CountGrayMatColor(bMat, 255); - var rate = whiteCount * 1.0 / (bMat.Width * bMat.Height); + Scalar lowerOrange = new Scalar(10, 150, 150); + Scalar upperOrange = new Scalar(25, 255, 255); + var mask = OpenCvCommonHelper.InRangeHsv(textMat, lowerOrange, upperOrange); + int highConfidencePixels = Cv2.CountNonZero(mask); + double rate = highConfidencePixels * 1.0 / (mask.Width * mask.Height); Debug.WriteLine($"识别到橙色文字区域占比:{rate}"); - if (rate > 0.06) - { - return true; - } - - return false; - } - - private bool IsOrangeOption2(Mat textMat) - { - // 只提取橙色 - using var bMat = OpenCvCommonHelper.Threshold(textMat, new Scalar(200, 165, 45), new Scalar(255, 205, 55)); - var whiteCount = OpenCvCommonHelper.CountGrayMatColor(bMat, 255); - var rate = whiteCount * 1.0 / (bMat.Width * bMat.Height); - Debug.WriteLine($"识别到橙色文字区域占比:{rate}"); - if (rate > 0.06) - { - return true; - } - - return false; + return rate > 0.15; } } From 8cffb01f0a389fcfbc8f3c76686fa0719a848c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 29 Jan 2025 17:44:38 +0800 Subject: [PATCH 49/81] fix method confusion --- BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs index 2ce61c41..918c4d34 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs @@ -852,7 +852,7 @@ public class PathExecutor await Delay(1000, ct); } - private async Task BeforeMoveToTarget(WaypointForTrack waypoint) + private async Task BeforeMoveCloseToTarget(WaypointForTrack waypoint) { if (waypoint.MoveMode == MoveModeEnum.Fly.Code && waypoint.Action == ActionEnum.StopFlying.Code) { @@ -863,7 +863,7 @@ public class PathExecutor } } - private async Task BeforeMoveCloseToTarget(WaypointForTrack waypoint) + private async Task BeforeMoveToTarget(WaypointForTrack waypoint) { if (waypoint.Action == ActionEnum.UpDownGrabLeaf.Code) { From c3cffff4f33aaec15dde65e41544d7865ed74798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 29 Jan 2025 22:23:12 +0800 Subject: [PATCH 50/81] fix CheckInBigMapUi --- BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs index 9e756e6c..adba027a 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs @@ -203,7 +203,7 @@ public class TpTask(CancellationToken ct) private async Task CheckInBigMapUi() { // 尝试打开地图失败后,先回到主界面后再次尝试打开地图 - if (await TryToOpenBigMapUi()) + if (!await TryToOpenBigMapUi()) { await new ReturnMainUiTask().Start(ct); if (!await TryToOpenBigMapUi()) From 2536b14af1598ec6893c63136bb9711f2a5f636f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 29 Jan 2025 22:58:23 +0800 Subject: [PATCH 51/81] fist run not init key binding --- BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs | 2 +- BetterGenshinImpact/ViewModel/MainWindowViewModel.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs index adba027a..8b1e4e0b 100644 --- a/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs +++ b/BetterGenshinImpact/GameTask/AutoTrackPath/TpTask.cs @@ -208,7 +208,7 @@ public class TpTask(CancellationToken ct) await new ReturnMainUiTask().Start(ct); if (!await TryToOpenBigMapUi()) { - throw new RetryException("尝试打开大地图失败,请确认你的打开地图按键是否是 M 键?"); + throw new RetryException("打开大地图失败,请检查按键绑定中「打开地图」按键设置是否和原神游戏中一致!"); } } } diff --git a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs index 76b19b63..d97b218c 100644 --- a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs +++ b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs @@ -115,7 +115,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel if (Config.CommonConfig.IsFirstRun) { // 自动初始化键位绑定 - InitKeyBinding(); + // InitKeyBinding(); Config.AutoFightConfig.TeamNames = ""; // 此配置以后无用 Config.CommonConfig.IsFirstRun = false; } @@ -134,6 +134,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel } + /* private void InitKeyBinding() { try @@ -151,6 +152,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel MessageBox.Error("读取原神键位并设置键位绑定数据时发生异常:" + e.Message + ",后续可以手动设置"); } } + */ /** * 不同的安装目录处理 From b14de9ed20adf456d1f6d54e40e35adf5e11656f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Thu, 30 Jan 2025 08:07:51 +0800 Subject: [PATCH 52/81] auto domain: SendInput instead of PostMessage --- .../GameTask/AutoDomain/AutoDomainTask.cs | 66 +++++++------- .../GameTask/AutoFight/AutoFightContext.cs | 52 +++++------ .../GameTask/AutoFight/Model/Avatar.cs | 91 ++++++++++--------- .../GameTask/AutoFight/Model/CombatScenes.cs | 8 +- .../GameTask/Common/BgiVision/BvStatus.cs | 3 +- 5 files changed, 113 insertions(+), 107 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs index 794764f4..54ee9088 100644 --- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs +++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs @@ -43,8 +43,6 @@ public class AutoDomainTask : ISoloTask private readonly AutoDomainParam _taskParam; - private readonly PostMessageSimulator _simulator; - private readonly YoloV8Predictor _predictor; private readonly AutoDomainConfig _config; @@ -55,10 +53,8 @@ public class AutoDomainTask : ISoloTask public AutoDomainTask(AutoDomainParam taskParam) { - _taskParam = taskParam; AutoFightAssets.DestroyInstance(); - _simulator = TaskContext.Instance().PostMessageSimulator; - + _taskParam = taskParam; _predictor = YoloV8Builder.CreateDefaultBuilder() .UseOnnxModel(Global.Absolute(@"Assets\Model\Domain\bgi_tree.onnx")) .WithSessionOptions(BgiSessionOption.Instance.Options) @@ -287,7 +283,7 @@ public class AutoDomainTask : ISoloTask private async Task EnterDomain() { - var fightAssets = AutoFightContext.Instance.FightAssets; + var fightAssets = AutoFightAssets.Instance; // 进入秘境 for (int i = 0; i < 3; i++) // 3次重试 有时候会拾取晶蝶 @@ -332,7 +328,7 @@ public class AutoDomainTask : ISoloTask while (retryTimes < 120) { retryTimes++; - using var cactRectArea = CaptureToRectArea().Find(AutoFightContext.Instance.FightAssets.ClickAnyCloseTipRa); + using var cactRectArea = CaptureToRectArea().Find(AutoFightAssets.Instance.ClickAnyCloseTipRa); if (!cactRectArea.IsEmpty()) { await Delay(1000, _ct); @@ -368,7 +364,7 @@ public class AutoDomainTask : ISoloTask await Task.Run((Action)(() => { - _simulator.SimulateAction(GIActions.MoveForward, KeyType.KeyDown); + Simulation.SendInput.SimulateAction(GIActions.MoveForward, KeyType.KeyDown); Sleep(30, _ct); // 组合键好像不能直接用 postmessage if (!_config.WalkToF) @@ -395,7 +391,7 @@ public class AutoDomainTask : ISoloTask } finally { - _simulator.SimulateAction(GIActions.MoveForward, KeyType.KeyUp); + Simulation.SendInput.SimulateAction(GIActions.MoveForward, KeyType.KeyUp); Sleep(50); if (!_config.WalkToF) { @@ -495,7 +491,7 @@ public class AutoDomainTask : ISoloTask { using var ra = CaptureToRectArea(); - var endTipsRect = ra.DeriveCrop(AutoFightContext.Instance.FightAssets.EndTipsUpperRect); + var endTipsRect = ra.DeriveCrop(AutoFightAssets.Instance.EndTipsUpperRect); var text = OcrFactory.Paddle.Ocr(endTipsRect.SrcGreyMat); if (text.Contains("挑战") || text.Contains("达成")) { @@ -503,7 +499,7 @@ public class AutoDomainTask : ISoloTask return true; } - endTipsRect = ra.DeriveCrop(AutoFightContext.Instance.FightAssets.EndTipsRect); + endTipsRect = ra.DeriveCrop(AutoFightAssets.Instance.EndTipsRect); text = OcrFactory.Paddle.Ocr(endTipsRect.SrcGreyMat); if (text.Contains("自动") || text.Contains("退出")) { @@ -611,13 +607,13 @@ public class AutoDomainTask : ISoloTask if (rightKeyDown) { // 先松开D键 - _simulator.KeyUp(moveRightKey); + Simulation.SendInput.Keyboard.KeyUp(moveRightKey); rightKeyDown = false; } if (!leftKeyDown) { - _simulator.KeyDown(moveLeftKey); + Simulation.SendInput.Keyboard.KeyDown(moveLeftKey); leftKeyDown = true; } } @@ -629,13 +625,13 @@ public class AutoDomainTask : ISoloTask if (leftKeyDown) { // 先松开A键 - _simulator.KeyUp(moveLeftKey); + Simulation.SendInput.Keyboard.KeyUp(moveLeftKey); leftKeyDown = false; } if (!rightKeyDown) { - _simulator.KeyDown(moveRightKey); + Simulation.SendInput.Keyboard.KeyDown(moveRightKey); rightKeyDown = true; } } @@ -644,14 +640,14 @@ public class AutoDomainTask : ISoloTask // 树在中间 松开所有键 if (rightKeyDown) { - _simulator.KeyUp(moveRightKey); + Simulation.SendInput.Keyboard.KeyUp(moveRightKey); prevKey = moveRightKey; rightKeyDown = false; } if (leftKeyDown) { - _simulator.KeyUp(moveLeftKey); + Simulation.SendInput.Keyboard.KeyUp(moveLeftKey); prevKey = moveLeftKey; leftKeyDown = false; } @@ -664,7 +660,9 @@ public class AutoDomainTask : ISoloTask backwardsAndForwardsCount++; } - _simulator.KeyPress(moveLeftKey, 60); + Simulation.SendInput.Keyboard.KeyDown(moveLeftKey); + Sleep(60); + Simulation.SendInput.Keyboard.KeyUp(moveLeftKey); prevKey = moveLeftKey; } else if (treeMiddleX > middleX) @@ -674,12 +672,16 @@ public class AutoDomainTask : ISoloTask backwardsAndForwardsCount++; } - _simulator.KeyPress(moveRightKey, 60); + Simulation.SendInput.Keyboard.KeyDown(moveRightKey); + Sleep(60); + Simulation.SendInput.Keyboard.KeyUp(moveRightKey); prevKey = moveRightKey; } else { - _simulator.KeyPress(moveForwardKey, 60); + Simulation.SendInput.Keyboard.KeyDown(moveForwardKey); + Sleep(60); + Simulation.SendInput.Keyboard.KeyUp(moveForwardKey); Sleep(500, _ct); treeCts.Cancel(); break; @@ -695,13 +697,13 @@ public class AutoDomainTask : ISoloTask { if (leftKeyDown) { - _simulator.KeyUp(moveLeftKey); + Simulation.SendInput.Keyboard.KeyUp(moveLeftKey); leftKeyDown = false; } if (!rightKeyDown) { - _simulator.KeyDown(moveRightKey); + Simulation.SendInput.Keyboard.KeyDown(moveRightKey); rightKeyDown = true; } } @@ -709,13 +711,13 @@ public class AutoDomainTask : ISoloTask { if (rightKeyDown) { - _simulator.KeyUp(moveRightKey); + Simulation.SendInput.Keyboard.KeyUp(moveRightKey); rightKeyDown = false; } if (!leftKeyDown) { - _simulator.KeyDown(moveLeftKey); + Simulation.SendInput.Keyboard.KeyDown(moveLeftKey); leftKeyDown = true; } } @@ -724,7 +726,9 @@ public class AutoDomainTask : ISoloTask if (backwardsAndForwardsCount >= _config.LeftRightMoveTimes) { // 左右移动5次说明已经在树中心了 - _simulator.KeyPress(moveForwardKey, 60); + Simulation.SendInput.Keyboard.KeyDown(moveForwardKey); + Sleep(60); + Simulation.SendInput.Keyboard.KeyUp(moveForwardKey); Sleep(500, _ct); treeCts.Cancel(); break; @@ -843,7 +847,7 @@ public class AutoDomainTask : ISoloTask break; } - var useCondensedResinRa = CaptureToRectArea().Find(AutoFightContext.Instance.FightAssets.UseCondensedResinRa); + var useCondensedResinRa = CaptureToRectArea().Find(AutoFightAssets.Instance.UseCondensedResinRa); if (!useCondensedResinRa.IsEmpty()) { useCondensedResinRa.Click(); @@ -883,13 +887,13 @@ public class AutoDomainTask : ISoloTask // 优先点击继续 - using var confirmRectArea = ra.Find(AutoFightContext.Instance.FightAssets.ConfirmRa); + using var confirmRectArea = ra.Find(AutoFightAssets.Instance.ConfirmRa); if (!confirmRectArea.IsEmpty()) { if (isLastTurn) { // 最后一回合 退出 - var exitRectArea = ra.Find(AutoFightContext.Instance.FightAssets.ExitRa); + var exitRectArea = ra.Find(AutoFightAssets.Instance.ExitRa); if (!exitRectArea.IsEmpty()) { exitRectArea.Click(); @@ -907,7 +911,7 @@ public class AutoDomainTask : ISoloTask if (condensedResinCount == 0 && fragileResinCount < 20) { // 没有体力了退出 - var exitRectArea = ra.Find(AutoFightContext.Instance.FightAssets.ExitRa); + var exitRectArea = ra.Find(AutoFightAssets.Instance.ExitRa); if (!exitRectArea.IsEmpty()) { exitRectArea.Click(); @@ -938,7 +942,7 @@ public class AutoDomainTask : ISoloTask var ra = CaptureToRectArea(); // 浓缩树脂 - var condensedResinCountRa = ra.Find(AutoFightContext.Instance.FightAssets.CondensedResinCountRa); + var condensedResinCountRa = ra.Find(AutoFightAssets.Instance.CondensedResinCountRa); if (!condensedResinCountRa.IsEmpty()) { // 图像右侧就是浓缩树脂数量 @@ -949,7 +953,7 @@ public class AutoDomainTask : ISoloTask } // 脆弱树脂 - var fragileResinCountRa = ra.Find(AutoFightContext.Instance.FightAssets.FragileResinCountRa); + var fragileResinCountRa = ra.Find(AutoFightAssets.Instance.FragileResinCountRa); if (!fragileResinCountRa.IsEmpty()) { // 图像右侧就是脆弱树脂数量 diff --git a/BetterGenshinImpact/GameTask/AutoFight/AutoFightContext.cs b/BetterGenshinImpact/GameTask/AutoFight/AutoFightContext.cs index ebcb8483..9df06aa7 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/AutoFightContext.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/AutoFightContext.cs @@ -1,27 +1,27 @@ -using BetterGenshinImpact.Core.Simulator; -using BetterGenshinImpact.GameTask.AutoFight.Assets; -using BetterGenshinImpact.Model; +// using BetterGenshinImpact.Core.Simulator; +// using BetterGenshinImpact.GameTask.AutoFight.Assets; +// using BetterGenshinImpact.Model; +// +// namespace BetterGenshinImpact.GameTask.AutoFight; -namespace BetterGenshinImpact.GameTask.AutoFight; - -/// -/// 自动战斗上下文 -/// 请在启动BetterGI以后再初始化 -/// -public class AutoFightContext : Singleton -{ - private AutoFightContext() - { - Simulator = TaskContext.Instance().PostMessageSimulator; - } - - /// - /// find资源 - /// - public AutoFightAssets FightAssets => AutoFightAssets.Instance; - - /// - /// 战斗专用的PostMessage模拟键鼠操作 - /// - public readonly PostMessageSimulator Simulator; -} +// /// +// /// 自动战斗上下文 +// /// 请在启动BetterGI以后再初始化 +// /// +// public class AutoFightContext : Singleton +// { +// private AutoFightContext() +// { +// Simulator = TaskContext.Instance().PostMessageSimulator; +// } +// +// /// +// /// find资源 +// /// +// public AutoFightAssets FightAssets => AutoFightAssets.Instance; +// +// /// +// /// 战斗专用的PostMessage模拟键鼠操作 +// /// +// public readonly PostMessageSimulator Simulator; +// } diff --git a/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs b/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs index 3b52ede3..dcb40390 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs @@ -18,6 +18,7 @@ using BetterGenshinImpact.GameTask.Common.BgiVision; using Vanara.PInvoke; using static BetterGenshinImpact.GameTask.Common.TaskControl; using BetterGenshinImpact.Core.Config; +using BetterGenshinImpact.GameTask.AutoFight.Assets; namespace BetterGenshinImpact.GameTask.AutoFight.Model; @@ -155,19 +156,19 @@ public class Avatar switch (Index) { case 1: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember1); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember1); break; case 2: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember2); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember2); break; case 3: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember3); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember3); break; case 4: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember4); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember4); break; case 5: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember5); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember5); break; default: break; @@ -210,19 +211,19 @@ public class Avatar switch (Index) { case 1: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember1); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember1); break; case 2: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember2); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember2); break; case 3: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember3); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember3); break; case 4: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember4); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember4); break; case 5: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember5); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember5); break; default: break; @@ -254,19 +255,19 @@ public class Avatar switch (Index) { case 1: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember1); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember1); break; case 2: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember2); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember2); break; case 3: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember3); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember3); break; case 4: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember4); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember4); break; case 5: - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SwitchMember5); + Simulation.SendInput.SimulateAction(GIActions.SwitchMember5); break; default: break; @@ -314,7 +315,7 @@ public class Avatar { var assetScale = TaskContext.Instance().SystemInfo.AssetScale; // 剪裁出队伍区域 - var teamRa = region.DeriveCrop(AutoFightContext.Instance.FightAssets.TeamRect); + var teamRa = region.DeriveCrop(AutoFightAssets.Instance.TeamRect); var blockX = NameRect.X + NameRect.Width * 2 - 10; var block = teamRa.DeriveCrop(new Rect(blockX, NameRect.Y, teamRa.Width - blockX, NameRect.Height * 2)); // Cv2.ImWrite($"block_{Name}.png", block.SrcMat); @@ -337,7 +338,7 @@ public class Avatar else { // 剪裁出IndexRect区域 - var teamRa = region.DeriveCrop(AutoFightContext.Instance.FightAssets.TeamRect); + var teamRa = region.DeriveCrop(AutoFightAssets.Instance.TeamRect); var blockX = NameRect.X + NameRect.Width * 2 - 10; var indexBlock = teamRa.DeriveCrop(new Rect(blockX + IndexRect.X, NameRect.Y + IndexRect.Y, IndexRect.Width, IndexRect.Height)); // Cv2.ImWrite($"indexBlock_{Name}.png", indexBlock.SrcMat); @@ -365,7 +366,7 @@ public class Avatar return; } - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.NormalAttack); + Simulation.SendInput.SimulateAction(GIActions.NormalAttack); ms -= 200; Sleep(200, Ct); } @@ -387,7 +388,7 @@ public class Avatar { if (Name == "纳西妲") { - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.ElementalSkill, KeyType.KeyDown); + Simulation.SendInput.SimulateAction(GIActions.ElementalSkill, KeyType.KeyDown); Sleep(300, Ct); for (int j = 0; j < 10; j++) { @@ -396,22 +397,22 @@ public class Avatar } Sleep(300); // 持续操作不应该被cts取消 - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.ElementalSkill, KeyType.KeyUp); + Simulation.SendInput.SimulateAction(GIActions.ElementalSkill, KeyType.KeyUp); } else if (Name == "坎蒂丝") { - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.ElementalSkill, KeyType.KeyDown); + Simulation.SendInput.SimulateAction(GIActions.ElementalSkill, KeyType.KeyDown); Thread.Sleep(3000); - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.ElementalSkill, KeyType.KeyUp); + Simulation.SendInput.SimulateAction(GIActions.ElementalSkill, KeyType.KeyUp); } else { - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.ElementalSkill, KeyType.Hold); + Simulation.SendInput.SimulateAction(GIActions.ElementalSkill, KeyType.Hold); } } else { - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.ElementalSkill, KeyType.KeyPress); + Simulation.SendInput.SimulateAction(GIActions.ElementalSkill, KeyType.KeyPress); } Sleep(200, Ct); @@ -436,7 +437,7 @@ public class Avatar /// public double GetSkillCurrentCd(ImageRegion imageRegion) { - var eRa = imageRegion.DeriveCrop(AutoFightContext.Instance.FightAssets.ERect); + var eRa = imageRegion.DeriveCrop(AutoFightAssets.Instance.ERect); var text = OcrFactory.Paddle.Ocr(eRa.SrcGreyMat); return StringUtils.TryParseDouble(text); } @@ -455,7 +456,7 @@ public class Avatar return; } - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.ElementalBurst); + Simulation.SendInput.SimulateAction(GIActions.ElementalBurst); Sleep(200, Ct); var region = CaptureToRectArea(); @@ -490,7 +491,7 @@ public class Avatar // /// // public double GetBurstCurrentCd(CaptureContent content) // { - // var qRa = content.CaptureRectArea.Crop(AutoFightContext.Instance.FightAssets.QRect); + // var qRa = content.CaptureRectArea.Crop(AutoFightAssets.Instance.QRect); // var text = OcrFactory.Paddle.Ocr(qRa.SrcGreyMat); // return StringUtils.TryParseDouble(text); // } @@ -510,9 +511,9 @@ public class Avatar ms = 200; } - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SprintMouse, KeyType.KeyDown); + Simulation.SendInput.SimulateAction(GIActions.SprintMouse, KeyType.KeyDown); Sleep(ms); // 冲刺不能被cts取消 - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.SprintMouse, KeyType.KeyUp); + Simulation.SendInput.SimulateAction(GIActions.SprintMouse, KeyType.KeyUp); } public void Walk(string key, int ms) @@ -545,9 +546,9 @@ public class Avatar return; } - AutoFightContext.Instance.Simulator.KeyDown(vk); + Simulation.SendInput.Keyboard.KeyDown(vk); Sleep(ms); // 行走不能被cts取消 - AutoFightContext.Instance.Simulator.KeyUp(vk); + Simulation.SendInput.Keyboard.KeyUp(vk); } /// @@ -574,7 +575,7 @@ public class Avatar /// public void Jump() { - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.Jump); + Simulation.SendInput.SimulateAction(GIActions.Jump); } /// @@ -590,7 +591,7 @@ public class Avatar if (Name == "那维莱特") { var dpi = TaskContext.Instance().DpiScale; - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.NormalAttack, KeyType.KeyDown); + Simulation.SendInput.SimulateAction(GIActions.NormalAttack, KeyType.KeyDown); while (ms >= 0) { if (Ct is { IsCancellationRequested: true }) @@ -603,13 +604,13 @@ public class Avatar Sleep(50); // 持续操作不应该被cts取消 } - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.NormalAttack, KeyType.KeyUp); + Simulation.SendInput.SimulateAction(GIActions.NormalAttack, KeyType.KeyUp); } else { - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.NormalAttack, KeyType.KeyDown); + Simulation.SendInput.SimulateAction(GIActions.NormalAttack, KeyType.KeyDown); Sleep(ms); // 持续操作不应该被cts取消 - AutoFightContext.Instance.Simulator.SimulateAction(GIActions.NormalAttack, KeyType.KeyUp); + Simulation.SendInput.SimulateAction(GIActions.NormalAttack, KeyType.KeyUp); } } @@ -618,11 +619,11 @@ public class Avatar key = key.ToLower(); if (key == "left") { - AutoFightContext.Instance.Simulator.LeftButtonDown(); + Simulation.SendInput.Mouse.LeftButtonDown(); } else if (key == "right") { - AutoFightContext.Instance.Simulator.RightButtonDown(); + Simulation.SendInput.Mouse.RightButtonDown(); } else if (key == "middle") { @@ -635,11 +636,11 @@ public class Avatar key = key.ToLower(); if (key == "left") { - AutoFightContext.Instance.Simulator.LeftButtonUp(); + Simulation.SendInput.Mouse.LeftButtonUp(); } else if (key == "right") { - AutoFightContext.Instance.Simulator.RightButtonUp(); + Simulation.SendInput.Mouse.RightButtonUp(); } else if (key == "middle") { @@ -652,11 +653,11 @@ public class Avatar key = key.ToLower(); if (key == "left") { - AutoFightContext.Instance.Simulator.LeftButtonClick(); + Simulation.SendInput.Mouse.LeftButtonClick(); } else if (key == "right") { - AutoFightContext.Instance.Simulator.RightButtonClick(); + Simulation.SendInput.Mouse.RightButtonClick(); } else if (key == "middle") { @@ -672,18 +673,18 @@ public class Avatar public void KeyDown(string key) { var vk = User32Helper.ToVk(key); - AutoFightContext.Instance.Simulator.KeyDown(vk); + Simulation.SendInput.Keyboard.KeyDown(vk); } public void KeyUp(string key) { var vk = User32Helper.ToVk(key); - AutoFightContext.Instance.Simulator.KeyUp(vk); + Simulation.SendInput.Keyboard.KeyUp(vk); } public void KeyPress(string key) { var vk = User32Helper.ToVk(key); - AutoFightContext.Instance.Simulator.KeyPress(vk); + Simulation.SendInput.Keyboard.KeyPress(vk); } } diff --git a/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs b/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs index c3ea2ca6..a2f9e2a0 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs @@ -217,7 +217,7 @@ public class CombatScenes : IDisposable { if (avatarIndexRectList == null && ExpectedTeamAvatarNum == 4) { - avatarIndexRectList = AutoFightContext.Instance.FightAssets.AvatarIndexRectList; + avatarIndexRectList = AutoFightAssets.Instance.AvatarIndexRectList; } if (avatarIndexRectList == null) @@ -284,7 +284,7 @@ public class CombatScenes : IDisposable } // 剪裁出队伍区域 - var teamRa = content.CaptureRectArea.DeriveCrop(AutoFightContext.Instance.FightAssets.TeamRectNoIndex); + var teamRa = content.CaptureRectArea.DeriveCrop(AutoFightAssets.Instance.TeamRectNoIndex); // 过滤出白色 var hsvFilterMat = OpenCvCommonHelper.InRangeHsv(teamRa.SrcMat, new Scalar(0, 0, 210), new Scalar(255, 30, 255)); @@ -319,10 +319,10 @@ public class CombatScenes : IDisposable { // 流浪者特殊处理 // 4人以上的队伍,不支持流浪者的识别 - var wanderer = rectArea.Find(AutoFightContext.Instance.FightAssets.WandererIconRa); + var wanderer = rectArea.Find(AutoFightAssets.Instance.WandererIconRa); if (wanderer.IsEmpty()) { - wanderer = rectArea.Find(AutoFightContext.Instance.FightAssets.WandererIconNoActiveRa); + wanderer = rectArea.Find(AutoFightAssets.Instance.WandererIconNoActiveRa); } if (wanderer.IsEmpty()) diff --git a/BetterGenshinImpact/GameTask/Common/BgiVision/BvStatus.cs b/BetterGenshinImpact/GameTask/Common/BgiVision/BvStatus.cs index 6bb72c25..87ccf3d0 100644 --- a/BetterGenshinImpact/GameTask/Common/BgiVision/BvStatus.cs +++ b/BetterGenshinImpact/GameTask/Common/BgiVision/BvStatus.cs @@ -10,6 +10,7 @@ using BetterGenshinImpact.Core.Simulator; using BetterGenshinImpact.GameTask.AutoFight; using Vanara.PInvoke; using System.Threading; +using BetterGenshinImpact.GameTask.AutoFight.Assets; using BetterGenshinImpact.GameTask.AutoSkip.Assets; using BetterGenshinImpact.GameTask.GameLoading.Assets; @@ -148,7 +149,7 @@ public static partial class Bv /// public static bool IsInRevivePrompt(ImageRegion region) { - using var confirmRectArea = region.Find(AutoFightContext.Instance.FightAssets.ConfirmRa); + using var confirmRectArea = region.Find(AutoFightAssets.Instance.ConfirmRa); if (!confirmRectArea.IsEmpty()) { var list = region.FindMulti(new RecognitionObject From 137ba4384a2cca57d70166859f3ac60eb10aa522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Thu, 30 Jan 2025 09:55:52 +0800 Subject: [PATCH 53/81] new e detect --- .../Simple/HsvTestWindow.cs | 2 +- .../AutoFight/Assets/AutoFightAssets.cs | 3 +++ .../GameTask/AutoFight/Model/Avatar.cs | 13 +++++++----- .../ViewModel/Pages/HotKeyPageViewModel.cs | 21 ++++++++++++++++--- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs b/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs index 94274491..63fe7d8c 100644 --- a/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs +++ b/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs @@ -61,7 +61,7 @@ internal class HsvTestWindow Cv2.CreateTrackbar("High S", _windowDetectionName, ref _highS, MaxValue, on_high_S_thresh_trackbar); Cv2.CreateTrackbar("Low V", _windowDetectionName, ref _lowV, MaxValue, on_low_V_thresh_trackbar); Cv2.CreateTrackbar("High V", _windowDetectionName, ref _highV, MaxValue, on_high_V_thresh_trackbar); - var frame = Cv2.ImRead(@"D:\HuiPrograming\Projects\CSharp\MiHoYo\BetterGenshinImpact\BetterGenshinImpact\bin\x64\Debug\net8.0-windows10.0.22621.0\log\textMat1.png", ImreadModes.Color); + var frame = Cv2.ImRead(@"E:\HuiTask\更好的原神\自动秘境\自动战斗\队伍识别\冷却时间\Clip_20250130_092132.png", ImreadModes.Color); Mat frameHsv = new Mat(); // Convert from BGR to HSV colorspace Cv2.CvtColor(frame, frameHsv, ColorConversionCodes.BGR2HSV); diff --git a/BetterGenshinImpact/GameTask/AutoFight/Assets/AutoFightAssets.cs b/BetterGenshinImpact/GameTask/AutoFight/Assets/AutoFightAssets.cs index 03c7cdc3..e48bcb4f 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Assets/AutoFightAssets.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Assets/AutoFightAssets.cs @@ -12,6 +12,7 @@ public class AutoFightAssets : BaseAssets public List AvatarSideIconRectList; // 侧边栏角色头像 非联机状态下 public List AvatarIndexRectList; // 侧边栏角色头像对应的白色块 非联机状态下 public Rect ERect; + public Rect ECooldownRect; public Rect QRect; public Rect EndTipsUpperRect; // 挑战达成提示 public Rect EndTipsRect; @@ -47,6 +48,8 @@ public class AutoFightAssets : BaseAssets (int)(355 * AssetScale), (int)(465 * AssetScale)); ERect = new Rect(CaptureRect.Width - (int)(267 * AssetScale), CaptureRect.Height - (int)(132 * AssetScale), (int)(77 * AssetScale), (int)(77 * AssetScale)); + ECooldownRect = new Rect(CaptureRect.Width - (int)(241 * AssetScale), CaptureRect.Height - (int)(97 * AssetScale), + (int)(41 * AssetScale), (int)(18 * AssetScale)); QRect = new Rect(CaptureRect.Width - (int)(157 * AssetScale), CaptureRect.Height - (int)(165 * AssetScale), (int)(110 * AssetScale), (int)(110 * AssetScale)); // 小道具位置 1920-133,800,60,50 diff --git a/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs b/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs index dcb40390..b83b8aa0 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Model/Avatar.cs @@ -56,7 +56,7 @@ public class Avatar /// 长按元素战技CD /// public double SkillHoldCd { get; set; } - + /// /// 最近一次使用元素战技的时间 /// @@ -120,7 +120,7 @@ public class Avatar { Logger.LogWarning("检测到复苏界面,存在角色被击败,前往七天神像复活"); // 先打开地图 - Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_ESCAPE); // NOTE: 此处按下Esc是为了关闭复苏界面,无需改键 + Simulation.SendInput.Keyboard.KeyPress(User32.VK.VK_ESCAPE); // NOTE: 此处按下Esc是为了关闭复苏界面,无需改键 Sleep(600, Ct); Simulation.SendInput.SimulateAction(GIActions.OpenMap); // tp 到七天神像复活 @@ -173,6 +173,7 @@ public class Avatar default: break; } + // Debug.WriteLine($"切换到{Index}号位"); // Cv2.ImWrite($"log/切换.png", region.SrcMat); Sleep(250, Ct); @@ -272,6 +273,7 @@ public class Avatar default: break; } + Sleep(250); } } @@ -437,8 +439,9 @@ public class Avatar /// public double GetSkillCurrentCd(ImageRegion imageRegion) { - var eRa = imageRegion.DeriveCrop(AutoFightAssets.Instance.ERect); - var text = OcrFactory.Paddle.Ocr(eRa.SrcGreyMat); + var eRa = imageRegion.DeriveCrop(AutoFightAssets.Instance.ECooldownRect); + var eRaWhite = OpenCvCommonHelper.InRangeHsv(eRa.SrcMat, new Scalar(0, 0, 235), new Scalar(0, 25, 255)); + var text = OcrFactory.Paddle.OcrWithoutDetector(eRaWhite); return StringUtils.TryParseDouble(text); } @@ -687,4 +690,4 @@ public class Avatar var vk = User32Helper.ToVk(key); Simulation.SendInput.Keyboard.KeyPress(vk); } -} +} \ No newline at end of file diff --git a/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs index 80ce0a34..343eb4e7 100644 --- a/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/HotKeyPageViewModel.cs @@ -28,9 +28,13 @@ using System.Diagnostics; using System.Reflection; using System.Threading; using System.Threading.Tasks; +using BetterGenshinImpact.Core.Recognition.OCR; +using BetterGenshinImpact.Core.Recognition.OpenCv; +using BetterGenshinImpact.GameTask.AutoFight.Assets; using BetterGenshinImpact.GameTask.Model.Area; using BetterGenshinImpact.GameTask.QuickTeleport.Assets; using BetterGenshinImpact.View; +using OpenCvSharp; using Vanara.PInvoke; using HotKeySettingModel = BetterGenshinImpact.Model.HotKeySettingModel; @@ -595,9 +599,20 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel // TaskControl.Logger.LogInformation("大地图界面缩放按钮位置:{Position}", Bv.GetBigMapScale( TaskControl.CaptureToRectArea())); - TaskControl.Logger.LogInformation($"尝试显示遮罩窗口"); - var maskWindow = MaskWindow.Instance(); - maskWindow.Invoke(() => { maskWindow.Hide(); }); + // TaskControl.Logger.LogInformation($"尝试显示遮罩窗口"); + // var maskWindow = MaskWindow.Instance(); + // maskWindow.Invoke(() => { maskWindow.Show(); }); + Task.Run(async () => { + for (int i = 0; i < 100; i++) + { + var imageRegion = TaskControl.CaptureToRectArea(); + var eRa = imageRegion.DeriveCrop(AutoFightAssets.Instance.ECooldownRect); + var eRaWhite = OpenCvCommonHelper.InRangeHsv(eRa.SrcMat, new Scalar(0, 0, 235), new Scalar(0, 25, 255)); + var text = OcrFactory.Paddle.OcrWithoutDetector(eRaWhite); + TaskControl.Logger.LogInformation("冷却时间 {Num}", StringUtils.TryParseDouble(text)); + await Task.Delay(10); + } + }); } )); debugDirectory.Children.Add(new HotKeySettingModel( From 70a8d544fd69523885a679f5b232c70a834ee0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Thu, 30 Jan 2025 10:29:14 +0800 Subject: [PATCH 54/81] ui: win10 not display switch blur button --- BetterGenshinImpact/View/MainWindow.xaml | 19 ++++++++++--------- .../ViewModel/MainWindowViewModel.cs | 9 ++++++--- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/BetterGenshinImpact/View/MainWindow.xaml b/BetterGenshinImpact/View/MainWindow.xaml index 1c03fa30..a97bd5bc 100644 --- a/BetterGenshinImpact/View/MainWindow.xaml +++ b/BetterGenshinImpact/View/MainWindow.xaml @@ -83,7 +83,7 @@ - + @@ -125,7 +125,7 @@ - + @@ -180,13 +180,14 @@ + Height="32" + Background="Transparent" + BorderBrush="Transparent" + Command="{Binding SwitchBackdropCommand}" + CornerRadius="0" + Icon="{ui:SymbolIcon Blur24}" + ToolTip="切换毛玻璃效果" + Visibility="{Binding IsWin11Later, Converter={StaticResource BooleanToVisibilityConverter}, Mode=OneWay}" /> $"BetterGI · 更好的原神 · {Global.Version}{(RuntimeHelper.IsDebug ? " · Dev" : string.Empty)}"; [ObservableProperty] - public bool _isVisible = true; + private bool _isVisible = true; [ObservableProperty] - public WindowState _windowState = WindowState.Normal; + private WindowState _windowState = WindowState.Normal; [ObservableProperty] - public WindowBackdropType _currentBackdropType = WindowBackdropType.Auto; + private WindowBackdropType _currentBackdropType = WindowBackdropType.Auto; + + [ObservableProperty] + private bool _isWin11Later = OsVersionHelper.IsWindows11_OrGreater; public AllConfig Config { get; set; } From 7d7289ac161e2433b01a664b12f1d16f2f52d72c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Thu, 30 Jan 2025 10:36:49 +0800 Subject: [PATCH 55/81] release all key after fight #1073 --- BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs b/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs index a2f9e2a0..dc7d8fbf 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Model/CombatScenes.cs @@ -19,6 +19,7 @@ using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Threading; +using BetterGenshinImpact.Core.Simulator; using static BetterGenshinImpact.GameTask.Common.TaskControl; namespace BetterGenshinImpact.GameTask.AutoFight.Model; @@ -249,6 +250,9 @@ public class CombatScenes : IDisposable public void AfterTask() { + // 释放所有按键 + Simulation.ReleaseAllKey(); + var mwk = SelectAvatar("玛薇卡"); if (mwk != null) { From 547a56b9327734ae592a031442c5bf1f12f43529 Mon Sep 17 00:00:00 2001 From: Yang-z Date: Fri, 31 Jan 2025 18:03:48 +0800 Subject: [PATCH 56/81] auto pathing: reduce the startup time of `MoveCloseTo` --- BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs index 918c4d34..79eeac6f 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs @@ -809,12 +809,11 @@ public class PathExecutor private async Task MoveCloseTo(WaypointForTrack waypoint) { - var screen = CaptureToRectArea(); - var position = await GetPosition(screen); - var targetOrientation = Navigation.GetTargetOrientation(waypoint, position); + ImageRegion screen; + Point2f position; + int targetOrientation; Logger.LogInformation("精确接近目标点,位置({x2},{y2})", $"{waypoint.GameX:F1}", $"{waypoint.GameY:F1}"); - await _rotateTask.WaitUntilRotatedTo(targetOrientation, 2); var stepsTaken = 0; while (!ct.IsCancellationRequested) { From 854baad4207803e827e68b029e58a72fc6c46135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Fri, 31 Jan 2025 18:13:09 +0800 Subject: [PATCH 57/81] test code --- BetterGenshinImpact.Test/Simple/HsvTestWindow.cs | 2 +- .../GameTask/Common/Job/ChooseTalkOptionTask.cs | 5 +++-- .../GameTask/Common/Job/GoToAdventurersGuildTask.cs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs b/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs index 63fe7d8c..21094d00 100644 --- a/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs +++ b/BetterGenshinImpact.Test/Simple/HsvTestWindow.cs @@ -61,7 +61,7 @@ internal class HsvTestWindow Cv2.CreateTrackbar("High S", _windowDetectionName, ref _highS, MaxValue, on_high_S_thresh_trackbar); Cv2.CreateTrackbar("Low V", _windowDetectionName, ref _lowV, MaxValue, on_low_V_thresh_trackbar); Cv2.CreateTrackbar("High V", _windowDetectionName, ref _highV, MaxValue, on_high_V_thresh_trackbar); - var frame = Cv2.ImRead(@"E:\HuiTask\更好的原神\自动秘境\自动战斗\队伍识别\冷却时间\Clip_20250130_092132.png", ImreadModes.Color); + var frame = Cv2.ImRead(@"E:\HuiTask\更好的原神\自动秘境\Q识别\拼图\2.png", ImreadModes.Color); Mat frameHsv = new Mat(); // Convert from BGR to HSV colorspace Cv2.CvtColor(frame, frameHsv, ColorConversionCodes.BGR2HSV); diff --git a/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs b/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs index 0930f991..60df0a66 100644 --- a/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs +++ b/BetterGenshinImpact/GameTask/Common/Job/ChooseTalkOptionTask.cs @@ -63,7 +63,7 @@ public partial class ChooseTalkOptionTask { if (isOrange) { - // region.DeriveCrop(optionRa.ToRect()).SrcMat.SaveImage(Global.Absolute($"log\\t{optionRa.Text}.png")); + region.DeriveCrop(optionRa.ToRect()).SrcMat.SaveImage(Global.Absolute($"log\\t{optionRa.Text}.png")); if (!IsOrangeOption(region.DeriveCrop(optionRa.ToRect()).SrcMat)) { return TalkOptionRes.FoundButNotOrange; @@ -204,7 +204,8 @@ public partial class ChooseTalkOptionTask int highConfidencePixels = Cv2.CountNonZero(mask); double rate = highConfidencePixels * 1.0 / (mask.Width * mask.Height); Debug.WriteLine($"识别到橙色文字区域占比:{rate}"); - return rate > 0.15; + _logger.LogInformation($"识别到橙色文字区域占比:{rate}"); + return rate > 0.1; } } diff --git a/BetterGenshinImpact/GameTask/Common/Job/GoToAdventurersGuildTask.cs b/BetterGenshinImpact/GameTask/Common/Job/GoToAdventurersGuildTask.cs index e8e5ecd4..3def90d1 100644 --- a/BetterGenshinImpact/GameTask/Common/Job/GoToAdventurersGuildTask.cs +++ b/BetterGenshinImpact/GameTask/Common/Job/GoToAdventurersGuildTask.cs @@ -80,7 +80,7 @@ public class GoToAdventurersGuildTask await new ReturnMainUiTask().Start(ct); // 结束后重新打开 - await Delay(1000, ct); + await Delay(1200, ct); var ra = CaptureToRectArea(); if (!Bv.FindFAndPress(ra, "凯瑟琳")) { From dfa0c75a15370ce9e872cefabaee855ef5b63491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Fri, 31 Jan 2025 18:13:21 +0800 Subject: [PATCH 58/81] 0.40.1 --- BetterGenshinImpact/BetterGenshinImpact.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj index 9e81a682..2a9fb4c2 100644 --- a/BetterGenshinImpact/BetterGenshinImpact.csproj +++ b/BetterGenshinImpact/BetterGenshinImpact.csproj @@ -10,7 +10,7 @@ true Assets\Images\logo.ico BetterGI - 0.40.0 + 0.40.1 x64 embedded From 09a520a92feebda7819cc3f1304e8c136e1810c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Fri, 31 Jan 2025 19:06:28 +0800 Subject: [PATCH 59/81] remove invalid link --- BetterGenshinImpact/Helpers/Http/ProxySpeedTester.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/BetterGenshinImpact/Helpers/Http/ProxySpeedTester.cs b/BetterGenshinImpact/Helpers/Http/ProxySpeedTester.cs index c38fb2e9..2750b02e 100644 --- a/BetterGenshinImpact/Helpers/Http/ProxySpeedTester.cs +++ b/BetterGenshinImpact/Helpers/Http/ProxySpeedTester.cs @@ -15,9 +15,6 @@ public class ProxySpeedTester "{0}", "https://mirror.ghproxy.com/{0}", "https://hub.gitmirror.com/{0}", - "https://ghproxy.cc/{0}", - "https://www.ghproxy.cc/{0}", - "https://ghproxy.cn/{0}", "https://ghproxy.net/{0}" ]; @@ -70,11 +67,12 @@ public class ProxySpeedTester // 模拟代理测试请求 var response = await _httpClient.GetAsync(string.Format(proxyAddress, target), cancellationToken); response.EnsureSuccessStatusCode(); - return (proxyAddress, await response.Content.ReadAsStringAsync(cancellationToken), true); + var content = await response.Content.ReadAsStringAsync(cancellationToken); + return (proxyAddress, content, true); } catch (Exception e) { return (proxyAddress, e.Message, false); } } -} +} \ No newline at end of file From 90b8a37389dc20ac84bf9ae6be19952fbe315f23 Mon Sep 17 00:00:00 2001 From: Yang-z Date: Fri, 31 Jan 2025 22:19:02 +0800 Subject: [PATCH 60/81] auto pathing: add `Orientation` to `WaypointType` --- .../AutoPathing/Model/Enum/WaypointType.cs | 2 + .../GameTask/AutoPathing/PathExecutor.cs | 48 +++++++++++++------ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/WaypointType.cs b/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/WaypointType.cs index 6e0e2da3..8abde910 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/WaypointType.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/WaypointType.cs @@ -7,6 +7,7 @@ public class WaypointType(string code, string msg) public static readonly WaypointType Path = new("path", "途径点"); public static readonly WaypointType Target = new("target", "目标点"); public static readonly WaypointType Teleport = new("teleport", "传送点"); + public static readonly WaypointType Orientation = new("Orientation", "方位点"); public static IEnumerable Values { @@ -15,6 +16,7 @@ public class WaypointType(string code, string msg) yield return Path; yield return Target; yield return Teleport; + yield return Orientation; } } diff --git a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs index 79eeac6f..18e3c6f2 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs @@ -178,24 +178,34 @@ public class PathExecutor { await BeforeMoveToTarget(waypoint); - // Path不用走得很近,Target需要接近,但都需要先移动到对应位置 - await MoveTo(waypoint); + if (waypoint.Type == WaypointType.Orientation.Code) + // 方位点,只需要朝向 + await FaceTo(waypoint); + else + // Path不用走得很近,Target需要接近,但都需要先移动到对应位置 + await MoveTo(waypoint); await BeforeMoveCloseToTarget(waypoint); - if (waypoint.Type == WaypointType.Target.Code - // 除了 fight mining stop_flying 之外的 action 都需要接近 - || (!string.IsNullOrEmpty(waypoint.Action) - && waypoint.Action != ActionEnum.StopFlying.Code - && waypoint.Action != ActionEnum.NahidaCollect.Code - && waypoint.Action != ActionEnum.Fight.Code - && waypoint.Action != ActionEnum.CombatScript.Code - && waypoint.Action != ActionEnum.Mining.Code)) + if ( + waypoint.Type != WaypointType.Orientation.Code // 方位点不需要接近 + && waypoint.Action != ActionEnum.Fight.Code // 战斗action强制不接近 + && ( + waypoint.Type == WaypointType.Target.Code + || ( + !string.IsNullOrEmpty(waypoint.Action) + && waypoint.Action != ActionEnum.StopFlying.Code + && waypoint.Action != ActionEnum.NahidaCollect.Code + && waypoint.Action != ActionEnum.CombatScript.Code + && waypoint.Action != ActionEnum.Mining.Code + // 除了上述之外的actions都强制接近,即时类型是Path(真的需要这样吗?) + // force_tp, up_down_grab_leaf, log_output, 这几个不需要接近; + // pick_around, hydro_collect, electro_collect, anemo_collect, 这几个现存脚本中没有用target? + ) + ) + ) { - if (waypoint.Action != ActionEnum.Fight.Code) // 战斗action强制不接近 - { - await MoveCloseTo(waypoint); - } + await MoveCloseTo(waypoint); } //skipOtherOperations如果重试,则跳过相关操作, @@ -567,6 +577,16 @@ public class PathExecutor await Delay(500, ct); // 多等一会 } + private async Task FaceTo(WaypointForTrack waypoint) + { + var screen = CaptureToRectArea(); + var position = await GetPosition(screen); + var targetOrientation = Navigation.GetTargetOrientation(waypoint, position); + Logger.LogInformation("朝向点,位置({x2},{y2})", $"{waypoint.GameX:F1}", $"{waypoint.GameY:F1}"); + await _rotateTask.WaitUntilRotatedTo(targetOrientation, 2); + await Delay(500, ct); + } + private async Task MoveTo(WaypointForTrack waypoint) { // 切人 From c2e028c52934b526c63eb9e6e1368b5708ba09c9 Mon Sep 17 00:00:00 2001 From: Scarlet Date: Fri, 31 Jan 2025 16:37:49 -0600 Subject: [PATCH 61/81] optimize: fight finish detection --- BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs index 4c5ad732..0b4fa6e3 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs @@ -457,7 +457,7 @@ public class AutoFightTask : ISoloTask await Delay(450, _ct); var ra = CaptureToRectArea(); var b3 = ra.SrcMat.At(50, 790); //进度条颜色 - var whiteTile = ra.SrcMat.At(50, 772); //白块 + var whiteTile = ra.SrcMat.At(50, 768); //白块 if (IsWhite(whiteTile.Item2, whiteTile.Item1, whiteTile.Item0) && IsYellow(b3.Item2, b3.Item1, b3.Item0) /* AreDifferencesWithinBounds(_finishDetectConfig.BattleEndProgressBarColor, (b3.Item0, b3.Item1, b3.Item2), _finishDetectConfig.BattleEndProgressBarColorTolerance)*/) { Logger.LogInformation("识别到战斗结束"); @@ -466,7 +466,8 @@ public class AutoFightTask : ISoloTask } Simulation.SendInput.SimulateAction(GIActions.Drop); - Logger.LogInformation($"未识别到战斗结束{b3.Item0},{b3.Item1},{b3.Item2}"); + Logger.LogInformation($"未识别到战斗结束yellow{b3.Item0},{b3.Item1},{b3.Item2}"); + Logger.LogInformation($"未识别到战斗结束white{whiteTile.Item0},{whiteTile.Item1},{whiteTile.Item2}"); /** if (!Bv.IsInMainUi(ra)) { @@ -477,10 +478,6 @@ public class AutoFightTask : ISoloTask _lastFightFlagTime = DateTime.Now; return false; - - // } - - return false; } bool IsYellow(int r, int g, int b) From 06b142b8b29b0a118b9ba51bd2d724a206f09f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sat, 1 Feb 2025 08:59:24 +0800 Subject: [PATCH 62/81] more check for script repo --- BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs | 5 +++++ BetterGenshinImpact/Helpers/Http/ProxySpeedTester.cs | 2 ++ 2 files changed, 7 insertions(+) diff --git a/BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs b/BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs index 5f958d5a..3051c4d8 100644 --- a/BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs +++ b/BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs @@ -92,6 +92,11 @@ public class ScriptRepoUpdater : Singleton // 解析信息 var fastProxyUrl = res.Item1; var jsonString = res.Item2; + if (string.IsNullOrEmpty(jsonString)) + { + throw new Exception("获取仓库信息失败"); + } + var (time, url, file) = ParseJson(jsonString); var updated = false; diff --git a/BetterGenshinImpact/Helpers/Http/ProxySpeedTester.cs b/BetterGenshinImpact/Helpers/Http/ProxySpeedTester.cs index 2750b02e..eafab0d6 100644 --- a/BetterGenshinImpact/Helpers/Http/ProxySpeedTester.cs +++ b/BetterGenshinImpact/Helpers/Http/ProxySpeedTester.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using Newtonsoft.Json.Linq; namespace BetterGenshinImpact.Helpers.Http; @@ -68,6 +69,7 @@ public class ProxySpeedTester var response = await _httpClient.GetAsync(string.Format(proxyAddress, target), cancellationToken); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(cancellationToken); + var json = JObject.Parse(content); return (proxyAddress, content, true); } catch (Exception e) From e735cacb17a76d06d0e324ffd43ae05642379e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sat, 1 Feb 2025 10:23:05 +0800 Subject: [PATCH 63/81] fix bettergi://start not valid --- .../ViewModel/Pages/HomePageViewModel.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs index ebc50e88..101a5b7d 100644 --- a/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs @@ -100,19 +100,22 @@ public partial class HomePageViewModel : ObservableObject, INavigationAware, IVi private void OnLoaded() { // OnTest(); - + var args = Environment.GetCommandLineArgs(); + + // url protocol + // BetterGI.dll bettergi://start/ if (args.Length > 1) { - if (args[1].Equals("start")) - { - _ = OnStartTriggerAsync(); - } - else if (args[1].Equals("startOneDragon")) + if (args[1].Contains("startOneDragon")) { var odVm = App.GetService(); odVm?.OneKeyExecuteCommand.Execute(null); } + else if (args[1].Contains("start")) + { + _ = OnStartTriggerAsync(); + } } } From f109ac5a14d9fa12eb68e0a9eaae4d00a0f546c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sat, 1 Feb 2025 10:43:52 +0800 Subject: [PATCH 64/81] MSIAfterburner warning --- BetterGenshinImpact/View/MaskWindow.xaml.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/BetterGenshinImpact/View/MaskWindow.xaml.cs b/BetterGenshinImpact/View/MaskWindow.xaml.cs index 0c772f67..e057451a 100644 --- a/BetterGenshinImpact/View/MaskWindow.xaml.cs +++ b/BetterGenshinImpact/View/MaskWindow.xaml.cs @@ -174,10 +174,23 @@ public partial class MaskWindow : Window { _logger.LogError("当前游戏分辨率不是16:9,一条龙、配队识别、地图传送、地图追踪等所有独立任务与全自动任务相关功能,都将会无法正常使用!"); } + + AfterburnerWarning(); // 读取游戏注册表配置 // ReadGameSettings(); } + + /** + * MSIAfterburner.exe 在左上角会导致识别失败 + */ + private void AfterburnerWarning() + { + if (Process.GetProcessesByName("MSIAfterburner").Length > 0) + { + _logger.LogWarning("检测到 MSI Afterburner 正在运行,如果信息位于左上角会遮盖一些图像识别要素导致识别失败,请关闭 MSI Afterburner 或者调整信息位置后重试!"); + } + } // private void ReadGameSettings() // { From c2709544fabfa15790aa58e1cc0547e2f67d4998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sat, 1 Feb 2025 13:33:05 +0800 Subject: [PATCH 65/81] allow full folder security --- .../Core/Config/CommonConfig.cs | 6 ++++ .../Helpers/SecurityControlHelper.cs | 36 +++++++++++++++++++ .../ViewModel/MainWindowViewModel.cs | 20 ++++++++++- 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 BetterGenshinImpact/Helpers/SecurityControlHelper.cs diff --git a/BetterGenshinImpact/Core/Config/CommonConfig.cs b/BetterGenshinImpact/Core/Config/CommonConfig.cs index 6da8e1f9..e1f35470 100644 --- a/BetterGenshinImpact/Core/Config/CommonConfig.cs +++ b/BetterGenshinImpact/Core/Config/CommonConfig.cs @@ -39,4 +39,10 @@ public partial class CommonConfig : ObservableObject /// [ObservableProperty] private bool _isFirstRun = true; + + /// + /// 这个版本是否运行过 + /// + [ObservableProperty] + private string _runForVersion = string.Empty; } diff --git a/BetterGenshinImpact/Helpers/SecurityControlHelper.cs b/BetterGenshinImpact/Helpers/SecurityControlHelper.cs new file mode 100644 index 00000000..b7a84a59 --- /dev/null +++ b/BetterGenshinImpact/Helpers/SecurityControlHelper.cs @@ -0,0 +1,36 @@ +using System; +using System.IO; +using System.Security.AccessControl; +using BetterGenshinImpact.GameTask.Common; +using Microsoft.Extensions.Logging; + +namespace BetterGenshinImpact.Helpers; + +public static class SecurityControlHelper +{ + + public static void AllowFullFolderSecurity(string dirPath) + { + if (!RuntimeHelper.IsElevated) + { + return; + } + + try + { + DirectoryInfo dir = new(dirPath); + DirectorySecurity dirSecurity = dir.GetAccessControl(AccessControlSections.All); + InheritanceFlags inherits = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; + FileSystemAccessRule everyoneFileSystemAccessRule = new("Everyone", FileSystemRights.FullControl, inherits, PropagationFlags.None, AccessControlType.Allow); + FileSystemAccessRule usersFileSystemAccessRule = new("Users", FileSystemRights.FullControl, inherits, PropagationFlags.None, AccessControlType.Allow); + dirSecurity.ModifyAccessRule(AccessControlModification.Add, everyoneFileSystemAccessRule, out _); + dirSecurity.ModifyAccessRule(AccessControlModification.Add, usersFileSystemAccessRule, out _); + dir.SetAccessControl(dirSecurity); + } + catch (Exception e) + { + TaskControl.Logger.LogError("首次运行自动初始化按键绑定异常:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message); + MessageBox.Show("检测到当前 BetterGI 位于C盘,尝试修改目录权限失败,可能会导致WebView2相关的功能无法使用!" + e.Message); + } + } +} diff --git a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs index 198e4143..0bfab5ec 100644 --- a/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs +++ b/BetterGenshinImpact/ViewModel/MainWindowViewModel.cs @@ -41,7 +41,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel [ObservableProperty] private WindowBackdropType _currentBackdropType = WindowBackdropType.Auto; - + [ObservableProperty] private bool _isWin11Later = OsVersionHelper.IsWindows11_OrGreater; @@ -113,6 +113,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel // 自动处理目录配置 await Patch1(); + // 首次运行 if (Config.CommonConfig.IsFirstRun) @@ -121,6 +122,13 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel // InitKeyBinding(); Config.AutoFightConfig.TeamNames = ""; // 此配置以后无用 Config.CommonConfig.IsFirstRun = false; + + } + // 版本是否运行过 + if (Config.CommonConfig.RunForVersion != Global.Version) + { + ModifyFolderSecurity(); + Config.CommonConfig.RunForVersion = Global.Version; } // 检查更新 @@ -137,6 +145,16 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel } + private void ModifyFolderSecurity() + { + // 检查程序是否位于C盘 + if (Global.StartUpPath.StartsWith(@"C:", StringComparison.OrdinalIgnoreCase)) + { + // 修改文件夹权限 + SecurityControlHelper.AllowFullFolderSecurity(Global.StartUpPath); + } + } + /* private void InitKeyBinding() { From 0fe4e86bc00d2a17b1cf50a4e1fa722f1be765d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sat, 1 Feb 2025 16:01:07 +0800 Subject: [PATCH 66/81] more genshin settings check --- .../Genshin/Settings2/GameSettingsChecker.cs | 62 +++ .../Settings2/GenshinGameInputSettings.cs | 122 ++++++ .../Genshin/Settings2/GenshinGameSettings.cs | 360 ++++++++++++++++++ BetterGenshinImpact/View/MaskWindow.xaml.cs | 3 +- 4 files changed, 546 insertions(+), 1 deletion(-) create mode 100644 BetterGenshinImpact/Genshin/Settings2/GameSettingsChecker.cs create mode 100644 BetterGenshinImpact/Genshin/Settings2/GenshinGameInputSettings.cs create mode 100644 BetterGenshinImpact/Genshin/Settings2/GenshinGameSettings.cs diff --git a/BetterGenshinImpact/Genshin/Settings2/GameSettingsChecker.cs b/BetterGenshinImpact/Genshin/Settings2/GameSettingsChecker.cs new file mode 100644 index 00000000..9faf8098 --- /dev/null +++ b/BetterGenshinImpact/Genshin/Settings2/GameSettingsChecker.cs @@ -0,0 +1,62 @@ +using System; +using BetterGenshinImpact.GameTask.Common; +using BetterGenshinImpact.Genshin.Settings; +using Microsoft.Extensions.Logging; + +namespace BetterGenshinImpact.Genshin.Settings2; + +public class GameSettingsChecker +{ + public static void LoadGameSettingsAndCheck() + { + try + { + var settingStr = GenshinGameSettings.GetStrFromRegistry(); + if (settingStr == null) + { + TaskControl.Logger.LogDebug("获取原神游戏设置失败"); + return; + } + + GenshinGameSettings? settings = GenshinGameSettings.Parse(settingStr); + if (settings == null) + { + TaskControl.Logger.LogDebug("获取原神游戏设置失败"); + return; + } + + GenshinGameInputSettings? inputSettings = GenshinGameInputSettings.Parse(settings.InputData); + if (inputSettings == null) + { + TaskControl.Logger.LogError("获取原神游戏输入设置失败"); + return; + } + + if (settings.GammaValue != "2.200000047683716") + { + TaskControl.Logger.LogError("检测到游戏亮度非默认值,将会影响功能正常使用,请在原神 游戏设置——图像——亮度 中恢复默认亮度!"); + } + + if (inputSettings.MouseSenseIndex != 2 + || inputSettings.MouseSenseIndexY != 2 + || inputSettings.MouseFocusSenseIndex != 2 + || inputSettings.MouseFocusSenseIndexY != 2) + { + TaskControl.Logger.LogInformation("当前:镜头水平灵敏度{X1},镜头垂直灵敏度{Y1},镜头水平灵敏度(瞄准模式){X2},镜头垂直灵敏度(瞄准模式){Y2}", + inputSettings.MouseSenseIndex + 1, inputSettings.MouseSenseIndexY + 1, + inputSettings.MouseFocusSenseIndex + 1, inputSettings.MouseFocusSenseIndexY + 1); + TaskControl.Logger.LogError("检测到镜头灵敏度不是默认值3,将会影响所有视角移动功能的正常使用,请在原神 游戏设置——控制 中恢复默认灵敏度!"); + } + + var lang = (TextLanguage)settings.DeviceLanguageType; + if (lang != TextLanguage.SimplifiedChinese) + { + TaskControl.Logger.LogWarning("当前游戏语言{Lang}不是简体中文,部分功能可能无法正常使用。The game language is not Simplified Chinese, some functions may not work properly", lang); + } + } + catch (Exception e) + { + TaskControl.Logger.LogDebug(e, "获取原神游戏设置失败"); + } + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Genshin/Settings2/GenshinGameInputSettings.cs b/BetterGenshinImpact/Genshin/Settings2/GenshinGameInputSettings.cs new file mode 100644 index 00000000..86ed4e11 --- /dev/null +++ b/BetterGenshinImpact/Genshin/Settings2/GenshinGameInputSettings.cs @@ -0,0 +1,122 @@ +using Newtonsoft.Json; + +namespace BetterGenshinImpact.Genshin.Settings2; + +public class GenshinGameInputSettings +{ + [JsonProperty("scriptVersion")] + public string ScriptVersion { get; set; } // 脚本版本 + + [JsonProperty("mouseSensitivity")] + public string MouseSensitivity { get; set; } // 鼠标灵敏度 + + [JsonProperty("joypadSenseIndex")] + public int JoypadSenseIndex { get; set; } // 手柄灵敏度索引 + + [JsonProperty("joypadFocusSenseIndex")] + public int JoypadFocusSenseIndex { get; set; } // 手柄焦点灵敏度索引 + + [JsonProperty("joypadInvertCameraX")] + public bool JoypadInvertCameraX { get; set; } // 手柄X轴反转摄像头 + + [JsonProperty("joypadInvertCameraY")] + public bool JoypadInvertCameraY { get; set; } // 手柄Y轴反转摄像头 + + [JsonProperty("joypadInvertFocusCameraX")] + public bool JoypadInvertFocusCameraX { get; set; } // 手柄X轴反转焦点摄像头 + + [JsonProperty("joypadInvertFocusCameraY")] + public bool JoypadInvertFocusCameraY { get; set; } // 手柄Y轴反转焦点摄像头 + + [JsonProperty("mouseSenseIndex")] + public int MouseSenseIndex { get; set; } // 鼠标灵敏度索引 + + [JsonProperty("mouseFocusSenseIndex")] + public int MouseFocusSenseIndex { get; set; } // 鼠标焦点灵敏度索引 + + [JsonProperty("touchpadSenseIndex")] + public int TouchpadSenseIndex { get; set; } // 触摸板灵敏度索引 + + [JsonProperty("touchpadFocusSenseIndex")] + public int TouchpadFocusSenseIndex { get; set; } // 触摸板焦点灵敏度索引 + + [JsonProperty("enableTouchpadFocusAcceleration")] + public bool EnableTouchpadFocusAcceleration { get; set; } // 启用触摸板焦点加速度 + + [JsonProperty("lastJoypadDefaultScale")] + public float LastJoypadDefaultScale { get; set; } // 最后一次手柄默认缩放 + + [JsonProperty("lastJoypadFocusScale")] + public float LastJoypadFocusScale { get; set; } // 最后一次手柄焦点缩放 + + [JsonProperty("lastPCDefaultScale")] + public float LastPCDefaultScale { get; set; } // 最后一次PC默认缩放 + + [JsonProperty("lastPCFocusScale")] + public float LastPCFocusScale { get; set; } // 最后一次PC焦点缩放 + + [JsonProperty("lastTouchDefaultScale")] + public float LastTouchDefaultScale { get; set; } // 最后一次触摸默认缩放 + + [JsonProperty("lastTouchFcousScale")] + public float LastTouchFocusScale { get; set; } // 最后一次触摸焦点缩放 + + [JsonProperty("switchWalkRunByBtn")] + public bool SwitchWalkRunByBtn { get; set; } // 通过按钮切换行走和奔跑 + + [JsonProperty("skiffCameraAutoFix")] + public bool SkiffCameraAutoFix { get; set; } // 小艇摄像头自动修正 + + [JsonProperty("skiffCameraAutoFixInCombat")] + public bool SkiffCameraAutoFixInCombat { get; set; } // 战斗中小艇摄像头自动修正 + + [JsonProperty("cameraDistanceRatio")] + public float CameraDistanceRatio { get; set; } // 摄像头距离比率 + + [JsonProperty("wwiseVibration")] + public bool WwiseVibration { get; set; } // Wwise振动 + + [JsonProperty("isYInited")] + public bool IsYInited { get; set; } // Y轴是否初始化 + + [JsonProperty("joypadSenseIndexY")] + public int JoypadSenseIndexY { get; set; } // 手柄Y轴灵敏度索引 + + [JsonProperty("joypadFocusSenseIndexY")] + public int JoypadFocusSenseIndexY { get; set; } // 手柄Y轴焦点灵敏度索引 + + [JsonProperty("mouseSenseIndexY")] + public int MouseSenseIndexY { get; set; } // 鼠标Y轴灵敏度索引 + + [JsonProperty("mouseFocusSenseIndexY")] + public int MouseFocusSenseIndexY { get; set; } // 鼠标Y轴焦点灵敏度索引 + + [JsonProperty("touchpadSenseIndexY")] + public int TouchpadSenseIndexY { get; set; } // 触摸板Y轴灵敏度索引 + + [JsonProperty("touchpadFocusSenseIndexY")] + public int TouchpadFocusSenseIndexY { get; set; } // 触摸板Y轴焦点灵敏度索引 + + [JsonProperty("lastJoypadDefaultScaleY")] + public float LastJoypadDefaultScaleY { get; set; } // 最后一次手柄Y轴默认缩放 + + [JsonProperty("lastJoypadFocusScaleY")] + public float LastJoypadFocusScaleY { get; set; } // 最后一次手柄Y轴焦点缩放 + + [JsonProperty("lastPCDefaultScaleY")] + public float LastPCDefaultScaleY { get; set; } // 最后一次PC Y轴默认缩放 + + [JsonProperty("lastPCFocusScaleY")] + public float LastPCFocusScaleY { get; set; } // 最后一次PC Y轴焦点缩放 + + [JsonProperty("lastTouchDefaultScaleY")] + public float LastTouchDefaultScaleY { get; set; } // 最后一次触摸Y轴默认缩放 + + [JsonProperty("lastTouchFcousScaleY")] + public float LastTouchFocusScaleY { get; set; } // 最后一次触摸Y轴焦点缩放 + + public static GenshinGameInputSettings? Parse(string json) + { + return JsonConvert.DeserializeObject(json); + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Genshin/Settings2/GenshinGameSettings.cs b/BetterGenshinImpact/Genshin/Settings2/GenshinGameSettings.cs new file mode 100644 index 00000000..e154d362 --- /dev/null +++ b/BetterGenshinImpact/Genshin/Settings2/GenshinGameSettings.cs @@ -0,0 +1,360 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.Json.Serialization; +using BetterGenshinImpact.Genshin.Settings; +using Microsoft.Win32; +using Newtonsoft.Json; +using JsonSerializerOptions = System.Text.Json.JsonSerializerOptions; + +namespace BetterGenshinImpact.Genshin.Settings2; + +public class GenshinGameSettings +{ + [JsonProperty("deviceUUID")] + public string DeviceUUID { get; set; } // 设备唯一标识符 + + [JsonProperty("userLocalDataVersionId")] + public string UserLocalDataVersionId { get; set; } // 用户本地数据版本ID + + [JsonProperty("deviceLanguageType")] + public int DeviceLanguageType { get; set; } // 设备语言类型 + + [JsonProperty("deviceVoiceLanguageType")] + public int DeviceVoiceLanguageType { get; set; } // 设备语音语言类型 + + [JsonProperty("selectedServerName")] + public string SelectedServerName { get; set; } // 选择的服务器名称 + + [JsonProperty("localLevelIndex")] + public int LocalLevelIndex { get; set; } // 本地等级索引 + + [JsonProperty("deviceID")] + public string DeviceID { get; set; } // 设备ID + + [JsonProperty("targetUID")] + public string TargetUID { get; set; } // 目标用户ID + + [JsonProperty("curAccountName")] + public string CurAccountName { get; set; } // 当前账户名称 + + [JsonProperty("uiSaveData")] + public string UiSaveData { get; set; } // UI保存数据 + + [JsonProperty("inputData")] + public string InputData { get; set; } // 输入设置数据 + + [JsonProperty("graphicsData")] + public string GraphicsData { get; set; } // 图形设置数据 + + [JsonProperty("globalPerfData")] + public string GlobalPerfData { get; set; } // 全局性能数据 + + [JsonProperty("miniMapConfig")] + public int MiniMapConfig { get; set; } // 小地图配置 + + [JsonProperty("enableCameraSlope")] + public bool EnableCameraSlope { get; set; } // 启用相机坡度 + + [JsonProperty("enableCameraCombatLock")] + public bool EnableCameraCombatLock { get; set; } // 启用相机战斗锁定 + + [JsonProperty("completionPkg")] + public bool CompletionPkg { get; set; } // 完成的包 + + [JsonProperty("completionPlayGoPkg")] + public bool CompletionPlayGoPkg { get; set; } // 完成的PlayGo包 + + [JsonProperty("onlyPlayWithPSPlayer")] + public bool OnlyPlayWithPSPlayer { get; set; } // 仅与PS玩家一起游戏 + + [JsonProperty("onlyPlayWithXboxPlayer")] + public bool OnlyPlayWithXboxPlayer { get; set; } // 仅与Xbox玩家一起游戏 + + [JsonProperty("needPlayGoFullPkgPatch")] + public bool NeedPlayGoFullPkgPatch { get; set; } // 需要PlayGo完整包补丁 + + [JsonProperty("resinNotification")] + public bool ResinNotification { get; set; } // 树脂通知 + + [JsonProperty("exploreNotification")] + public bool ExploreNotification { get; set; } // 探索通知 + + [JsonProperty("volumeGlobal")] + public int VolumeGlobal { get; set; } // 全局音量 + + [JsonProperty("volumeSFX")] + public int VolumeSFX { get; set; } // 音效音量 + + [JsonProperty("volumeMusic")] + public int VolumeMusic { get; set; } // 音乐音量 + + [JsonProperty("volumeVoice")] + public int VolumeVoice { get; set; } // 语音音量 + + [JsonProperty("audioAPI")] + public int AudioAPI { get; set; } // 音频API + + [JsonProperty("audioDynamicRange")] + public int AudioDynamicRange { get; set; } // 音频动态范围 + + [JsonProperty("audioOutput")] + public int AudioOutput { get; set; } // 音频输出 + + [JsonProperty("_audioSuccessInit")] + public bool AudioSuccessInit { get; set; } // 音频成功初始化 + + [JsonProperty("enableAudioChangeAndroidMinimumBufferCapacity")] + public bool EnableAudioChangeAndroidMinimumBufferCapacity { get; set; } // 启用更改Android最小缓冲容量的音频 + + [JsonProperty("audioAndroidMiniumBufferCapacity")] + public int AudioAndroidMiniumBufferCapacity { get; set; } // Android音频最小缓冲容量 + + [JsonProperty("vibrationLevel")] + public int VibrationLevel { get; set; } // 震动等级 + + [JsonProperty("vibrationIntensity")] + public int VibrationIntensity { get; set; } // 震动强度 + + [JsonProperty("usingNewVibrationSetting")] + public bool UsingNewVibrationSetting { get; set; } // 使用新的震动设置 + + [JsonProperty("motionBlur")] + public bool MotionBlur { get; set; } // 动态模糊 + + [JsonProperty("gyroAiming")] + public bool GyroAiming { get; set; } // 陀螺仪瞄准 + + [JsonProperty("gyroHorMoveSpeedIndex")] + public int GyroHorMoveSpeedIndex { get; set; } // 陀螺仪水平移动速度索引 + + [JsonProperty("gyroVerMoveSpeedIndex")] + public int GyroVerMoveSpeedIndex { get; set; } // 陀螺仪垂直移动速度索引 + + [JsonProperty("gyroHorReverse")] + public bool GyroHorReverse { get; set; } // 陀螺仪水平反转 + + [JsonProperty("gyroVerReverse")] + public bool GyroVerReverse { get; set; } // 陀螺仪垂直反转 + + [JsonProperty("gyroRotateType")] + public int GyroRotateType { get; set; } // 陀螺仪旋转类型 + + [JsonProperty("gyroExcludeRightStickVerInput")] + public bool GyroExcludeRightStickVerInput { get; set; } // 陀螺仪排除右摇杆垂直输入 + + [JsonProperty("firstHDRSetting")] + public bool FirstHDRSetting { get; set; } // 首次HDR设置 + + [JsonProperty("maxLuminosity")] + public float MaxLuminosity { get; set; } // 最大亮度 + + [JsonProperty("uiPaperWhite")] + public float UiPaperWhite { get; set; } // UI纸白 + + [JsonProperty("scenePaperWhite")] + public float ScenePaperWhite { get; set; } // 场景纸白 + + /// + /// 2.200000047683716 + /// + [JsonProperty("gammaValue")] + public string GammaValue { get; set; } // 伽马值 + + [JsonProperty("enableHDR")] + public bool EnableHDR { get; set; } // 启用HDR + + [JsonProperty("_overrideControllerMapKeyList")] + public List OverrideControllerMapKeyList { get; set; } // 覆盖控制器映射键列表 + + [JsonProperty("_overrideControllerMapValueList")] + public List OverrideControllerMapValueList { get; set; } // 覆盖控制器映射值列表 + + [JsonProperty("rewiredMapMigrateRecord")] + public List RewiredMapMigrateRecord { get; set; } // 重布线映射迁移记录 + + [JsonProperty("rewiredDisableKeyboard")] + public bool RewiredDisableKeyboard { get; set; } // 重布线禁用键盘 + + [JsonProperty("rewiredEnableKeyboard")] + public bool RewiredEnableKeyboard { get; set; } // 重布线启用键盘 + + [JsonProperty("rewiredEnableEDS")] + public bool RewiredEnableEDS { get; set; } // 重布线启用EDS + + [JsonProperty("disableRewiredDelayInit")] + public bool DisableRewiredDelayInit { get; set; } // 禁用重布线延迟初始化 + + [JsonProperty("disableRewiredInitProtection")] + public bool DisableRewiredInitProtection { get; set; } // 禁用重布线初始化保护 + + [JsonProperty("disableSetJoyInfoForWebViewOnPCMobile")] + public bool DisableSetJoyInfoForWebViewOnPCMobile { get; set; } // 禁用在PC和移动设备上的WebView设置Joy信息 + + [JsonProperty("conflictKeyBindingElementId")] + public List ConflictKeyBindingElementId { get; set; } // 冲突的按键绑定元素ID + + [JsonProperty("conflictKeyBindingActionId")] + public List ConflictKeyBindingActionId { get; set; } // 冲突的按键绑定动作ID + + [JsonProperty("lastSeenPreDownloadTime")] + public long LastSeenPreDownloadTime { get; set; } // 上次看到的预下载时间 + + [JsonProperty("lastSeenSettingResourceTabScriptVersion")] + public string LastSeenSettingResourceTabScriptVersion { get; set; } // 上次看到的设置资源标签脚本版本 + + [JsonProperty("enableEffectAssembleInEditor")] + public bool EnableEffectAssembleInEditor { get; set; } // 启用在编辑器中组装效果 + + [JsonProperty("forceDisableQuestResourceManagement")] + public bool ForceDisableQuestResourceManagement { get; set; } // 强制禁用任务资源管理 + + [JsonProperty("needReportQuestResourceDeleteStatusFiles")] + public bool NeedReportQuestResourceDeleteStatusFiles { get; set; } // 需要报告任务资源删除状态文件 + + [JsonProperty("disableTeamPageBackgroundSwitch")] + public bool DisableTeamPageBackgroundSwitch { get; set; } // 禁用团队页面背景切换 + + [JsonProperty("disableHttpDns")] + public bool DisableHttpDns { get; set; } // 禁用HTTP DNS + + [JsonProperty("mtrCached")] + public bool MtrCached { get; set; } // MTR缓存 + + [JsonProperty("mtrIsOpen")] + public bool MtrIsOpen { get; set; } // MTR是否开启 + + [JsonProperty("mtrMaxTTL")] + public int MtrMaxTTL { get; set; } // MTR最大TTL + + [JsonProperty("mtrTimeOut")] + public int MtrTimeOut { get; set; } // MTR超时时间 + + [JsonProperty("mtrTraceCount")] + public int MtrTraceCount { get; set; } // MTR跟踪次数 + + [JsonProperty("mtrAbortTimeOutCount")] + public int MtrAbortTimeOutCount { get; set; } // MTR中止超时计数 + + [JsonProperty("mtrAutoTraceInterval")] + public int MtrAutoTraceInterval { get; set; } // MTR自动跟踪间隔 + + [JsonProperty("mtrTraceCDEachReason")] + public int MtrTraceCDEachReason { get; set; } // MTR每个原因的冷却时间 + + [JsonProperty("mtrTimeInterval")] + public int MtrTimeInterval { get; set; } // MTR时间间隔 + + [JsonProperty("mtrBanReasons")] + public List MtrBanReasons { get; set; } // MTR禁止原因 + + [JsonProperty("_customDataKeyList")] + public List CustomDataKeyList { get; set; } // 自定义数据键列表 + + [JsonProperty("_customDataValueList")] + public List CustomDataValueList { get; set; } // 自定义数据值列表 + + [JsonProperty("_serializedCodeSwitches")] + public List SerializedCodeSwitches { get; set; } // 序列化代码开关 + + [JsonProperty("urlCheckCached")] + public bool UrlCheckCached { get; set; } // URL检查缓存 + + [JsonProperty("urlCheckIsOpen")] + public bool UrlCheckIsOpen { get; set; } // URL检查是否开启 + + [JsonProperty("urlCheckAllIP")] + public bool UrlCheckAllIP { get; set; } // URL检查所有IP + + [JsonProperty("urlCheckTimeOut")] + public int UrlCheckTimeOut { get; set; } // URL检查超时时间 + + [JsonProperty("urlCheckSueecssTraceCount")] + public int UrlCheckSuccessTraceCount { get; set; } // URL检查成功跟踪计数 + + [JsonProperty("urlCheckErrorTraceCount")] + public int UrlCheckErrorTraceCount { get; set; } // URL检查错误跟踪计数 + + [JsonProperty("urlCheckAbortTimeOutCount")] + public int UrlCheckAbortTimeOutCount { get; set; } // URL检查中止超时计数 + + [JsonProperty("urlCheckTimeInterval")] + public int UrlCheckTimeInterval { get; set; } // URL检查时间间隔 + + [JsonProperty("urlCheckCDEachReason")] + public int UrlCheckCDEachReason { get; set; } // URL检查每个原因的冷却时间 + + [JsonProperty("urlCheckBanReasons")] + public List UrlCheckBanReasons { get; set; } // URL检查禁止原因 + + [JsonProperty("mtrUseOldWinVersion")] + public bool MtrUseOldWinVersion { get; set; } // 使用旧版Windows的MTR + + [JsonProperty("greyTestDeviceUniqueId")] + public string GreyTestDeviceUniqueId { get; set; } // 灰度测试设备唯一ID + + [JsonProperty("muteAudioOnAppMinimized")] + public bool MuteAudioOnAppMinimized { get; set; } // 应用最小化时静音 + + [JsonProperty("disableFallbackControllerType")] + public bool DisableFallbackControllerType { get; set; } // 禁用回退控制器类型 + + [JsonProperty("lastShowDoorProgress")] + public float LastShowDoorProgress { get; set; } // 上次显示门进度 + + [JsonProperty("globalPerfSettingVersion")] + public int GlobalPerfSettingVersion { get; set; } // 全局性能设置版本 + + + public static string? GetStrFromRegistry() + { + if (GenshinRegistry.GetRegistryKey() is not { } hk) + { + return null; + } + + using (hk) + { + string value_name = SearchRegistryName(hk); + if (hk.GetValue(value_name) is not byte[] rawBytes) + { + return null; + } + + var str = Encoding.UTF8.GetString(rawBytes); + // Debug.WriteLine(str); + + return str; + } + } + + public static GenshinGameSettings? Parse(string json) + { + return JsonConvert.DeserializeObject(json); + } + + + private static string SearchRegistryName(RegistryKey key) + { + string value_name = string.Empty; + string[] names = key.GetValueNames(); + + foreach (string name in names) + { + if (name.Contains("GENERAL_DATA")) + { + value_name = name; + break; + } + } + + if (value_name == string.Empty) + { + throw new ArgumentException(value_name); + } + + return value_name; + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/View/MaskWindow.xaml.cs b/BetterGenshinImpact/View/MaskWindow.xaml.cs index e057451a..e0d8b6a3 100644 --- a/BetterGenshinImpact/View/MaskWindow.xaml.cs +++ b/BetterGenshinImpact/View/MaskWindow.xaml.cs @@ -19,6 +19,7 @@ using System.Windows.Documents; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Threading; +using BetterGenshinImpact.Genshin.Settings2; using Vanara.PInvoke; using FontFamily = System.Windows.Media.FontFamily; @@ -178,7 +179,7 @@ public partial class MaskWindow : Window AfterburnerWarning(); // 读取游戏注册表配置 - // ReadGameSettings(); + GameSettingsChecker.LoadGameSettingsAndCheck(); } /** From 1eee073adb11de89662674e00bc8409a9b208200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sat, 1 Feb 2025 18:11:51 +0800 Subject: [PATCH 67/81] =?UTF-8?q?1.=20=E4=BF=AE=E6=AD=A3=20Orientation=20?= =?UTF-8?q?=E5=A4=A7=E5=86=99=E7=9A=84=E9=97=AE=E9=A2=98=202.=20=E7=BE=8E?= =?UTF-8?q?=E5=8C=96=E4=BA=86=E6=98=AF=E5=90=A6=E4=BD=9C=E4=B8=BA=20target?= =?UTF-8?q?=20=E7=82=B9=E4=BD=8D=E6=8E=A5=E8=BF=91=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AutoPathing/Model/Enum/ActionEnum.cs | 63 +++++++++++++------ .../AutoPathing/Model/Enum/WaypointType.cs | 2 +- .../GameTask/AutoPathing/PathExecutor.cs | 44 +++++++------ 3 files changed, 71 insertions(+), 38 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/ActionEnum.cs b/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/ActionEnum.cs index 26523d6c..1442720b 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/ActionEnum.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/ActionEnum.cs @@ -2,23 +2,23 @@ namespace BetterGenshinImpact.GameTask.AutoPathing.Model.Enum; -public class ActionEnum(string code, string msg) +public class ActionEnum(string code, string msg, ActionUseWaypointTypeEnum useWaypointTypeEnum) { - public static readonly ActionEnum StopFlying = new("stop_flying", "下落攻击"); - public static readonly ActionEnum ForceTp = new("force_tp", "当前点传送"); - public static readonly ActionEnum NahidaCollect = new("nahida_collect", "纳西妲长按E收集"); - public static readonly ActionEnum PickAround = new("pick_around", "尝试在周围拾取"); - public static readonly ActionEnum Fight = new("fight", "战斗"); - public static readonly ActionEnum UpDownGrabLeaf = new("up_down_grab_leaf", "四叶印"); + public static readonly ActionEnum StopFlying = new("stop_flying", "下落攻击", ActionUseWaypointTypeEnum.Custom); + public static readonly ActionEnum ForceTp = new("force_tp", "当前点传送", ActionUseWaypointTypeEnum.Custom); + public static readonly ActionEnum NahidaCollect = new("nahida_collect", "纳西妲长按E收集", ActionUseWaypointTypeEnum.Custom); + public static readonly ActionEnum PickAround = new("pick_around", "尝试在周围拾取", ActionUseWaypointTypeEnum.Custom); + public static readonly ActionEnum Fight = new("fight", "战斗", ActionUseWaypointTypeEnum.Path); + public static readonly ActionEnum UpDownGrabLeaf = new("up_down_grab_leaf", "四叶印", ActionUseWaypointTypeEnum.Custom); - public static readonly ActionEnum HydroCollect = new("hydro_collect", "水元素力采集"); - public static readonly ActionEnum ElectroCollect = new("electro_collect", "雷元素力采集"); - public static readonly ActionEnum AnemoCollect = new("anemo_collect", "风元素力采集"); - - public static readonly ActionEnum CombatScript = new("combat_script", "战斗策略脚本"); // 这个必须要 action_params 里面有脚本 - - public static readonly ActionEnum Mining = new("mining", "挖矿"); - public static readonly ActionEnum LogOutput = new("log_output", "输出日志"); + public static readonly ActionEnum HydroCollect = new("hydro_collect", "水元素力采集", ActionUseWaypointTypeEnum.Target); + public static readonly ActionEnum ElectroCollect = new("electro_collect", "雷元素力采集", ActionUseWaypointTypeEnum.Target); + public static readonly ActionEnum AnemoCollect = new("anemo_collect", "风元素力采集", ActionUseWaypointTypeEnum.Target); + + public static readonly ActionEnum CombatScript = new("combat_script", "战斗策略脚本", ActionUseWaypointTypeEnum.Custom); // 这个必须要 action_params 里面有脚本 + + public static readonly ActionEnum Mining = new("mining", "挖矿", ActionUseWaypointTypeEnum.Custom); + public static readonly ActionEnum LogOutput = new("log_output", "输出日志", ActionUseWaypointTypeEnum.Custom); // 还有要加入的其他动作 // 滚轮F @@ -29,15 +29,32 @@ public class ActionEnum(string code, string msg) public static IEnumerable Values { - get - { - yield return StopFlying; - } + get { yield return StopFlying; } } public string Code { get; private set; } = code; public string Msg { get; private set; } = msg; + public ActionUseWaypointTypeEnum UseWaypointTypeEnum { get; private set; } = useWaypointTypeEnum; + + public static ActionEnum? GetEnumByCode(string? code) + { + if (string.IsNullOrEmpty(code)) + { + return null; + } + + foreach (var item in Values) + { + if (item.Code == code) + { + return item; + } + } + + return null; + } + public static string GetMsgByCode(string code) { foreach (var item in Values) @@ -47,6 +64,14 @@ public class ActionEnum(string code, string msg) return item.Msg; } } + return code; } } + +public enum ActionUseWaypointTypeEnum +{ + Custom, // 跟随路径点 Type + Path, // 强制 Path + Target // 强制 Target +} \ No newline at end of file diff --git a/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/WaypointType.cs b/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/WaypointType.cs index 8abde910..c7ff4929 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/WaypointType.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/Model/Enum/WaypointType.cs @@ -7,7 +7,7 @@ public class WaypointType(string code, string msg) public static readonly WaypointType Path = new("path", "途径点"); public static readonly WaypointType Target = new("target", "目标点"); public static readonly WaypointType Teleport = new("teleport", "传送点"); - public static readonly WaypointType Orientation = new("Orientation", "方位点"); + public static readonly WaypointType Orientation = new("orientation", "方位点"); public static IEnumerable Values { diff --git a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs index 18e3c6f2..e979a952 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs @@ -178,32 +178,21 @@ public class PathExecutor { await BeforeMoveToTarget(waypoint); + // Path不用走得很近,Target需要接近,但都需要先移动到对应位置 if (waypoint.Type == WaypointType.Orientation.Code) + { // 方位点,只需要朝向 + // 考虑到方位点大概率是作为执行action的最后一个点,所以放在此处处理,不和传送点一样单独处理 await FaceTo(waypoint); + } else - // Path不用走得很近,Target需要接近,但都需要先移动到对应位置 + { await MoveTo(waypoint); + } await BeforeMoveCloseToTarget(waypoint); - if ( - waypoint.Type != WaypointType.Orientation.Code // 方位点不需要接近 - && waypoint.Action != ActionEnum.Fight.Code // 战斗action强制不接近 - && ( - waypoint.Type == WaypointType.Target.Code - || ( - !string.IsNullOrEmpty(waypoint.Action) - && waypoint.Action != ActionEnum.StopFlying.Code - && waypoint.Action != ActionEnum.NahidaCollect.Code - && waypoint.Action != ActionEnum.CombatScript.Code - && waypoint.Action != ActionEnum.Mining.Code - // 除了上述之外的actions都强制接近,即时类型是Path(真的需要这样吗?) - // force_tp, up_down_grab_leaf, log_output, 这几个不需要接近; - // pick_around, hydro_collect, electro_collect, anemo_collect, 这几个现存脚本中没有用target? - ) - ) - ) + if (IsTargetPoint(waypoint)) { await MoveCloseTo(waypoint); } @@ -264,6 +253,25 @@ public class PathExecutor } } + private bool IsTargetPoint(WaypointForTrack waypoint) + { + // 方位点不需要接近 + if (waypoint.Type == WaypointType.Orientation.Code) + { + return false; + } + + var action = ActionEnum.GetEnumByCode(waypoint.Action); + if (action is not null && action.UseWaypointTypeEnum != ActionUseWaypointTypeEnum.Custom) + { + // 强制点位类型的 action,以 action 为准 + return action.UseWaypointTypeEnum == ActionUseWaypointTypeEnum.Target; + } + + // 其余情况和没有action的情况以点位类型为准 + return waypoint.Type == WaypointType.Target.Code; + } + private async Task SwitchPartyBefore(PathingTask task) { var ra = CaptureToRectArea(); From 297618b95f03a3984679c9d5fd6f2cc67e1f9ad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Sat, 1 Feb 2025 23:03:25 +0800 Subject: [PATCH 68/81] fix windows notify --- BetterGenshinImpact/Helpers/TempManager.cs | 9 ++++--- .../Model/NotificationTestResult.cs | 2 +- .../Notification/NotificationService.cs | 27 ++++++++++--------- .../Service/Notifier/WindowsUwpNotifier.cs | 5 ++-- .../ViewModel/Pages/HomePageViewModel.cs | 1 + 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/BetterGenshinImpact/Helpers/TempManager.cs b/BetterGenshinImpact/Helpers/TempManager.cs index 25ae16f2..5dda1144 100644 --- a/BetterGenshinImpact/Helpers/TempManager.cs +++ b/BetterGenshinImpact/Helpers/TempManager.cs @@ -6,17 +6,18 @@ namespace BetterGenshinImpact.Helpers; public class TempManager { - public static readonly string TempDirectory = Global.Absolute("User/Temp"); - static TempManager() + public static string GetTempDirectory() { - Directory.CreateDirectory(TempDirectory); + var tmp = Global.Absolute("User/Temp"); + Directory.CreateDirectory(tmp); + return tmp; } public static void CleanUp() { try { - DirectoryHelper.DeleteDirectoryRecursively(TempDirectory); + DirectoryHelper.DeleteDirectoryRecursively(GetTempDirectory()); } catch { diff --git a/BetterGenshinImpact/Service/Notification/Model/NotificationTestResult.cs b/BetterGenshinImpact/Service/Notification/Model/NotificationTestResult.cs index 2e909a29..6b5a05ec 100644 --- a/BetterGenshinImpact/Service/Notification/Model/NotificationTestResult.cs +++ b/BetterGenshinImpact/Service/Notification/Model/NotificationTestResult.cs @@ -7,7 +7,7 @@ public class NotificationTestResult public static NotificationTestResult Success() { - return new NotificationTestResult { IsSuccess = true, Message = "成功" }; + return new NotificationTestResult { IsSuccess = true, Message = "通知成功" }; } public static NotificationTestResult Error(string message) diff --git a/BetterGenshinImpact/Service/Notification/NotificationService.cs b/BetterGenshinImpact/Service/Notification/NotificationService.cs index 98942c0f..15c10cbb 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationService.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationService.cs @@ -1,19 +1,14 @@ -using BetterGenshinImpact.Core.Config; -using BetterGenshinImpact.Service.Interface; -using BetterGenshinImpact.Service.Notification.Model; +using BetterGenshinImpact.Service.Notification.Model; using BetterGenshinImpact.Service.Notifier; using BetterGenshinImpact.Service.Notifier.Exception; using BetterGenshinImpact.Service.Notifier.Interface; using Microsoft.Extensions.Hosting; using System; -using System.Drawing; using System.Net.Http; -using System.Text; -using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using System.Windows.Media.Imaging; using BetterGenshinImpact.GameTask; +using BetterGenshinImpact.GameTask.Common; using BetterGenshinImpact.Service.Notification.Model.Enum; namespace BetterGenshinImpact.Service.Notification; @@ -38,6 +33,7 @@ public class NotificationService : IHostedService { throw new Exception("Not instantiated"); } + return _instance; } @@ -58,6 +54,7 @@ public class NotificationService : IHostedService { _notifierManager.RegisterNotifier(new WebhookNotifier(NotifyHttpClient, TaskContext.Instance().Config.NotificationConfig.WebhookEndpoint)); } + if (TaskContext.Instance().Config.NotificationConfig.WindowsUwpNotificationEnabled) { _notifierManager.RegisterNotifier(new WindowsUwpNotifier()); @@ -79,14 +76,20 @@ public class NotificationService : IHostedService { return NotificationTestResult.Error("通知类型未启用"); } - await notifier.SendAsync(new TestNotificationData + + var testData = new TestNotificationData { Event = NotificationEvent.Test, Action = NotificationAction.Started, Conclusion = NotificationConclusion.Success, - Message = "测试通知", - // Screenshot = - }); + Message = "这是一条测试通知信息", + }; + if (TaskContext.Instance().IsInitialized) + { + testData.Screenshot = TaskControl.CaptureToRectArea().SrcBitmap; + } + + await notifier.SendAsync(testData); return NotificationTestResult.Success(); } catch (NotifierException ex) @@ -104,4 +107,4 @@ public class NotificationService : IHostedService { Task.Run(() => NotifyAllNotifiersAsync(notificationData)); } -} +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs b/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs index e151e714..dadfe832 100644 --- a/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs @@ -14,13 +14,12 @@ public class WindowsUwpNotifier : INotifier public Task SendAsync(INotificationData data) { - var toastBuilder = new ToastContentBuilder() - .AddHeader("BetterGI", "BetterGI", "action=click"); + var toastBuilder = new ToastContentBuilder(); if (data.Screenshot != null) { string uniqueFileName = $"notification_image_{Guid.NewGuid()}.png"; - string imagePath = Path.Combine(TempManager.TempDirectory, uniqueFileName); + string imagePath = Path.Combine(TempManager.GetTempDirectory(), uniqueFileName); data.Screenshot.Save(imagePath, System.Drawing.Imaging.ImageFormat.Png); toastBuilder.AddHeroImage(new Uri(imagePath)); } diff --git a/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs index 101a5b7d..f27dd987 100644 --- a/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/HomePageViewModel.cs @@ -278,6 +278,7 @@ public partial class HomePageViewModel : ObservableObject, INavigationAware, IVi TaskDispatcherEnabled = false; _mouseKeyMonitor.Unsubscribe(); + TaskContext.Instance().IsInitialized = false; } } } From e44c55eb03eaccd2e10129f7ebb3d572bd405849 Mon Sep 17 00:00:00 2001 From: Scighost Date: Sun, 2 Feb 2025 22:46:43 +0800 Subject: [PATCH 69/81] Fix the issue of WebView2 UserDataFolder cannot be created --- .../View/Controls/Webview/WebpagePanel.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/BetterGenshinImpact/View/Controls/Webview/WebpagePanel.cs b/BetterGenshinImpact/View/Controls/Webview/WebpagePanel.cs index ef645539..0c62195c 100644 --- a/BetterGenshinImpact/View/Controls/Webview/WebpagePanel.cs +++ b/BetterGenshinImpact/View/Controls/Webview/WebpagePanel.cs @@ -4,6 +4,7 @@ using Microsoft.Web.WebView2.Wpf; using System; using System.Diagnostics; using System.IO; +using System.Security.AccessControl; using System.Text; using System.Threading; using System.Windows; @@ -31,6 +32,7 @@ public class WebpagePanel : UserControl } else { + EnsureWebView2DataFolder(); _webView = new WebView2() { CreationProperties = new CoreWebView2CreationProperties @@ -155,4 +157,19 @@ public class WebpagePanel : UserControl return button; } + + private void EnsureWebView2DataFolder() + { + try + { + string folder = Path.Combine(new FileInfo(Environment.ProcessPath!).DirectoryName!, @"WebView2Data\\"); + Directory.CreateDirectory(folder); + DirectoryInfo info = new DirectoryInfo(folder); + DirectorySecurity access = info.GetAccessControl(); + access.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow)); + info.SetAccessControl(access); + } + catch { } + } + } From 1efd8d9454e38af022d71b40def39ca484c3e292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 3 Feb 2025 15:02:25 +0800 Subject: [PATCH 70/81] =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BetterGenshinImpact.csproj | 1 + .../GameTask/AutoDomain/AutoDomainTask.cs | 11 ++- .../AutoGeniusInvokation/Model/Duel.cs | 10 +- BetterGenshinImpact/GameTask/TaskRunner.cs | 25 +---- .../Builder/DomainNotificationBuilder.cs | 15 --- .../GeniusInvocationNotificationBuilder.cs | 15 --- .../Builder/INotificationBuilder.cs | 87 ---------------- .../Builder/ScriptNotificationBuilder.cs | 14 --- .../Builder/TaskNotificationBuilder.cs | 13 --- .../Builder/TestNotificationBuilder.cs | 7 -- .../Converter/BaseDateTimeJsonConverter.cs | 28 ++++++ .../Converter/DateTimeJsonConverter.cs | 7 ++ .../Converter/ImageToBase64Converter.cs | 4 +- .../Notification/Model/Base/TaskDetails.cs | 10 -- .../Model/BaseNotificationData.cs | 90 +++++++++++++++++ .../Model/DomainNotificationData.cs | 2 +- .../Model/Enum/NotificationAction.cs | 24 ++--- .../Model/Enum/NotificationEvent.cs | 14 +-- ...nclusion.cs => NotificationEventResult.cs} | 4 +- .../Model/GeniusInvocationNotificationData.cs | 2 +- .../Notification/Model/INotificationData.cs | 28 ------ .../Model/ScriptNotificationData.cs | 2 +- .../Model/TaskNotificationData.cs | 12 --- .../Model/TestNotificationData.cs | 11 --- .../Notification/NotificationHelper.cs | 98 +++++++++---------- .../Notification/NotificationService.cs | 11 +-- .../Service/Notification/Notify.cs | 23 +++++ .../Service/Notifier/Interface/INotifier.cs | 2 +- .../Service/Notifier/NotifierManager.cs | 6 +- .../Service/Notifier/WebhookNotifier.cs | 4 +- .../Service/Notifier/WindowsUwpNotifier.cs | 2 +- BetterGenshinImpact/Service/ScriptService.cs | 22 ++--- 32 files changed, 256 insertions(+), 348 deletions(-) delete mode 100644 BetterGenshinImpact/Service/Notification/Builder/DomainNotificationBuilder.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Builder/GeniusInvocationNotificationBuilder.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Builder/INotificationBuilder.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Builder/ScriptNotificationBuilder.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Builder/TaskNotificationBuilder.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Builder/TestNotificationBuilder.cs create mode 100644 BetterGenshinImpact/Service/Notification/Converter/BaseDateTimeJsonConverter.cs create mode 100644 BetterGenshinImpact/Service/Notification/Converter/DateTimeJsonConverter.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Model/Base/TaskDetails.cs create mode 100644 BetterGenshinImpact/Service/Notification/Model/BaseNotificationData.cs rename BetterGenshinImpact/Service/Notification/Model/Enum/{NotificationConclusion.cs => NotificationEventResult.cs} (75%) delete mode 100644 BetterGenshinImpact/Service/Notification/Model/INotificationData.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Model/TaskNotificationData.cs delete mode 100644 BetterGenshinImpact/Service/Notification/Model/TestNotificationData.cs create mode 100644 BetterGenshinImpact/Service/Notification/Notify.cs diff --git a/BetterGenshinImpact/BetterGenshinImpact.csproj b/BetterGenshinImpact/BetterGenshinImpact.csproj index c4f4dbdc..89a4ba79 100644 --- a/BetterGenshinImpact/BetterGenshinImpact.csproj +++ b/BetterGenshinImpact/BetterGenshinImpact.csproj @@ -148,6 +148,7 @@ + diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs index b544158c..c108545c 100644 --- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs +++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs @@ -30,6 +30,7 @@ using BetterGenshinImpact.GameTask.AutoTrackPath; using BetterGenshinImpact.GameTask.Common.BgiVision; using BetterGenshinImpact.GameTask.Common.Element.Assets; using BetterGenshinImpact.GameTask.Common.Job; +using BetterGenshinImpact.Service.Notification.Model.Enum; using Vanara.PInvoke; using static BetterGenshinImpact.GameTask.Common.TaskControl; using static Vanara.PInvoke.Kernel32; @@ -70,8 +71,7 @@ public class AutoDomainTask : ISoloTask _ct = ct; Init(); - // TODO: 使用exception逻辑让started必有对应的completed - NotificationBuilderFactory.CreateWith(_taskParam).Started().Build().Send(); + Notify.Event("domain.start").Success("自动秘境启动"); // 3次复活重试 for (int i = 0; i < 3; i++) @@ -88,6 +88,7 @@ public class AutoDomainTask : ISoloTask { Logger.LogWarning("自动秘境:{Text}", "复活后重试秘境..."); await Delay(2000, ct); + Notify.Event("domain.retry").Error("存在角色死亡,复活后重试秘境..."); continue; } else @@ -103,6 +104,7 @@ public class AutoDomainTask : ISoloTask await Delay(2000, ct); await ArtifactSalvage(); + Notify.Event("domain.end").Success("自动秘境结束"); } private async Task DoDomain() @@ -158,11 +160,10 @@ public class AutoDomainTask : ISoloTask { Logger.LogInformation("体力已经耗尽,结束自动秘境"); } - - NotificationBuilderFactory.CreateWith(_taskParam).Success().Build().Send(); + break; } - NotificationBuilderFactory.CreateWith(_taskParam).InProgress().Build().Send(); + Notify.Event(NotificationEvent.DomainReward).Success("自动秘境奖励领取"); } } diff --git a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs index 813b46be..2ded1634 100644 --- a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs +++ b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs @@ -61,8 +61,7 @@ public class Duel try { AutoGeniusInvokationAssets.DestroyInstance(); - - NotificationBuilderFactory.CreateWith(this).Started().Build().Send(); + GeniusInvokationControl.GetInstance().Init(ct); // 对局准备 选择初始手牌 @@ -288,15 +287,12 @@ public class Duel } catch (TaskCanceledException ex) { - NotificationBuilderFactory.CreateWith(this).Exception(ex.Message).Build().Send(); - NotificationBuilderFactory.CreateWith(this).Failure().Build().Send(); throw; } catch (NormalEndException ex) { _logger.LogInformation("对局结束"); - NotificationBuilderFactory.CreateWith(this).Success().Build().Send(); - throw; + // throw; } catch (System.Exception ex) { @@ -304,8 +300,6 @@ public class Duel { _logger.LogError(ex.StackTrace); } - NotificationBuilderFactory.CreateWith(this).Exception(ex.Message).Build().Send(); - NotificationBuilderFactory.CreateWith(this).Failure().Build().Send(); throw; } } diff --git a/BetterGenshinImpact/GameTask/TaskRunner.cs b/BetterGenshinImpact/GameTask/TaskRunner.cs index 9ef06525..1e27e8dd 100644 --- a/BetterGenshinImpact/GameTask/TaskRunner.cs +++ b/BetterGenshinImpact/GameTask/TaskRunner.cs @@ -7,14 +7,11 @@ using Microsoft.Extensions.Logging; using System; using System.Threading; using System.Threading.Tasks; -using BetterGenshinImpact.GameTask.AutoGeniusInvokation; -using BetterGenshinImpact.GameTask.AutoMusicGame; using BetterGenshinImpact.Helpers; using Wpf.Ui.Violeta.Controls; using static BetterGenshinImpact.GameTask.Common.TaskControl; using BetterGenshinImpact.Service; using BetterGenshinImpact.Service.Notification; -using BetterGenshinImpact.Service.Notification.Model.Base; namespace BetterGenshinImpact.GameTask; @@ -46,33 +43,27 @@ public class TaskRunner public async Task RunCurrentAsync(Func action) { // 加锁 - TaskDetails taskDetails = new(); var hasLock = await TaskSemaphore.WaitAsync(0); if (!hasLock) { _logger.LogError("任务启动失败:当前存在正在运行中的独立任务,请不要重复执行任务!"); return; } - bool isSuccess = false; - NotificationBuilderFactory.CreateWith(taskDetails).Started().Build().Send(); try { _logger.LogInformation("→ {Text}", _name + "任务启动!"); // 初始化 Init(); - - // 发送运行任务通知 - + CancellationContext.Instance.Set(); RunnerContext.Instance.Clear(); await action(); - isSuccess = true; } catch (NormalEndException e) { - NotificationBuilderFactory.CreateWith(taskDetails).Exception("任务中断:" + e.Message).Build().Send(); + Notify.Event("task.cancel").Success("任务手动取消,或正常结束"); _logger.LogInformation("任务中断:{Msg}", e.Message); if (RunnerContext.Instance.IsContinuousRunGroup) { @@ -82,8 +73,8 @@ public class TaskRunner } catch (TaskCanceledException e) { + Notify.Event("task.cancel").Success("任务被手动取消"); _logger.LogInformation("任务中断:{Msg}", "任务被取消"); - NotificationBuilderFactory.CreateWith(taskDetails).Exception("任务被取消").Build().Send(); if (RunnerContext.Instance.IsContinuousRunGroup) { // 连续执行时,抛出异常,终止执行 @@ -92,22 +83,14 @@ public class TaskRunner } catch (Exception e) { + Notify.Event("task.error").Error("任务执行异常", e); _logger.LogError(e.Message); _logger.LogDebug(e.StackTrace); - NotificationBuilderFactory.CreateWith(taskDetails).Exception(e.Message).Build().Send(); } finally { End(); _logger.LogInformation("→ {Text}", _name + "任务结束"); - if (isSuccess) - { - NotificationBuilderFactory.CreateWith(taskDetails).Success().Build().Send(); - } - else - { - NotificationBuilderFactory.CreateWith(taskDetails).Failure().Build().Send(); - } CancellationContext.Instance.Clear(); RunnerContext.Instance.Clear(); diff --git a/BetterGenshinImpact/Service/Notification/Builder/DomainNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/DomainNotificationBuilder.cs deleted file mode 100644 index 2d630342..00000000 --- a/BetterGenshinImpact/Service/Notification/Builder/DomainNotificationBuilder.cs +++ /dev/null @@ -1,15 +0,0 @@ -using BetterGenshinImpact.GameTask.AutoDomain; -using BetterGenshinImpact.Service.Notification.Model; -using BetterGenshinImpact.Service.Notification.Model.Base; - -namespace BetterGenshinImpact.Service.Notification.Builder; - -public class DomainNotificationBuilder : INotificationBuilder -{ - public DomainNotificationBuilder WithDomain(AutoDomainParam domain) - { - _notificationData.Domain = domain; - return this; - } -} - diff --git a/BetterGenshinImpact/Service/Notification/Builder/GeniusInvocationNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/GeniusInvocationNotificationBuilder.cs deleted file mode 100644 index 0dbc94ee..00000000 --- a/BetterGenshinImpact/Service/Notification/Builder/GeniusInvocationNotificationBuilder.cs +++ /dev/null @@ -1,15 +0,0 @@ -using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Model; -using BetterGenshinImpact.Service.Notification.Model; -using BetterGenshinImpact.Service.Notification.Model.Base; - -namespace BetterGenshinImpact.Service.Notification.Builder; - -public class GeniusInvocationNotificationBuilder : INotificationBuilder -{ - public GeniusInvocationNotificationBuilder WithGeniusInvocation(Duel geniusInvocation) - { - _notificationData.GeniusInvocation = geniusInvocation; - return this; - } -} - diff --git a/BetterGenshinImpact/Service/Notification/Builder/INotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/INotificationBuilder.cs deleted file mode 100644 index 79eef09c..00000000 --- a/BetterGenshinImpact/Service/Notification/Builder/INotificationBuilder.cs +++ /dev/null @@ -1,87 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Model; -using BetterGenshinImpact.Service.Notification.Model.Enum; -using System.Drawing; - -namespace BetterGenshinImpact.Service.Notification.Builder; - -public abstract class INotificationBuilder - where TBuilder : INotificationBuilder - where TNotificationData : INotificationData, new() -{ - protected readonly TNotificationData _notificationData = new(); - - protected TBuilder Self => (TBuilder)this; - - public TBuilder WithEvent(NotificationEvent notificationEvent) - { - _notificationData.Event = notificationEvent; - return Self; - } - - public TBuilder WithAction(NotificationAction action) - { - _notificationData.Action = action; - return Self; - } - - public TBuilder WithConclusion(NotificationConclusion? conclusion) - { - _notificationData.Conclusion = conclusion; - return Self; - } - - public TBuilder Started() - { - return WithAction(NotificationAction.Started); - } - - private TBuilder Completed() // 一个completed任务,需要携带conclusion,故不暴露 - { - return WithAction(NotificationAction.Completed); - } - - public TBuilder Success() - { - return Completed() - .WithConclusion(NotificationConclusion.Success); - } - public TBuilder PartialSuccess() - { - return Completed() - .WithConclusion(NotificationConclusion.PartialSuccess); - } - - public TBuilder Failure() - { - return Completed() - .WithConclusion(NotificationConclusion.Failure); - } - - public TBuilder Exception(string message) - { - return WithAction(NotificationAction.Exception) - .WithMessage(message); - } - - public TBuilder InProgress() - { - return WithAction(NotificationAction.InProgress); - } - - public TBuilder WithScreenshot(Image? screenshot) - { - _notificationData.Screenshot = screenshot; - return Self; - } - - public TBuilder WithMessage(string message) - { - _notificationData.Message = message; - return Self; - } - - public TNotificationData Build() - { - return _notificationData; - } -} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Builder/ScriptNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/ScriptNotificationBuilder.cs deleted file mode 100644 index 83d6c506..00000000 --- a/BetterGenshinImpact/Service/Notification/Builder/ScriptNotificationBuilder.cs +++ /dev/null @@ -1,14 +0,0 @@ -using BetterGenshinImpact.Core.Script.Group; -using BetterGenshinImpact.Service.Notification.Model; -using BetterGenshinImpact.Service.Notification.Model.Base; - -namespace BetterGenshinImpact.Service.Notification.Builder; - -public class ScriptNotificationBuilder : INotificationBuilder -{ - public ScriptNotificationBuilder WithScript(ScriptGroupProject script) - { - _notificationData.Script = script; - return this; - } -} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Builder/TaskNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/TaskNotificationBuilder.cs deleted file mode 100644 index 3cea8d4c..00000000 --- a/BetterGenshinImpact/Service/Notification/Builder/TaskNotificationBuilder.cs +++ /dev/null @@ -1,13 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Model; -using BetterGenshinImpact.Service.Notification.Model.Base; - -namespace BetterGenshinImpact.Service.Notification.Builder; - -public class TaskNotificationBuilder : INotificationBuilder -{ - public TaskNotificationBuilder WithTask(TaskDetails task) - { - _notificationData.Task = task; - return this; - } -} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Builder/TestNotificationBuilder.cs b/BetterGenshinImpact/Service/Notification/Builder/TestNotificationBuilder.cs deleted file mode 100644 index 121c8648..00000000 --- a/BetterGenshinImpact/Service/Notification/Builder/TestNotificationBuilder.cs +++ /dev/null @@ -1,7 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Model; - -namespace BetterGenshinImpact.Service.Notification.Builder; - -public class TestNotificationBuilder : INotificationBuilder -{ -} diff --git a/BetterGenshinImpact/Service/Notification/Converter/BaseDateTimeJsonConverter.cs b/BetterGenshinImpact/Service/Notification/Converter/BaseDateTimeJsonConverter.cs new file mode 100644 index 00000000..ea8434d6 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Converter/BaseDateTimeJsonConverter.cs @@ -0,0 +1,28 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace BetterGenshinImpact.Service.Notification.Converter; + +public class BaseDateTimeJsonConverter(string format) : JsonConverter +{ + + // 反序列化方法 + public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + if (DateTime.TryParseExact(reader.GetString(), format, null, System.Globalization.DateTimeStyles.None, out DateTime date)) + { + return date; + } + } + return reader.GetDateTime(); + } + + // 序列化方法 + public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) + { + writer.WriteStringValue(value.ToString(format)); + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Converter/DateTimeJsonConverter.cs b/BetterGenshinImpact/Service/Notification/Converter/DateTimeJsonConverter.cs new file mode 100644 index 00000000..ae4b9aea --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Converter/DateTimeJsonConverter.cs @@ -0,0 +1,7 @@ +using System.Text.Json.Serialization; + +namespace BetterGenshinImpact.Service.Notification.Converter; + +public class DateTimeJsonConverter() : BaseDateTimeJsonConverter("yyyy-MM-dd HH:mm:ss") +{ +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Converter/ImageToBase64Converter.cs b/BetterGenshinImpact/Service/Notification/Converter/ImageToBase64Converter.cs index 2432c3ea..3b244b93 100644 --- a/BetterGenshinImpact/Service/Notification/Converter/ImageToBase64Converter.cs +++ b/BetterGenshinImpact/Service/Notification/Converter/ImageToBase64Converter.cs @@ -11,11 +11,11 @@ public class ImageToBase64Converter : JsonConverter { public override Image? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - if (reader.GetString() is string base64) + if (reader.GetString() is { } base64) { return Image.FromStream(new MemoryStream(Convert.FromBase64String(base64))); } - return default; + return null; } public override void Write(Utf8JsonWriter writer, Image value, JsonSerializerOptions options) diff --git a/BetterGenshinImpact/Service/Notification/Model/Base/TaskDetails.cs b/BetterGenshinImpact/Service/Notification/Model/Base/TaskDetails.cs deleted file mode 100644 index 6ae08668..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/Base/TaskDetails.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace BetterGenshinImpact.Service.Notification.Model.Base; - -// TODO: 需要制定标准,目前瞎写的 -public class TaskDetails -{ - public Guid Id { get; set; } = Guid.NewGuid(); - public DateTime StartTime { get; set; } = DateTime.Now; -} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/BaseNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/BaseNotificationData.cs new file mode 100644 index 00000000..70f1ad97 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Model/BaseNotificationData.cs @@ -0,0 +1,90 @@ +using System; +using BetterGenshinImpact.Service.Notification.Model.Enum; +using System.Text.Json.Serialization; +using System.Drawing; +using BetterGenshinImpact.GameTask; +using BetterGenshinImpact.GameTask.Common; +using BetterGenshinImpact.Service.Notification.Converter; + +namespace BetterGenshinImpact.Service.Notification.Model; + +public class BaseNotificationData +{ + /// + /// NotificationEvent + /// 事件名称 + /// + public string Event { get; set; } = string.Empty; + + /// + /// 事件结果 + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public NotificationEventResult Result { get; set; } + + /// + /// 事件触发时间 + /// + [JsonConverter(typeof(DateTimeJsonConverter))] + public DateTime Timestamp { get; set; } = DateTime.Now; + + /// + /// 事件触发时的截图 + /// + [JsonConverter(typeof(ImageToBase64Converter))] + public Image? Screenshot { get; set; } + + /// + /// 事件消息 + /// + public string? Message { get; set; } + + /// + /// 额外的事件数据 + /// + public object? Data { get; set; } + + public void Send() + { + if (TaskContext.Instance().Config.NotificationConfig.IncludeScreenShot) + { + Screenshot = (Bitmap)TaskControl.CaptureToRectArea().SrcBitmap.Clone(); + } + + NotificationService.Instance().NotifyAllNotifiers(this); + } + + public void Send(string message) + { + Message = message; + Send(); + } + + public void Success(string message) + { + Message = message; + Result = NotificationEventResult.Success; + Send(); + } + + public void Fail(string message) + { + Message = message; + Result = NotificationEventResult.Fail; + Send(); + } + + public void Error(string message) + { + Message = message; + Result = NotificationEventResult.Fail; + Send(); + } + + public void Error(string message, Exception exception) + { + Message = message + Environment.NewLine + exception.Message + Environment.NewLine + exception.StackTrace; + Result = NotificationEventResult.Fail; + Send(); + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/DomainNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/DomainNotificationData.cs index 99851082..19489223 100644 --- a/BetterGenshinImpact/Service/Notification/Model/DomainNotificationData.cs +++ b/BetterGenshinImpact/Service/Notification/Model/DomainNotificationData.cs @@ -5,7 +5,7 @@ using System.Text.Json.Serialization; namespace BetterGenshinImpact.Service.Notification.Model; -public class DomainNotificationData : INotificationData +public class DomainNotificationData : BaseNotificationData { public AutoDomainParam? Domain { get; set; } } \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs index 3df23915..9d38b133 100644 --- a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs +++ b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs @@ -1,11 +1,13 @@ -namespace BetterGenshinImpact.Service.Notification.Model.Enum; - -// 希望一个Started对应且只能对应一个Completed -// 但enforce这个是否必要? -public enum NotificationAction -{ - Started, - Completed, - InProgress, - Exception, -} +// using System; +// +// namespace BetterGenshinImpact.Service.Notification.Model.Enum; +// +// // 希望一个Started对应且只能对应一个Completed +// // 但enforce这个是否必要? +// [Obsolete] +// public enum NotificationAction +// { +// Started, +// Completed, +// Exception, +// } diff --git a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs index a27313ab..8d122a71 100644 --- a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs +++ b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs @@ -1,10 +1,12 @@ namespace BetterGenshinImpact.Service.Notification.Model.Enum; -public enum NotificationEvent +public class NotificationEvent(string code, string msg) { - Test, //测试 - GeniusInvocation, //七圣召唤 - Domain, //副本 - Script, //路径追踪脚本 - Task, //宏观上的任务 + public static NotificationEvent Test = new("notify.test", "测试通知"); + + + public static NotificationEvent DomainReward = new("domain.reward", "测试通知"); + + public string Code { get; private set; } = code; + public string Msg { get; private set; } = msg; } diff --git a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationConclusion.cs b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEventResult.cs similarity index 75% rename from BetterGenshinImpact/Service/Notification/Model/Enum/NotificationConclusion.cs rename to BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEventResult.cs index 83bf5bbd..f922ed1e 100644 --- a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationConclusion.cs +++ b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEventResult.cs @@ -1,8 +1,8 @@ namespace BetterGenshinImpact.Service.Notification.Model.Enum; -public enum NotificationConclusion +public enum NotificationEventResult { Success, - Failure, + Fail, PartialSuccess, // 还没想好怎么用,先放在这里 } diff --git a/BetterGenshinImpact/Service/Notification/Model/GeniusInvocationNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/GeniusInvocationNotificationData.cs index 1a9e94e0..0d51b8a2 100644 --- a/BetterGenshinImpact/Service/Notification/Model/GeniusInvocationNotificationData.cs +++ b/BetterGenshinImpact/Service/Notification/Model/GeniusInvocationNotificationData.cs @@ -5,7 +5,7 @@ using System.Text.Json.Serialization; namespace BetterGenshinImpact.Service.Notification.Model; -public class GeniusInvocationNotificationData : INotificationData +public class GeniusInvocationNotificationData : BaseNotificationData { public Duel? GeniusInvocation { get; set; } } \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs deleted file mode 100644 index 7a53734e..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/INotificationData.cs +++ /dev/null @@ -1,28 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Model.Enum; -using System.Text.Json.Serialization; -using System.Drawing; -using BetterGenshinImpact.Service.Notification.Converter; - -namespace BetterGenshinImpact.Service.Notification.Model; - -public abstract class INotificationData -{ - [JsonConverter(typeof(JsonStringEnumConverter))] - public NotificationEvent Event { get; set; } - - [JsonConverter(typeof(JsonStringEnumConverter))] - public NotificationAction Action { get; set; } - - [JsonConverter(typeof(JsonStringEnumConverter))] - public NotificationConclusion? Conclusion { get; set; } - - [JsonConverter(typeof(ImageToBase64Converter))] - public Image? Screenshot { get; set; } - - public string? Message { get; set; } - - public void Send() - { - NotificationHelper.Notify(this); - } -} diff --git a/BetterGenshinImpact/Service/Notification/Model/ScriptNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/ScriptNotificationData.cs index 37577268..a45590bc 100644 --- a/BetterGenshinImpact/Service/Notification/Model/ScriptNotificationData.cs +++ b/BetterGenshinImpact/Service/Notification/Model/ScriptNotificationData.cs @@ -5,7 +5,7 @@ using System.Text.Json.Serialization; namespace BetterGenshinImpact.Service.Notification.Model; -public class ScriptNotificationData : INotificationData +public class ScriptNotificationData : BaseNotificationData { public ScriptGroupProject? Script { get; set; } } \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notification/Model/TaskNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/TaskNotificationData.cs deleted file mode 100644 index 66e3520f..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/TaskNotificationData.cs +++ /dev/null @@ -1,12 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Converter; -using BetterGenshinImpact.Service.Notification.Model.Enum; -using System.Drawing; -using System.Text.Json.Serialization; -using BetterGenshinImpact.Service.Notification.Model.Base; - -namespace BetterGenshinImpact.Service.Notification.Model; - -public class TaskNotificationData : INotificationData -{ - public TaskDetails? Task { get; set; } -} diff --git a/BetterGenshinImpact/Service/Notification/Model/TestNotificationData.cs b/BetterGenshinImpact/Service/Notification/Model/TestNotificationData.cs deleted file mode 100644 index 387d83ce..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/TestNotificationData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using BetterGenshinImpact.Service.Notification.Converter; -using BetterGenshinImpact.Service.Notification.Model.Enum; -using System.Drawing; -using System.Text.Json.Serialization; -using BetterGenshinImpact.Service.Notification.Model.Base; - -namespace BetterGenshinImpact.Service.Notification.Model; - -public class TestNotificationData : INotificationData -{ -} diff --git a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs index c097b6d7..cfb0e6d8 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs @@ -1,49 +1,49 @@ -using System.Drawing; -using BetterGenshinImpact.Core.Config; -using BetterGenshinImpact.Core.Script.Group; -using BetterGenshinImpact.GameTask; -using BetterGenshinImpact.GameTask.AutoDomain; -using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Model; -using BetterGenshinImpact.GameTask.Common; -using BetterGenshinImpact.Service.Notification.Builder; -using BetterGenshinImpact.Service.Notification.Model; -using BetterGenshinImpact.Service.Notification.Model.Base; -using BetterGenshinImpact.Service.Notification.Model.Enum; - -namespace BetterGenshinImpact.Service.Notification; - -public class NotificationHelper -{ - public static void Notify(INotificationData notificationData) - { - if (TaskContext.Instance().Config.NotificationConfig.IncludeScreenShot) - { - var screenShot = (Bitmap)TaskControl.CaptureToRectArea().SrcBitmap.Clone(); - notificationData.Screenshot = screenShot; - } - NotificationService.Instance().NotifyAllNotifiers(notificationData); - } -} - -public class NotificationBuilderFactory -{ - public static ScriptNotificationBuilder CreateWith(ScriptGroupProject script) - { - return new ScriptNotificationBuilder().WithEvent(NotificationEvent.Script).WithScript(script); - } - - public static TaskNotificationBuilder CreateWith(TaskDetails task) - { - return new TaskNotificationBuilder().WithEvent(NotificationEvent.Task).WithTask(task); - } - - public static GeniusInvocationNotificationBuilder CreateWith(Duel geniusInvocation) - { - return new GeniusInvocationNotificationBuilder().WithEvent(NotificationEvent.GeniusInvocation).WithGeniusInvocation(geniusInvocation); - } - - public static DomainNotificationBuilder CreateWith(AutoDomainParam domain) - { - return new DomainNotificationBuilder().WithEvent(NotificationEvent.Domain).WithDomain(domain); - } -} +// using System.Drawing; +// using BetterGenshinImpact.Core.Config; +// using BetterGenshinImpact.Core.Script.Group; +// using BetterGenshinImpact.GameTask; +// using BetterGenshinImpact.GameTask.AutoDomain; +// using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Model; +// using BetterGenshinImpact.GameTask.Common; +// using BetterGenshinImpact.Service.Notification.Builder; +// using BetterGenshinImpact.Service.Notification.Model; +// using BetterGenshinImpact.Service.Notification.Model.Base; +// using BetterGenshinImpact.Service.Notification.Model.Enum; +// +// namespace BetterGenshinImpact.Service.Notification; +// +// public class NotificationHelper +// { +// public static void Notify(BaseNotificationData notificationData) +// { +// if (TaskContext.Instance().Config.NotificationConfig.IncludeScreenShot) +// { +// var screenShot = (Bitmap)TaskControl.CaptureToRectArea().SrcBitmap.Clone(); +// notificationData.Screenshot = screenShot; +// } +// NotificationService.Instance().NotifyAllNotifiers(notificationData); +// } +// } +// +// public class NotificationBuilderFactory +// { +// public static ScriptNotificationBuilder CreateWith(ScriptGroupProject script) +// { +// return new ScriptNotificationBuilder().WithEvent(NotificationEvent.Script).WithScript(script); +// } +// +// public static TaskNotificationBuilder CreateWith(TaskDetails task) +// { +// return new TaskNotificationBuilder().WithEvent(NotificationEvent.Task).WithTask(task); +// } +// +// public static GeniusInvocationNotificationBuilder CreateWith(Duel geniusInvocation) +// { +// return new GeniusInvocationNotificationBuilder().WithEvent(NotificationEvent.GeniusInvocation).WithGeniusInvocation(geniusInvocation); +// } +// +// public static DomainNotificationBuilder CreateWith(AutoDomainParam domain) +// { +// return new DomainNotificationBuilder().WithEvent(NotificationEvent.Domain).WithDomain(domain); +// } +// } diff --git a/BetterGenshinImpact/Service/Notification/NotificationService.cs b/BetterGenshinImpact/Service/Notification/NotificationService.cs index 15c10cbb..0510d957 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationService.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationService.cs @@ -77,11 +77,10 @@ public class NotificationService : IHostedService return NotificationTestResult.Error("通知类型未启用"); } - var testData = new TestNotificationData + var testData = new BaseNotificationData { - Event = NotificationEvent.Test, - Action = NotificationAction.Started, - Conclusion = NotificationConclusion.Success, + Event = NotificationEvent.Test.Code, + Result = NotificationEventResult.Success, Message = "这是一条测试通知信息", }; if (TaskContext.Instance().IsInitialized) @@ -98,12 +97,12 @@ public class NotificationService : IHostedService } } - public async Task NotifyAllNotifiersAsync(INotificationData notificationData) + public async Task NotifyAllNotifiersAsync(BaseNotificationData notificationData) { await _notifierManager.SendNotificationToAllAsync(notificationData); } - public void NotifyAllNotifiers(INotificationData notificationData) + public void NotifyAllNotifiers(BaseNotificationData notificationData) { Task.Run(() => NotifyAllNotifiersAsync(notificationData)); } diff --git a/BetterGenshinImpact/Service/Notification/Notify.cs b/BetterGenshinImpact/Service/Notification/Notify.cs new file mode 100644 index 00000000..7a3c2f78 --- /dev/null +++ b/BetterGenshinImpact/Service/Notification/Notify.cs @@ -0,0 +1,23 @@ +using BetterGenshinImpact.Service.Notification.Model; +using BetterGenshinImpact.Service.Notification.Model.Enum; + +namespace BetterGenshinImpact.Service.Notification; + +public class Notify +{ + public static BaseNotificationData Event(string eventName) + { + return new BaseNotificationData + { + Event = eventName + }; + } + + public static BaseNotificationData Event(NotificationEvent eventEnum) + { + return new BaseNotificationData + { + Event = eventEnum.Code + }; + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs b/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs index d4023bc3..3705e03f 100644 --- a/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/Interface/INotifier.cs @@ -8,5 +8,5 @@ public interface INotifier { string Name { get; } - Task SendAsync(INotificationData data); + Task SendAsync(BaseNotificationData data); } diff --git a/BetterGenshinImpact/Service/Notifier/NotifierManager.cs b/BetterGenshinImpact/Service/Notifier/NotifierManager.cs index 17e4e42a..fd563257 100644 --- a/BetterGenshinImpact/Service/Notifier/NotifierManager.cs +++ b/BetterGenshinImpact/Service/Notifier/NotifierManager.cs @@ -37,7 +37,7 @@ public class NotifierManager return _notifiers.FirstOrDefault(o => o is T); } - public async Task SendNotificationAsync(INotifier notifier, INotificationData content) + public async Task SendNotificationAsync(INotifier notifier, BaseNotificationData content) { try { @@ -49,7 +49,7 @@ public class NotifierManager } } - public async Task SendNotificationAsync(INotificationData content) where T : INotifier + public async Task SendNotificationAsync(BaseNotificationData content) where T : INotifier { var notifier = _notifiers.FirstOrDefault(o => o is T); @@ -59,7 +59,7 @@ public class NotifierManager } } - public async Task SendNotificationToAllAsync(INotificationData content) + public async Task SendNotificationToAllAsync(BaseNotificationData content) { await Task.WhenAll(_notifiers.Select(notifier => SendNotificationAsync(notifier, content))); } diff --git a/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs b/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs index 8600dcf4..d196c777 100644 --- a/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs @@ -27,7 +27,7 @@ public class WebhookNotifier : INotifier Endpoint = endpoint; } - public async Task SendAsync(INotificationData content) + public async Task SendAsync(BaseNotificationData content) { try { @@ -49,7 +49,7 @@ public class WebhookNotifier : INotifier } - private StringContent TransformData(INotificationData notificationData) + private StringContent TransformData(BaseNotificationData notificationData) { // using object type here so it serializes the interface correctly var serializedData = JsonSerializer.Serialize(notificationData, _jsonSerializerOptions); diff --git a/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs b/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs index dadfe832..8cfcf595 100644 --- a/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/WindowsUwpNotifier.cs @@ -12,7 +12,7 @@ public class WindowsUwpNotifier : INotifier { public string Name => "Windows通知"; - public Task SendAsync(INotificationData data) + public Task SendAsync(BaseNotificationData data) { var toastBuilder = new ToastContentBuilder(); diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index ad65f7e3..f55fdb5f 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -69,7 +69,9 @@ public partial class ScriptService : IScriptService } var timerOperation = hasTimer ? DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty : DispatcherTimerOperationEnum.UseSelfCaptureImage; - + + Notify.Event("group.start").Success($"配置组{groupName}启动"); + await new TaskRunner(timerOperation) .RunThreadAsync(async () => { @@ -98,10 +100,8 @@ public partial class ScriptService : IScriptService for (var i = 0; i < project.RunNum; i++) { - bool isSuccess = false; try { - NotificationBuilderFactory.CreateWith(project).Started().Build().Send(); if (hasTimer) { TaskTriggerDispatcher.Instance().ClearTriggers(); @@ -112,7 +112,6 @@ public partial class ScriptService : IScriptService stopwatch.Reset(); stopwatch.Start(); await ExecuteProject(project); - isSuccess = true; //多次执行时及时中断 if (project.GroupInfo is { Config.PathingConfig.Enabled: true } && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring)) @@ -124,37 +123,27 @@ public partial class ScriptService : IScriptService } catch (NormalEndException e) { - NotificationBuilderFactory.CreateWith(project).Exception(e.Message).Build().Send(); throw; } catch (TaskCanceledException e) { _logger.LogInformation("取消执行配置组: {Msg}", e.Message); - NotificationBuilderFactory.CreateWith(project).Exception("取消执行配置组: " + e.Message).Build().Send(); throw; } catch (Exception e) { _logger.LogDebug(e, "执行脚本时发生异常"); _logger.LogError("执行脚本时发生异常: {Msg}", e.Message); - NotificationBuilderFactory.CreateWith(project).Exception("执行脚本时发生异常: " + e.Message).Build().Send(); } finally { stopwatch.Stop(); var elapsedTime = TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds); - _logger.LogDebug("→ 脚本执行结束: {Name}, 耗时: {ElapsedMilliseconds} 毫秒", project.Name, stopwatch.ElapsedMilliseconds); + // _logger.LogDebug("→ 脚本执行结束: {Name}, 耗时: {ElapsedMilliseconds} 毫秒", project.Name, stopwatch.ElapsedMilliseconds); _logger.LogInformation("→ 脚本执行结束: {Name}, 耗时: {Minutes}分{Seconds:0.000}秒", project.Name, elapsedTime.Hours * 60 + elapsedTime.Minutes, elapsedTime.TotalSeconds % 60); _logger.LogInformation("------------------------------"); - if (isSuccess) - { - NotificationBuilderFactory.CreateWith(project).Success().Build().Send(); - } - else - { - NotificationBuilderFactory.CreateWith(project).Failure().Build().Send(); - } + } await Task.Delay(2000); @@ -166,6 +155,7 @@ public partial class ScriptService : IScriptService { _logger.LogInformation("配置组 {Name} 执行结束", groupName); } + Notify.Event("group.end").Success($"配置组{groupName}结束"); } private List ReloadScriptProjects(IEnumerable projectList, ref bool hasTimer) From 644c3d0193d34fb0e23188f849989d5a02a9a1e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 3 Feb 2025 15:54:19 +0800 Subject: [PATCH 71/81] =?UTF-8?q?=E6=9B=B4=E5=A4=9A=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/AutoGeniusInvokation/Model/Duel.cs | 4 ++++ .../GameTask/AutoMusicGame/AutoAlbumTask.cs | 7 +++++-- .../ViewModel/Pages/OneDragonFlowViewModel.cs | 3 +++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs index 2ded1634..3fb9469d 100644 --- a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs +++ b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs @@ -60,6 +60,8 @@ public class Duel LogScreenResolution(); try { + Notify.Event("tcg.start").Success("自动七胜召唤启动"); + AutoGeniusInvokationAssets.DestroyInstance(); GeniusInvokationControl.GetInstance().Init(ct); @@ -302,6 +304,8 @@ public class Duel } throw; } + + Notify.Event("tcg.end").Success("自动七胜召唤结束"); } private HashSet PredictionDiceType() diff --git a/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs b/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs index 5284db78..a9ccde19 100644 --- a/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs +++ b/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs @@ -8,6 +8,7 @@ using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception; using BetterGenshinImpact.GameTask.AutoMusicGame.Assets; using BetterGenshinImpact.GameTask.Common.BgiVision; using BetterGenshinImpact.GameTask.Model.Area; +using BetterGenshinImpact.Service.Notification; using Microsoft.Extensions.Logging; using static BetterGenshinImpact.GameTask.Common.TaskControl; @@ -27,8 +28,10 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask try { AutoMusicGameTask.Init(); + Notify.Event("album.start").Success("自动音游专辑启动"); Logger.LogInformation("开始自动演奏整个专辑未完成的音乐"); await StartOneAlbum(ct); + Notify.Event("album.end").Success("自动音游专辑启动"); } catch (NormalEndException e) { @@ -37,6 +40,7 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask catch (Exception e) { Logger.LogError("自动音乐专辑任务异常:{Msg}", e.Message); + Notify.Event("album.error").Error("自动音游专辑异常", e); } } @@ -98,7 +102,7 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask await Delay(800, ct); continue; } - + Logger.LogInformation("第{Num}首{Difficulty}难度的乐曲:{Message}", i + 1, difficultyName, "没有完成【大音天籁】"); } else @@ -116,7 +120,6 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask } - // 点击确认按钮 Bv.ClickWhiteConfirmButton(CaptureToRectArea()); await Delay(800, ct); diff --git a/BetterGenshinImpact/ViewModel/Pages/OneDragonFlowViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/OneDragonFlowViewModel.cs index 088b8b85..5d397f1d 100644 --- a/BetterGenshinImpact/ViewModel/Pages/OneDragonFlowViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/OneDragonFlowViewModel.cs @@ -14,6 +14,7 @@ using BetterGenshinImpact.GameTask; using BetterGenshinImpact.GameTask.Common.Element.Assets; using BetterGenshinImpact.GameTask.Model.Enum; using BetterGenshinImpact.Service; +using BetterGenshinImpact.Service.Notification; using BetterGenshinImpact.View.Windows; using CommunityToolkit.Mvvm.Input; using Newtonsoft.Json; @@ -207,6 +208,7 @@ public partial class OneDragonFlowViewModel : ObservableObject, INavigationAware await new TaskRunner(DispatcherTimerOperationEnum.UseSelfCaptureImage) .RunThreadAsync(async () => { + Notify.Event("dragon.start").Success("一条龙启动"); foreach (var task in TaskList) { if (task is { IsEnabled: true, Action: not null }) @@ -215,6 +217,7 @@ public partial class OneDragonFlowViewModel : ObservableObject, INavigationAware await Task.Delay(1000); } } + Notify.Event("dragon.end").Success("一条龙结束"); }); } From 151b383c404af98f16210db1e8edb10b41654df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Mon, 3 Feb 2025 19:28:09 +0800 Subject: [PATCH 72/81] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A3=9E=E4=B9=A6?= =?UTF-8?q?=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Notification/NotificationConfig.cs | 21 ++ .../Notification/NotificationService.cs | 5 + .../Service/Notifier/FeishuNotifier.cs | 66 ++++++ .../View/Pages/CommonSettingsPage.xaml | 189 +++++++++++++++--- .../Pages/CommonSettingsPageViewModel.cs | 14 ++ 5 files changed, 264 insertions(+), 31 deletions(-) create mode 100644 BetterGenshinImpact/Service/Notifier/FeishuNotifier.cs diff --git a/BetterGenshinImpact/Service/Notification/NotificationConfig.cs b/BetterGenshinImpact/Service/Notification/NotificationConfig.cs index 1da20fe9..639f7ed5 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationConfig.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationConfig.cs @@ -20,6 +20,10 @@ public partial class NotificationConfig : ObservableObject /// [ObservableProperty] private string _webhookEndpoint = string.Empty; + + + // [ObservableProperty] + // private string _webhookEventSubscribe = string.Empty; /// /// 是否包含截图 @@ -32,5 +36,22 @@ public partial class NotificationConfig : ObservableObject /// [ObservableProperty] private bool _windowsUwpNotificationEnabled = false; + + + // 飞书通知 + /// + /// 飞书通知是否启用 + /// + [ObservableProperty] + private bool _feishuNotificationEnabled = false; + + + /// + /// 飞书通知地址 + /// + [ObservableProperty] + private string _feishuWebhookUrl = string.Empty; + + } diff --git a/BetterGenshinImpact/Service/Notification/NotificationService.cs b/BetterGenshinImpact/Service/Notification/NotificationService.cs index 0510d957..5b50c7e7 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationService.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationService.cs @@ -59,6 +59,11 @@ public class NotificationService : IHostedService { _notifierManager.RegisterNotifier(new WindowsUwpNotifier()); } + + if (TaskContext.Instance().Config.NotificationConfig.FeishuNotificationEnabled) + { + _notifierManager.RegisterNotifier(new FeishuNotifier(NotifyHttpClient, TaskContext.Instance().Config.NotificationConfig.FeishuWebhookUrl)); + } } public void RefreshNotifiers() diff --git a/BetterGenshinImpact/Service/Notifier/FeishuNotifier.cs b/BetterGenshinImpact/Service/Notifier/FeishuNotifier.cs new file mode 100644 index 00000000..04e14e63 --- /dev/null +++ b/BetterGenshinImpact/Service/Notifier/FeishuNotifier.cs @@ -0,0 +1,66 @@ +using BetterGenshinImpact.Service.Notifier.Exception; +using BetterGenshinImpact.Service.Notifier.Interface; +using System.Net.Http; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using BetterGenshinImpact.Service.Notification.Model; + +namespace BetterGenshinImpact.Service.Notifier; + +public class FeishuNotifier : INotifier +{ + public string Name { get; set; } = "Feishu"; + + public string Endpoint { get; set; } + + private readonly HttpClient _httpClient; + + public FeishuNotifier(HttpClient httpClient, string endpoint = "") + { + _httpClient = httpClient; + Endpoint = endpoint; + } + + public async Task SendAsync(BaseNotificationData content) + { + if (string.IsNullOrEmpty(Endpoint)) + { + throw new NotifierException("Feishu webhook endpoint is not set"); + } + + try + { + var response = await _httpClient.PostAsync(Endpoint, TransformData(content)); + + if (!response.IsSuccessStatusCode) + { + throw new NotifierException($"Feishu webhook call failed with code: {response.StatusCode}"); + } + } + catch (NotifierException) + { + throw; + } + catch (System.Exception ex) + { + throw new NotifierException($"Error sending Feishu webhook: {ex.Message}"); + } + } + + private StringContent TransformData(BaseNotificationData notificationData) + { + var feishuMessage = new + { + msg_type = "text", + content = new + { + text = notificationData.Message + } + }; + + var serializedData = JsonSerializer.Serialize(feishuMessage); + + return new StringContent(serializedData, Encoding.UTF8, "application/json"); + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml index 75959825..4818d696 100644 --- a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml @@ -81,7 +81,9 @@ Grid.Column="0" Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}" TextWrapping="Wrap"> - 在遮罩内显示日志窗口, + 在遮罩内显示日志窗口, + 点击打开日志文件夹 @@ -333,7 +335,9 @@ Grid.Column="0" Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}" TextWrapping="Wrap"> - 可以通过快捷键保存截图,文件保存在 + 可以通过快捷键保存截图,文件保存在 + log/screenshot @@ -431,11 +435,71 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + - + @@ -619,6 +658,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs index 6c763922..3623c55b 100644 --- a/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs @@ -136,4 +136,18 @@ public partial class CommonSettingsPageViewModel : ObservableObject, INavigation Toast.Error(res.Message); } } + + [RelayCommand] + private async Task OnTestFeishuNotification() + { + var res = await _notificationService.TestNotifierAsync(); + if(res.IsSuccess) + { + Toast.Success(res.Message); + } + else + { + Toast.Error(res.Message); + } + } } \ No newline at end of file From 92516c26d2e5db14423a233fbf1e36fcc5835115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Tue, 4 Feb 2025 17:11:53 +0800 Subject: [PATCH 73/81] =?UTF-8?q?=E6=94=AF=E6=8C=81=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=A6=81=E9=80=9A=E7=9F=A5=E7=9A=84=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GameTask/AutoDomain/AutoDomainTask.cs | 6 +-- .../AutoGeniusInvokation/Model/Duel.cs | 5 +- .../GameTask/AutoMusicGame/AutoAlbumTask.cs | 7 +-- BetterGenshinImpact/GameTask/TaskRunner.cs | 7 +-- .../Model/Enum/NotificationAction.cs | 13 ----- .../Model/Enum/NotificationEvent.cs | 20 ++++++-- .../Notification/NotificationConfig.cs | 11 +++-- .../Notification/NotificationHelper.cs | 49 ------------------- .../Notification/NotificationService.cs | 11 ++++- .../Service/Notifier/WebhookNotifier.cs | 5 ++ BetterGenshinImpact/Service/ScriptService.cs | 5 +- .../View/Pages/CommonSettingsPage.xaml | 30 ++++++++++-- .../ViewModel/Pages/OneDragonFlowViewModel.cs | 5 +- 13 files changed, 85 insertions(+), 89 deletions(-) delete mode 100644 BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs delete mode 100644 BetterGenshinImpact/Service/Notification/NotificationHelper.cs diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs index c108545c..47c5bb27 100644 --- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs +++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs @@ -71,7 +71,7 @@ public class AutoDomainTask : ISoloTask _ct = ct; Init(); - Notify.Event("domain.start").Success("自动秘境启动"); + Notify.Event(NotificationEvent.DomainStart).Success("自动秘境启动"); // 3次复活重试 for (int i = 0; i < 3; i++) @@ -88,7 +88,7 @@ public class AutoDomainTask : ISoloTask { Logger.LogWarning("自动秘境:{Text}", "复活后重试秘境..."); await Delay(2000, ct); - Notify.Event("domain.retry").Error("存在角色死亡,复活后重试秘境..."); + Notify.Event(NotificationEvent.DomainRetry).Error("存在角色死亡,复活后重试秘境..."); continue; } else @@ -104,7 +104,7 @@ public class AutoDomainTask : ISoloTask await Delay(2000, ct); await ArtifactSalvage(); - Notify.Event("domain.end").Success("自动秘境结束"); + Notify.Event(NotificationEvent.DomainEnd).Success("自动秘境结束"); } private async Task DoDomain() diff --git a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs index 3fb9469d..05c25e2e 100644 --- a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs +++ b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using BetterGenshinImpact.Service.Notification.Model.Enum; namespace BetterGenshinImpact.GameTask.AutoGeniusInvokation.Model; @@ -60,7 +61,7 @@ public class Duel LogScreenResolution(); try { - Notify.Event("tcg.start").Success("自动七胜召唤启动"); + Notify.Event(NotificationEvent.TcgStart).Success("自动七胜召唤启动"); AutoGeniusInvokationAssets.DestroyInstance(); @@ -305,7 +306,7 @@ public class Duel throw; } - Notify.Event("tcg.end").Success("自动七胜召唤结束"); + Notify.Event(NotificationEvent.TcgEnd).Success("自动七胜召唤结束"); } private HashSet PredictionDiceType() diff --git a/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs b/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs index a9ccde19..2227a34b 100644 --- a/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs +++ b/BetterGenshinImpact/GameTask/AutoMusicGame/AutoAlbumTask.cs @@ -9,6 +9,7 @@ using BetterGenshinImpact.GameTask.AutoMusicGame.Assets; using BetterGenshinImpact.GameTask.Common.BgiVision; using BetterGenshinImpact.GameTask.Model.Area; using BetterGenshinImpact.Service.Notification; +using BetterGenshinImpact.Service.Notification.Model.Enum; using Microsoft.Extensions.Logging; using static BetterGenshinImpact.GameTask.Common.TaskControl; @@ -28,10 +29,10 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask try { AutoMusicGameTask.Init(); - Notify.Event("album.start").Success("自动音游专辑启动"); + Notify.Event(NotificationEvent.AlbumStart).Success("自动音游专辑启动"); Logger.LogInformation("开始自动演奏整个专辑未完成的音乐"); await StartOneAlbum(ct); - Notify.Event("album.end").Success("自动音游专辑启动"); + Notify.Event(NotificationEvent.AlbumEnd).Success("自动音游专辑结束"); } catch (NormalEndException e) { @@ -40,7 +41,7 @@ public class AutoAlbumTask(AutoMusicGameParam taskParam) : ISoloTask catch (Exception e) { Logger.LogError("自动音乐专辑任务异常:{Msg}", e.Message); - Notify.Event("album.error").Error("自动音游专辑异常", e); + Notify.Event(NotificationEvent.AlbumError).Error("自动音游专辑异常", e); } } diff --git a/BetterGenshinImpact/GameTask/TaskRunner.cs b/BetterGenshinImpact/GameTask/TaskRunner.cs index 1e27e8dd..6662c1d7 100644 --- a/BetterGenshinImpact/GameTask/TaskRunner.cs +++ b/BetterGenshinImpact/GameTask/TaskRunner.cs @@ -12,6 +12,7 @@ using Wpf.Ui.Violeta.Controls; using static BetterGenshinImpact.GameTask.Common.TaskControl; using BetterGenshinImpact.Service; using BetterGenshinImpact.Service.Notification; +using BetterGenshinImpact.Service.Notification.Model.Enum; namespace BetterGenshinImpact.GameTask; @@ -63,7 +64,7 @@ public class TaskRunner } catch (NormalEndException e) { - Notify.Event("task.cancel").Success("任务手动取消,或正常结束"); + Notify.Event(NotificationEvent.TaskCancel).Success("任务手动取消,或正常结束"); _logger.LogInformation("任务中断:{Msg}", e.Message); if (RunnerContext.Instance.IsContinuousRunGroup) { @@ -73,7 +74,7 @@ public class TaskRunner } catch (TaskCanceledException e) { - Notify.Event("task.cancel").Success("任务被手动取消"); + Notify.Event(NotificationEvent.TaskCancel).Success("任务被手动取消"); _logger.LogInformation("任务中断:{Msg}", "任务被取消"); if (RunnerContext.Instance.IsContinuousRunGroup) { @@ -83,7 +84,7 @@ public class TaskRunner } catch (Exception e) { - Notify.Event("task.error").Error("任务执行异常", e); + Notify.Event(NotificationEvent.TaskError).Error("任务执行异常", e); _logger.LogError(e.Message); _logger.LogDebug(e.StackTrace); } diff --git a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs deleted file mode 100644 index 9d38b133..00000000 --- a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationAction.cs +++ /dev/null @@ -1,13 +0,0 @@ -// using System; -// -// namespace BetterGenshinImpact.Service.Notification.Model.Enum; -// -// // 希望一个Started对应且只能对应一个Completed -// // 但enforce这个是否必要? -// [Obsolete] -// public enum NotificationAction -// { -// Started, -// Completed, -// Exception, -// } diff --git a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs index 8d122a71..9d73af87 100644 --- a/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs +++ b/BetterGenshinImpact/Service/Notification/Model/Enum/NotificationEvent.cs @@ -2,10 +2,22 @@ public class NotificationEvent(string code, string msg) { - public static NotificationEvent Test = new("notify.test", "测试通知"); - - - public static NotificationEvent DomainReward = new("domain.reward", "测试通知"); + public static readonly NotificationEvent Test = new("notify.test", "测试通知"); + public static readonly NotificationEvent DomainReward = new("domain.reward", "自动秘境奖励"); + public static readonly NotificationEvent DomainStart = new("domain.start", "自动秘境启动"); + public static readonly NotificationEvent DomainEnd = new("domain.end", "自动秘境结束"); + public static readonly NotificationEvent DomainRetry = new("domain.retry", "自动秘境重试"); + public static readonly NotificationEvent TaskCancel = new("task.cancel", "任务启动"); + public static readonly NotificationEvent TaskError = new("task.error", "任务错误"); + public static readonly NotificationEvent GroupStart = new("group.start", "配置组启动"); + public static readonly NotificationEvent GroupEnd = new("group.end", "配置组结束"); + public static readonly NotificationEvent DragonStart = new("dragon.start", "一条龙启动"); + public static readonly NotificationEvent DragonEnd = new("dragon.end", "一条龙结束"); + public static readonly NotificationEvent TcgStart = new("tcg.start", "七圣召唤启动"); + public static readonly NotificationEvent TcgEnd = new("tcg.end", "七圣召唤结束"); + public static readonly NotificationEvent AlbumStart = new("album.start", "自动音游专辑启动"); + public static readonly NotificationEvent AlbumEnd = new("album.end", "自动音游专辑结束"); + public static readonly NotificationEvent AlbumError = new("album.error", "自动音游专辑错误"); public string Code { get; private set; } = code; public string Msg { get; private set; } = msg; diff --git a/BetterGenshinImpact/Service/Notification/NotificationConfig.cs b/BetterGenshinImpact/Service/Notification/NotificationConfig.cs index 639f7ed5..27370298 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationConfig.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationConfig.cs @@ -9,6 +9,11 @@ namespace BetterGenshinImpact.Service.Notification; [Serializable] public partial class NotificationConfig : ObservableObject { + + + [ObservableProperty] + private string _notificationEventSubscribe = string.Empty; + /// /// /// @@ -21,15 +26,13 @@ public partial class NotificationConfig : ObservableObject [ObservableProperty] private string _webhookEndpoint = string.Empty; - - // [ObservableProperty] - // private string _webhookEventSubscribe = string.Empty; + /// /// 是否包含截图 /// [ObservableProperty] - private bool _includeScreenShot = false; + private bool _includeScreenShot = true; /// /// windows uwp 通知是否启用 diff --git a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs b/BetterGenshinImpact/Service/Notification/NotificationHelper.cs deleted file mode 100644 index cfb0e6d8..00000000 --- a/BetterGenshinImpact/Service/Notification/NotificationHelper.cs +++ /dev/null @@ -1,49 +0,0 @@ -// using System.Drawing; -// using BetterGenshinImpact.Core.Config; -// using BetterGenshinImpact.Core.Script.Group; -// using BetterGenshinImpact.GameTask; -// using BetterGenshinImpact.GameTask.AutoDomain; -// using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Model; -// using BetterGenshinImpact.GameTask.Common; -// using BetterGenshinImpact.Service.Notification.Builder; -// using BetterGenshinImpact.Service.Notification.Model; -// using BetterGenshinImpact.Service.Notification.Model.Base; -// using BetterGenshinImpact.Service.Notification.Model.Enum; -// -// namespace BetterGenshinImpact.Service.Notification; -// -// public class NotificationHelper -// { -// public static void Notify(BaseNotificationData notificationData) -// { -// if (TaskContext.Instance().Config.NotificationConfig.IncludeScreenShot) -// { -// var screenShot = (Bitmap)TaskControl.CaptureToRectArea().SrcBitmap.Clone(); -// notificationData.Screenshot = screenShot; -// } -// NotificationService.Instance().NotifyAllNotifiers(notificationData); -// } -// } -// -// public class NotificationBuilderFactory -// { -// public static ScriptNotificationBuilder CreateWith(ScriptGroupProject script) -// { -// return new ScriptNotificationBuilder().WithEvent(NotificationEvent.Script).WithScript(script); -// } -// -// public static TaskNotificationBuilder CreateWith(TaskDetails task) -// { -// return new TaskNotificationBuilder().WithEvent(NotificationEvent.Task).WithTask(task); -// } -// -// public static GeniusInvocationNotificationBuilder CreateWith(Duel geniusInvocation) -// { -// return new GeniusInvocationNotificationBuilder().WithEvent(NotificationEvent.GeniusInvocation).WithGeniusInvocation(geniusInvocation); -// } -// -// public static DomainNotificationBuilder CreateWith(AutoDomainParam domain) -// { -// return new DomainNotificationBuilder().WithEvent(NotificationEvent.Domain).WithDomain(domain); -// } -// } diff --git a/BetterGenshinImpact/Service/Notification/NotificationService.cs b/BetterGenshinImpact/Service/Notification/NotificationService.cs index 5b50c7e7..8ca6c544 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationService.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationService.cs @@ -59,7 +59,7 @@ public class NotificationService : IHostedService { _notifierManager.RegisterNotifier(new WindowsUwpNotifier()); } - + if (TaskContext.Instance().Config.NotificationConfig.FeishuNotificationEnabled) { _notifierManager.RegisterNotifier(new FeishuNotifier(NotifyHttpClient, TaskContext.Instance().Config.NotificationConfig.FeishuWebhookUrl)); @@ -104,6 +104,15 @@ public class NotificationService : IHostedService public async Task NotifyAllNotifiersAsync(BaseNotificationData notificationData) { + var subscribeEventStr = TaskContext.Instance().Config.NotificationConfig.NotificationEventSubscribe; + if (!string.IsNullOrEmpty(subscribeEventStr)) + { + if (!subscribeEventStr.Contains(notificationData.Event)) + { + return; + } + } + await _notifierManager.SendNotificationToAllAsync(notificationData); } diff --git a/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs b/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs index d196c777..e6b6483f 100644 --- a/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/WebhookNotifier.cs @@ -29,6 +29,11 @@ public class WebhookNotifier : INotifier public async Task SendAsync(BaseNotificationData content) { + if (string.IsNullOrEmpty(Endpoint)) + { + throw new NotifierException("Webhook 地址为空"); + } + try { var response = await _httpClient.PostAsync(Endpoint, TransformData(content)); diff --git a/BetterGenshinImpact/Service/ScriptService.cs b/BetterGenshinImpact/Service/ScriptService.cs index f55fdb5f..51323dd1 100644 --- a/BetterGenshinImpact/Service/ScriptService.cs +++ b/BetterGenshinImpact/Service/ScriptService.cs @@ -16,6 +16,7 @@ using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception; using BetterGenshinImpact.GameTask.Common; using BetterGenshinImpact.GameTask.Common.BgiVision; using BetterGenshinImpact.Service.Notification; +using BetterGenshinImpact.Service.Notification.Model.Enum; namespace BetterGenshinImpact.Service; @@ -70,7 +71,7 @@ public partial class ScriptService : IScriptService var timerOperation = hasTimer ? DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty : DispatcherTimerOperationEnum.UseSelfCaptureImage; - Notify.Event("group.start").Success($"配置组{groupName}启动"); + Notify.Event(NotificationEvent.GroupStart).Success($"配置组{groupName}启动"); await new TaskRunner(timerOperation) .RunThreadAsync(async () => @@ -155,7 +156,7 @@ public partial class ScriptService : IScriptService { _logger.LogInformation("配置组 {Name} 执行结束", groupName); } - Notify.Event("group.end").Success($"配置组{groupName}结束"); + Notify.Event(NotificationEvent.GroupEnd).Success($"配置组{groupName}结束"); } private List ReloadScriptProjects(IEnumerable projectList, ref bool hasTimer) diff --git a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml index 4818d696..2ecf8eec 100644 --- a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml @@ -3,9 +3,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:b="http://schemas.microsoft.com/xaml/behaviors" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:helpers="clr-namespace:BetterGenshinImpact.Helpers" - xmlns:local="clr-namespace:BetterGenshinImpact.View.Pages" - xmlns:markup="clr-namespace:BetterGenshinImpact.Markup" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:pages="clr-namespace:BetterGenshinImpact.ViewModel.Pages" xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" @@ -497,6 +494,33 @@ Margin="0,0,36,0" IsChecked="{Binding Config.NotificationConfig.IncludeScreenShot, Mode=TwoWay}" /> + + + + + + + + + + + + + diff --git a/BetterGenshinImpact/ViewModel/Pages/OneDragonFlowViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/OneDragonFlowViewModel.cs index 5d397f1d..d05f2203 100644 --- a/BetterGenshinImpact/ViewModel/Pages/OneDragonFlowViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/OneDragonFlowViewModel.cs @@ -15,6 +15,7 @@ using BetterGenshinImpact.GameTask.Common.Element.Assets; using BetterGenshinImpact.GameTask.Model.Enum; using BetterGenshinImpact.Service; using BetterGenshinImpact.Service.Notification; +using BetterGenshinImpact.Service.Notification.Model.Enum; using BetterGenshinImpact.View.Windows; using CommunityToolkit.Mvvm.Input; using Newtonsoft.Json; @@ -208,7 +209,7 @@ public partial class OneDragonFlowViewModel : ObservableObject, INavigationAware await new TaskRunner(DispatcherTimerOperationEnum.UseSelfCaptureImage) .RunThreadAsync(async () => { - Notify.Event("dragon.start").Success("一条龙启动"); + Notify.Event(NotificationEvent.DragonStart).Success("一条龙启动"); foreach (var task in TaskList) { if (task is { IsEnabled: true, Action: not null }) @@ -217,7 +218,7 @@ public partial class OneDragonFlowViewModel : ObservableObject, INavigationAware await Task.Delay(1000); } } - Notify.Event("dragon.end").Success("一条龙结束"); + Notify.Event(NotificationEvent.DragonEnd).Success("一条龙结束"); }); } From 202ac612428459a6b389362f594918079c89650f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Tue, 4 Feb 2025 20:25:31 +0800 Subject: [PATCH 74/81] fix #1100 --- .../AutoFight/Script/CombatCommand.cs | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/BetterGenshinImpact/GameTask/AutoFight/Script/CombatCommand.cs b/BetterGenshinImpact/GameTask/AutoFight/Script/CombatCommand.cs index d503ec35..98311b8b 100644 --- a/BetterGenshinImpact/GameTask/AutoFight/Script/CombatCommand.cs +++ b/BetterGenshinImpact/GameTask/AutoFight/Script/CombatCommand.cs @@ -67,35 +67,34 @@ public class CombatCommand public void Execute(CombatScenes combatScenes) { - // 如果是当前角色 Avatar? avatar; if (Name == CombatScriptParser.CurrentAvatarName) { + // 如果是当前角色,不进行角色切换 avatar = combatScenes.Avatars[0]; // 随便取一个角色 } else { + // 其余情况要进行角色切换 avatar = combatScenes.SelectAvatar(Name); + if (avatar == null) + { + return; + } + // 非宏类脚本,等待切换角色成功 + if (Method != Method.Wait + && Method != Method.MouseDown + && Method != Method.MouseUp + && Method != Method.Click + && Method != Method.MoveBy + && Method != Method.KeyDown + && Method != Method.KeyUp + && Method != Method.KeyPress) + { + avatar.Switch(); + } } - if (avatar == null) - { - return; - } - - - // 非宏类脚本,等待切换角色成功 - if (Method != Method.Wait - && Method != Method.MouseDown - && Method != Method.MouseUp - && Method != Method.Click - && Method != Method.MoveBy - && Method != Method.KeyDown - && Method != Method.KeyUp - && Method != Method.KeyPress) - { - avatar.Switch(); - } - + Execute(avatar); } From 75449f8ced47f3903f0b180e157f79596e935dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Tue, 4 Feb 2025 20:46:14 +0800 Subject: [PATCH 75/81] pathing: auto skip config --- BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs index e979a952..15f9307a 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs @@ -1001,6 +1001,7 @@ public class PathExecutor { _autoSkipTrigger = new AutoSkipTrigger(new AutoSkipConfig { + QuicklySkipConversationsEnabled = true, // 快速点击过剧情 ClickChatOption = "优先选择最后一个选项", }); _autoSkipTrigger.Init(); From 31fcf9cedf00841ff46975d13830cf915b16e9e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Tue, 4 Feb 2025 21:06:13 +0800 Subject: [PATCH 76/81] =?UTF-8?q?fix=20WindowStartupLocation=20without=20O?= =?UTF-8?q?wner=20=E4=BF=AE=E5=A4=8D=E8=84=9A=E6=9C=AC=E8=AE=A2=E9=98=85?= =?UTF-8?q?=E5=92=8C=E9=85=8D=E7=BD=AE=E7=BB=84=E8=BF=90=E8=A1=8C=E7=9A=84?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E6=A1=86=E5=9C=A8=E9=AB=98DPI=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=B1=8F=E4=B8=8B=E8=B7=91=E5=88=B0=E5=B1=8F=E5=B9=95?= =?UTF-8?q?=E5=A4=96=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs | 8 +++++--- .../ViewModel/Pages/ScriptControlViewModel.cs | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs b/BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs index 3051c4d8..ba47d8a5 100644 --- a/BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs +++ b/BetterGenshinImpact/Core/Script/ScriptRepoUpdater.cs @@ -96,7 +96,7 @@ public class ScriptRepoUpdater : Singleton { throw new Exception("获取仓库信息失败"); } - + var (time, url, file) = ParseJson(jsonString); var updated = false; @@ -115,6 +115,7 @@ public class ScriptRepoUpdater : Singleton { needDownload = true; } + if (needDownload) { await DownloadRepoAndUnzip(string.Format(fastProxyUrl, url)); @@ -251,6 +252,7 @@ public class ScriptRepoUpdater : Singleton Content = $"检测到{(formClipboard ? "剪切板上存在" : "")}脚本订阅链接,解析后需要导入的脚本为:{pathJson}。\n是否导入并覆盖此文件或者文件夹下的脚本?", CloseButtonText = "关闭", PrimaryButtonText = "确认导入", + Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner, }; @@ -398,7 +400,7 @@ public class ScriptRepoUpdater : Singleton { // 目标文件所在文件夹不存在时创建它 Directory.CreateDirectory(Path.GetDirectoryName(destPath)!); - + if (File.Exists(destPath)) { File.Delete(destPath); @@ -495,4 +497,4 @@ public class ScriptRepoUpdater : Singleton } } } -} +} \ No newline at end of file diff --git a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs index b5160bde..51c27c24 100644 --- a/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/ScriptControlViewModel.cs @@ -1324,6 +1324,7 @@ public partial class ScriptControlViewModel : ObservableObject, INavigationAware }, CloseButtonText = "关闭", PrimaryButtonText = "确认执行", + Owner = Application.Current.MainWindow, WindowStartupLocation = WindowStartupLocation.CenterOwner, }; From eeecb5b44fb67a3e8c3c433fa40c13f2b4f887e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Tue, 4 Feb 2025 21:48:25 +0800 Subject: [PATCH 77/81] pathing: auto skip config2 --- BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs index 15f9307a..bd51cb40 100644 --- a/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs +++ b/BetterGenshinImpact/GameTask/AutoPathing/PathExecutor.cs @@ -1002,6 +1002,7 @@ public class PathExecutor _autoSkipTrigger = new AutoSkipTrigger(new AutoSkipConfig { QuicklySkipConversationsEnabled = true, // 快速点击过剧情 + ClosePopupPagedEnabled = true, ClickChatOption = "优先选择最后一个选项", }); _autoSkipTrigger.Init(); From 184d186c9c44ab9a1656201a51d3b7e37aae5b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B7=E4=B8=AA=E5=90=8D=E5=AD=97=E5=A5=BD=E9=9A=BE?= Date: Tue, 4 Feb 2025 23:10:58 +0800 Subject: [PATCH 78/81] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Notification/NotificationConfig.cs | 14 ++- .../Notification/NotificationService.cs | 5 ++ .../Service/Notifier/WorkWeixinNotifier.cs | 66 ++++++++++++++ .../View/Pages/CommonSettingsPage.xaml | 88 +++++++++++++++++++ .../Pages/CommonSettingsPageViewModel.cs | 14 +++ 5 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs diff --git a/BetterGenshinImpact/Service/Notification/NotificationConfig.cs b/BetterGenshinImpact/Service/Notification/NotificationConfig.cs index 27370298..5e88042c 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationConfig.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationConfig.cs @@ -56,5 +56,17 @@ public partial class NotificationConfig : ObservableObject private string _feishuWebhookUrl = string.Empty; - + // 企业微信通知 + /// + /// 企业微信通知是否启用 + /// + [ObservableProperty] + private bool _workweixinNotificationEnabled = false; + + + /// + /// 企业微信通知通知地址 + /// + [ObservableProperty] + private string _workweixinWebhookUrl = string.Empty; } diff --git a/BetterGenshinImpact/Service/Notification/NotificationService.cs b/BetterGenshinImpact/Service/Notification/NotificationService.cs index 8ca6c544..3d518f4f 100644 --- a/BetterGenshinImpact/Service/Notification/NotificationService.cs +++ b/BetterGenshinImpact/Service/Notification/NotificationService.cs @@ -64,6 +64,11 @@ public class NotificationService : IHostedService { _notifierManager.RegisterNotifier(new FeishuNotifier(NotifyHttpClient, TaskContext.Instance().Config.NotificationConfig.FeishuWebhookUrl)); } + + if (TaskContext.Instance().Config.NotificationConfig.WorkweixinNotificationEnabled) + { + _notifierManager.RegisterNotifier(new WorkWeixinNotifier(NotifyHttpClient, TaskContext.Instance().Config.NotificationConfig.WorkweixinWebhookUrl)); + } } public void RefreshNotifiers() diff --git a/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs b/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs new file mode 100644 index 00000000..180b27db --- /dev/null +++ b/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs @@ -0,0 +1,66 @@ +using BetterGenshinImpact.Service.Notifier.Exception; +using BetterGenshinImpact.Service.Notifier.Interface; +using System.Net.Http; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using BetterGenshinImpact.Service.Notification.Model; + +namespace BetterGenshinImpact.Service.Notifier; + +public class WorkWeixinNotifier : INotifier +{ + public string Name { get; set; } = "WorkWeixin"; + + public string Endpoint { get; set; } + + private readonly HttpClient _httpClient; + + public WorkWeixinNotifier(HttpClient httpClient, string endpoint = "") + { + _httpClient = httpClient; + Endpoint = endpoint; + } + + public async Task SendAsync(BaseNotificationData content) + { + if (string.IsNullOrEmpty(Endpoint)) + { + throw new NotifierException("WorkWeixin webhook endpoint is not set"); + } + + try + { + var response = await _httpClient.PostAsync(Endpoint, TransformData(content)); + + if (!response.IsSuccessStatusCode) + { + throw new NotifierException($"WorkWeixin webhook call failed with code: {response.StatusCode}"); + } + } + catch (NotifierException) + { + throw; + } + catch (System.Exception ex) + { + throw new NotifierException($"Error sending WorkWeixin webhook: {ex.Message}"); + } + } + + private StringContent TransformData(BaseNotificationData notificationData) + { + var workweixinMessage = new + { + msgtype = "text", + content = new + { + text = notificationData.Message + } + }; + + var serializedData = JsonSerializer.Serialize(workweixinMessage); + + return new StringContent(serializedData, Encoding.UTF8, "application/json"); + } +} \ No newline at end of file diff --git a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml index 2ecf8eec..67c6ce1b 100644 --- a/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml +++ b/BetterGenshinImpact/View/Pages/CommonSettingsPage.xaml @@ -770,6 +770,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs index 3623c55b..1f5ab887 100644 --- a/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs +++ b/BetterGenshinImpact/ViewModel/Pages/CommonSettingsPageViewModel.cs @@ -150,4 +150,18 @@ public partial class CommonSettingsPageViewModel : ObservableObject, INavigation Toast.Error(res.Message); } } + + [RelayCommand] + private async Task OnTestWorkWeixinNotification() + { + var res = await _notificationService.TestNotifierAsync(); + if(res.IsSuccess) + { + Toast.Success(res.Message); + } + else + { + Toast.Error(res.Message); + } + } } \ No newline at end of file From 8afcf9ddffa70d6170bc17139c4347f6e9540420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B7=E4=B8=AA=E5=90=8D=E5=AD=97=E5=A5=BD=E9=9A=BE?= <25520958+MisakaAldrich@users.noreply.github.com> Date: Wed, 5 Feb 2025 00:08:52 +0800 Subject: [PATCH 79/81] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs b/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs index 180b27db..65a273e0 100644 --- a/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs +++ b/BetterGenshinImpact/Service/Notifier/WorkWeixinNotifier.cs @@ -53,9 +53,9 @@ public class WorkWeixinNotifier : INotifier var workweixinMessage = new { msgtype = "text", - content = new + text = new { - text = notificationData.Message + content = notificationData.Message } }; From 7fb04270b175be3771dfae2e80e3ba3a58c50df1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 5 Feb 2025 10:30:18 +0800 Subject: [PATCH 80/81] update warning text --- BetterGenshinImpact/View/MaskWindow.xaml.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BetterGenshinImpact/View/MaskWindow.xaml.cs b/BetterGenshinImpact/View/MaskWindow.xaml.cs index e0d8b6a3..e48224fd 100644 --- a/BetterGenshinImpact/View/MaskWindow.xaml.cs +++ b/BetterGenshinImpact/View/MaskWindow.xaml.cs @@ -189,7 +189,7 @@ public partial class MaskWindow : Window { if (Process.GetProcessesByName("MSIAfterburner").Length > 0) { - _logger.LogWarning("检测到 MSI Afterburner 正在运行,如果信息位于左上角会遮盖一些图像识别要素导致识别失败,请关闭 MSI Afterburner 或者调整信息位置后重试!"); + _logger.LogWarning("检测到 MSI Afterburner 正在运行,如果信息位于特定UI上遮盖图像识别要素可能导致识别失败,请关闭MSI Afterburner 或者调整信息位置后重试!"); } } From 94638275825bda90c08dd668d6eac3b86ada493d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E9=B8=AD=E8=9B=8B?= Date: Wed, 5 Feb 2025 10:51:05 +0800 Subject: [PATCH 81/81] new banner --- BetterGenshinImpact/Assets/Images/banner.jpg | Bin 0 -> 294805 bytes .../Assets/Images/banner_sayu.jpg | Bin 138955 -> 0 bytes BetterGenshinImpact/View/Pages/HomePage.xaml | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 BetterGenshinImpact/Assets/Images/banner.jpg delete mode 100644 BetterGenshinImpact/Assets/Images/banner_sayu.jpg diff --git a/BetterGenshinImpact/Assets/Images/banner.jpg b/BetterGenshinImpact/Assets/Images/banner.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ebc13f72214e7e86718ca86d3edb7db41e8d0daf GIT binary patch literal 294805 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

>$}gkrl34C+dK>r_5DV~11ZuPg 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�^_OS)OqJZNntjr*lvA8^v@zEiI?OIpgzEN$ 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 DVfo-g diff --git a/BetterGenshinImpact/View/Pages/HomePage.xaml b/BetterGenshinImpact/View/Pages/HomePage.xaml index 441cc07c..cb605780 100644 --- a/BetterGenshinImpact/View/Pages/HomePage.xaml +++ b/BetterGenshinImpact/View/Pages/HomePage.xaml @@ -29,7 +29,7 @@ -

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