using BetterGenshinImpact.Core.Config; using BetterGenshinImpact.Core.Recorder; using BetterGenshinImpact.Core.Script; using BetterGenshinImpact.GameTask; using BetterGenshinImpact.GameTask.Model.Enum; using BetterGenshinImpact.Model; using BetterGenshinImpact.Service.Interface; using BetterGenshinImpact.View.Windows; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Interop; using BetterGenshinImpact.Core.Recorder.Model; using BetterGenshinImpact.GameTask.Common; using BetterGenshinImpact.Helpers; using BetterGenshinImpact.Helpers.Device; using Wpf.Ui; using Wpf.Ui.Controls; using Wpf.Ui.Violeta.Controls; using MessageBoxButton = Wpf.Ui.Controls.MessageBoxButton; namespace BetterGenshinImpact.ViewModel.Pages; public partial class KeyMouseRecordPageViewModel : ObservableObject, INavigationAware, IViewModel { private readonly ILogger _logger = App.GetLogger(); private readonly string scriptPath = Global.Absolute(@"User\KeyMouseScript"); [ObservableProperty] private ObservableCollection _scriptItems = []; [ObservableProperty] private bool _isRecording = false; private readonly ISnackbarService _snackbarService; public AllConfig Config { get; set; } string fileName = $"{DateTime.Now:yyyyMMddHH_mmssffff}"; public KeyMouseRecordPageViewModel(ISnackbarService snackbarService, IConfigService configService) { _snackbarService = snackbarService; Config = configService.Get(); } private void InitScriptListViewData() { _scriptItems.Clear(); var directoryInfos = LoadScriptDirectories(scriptPath) .OrderByDescending(d => d.CreationTime) .ToList(); foreach (var d in directoryInfos) { _scriptItems.Add(new KeyMouseScriptItem { Name = d.Name, Path = d.FullName, CreateTime = d.CreationTime, CreateTimeStr = d.CreationTime.ToString("yyyy-MM-dd HH:mm:ss") }); } } private List LoadScriptDirectories(string folder) { if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } var directories = Directory.GetDirectories(folder); return directories.Select(dir => new DirectoryInfo(dir)).ToList(); } public void OnNavigatedTo() { InitScriptListViewData(); } public void OnNavigatedFrom() { } [RelayCommand] public async Task OnStartRecord() { var s = RecordContext.Instance.SysParams; // 提前实例化,避免延迟 Debug.WriteLine(s.EnhancePointerPrecision); if (!TaskContext.Instance().IsInitialized) { Toast.Warning("请先在启动页,启动截图器再使用本功能"); return; } if (TaskContext.Instance().Config.CommonConfig.ProcessCheckEnabled && !RuntimeHelper.IsDebug) { try { if (EnvironmentUtil.IsProcessRunning("QQ") || EnvironmentUtil.IsProcessRunning("WeChat") || EnvironmentUtil.IsProcessRunning("dingtalk") || EnvironmentUtil.IsProcessRunning("Feishu")) { throw new Exception("请关闭 QQ、微信、飞书等聊天软件再进行录制"); } if (EnvironmentUtil.GetMasterVolume() <= 0) { throw new Exception("请保持系统音量大于0再进行录制"); } } catch (Exception e) { // await MessageBox.ShowAsync(e.Message, "校验错误", System.Windows.MessageBoxButton.OK, MessageBoxImage.Error); // SystemControl.ActivateWindow(new WindowInteropHelper(UIDispatcherHelper.MainWindow).Handle); Toast.Error(e.Message); _logger.LogError(e.Message); return; } } fileName = $"{DateTime.Now:yyyy_MM_dd_HH_mm_ss}"; await Task.Run(() => { try { var pcFolder = Global.Absolute(@$"User/KeyMouseScript/{fileName}"); Directory.CreateDirectory(pcFolder); // 移动PC信息 var src= Global.Absolute(@$"User/pc.json"); if (File.Exists(src)) { File.Copy(Global.Absolute(@$"User/pc.json"), Path.Combine(pcFolder, "pc.json"), true); } } catch (Exception e) { TaskControl.Logger.LogDebug("移动PC信息失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message); } }); if (!IsRecording) { IsRecording = true; SystemSettingsManager.GetSystemSettings(); SystemSettingsManager.SetSystemSettings(); try { await GlobalKeyMouseRecord.Instance.StartRecord(fileName); } catch (Exception e) { _logger.LogDebug(e, "启动录制时发生异常"); _logger.LogError(e.Message); IsRecording = false; } } } [RelayCommand] public void OnStopRecord() { if (IsRecording) { try { GlobalKeyMouseRecord.Instance.StopRecord(); // Genshin Copilot Macro // File.WriteAllText(Path.Combine(scriptPath, $"{fileName}/{fileName}.json"), macro); // 刷新ListView InitScriptListViewData(); IsRecording = false; } catch (Exception e) { _logger.LogDebug(e, "停止录制时发生异常"); _logger.LogError(e.Message); } SystemSettingsManager.RestoreSystemSettings(); Task.Run(() => { try { var pcFolder = Global.Absolute(@$"User/KeyMouseScript/{fileName}"); Directory.CreateDirectory(pcFolder); // 移动PC信息 var src= Global.Absolute(@$"User/pc.json"); if (File.Exists(src)) { File.Copy(Global.Absolute(@$"User/pc.json"), Path.Combine(pcFolder, "pc.json"), true); } } catch (Exception e) { TaskControl.Logger.LogDebug("移动PC信息失败:" + e.Source + "\r\n--" + Environment.NewLine + e.StackTrace + "\r\n---" + Environment.NewLine + e.Message); } }); } } [RelayCommand] public async Task OnStartPlay(string path) { var file = new FileInfo(Path.Combine(path, "systemInfo.json")); var name = file.Directory?.Name; _logger.LogInformation("重放开始:{Name}", name); try { await new TaskRunner(DispatcherTimerOperationEnum.UseSelfCaptureImage) .RunAsync(async () => await KeyMouseMacroPlayerJsonLine.PlayMacro(file.FullName, CancellationContext.Instance.Cts.Token)); } catch (Exception e) { _logger.LogError(e, "重放脚本时发生异常"); } finally { _logger.LogInformation("重放结束:{Name}", name); } } [RelayCommand] public void OnOpenScriptFolder() { Process.Start("explorer.exe", scriptPath); } [RelayCommand] public void OnEditScript(KeyMouseScriptItem? item) { if (item == null) { return; } try { var str = PromptDialog.Prompt("请输入要修改为的名称(实际就是文件名)", "修改名称"); if (!string.IsNullOrEmpty(str)) { // 检查原始文件是否存在 var originalFilePath = Path.Combine(scriptPath, item.Name); if (File.Exists(originalFilePath)) { // 重命名文件 File.Move(originalFilePath, Path.Combine(scriptPath, str + ".json")); _snackbarService.Show( "修改名称成功", $"脚本名称 {item.Name} 修改为 {str}", ControlAppearance.Success, null, TimeSpan.FromSeconds(2) ); } } } catch (Exception) { _snackbarService.Show( "修改失败", $"{item.Name} 修改失败", ControlAppearance.Danger, null, TimeSpan.FromSeconds(3) ); } finally { InitScriptListViewData(); } } [RelayCommand] public void OnDeleteScript(KeyMouseScriptItem? item) { if (item == null) { return; } try { var path = item.Path; // 校验文件夹是否在 scriptPath 下 if (!path.StartsWith(scriptPath)) { _snackbarService.Show( "删除失败", $"{path} 删除失败,不在脚本目录下", ControlAppearance.Danger, null, TimeSpan.FromSeconds(3) ); return; } // 删除目录 Directory.Delete(path, true); _snackbarService.Show( "删除成功", $"{item.Name} 已经被删除", ControlAppearance.Success, null, TimeSpan.FromSeconds(2) ); } catch (Exception) { _snackbarService.Show( "删除失败", $"{item.Name} 删除失败", ControlAppearance.Danger, null, TimeSpan.FromSeconds(3) ); } finally { InitScriptListViewData(); } } [RelayCommand] public void OnGoToKmScriptUrl() { Process.Start(new ProcessStartInfo("https://bgi.huiyadan.com/feats/autos/kmscript.html") { UseShellExecute = true }); } [RelayCommand] public void OnOpenLocalScriptRepo() { Config.ScriptConfig.ScriptRepoHintDotVisible = false; ScriptRepoUpdater.Instance.OpenLocalRepoInWebView(); } }