rft: Wpf自动战斗任务序列化

This commit is contained in:
status102
2025-02-25 10:55:18 +08:00
parent 206352a8e6
commit fe362d09fc
4 changed files with 181 additions and 60 deletions

View File

@@ -2623,50 +2623,6 @@ namespace MaaWpfGui.Main
return id != 0 && AsstStart();
}
/// <summary>
/// 自动抄作业。
/// </summary>
/// <param name="filename">作业 JSON 的文件路径,绝对、相对路径均可。</param>
/// <param name="formation">是否进行 “快捷编队”。</param>
/// <param name="addTrust">是否追加信赖干员</param>
/// <param name="addUserAdditional">是否追加自定干员</param>
/// <param name="userAdditional">自定干员列表</param>
/// <param name="needNavigate">是否导航至关卡(启用自动战斗序列)</param>
/// <param name="navigateName">关卡名</param>
/// <param name="isRaid">是不是突袭</param>
/// <param name="type">任务类型</param>
/// <param name="loopTimes">任务重复执行次数</param>
/// <param name="useSanityPotion">是否使用理智药</param>
/// <param name="asstStart">是否启动战斗</param>
/// <returns>是否成功。</returns>
public bool AsstStartCopilot(string filename, bool formation, bool addTrust, bool addUserAdditional, JArray userAdditional, bool needNavigate, string navigateName, bool isRaid, AsstTaskType type, int loopTimes, bool useSanityPotion, bool asstStart = true)
{
var taskParams = new JObject
{
["filename"] = filename,
["formation"] = formation,
["add_trust"] = addTrust,
["need_navigate"] = needNavigate,
["is_raid"] = isRaid,
["loop_times"] = loopTimes,
["use_sanity_potion"] = useSanityPotion,
};
if (addUserAdditional)
{
taskParams["user_additional"] = userAdditional;
}
if (needNavigate)
{
taskParams["navigate_name"] = navigateName;
}
AsstTaskId id = AsstAppendTaskWithEncoding(type, taskParams);
_taskStatus.Add(id, TaskType.Copilot);
return id != 0 && (!asstStart || AsstStart());
}
public bool AsstStartVideoRec(string filename)
{
var taskParams = new JObject

View File

@@ -0,0 +1,30 @@
// <copyright file="AsstBaseTask.cs" company="MaaAssistantArknights">
// MaaWpfGui - A part of the MaaCoreArknights project
// Copyright (C) 2021 MistEO and Contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License v3.0 only as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
// </copyright>
#nullable enable
using System;
using MaaWpfGui.Services;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace MaaWpfGui.Models.AsstTasks;
[JsonObject(MemberSerialization.OptIn)]
public class AsstBaseTask
{
public virtual AsstTaskType TaskType { get; private set; }
public virtual (AsstTaskType TaskType, JObject Params) Serialize()
{
throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,110 @@
// <copyright file="AsstCopilotTask.cs" company="MaaAssistantArknights">
// MaaWpfGui - A part of the MaaCoreArknights project
// Copyright (C) 2021 MistEO and Contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License v3.0 only as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
// </copyright>
#nullable enable
using System.Collections.Generic;
using MaaWpfGui.Services;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace MaaWpfGui.Models.AsstTasks;
/// <summary>
/// 自动抄作业。
/// </summary>
public class AsstCopilotTask : AsstBaseTask
{
public override AsstTaskType TaskType => AsstTaskType.Copilot;
/// <summary>
/// Gets or sets 作业 JSON 的文件路径,绝对、相对路径均可
/// </summary>
public string FileName { get; set; } = string.Empty;
/// <summary>
/// Gets or sets a value indicating whether 自动编队
/// </summary>
public bool Formation { get; set; }
/// <summary>
/// Gets or sets a value indicating whether 追加信赖干员
/// </summary>
public bool AddTrust { get; set; }
/// <summary>
/// Gets or sets a value indicating whether 导航至关卡(启用自动战斗序列、取消代理)
/// </summary>
public bool NeedNavigate { get; set; }
/// <summary>
/// Gets or sets 关卡名仅导航用Wpf会自动读取地图对应的关卡名
/// </summary>
public string? StageName { get; set; }
/// <summary>
/// Gets or sets a value indicating whether 突袭难度
/// </summary>
public bool IsRaid { get; set; }
/// <summary>
/// Gets or sets 重复次数
/// </summary>
public int LoopTimes { get; set; }
/// <summary>
/// Gets or sets a value indicating whether 使用理智药
/// </summary>
public bool UseSanityPotion { get; set; }
/// <summary>
/// Gets or sets 自定干员列表
/// </summary>
public List<UserAdditional>? UserAdditionals { get; set; }
public override (AsstTaskType TaskType, JObject Params) Serialize()
{
var taskParams = new JObject
{
["filename"] = FileName,
["formation"] = Formation,
["add_trust"] = AddTrust,
["need_navigate"] = NeedNavigate,
["is_raid"] = IsRaid,
["loop_times"] = LoopTimes,
["use_sanity_potion"] = UseSanityPotion,
};
if (UserAdditionals?.Count > 0)
{
taskParams["user_additional"] = JsonConvert.SerializeObject(UserAdditionals);
}
if (NeedNavigate)
{
taskParams["navigate_name"] = StageName;
}
return (TaskType, taskParams);
}
public class UserAdditional
{
/// <summary>
/// Gets or sets 干员名ocr文本跟随客户端语言
/// </summary>
[JsonProperty("name")]
public string Name { get; set; } = string.Empty;
[JsonProperty("skill")]
public int Skill { get; set; }
}
}

View File

@@ -25,15 +25,17 @@ using System.Windows.Controls;
using System.Windows.Input;
using MaaWpfGui.Constants;
using MaaWpfGui.Helper;
using MaaWpfGui.Main;
using MaaWpfGui.Models;
using MaaWpfGui.Models.AsstTasks;
using MaaWpfGui.Services;
using MaaWpfGui.States;
using Microsoft.Win32;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Serilog;
using Stylet;
using static MaaWpfGui.Helper.CopilotHelper;
using static MaaWpfGui.Models.AsstTasks.AsstCopilotTask;
using DataFormats = System.Windows.Forms.DataFormats;
using Task = System.Threading.Tasks.Task;
@@ -56,7 +58,7 @@ namespace MaaWpfGui.ViewModels.UI
private const string TempCopilotFile = "cache/_temp_copilot.json";
private static readonly string[] _supportExt = [".json", ".mp4", ".m4s", ".mkv", ".flv", ".avi"];
private const string CopilotJsonDir = "config/copilot";
private const string StageNameRegex = @"(?:[a-z]{0,3})(?:\d{0,2})-(?:(?:A|B|C|D|EX|S|TR|MO)-?)?(?:\d{1,2})(\(Raid\)(?=\.json))?";
private const string StageNameRegex = @"(?:[a-z]{0,3})(?:\d{0,2})-(?:(?:A|B|C|D|EX|S|TR|MO)-?)?(?:\d{1,2})";
private const string InvalidStageNameChars = @"[:',\.\(\)\|\[\]\?,。【】{};:]"; // 无效字符
[GeneratedRegex(InvalidStageNameChars)]
@@ -1151,27 +1153,39 @@ namespace MaaWpfGui.ViewModels.UI
}
Regex regex = new Regex(@"(?<=;)(?<name>[^,;]+)(?:, *(?<skill>\d))?(?=;)", RegexOptions.Compiled);
JArray userAdditional = new(regex.Matches(";" + UserAdditional + ";").ToList().Select(match => new JObject
var userAdditional = regex.Matches(";" + UserAdditional + ";").ToList().Select(match => new UserAdditional
{
["name"] = match.Groups[1].Value.Trim(),
["skill"] = string.IsNullOrEmpty(match.Groups[2].Value) ? 0 : int.Parse(match.Groups[2].Value),
}));
Name = match.Groups[1].Value.Trim(),
Skill = string.IsNullOrEmpty(match.Groups[2].Value) ? 0 : int.Parse(match.Groups[2].Value),
});
bool ret = true;
if (UseCopilotList)
{
_copilotIdList.Clear();
bool startAny = false;
foreach (var model in CopilotItemViewModels.Where(i => i.IsChecked))
{
_copilotIdList.Add(model.CopilotId);
ret &= Instances.AsstProxy.AsstStartCopilot(model.FilePath, Form, AddTrust, AddUserAdditional, userAdditional, UseCopilotList, model.Name, model.IsRaid, _taskType, Loop ? LoopTimes : 1, _useSanityPotion, false);
startAny = true;
}
var tasks = CopilotItemViewModels.Where(i => i.IsChecked).Select(model =>
{
_copilotIdList.Add(model.CopilotId);
var task = new AsstCopilotTask()
{
FileName = model.FilePath,
Formation = _form,
AddTrust = _addTrust,
UserAdditionals = userAdditional.ToList(),
NeedNavigate = UseCopilotList,
StageName = model.Name,
IsRaid = model.IsRaid,
LoopTimes = Loop ? LoopTimes : 1,
UseSanityPotion = _useSanityPotion,
};
var (type, param) = task.Serialize();
return Instances.AsstProxy.AsstAppendTaskWithEncoding(AsstProxy.TaskType.Copilot, type, param);
}).ToList();
if (startAny)
if (tasks.Count > 0)
{
ret &= Instances.AsstProxy.AsstStart();
ret = tasks.All(t => t) && Instances.AsstProxy.AsstStart();
}
else
{// 一个都没启动,怎会有如此无聊之人
@@ -1181,7 +1195,18 @@ namespace MaaWpfGui.ViewModels.UI
}
else
{
ret &= Instances.AsstProxy.AsstStartCopilot(IsDataFromWeb ? TempCopilotFile : Filename, Form, AddTrust, AddUserAdditional, userAdditional, UseCopilotList, string.Empty, false, _taskType, Loop ? LoopTimes : 1, false);
var task = new AsstCopilotTask()
{
FileName = IsDataFromWeb ? TempCopilotFile : Filename,
Formation = _form,
AddTrust = _addTrust,
UserAdditionals = userAdditional.ToList(),
NeedNavigate = false,
LoopTimes = Loop ? LoopTimes : 1,
UseSanityPotion = _useSanityPotion,
};
ret = Instances.AsstProxy.AsstAppendTaskWithEncoding(AsstProxy.TaskType.Copilot, _taskType, task.Serialize().Params);
ret &= Instances.AsstProxy.AsstStart();
}
if (ret)