diff --git a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs
index 3b72b5c5..c1c2bf34 100644
--- a/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs
+++ b/BetterGenshinImpact/GameTask/AutoDomain/AutoDomainTask.cs
@@ -42,8 +42,6 @@ public class AutoDomainTask
private readonly AutoDomainConfig _config;
- private bool IsRunning { get; set; }
-
public AutoDomainTask(AutoDomainParam taskParam)
{
_taskParam = taskParam;
@@ -54,13 +52,20 @@ public class AutoDomainTask
_clickOffset = new ClickOffset(captureArea.X, captureArea.Y, assetScale);
_combatCommands = CombatScriptParser.Parse(_taskParam.CombatStrategyContent);
_config = TaskContext.Instance().Config.AutoDomainConfig;
- IsRunning = false;
}
public async void Start()
{
+ var hasLock = false;
try
{
+ Monitor.TryEnter(TaskContext.TaskLocker, ref hasLock);
+ if (!hasLock)
+ {
+ Logger.LogError("启动自动秘境功能失败:当前存在正在运行中的独立任务,请不要重复执行任务!");
+ return;
+ }
+
Init();
var combatScenes = new CombatScenes().InitializeTeam(GetContentFromDispatcher());
@@ -125,13 +130,16 @@ public class AutoDomainTask
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyTrigger);
TaskSettingsPageViewModel.SetSwitchAutoDomainButtonText(false);
Logger.LogInformation("→ {Text}", "自动秘境结束");
- IsRunning = false;
+
+ if (hasLock)
+ {
+ Monitor.Exit(TaskContext.TaskLocker);
+ }
}
}
private void Init()
{
- IsRunning = true;
LogScreenResolution();
if (_taskParam.DomainRoundNum == 9999)
{
@@ -374,7 +382,6 @@ public class AutoDomainTask
return false;
}
-
///
/// 旋转视角后寻找石化古树
///
@@ -665,10 +672,8 @@ public class AutoDomainTask
Sleep(800, _taskParam.Cts);
}
-
Sleep(1000, _taskParam.Cts);
-
var captureArea = TaskContext.Instance().SystemInfo.CaptureAreaRect;
for (var i = 0; i < 30; i++)
{
@@ -757,4 +762,4 @@ public class AutoDomainTask
Logger.LogInformation("剩余:浓缩树脂 {CondensedResinCount} 脆弱树脂 {FragileResinCount}", condensedResinCount, fragileResinCount);
return (condensedResinCount, fragileResinCount);
}
-}
\ No newline at end of file
+}
diff --git a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs
index 59bde555..dea23e5d 100644
--- a/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs
+++ b/BetterGenshinImpact/GameTask/AutoFight/AutoFightTask.cs
@@ -7,6 +7,7 @@ using BetterGenshinImpact.ViewModel.Pages;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
using static Vanara.PInvoke.Gdi32;
@@ -27,8 +28,16 @@ public class AutoFightTask
public async void Start()
{
+ var hasLock = false;
try
{
+ Monitor.TryEnter(TaskContext.TaskLocker, ref hasLock);
+ if (!hasLock)
+ {
+ Logger.LogError("启动自动战斗功能失败:当前存在正在运行中的独立任务,请不要重复执行任务!");
+ return;
+ }
+
Init();
var combatScenes = new CombatScenes().InitializeTeam(GetContentFromDispatcher());
if (!combatScenes.CheckTeamInitialized())
@@ -78,6 +87,11 @@ public class AutoFightTask
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyTrigger);
TaskSettingsPageViewModel.SetSwitchAutoFightButtonText(false);
Logger.LogInformation("→ {Text}", "自动战斗结束");
+
+ if (hasLock)
+ {
+ Monitor.Exit(TaskContext.TaskLocker);
+ }
}
}
@@ -98,4 +112,4 @@ public class AutoFightTask
Logger.LogWarning("游戏窗口分辨率不是 1920x1080 !当前分辨率为 {Width}x{Height} , 非 1920x1080 分辨率的游戏可能无法正常使用自动战斗功能 !", gameScreenSize.Width, gameScreenSize.Height);
}
}
-}
\ No newline at end of file
+}
diff --git a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs
index 13b50ff2..9364c457 100644
--- a/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs
+++ b/BetterGenshinImpact/GameTask/AutoGeniusInvokation/Model/Duel.cs
@@ -59,9 +59,17 @@ public class Duel
public void Run(GeniusInvokationTaskParam taskParam)
{
+ var hasLock = false;
Cts = taskParam.Cts;
try
{
+ Monitor.TryEnter(TaskContext.TaskLocker, ref hasLock);
+ if (!hasLock)
+ {
+ _logger.LogError("启动自动七圣召唤功能失败:当前存在正在运行中的独立任务,请不要重复执行任务!");
+ return;
+ }
+
LogScreenResolution();
_logger.LogInformation("========================================");
_logger.LogInformation("→ {Text}", "全自动七圣召唤,启动!");
@@ -312,6 +320,11 @@ public class Duel
TaskSettingsPageViewModel.SetSwitchAutoGeniusInvokationButtonText(false);
_logger.LogInformation("← {Text}", "退出全自动七圣召唤");
taskParam.Dispatcher.StartTimer();
+
+ if (hasLock)
+ {
+ Monitor.Exit(TaskContext.TaskLocker);
+ }
}
}
diff --git a/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs b/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs
index 99162131..4e2650db 100644
--- a/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs
+++ b/BetterGenshinImpact/GameTask/AutoWood/AutoWoodTask.cs
@@ -11,6 +11,7 @@ using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.Linq;
+using System.Threading;
using static BetterGenshinImpact.GameTask.Common.TaskControl;
using static Vanara.PInvoke.User32;
@@ -41,8 +42,16 @@ public class AutoWoodTask
public void Start(WoodTaskParam taskParam)
{
+ var hasLock = false;
try
{
+ Monitor.TryEnter(TaskContext.TaskLocker, ref hasLock);
+ if (!hasLock)
+ {
+ Logger.LogError("启动自动伐木功能失败:当前存在正在运行中的独立任务,请不要重复执行任务!");
+ return;
+ }
+
TaskTriggerDispatcher.Instance().StopTimer();
Logger.LogInformation("→ {Text} 设置伐木总次数:{Cnt}", "自动伐木,启动!", taskParam.WoodRoundNum);
@@ -97,6 +106,11 @@ public class AutoWoodTask
TaskSettingsPageViewModel.SetSwitchAutoWoodButtonText(false);
Logger.LogInformation("← {Text}", "退出自动伐木");
taskParam.Dispatcher.StartTimer();
+
+ if (hasLock)
+ {
+ Monitor.Exit(TaskContext.TaskLocker);
+ }
}
}
diff --git a/BetterGenshinImpact/GameTask/TaskContext.cs b/BetterGenshinImpact/GameTask/TaskContext.cs
index e639f680..6f6ed060 100644
--- a/BetterGenshinImpact/GameTask/TaskContext.cs
+++ b/BetterGenshinImpact/GameTask/TaskContext.cs
@@ -13,7 +13,7 @@ namespace BetterGenshinImpact.GameTask
public class TaskContext
{
private static TaskContext? _uniqueInstance;
- private static readonly object Locker = new();
+ private static readonly object InstanceLocker = new();
private TaskContext()
{
@@ -23,7 +23,7 @@ namespace BetterGenshinImpact.GameTask
{
if (_uniqueInstance == null)
{
- lock (Locker)
+ lock (InstanceLocker)
{
_uniqueInstance ??= new TaskContext();
}
@@ -41,6 +41,8 @@ namespace BetterGenshinImpact.GameTask
IsInitialized = true;
}
+ public static readonly object TaskLocker = new();
+
public bool IsInitialized { get; set; }
public IntPtr GameHandle { get; set; }
@@ -49,10 +51,8 @@ namespace BetterGenshinImpact.GameTask
public float DpiScale { get; set; }
-
public SystemInfo SystemInfo { get; set; }
-
public AllConfig Config
{
get
@@ -74,4 +74,4 @@ namespace BetterGenshinImpact.GameTask
///
public DateTime LinkedStartGenshinTime { get; set; } = DateTime.MinValue;
}
-}
\ No newline at end of file
+}
diff --git a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs
index 2e9db443..f3c389f9 100644
--- a/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs
+++ b/BetterGenshinImpact/GameTask/TaskTriggerDispatcher.cs
@@ -1,4 +1,5 @@
-using BetterGenshinImpact.GameTask.AutoDomain;
+using BetterGenshinImpact.Core.Config;
+using BetterGenshinImpact.GameTask.AutoDomain;
using BetterGenshinImpact.GameTask.AutoFight;
using BetterGenshinImpact.GameTask.AutoGeniusInvokation;
using BetterGenshinImpact.GameTask.AutoWood;
@@ -9,21 +10,18 @@ using BetterGenshinImpact.Helpers;
using BetterGenshinImpact.View;
using Fischless.GameCapture;
using Microsoft.Extensions.Logging;
+using OpenCvSharp;
+using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using BetterGenshinImpact.Core.Config;
using Vanara.PInvoke;
-using System.IO;
-using System.Drawing.Imaging;
-using OpenCvSharp;
-using OpenCvSharp.Extensions;
-using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrackBar;
-using Point = OpenCvSharp.Point;
namespace BetterGenshinImpact.GameTask
{
@@ -308,7 +306,6 @@ namespace BetterGenshinImpact.GameTask
return;
}
-
var speedTimer = new SpeedTimer();
// 捕获游戏画面
var bitmap = GameCapture.Capture();
@@ -484,4 +481,4 @@ namespace BetterGenshinImpact.GameTask
}
}
}
-}
\ No newline at end of file
+}
diff --git a/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs b/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs
index f4ddea8b..849f9280 100644
--- a/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs
+++ b/BetterGenshinImpact/ViewModel/Pages/TaskSettingsPageViewModel.cs
@@ -26,7 +26,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw
private readonly TaskTriggerDispatcher _taskDispatcher;
private CancellationTokenSource? _cts;
-
+ private static readonly object _locker = new();
[ObservableProperty] private string[] _strategyList;
[ObservableProperty] private string _switchAutoGeniusInvokationButtonText;
@@ -34,13 +34,11 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw
[ObservableProperty] private int _autoWoodRoundNum;
[ObservableProperty] private string _switchAutoWoodButtonText;
-
[ObservableProperty] private string[] _combatStrategyList;
[ObservableProperty] private int _autoDomainRoundNum;
[ObservableProperty] private string _switchAutoDomainButtonText = "启动";
[ObservableProperty] private string _switchAutoFightButtonText = "启动";
-
public TaskSettingsPageViewModel(IConfigService configService, INavigationService navigationService, TaskTriggerDispatcher taskTriggerDispatcher)
{
Config = configService.Get();
@@ -84,6 +82,7 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw
case "Combat":
CombatStrategyList = LoadCustomScript(Global.Absolute(@"User\AutoFight"));
break;
+
case "GeniusInvocation":
StrategyList = LoadCustomScript(Global.Absolute(@"User\AutoGeniusInvokation"));
break;
@@ -109,33 +108,36 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw
{
try
{
- if (SwitchAutoGeniusInvokationButtonText == "启动")
+ lock (_locker)
{
- if (string.IsNullOrEmpty(Config.AutoGeniusInvokationConfig.StrategyName))
+ if (SwitchAutoGeniusInvokationButtonText == "启动")
{
- MessageBox.Show("请先选择策略");
- return;
+ if (string.IsNullOrEmpty(Config.AutoGeniusInvokationConfig.StrategyName))
+ {
+ MessageBox.Show("请先选择策略");
+ return;
+ }
+
+ var path = Global.Absolute(@"User\AutoGeniusInvokation\" + Config.AutoGeniusInvokationConfig.StrategyName + ".txt");
+
+ if (!File.Exists(path))
+ {
+ MessageBox.Show("策略文件不存在");
+ return;
+ }
+
+ var content = File.ReadAllText(path);
+ _cts?.Cancel();
+ _cts = new CancellationTokenSource();
+ var param = new GeniusInvokationTaskParam(_cts, _taskDispatcher, content);
+ _taskDispatcher.StartIndependentTask(IndependentTaskEnum.AutoGeniusInvokation, param);
+ SwitchAutoGeniusInvokationButtonText = "停止";
}
-
- var path = Global.Absolute(@"User\AutoGeniusInvokation\" + Config.AutoGeniusInvokationConfig.StrategyName + ".txt");
-
- if (!File.Exists(path))
+ else
{
- MessageBox.Show("策略文件不存在");
- return;
+ _cts?.Cancel();
+ SwitchAutoGeniusInvokationButtonText = "启动";
}
-
- var content = File.ReadAllText(path);
- _cts?.Cancel();
- _cts = new CancellationTokenSource();
- var param = new GeniusInvokationTaskParam(_cts, _taskDispatcher, content);
- _taskDispatcher.StartIndependentTask(IndependentTaskEnum.AutoGeniusInvokation, param);
- SwitchAutoGeniusInvokationButtonText = "停止";
- }
- else
- {
- _cts?.Cancel();
- SwitchAutoGeniusInvokationButtonText = "启动";
}
}
catch (System.Exception ex)
@@ -155,18 +157,21 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw
{
try
{
- if (SwitchAutoWoodButtonText == "启动")
+ lock (_locker)
{
- _cts?.Cancel();
- _cts = new CancellationTokenSource();
- var param = new WoodTaskParam(_cts, _taskDispatcher, AutoWoodRoundNum);
- _taskDispatcher.StartIndependentTask(IndependentTaskEnum.AutoWood, param);
- SwitchAutoWoodButtonText = "停止";
- }
- else
- {
- _cts?.Cancel();
- SwitchAutoWoodButtonText = "启动";
+ if (SwitchAutoWoodButtonText == "启动")
+ {
+ _cts?.Cancel();
+ _cts = new CancellationTokenSource();
+ var param = new WoodTaskParam(_cts, _taskDispatcher, AutoWoodRoundNum);
+ _taskDispatcher.StartIndependentTask(IndependentTaskEnum.AutoWood, param);
+ SwitchAutoWoodButtonText = "停止";
+ }
+ else
+ {
+ _cts?.Cancel();
+ SwitchAutoWoodButtonText = "启动";
+ }
}
}
catch (System.Exception ex)
@@ -181,30 +186,32 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw
Process.Start(new ProcessStartInfo("https://bgi.huiyadan.com/doc.html#%E8%87%AA%E5%8A%A8%E4%BC%90%E6%9C%A8") { UseShellExecute = true });
}
-
[RelayCommand]
public void OnSwitchAutoFight()
{
try
{
- if (SwitchAutoFightButtonText == "启动")
+ lock (_locker)
{
- var content = ReadFightStrategy(Config.AutoFightConfig.StrategyName);
- if (string.IsNullOrEmpty(content))
+ if (SwitchAutoFightButtonText == "启动")
{
- return;
- }
+ var content = ReadFightStrategy(Config.AutoFightConfig.StrategyName);
+ if (string.IsNullOrEmpty(content))
+ {
+ return;
+ }
- _cts?.Cancel();
- _cts = new CancellationTokenSource();
- var param = new AutoFightParam(_cts, content);
- _taskDispatcher.StartIndependentTask(IndependentTaskEnum.AutoFight, param);
- SwitchAutoFightButtonText = "停止";
- }
- else
- {
- _cts?.Cancel();
- SwitchAutoFightButtonText = "启动";
+ _cts?.Cancel();
+ _cts = new CancellationTokenSource();
+ var param = new AutoFightParam(_cts, content);
+ _taskDispatcher.StartIndependentTask(IndependentTaskEnum.AutoFight, param);
+ SwitchAutoFightButtonText = "停止";
+ }
+ else
+ {
+ _cts?.Cancel();
+ SwitchAutoFightButtonText = "启动";
+ }
}
}
catch (System.Exception ex)
@@ -244,24 +251,27 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw
{
try
{
- if (SwitchAutoDomainButtonText == "启动")
+ lock (_locker)
{
- var content = ReadFightStrategy(Config.AutoFightConfig.StrategyName);
- if (string.IsNullOrEmpty(content))
+ if (SwitchAutoDomainButtonText == "启动")
{
- return;
- }
+ var content = ReadFightStrategy(Config.AutoFightConfig.StrategyName);
+ if (string.IsNullOrEmpty(content))
+ {
+ return;
+ }
- _cts?.Cancel();
- _cts = new CancellationTokenSource();
- var param = new AutoDomainParam(_cts, AutoDomainRoundNum, content);
- _taskDispatcher.StartIndependentTask(IndependentTaskEnum.AutoDomain, param);
- SwitchAutoDomainButtonText = "停止";
- }
- else
- {
- _cts?.Cancel();
- SwitchAutoDomainButtonText = "启动";
+ _cts?.Cancel();
+ _cts = new CancellationTokenSource();
+ var param = new AutoDomainParam(_cts, AutoDomainRoundNum, content);
+ _taskDispatcher.StartIndependentTask(IndependentTaskEnum.AutoDomain, param);
+ SwitchAutoDomainButtonText = "停止";
+ }
+ else
+ {
+ _cts?.Cancel();
+ SwitchAutoDomainButtonText = "启动";
+ }
}
}
catch (System.Exception ex)
@@ -276,7 +286,6 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw
Process.Start(new ProcessStartInfo("https://bgi.huiyadan.com/feats/domain.html") { UseShellExecute = true });
}
-
public static void SetSwitchAutoGeniusInvokationButtonText(bool running)
{
var instance = App.GetService();
@@ -320,4 +329,4 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw
instance.SwitchAutoFightButtonText = running ? "停止" : "启动";
}
-}
\ No newline at end of file
+}