mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-04-28 22:59:45 +08:00
add lock for independent task
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ? "停止" : "启动";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user