mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-03-15 07:43:20 +08:00
fix: 修复命令行启动时自动更新阻塞导致 StartGameTask 跳过等待主界面的问题 (#2902)
Co-authored-by: ShadowLemoon <119576779+ShadowLemoon@users.noreply.github.com>
This commit is contained in:
@@ -56,6 +56,12 @@ public class ScriptRepoUpdater : Singleton<ScriptRepoUpdater>
|
||||
/// </summary>
|
||||
public event EventHandler? AutoUpdateStateChanged;
|
||||
|
||||
/// <summary>
|
||||
/// 命令行启动时并行执行的自动更新 Task。
|
||||
/// StartGameTask 结束后会 await 此 Task,确保更新完成后再执行任务。
|
||||
/// </summary>
|
||||
public Task? CommandLineAutoUpdateTask { get; set; }
|
||||
|
||||
// 仓储位置
|
||||
public static readonly string ReposPath = Global.Absolute("Repos");
|
||||
|
||||
|
||||
96
BetterGenshinImpact/Helpers/CommandLineOptions.cs
Normal file
96
BetterGenshinImpact/Helpers/CommandLineOptions.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace BetterGenshinImpact.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// 命令行参数统一解析,启动时解析一次,各处查询解析结果。
|
||||
/// </summary>
|
||||
public class CommandLineOptions
|
||||
{
|
||||
private static CommandLineOptions? _instance;
|
||||
|
||||
public static CommandLineOptions Instance => _instance ??= Parse(Environment.GetCommandLineArgs());
|
||||
|
||||
public CommandLineAction Action { get; }
|
||||
|
||||
/// <summary>
|
||||
/// startOneDragon 时可选的配置名称(第 3 个参数)
|
||||
/// </summary>
|
||||
public string? OneDragonConfigName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// --startGroups / --TaskProgress 时传入的组名列表(第 3 个参数起)
|
||||
/// </summary>
|
||||
public string[] GroupNames { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// 是否有命令行任务参数(startOneDragon / --startGroups / --TaskProgress / start)
|
||||
/// </summary>
|
||||
public bool HasTaskArgs => Action != CommandLineAction.None;
|
||||
|
||||
/// <summary>
|
||||
/// 是否是需要 StartGameTask 自行处理游戏启动的命令
|
||||
/// (一条龙、配置组、任务进度由各自流程中的 StartGameTask 启动游戏)
|
||||
/// </summary>
|
||||
public bool ShouldDeferGameStart => Action is CommandLineAction.StartOneDragon
|
||||
or CommandLineAction.StartGroups
|
||||
or CommandLineAction.TaskProgress;
|
||||
|
||||
private CommandLineOptions(CommandLineAction action, string? oneDragonConfigName = null, string[]? groupNames = null)
|
||||
{
|
||||
Action = action;
|
||||
OneDragonConfigName = oneDragonConfigName;
|
||||
GroupNames = groupNames ?? [];
|
||||
}
|
||||
|
||||
internal static CommandLineOptions Parse(string[] args)
|
||||
{
|
||||
if (args.Length <= 1)
|
||||
return new CommandLineOptions(CommandLineAction.None);
|
||||
|
||||
var arg1 = args[1].Trim();
|
||||
var extra = args.Skip(2).Select(x => x.Trim()).ToArray();
|
||||
|
||||
if (arg1.Contains("startOneDragon", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new CommandLineOptions(CommandLineAction.StartOneDragon,
|
||||
oneDragonConfigName: extra.Length > 0 ? extra[0] : null);
|
||||
}
|
||||
|
||||
if (arg1.Equals("--startGroups", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new CommandLineOptions(CommandLineAction.StartGroups, groupNames: extra);
|
||||
}
|
||||
|
||||
if (arg1.Equals("--TaskProgress", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new CommandLineOptions(CommandLineAction.TaskProgress, groupNames: extra);
|
||||
}
|
||||
|
||||
if (arg1.Contains("start", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new CommandLineOptions(CommandLineAction.Start);
|
||||
}
|
||||
|
||||
return new CommandLineOptions(CommandLineAction.None);
|
||||
}
|
||||
}
|
||||
|
||||
public enum CommandLineAction
|
||||
{
|
||||
/// <summary>双击启动,无命令行参数</summary>
|
||||
None,
|
||||
|
||||
/// <summary>纯 "start" — 仅启动截图器</summary>
|
||||
Start,
|
||||
|
||||
/// <summary>startOneDragon — 启动一条龙</summary>
|
||||
StartOneDragon,
|
||||
|
||||
/// <summary>--startGroups — 启动调度组</summary>
|
||||
StartGroups,
|
||||
|
||||
/// <summary>--TaskProgress — 启动任务进度</summary>
|
||||
TaskProgress,
|
||||
}
|
||||
@@ -9,8 +9,7 @@ using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using BetterGenshinImpact.Core.Script;
|
||||
using BetterGenshinImpact.GameTask;
|
||||
using BetterGenshinImpact.GameTask.Common;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using BetterGenshinImpact.Helpers;
|
||||
using Wpf.Ui;
|
||||
|
||||
namespace BetterGenshinImpact.Service;
|
||||
@@ -49,66 +48,56 @@ public class ApplicationHostService(IServiceProvider serviceProvider) : IHostedS
|
||||
{
|
||||
_navigationWindow = (serviceProvider.GetService(typeof(INavigationWindow)) as INavigationWindow)!;
|
||||
_navigationWindow!.ShowWindow();
|
||||
//
|
||||
var args = Environment.GetCommandLineArgs();
|
||||
|
||||
if (args.Length > 1)
|
||||
var cmdOptions = CommandLineOptions.Instance;
|
||||
|
||||
if (cmdOptions.HasTaskArgs)
|
||||
{
|
||||
|
||||
//无论如何,先跳到主页,否则在通过参数的任务在执行完之前,不会加载快捷键
|
||||
_ = _navigationWindow.Navigate(typeof(HomePage));
|
||||
|
||||
// 命令行启动时,先等待自动更新订阅脚本完成,再运行配置组/一条龙
|
||||
// (正常双击启动在 MainWindowViewModel.OnLoaded 中以 fire-and-forget 方式调用)
|
||||
// 命令行启动时,并行更新订阅脚本(不阻塞游戏启动和导航)
|
||||
// StartGameTask 会在游戏进入主界面后等待此 Task 完成,再开始执行任务
|
||||
var scriptConfig = TaskContext.Instance().Config.ScriptConfig;
|
||||
if (scriptConfig.AutoUpdateBeforeCommandLineRun)
|
||||
{
|
||||
await Task.Run(() => ScriptRepoUpdater.Instance.AutoUpdateSubscribedScripts());
|
||||
ScriptRepoUpdater.Instance.CommandLineAutoUpdateTask =
|
||||
Task.Run(() => ScriptRepoUpdater.Instance.AutoUpdateSubscribedScripts());
|
||||
}
|
||||
|
||||
if (args[1].Contains("startOneDragon", StringComparison.InvariantCultureIgnoreCase))
|
||||
switch (cmdOptions.Action)
|
||||
{
|
||||
case CommandLineAction.StartOneDragon:
|
||||
// 通过命令行参数启动「一条龙」 => 跳转到一条龙配置页。
|
||||
_ = _navigationWindow.Navigate(typeof(OneDragonFlowPage));
|
||||
// 后续代码在 OneDragonFlowViewModel / OnLoaded 中。
|
||||
break;
|
||||
|
||||
// 通过命令行参数启动「一条龙」 => 跳转到一条龙配置页。
|
||||
_ = _navigationWindow.Navigate(typeof(OneDragonFlowPage));
|
||||
// 后续代码在 OneDragonFlowViewModel / OnLoaded 中。
|
||||
}
|
||||
else if (args[1].Trim().Equals("--startGroups", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
// 通过命令行参数启动「调度组」 => 跳转到调度器配置页。
|
||||
_ = _navigationWindow.Navigate(typeof(ScriptControlPage));
|
||||
if (args.Length > 2)
|
||||
{
|
||||
// 获取调度组
|
||||
var names = args.Skip(2).ToArray().Select(x => x.Trim()).ToArray();
|
||||
// 启动调度器
|
||||
var scheduler = App.GetService<ScriptControlViewModel>();
|
||||
scheduler?.OnStartMultiScriptGroupWithNamesAsync(names);
|
||||
}
|
||||
}else if (args[1].Trim().Equals("--TaskProgress", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
case CommandLineAction.StartGroups:
|
||||
// 通过命令行参数启动「调度组」 => 跳转到调度器配置页。
|
||||
_ = _navigationWindow.Navigate(typeof(ScriptControlPage));
|
||||
if (cmdOptions.GroupNames.Length > 0)
|
||||
{
|
||||
var scheduler = App.GetService<ScriptControlViewModel>();
|
||||
scheduler?.OnStartMultiScriptGroupWithNamesAsync(cmdOptions.GroupNames);
|
||||
}
|
||||
break;
|
||||
|
||||
// 通过命令行参数启动「调度组」 => 跳转到调度器配置页。
|
||||
_ = _navigationWindow.Navigate(typeof(ScriptControlPage));
|
||||
if (args.Length > 1)
|
||||
{
|
||||
// 获取调度组
|
||||
var names = args.Skip(2).ToArray().Select(x => x.Trim()).ToArray();
|
||||
// 启动调度器
|
||||
var scheduler = App.GetService<ScriptControlViewModel>();
|
||||
scheduler?.OnStartMultiScriptTaskProgressAsync(names);
|
||||
}
|
||||
}
|
||||
else if (args[1].Contains("start"))
|
||||
{
|
||||
// 通过命令行参数打开「启动页开关」 => 跳转到主页。
|
||||
_ = _navigationWindow.Navigate(typeof(HomePage));
|
||||
// 后续代码在 HomePageViewModel / OnLoaded 中。
|
||||
}
|
||||
else
|
||||
{
|
||||
// 其它命令行参数 => 跳转到主页。
|
||||
_ = _navigationWindow.Navigate(typeof(HomePage));
|
||||
case CommandLineAction.TaskProgress:
|
||||
// 通过命令行参数启动「任务进度」 => 跳转到调度器配置页。
|
||||
_ = _navigationWindow.Navigate(typeof(ScriptControlPage));
|
||||
if (cmdOptions.GroupNames.Length > 0)
|
||||
{
|
||||
var scheduler = App.GetService<ScriptControlViewModel>();
|
||||
scheduler?.OnStartMultiScriptTaskProgressAsync(cmdOptions.GroupNames);
|
||||
}
|
||||
break;
|
||||
|
||||
case CommandLineAction.Start:
|
||||
// 通过命令行参数打开「启动页开关」 => 跳转到主页。
|
||||
_ = _navigationWindow.Navigate(typeof(HomePage));
|
||||
// 后续代码在 HomePageViewModel / OnLoaded 中。
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -621,5 +621,13 @@ public partial class ScriptService : IScriptService
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 等待命令行启动时并行执行的自动更新完成(如果有)
|
||||
var pendingUpdate = ScriptRepoUpdater.Instance.CommandLineAutoUpdateTask;
|
||||
if (pendingUpdate != null)
|
||||
{
|
||||
await pendingUpdate;
|
||||
ScriptRepoUpdater.Instance.CommandLineAutoUpdateTask = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ public partial class MainWindowViewModel : ObservableObject, IViewModel
|
||||
// 预热OCR
|
||||
await OcrPreheating();
|
||||
|
||||
if (Environment.GetCommandLineArgs().Length > 1)
|
||||
if (CommandLineOptions.Instance.HasTaskArgs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -133,8 +133,9 @@ public partial class HomePageViewModel : ViewModel
|
||||
|
||||
_autoRun = false;
|
||||
|
||||
var args = Environment.GetCommandLineArgs();
|
||||
if (args.Length > 1 && args[1].Contains("start"))
|
||||
// 只对纯 "start" 参数自动启动截图器
|
||||
// startOneDragon、--startGroups 等由各自流程中的 StartGameTask 处理
|
||||
if (CommandLineOptions.Instance.Action == CommandLineAction.Start)
|
||||
{
|
||||
_ = OnStartTriggerAsync();
|
||||
}
|
||||
|
||||
@@ -545,15 +545,16 @@ public partial class OneDragonFlowViewModel : ViewModel
|
||||
}
|
||||
_autoRun = false;
|
||||
//
|
||||
var args = Environment.GetCommandLineArgs();
|
||||
if (args.Length > 1 && args[1].Contains("startOneDragon"))
|
||||
var cmdOptions = CommandLineOptions.Instance;
|
||||
if (cmdOptions.Action == CommandLineAction.StartOneDragon)
|
||||
{
|
||||
// 通过命令行参数启动一条龙。
|
||||
if (args.Length > 2)
|
||||
if (cmdOptions.OneDragonConfigName != null)
|
||||
{
|
||||
// 从命令行参数中提取一条龙配置名称。
|
||||
_logger.LogInformation($"参数指定的一条龙配置:{args[2]}");
|
||||
var argsOneDragonConfig = ConfigList.FirstOrDefault(x => x.Name == args[2], null);
|
||||
_logger.LogInformation($"参数指定的一条龙配置:{cmdOptions.OneDragonConfigName}");
|
||||
var argsOneDragonConfig = ConfigList.FirstOrDefault(x =>
|
||||
string.Equals(x.Name, cmdOptions.OneDragonConfigName, StringComparison.Ordinal));
|
||||
if (argsOneDragonConfig != null)
|
||||
{
|
||||
// 设定配置,配置下拉框会选定。
|
||||
|
||||
Reference in New Issue
Block a user