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
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/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/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 1fa3787c..f3e9b10a 100644
--- a/BetterGenshinImpact/Service/ScriptService.cs
+++ b/BetterGenshinImpact/Service/ScriptService.cs
@@ -251,7 +251,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();
@@ -259,29 +259,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
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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -1350,12 +1350,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+