mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-21 09:45:48 +08:00
@@ -54,9 +54,6 @@ public class GearTaskData
|
||||
[JsonProperty("parameters")]
|
||||
public string? Parameters { get; set; } = "{}";
|
||||
|
||||
[JsonProperty("group_config_json")]
|
||||
public string? GroupConfigJson { get; set; }
|
||||
|
||||
[JsonProperty("created_time")]
|
||||
public DateTime CreatedTime { get; set; } = DateTime.Now;
|
||||
|
||||
@@ -68,4 +65,4 @@ public class GearTaskData
|
||||
|
||||
[JsonProperty("children")]
|
||||
public List<GearTaskData> Children { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ using BetterGenshinImpact.Model.Gear.Tasks;
|
||||
using BetterGenshinImpact.Model.Gear.Parameter;
|
||||
using BetterGenshinImpact.Core.Script;
|
||||
using BetterGenshinImpact.Core.Config;
|
||||
using BetterGenshinImpact.Core.Script.Group;
|
||||
using BetterGenshinImpact.Service.GearTask;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
@@ -73,9 +72,8 @@ public class GearTaskConverter
|
||||
/// </summary>
|
||||
/// <param name="taskData">任务数据</param>
|
||||
/// <param name="parent">父任务</param>
|
||||
/// <param name="inheritedGroupConfig">从父任务组继承下来的配置</param>
|
||||
/// <returns>转换后的任务</returns>
|
||||
public async Task<BaseGearTask> ConvertTaskDataAsync(GearTaskData taskData, BaseGearTask? parent = null, ScriptGroupConfig? inheritedGroupConfig = null)
|
||||
public async Task<BaseGearTask> ConvertTaskDataAsync(GearTaskData taskData, BaseGearTask? parent = null)
|
||||
{
|
||||
if (taskData == null)
|
||||
{
|
||||
@@ -84,7 +82,6 @@ public class GearTaskConverter
|
||||
|
||||
try
|
||||
{
|
||||
var currentGroupConfig = GearTaskGroupConfigHelper.Deserialize(taskData.GroupConfigJson) ?? inheritedGroupConfig;
|
||||
BaseGearTask task;
|
||||
|
||||
// 如果是目录类型或者任务被禁用,创建容器任务
|
||||
@@ -109,7 +106,7 @@ public class GearTaskConverter
|
||||
else
|
||||
{
|
||||
// 使用工厂创建具体的任务实例
|
||||
var preparedTaskData = PrepareTaskDataForExecution(taskData, currentGroupConfig);
|
||||
var preparedTaskData = PrepareTaskDataForExecution(taskData);
|
||||
task = await _taskFactory.CreateTaskAsync(preparedTaskData);
|
||||
task.Father = parent;
|
||||
|
||||
@@ -126,7 +123,7 @@ public class GearTaskConverter
|
||||
{
|
||||
try
|
||||
{
|
||||
var childTask = await ConvertTaskDataAsync(childData, task, currentGroupConfig);
|
||||
var childTask = await ConvertTaskDataAsync(childData, task);
|
||||
task.Children.Add(childTask);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -372,60 +369,23 @@ public class GearTaskConverter
|
||||
return result;
|
||||
}
|
||||
|
||||
private GearTaskData PrepareTaskDataForExecution(GearTaskData taskData, ScriptGroupConfig? groupConfig)
|
||||
private GearTaskData PrepareTaskDataForExecution(GearTaskData taskData)
|
||||
{
|
||||
if (string.Equals(taskData.TaskType, "Javascript", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return PrepareJavascriptTaskDataForExecution(taskData, groupConfig);
|
||||
}
|
||||
|
||||
if (!string.Equals(taskData.TaskType, "Pathing", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (string.Equals(taskData.TaskType, "Shell", StringComparison.OrdinalIgnoreCase) &&
|
||||
groupConfig?.EnableShellConfig == true)
|
||||
{
|
||||
return CreateCopiedTaskData(taskData, JsonConvert.SerializeObject(groupConfig.ShellConfig));
|
||||
}
|
||||
|
||||
return taskData;
|
||||
}
|
||||
|
||||
return PreparePathingTaskDataForExecution(taskData, groupConfig);
|
||||
}
|
||||
|
||||
private GearTaskData PrepareJavascriptTaskDataForExecution(GearTaskData taskData, ScriptGroupConfig? groupConfig)
|
||||
{
|
||||
var parameters = DeserializeJavascriptParams(taskData.Parameters);
|
||||
if (string.IsNullOrWhiteSpace(parameters.FolderName))
|
||||
{
|
||||
parameters.FolderName = ExtractTaskFolderName(taskData.Path);
|
||||
}
|
||||
|
||||
if (parameters.PathingPartyConfig == null && groupConfig != null)
|
||||
{
|
||||
parameters.PathingPartyConfig = groupConfig.PathingConfig;
|
||||
}
|
||||
|
||||
return CreateCopiedTaskData(taskData, JsonConvert.SerializeObject(parameters));
|
||||
}
|
||||
|
||||
private GearTaskData PreparePathingTaskDataForExecution(GearTaskData taskData, ScriptGroupConfig? groupConfig)
|
||||
{
|
||||
var parameters = DeserializePathingParams(taskData.Parameters);
|
||||
if (parameters.PathingPartyConfig == null && groupConfig != null)
|
||||
{
|
||||
parameters.PathingPartyConfig = groupConfig.PathingConfig;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(parameters.Path)
|
||||
&& !TryExtractPathingRepoRelativePath(parameters.Path, out _))
|
||||
{
|
||||
return CreateCopiedTaskData(taskData, JsonConvert.SerializeObject(parameters));
|
||||
return taskData;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(taskData.Path))
|
||||
{
|
||||
return CreateCopiedTaskData(taskData, JsonConvert.SerializeObject(parameters));
|
||||
return taskData;
|
||||
}
|
||||
|
||||
if (TryExtractPathingRepoRelativePath(taskData.Path, out var repoRelativePath)
|
||||
@@ -438,7 +398,20 @@ public class GearTaskConverter
|
||||
parameters.Path = taskData.Path.Trim().TrimEnd('\\', '/');
|
||||
}
|
||||
|
||||
return CreateCopiedTaskData(taskData, JsonConvert.SerializeObject(parameters));
|
||||
return new GearTaskData
|
||||
{
|
||||
Name = taskData.Name,
|
||||
TaskType = taskData.TaskType,
|
||||
Path = taskData.Path,
|
||||
IsEnabled = taskData.IsEnabled,
|
||||
IsDirectory = taskData.IsDirectory,
|
||||
IsExpanded = taskData.IsExpanded,
|
||||
Parameters = JsonConvert.SerializeObject(parameters),
|
||||
CreatedTime = taskData.CreatedTime,
|
||||
ModifiedTime = taskData.ModifiedTime,
|
||||
Priority = taskData.Priority,
|
||||
Children = taskData.Children
|
||||
};
|
||||
}
|
||||
|
||||
private PathingGearTaskParams DeserializePathingParams(string? parametersJson)
|
||||
@@ -458,61 +431,6 @@ public class GearTaskConverter
|
||||
}
|
||||
}
|
||||
|
||||
private JavascriptGearTaskParams DeserializeJavascriptParams(string? parametersJson)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(parametersJson))
|
||||
{
|
||||
return new JavascriptGearTaskParams();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<JavascriptGearTaskParams>(parametersJson) ?? new JavascriptGearTaskParams();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new JavascriptGearTaskParams();
|
||||
}
|
||||
}
|
||||
|
||||
private static GearTaskData CreateCopiedTaskData(GearTaskData taskData, string parametersJson)
|
||||
{
|
||||
return new GearTaskData
|
||||
{
|
||||
Name = taskData.Name,
|
||||
TaskType = taskData.TaskType,
|
||||
Path = taskData.Path,
|
||||
IsEnabled = taskData.IsEnabled,
|
||||
IsDirectory = taskData.IsDirectory,
|
||||
IsExpanded = taskData.IsExpanded,
|
||||
GroupConfigJson = taskData.GroupConfigJson,
|
||||
Parameters = parametersJson,
|
||||
CreatedTime = taskData.CreatedTime,
|
||||
ModifiedTime = taskData.ModifiedTime,
|
||||
Priority = taskData.Priority,
|
||||
Children = taskData.Children
|
||||
};
|
||||
}
|
||||
|
||||
private static string ExtractTaskFolderName(string? sourcePath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sourcePath))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var trimmedPath = sourcePath.Trim().TrimEnd('\\', '/');
|
||||
if (string.IsNullOrWhiteSpace(trimmedPath))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var lastSeparatorIndex = Math.Max(trimmedPath.LastIndexOf('\\'), trimmedPath.LastIndexOf('/'));
|
||||
return lastSeparatorIndex >= 0 && lastSeparatorIndex < trimmedPath.Length - 1
|
||||
? trimmedPath[(lastSeparatorIndex + 1)..]
|
||||
: trimmedPath;
|
||||
}
|
||||
|
||||
private static string BuildPathingPlaceholderPath(string repoRelativePath, bool isDirectory)
|
||||
{
|
||||
var normalized = repoRelativePath.Replace('/', Path.DirectorySeparatorChar);
|
||||
|
||||
@@ -7,7 +7,6 @@ using BetterGenshinImpact.Core.Script;
|
||||
using BetterGenshinImpact.GameTask;
|
||||
using BetterGenshinImpact.Model.Gear;
|
||||
using BetterGenshinImpact.Model.Gear.Tasks;
|
||||
using BetterGenshinImpact.Service.GearTask;
|
||||
using BetterGenshinImpact.Service.GearTask.Execution;
|
||||
using BetterGenshinImpact.ViewModel.Pages.Component;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
@@ -262,7 +261,6 @@ public partial class GearTaskExecutor : ObservableObject, IGearTaskEventConsumer
|
||||
Path = viewModel.Path,
|
||||
IsEnabled = viewModel.IsEnabled,
|
||||
IsDirectory = viewModel.IsDirectory,
|
||||
GroupConfigJson = GearTaskGroupConfigHelper.Serialize(viewModel.GroupConfig),
|
||||
Parameters = viewModel.Parameters,
|
||||
CreatedTime = viewModel.CreatedTime,
|
||||
ModifiedTime = viewModel.ModifiedTime,
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
using BetterGenshinImpact.Core.Script.Group;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BetterGenshinImpact.Service.GearTask;
|
||||
|
||||
/// <summary>
|
||||
/// GearTask 任务组配置的序列化辅助方法。
|
||||
/// </summary>
|
||||
internal static class GearTaskGroupConfigHelper
|
||||
{
|
||||
public static string? Serialize(ScriptGroupConfig? groupConfig)
|
||||
{
|
||||
if (groupConfig == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return System.Text.Json.JsonSerializer.Serialize(groupConfig, global::BetterGenshinImpact.Service.ConfigService.JsonOptions);
|
||||
}
|
||||
|
||||
public static ScriptGroupConfig? Deserialize(string? groupConfigJson)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(groupConfigJson))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var groupConfig = JsonConvert.DeserializeObject<ScriptGroupConfig>(groupConfigJson);
|
||||
if (groupConfig == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
groupConfig.PathingConfig ??= new();
|
||||
groupConfig.ShellConfig ??= new();
|
||||
return groupConfig;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,7 +207,6 @@ public class GearTaskStorageService
|
||||
// 当 Children 存在值的情况下,IsDirectory 必定为 true
|
||||
IsDirectory = children.Count > 0 || viewModel.IsDirectory,
|
||||
IsExpanded = viewModel.IsExpanded,
|
||||
GroupConfigJson = GearTaskGroupConfigHelper.Serialize(viewModel.GroupConfig),
|
||||
Parameters = viewModel.Parameters,
|
||||
CreatedTime = viewModel.CreatedTime,
|
||||
ModifiedTime = viewModel.ModifiedTime,
|
||||
@@ -251,7 +250,6 @@ public class GearTaskStorageService
|
||||
IsEnabled = data.IsEnabled,
|
||||
IsDirectory = data.IsDirectory,
|
||||
IsExpanded = data.IsExpanded,
|
||||
GroupConfig = GearTaskGroupConfigHelper.Deserialize(data.GroupConfigJson),
|
||||
Parameters = data.Parameters,
|
||||
CreatedTime = data.CreatedTime,
|
||||
ModifiedTime = data.ModifiedTime,
|
||||
@@ -278,4 +276,4 @@ public class GearTaskStorageService
|
||||
var safeName = string.Join("_", name.Split(invalidChars, StringSplitOptions.RemoveEmptyEntries));
|
||||
return string.IsNullOrWhiteSpace(safeName) ? "unnamed_task" : safeName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -448,13 +448,6 @@
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="任务组设置"
|
||||
Command="{Binding OpenTaskGroupSettingsCommand}"
|
||||
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}">
|
||||
<MenuItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Settings24" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="删除"
|
||||
Command="{Binding DeleteTaskNodeCommand}"
|
||||
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}">
|
||||
@@ -628,15 +621,11 @@
|
||||
<MenuItem Header="Shell" Command="{Binding AddTaskNodeCommand}" CommandParameter="Shell" />
|
||||
<MenuItem Header="C# 方法" Command="{Binding AddTaskNodeCommand}" CommandParameter="CSharp" />
|
||||
</ContextMenu>
|
||||
</ui:DropDownButton.Flyout>
|
||||
</ui:DropDownButton.Flyout>
|
||||
</ui:DropDownButton>
|
||||
<ui:Button Command="{Binding AddTaskGroupCommand}"
|
||||
Content="添加组"
|
||||
Icon="{ui:SymbolIcon Folder24}" />
|
||||
<ui:Button Command="{Binding OpenSelectedTaskGroupSettingsCommand}"
|
||||
Content="组设置"
|
||||
Margin="10,0,0,0"
|
||||
Icon="{ui:SymbolIcon Settings24}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- 任务树 -->
|
||||
@@ -713,13 +702,6 @@
|
||||
<ui:GridViewColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<ui:Button Command="{Binding DataContext.OpenTaskGroupSettingsCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
CommandParameter="{Binding}"
|
||||
Icon="{ui:SymbolIcon Settings24}"
|
||||
Appearance="Transparent"
|
||||
Padding="4"
|
||||
ToolTip="任务组设置"
|
||||
Visibility="{Binding IsDirectory, Converter={StaticResource BooleanToVisibilityConverter}}" />
|
||||
<ui:Button Command="{Binding DataContext.DeleteTaskNodeCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
CommandParameter="{Binding}"
|
||||
Icon="{ui:SymbolIcon Delete24}"
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using BetterGenshinImpact.Core.Script.Group;
|
||||
using BetterGenshinImpact.Service;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Newtonsoft.Json;
|
||||
using JsonSerializer = System.Text.Json.JsonSerializer;
|
||||
|
||||
namespace BetterGenshinImpact.ViewModel.Pages.Component;
|
||||
|
||||
@@ -56,12 +52,6 @@ public partial class GearTaskViewModel : ObservableObject
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<GearTaskViewModel> _children = new();
|
||||
|
||||
/// <summary>
|
||||
/// 任务组配置,对应调度器 v1 的配置组设置。
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
private ScriptGroupConfig? _groupConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 任务参数,存储为JSON字符串
|
||||
/// shell 脚本存储 shell 命令
|
||||
@@ -172,7 +162,6 @@ public partial class GearTaskViewModel : ObservableObject
|
||||
IsEnabled = IsEnabled,
|
||||
IsDirectory = IsDirectory,
|
||||
Parameters = Parameters,
|
||||
GroupConfig = CloneGroupConfig(GroupConfig),
|
||||
Priority = Priority,
|
||||
Tags = Tags,
|
||||
CreatedTime = CreatedTime,
|
||||
@@ -186,15 +175,4 @@ public partial class GearTaskViewModel : ObservableObject
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
private static ScriptGroupConfig? CloneGroupConfig(ScriptGroupConfig? source)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var json = JsonSerializer.Serialize(source, ConfigService.JsonOptions);
|
||||
return JsonConvert.DeserializeObject<ScriptGroupConfig>(json);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,25 +9,17 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using BetterGenshinImpact.Core.Config;
|
||||
using BetterGenshinImpact.Core.Script;
|
||||
using BetterGenshinImpact.Core.Script.Group;
|
||||
using BetterGenshinImpact.GameTask;
|
||||
using BetterGenshinImpact.Helpers.Ui;
|
||||
using BetterGenshinImpact.Service;
|
||||
using BetterGenshinImpact.Service.GearTask;
|
||||
using BetterGenshinImpact.Service.GearTask.Execution;
|
||||
using BetterGenshinImpact.View.Pages.View;
|
||||
using BetterGenshinImpact.View.Windows;
|
||||
using BetterGenshinImpact.View.Windows.GearTask;
|
||||
using BetterGenshinImpact.ViewModel.Pages.Component;
|
||||
using BetterGenshinImpact.ViewModel.Pages.View;
|
||||
using BetterGenshinImpact.ViewModel.Windows;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Wpf.Ui.Controls;
|
||||
using Wpf.Ui.Violeta.Controls;
|
||||
using MessageBoxButton = System.Windows.MessageBoxButton;
|
||||
using MessageBoxResult = System.Windows.MessageBoxResult;
|
||||
|
||||
namespace BetterGenshinImpact.ViewModel.Pages;
|
||||
|
||||
@@ -593,18 +585,6 @@ public partial class GearTaskListPageViewModel : ViewModel
|
||||
await _storageService.SaveTaskDefinitionAsync(SelectedTaskDefinition);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task OpenSelectedTaskGroupSettings()
|
||||
{
|
||||
await OpenTaskGroupSettingsInternalAsync(SelectedTaskNode);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task OpenTaskGroupSettings(GearTaskViewModel? taskNode)
|
||||
{
|
||||
await OpenTaskGroupSettingsInternalAsync(taskNode);
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task DeleteTaskNode(GearTaskViewModel? taskNode)
|
||||
{
|
||||
@@ -629,52 +609,6 @@ public partial class GearTaskListPageViewModel : ViewModel
|
||||
await _storageService.SaveTaskDefinitionAsync(SelectedTaskDefinition);
|
||||
}
|
||||
|
||||
private async Task OpenTaskGroupSettingsInternalAsync(GearTaskViewModel? taskNode)
|
||||
{
|
||||
if (SelectedTaskDefinition == null)
|
||||
{
|
||||
Toast.Warning("请先选择一个任务定义");
|
||||
return;
|
||||
}
|
||||
|
||||
if (taskNode == null || !taskNode.IsDirectory)
|
||||
{
|
||||
Toast.Warning("请先选择一个任务组");
|
||||
return;
|
||||
}
|
||||
|
||||
taskNode.GroupConfig ??= new ScriptGroupConfig();
|
||||
|
||||
var dialogWindow = new FluentWindow
|
||||
{
|
||||
Title = "任务组设置",
|
||||
Content = new ScriptGroupConfigView(new ScriptGroupConfigViewModel(TaskContext.Instance().Config, taskNode.GroupConfig)),
|
||||
Width = 800,
|
||||
Height = 600,
|
||||
MinWidth = 800,
|
||||
MaxWidth = 800,
|
||||
MinHeight = 600,
|
||||
Owner = Application.Current.MainWindow,
|
||||
WindowStartupLocation = WindowStartupLocation.CenterOwner,
|
||||
ExtendsContentIntoTitleBar = true,
|
||||
WindowBackdropType = WindowBackdropType.Auto,
|
||||
};
|
||||
dialogWindow.SourceInitialized += (_, _) => WindowHelper.TryApplySystemBackdrop(dialogWindow);
|
||||
dialogWindow.ShowDialog();
|
||||
|
||||
try
|
||||
{
|
||||
taskNode.ModifiedTime = DateTime.Now;
|
||||
SelectedTaskDefinition.ModifiedTime = DateTime.Now;
|
||||
await _storageService.SaveTaskDefinitionAsync(SelectedTaskDefinition);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "保存任务组设置失败: {TaskName}", taskNode.Name);
|
||||
ThemedMessageBox.Error($"保存任务组设置失败:{ex.Message}", "保存失败");
|
||||
}
|
||||
}
|
||||
|
||||
private bool RemoveTaskFromTree(GearTaskViewModel parent, GearTaskViewModel target)
|
||||
{
|
||||
if (parent.Children.Contains(target))
|
||||
|
||||
Reference in New Issue
Block a user