mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-03-19 08:19:48 +08:00
在 `TpTask.cs` 文件中,添加了 `using BetterGenshinImpact.GameTask.Common.Exceptions;` 引用,并在 `TpTask` 类中添加了对 `TpPointNotActivate` 异常的处理逻辑,当传送点未激活或不存在时,按下 ESC 键返回大地图界面,并抛出异常。同时在 `ClickTpPoint` 方法中,修改了判断逻辑,增加了对传送点未激活或不存在的异常处理。 在 `MapAssets.cs`、`NewRetry.cs`、`TaskControl.cs` 文件中,将 `Exception` 修改为 `System.Exception`。 在 `NormalEndException.cs` 和 `RetryException.cs` 文件中,删除了旧的异常类定义,并重新添加了新的异常类定义。 在 `TpPointNotActivate.cs` 文件中,添加了新的异常类 `TpPointNotActivate`。
187 lines
5.7 KiB
C#
187 lines
5.7 KiB
C#
using BetterGenshinImpact.GameTask.AutoGeniusInvokation.Exception;
|
|
using BetterGenshinImpact.GameTask.Model.Area;
|
|
using Fischless.GameCapture;
|
|
using Microsoft.Extensions.Logging;
|
|
using System;
|
|
using System.Drawing;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace BetterGenshinImpact.GameTask.Common;
|
|
|
|
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)
|
|
{
|
|
if (!SystemControl.IsGenshinImpactActiveByProcess())
|
|
{
|
|
Logger.LogInformation("当前获取焦点的窗口不是原神,停止执行");
|
|
throw new NormalEndException("当前获取焦点的窗口不是原神");
|
|
}
|
|
|
|
Thread.Sleep(millisecondsTimeout);
|
|
}
|
|
|
|
public static void Sleep(int millisecondsTimeout)
|
|
{
|
|
NewRetry.Do(() =>
|
|
{
|
|
if (!SystemControl.IsGenshinImpactActiveByProcess())
|
|
{
|
|
Logger.LogInformation("当前获取焦点的窗口不是原神,暂停");
|
|
throw new RetryException("当前获取焦点的窗口不是原神");
|
|
}
|
|
}, TimeSpan.FromSeconds(1), 100);
|
|
Thread.Sleep(millisecondsTimeout);
|
|
}
|
|
|
|
public static void Sleep(int millisecondsTimeout, CancellationTokenSource? cts)
|
|
{
|
|
if (cts is { IsCancellationRequested: true })
|
|
{
|
|
throw new NormalEndException("取消自动任务");
|
|
}
|
|
|
|
if (millisecondsTimeout <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
NewRetry.Do(() =>
|
|
{
|
|
if (cts is { IsCancellationRequested: true })
|
|
{
|
|
throw new NormalEndException("取消自动任务");
|
|
}
|
|
|
|
if (!SystemControl.IsGenshinImpactActiveByProcess())
|
|
{
|
|
Logger.LogInformation("当前获取焦点的窗口不是原神,暂停");
|
|
throw new RetryException("当前获取焦点的窗口不是原神");
|
|
}
|
|
}, TimeSpan.FromSeconds(1), 100);
|
|
Thread.Sleep(millisecondsTimeout);
|
|
if (cts is { IsCancellationRequested: true })
|
|
{
|
|
throw new NormalEndException("取消自动任务");
|
|
}
|
|
}
|
|
|
|
public static async Task Delay(int millisecondsTimeout, CancellationTokenSource cts)
|
|
{
|
|
if (cts is { IsCancellationRequested: true })
|
|
{
|
|
throw new NormalEndException("取消自动任务");
|
|
}
|
|
|
|
if (millisecondsTimeout <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
NewRetry.Do(() =>
|
|
{
|
|
if (cts is { IsCancellationRequested: true })
|
|
{
|
|
throw new NormalEndException("取消自动任务");
|
|
}
|
|
|
|
if (!SystemControl.IsGenshinImpactActiveByProcess())
|
|
{
|
|
Logger.LogInformation("当前获取焦点的窗口不是原神,暂停");
|
|
throw new RetryException("当前获取焦点的窗口不是原神");
|
|
}
|
|
}, TimeSpan.FromSeconds(1), 100);
|
|
await Task.Delay(millisecondsTimeout, cts.Token);
|
|
if (cts is { IsCancellationRequested: true })
|
|
{
|
|
throw new NormalEndException("取消自动任务");
|
|
}
|
|
}
|
|
|
|
public static Bitmap CaptureGameBitmap(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)
|
|
{
|
|
Logger.LogWarning("截图失败!");
|
|
// 重试5次
|
|
for (var i = 0; i < 5; i++)
|
|
{
|
|
bitmap = gameCapture?.Capture();
|
|
if (bitmap != null)
|
|
{
|
|
return bitmap;
|
|
}
|
|
|
|
Sleep(30);
|
|
}
|
|
|
|
throw new System.Exception("尝试多次后,截图失败!");
|
|
}
|
|
else
|
|
{
|
|
return bitmap;
|
|
}
|
|
}
|
|
|
|
private static CaptureContent CaptureToContent(IGameCapture? gameCapture)
|
|
{
|
|
var bitmap = CaptureGameBitmap(gameCapture);
|
|
return new CaptureContent(bitmap, 0, 0);
|
|
}
|
|
|
|
// [Obsolete]
|
|
// 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);
|
|
}
|
|
}
|