add lock for independent task

This commit is contained in:
辉鸭蛋
2024-03-16 15:20:01 +08:00
parent 62492b3f95
commit 037d4dadff
7 changed files with 146 additions and 94 deletions

View File

@@ -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;
}
/// <summary>
/// 旋转视角后寻找石化古树
/// </summary>
@@ -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);
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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
/// </summary>
public DateTime LinkedStartGenshinTime { get; set; } = DateTime.MinValue;
}
}
}

View File

@@ -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
}
}
}
}
}

View File

@@ -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<TaskSettingsPageViewModel>();
@@ -320,4 +329,4 @@ public partial class TaskSettingsPageViewModel : ObservableObject, INavigationAw
instance.SwitchAutoFightButtonText = running ? "停止" : "启动";
}
}
}