mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-21 09:45:48 +08:00
清除所有 DispatcherTimerOperationEnum 内容
This commit is contained in:
@@ -51,13 +51,13 @@ public partial class AllConfig : ObservableObject
|
||||
[ObservableProperty]
|
||||
private int _triggerInterval = 50;
|
||||
|
||||
/// <summary>
|
||||
/// WGC使用位图缓存
|
||||
/// 高帧率情况下,可能会导致卡顿
|
||||
/// 云原神可能会出现黑屏
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _wgcUseBitmapCache = true;
|
||||
// /// <summary>
|
||||
// /// WGC使用位图缓存
|
||||
// /// 高帧率情况下,可能会导致卡顿
|
||||
// /// 云原神可能会出现黑屏
|
||||
// /// </summary>
|
||||
// [ObservableProperty]
|
||||
// private bool _wgcUseBitmapCache = true;
|
||||
|
||||
/// <summary>
|
||||
/// 自动修复Win11下BitBlt截图方式不可用的问题
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace BetterGenshinImpact.GameTask.AutoFishing
|
||||
break;
|
||||
}
|
||||
|
||||
using var bitmap = TaskControl.CaptureGameBitmapNoRetry(TaskTriggerDispatcher.Instance().GameCapture);
|
||||
using var bitmap = TaskControl.CaptureGameImageNoRetry(TaskTriggerDispatcher.Instance().GameCapture);
|
||||
if (bitmap == null)
|
||||
{
|
||||
_logger.LogWarning("截图失败");
|
||||
|
||||
@@ -19,13 +19,13 @@ public class CaptureContent : IDisposable
|
||||
|
||||
public ImageRegion CaptureRectArea { get; private set; }
|
||||
|
||||
public CaptureContent(Mat srcBitmap, int frameIndex, double interval)
|
||||
public CaptureContent(Mat image, int frameIndex, double interval)
|
||||
{
|
||||
FrameIndex = frameIndex;
|
||||
TimerInterval = interval;
|
||||
var systemInfo = TaskContext.Instance().SystemInfo;
|
||||
|
||||
var gameCaptureRegion = systemInfo.DesktopRectArea.Derive(srcBitmap, systemInfo.CaptureAreaRect.X, systemInfo.CaptureAreaRect.Y);
|
||||
var gameCaptureRegion = systemInfo.DesktopRectArea.Derive(image, systemInfo.CaptureAreaRect.X, systemInfo.CaptureAreaRect.Y);
|
||||
CaptureRectArea = gameCaptureRegion.DeriveTo1080P();
|
||||
}
|
||||
|
||||
@@ -42,4 +42,4 @@ public class CaptureContent : IDisposable
|
||||
{
|
||||
CaptureRectArea.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,6 @@ public class TaskControl
|
||||
public static ILogger Logger { get; } = App.GetLogger<TaskControl>();
|
||||
|
||||
public static readonly SemaphoreSlim TaskSemaphore = new(1, 1);
|
||||
|
||||
|
||||
|
||||
|
||||
public static void CheckAndSleep(int millisecondsTimeout)
|
||||
@@ -178,29 +176,19 @@ public class TaskControl
|
||||
}
|
||||
}
|
||||
|
||||
public static Mat CaptureGameBitmap(IGameCapture? gameCapture)
|
||||
public static Mat CaptureGameImage(IGameCapture? gameCapture)
|
||||
{
|
||||
var bitmap = gameCapture?.Capture();
|
||||
// wgc 缓冲区设置的2 所以至少截图3次
|
||||
if (gameCapture?.Mode == CaptureModes.WindowsGraphicsCapture)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
bitmap = gameCapture?.Capture();
|
||||
Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
if (bitmap == null)
|
||||
var image = gameCapture?.Capture();
|
||||
if (image == null)
|
||||
{
|
||||
Logger.LogWarning("截图失败!");
|
||||
// 重试5次
|
||||
for (var i = 0; i < 5; i++)
|
||||
// 重试3次
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
bitmap = gameCapture?.Capture();
|
||||
if (bitmap != null)
|
||||
image = gameCapture?.Capture();
|
||||
if (image != null)
|
||||
{
|
||||
return bitmap;
|
||||
return image;
|
||||
}
|
||||
|
||||
Sleep(30);
|
||||
@@ -210,56 +198,23 @@ public class TaskControl
|
||||
}
|
||||
else
|
||||
{
|
||||
return bitmap;
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
public static Mat? CaptureGameBitmapNoRetry(IGameCapture? gameCapture)
|
||||
public static Mat? CaptureGameImageNoRetry(IGameCapture? gameCapture)
|
||||
{
|
||||
return gameCapture?.Capture();
|
||||
}
|
||||
|
||||
// private static CaptureContent CaptureToContent(IGameCapture? gameCapture)
|
||||
// {
|
||||
// var bitmap = CaptureGameBitmap(gameCapture);
|
||||
// return new CaptureContent(bitmap, 0, 0);
|
||||
// }
|
||||
//
|
||||
// public static CaptureContent CaptureToContent()
|
||||
// {
|
||||
// return CaptureToContent(TaskTriggerDispatcher.GlobalGameCapture);
|
||||
// }
|
||||
|
||||
// public static ImageRegion CaptureToRectArea()
|
||||
// {
|
||||
// return CaptureToContent(TaskTriggerDispatcher.GlobalGameCapture).CaptureRectArea;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 此方法 TaskDispatcher至少处于 DispatcherCaptureModeEnum.CacheCaptureWithTrigger 状态才能使用
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// [Obsolete]
|
||||
// public static CaptureContent GetContentFromDispatcher()
|
||||
// {
|
||||
// return TaskTriggerDispatcher.Instance().GetLastCaptureContent();
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 此方法 TaskDispatcher至少处于 DispatcherCaptureModeEnum.CacheCaptureWithTrigger 状态才能使用
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// public static ImageRegion GetRectAreaFromDispatcher()
|
||||
// {
|
||||
// return TaskTriggerDispatcher.Instance().GetLastCaptureContent().CaptureRectArea;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 自动判断当前运行上下文中截图方式,并选择合适的截图方式返回
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static ImageRegion CaptureToRectArea(bool forceNew = false)
|
||||
{
|
||||
return TaskTriggerDispatcher.Instance().CaptureToRectArea(forceNew);
|
||||
var image =CaptureGameImage(TaskTriggerDispatcher.GlobalGameCapture);
|
||||
var content = new CaptureContent(image, 0, 0);
|
||||
return content.CaptureRectArea;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
namespace BetterGenshinImpact.GameTask.Model.Enum;
|
||||
|
||||
/// <summary>
|
||||
/// 存在触发器运行的情况下,优先使用触发器的缓存图像
|
||||
/// 此枚举会影响调度器使用的 DispatcherCaptureModeEnum 模式
|
||||
/// </summary>
|
||||
public enum DispatcherTimerOperationEnum
|
||||
{
|
||||
// 关闭实时触发器,自己主动获取图像
|
||||
UseSelfCaptureImage,
|
||||
|
||||
// 使用实时触发器的缓存图模式,但是不执行触发器
|
||||
UseCacheImage,
|
||||
|
||||
// 使用实时触发器的缓存图模式,并执行触发器
|
||||
UseCacheImageWithTrigger,
|
||||
|
||||
// 使用实时触发器的缓存图模式,并清空当前已有触发器,执行触发器
|
||||
// 清空触发器是为了让js脚本手动添加触发器
|
||||
UseCacheImageWithTriggerEmpty,
|
||||
|
||||
// 不做任何操作
|
||||
None
|
||||
}
|
||||
// namespace BetterGenshinImpact.GameTask.Model.Enum;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 存在触发器运行的情况下,优先使用触发器的缓存图像
|
||||
// /// 此枚举会影响调度器使用的 DispatcherCaptureModeEnum 模式
|
||||
// /// </summary>
|
||||
// public enum DispatcherTimerOperationEnum
|
||||
// {
|
||||
// // 关闭实时触发器,自己主动获取图像
|
||||
// UseSelfCaptureImage,
|
||||
//
|
||||
// // 使用实时触发器的缓存图模式,但是不执行触发器
|
||||
// UseCacheImage,
|
||||
//
|
||||
// // 使用实时触发器的缓存图模式,并执行触发器
|
||||
// UseCacheImageWithTrigger,
|
||||
//
|
||||
// // 使用实时触发器的缓存图模式,并清空当前已有触发器,执行触发器
|
||||
// // 清空触发器是为了让js脚本手动添加触发器
|
||||
// UseCacheImageWithTriggerEmpty,
|
||||
//
|
||||
// // 不做任何操作
|
||||
// None
|
||||
// }
|
||||
|
||||
@@ -23,7 +23,7 @@ public class TaskRunner
|
||||
{
|
||||
private readonly ILogger<TaskRunner> _logger = App.GetLogger<TaskRunner>();
|
||||
|
||||
private readonly DispatcherTimerOperationEnum _timerOperation = DispatcherTimerOperationEnum.None;
|
||||
// private readonly DispatcherTimerOperationEnum _timerOperation = DispatcherTimerOperationEnum.None;
|
||||
|
||||
private readonly string _name = string.Empty;
|
||||
|
||||
@@ -31,11 +31,11 @@ public class TaskRunner
|
||||
{
|
||||
}
|
||||
|
||||
public TaskRunner(DispatcherTimerOperationEnum timerOperation)
|
||||
{
|
||||
_timerOperation = timerOperation;
|
||||
}
|
||||
|
||||
// public TaskRunner(DispatcherTimerOperationEnum timerOperation)
|
||||
// {
|
||||
// _timerOperation = timerOperation;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 加锁并独立运行任务
|
||||
/// </summary>
|
||||
@@ -134,27 +134,27 @@ public class TaskRunner
|
||||
var maskWindow = MaskWindow.Instance();
|
||||
SystemControl.ActivateWindow();
|
||||
maskWindow.Invoke(maskWindow.Show);
|
||||
if (_timerOperation == DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
{
|
||||
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待日志窗口被激活
|
||||
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.Stop);
|
||||
}
|
||||
else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImage)
|
||||
{
|
||||
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture);
|
||||
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
|
||||
}
|
||||
else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTrigger)
|
||||
{
|
||||
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
|
||||
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
|
||||
}
|
||||
else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
|
||||
{
|
||||
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
|
||||
TaskTriggerDispatcher.Instance().ClearTriggers();
|
||||
Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
|
||||
}
|
||||
// if (_timerOperation == DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
// {
|
||||
// Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待日志窗口被激活
|
||||
// TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.Stop);
|
||||
// }
|
||||
// else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImage)
|
||||
// {
|
||||
// TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.OnlyCacheCapture);
|
||||
// Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
|
||||
// }
|
||||
// else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTrigger)
|
||||
// {
|
||||
// TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
|
||||
// Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
|
||||
// }
|
||||
// else if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
|
||||
// {
|
||||
// TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
|
||||
// TaskTriggerDispatcher.Instance().ClearTriggers();
|
||||
// Thread.Sleep(TaskContext.Instance().Config.TriggerInterval * 5); // 等待缓存图像
|
||||
// }
|
||||
}
|
||||
|
||||
public void End()
|
||||
@@ -165,27 +165,27 @@ public class TaskRunner
|
||||
}
|
||||
|
||||
VisionContext.Instance().DrawContent.ClearAll();
|
||||
if (_timerOperation == DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
{
|
||||
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.Start);
|
||||
}
|
||||
else if (_timerOperation is DispatcherTimerOperationEnum.UseCacheImage or DispatcherTimerOperationEnum.UseCacheImageWithTrigger or DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
|
||||
{
|
||||
// 还原到原来的模式
|
||||
if (TaskContext.Instance().Config.CommonConfig.ScreenshotEnabled || TaskContext.Instance().Config.MacroConfig.CombatMacroEnabled)
|
||||
{
|
||||
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.NormalTrigger);
|
||||
}
|
||||
|
||||
if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
|
||||
{
|
||||
TaskTriggerDispatcher.Instance().SetTriggers(GameTaskManager.LoadInitialTriggers());
|
||||
}
|
||||
}
|
||||
// if (_timerOperation == DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
// {
|
||||
// TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.Start);
|
||||
// }
|
||||
// else if (_timerOperation is DispatcherTimerOperationEnum.UseCacheImage or DispatcherTimerOperationEnum.UseCacheImageWithTrigger or DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
|
||||
// {
|
||||
// // 还原到原来的模式
|
||||
// if (TaskContext.Instance().Config.CommonConfig.ScreenshotEnabled || TaskContext.Instance().Config.MacroConfig.CombatMacroEnabled)
|
||||
// {
|
||||
// TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.CacheCaptureWithTrigger);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// TaskTriggerDispatcher.Instance().SetCacheCaptureMode(DispatcherCaptureModeEnum.NormalTrigger);
|
||||
// }
|
||||
//
|
||||
// if (_timerOperation == DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty)
|
||||
// {
|
||||
// TaskTriggerDispatcher.Instance().SetTriggers(GameTaskManager.LoadInitialTriggers());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,31 +1,17 @@
|
||||
using BetterGenshinImpact.Core.Config;
|
||||
using BetterGenshinImpact.GameTask.AutoDomain;
|
||||
using BetterGenshinImpact.GameTask.AutoFight;
|
||||
using BetterGenshinImpact.GameTask.AutoGeniusInvokation;
|
||||
using BetterGenshinImpact.GameTask.AutoMusicGame;
|
||||
using BetterGenshinImpact.GameTask.AutoSkip;
|
||||
using BetterGenshinImpact.GameTask.AutoSkip.Model;
|
||||
using BetterGenshinImpact.GameTask.AutoTrackPath;
|
||||
using BetterGenshinImpact.GameTask.AutoWood;
|
||||
using BetterGenshinImpact.GameTask.Common;
|
||||
using BetterGenshinImpact.GameTask.Model;
|
||||
using BetterGenshinImpact.GameTask.Model.Area;
|
||||
using BetterGenshinImpact.GameTask.Model.Enum;
|
||||
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 Vanara.PInvoke;
|
||||
|
||||
namespace BetterGenshinImpact.GameTask
|
||||
@@ -49,11 +35,6 @@ namespace BetterGenshinImpact.GameTask
|
||||
|
||||
private DateTime _prevManualGc = DateTime.MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// 捕获结果队列
|
||||
/// </summary>
|
||||
private Bitmap _bitmap = new(10, 10);
|
||||
|
||||
/// <summary>
|
||||
/// 调度器捕获模式, 影响以下内容:
|
||||
/// 1. 是否缓存图像
|
||||
@@ -61,7 +42,6 @@ namespace BetterGenshinImpact.GameTask
|
||||
/// </summary>
|
||||
private DispatcherCaptureModeEnum _dispatcherCacheCaptureMode = DispatcherCaptureModeEnum.NormalTrigger;
|
||||
|
||||
private static readonly object _bitmapLocker = new();
|
||||
private static readonly object _triggerListLocker = new();
|
||||
|
||||
public event EventHandler? UiTaskStopTickEvent;
|
||||
@@ -143,7 +123,6 @@ namespace BetterGenshinImpact.GameTask
|
||||
GameCapture.Start(hWnd,
|
||||
new Dictionary<string, object>()
|
||||
{
|
||||
{ "useBitmapCache", TaskContext.Instance().Config.WgcUseBitmapCache },
|
||||
{ "autoFixWin11BitBlt", OsVersionHelper.IsWindows11_OrGreater && TaskContext.Instance().Config.AutoFixWin11BitBlt }
|
||||
}
|
||||
);
|
||||
@@ -187,11 +166,6 @@ namespace BetterGenshinImpact.GameTask
|
||||
}
|
||||
}
|
||||
|
||||
public System.Timers.Timer GetTimer()
|
||||
{
|
||||
return _timer;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stop();
|
||||
@@ -305,10 +279,9 @@ namespace BetterGenshinImpact.GameTask
|
||||
// 帧序号自增 1分钟后归零(MaxFrameIndexSecond)
|
||||
_frameIndex = (_frameIndex + 1) % (int)(CaptureContent.MaxFrameIndexSecond * 1000d / _timer.Interval);
|
||||
|
||||
if (_dispatcherCacheCaptureMode == DispatcherCaptureModeEnum.NormalTrigger
|
||||
&& (_triggers == null || !_triggers.Exists(t => t.IsEnabled)))
|
||||
if (_triggers == null || !_triggers.Exists(t => t.IsEnabled))
|
||||
{
|
||||
// Debug.WriteLine("没有可用的触发器且不处于仅截屏状态, 不再进行截屏");
|
||||
Debug.WriteLine("没有可用的触发器且不处于仅截屏状态, 不再进行截屏");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -323,11 +296,6 @@ namespace BetterGenshinImpact.GameTask
|
||||
return;
|
||||
}
|
||||
|
||||
// if (IsOnlyCacheCapture(bitmap))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// 循环执行所有触发器 有独占状态的触发器的时候只执行独占触发器
|
||||
var content = new CaptureContent(bitmap, _frameIndex, _timer.Interval);
|
||||
|
||||
@@ -410,43 +378,21 @@ namespace BetterGenshinImpact.GameTask
|
||||
{
|
||||
return rect.Width == 0 || rect.Height == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否仅缓存截图
|
||||
/// </summary>
|
||||
/// <param name="bitmap"></param>
|
||||
/// <returns></returns>
|
||||
private bool IsOnlyCacheCapture(Bitmap bitmap)
|
||||
{
|
||||
lock (_bitmapLocker)
|
||||
{
|
||||
if (_dispatcherCacheCaptureMode is DispatcherCaptureModeEnum.OnlyCacheCapture or DispatcherCaptureModeEnum.CacheCaptureWithTrigger)
|
||||
{
|
||||
_bitmap = new Bitmap(bitmap);
|
||||
if (_dispatcherCacheCaptureMode == DispatcherCaptureModeEnum.OnlyCacheCapture)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetCacheCaptureMode(DispatcherCaptureModeEnum mode)
|
||||
{
|
||||
if (mode is DispatcherCaptureModeEnum.Start)
|
||||
{
|
||||
this.StartTimer();
|
||||
}
|
||||
else if (mode is DispatcherCaptureModeEnum.Stop)
|
||||
{
|
||||
this.StopTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
_dispatcherCacheCaptureMode = mode;
|
||||
}
|
||||
// if (mode is DispatcherCaptureModeEnum.Start)
|
||||
// {
|
||||
// this.StartTimer();
|
||||
// }
|
||||
// else if (mode is DispatcherCaptureModeEnum.Stop)
|
||||
// {
|
||||
// this.StopTimer();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _dispatcherCacheCaptureMode = mode;
|
||||
// }
|
||||
}
|
||||
|
||||
public DispatcherCaptureModeEnum GetCacheCaptureMode()
|
||||
@@ -454,73 +400,37 @@ namespace BetterGenshinImpact.GameTask
|
||||
return _dispatcherCacheCaptureMode;
|
||||
}
|
||||
|
||||
// public Bitmap GetLastCaptureBitmap()
|
||||
// {
|
||||
// lock (_bitmapLocker)
|
||||
// {
|
||||
// return new Bitmap(_bitmap);
|
||||
// }
|
||||
// }
|
||||
|
||||
public CaptureContent GetLastCaptureContent()
|
||||
{
|
||||
var bitmap = TaskControl.CaptureGameBitmap(GameCapture);
|
||||
return new CaptureContent(bitmap, _frameIndex, _timer.Interval);
|
||||
}
|
||||
|
||||
public ImageRegion CaptureToRectArea(bool forceNew = false)
|
||||
{
|
||||
// 触发器启动的情况下优先使用触发器的截图
|
||||
if (!forceNew && _timer.Enabled && _dispatcherCacheCaptureMode is DispatcherCaptureModeEnum.OnlyCacheCapture or DispatcherCaptureModeEnum.CacheCaptureWithTrigger)
|
||||
{
|
||||
return GetLastCaptureContent().CaptureRectArea;
|
||||
}
|
||||
else
|
||||
{
|
||||
var bitmap = TaskControl.CaptureGameBitmap(GameCapture);
|
||||
var content = new CaptureContent(bitmap, 0, 0);
|
||||
return content.CaptureRectArea;
|
||||
}
|
||||
}
|
||||
|
||||
public void TakeScreenshot()
|
||||
{
|
||||
if (_dispatcherCacheCaptureMode is DispatcherCaptureModeEnum.OnlyCacheCapture or DispatcherCaptureModeEnum.CacheCaptureWithTrigger)
|
||||
try
|
||||
{
|
||||
try
|
||||
var path = Global.Absolute($@"log\screenshot\");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
var path = Global.Absolute($@"log\screenshot\");
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
var bitmap = TaskControl.CaptureGameBitmap(GameCapture);
|
||||
var name = $@"{DateTime.Now:yyyyMMddHHmmssffff}.png";
|
||||
var savePath = Global.Absolute($@"log\screenshot\{name}");
|
||||
|
||||
if (TaskContext.Instance().Config.CommonConfig.ScreenshotUidCoverEnabled)
|
||||
{
|
||||
var rect = TaskContext.Instance().Config.MaskWindowConfig.UidCoverRect;
|
||||
bitmap.Rectangle(rect, Scalar.White, -1);
|
||||
Cv2.ImWrite(savePath, bitmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cv2.ImWrite(savePath, bitmap);
|
||||
}
|
||||
|
||||
_logger.LogInformation("截图已保存: {Name}", name);
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
var bitmap = TaskControl.CaptureGameImage(GameCapture);
|
||||
var name = $@"{DateTime.Now:yyyyMMddHHmmssffff}.png";
|
||||
var savePath = Global.Absolute($@"log\screenshot\{name}");
|
||||
|
||||
if (TaskContext.Instance().Config.CommonConfig.ScreenshotUidCoverEnabled)
|
||||
{
|
||||
_logger.LogError("截图保存失败: {Message}", e.Message);
|
||||
_logger.LogDebug("截图保存失败: {StackTrace}", e.StackTrace);
|
||||
var rect = TaskContext.Instance().Config.MaskWindowConfig.UidCoverRect;
|
||||
bitmap.Rectangle(rect, Scalar.White, -1);
|
||||
Cv2.ImWrite(savePath, bitmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cv2.ImWrite(savePath, bitmap);
|
||||
}
|
||||
|
||||
_logger.LogInformation("截图已保存: {Name}", name);
|
||||
}
|
||||
else
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogWarning("当前不处于截图模式,无法保存截图");
|
||||
_logger.LogError("截图保存失败: {Message}", e.Message);
|
||||
_logger.LogDebug("截图保存失败: {StackTrace}", e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ public class NotificationService : IHostedService
|
||||
{
|
||||
if (TaskContext.Instance().Config.NotificationConfig.IncludeScreenShot)
|
||||
{
|
||||
var bitmap = TaskControl.CaptureGameBitmapNoRetry(TaskTriggerDispatcher.GlobalGameCapture);
|
||||
var bitmap = TaskControl.CaptureGameImageNoRetry(TaskTriggerDispatcher.GlobalGameCapture);
|
||||
if (bitmap != null)
|
||||
{
|
||||
notificationData.Screenshot = bitmap.ToBitmap();
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace BetterGenshinImpact.Service;
|
||||
public partial class ScriptService : IScriptService
|
||||
{
|
||||
private readonly ILogger<ScriptService> _logger = App.GetLogger<ScriptService>();
|
||||
|
||||
private static bool IsCurrentHourEqual(string input)
|
||||
{
|
||||
// 尝试将输入字符串转换为整数
|
||||
@@ -41,52 +42,51 @@ public partial class ScriptService : IScriptService
|
||||
// 如果输入非数字或不合法,返回 false
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task RunMulti(IEnumerable<ScriptGroupProject> projectList, string? groupName = null)
|
||||
{
|
||||
groupName ??= "默认";
|
||||
|
||||
var hasTimer = false;
|
||||
var list = ReloadScriptProjects(projectList, ref hasTimer);
|
||||
var list = ReloadScriptProjects(projectList);
|
||||
|
||||
// 针对JS 脚本,检查是否包含定时器操作
|
||||
var jsProjects = ExtractJsProjects(list);
|
||||
if (!hasTimer && jsProjects.Count > 0)
|
||||
{
|
||||
var codeList = await ReadCodeList(jsProjects);
|
||||
hasTimer = HasTimerOperation(codeList);
|
||||
}
|
||||
// // 针对JS 脚本,检查是否包含定时器操作
|
||||
// var jsProjects = ExtractJsProjects(list);
|
||||
// if (!hasTimer && jsProjects.Count > 0)
|
||||
// {
|
||||
// var codeList = await ReadCodeList(jsProjects);
|
||||
// hasTimer = HasTimerOperation(codeList);
|
||||
// }
|
||||
|
||||
// 没启动时候,启动截图器
|
||||
await StartGameTask();
|
||||
|
||||
if (!string.IsNullOrEmpty(groupName))
|
||||
{
|
||||
if (hasTimer)
|
||||
{
|
||||
_logger.LogInformation("配置组 {Name} 包含实时任务操作调用", groupName);
|
||||
}
|
||||
// if (hasTimer)
|
||||
// {
|
||||
// _logger.LogInformation("配置组 {Name} 包含实时任务操作调用", groupName);
|
||||
// }
|
||||
|
||||
_logger.LogInformation("配置组 {Name} 加载完成,共{Cnt}个脚本,开始执行", groupName, list.Count);
|
||||
}
|
||||
|
||||
var timerOperation = hasTimer ? DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty : DispatcherTimerOperationEnum.UseSelfCaptureImage;
|
||||
|
||||
// var timerOperation = hasTimer ? DispatcherTimerOperationEnum.UseCacheImageWithTriggerEmpty : DispatcherTimerOperationEnum.UseSelfCaptureImage;
|
||||
|
||||
Notify.Event(NotificationEvent.GroupStart).Success($"配置组{groupName}启动");
|
||||
|
||||
await new TaskRunner(timerOperation)
|
||||
|
||||
await new TaskRunner()
|
||||
.RunThreadAsync(async () =>
|
||||
{
|
||||
var stopwatch = new Stopwatch();
|
||||
|
||||
foreach (var project in list)
|
||||
{
|
||||
|
||||
if (project.GroupInfo is { Config.PathingConfig.Enabled: true } && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring))
|
||||
{
|
||||
_logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (project.Status != "Enabled")
|
||||
{
|
||||
_logger.LogInformation("脚本 {Name} 状态为禁用,跳过执行", project.Name);
|
||||
@@ -103,24 +103,21 @@ public partial class ScriptService : IScriptService
|
||||
{
|
||||
try
|
||||
{
|
||||
if (hasTimer)
|
||||
{
|
||||
TaskTriggerDispatcher.Instance().ClearTriggers();
|
||||
}
|
||||
TaskTriggerDispatcher.Instance().ClearTriggers();
|
||||
|
||||
|
||||
_logger.LogInformation("------------------------------");
|
||||
|
||||
stopwatch.Reset();
|
||||
stopwatch.Start();
|
||||
await ExecuteProject(project);
|
||||
|
||||
|
||||
//多次执行时及时中断
|
||||
if (project.GroupInfo is { Config.PathingConfig.Enabled: true } && IsCurrentHourEqual(project.GroupInfo.Config.PathingConfig.SkipDuring))
|
||||
{
|
||||
_logger.LogInformation($"{project.Name}任务已到禁止执行时段,将跳过!");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
catch (NormalEndException e)
|
||||
{
|
||||
@@ -144,7 +141,6 @@ public partial class ScriptService : IScriptService
|
||||
_logger.LogInformation("→ 脚本执行结束: {Name}, 耗时: {Minutes}分{Seconds:0.000}秒", project.Name,
|
||||
elapsedTime.Hours * 60 + elapsedTime.Minutes, elapsedTime.TotalSeconds % 60);
|
||||
_logger.LogInformation("------------------------------");
|
||||
|
||||
}
|
||||
|
||||
await Task.Delay(2000);
|
||||
@@ -152,14 +148,18 @@ public partial class ScriptService : IScriptService
|
||||
}
|
||||
});
|
||||
|
||||
// 还原定时器
|
||||
TaskTriggerDispatcher.Instance().SetTriggers(GameTaskManager.LoadInitialTriggers());
|
||||
|
||||
if (!string.IsNullOrEmpty(groupName))
|
||||
{
|
||||
_logger.LogInformation("配置组 {Name} 执行结束", groupName);
|
||||
}
|
||||
|
||||
Notify.Event(NotificationEvent.GroupEnd).Success($"配置组{groupName}结束");
|
||||
}
|
||||
|
||||
private List<ScriptGroupProject> ReloadScriptProjects(IEnumerable<ScriptGroupProject> projectList, ref bool hasTimer)
|
||||
private List<ScriptGroupProject> ReloadScriptProjects(IEnumerable<ScriptGroupProject> projectList)
|
||||
{
|
||||
var list = new List<ScriptGroupProject>();
|
||||
foreach (var project in projectList)
|
||||
@@ -181,14 +181,14 @@ public partial class ScriptService : IScriptService
|
||||
var newProject = ScriptGroupProject.BuildPathingProject(project.Name, project.FolderName);
|
||||
CopyProjectProperties(project, newProject);
|
||||
list.Add(newProject);
|
||||
hasTimer = true;
|
||||
// hasTimer = true;
|
||||
}
|
||||
else if (project.Type == "Shell")
|
||||
{
|
||||
var newProject = ScriptGroupProject.BuildShellProject(project.Name);
|
||||
CopyProjectProperties(project, newProject);
|
||||
list.Add(newProject);
|
||||
hasTimer = true;
|
||||
// hasTimer = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,23 +204,22 @@ public partial class ScriptService : IScriptService
|
||||
target.GroupInfo = source.GroupInfo;
|
||||
}
|
||||
|
||||
private List<ScriptProject> ExtractJsProjects(List<ScriptGroupProject> list)
|
||||
{
|
||||
var jsProjects = new List<ScriptProject>();
|
||||
foreach (var project in list)
|
||||
{
|
||||
if (project is { Type: "Javascript", Project: not null })
|
||||
{
|
||||
jsProjects.Add(project.Project);
|
||||
}
|
||||
}
|
||||
|
||||
return jsProjects;
|
||||
}
|
||||
// private List<ScriptProject> ExtractJsProjects(List<ScriptGroupProject> list)
|
||||
// {
|
||||
// var jsProjects = new List<ScriptProject>();
|
||||
// foreach (var project in list)
|
||||
// {
|
||||
// if (project is { Type: "Javascript", Project: not null })
|
||||
// {
|
||||
// jsProjects.Add(project.Project);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return jsProjects;
|
||||
// }
|
||||
|
||||
private async Task ExecuteProject(ScriptGroupProject project)
|
||||
{
|
||||
|
||||
if (project.Type == "Javascript")
|
||||
{
|
||||
if (project.Project == null)
|
||||
@@ -241,7 +240,8 @@ public partial class ScriptService : IScriptService
|
||||
_logger.LogInformation("→ 开始执行地图追踪任务: {Name}", project.Name);
|
||||
await project.Run();
|
||||
}
|
||||
else if (project.Type == "Shell"){
|
||||
else if (project.Type == "Shell")
|
||||
{
|
||||
_logger.LogInformation("→ 开始执行shell: {Name}", project.Name);
|
||||
await project.Run();
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@ public partial class CaptureTestWindow : Window
|
||||
_capture.Start(hWnd,
|
||||
new Dictionary<string, object>()
|
||||
{
|
||||
{ "useBitmapCache", TaskContext.Instance().Config.WgcUseBitmapCache },
|
||||
{ "autoFixWin11BitBlt", OsVersionHelper.IsWindows11 && TaskContext.Instance().Config.AutoFixWin11BitBlt }
|
||||
}
|
||||
);
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
Margin="0,0,36,0"
|
||||
Text="{Binding Config.TriggerInterval, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
<Separator Margin="-18,0" BorderThickness="0,1,0,0" />
|
||||
<!--<Separator Margin="-18,0" BorderThickness="0,1,0,0" />
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -201,7 +201,7 @@
|
||||
Grid.Column="1"
|
||||
Margin="0,0,36,0"
|
||||
IsChecked="{Binding Config.WgcUseBitmapCache, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
</Grid>-->
|
||||
<Separator Margin="-18,0" BorderThickness="0,1,0,0" />
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
|
||||
@@ -125,7 +125,7 @@ public partial class KeyMouseRecordPageViewModel : ViewModel
|
||||
{
|
||||
var s = await File.ReadAllTextAsync(path);
|
||||
|
||||
await new TaskRunner(DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
await new TaskRunner()
|
||||
.RunThreadAsync(async () => await KeyMouseMacroPlayer.PlayMacro(s, CancellationContext.Instance.Cts.Token));
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -213,7 +213,7 @@ public partial class OneDragonFlowViewModel : ViewModel
|
||||
// 没启动的时候先启动
|
||||
await ScriptService.StartGameTask();
|
||||
|
||||
await new TaskRunner(DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
await new TaskRunner()
|
||||
.RunThreadAsync(async () =>
|
||||
{
|
||||
Notify.Event(NotificationEvent.DragonStart).Success("一条龙启动");
|
||||
|
||||
@@ -183,7 +183,7 @@ public partial class TaskSettingsPageViewModel : ViewModel
|
||||
}
|
||||
|
||||
SwitchAutoGeniusInvokationEnabled = true;
|
||||
await new TaskRunner(DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
await new TaskRunner()
|
||||
.RunSoloTaskAsync(new AutoGeniusInvokationTask(new GeniusInvokationTaskParam(content)));
|
||||
SwitchAutoGeniusInvokationEnabled = false;
|
||||
}
|
||||
@@ -219,7 +219,7 @@ public partial class TaskSettingsPageViewModel : ViewModel
|
||||
public async Task OnSwitchAutoWood()
|
||||
{
|
||||
SwitchAutoWoodEnabled = true;
|
||||
await new TaskRunner(DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
await new TaskRunner()
|
||||
.RunSoloTaskAsync(new AutoWoodTask(new WoodTaskParam(AutoWoodRoundNum, AutoWoodDailyMaxCount)));
|
||||
SwitchAutoWoodEnabled = false;
|
||||
}
|
||||
@@ -241,7 +241,7 @@ public partial class TaskSettingsPageViewModel : ViewModel
|
||||
var param = new AutoFightParam(path, Config.AutoFightConfig);
|
||||
|
||||
SwitchAutoFightEnabled = true;
|
||||
await new TaskRunner(DispatcherTimerOperationEnum.UseCacheImageWithTrigger)
|
||||
await new TaskRunner()
|
||||
.RunSoloTaskAsync(new AutoFightTask(param));
|
||||
SwitchAutoFightEnabled = false;
|
||||
}
|
||||
@@ -261,7 +261,7 @@ public partial class TaskSettingsPageViewModel : ViewModel
|
||||
}
|
||||
|
||||
SwitchAutoDomainEnabled = true;
|
||||
await new TaskRunner(DispatcherTimerOperationEnum.UseCacheImage)
|
||||
await new TaskRunner()
|
||||
.RunSoloTaskAsync(new AutoDomainTask(new AutoDomainParam(AutoDomainRoundNum, path)));
|
||||
SwitchAutoDomainEnabled = false;
|
||||
}
|
||||
@@ -376,7 +376,7 @@ public partial class TaskSettingsPageViewModel : ViewModel
|
||||
private async Task OnSwitchAutoMusicGame()
|
||||
{
|
||||
SwitchAutoMusicGameEnabled = true;
|
||||
await new TaskRunner(DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
await new TaskRunner()
|
||||
.RunSoloTaskAsync(new AutoMusicGameTask(new AutoMusicGameParam()));
|
||||
SwitchAutoMusicGameEnabled = false;
|
||||
}
|
||||
@@ -391,7 +391,7 @@ public partial class TaskSettingsPageViewModel : ViewModel
|
||||
private async Task OnSwitchAutoAlbum()
|
||||
{
|
||||
SwitchAutoAlbumEnabled = true;
|
||||
await new TaskRunner(DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
await new TaskRunner()
|
||||
.RunSoloTaskAsync(new AutoAlbumTask(new AutoMusicGameParam()));
|
||||
SwitchAutoAlbumEnabled = false;
|
||||
}
|
||||
@@ -401,7 +401,7 @@ public partial class TaskSettingsPageViewModel : ViewModel
|
||||
{
|
||||
SwitchAutoFishingEnabled = true;
|
||||
var param = AutoFishingTaskParam.BuildFromConfig(TaskContext.Instance().Config.AutoFishingConfig, SaveScreenshotOnKeyTick);
|
||||
await new TaskRunner(DispatcherTimerOperationEnum.UseSelfCaptureImage)
|
||||
await new TaskRunner()
|
||||
.RunSoloTaskAsync(new AutoFishingTask(param));
|
||||
SwitchAutoFishingEnabled = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user