mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-21 09:45:48 +08:00
add ffmpeg recorder
This commit is contained in:
@@ -56,7 +56,7 @@ public partial class MaskWindowConfig : ObservableObject
|
||||
/// 显示状态指示
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private bool _showStatus = true;
|
||||
private bool _showStatus = false;
|
||||
|
||||
/// <summary>
|
||||
/// UID遮盖是否启用
|
||||
|
||||
@@ -170,7 +170,7 @@ public class MouseKeyMonitor
|
||||
|
||||
private void GlobalHookMouseWheelExt(object? sender, MouseEventExtArgs e)
|
||||
{
|
||||
Debug.WriteLine("MouseMove: {0}; \t Location: {1};\t Delta: {2};\t System Timestamp: {3}", e.Button, e.Location, e.Delta, e.Timestamp);
|
||||
// Debug.WriteLine("MouseMove: {0}; \t Location: {1};\t Delta: {2};\t System Timestamp: {3}", e.Button, e.Location, e.Delta, e.Timestamp);
|
||||
GlobalKeyMouseRecord.Instance.GlobalHookMouseWheel(e);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,9 @@ public class GlobalKeyMouseRecord : Singleton<GlobalKeyMouseRecord>
|
||||
|
||||
private KeyMouseRecorder? _recorder;
|
||||
|
||||
private SharpAviRecorder _sharpAviRecorder;
|
||||
// private SharpAviRecorder _sharpAviRecorder;
|
||||
|
||||
private FfmpegRecorder? _ffmpegRecorder;
|
||||
|
||||
private readonly Dictionary<Keys, bool> _keyDownState = [];
|
||||
|
||||
@@ -63,7 +65,7 @@ public class GlobalKeyMouseRecord : Singleton<GlobalKeyMouseRecord>
|
||||
SystemControl.ActivateWindow();
|
||||
|
||||
_logger.LogInformation("录制:{Text}", "实时任务已暂停");
|
||||
_logger.LogInformation("注意:录制时遇到主界面(鼠标永远在界面中心)和其他界面(鼠标可自由移动,比如地图等)的切换,请把手离开鼠标等待录制模式切换日志");
|
||||
// _logger.LogInformation("注意:录制时遇到主界面(鼠标永远在界面中心)和其他界面(鼠标可自由移动,比如地图等)的切换,请把手离开鼠标等待录制模式切换日志");
|
||||
|
||||
// 先实例化
|
||||
_recorder = new KeyMouseRecorder();
|
||||
@@ -73,8 +75,10 @@ public class GlobalKeyMouseRecord : Singleton<GlobalKeyMouseRecord>
|
||||
{
|
||||
Directory.CreateDirectory(videoPath);
|
||||
}
|
||||
_sharpAviRecorder = new SharpAviRecorder( Path.Combine(videoPath, $"{DateTime.Now:yyyyMMddHH_mmssffff.avi}"),
|
||||
CodecIds.MotionJpeg, 90, 0, SupportedWaveFormat.WAVE_FORMAT_44M16, false, 0);
|
||||
// _sharpAviRecorder = new SharpAviRecorder( Path.Combine(videoPath, $"{DateTime.Now:yyyyMMddHH_mmssffff.avi}"),
|
||||
// CodecIds.MotionJpeg, 90, 0, SupportedWaveFormat.WAVE_FORMAT_44M16, false, 0);
|
||||
|
||||
_ffmpegRecorder = new FfmpegRecorder();
|
||||
|
||||
TaskTriggerDispatcher.Instance().StopTimer();
|
||||
|
||||
@@ -87,7 +91,7 @@ public class GlobalKeyMouseRecord : Singleton<GlobalKeyMouseRecord>
|
||||
|
||||
|
||||
// _timer.Start();
|
||||
_sharpAviRecorder.Start();
|
||||
_ffmpegRecorder.Start();
|
||||
_directInputMonitor.Start();
|
||||
|
||||
Status = KeyMouseRecorderStatus.Recording;
|
||||
@@ -108,7 +112,7 @@ public class GlobalKeyMouseRecord : Singleton<GlobalKeyMouseRecord>
|
||||
_directInputMonitor?.Dispose();
|
||||
_directInputMonitor = null;
|
||||
|
||||
_sharpAviRecorder.Dispose();
|
||||
_ffmpegRecorder?.Stop();
|
||||
|
||||
// _timer.Stop();
|
||||
|
||||
@@ -191,10 +195,10 @@ public class GlobalKeyMouseRecord : Singleton<GlobalKeyMouseRecord>
|
||||
|
||||
public void GlobalHookMouseMoveTo(MouseEventExtArgs e)
|
||||
{
|
||||
if (_isInMainUi)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// if (_isInMainUi)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// Debug.WriteLine($"MouseMove: {e.X}, {e.Y}");
|
||||
_recorder?.MouseMoveTo(e);
|
||||
}
|
||||
@@ -208,7 +212,7 @@ public class GlobalKeyMouseRecord : Singleton<GlobalKeyMouseRecord>
|
||||
public void GlobalHookMouseMoveBy(MouseState state)
|
||||
{
|
||||
// Debug.WriteLine($"MouseMoveBy: {state.X}, {state.Y}");
|
||||
if (state is { X: 0, Y: 0 } || !_isInMainUi)
|
||||
if (state is { X: 0, Y: 0 })
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using Gma.System.MouseKeyHook;
|
||||
using SharpDX.DirectInput;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Windows.Forms;
|
||||
@@ -38,69 +39,72 @@ public class KeyMouseRecorder
|
||||
{
|
||||
var rect = TaskContext.Instance().SystemInfo.CaptureAreaRect;
|
||||
// 合并鼠标移动事件
|
||||
var mergedMacroEvents = new List<MacroEvent>();
|
||||
MacroEvent? currentMerge = null;
|
||||
foreach (var macroEvent in MacroEvents)
|
||||
{
|
||||
if (currentMerge == null)
|
||||
{
|
||||
currentMerge = macroEvent;
|
||||
continue;
|
||||
}
|
||||
if (currentMerge.Type != macroEvent.Type)
|
||||
{
|
||||
mergedMacroEvents.Add(currentMerge);
|
||||
currentMerge = macroEvent;
|
||||
continue;
|
||||
}
|
||||
switch (macroEvent.Type)
|
||||
{
|
||||
case MacroEventType.MouseMoveTo:
|
||||
// 控制合并时间片段长度
|
||||
if (macroEvent.Time - currentMerge.Time > MergedEventTimeMax)
|
||||
{
|
||||
mergedMacroEvents.Add(currentMerge);
|
||||
currentMerge = macroEvent;
|
||||
break;
|
||||
}
|
||||
// 合并为最后一个事件的位置,避免丢步
|
||||
currentMerge.MouseX = macroEvent.MouseX;
|
||||
currentMerge.MouseY = macroEvent.MouseY;
|
||||
break;
|
||||
|
||||
case MacroEventType.MouseMoveBy:
|
||||
if (macroEvent.Time - currentMerge.Time > MergedEventTimeMax)
|
||||
{
|
||||
mergedMacroEvents.Add(currentMerge);
|
||||
currentMerge = macroEvent;
|
||||
break;
|
||||
}
|
||||
// 相对位移量相加
|
||||
currentMerge.MouseX += macroEvent.MouseX;
|
||||
currentMerge.MouseY += macroEvent.MouseY;
|
||||
if (macroEvent.CameraOrientation != null)
|
||||
{
|
||||
currentMerge.CameraOrientation = macroEvent.CameraOrientation;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
mergedMacroEvents.Add(currentMerge);
|
||||
mergedMacroEvents.Add(macroEvent);
|
||||
currentMerge = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// var mergedMacroEvents = new List<MacroEvent>();
|
||||
// MacroEvent? currentMerge = null;
|
||||
// foreach (var macroEvent in MacroEvents)
|
||||
// {
|
||||
// if (currentMerge == null)
|
||||
// {
|
||||
// currentMerge = macroEvent;
|
||||
// continue;
|
||||
// }
|
||||
// if (currentMerge.Type != macroEvent.Type)
|
||||
// {
|
||||
// mergedMacroEvents.Add(currentMerge);
|
||||
// currentMerge = macroEvent;
|
||||
// continue;
|
||||
// }
|
||||
// switch (macroEvent.Type)
|
||||
// {
|
||||
// case MacroEventType.MouseMoveTo:
|
||||
// // 控制合并时间片段长度
|
||||
// if (macroEvent.Time - currentMerge.Time > MergedEventTimeMax)
|
||||
// {
|
||||
// mergedMacroEvents.Add(currentMerge);
|
||||
// currentMerge = macroEvent;
|
||||
// break;
|
||||
// }
|
||||
// // 合并为最后一个事件的位置,避免丢步
|
||||
// currentMerge.MouseX = macroEvent.MouseX;
|
||||
// currentMerge.MouseY = macroEvent.MouseY;
|
||||
// break;
|
||||
//
|
||||
// case MacroEventType.MouseMoveBy:
|
||||
// if (macroEvent.Time - currentMerge.Time > MergedEventTimeMax)
|
||||
// {
|
||||
// mergedMacroEvents.Add(currentMerge);
|
||||
// currentMerge = macroEvent;
|
||||
// break;
|
||||
// }
|
||||
// // 相对位移量相加
|
||||
// currentMerge.MouseX += macroEvent.MouseX;
|
||||
// currentMerge.MouseY += macroEvent.MouseY;
|
||||
// if (macroEvent.CameraOrientation != null)
|
||||
// {
|
||||
// currentMerge.CameraOrientation = macroEvent.CameraOrientation;
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// default:
|
||||
// mergedMacroEvents.Add(currentMerge);
|
||||
// mergedMacroEvents.Add(macroEvent);
|
||||
// currentMerge = null;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
KeyMouseScript keyMouseScript = new()
|
||||
{
|
||||
MacroEvents = mergedMacroEvents,
|
||||
MacroEvents = MacroEvents,
|
||||
MouseMoveByMacroEvents = MouseMoveByMacroEvents,
|
||||
Info = new KeyMouseScriptInfo
|
||||
{
|
||||
X = rect.X,
|
||||
Y = rect.Y,
|
||||
Width = rect.Width,
|
||||
Height = rect.Height,
|
||||
RecordDpi = TaskContext.Instance().DpiScale
|
||||
RecordDpi = TaskContext.Instance().DpiScale,
|
||||
StartTime = $"{StartTime:yyyy-MM-dd HH:mm:ss:ffff}",
|
||||
StartTimeUnixTimestamp = (StartTime - new DateTime(1970, 1, 1)).TotalNanoseconds.ToString("F0")
|
||||
}
|
||||
};
|
||||
return JsonSerializer.Serialize(keyMouseScript, JsonOptions);
|
||||
@@ -174,22 +178,21 @@ public class KeyMouseRecorder
|
||||
public void MouseMoveBy(MouseState state)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
int? cao = null;
|
||||
if (TaskContext.Instance().Config.RecordConfig.IsRecordCameraOrientation)
|
||||
{
|
||||
if ((now - LastOrientationDetection).TotalMilliseconds > 100.0)
|
||||
{
|
||||
LastOrientationDetection = now;
|
||||
cao = (int)Math.Round(CameraOrientation.Compute(TaskControl.CaptureToRectArea().SrcMat));
|
||||
}
|
||||
}
|
||||
MacroEvents.Add(new MacroEvent
|
||||
// int? cao = null;
|
||||
// if (TaskContext.Instance().Config.RecordConfig.IsRecordCameraOrientation)
|
||||
// {
|
||||
// if ((now - LastOrientationDetection).TotalMilliseconds > 100.0)
|
||||
// {
|
||||
// LastOrientationDetection = now;
|
||||
// cao = (int)Math.Round(CameraOrientation.Compute(TaskControl.CaptureToRectArea().SrcMat));
|
||||
// }
|
||||
// }
|
||||
MouseMoveByMacroEvents.Add(new MacroEvent
|
||||
{
|
||||
Type = MacroEventType.MouseMoveBy,
|
||||
MouseX = state.X,
|
||||
MouseY = state.Y,
|
||||
Time = (now - StartTime).TotalMilliseconds,
|
||||
CameraOrientation = cao,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace BetterGenshinImpact.Core.Recorder.Model;
|
||||
public class KeyMouseScript
|
||||
{
|
||||
public List<MacroEvent> MacroEvents { get; set; } = [];
|
||||
public List<MacroEvent> MouseMoveByMacroEvents { get; set; } = [];
|
||||
public KeyMouseScriptInfo? Info { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -24,4 +24,8 @@ public class KeyMouseScriptInfo
|
||||
public int Height { get; set; }
|
||||
|
||||
public double RecordDpi { get; set; } = 1.0;
|
||||
|
||||
public string StartTime { get; set; } = string.Empty;
|
||||
|
||||
public string StartTimeUnixTimestamp { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
120
BetterGenshinImpact/Core/Video/FfmpegRecorder.cs
Normal file
120
BetterGenshinImpact/Core/Video/FfmpegRecorder.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using BetterGenshinImpact.Core.Config;
|
||||
using BetterGenshinImpact.GameTask.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog.Core;
|
||||
|
||||
|
||||
namespace BetterGenshinImpact.Core.Video;
|
||||
|
||||
public class FfmpegRecorder
|
||||
{
|
||||
// ffmpeg进程
|
||||
private readonly Process _process;
|
||||
|
||||
// ffmpeg.exe实体文件路径
|
||||
private static readonly string FfmpegPath = Global.Absolute(@"video\bin\ffmpeg.exe");
|
||||
|
||||
private readonly string _filePath;
|
||||
private string _startTime = string.Empty;
|
||||
|
||||
public FfmpegRecorder()
|
||||
{
|
||||
if (!File.Exists(FfmpegPath))
|
||||
{
|
||||
throw new Exception("ffmpeg.exe不存在");
|
||||
}
|
||||
|
||||
_filePath = Global.Absolute($@"video\{DateTime.Now:yyyyMMddHH_mmssffff}.mp4");
|
||||
var processInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = FfmpegPath,
|
||||
Arguments = $" -f gdigrab -hwaccel cuvid -show_region 1 -framerate 60 -use_wallclock_as_timestamps 1 -i title=原神 -pix_fmt yuv420p -c:v libx264 -preset ultrafast \"{_filePath}\"",
|
||||
StandardInputEncoding = Encoding.UTF8,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
// StandardOutputEncoding = Encoding.UTF8,
|
||||
};
|
||||
_process = new Process { StartInfo = processInfo };
|
||||
// _process.OutputDataReceived += (sender, args) => { Debug.WriteLine(args.Data); };
|
||||
_process.ErrorDataReceived += (sender, args) =>
|
||||
{
|
||||
Debug.WriteLine(args.Data);
|
||||
if (string.IsNullOrEmpty(_startTime))
|
||||
{
|
||||
if (args.Data != null && args.Data.Contains("start"))
|
||||
{
|
||||
string pattern = @"start:\s*(\d+\.\d+)";
|
||||
|
||||
Match match = Regex.Match(args.Data, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
_startTime = match.Groups[1].Value;
|
||||
TaskControl.Logger.LogInformation("ffmpeg录制: 视频起始时间戳 {Text}", _startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 功能: 开始录制
|
||||
/// </summary>
|
||||
public bool Start()
|
||||
{
|
||||
_process.Start();
|
||||
// _process.BeginOutputReadLine();
|
||||
_process.BeginErrorReadLine();
|
||||
TaskControl.Logger.LogInformation("ffmpeg录制: {Text}", "已启动");
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 功能: 停止录制
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
// Kernel32.AttachConsole((uint)_process.Id);
|
||||
// Kernel32.SetConsoleCtrlHandler(null, true);
|
||||
// Kernel32.GenerateConsoleCtrlEvent(0, 0);
|
||||
// Kernel32.FreeConsole();
|
||||
|
||||
// AttachConsole(_process.Id);
|
||||
// SetConsoleCtrlHandler(IntPtr.Zero, true);
|
||||
// GenerateConsoleCtrlEvent(0, 0);
|
||||
// FreeConsole();
|
||||
TaskControl.Logger.LogInformation("ffmpeg录制: {Text}", "正在停止录制,请稍后...");
|
||||
_process.StandardInput.WriteLine("q");
|
||||
|
||||
if (!_process.WaitForExit(5000))
|
||||
{
|
||||
_process.Kill();
|
||||
}
|
||||
|
||||
_process.Close();
|
||||
_process.Dispose();
|
||||
|
||||
|
||||
Thread.Sleep(3000);
|
||||
if (File.Exists(_filePath))
|
||||
{
|
||||
// 重命名文件
|
||||
var newFilePath = Global.Absolute($@"video\{_startTime}.mp4");
|
||||
File.Move(_filePath, newFilePath);
|
||||
TaskControl.Logger.LogInformation("ffmpeg录制: {Text}", $"录制完成");
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskControl.Logger.LogError("ffmpeg录制: {Text}", "未找到结果文件,录制失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ namespace BetterGenshinImpact.GameTask
|
||||
/// 1. 是否缓存图像
|
||||
/// 2. 是否执行触发器
|
||||
/// </summary>
|
||||
private DispatcherCaptureModeEnum _dispatcherCacheCaptureMode = DispatcherCaptureModeEnum.NormalTrigger;
|
||||
private DispatcherCaptureModeEnum _dispatcherCacheCaptureMode = DispatcherCaptureModeEnum.OnlyCacheCapture;
|
||||
|
||||
private static readonly object _bitmapLocker = new();
|
||||
private static readonly object _triggerListLocker = new();
|
||||
@@ -129,7 +129,7 @@ namespace BetterGenshinImpact.GameTask
|
||||
public void Start(IntPtr hWnd, CaptureModes mode, int interval = 50)
|
||||
{
|
||||
// 初始化截图器
|
||||
GameCapture = GameCaptureFactory.Create(mode);
|
||||
// GameCapture = GameCaptureFactory.Create(mode);
|
||||
// 激活窗口 保证后面能够正常获取窗口信息
|
||||
SystemControl.ActivateWindow(hWnd);
|
||||
|
||||
@@ -137,22 +137,22 @@ namespace BetterGenshinImpact.GameTask
|
||||
TaskContext.Instance().Init(hWnd);
|
||||
|
||||
// 初始化触发器(一定要在任务上下文初始化完毕后使用)
|
||||
_triggers = GameTaskManager.LoadInitialTriggers();
|
||||
_triggers = [];
|
||||
|
||||
// 启动截图
|
||||
GameCapture.Start(hWnd,
|
||||
new Dictionary<string, object>()
|
||||
{
|
||||
{ "useBitmapCache", TaskContext.Instance().Config.WgcUseBitmapCache },
|
||||
{ "autoFixWin11BitBlt", OsVersionHelper.IsWindows11_OrGreater && TaskContext.Instance().Config.AutoFixWin11BitBlt }
|
||||
}
|
||||
);
|
||||
// GameCapture.Start(hWnd,
|
||||
// new Dictionary<string, object>()
|
||||
// {
|
||||
// { "useBitmapCache", TaskContext.Instance().Config.WgcUseBitmapCache },
|
||||
// { "autoFixWin11BitBlt", OsVersionHelper.IsWindows11_OrGreater && TaskContext.Instance().Config.AutoFixWin11BitBlt }
|
||||
// }
|
||||
// );
|
||||
|
||||
// 捕获模式初始化配置
|
||||
if (TaskContext.Instance().Config.CommonConfig.ScreenshotEnabled || TaskContext.Instance().Config.MacroConfig.CombatMacroEnabled)
|
||||
{
|
||||
_dispatcherCacheCaptureMode = DispatcherCaptureModeEnum.CacheCaptureWithTrigger;
|
||||
}
|
||||
// if (TaskContext.Instance().Config.CommonConfig.ScreenshotEnabled || TaskContext.Instance().Config.MacroConfig.CombatMacroEnabled)
|
||||
// {
|
||||
// _dispatcherCacheCaptureMode = DispatcherCaptureModeEnum.CacheCaptureWithTrigger;
|
||||
// }
|
||||
|
||||
// 启动定时器
|
||||
_frameIndex = 0;
|
||||
@@ -211,21 +211,21 @@ namespace BetterGenshinImpact.GameTask
|
||||
|
||||
// 检查截图器是否初始化
|
||||
var maskWindow = MaskWindow.Instance();
|
||||
if (GameCapture == null || !GameCapture.IsCapturing)
|
||||
{
|
||||
if (!TaskContext.Instance().SystemInfo.GameProcess.HasExited)
|
||||
{
|
||||
_logger.LogError("截图器未初始化!");
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation("游戏已退出,BetterGI 自动停止截图器");
|
||||
}
|
||||
|
||||
UiTaskStopTickEvent?.Invoke(sender, e);
|
||||
maskWindow.Invoke(maskWindow.Hide);
|
||||
return;
|
||||
}
|
||||
// if (GameCapture == null || !GameCapture.IsCapturing)
|
||||
// {
|
||||
// if (!TaskContext.Instance().SystemInfo.GameProcess.HasExited)
|
||||
// {
|
||||
// _logger.LogError("截图器未初始化!");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _logger.LogInformation("游戏已退出,BetterGI 自动停止截图器");
|
||||
// }
|
||||
//
|
||||
// UiTaskStopTickEvent?.Invoke(sender, e);
|
||||
// maskWindow.Invoke(maskWindow.Hide);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// 检查游戏是否在前台
|
||||
var hasBackgroundTriggerToRun = false;
|
||||
@@ -303,60 +303,60 @@ 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)))
|
||||
{
|
||||
// Debug.WriteLine("没有可用的触发器且不处于仅截屏状态, 不再进行截屏");
|
||||
return;
|
||||
}
|
||||
|
||||
var speedTimer = new SpeedTimer();
|
||||
// 捕获游戏画面
|
||||
var bitmap = GameCapture.Capture();
|
||||
speedTimer.Record("截图");
|
||||
|
||||
if (bitmap == null)
|
||||
{
|
||||
_logger.LogWarning("截图失败!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsOnlyCacheCapture(bitmap))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 循环执行所有触发器 有独占状态的触发器的时候只执行独占触发器
|
||||
var content = new CaptureContent(bitmap, _frameIndex, _timer.Interval);
|
||||
|
||||
lock (_triggerListLocker)
|
||||
{
|
||||
var exclusiveTrigger = _triggers!.FirstOrDefault(t => t is { IsEnabled: true, IsExclusive: true });
|
||||
if (exclusiveTrigger != null)
|
||||
{
|
||||
exclusiveTrigger.OnCapture(content);
|
||||
speedTimer.Record(exclusiveTrigger.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
var runningTriggers = _triggers!.Where(t => t.IsEnabled);
|
||||
if (hasBackgroundTriggerToRun)
|
||||
{
|
||||
runningTriggers = runningTriggers.Where(t => t.IsBackgroundRunning);
|
||||
}
|
||||
|
||||
foreach (var trigger in runningTriggers)
|
||||
{
|
||||
trigger.OnCapture(content);
|
||||
speedTimer.Record(trigger.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
speedTimer.DebugPrint();
|
||||
content.Dispose();
|
||||
// _frameIndex = (_frameIndex + 1) % (int)(CaptureContent.MaxFrameIndexSecond * 1000d / _timer.Interval);
|
||||
//
|
||||
// if (_dispatcherCacheCaptureMode == DispatcherCaptureModeEnum.NormalTrigger
|
||||
// && (_triggers == null || !_triggers.Exists(t => t.IsEnabled)))
|
||||
// {
|
||||
// // Debug.WriteLine("没有可用的触发器且不处于仅截屏状态, 不再进行截屏");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// var speedTimer = new SpeedTimer();
|
||||
// // 捕获游戏画面
|
||||
// var bitmap = GameCapture.Capture();
|
||||
// speedTimer.Record("截图");
|
||||
//
|
||||
// if (bitmap == null)
|
||||
// {
|
||||
// _logger.LogWarning("截图失败!");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (IsOnlyCacheCapture(bitmap))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // 循环执行所有触发器 有独占状态的触发器的时候只执行独占触发器
|
||||
// var content = new CaptureContent(bitmap, _frameIndex, _timer.Interval);
|
||||
//
|
||||
// lock (_triggerListLocker)
|
||||
// {
|
||||
// var exclusiveTrigger = _triggers!.FirstOrDefault(t => t is { IsEnabled: true, IsExclusive: true });
|
||||
// if (exclusiveTrigger != null)
|
||||
// {
|
||||
// exclusiveTrigger.OnCapture(content);
|
||||
// speedTimer.Record(exclusiveTrigger.Name);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var runningTriggers = _triggers!.Where(t => t.IsEnabled);
|
||||
// if (hasBackgroundTriggerToRun)
|
||||
// {
|
||||
// runningTriggers = runningTriggers.Where(t => t.IsBackgroundRunning);
|
||||
// }
|
||||
//
|
||||
// foreach (var trigger in runningTriggers)
|
||||
// {
|
||||
// trigger.OnCapture(content);
|
||||
// speedTimer.Record(trigger.Name);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// speedTimer.DebugPrint();
|
||||
// content.Dispose();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -58,7 +58,16 @@
|
||||
<ui:SymbolIcon Symbol="Play24" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
|
||||
<ui:NavigationViewItem Content="录制回放"
|
||||
NavigationCacheMode="Enabled"
|
||||
TargetPageType="{x:Type pages:KeyMouseRecordPage}">
|
||||
<ui:NavigationViewItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Record24" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
|
||||
<!--
|
||||
<ui:NavigationViewItem Content="实时触发"
|
||||
NavigationCacheMode="Enabled"
|
||||
TargetPageType="{x:Type pages:TriggerSettingsPage}">
|
||||
@@ -74,7 +83,7 @@
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
|
||||
<!--<ui:NavigationViewItemSeparator />-->
|
||||
~1~<ui:NavigationViewItemSeparator />@1@
|
||||
|
||||
<ui:NavigationViewItem Content="一条龙"
|
||||
NavigationCacheMode="Enabled"
|
||||
@@ -90,8 +99,8 @@
|
||||
</ui:NavigationViewItem.Icon>
|
||||
<ui:NavigationViewItem.MenuItems>
|
||||
|
||||
<!--<ui:NavigationViewItemSeparator />-->
|
||||
<!-- ConvertRange20 -->
|
||||
~1~<ui:NavigationViewItemSeparator />@1@
|
||||
~1~ ConvertRange20 @1@
|
||||
<ui:NavigationViewItem Content="调度器"
|
||||
NavigationCacheMode="Enabled"
|
||||
TargetPageType="{x:Type pages:ScriptControlPage}">
|
||||
@@ -99,7 +108,7 @@
|
||||
<ui:SymbolIcon Symbol="DeveloperBoard24" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
<!-- WebAsset24 | DocumentJs16 | Script16 -->
|
||||
~1~ WebAsset24 | DocumentJs16 | Script16 @1@
|
||||
<ui:NavigationViewItem Content="JS 脚本"
|
||||
NavigationCacheMode="Enabled"
|
||||
TargetPageType="{x:Type pages:JsListPage}">
|
||||
@@ -107,7 +116,7 @@
|
||||
<ui:SymbolIcon Symbol="DocumentJs16" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
<!-- Map24 -->
|
||||
~1~ Map24 @1@
|
||||
<ui:NavigationViewItem Content="地图追踪"
|
||||
NavigationCacheMode="Enabled"
|
||||
TargetPageType="{x:Type pages:MapPathingPage}">
|
||||
@@ -115,7 +124,7 @@
|
||||
<ui:SymbolIcon Symbol="Map24" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
<!-- Script16 -->
|
||||
~1~ Script16 @1@
|
||||
<ui:NavigationViewItem Content="录制回放"
|
||||
NavigationCacheMode="Enabled"
|
||||
TargetPageType="{x:Type pages:KeyMouseRecordPage}">
|
||||
@@ -132,7 +141,7 @@
|
||||
<ui:NavigationViewItem.Icon>
|
||||
<ui:SymbolIcon Symbol="XboxController24" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
</ui:NavigationViewItem>-->
|
||||
|
||||
<ui:NavigationViewItem Content="快捷键"
|
||||
NavigationCacheMode="Enabled"
|
||||
@@ -141,13 +150,6 @@
|
||||
<ui:SymbolIcon Symbol="Flash24" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
<!--<ui:NavigationViewItem Content="通知"
|
||||
NavigationCacheMode="Enabled"
|
||||
TargetPageType="{x:Type pages:NotificationSettingsPage}">
|
||||
<ui:NavigationViewItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Alert24" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>-->
|
||||
</ui:NavigationView.MenuItems>
|
||||
<ui:NavigationView.FooterMenuItems>
|
||||
<ui:NavigationViewItem Content="设置"
|
||||
|
||||
@@ -424,12 +424,12 @@
|
||||
<ui:ToggleSwitch Margin="0,0,36,0" IsChecked="{Binding Config.CommonConfig.ExitToTray, Mode=TwoWay}" />
|
||||
</ui:CardControl>
|
||||
|
||||
<ui:TextBlock Margin="0,0,0,8"
|
||||
<!--<ui:TextBlock Margin="0,0,0,8"
|
||||
FontTypography="BodyStrong"
|
||||
Text="通知设置" />
|
||||
Text="通知设置" />-->
|
||||
|
||||
<!-- Webhook -->
|
||||
<ui:CardExpander Margin="0,0,0,12"
|
||||
<!--<ui:CardExpander Margin="0,0,0,12"
|
||||
ContentPadding="0"
|
||||
Icon="{ui:SymbolIcon VirtualNetwork20}">
|
||||
<ui:CardExpander.Header>
|
||||
@@ -523,7 +523,7 @@
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ui:CardExpander>
|
||||
</ui:CardExpander>-->
|
||||
|
||||
<!-- 地图 -->
|
||||
<!--<ui:CardControl Margin="0,0,0,12"
|
||||
|
||||
@@ -35,14 +35,12 @@
|
||||
<ui:TextBlock Grid.Row="0"
|
||||
Margin="0,0,0,8"
|
||||
FontTypography="BodyStrong"
|
||||
Text="键鼠录制回放功能(实验功能)" />
|
||||
Text="键鼠录制回放功能" />
|
||||
<ui:TextBlock Grid.Row="1"
|
||||
Margin="0,0,0,8"
|
||||
Foreground="{ui:ThemeResource TextFillColorTertiaryBrush}"
|
||||
TextWrapping="Wrap">
|
||||
建议在游戏内使用快捷键进行录制,录制完成后在调度器中使用。<Hyperlink Command="{Binding GoToKmScriptUrlCommand}" Foreground="{ui:ThemeResource TextFillColorSecondaryBrush}">
|
||||
点击查看键鼠录制回放功能教程
|
||||
</Hyperlink>
|
||||
建议在游戏内使用快捷键进行录制,
|
||||
</ui:TextBlock>
|
||||
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal">
|
||||
@@ -50,7 +48,7 @@
|
||||
Content="打开脚本目录"
|
||||
Icon="{ui:SymbolIcon FolderOpen24}" />
|
||||
<Separator Width="10" Opacity="0" />
|
||||
<ui:Button Command="{Binding OpenLocalScriptRepoCommand}" Icon="{ui:SymbolIcon Archive24}">
|
||||
<!--<ui:Button Command="{Binding OpenLocalScriptRepoCommand}" Icon="{ui:SymbolIcon Archive24}">
|
||||
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<ui:TextBlock>脚本仓库</ui:TextBlock>
|
||||
<ui:InfoBadge Margin="0,-8,-14,0"
|
||||
@@ -61,7 +59,7 @@
|
||||
Visibility="{Binding Config.ScriptConfig.ScriptRepoHintDotVisible, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
</Grid>
|
||||
</ui:Button>
|
||||
<Separator Width="10" Opacity="0" />
|
||||
<Separator Width="10" Opacity="0" />-->
|
||||
<ui:Button Command="{Binding StartRecordCommand}"
|
||||
Content="开始录制"
|
||||
Icon="{ui:SymbolIcon Record20}"
|
||||
|
||||
@@ -26,7 +26,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel
|
||||
{
|
||||
private readonly ILogger<MainWindowViewModel> _logger;
|
||||
private readonly IConfigService _configService;
|
||||
public string Title => $"BetterGI · 更好的原神 · {Global.Version}{(RuntimeHelper.IsDebug ? " · Dev" : string.Empty)}";
|
||||
public string Title => $"BetterGI · 更好的原神 · 采集版 · {Global.Version}{(RuntimeHelper.IsDebug ? " · Dev" : string.Empty)}";
|
||||
|
||||
[ObservableProperty]
|
||||
public bool _isVisible = true;
|
||||
@@ -69,46 +69,46 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel
|
||||
[SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.RelayCommandGenerator", "MVVMTK0039:Async void returning method annotated with RelayCommand")]
|
||||
private async void OnLoaded()
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var s = OcrFactory.Paddle.Ocr(new Mat(Global.Absolute(@"Assets\Model\PaddleOCR\test_ocr.png"), ImreadModes.Grayscale));
|
||||
Debug.WriteLine("PaddleOcr预热结果:" + s);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
_logger.LogError("PaddleOcr预热异常,解决方案:https://bgi.huiyadan.com/faq.html:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
|
||||
var innerException = e.InnerException;
|
||||
if (innerException != null)
|
||||
{
|
||||
_logger.LogError("PaddleOcr预热内部异常,解决方案:https://bgi.huiyadan.com/faq.html:" + innerException.Source + "\r\n--" + Environment.NewLine + innerException.StackTrace + "\r\n---" + Environment.NewLine + innerException.Message);
|
||||
throw innerException;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Warning("PaddleOcr预热失败,解决方案:https://bgi.huiyadan.com/faq.html," + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await Task.Run(GetNewestInfoAsync);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine("获取最新版本信息失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
|
||||
_logger.LogWarning("获取 BetterGI 最新版本信息失败");
|
||||
}
|
||||
// try
|
||||
// {
|
||||
// await Task.Run(() =>
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// var s = OcrFactory.Paddle.Ocr(new Mat(Global.Absolute(@"Assets\Model\PaddleOCR\test_ocr.png"), ImreadModes.Grayscale));
|
||||
// Debug.WriteLine("PaddleOcr预热结果:" + s);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// Console.WriteLine(e);
|
||||
// _logger.LogError("PaddleOcr预热异常,解决方案:https://bgi.huiyadan.com/faq.html:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
|
||||
// var innerException = e.InnerException;
|
||||
// if (innerException != null)
|
||||
// {
|
||||
// _logger.LogError("PaddleOcr预热内部异常,解决方案:https://bgi.huiyadan.com/faq.html:" + innerException.Source + "\r\n--" + Environment.NewLine + innerException.StackTrace + "\r\n---" + Environment.NewLine + innerException.Message);
|
||||
// throw innerException;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// MessageBox.Warning("PaddleOcr预热失败,解决方案:https://bgi.huiyadan.com/faq.html," + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
|
||||
// }
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// await Task.Run(GetNewestInfoAsync);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// Debug.WriteLine("获取最新版本信息失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message);
|
||||
// _logger.LogWarning("获取 BetterGI 最新版本信息失败");
|
||||
// }
|
||||
|
||||
// Win11下 BitBlt截图方式不可用,需要关闭窗口优化功能
|
||||
if (OsVersionHelper.IsWindows11_OrGreater && TaskContext.Instance().Config.AutoFixWin11BitBlt)
|
||||
@@ -117,7 +117,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel
|
||||
}
|
||||
|
||||
// 更新仓库
|
||||
ScriptRepoUpdater.Instance.AutoUpdate();
|
||||
// ScriptRepoUpdater.Instance.AutoUpdate();
|
||||
}
|
||||
|
||||
private async Task GetNewestInfoAsync()
|
||||
|
||||
@@ -28,6 +28,7 @@ using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BetterGenshinImpact.Core.Video;
|
||||
using BetterGenshinImpact.GameTask.Model.Area;
|
||||
using Vanara.PInvoke;
|
||||
using HotKeySettingModel = BetterGenshinImpact.Model.HotKeySettingModel;
|
||||
@@ -182,20 +183,20 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
||||
);
|
||||
HotKeySettingModels.Add(systemDirectory);
|
||||
|
||||
var timerDirectory = new HotKeySettingModel(
|
||||
"实时任务"
|
||||
);
|
||||
HotKeySettingModels.Add(timerDirectory);
|
||||
|
||||
var soloTaskDirectory = new HotKeySettingModel(
|
||||
"独立任务"
|
||||
);
|
||||
HotKeySettingModels.Add(soloTaskDirectory);
|
||||
|
||||
var macroDirectory = new HotKeySettingModel(
|
||||
"操控辅助"
|
||||
);
|
||||
HotKeySettingModels.Add(macroDirectory);
|
||||
// var timerDirectory = new HotKeySettingModel(
|
||||
// "实时任务"
|
||||
// );
|
||||
// HotKeySettingModels.Add(timerDirectory);
|
||||
//
|
||||
// var soloTaskDirectory = new HotKeySettingModel(
|
||||
// "独立任务"
|
||||
// );
|
||||
// HotKeySettingModels.Add(soloTaskDirectory);
|
||||
//
|
||||
// var macroDirectory = new HotKeySettingModel(
|
||||
// "操控辅助"
|
||||
// );
|
||||
// HotKeySettingModels.Add(macroDirectory);
|
||||
|
||||
var devDirectory = new HotKeySettingModel(
|
||||
"开发者"
|
||||
@@ -233,7 +234,7 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
||||
}
|
||||
));
|
||||
|
||||
var autoPickEnabledHotKeySettingModel = new HotKeySettingModel(
|
||||
/*var autoPickEnabledHotKeySettingModel = new HotKeySettingModel(
|
||||
"自动拾取开关",
|
||||
nameof(Config.HotKeyConfig.AutoPickEnabledHotkey),
|
||||
Config.HotKeyConfig.AutoPickEnabledHotkey,
|
||||
@@ -424,7 +425,7 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
||||
{
|
||||
OnKeyDownAction = (_, _) => { OneKeyFightTask.Instance.KeyDown(); },
|
||||
OnKeyUpAction = (_, _) => { OneKeyFightTask.Instance.KeyUp(); }
|
||||
});
|
||||
});*/
|
||||
|
||||
devDirectory.Children.Add(new HotKeySettingModel(
|
||||
"启动/停止键鼠录制",
|
||||
@@ -451,6 +452,7 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
||||
}
|
||||
));
|
||||
|
||||
/*
|
||||
devDirectory.Children.Add(new HotKeySettingModel(
|
||||
"(开发)获取当前大地图中心点位置",
|
||||
nameof(Config.HotKeyConfig.RecBigMapPosHotkey),
|
||||
@@ -499,6 +501,7 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
||||
}
|
||||
}
|
||||
));
|
||||
*/
|
||||
|
||||
// DEBUG
|
||||
if (RuntimeHelper.IsDebug)
|
||||
@@ -508,13 +511,13 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
||||
);
|
||||
HotKeySettingModels.Add(debugDirectory);
|
||||
|
||||
soloTaskDirectory.Children.Add(new HotKeySettingModel(
|
||||
"启动/停止自动活动音游",
|
||||
nameof(Config.HotKeyConfig.AutoMusicGameHotkey),
|
||||
Config.HotKeyConfig.AutoMusicGameHotkey,
|
||||
Config.HotKeyConfig.AutoMusicGameHotkeyType,
|
||||
(_, _) => { SwitchSoloTask(_taskSettingsPageViewModel.SwitchAutoMusicGameCommand); }
|
||||
));
|
||||
// soloTaskDirectory.Children.Add(new HotKeySettingModel(
|
||||
// "启动/停止自动活动音游",
|
||||
// nameof(Config.HotKeyConfig.AutoMusicGameHotkey),
|
||||
// Config.HotKeyConfig.AutoMusicGameHotkey,
|
||||
// Config.HotKeyConfig.AutoMusicGameHotkeyType,
|
||||
// (_, _) => { SwitchSoloTask(_taskSettingsPageViewModel.SwitchAutoMusicGameCommand); }
|
||||
// ));
|
||||
// HotKeySettingModels.Add(new HotKeySettingModel(
|
||||
// "(测试)启动/停止自动追踪",
|
||||
// nameof(Config.HotKeyConfig.AutoTrackHotkey),
|
||||
@@ -544,6 +547,8 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
||||
// // _taskSettingsPageViewModel.OnSwitchAutoTrackPath();
|
||||
// }
|
||||
// ));
|
||||
|
||||
FfmpegRecorder ffmpegRecorder = new FfmpegRecorder();
|
||||
debugDirectory.Children.Add(new HotKeySettingModel(
|
||||
"(测试)测试",
|
||||
nameof(Config.HotKeyConfig.Test1Hotkey),
|
||||
@@ -574,14 +579,8 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
||||
|
||||
// 拾取物品
|
||||
// Task.Run(async () => { await new ScanPickTask().Start(new CancellationToken()); });
|
||||
|
||||
Simulation.SendInput.Keyboard.KeyDown(false, User32.VK.VK_LMENU);
|
||||
// TaskContext.Instance().PostMessageSimulator.KeyDown(User32.VK.VK_MENU);
|
||||
Thread.Sleep(500);
|
||||
GameCaptureRegion.GameRegion1080PPosMove(200, 100);
|
||||
Thread.Sleep(500);
|
||||
// TaskContext.Instance().PostMessageSimulator.KeyUp(User32.VK.VK_MENU);
|
||||
Simulation.SendInput.Keyboard.KeyUp(false, User32.VK.VK_LMENU);
|
||||
|
||||
ffmpegRecorder.Start();
|
||||
}
|
||||
));
|
||||
debugDirectory.Children.Add(new HotKeySettingModel(
|
||||
@@ -591,8 +590,9 @@ public partial class HotKeyPageViewModel : ObservableObject, IViewModel
|
||||
Config.HotKeyConfig.Test2HotkeyType,
|
||||
(_, _) =>
|
||||
{
|
||||
GoToCraftingBenchTask goToCraftingBenchTask = new GoToCraftingBenchTask();
|
||||
Task.Run(async () => { await goToCraftingBenchTask.Start("璃月", new CancellationToken()); });
|
||||
// GoToCraftingBenchTask goToCraftingBenchTask = new GoToCraftingBenchTask();
|
||||
// Task.Run(async () => { await goToCraftingBenchTask.Start("璃月", new CancellationToken()); });
|
||||
ffmpegRecorder.Stop();
|
||||
}
|
||||
));
|
||||
|
||||
|
||||
64
Build/setup_build_for_train.cmd
Normal file
64
Build/setup_build_for_train.cmd
Normal file
@@ -0,0 +1,64 @@
|
||||
cd /d %~dp0
|
||||
if exist dist rd /s /q dist
|
||||
mkdir dist\BetterGI
|
||||
|
||||
@echo [prepare compiler]
|
||||
for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath`) do set "path=%path%;%%i\MSBuild\Current\Bin;%%i\Common7\IDE"
|
||||
|
||||
@echo [prepare version]
|
||||
cd /d ..\BetterGenshinImpact
|
||||
set "script=Get-Content 'BetterGenshinImpact.csproj' | Select-String -Pattern 'AssemblyVersion\>(.*)\<\/AssemblyVersion' | ForEach-Object { $_.Matches.Groups[1].Value }"
|
||||
for /f "usebackq delims=" %%i in (`powershell -NoLogo -NoProfile -Command "%script%"`) do set version=%%i
|
||||
echo current version is %version%
|
||||
if "%b%"=="" ( set "b=%version%" )
|
||||
|
||||
set "tmpfolder=%~dp0dist\BetterGI"
|
||||
set "archiveFile=BetterGI_T_v%b%.7z"
|
||||
set "setupFile=BetterGI_T_Setup_v%b%.exe"
|
||||
|
||||
echo [build app using vs2022]
|
||||
cd /d %~dp0
|
||||
rd /s /q ..\BetterGenshinImpact\bin\x64\Release\net8.0-windows10.0.22621.0\publish\win-x64\
|
||||
cd ..\
|
||||
dotnet publish -c Release -p:PublishProfile=FolderProfile
|
||||
|
||||
echo [pack app using 7z]
|
||||
cd /d %~dp0
|
||||
cd /d ..\BetterGenshinImpact\bin\x64\Release\net8.0-windows10.0.22621.0\publish\win-x64\
|
||||
xcopy * "%tmpfolder%" /E /C /I /Y
|
||||
cd /d %~dp0
|
||||
del /f /q %tmpfolder%\*.lib
|
||||
del /f /q %tmpfolder%\*ffmpeg*.dll
|
||||
|
||||
:: 一些训练版本不需要的依赖
|
||||
del /f /q %tmpfolder%\onnxruntime*.dll
|
||||
del /f /q %tmpfolder%\paddle*.dll
|
||||
rd /s /q %tmpfolder%\Assets\Model
|
||||
|
||||
|
||||
|
||||
:: 添加一些配置文件开始(大文件不适合放在Github)
|
||||
if exist "E:\HuiTask\BetterGIBuild\BetterGI_train" (
|
||||
xcopy "E:\HuiTask\BetterGIBuild\BetterGI_train\*" "%tmpfolder%" /E /C /I /Y
|
||||
)
|
||||
:: 添加一些配置文件结束
|
||||
|
||||
MicaSetup.Tools\7-Zip\7z a publish.7z %tmpfolder%\ -t7z -mx=5 -mf=BCJ2 -r -y
|
||||
copy /y publish.7z .\MicaSetup\Resources\Setups\publish.7z
|
||||
if exist "%zipFile%" ( del /f /q "%zipfile%" )
|
||||
rename publish.7z %archiveFile%
|
||||
|
||||
@echo [build uninst using vs2022]
|
||||
msbuild MicaSetup\MicaSetup.Uninst.csproj /t:Rebuild /p:Configuration=Release /p:DeployOnBuild=true /p:PublishProfile=FolderProfile /restore
|
||||
|
||||
@echo [build setup using vs2022]
|
||||
copy /y .\MicaSetup\bin\Release\net472\MicaSetup.exe .\MicaSetup\Resources\Setups\Uninst.exe
|
||||
msbuild MicaSetup\MicaSetup.csproj /t:Build /p:Configuration=Release /p:DeployOnBuild=true /p:PublishProfile=FolderProfile /restore
|
||||
|
||||
@echo [finish]
|
||||
del /f /q MicaSetup.exe
|
||||
copy /y .\MicaSetup\bin\Release\net472\MicaSetup.exe .\
|
||||
rename MicaSetup.exe %setupFile%
|
||||
rd /s /q dist\BetterGI
|
||||
|
||||
@pause
|
||||
Reference in New Issue
Block a user