mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-20 10:57:45 +08:00
feat: 自动战斗新增战斗列表选项(异形UI不支持) (#6350)
This commit is contained in:
@@ -610,6 +610,27 @@
|
||||
50
|
||||
]
|
||||
},
|
||||
"ChangeToAdverseDifficulty": {
|
||||
"template": "AdverseDifficulty.png",
|
||||
"action": "ClickSelf",
|
||||
"roi": [
|
||||
625,
|
||||
640,
|
||||
80,
|
||||
65
|
||||
],
|
||||
"maxTimes": 3,
|
||||
"next": [
|
||||
"AdverseConfirm",
|
||||
"#self"
|
||||
]
|
||||
},
|
||||
"AdverseConfirm": {
|
||||
"baseTask": "ChangeToAdverseDifficulty",
|
||||
"action": "DoNothing",
|
||||
"template": "NormalDifficulty.png",
|
||||
"next": []
|
||||
},
|
||||
"Episode": {
|
||||
"Doc": "base_task",
|
||||
"algorithm": "JustReturn",
|
||||
@@ -7022,6 +7043,12 @@
|
||||
"Stop"
|
||||
]
|
||||
},
|
||||
"BattleQuickFormationCheck": {
|
||||
"baseTask": "BattleQuickFormation",
|
||||
"template": "BattleQuickFormation.png",
|
||||
"action": "DoNothing",
|
||||
"next": []
|
||||
},
|
||||
"BattleQuickFormation": {
|
||||
"action": "ClickSelf",
|
||||
"roi": [
|
||||
@@ -13080,6 +13107,45 @@
|
||||
163
|
||||
]
|
||||
},
|
||||
"Copilot@ClickCornerUntilFailedOrStartButton": {
|
||||
"algorithm": "JustReturn",
|
||||
"action": "DoNothing",
|
||||
"next": [
|
||||
"Copilot@MissionFailed",
|
||||
"Copilot@BattleStartPreFlag",
|
||||
"Copilot@ClickCornerUntilStartButton"
|
||||
]
|
||||
},
|
||||
"Copilot@ClickCornerUntilStartButton": {
|
||||
"next": [
|
||||
"Copilot@ClickCornerUntilFailedOrStartButton"
|
||||
]
|
||||
},
|
||||
"Copilot@MissionFailed": {
|
||||
"Doc": "如果没有三星就终止",
|
||||
"template": "MissionFailed.png",
|
||||
"action": "DoNothing",
|
||||
"roi": [
|
||||
210,
|
||||
290,
|
||||
70,
|
||||
70
|
||||
],
|
||||
"next_Doc": "主动抛错",
|
||||
"next": [
|
||||
"Copilot@BattleStartPreFlag"
|
||||
]
|
||||
},
|
||||
"Copilot@BattleStartPreFlag": {
|
||||
"baseTask": "BattleStartPre",
|
||||
"action": "DoNothing",
|
||||
"roi":[
|
||||
0,
|
||||
0,
|
||||
1280,
|
||||
720
|
||||
]
|
||||
},
|
||||
"ClickCornerUntilStartButton": {
|
||||
"algorithm": "JustReturn",
|
||||
"action": "ClickRect",
|
||||
|
||||
BIN
resource/template/AdverseDifficulty.png
Normal file
BIN
resource/template/AdverseDifficulty.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
resource/template/MissionFailed.png
Normal file
BIN
resource/template/MissionFailed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
BIN
resource/template/NormalDifficulty.png
Normal file
BIN
resource/template/NormalDifficulty.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
@@ -73,8 +73,10 @@
|
||||
<ClInclude Include="Task\Interface\CustomTask.h" />
|
||||
<ClInclude Include="Task\Interface\VideoRecognitionTask.h" />
|
||||
<ClInclude Include="Task\Interface\OperBoxTask.h" />
|
||||
<ClInclude Include="Task\Miscellaneous\CopilotListNotificationPlugin.h" />
|
||||
<ClInclude Include="Task\Miscellaneous\OperBoxRecognitionTask.h" />
|
||||
<ClInclude Include="Task\Miscellaneous\AccountSwitchTask.h" />
|
||||
<ClInclude Include="Task\Miscellaneous\TaskFileReloadTask.h" />
|
||||
<ClInclude Include="Task\Reclamation\ReclamationControlTask.h" />
|
||||
<ClInclude Include="Task\Reclamation\ReclamationConclusionReportPlugin.h" />
|
||||
<ClInclude Include="Task\Reclamation\ReclamationBattlePlugin.h" />
|
||||
@@ -234,8 +236,10 @@
|
||||
<ClCompile Include="Task\Infrast\InfrastProcessingTask.cpp" />
|
||||
<ClCompile Include="Task\Interface\VideoRecognitionTask.cpp" />
|
||||
<ClCompile Include="Task\Interface\OperBoxTask.cpp" />
|
||||
<ClCompile Include="Task\Miscellaneous\CopilotListNotificationPlugin.cpp" />
|
||||
<ClCompile Include="Task\Miscellaneous\OperBoxRecognitionTask.cpp" />
|
||||
<ClCompile Include="Task\Miscellaneous\AccountSwitchTask.cpp" />
|
||||
<ClCompile Include="Task\Miscellaneous\TaskFileReloadTask.cpp" />
|
||||
<ClCompile Include="Task\Reclamation\ReclamationControlTask.cpp" />
|
||||
<ClCompile Include="Task\Reclamation\ReclamationConclusionReportPlugin.cpp" />
|
||||
<ClCompile Include="Task\Reclamation\ReclamationBattlePlugin.cpp" />
|
||||
|
||||
@@ -633,6 +633,12 @@
|
||||
<ClInclude Include="Task\Infrast\InfrastProcessingTask.h">
|
||||
<Filter>源文件\Task\Infrast</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Task\Miscellaneous\CopilotListNotificationPlugin.h">
|
||||
<Filter>源文件\Task\Miscellaneous</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Task\Miscellaneous\TaskFileReloadTask.h">
|
||||
<Filter>源文件\Task\Miscellaneous</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Vision\VisionHelper.cpp">
|
||||
@@ -1049,5 +1055,11 @@
|
||||
<ClCompile Include="Task\Infrast\InfrastProcessingTask.cpp">
|
||||
<Filter>源文件\Task\Infrast</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Task\Miscellaneous\CopilotListNotificationPlugin.cpp">
|
||||
<Filter>源文件\Task\Miscellaneous</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Task\Miscellaneous\TaskFileReloadTask.cpp">
|
||||
<Filter>源文件\Task\Miscellaneous</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -3,33 +3,48 @@
|
||||
#include <regex>
|
||||
|
||||
#include "Config/Miscellaneous/CopilotConfig.h"
|
||||
#include "Config/TaskData.h"
|
||||
#include "Task/Miscellaneous/BattleFormationTask.h"
|
||||
#include "Task/Miscellaneous/BattleProcessTask.h"
|
||||
#include "Task/Miscellaneous/CopilotListNotificationPlugin.h"
|
||||
#include "Task/Miscellaneous/TaskFileReloadTask.h"
|
||||
#include "Task/ProcessTask.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
#include "Utils/Platform.hpp"
|
||||
|
||||
asst::CopilotTask::CopilotTask(const AsstCallback& callback, Assistant* inst)
|
||||
: InterfaceTask(callback, inst, TaskType),
|
||||
m_task_file_reload_task_ptr(std::make_shared<TaskFileReloadTask>(callback, inst, TaskType)),
|
||||
m_navigate_task_ptr(std::make_shared<ProcessTask>(callback, inst, TaskType)),
|
||||
m_not_use_prts_task_ptr(std::make_shared<ProcessTask>(callback, inst, TaskType)),
|
||||
m_adverse_select_task_ptr(std::make_shared<ProcessTask>(callback, inst, TaskType)),
|
||||
m_formation_task_ptr(std::make_shared<BattleFormationTask>(callback, inst, TaskType)),
|
||||
m_battle_task_ptr(std::make_shared<BattleProcessTask>(callback, inst, TaskType)),
|
||||
m_stop_task_ptr(std::make_shared<ProcessTask>(callback, inst, TaskType))
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
m_subtasks.emplace_back(m_task_file_reload_task_ptr);
|
||||
m_subtasks.emplace_back(m_navigate_task_ptr);
|
||||
m_subtasks.emplace_back(m_not_use_prts_task_ptr);
|
||||
|
||||
// 选择突袭模式
|
||||
m_adverse_select_task_ptr->set_tasks({ "ChangeToAdverseDifficulty", "AdverseConfirm" });
|
||||
m_subtasks.emplace_back(m_adverse_select_task_ptr);
|
||||
|
||||
auto start_1_tp = std::make_shared<ProcessTask>(callback, inst, TaskType);
|
||||
start_1_tp->set_tasks({ "BattleStartPre" }).set_retry_times(0).set_ignore_error(true);
|
||||
m_subtasks.emplace_back(start_1_tp);
|
||||
|
||||
m_subtasks.emplace_back(m_formation_task_ptr);
|
||||
m_subtasks.emplace_back(m_formation_task_ptr)->set_retry_times(0);
|
||||
|
||||
auto start_2_tp = std::make_shared<ProcessTask>(callback, inst, TaskType);
|
||||
start_2_tp->set_tasks({ "BattleStartAll" }).set_ignore_error(false);
|
||||
m_copilot_list_notification_ptr = start_2_tp->register_plugin<CopilotListNotificationPlugin>();
|
||||
m_subtasks.emplace_back(start_2_tp);
|
||||
|
||||
m_subtasks.emplace_back(m_battle_task_ptr)->set_retry_times(0);
|
||||
|
||||
m_stop_task_ptr->set_tasks({ "ClickCornerUntilStartButton" });
|
||||
m_stop_task_ptr->set_enable(false);
|
||||
m_subtasks.emplace_back(m_stop_task_ptr);
|
||||
}
|
||||
@@ -56,10 +71,14 @@ bool asst::CopilotTask::set_params(const json::value& params)
|
||||
Log.error("CopilotConfig parse failed");
|
||||
return false;
|
||||
}
|
||||
m_task_file_reload_task_ptr->set_magic_code(match[1].str());
|
||||
}
|
||||
else if (!Copilot.load(utils::path(*filename_opt))) {
|
||||
Log.error("CopilotConfig parse failed");
|
||||
return false;
|
||||
else {
|
||||
if (!Copilot.load(utils::path(*filename_opt))) {
|
||||
Log.error("CopilotConfig parse failed");
|
||||
return false;
|
||||
}
|
||||
m_task_file_reload_task_ptr->set_path(std::move(*filename_opt));
|
||||
}
|
||||
|
||||
m_stage_name = Copilot.get_stage_name();
|
||||
@@ -70,6 +89,8 @@ bool asst::CopilotTask::set_params(const json::value& params)
|
||||
|
||||
bool with_formation = params.get("formation", false);
|
||||
m_formation_task_ptr->set_enable(with_formation);
|
||||
|
||||
// 自动补信赖
|
||||
m_formation_task_ptr->set_add_trust(params.get("add_trust", false));
|
||||
m_formation_task_ptr->set_add_user_additional(params.get("add_user_additional", false));
|
||||
auto user_additional_opt = params.find<json::array>("user_additional");
|
||||
@@ -88,21 +109,47 @@ bool asst::CopilotTask::set_params(const json::value& params)
|
||||
m_formation_task_ptr->set_user_additional(std::move(user_additional));
|
||||
}
|
||||
|
||||
// 是否在当前页面左右滑动寻找关卡
|
||||
// 启用队列的话,这项为true
|
||||
bool need_navigate = params.get("need_navigate", false);
|
||||
m_task_file_reload_task_ptr->set_enable(need_navigate);
|
||||
|
||||
// 不使用代理指挥
|
||||
m_not_use_prts_task_ptr->set_enable(need_navigate);
|
||||
m_not_use_prts_task_ptr->set_tasks({ "NotUsePrts", "Stop" });
|
||||
|
||||
bool is_adverse = params.get("is_adverse", false);
|
||||
m_adverse_select_task_ptr->set_enable(need_navigate && is_adverse);
|
||||
|
||||
// 防止在关卡名展开的情况下无法滑动,调整滑动区域
|
||||
std::string m_navigate_name = params.get("navigate_name", std::string());
|
||||
Task.get<OcrTaskInfo>(m_navigate_name + "@Copilot@ClickStageName")->text = { m_navigate_name };
|
||||
Task.get<OcrTaskInfo>(m_navigate_name + "@Copilot@ClickedCorrectStage")->text = { m_navigate_name };
|
||||
Task.get(m_navigate_name + "@Copilot@FullStageNavigation")->specific_rect = Rect(600, 100, 20, 20);
|
||||
m_navigate_task_ptr->set_tasks({ m_navigate_name + "@Copilot@StageNavigationBegin" });
|
||||
m_navigate_task_ptr->set_enable(need_navigate);
|
||||
|
||||
std::string support_unit_name = params.get("support_unit_name", std::string());
|
||||
m_formation_task_ptr->set_support_unit_name(std::move(support_unit_name));
|
||||
|
||||
size_t loop_times = params.get("loop_times", 1);
|
||||
if (loop_times > 1) {
|
||||
m_stop_task_ptr->set_tasks({ "ClickCornerUntilStartButton" });
|
||||
m_stop_task_ptr->set_enable(true);
|
||||
|
||||
// 追加
|
||||
m_subtasks.reserve(m_subtasks.size() * loop_times);
|
||||
auto raw_end = m_subtasks.end();
|
||||
for (size_t i = 1; i < loop_times; ++i) {
|
||||
// FIXME: 如果多次调用 set_params,这里复制的会有问题
|
||||
m_subtasks.insert(m_subtasks.end(), m_subtasks.begin(), raw_end);
|
||||
}
|
||||
m_stop_task_ptr->set_enable(true);
|
||||
}
|
||||
else {
|
||||
m_stop_task_ptr->set_enable(false);
|
||||
else if (need_navigate) {
|
||||
// 如果没三星就中止
|
||||
Task.get<OcrTaskInfo>("Copilot@BattleStartPreFlag")->text.emplace_back(m_navigate_name);
|
||||
m_stop_task_ptr->set_tasks({ "Copilot@ClickCornerUntilFailedOrStartButton" });
|
||||
m_stop_task_ptr->set_enable(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class TaskFileReloadTask;
|
||||
class BattleProcessTask;
|
||||
class BattleFormationTask;
|
||||
class CopilotListNotificationPlugin;
|
||||
class ProcessTask;
|
||||
|
||||
// 抄作业任务
|
||||
@@ -22,8 +24,13 @@ namespace asst
|
||||
std::string get_stage_name() const { return m_stage_name; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<TaskFileReloadTask> m_task_file_reload_task_ptr = nullptr;
|
||||
std::shared_ptr<ProcessTask> m_navigate_task_ptr = nullptr;
|
||||
std::shared_ptr<ProcessTask> m_not_use_prts_task_ptr = nullptr;
|
||||
std::shared_ptr<ProcessTask> m_adverse_select_task_ptr = nullptr;
|
||||
std::shared_ptr<BattleFormationTask> m_formation_task_ptr = nullptr;
|
||||
std::shared_ptr<BattleProcessTask> m_battle_task_ptr = nullptr;
|
||||
std::shared_ptr<CopilotListNotificationPlugin> m_copilot_list_notification_ptr = nullptr;
|
||||
std::shared_ptr<ProcessTask> m_stop_task_ptr = nullptr;
|
||||
std::string m_stage_name;
|
||||
};
|
||||
|
||||
@@ -25,8 +25,11 @@ namespace asst
|
||||
void append_additional_formation(AdditionalFormation formation);
|
||||
|
||||
void set_support_unit_name(std::string name);
|
||||
// 是否追加自定干员
|
||||
void set_add_user_additional(bool add_user_additional);
|
||||
// 设置追加自定干员列表
|
||||
void set_user_additional(std::vector<std::pair<std::string, int>> user_additional);
|
||||
// 是否追加低信赖干员
|
||||
void set_add_trust(bool add_trust);
|
||||
|
||||
enum class DataResource
|
||||
@@ -45,7 +48,6 @@ namespace asst
|
||||
bool add_additional();
|
||||
// 补充刷信赖的干员,从最小的开始
|
||||
bool add_trust_operators();
|
||||
|
||||
bool enter_selection_page();
|
||||
bool select_opers_in_cur_page(std::vector<OperGroup>& groups);
|
||||
void swipe_page();
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#include "CopilotListNotificationPlugin.h"
|
||||
|
||||
bool asst::CopilotListNotificationPlugin::verify(AsstMsg msg, const json::value& details) const
|
||||
{
|
||||
if (msg != AsstMsg::SubTaskStart || details.get("subtask", std::string()) != "ProcessTask") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string task = details.at("details").at("task").as_string();
|
||||
if (task != "BattleStartAll" && task.starts_with("BattleStart")) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool asst::CopilotListNotificationPlugin::_run()
|
||||
{
|
||||
json::value info = basic_info_with_what("CopilotListEnterSuccess");
|
||||
callback(AsstMsg::SubTaskExtraInfo, info);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "Task/AbstractTaskPlugin.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class CopilotListNotificationPlugin : public AbstractTaskPlugin
|
||||
{
|
||||
public:
|
||||
using AbstractTaskPlugin::AbstractTaskPlugin;
|
||||
virtual ~CopilotListNotificationPlugin() override = default;
|
||||
virtual bool verify(AsstMsg msg, const json::value& details) const override;
|
||||
|
||||
private:
|
||||
virtual bool _run() override;
|
||||
};
|
||||
}
|
||||
40
src/MaaCore/Task/Miscellaneous/TaskFileReloadTask.cpp
Normal file
40
src/MaaCore/Task/Miscellaneous/TaskFileReloadTask.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "TaskFileReloadTask.h"
|
||||
|
||||
#include "Config/Miscellaneous/CopilotConfig.h"
|
||||
#include "Utils/Logger.hpp"
|
||||
|
||||
void asst::TaskFileReloadTask::set_magic_code(std::string code)
|
||||
{
|
||||
is_magic_code = true;
|
||||
m_file = std::move(code);
|
||||
}
|
||||
|
||||
void asst::TaskFileReloadTask::set_path(std::string path)
|
||||
{
|
||||
is_path = true;
|
||||
m_file = std::move(path);
|
||||
}
|
||||
|
||||
bool asst::TaskFileReloadTask::_run()
|
||||
{
|
||||
if (is_magic_code) {
|
||||
if (!Copilot.parse_magic_code(m_file)) {
|
||||
Log.error("CopilotConfig parse failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (is_path) {
|
||||
if (!Copilot.load(utils::path(m_file))) {
|
||||
Log.error("CopilotConfig parse failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
json::value info = basic_info_with_what("CopilotListLoadTaskFileSuccess");
|
||||
info["details"]["stage_name"] = Copilot.get_stage_name();
|
||||
callback(AsstMsg::SubTaskExtraInfo, info);
|
||||
return true;
|
||||
}
|
||||
19
src/MaaCore/Task/Miscellaneous/TaskFileReloadTask.h
Normal file
19
src/MaaCore/Task/Miscellaneous/TaskFileReloadTask.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "Task/AbstractTaskPlugin.h"
|
||||
|
||||
namespace asst
|
||||
{
|
||||
class TaskFileReloadTask : public AbstractTask
|
||||
{
|
||||
public:
|
||||
using AbstractTask::AbstractTask;
|
||||
virtual ~TaskFileReloadTask() override = default;
|
||||
void set_magic_code(std::string code);
|
||||
void set_path(std::string path);
|
||||
|
||||
private:
|
||||
virtual bool _run() override;
|
||||
std::string m_file;
|
||||
bool is_path = false, is_magic_code = false;
|
||||
};
|
||||
}
|
||||
@@ -127,6 +127,7 @@ namespace MaaWpfGui.Constants
|
||||
public const string CopilotAddUserAdditional = "Copilot.AddUserAdditional";
|
||||
public const string CopilotUserAdditional = "Copilot.UserAdditional";
|
||||
public const string CopilotLoopTimes = "Copilot.LoopTimes";
|
||||
public const string CopilotTaskList = "Copilot.CopilotTaskList";
|
||||
|
||||
public const string UpdateProxy = "VersionUpdate.Proxy";
|
||||
public const string VersionType = "VersionUpdate.VersionType";
|
||||
|
||||
@@ -15,15 +15,14 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Media.Imaging;
|
||||
using HandyControl.Data;
|
||||
using HandyControl.Tools.Extension;
|
||||
using MaaWpfGui.Constants;
|
||||
using MaaWpfGui.Extensions;
|
||||
using MaaWpfGui.Helper;
|
||||
@@ -531,6 +530,7 @@ namespace MaaWpfGui.Main
|
||||
toast.Show();
|
||||
if (isCoplitTaskChain)
|
||||
{
|
||||
AsstStop();
|
||||
runningState.SetIdle(true);
|
||||
Instances.CopilotViewModel.AddLog(LocalizationHelper.GetString("CombatError"), UiLogColor.Error);
|
||||
}
|
||||
@@ -573,7 +573,11 @@ namespace MaaWpfGui.Main
|
||||
Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("CompleteTask") + taskChain);
|
||||
if (isCoplitTaskChain)
|
||||
{
|
||||
runningState.SetIdle(true);
|
||||
if (!Instances.CopilotViewModel.UseCopilotList || Instances.CopilotViewModel.CopilotItemViewModels.All(model => !model.IsChecked))
|
||||
{
|
||||
runningState.SetIdle(true);
|
||||
}
|
||||
|
||||
Instances.CopilotViewModel.AddLog(LocalizationHelper.GetString("CompleteCombat"), UiLogColor.Info);
|
||||
}
|
||||
|
||||
@@ -1058,6 +1062,12 @@ namespace MaaWpfGui.Main
|
||||
}
|
||||
|
||||
break;
|
||||
case "CopilotListLoadTaskFileSuccess":
|
||||
Instances.CopilotViewModel.AddLog("Parse " + subTaskDetails["stage_name"].ToString() + " Success");
|
||||
break;
|
||||
case "CopilotListEnterSuccess":
|
||||
Instances.CopilotViewModel.EnterCopilotTask();
|
||||
break;
|
||||
|
||||
case "SSSStage":
|
||||
{
|
||||
@@ -1832,35 +1842,37 @@ namespace MaaWpfGui.Main
|
||||
/// <param name="add_trust">是否追加信赖干员</param>
|
||||
/// <param name="add_user_additional">是否追加自定干员</param>
|
||||
/// <param name="user_additional">自定干员列表</param>
|
||||
/// <param name="need_navigate">是否导航至关卡(启用自动战斗序列)</param>
|
||||
/// <param name="navigate_name">关卡名</param>
|
||||
/// <param name="is_adverse">是不是突袭</param>
|
||||
/// <param name="type">任务类型</param>
|
||||
/// <param name="loop_times">任务重复执行次数</param>
|
||||
/// <param name="asst_start">是否启动战斗</param>
|
||||
/// <returns>是否成功。</returns>
|
||||
public bool AsstStartCopilot(string filename, bool formation, bool add_trust, bool add_user_additional, string user_additional, string type, int loop_times)
|
||||
public bool AsstStartCopilot(string filename, bool formation, bool add_trust, bool add_user_additional, JArray user_additional, bool need_navigate, string navigate_name, bool is_adverse, string type, int loop_times, bool asst_start = true)
|
||||
{
|
||||
JArray m_user_additional = new JArray();
|
||||
Regex regex = new Regex(@"(?<=;)(?<name>[^,;]+)(?:, *(?<skill>\d))? *", RegexOptions.Compiled);
|
||||
MatchCollection matches = regex.Matches(";" + user_additional);
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
m_user_additional.Add(new JObject
|
||||
{
|
||||
["name"] = match.Groups[1].Value.Trim(),
|
||||
["skill"] = match.Groups[2].Value.IsNullOrEmpty() ? 0 : int.Parse(match.Groups[2].Value),
|
||||
});
|
||||
}
|
||||
|
||||
var task_params = new JObject
|
||||
{
|
||||
["filename"] = filename,
|
||||
["formation"] = formation,
|
||||
["add_trust"] = add_trust,
|
||||
["add_user_additional"] = add_user_additional,
|
||||
["user_additional"] = m_user_additional,
|
||||
["user_additional"] = user_additional,
|
||||
["need_navigate"] = need_navigate,
|
||||
["navigate_name"] = navigate_name,
|
||||
["is_adverse"] = is_adverse,
|
||||
["loop_times"] = loop_times,
|
||||
};
|
||||
AsstTaskId id = AsstAppendTaskWithEncoding(type, task_params);
|
||||
_latestTaskId[TaskType.Copilot] = id;
|
||||
return id != 0 && AsstStart();
|
||||
if (asst_start)
|
||||
{
|
||||
return id != 0 && AsstStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
return id != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool AsstStartVideoRec(string filename)
|
||||
|
||||
@@ -446,6 +446,10 @@ The video aspect ratio needs to be 16:9 without interference factors such as bla
|
||||
<system:String x:Key="AddTrust">Add low-trust operators</system:String>
|
||||
<system:String x:Key="AddUserAdditional">Add custom operators</system:String>
|
||||
<system:String x:Key="AddUserAdditionalTip">Use ";" as the separator, "," to separate the operator name and skills, for example: W, 3; Ash, 2</system:String>
|
||||
<system:String x:Key="UseCopilotList">Battle list</system:String>
|
||||
<system:String x:Key="UseCopilotListTip">Please switch to the level selection page before starting</system:String>
|
||||
<system:String x:Key="CopilotAddTask">Right click to add raid difficulty</system:String>
|
||||
<system:String x:Key="CopilotClearTask">Right click to clear inactive tasks</system:String>
|
||||
<system:String x:Key="LoopTimes">Loop Times</system:String>
|
||||
<system:String x:Key="Start">Start</system:String>
|
||||
<system:String x:Key="VideoLink">Video Link</system:String>
|
||||
@@ -459,6 +463,12 @@ The video aspect ratio needs to be 16:9 without interference factors such as bla
|
||||
Please start on the 「Start Deployment」 screen after manual formation (can be used with 「Loop Times」)\n\n
|
||||
5. Video recognition is now supported, please drag the strategy video to use.\n
|
||||
The video aspect ratio needs to be 16:9 without interference factors such as black borders, emulator borders special shapes and screen corrections.\n\n
|
||||
6. Battle list:\n
|
||||
After selecting the job, check that the level name below the list is correct (eg: CV-EX-1). \n
|
||||
Add: Left click to add normal difficulty, right click to add raid difficulty. \n
|
||||
Clear: Left click to clear the list, right click to remove only inactive tasks. \n
|
||||
Before starting, you need to switch to the level selection interface. Cross-chapter navigation is not supported. \n
|
||||
The operation will be terminated when encountering insufficient sanity, losing the battle, or failing to settle with three stars. \n\n
|
||||
</system:String>
|
||||
<system:String x:Key="CopilotFileReadError">Failed to read file!</system:String>
|
||||
<system:String x:Key="CopilotNoFound">No corresponding file found!</system:String>
|
||||
|
||||
@@ -438,6 +438,10 @@ Bilibili: ログイン インターフェイスに表示されるアカウント
|
||||
<system:String x:Key="AddTrust">信頼性の低いオペレーターを追加する</system:String>
|
||||
<system:String x:Key="AddUserAdditional">カスタム戦術要員の追加</system:String>
|
||||
<system:String x:Key="AddUserAdditionalTip">使用「;」オペレータ名とスキルを区切るには、区切り文字として「,」を使用します。例: W, 3; Ash, 2</system:String>
|
||||
<system:String x:Key="UseCopilotList">バトルリスト</system:String>
|
||||
<system:String x:Key="UseCopilotListTip">開始前にレベル選択ページに切り替えてください</system:String>
|
||||
<system:String x:Key="CopilotAddTask">右クリックしてレイドの難易度を追加します</system:String>
|
||||
<system:String x:Key="CopilotClearTask">右クリックして非アクティブなタスクをクリアします</system:String>
|
||||
<system:String x:Key="LoopTimes">ループ回数</system:String>
|
||||
<system:String x:Key="Start">開始</system:String>
|
||||
<system:String x:Key="VideoLink">映像へのハイパーリンク</system:String>
|
||||
@@ -451,6 +455,12 @@ Bilibili: ログイン インターフェイスに表示されるアカウント
|
||||
手動形成後、「開始デプロイメント」画面から開始してください(「ループ回数」で使用可能)。\n\n
|
||||
5. ビデオ認識もサポートされており、ガイドビデオをドラッグして使用できます。\n
|
||||
ビデオ解像度は16:9必須。黒枠、エミュレーター枠、特殊な形状、画面効果などが無いことを確認してください。\n\n
|
||||
6. バトルリスト:\n
|
||||
ジョブを選択した後、リストの下のレベル名が正しいことを確認してください (例: CV-EX-1)。 \n
|
||||
追加: 左クリックしてノーマル難易度を追加し、右クリックしてレイド難易度を追加します。\n
|
||||
クリア: 左クリックするとリストがクリアされ、右クリックすると非アクティブなタスクのみが削除されます。\n
|
||||
開始する前に、レベル選択インターフェースに切り替える必要があります。章間のナビゲーションはサポートされていません。\n
|
||||
正気度が不十分な場合、戦闘が失敗した場合、または 3 つ星を解決できない場合、アクションは終了します。 \n\n
|
||||
</system:String>
|
||||
<system:String x:Key="CopilotFileReadError">ファイルの読み取りに失敗しました!</system:String>
|
||||
<system:String x:Key="CopilotNoFound">対応する攻略ファイルが見つかりません!</system:String>
|
||||
|
||||
@@ -448,6 +448,10 @@ Bilibili: 로그인 인터페이스에 표시되는 계정 이름(예: Zhang San
|
||||
<system:String x:Key="AddTrust">신뢰도가 낮은 운영자 추가</system:String>
|
||||
<system:String x:Key="AddUserAdditional">맞춤 연산자 추가</system:String>
|
||||
<system:String x:Key="AddUserAdditionalTip">사용 ";" 운영자 이름과 기술을 구분하기 위해 구분 기호 ","를 사용합니다. 예: W, 3; Ash, 2</system:String>
|
||||
<system:String x:Key="UseCopilotList">전투 목록</system:String>
|
||||
<system:String x:Key="UseCopilotListTip">시작하기 전에 레벨 선택 페이지로 전환하세요</system:String>
|
||||
<system:String x:Key="CopilotAddTask">공격대 난이도를 추가하려면 마우스 오른쪽 버튼을 클릭하세요.</system:String>
|
||||
<system:String x:Key="CopilotClearTask">비활성 작업을 지우려면 마우스 오른쪽 버튼을 클릭하세요.</system:String>
|
||||
<system:String x:Key="LoopTimes">반복 횟수</system:String>
|
||||
<system:String x:Key="Start">시작</system:String>
|
||||
<system:String x:Key="VideoLink">영상 링크</system:String>
|
||||
@@ -461,6 +465,12 @@ Bilibili: 로그인 인터페이스에 표시되는 계정 이름(예: Zhang San
|
||||
수동 편성 후 '작전 개시' 버튼이 있는 화면에서 시작하세요. ('반복 횟수'와 함께 사용 가능)\n\n
|
||||
5. 동영상 인식이 지원되며, 가이드 동영상를 드래그하여 사용할 수 있습니다.\n
|
||||
동영상의 해상도는 16:9여야 하며, 검은색 테두리, 에뮬레이터 테두리, 특수한 모양의 화면 보정 등의 방해 요소가 없어야 합니다.\n\n
|
||||
6. 전투 목록:\n
|
||||
작업을 선택한 후 목록 아래의 레벨 이름이 올바른지 확인하세요(예: CV-EX-1). \n
|
||||
추가: 일반 난이도를 추가하려면 마우스 왼쪽 버튼을 클릭하고, 레이드 난이도를 추가하려면 마우스 오른쪽 버튼을 클릭하세요. \n
|
||||
지우기: 목록을 지우려면 마우스 왼쪽 버튼을 클릭하고, 비활성 작업만 제거하려면 마우스 오른쪽 버튼을 클릭합니다. \n
|
||||
시작하기 전에 레벨 선택 인터페이스로 전환해야 합니다. 크로스 챕터 탐색은 지원되지 않습니다. \n
|
||||
정신력이 부족하거나, 전투가 실패하거나, 별 3개를 해결할 수 없는 경우 액션이 종료됩니다. \n\n
|
||||
</system:String>
|
||||
<system:String x:Key="CopilotFileReadError">파일을 읽지 못했습니다!</system:String>
|
||||
<system:String x:Key="CopilotNoFound">해당 파일을 찾을 수 없습니다!</system:String>
|
||||
|
||||
@@ -468,6 +468,10 @@
|
||||
<system:String x:Key="AddUserAdditional">追加自定干员</system:String>
|
||||
<system:String x:Key="AddUserAdditionalTip">以英文";"为分隔符,英文","分隔干员名与技能,例: 史尔特尔,3;艾雅法拉,1</system:String>
|
||||
<system:String x:Key="LoopTimes">循环次数</system:String>
|
||||
<system:String x:Key="UseCopilotList">战斗列表</system:String>
|
||||
<system:String x:Key="UseCopilotListTip">开始前请切换至关卡选择页面</system:String>
|
||||
<system:String x:Key="CopilotAddTask">右键添加突袭难度</system:String>
|
||||
<system:String x:Key="CopilotClearTask">右键清除未激活任务</system:String>
|
||||
<system:String x:Key="Start">开始</system:String>
|
||||
<system:String x:Key="VideoLink">视频链接</system:String>
|
||||
<!-- 日志 -->
|
||||
@@ -480,6 +484,12 @@
|
||||
请手动编队后在「开始部署」界面开始(可配合「循环次数」使用)\n\n
|
||||
5. 现已支持视频识别,请将攻略视频文件拖入后开始。\n
|
||||
需要视频分辨率为 16:9,无黑边、模拟器边框、异形屏矫正等干扰元素\n\n
|
||||
6. 战斗列表:\n
|
||||
选择作业后,检查列表下方的关卡名是否正确(如: CV-EX-1)。\n
|
||||
添加: 左键添加正常难度,右键添加突袭难度。\n
|
||||
清除: 左键清空列表,右键仅移除未激活的任务。\n
|
||||
开始前,需要切换至对应关卡的选择界面,不支持跨章节导航。\n
|
||||
遇到 理智不足、战斗失败、未能以三星结算 时将会中止运行。\n\n
|
||||
</system:String>
|
||||
<system:String x:Key="CopilotFileReadError">读取文件失败!</system:String>
|
||||
<system:String x:Key="CopilotNoFound">未找到对应作业!</system:String>
|
||||
@@ -645,11 +655,11 @@
|
||||
<system:String x:Key="GameResourceUpdated">游戏资源已更新,请重启 MAA</system:String>
|
||||
<system:String x:Key="GameResourceUpdating">正在更新游戏资源,请耐心等待</system:String>
|
||||
<!-- Api -->
|
||||
<!-- External Notification -->
|
||||
<!-- External Notification -->
|
||||
<system:String x:Key="ExternalNotificationEmailTemplateHello">博士,有新的通知哦!</system:String>
|
||||
<system:String x:Key="ExternalNotificationEmailTemplateFooterLineOne">您会收到此邮件,是因为您在 MAA 中设置了 SMTP 服务器并开启了邮件通知服务。</system:String>
|
||||
<system:String x:Key="ExternalNotificationEmailTemplateFooterLineTwo">此邮件为系统自动发送,请勿回复。</system:String>
|
||||
<system:String x:Key="ExternalNotificationEmailTemplateLinkOfficialSite">官网</system:String>
|
||||
<system:String x:Key="ExternalNotificationEmailTemplateLinkCopilotSite">作业站</system:String>
|
||||
<!-- External Notification -->
|
||||
<!-- External Notification -->
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -448,6 +448,10 @@
|
||||
<system:String x:Key="AddTrust">補充低信賴幹員</system:String>
|
||||
<system:String x:Key="AddUserAdditional">追加自定幹員</system:String>
|
||||
<system:String x:Key="AddUserAdditionalTip">使用";"作為分隔符,用","分隔操作員姓名和技能,例:史尔特尔,3;艾雅法拉,1</system:String>
|
||||
<system:String x:Key="UseCopilotList">戰鬥列表</system:String>
|
||||
<system:String x:Key="UseCopilotListTip">開始前請切換至關卡選擇頁面</system:String>
|
||||
<system:String x:Key="CopilotAddTask">右鍵添加突襲難度</system:String>
|
||||
<system:String x:Key="CopilotClearTask">右鍵清除未激活任務</system:String>
|
||||
<system:String x:Key="LoopTimes">循環次數</system:String>
|
||||
<system:String x:Key="Start">開始</system:String>
|
||||
<system:String x:Key="VideoLink">影片連結</system:String>
|
||||
@@ -461,6 +465,12 @@
|
||||
請手動編隊後在「開始部署」介面開始(可配合「循環次數」使用)\n\n
|
||||
5. 現已支援影片辨識,請將攻略影片拖入使用。 \n
|
||||
需要影片分辨率為 16:9,無黑邊、模擬器邊框、異形屏矯正等干擾因素。\n\n
|
||||
6. 戰鬥列表:\n
|
||||
選擇作業後,檢查列表下方的關卡名是否正確 (如: CV-EX-1) 。 \n
|
||||
添加: 左鍵添加正常難度,右鍵添加突襲難度。 \n
|
||||
清除: 左鍵清空列表,右鍵僅移除未激活的任務。 \n
|
||||
開始前,需要切換至對應關卡的選擇界面,不支持跨章節導航。 \n
|
||||
遇到 理智不足、戰鬥失敗、未能以三星結算 時將會中止運行。 \n\n
|
||||
</system:String>
|
||||
<system:String x:Key="CopilotFileReadError">讀取檔案失敗!</system:String>
|
||||
<system:String x:Key="CopilotNoFound">未找到對應作業!</system:String>
|
||||
|
||||
107
src/MaaWpfGui/ViewModels/CopilotItemViewModel.cs
Normal file
107
src/MaaWpfGui/ViewModels/CopilotItemViewModel.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System.Security.RightsManagement;
|
||||
using MaaWpfGui.Helper;
|
||||
using Stylet;
|
||||
using Vanara.PInvoke;
|
||||
|
||||
namespace MaaWpfGui.ViewModels
|
||||
{
|
||||
public class CopilotItemViewModel : PropertyChangedBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CopilotItemViewModel"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="filePath">The original Name of file</param>
|
||||
/// <param name="isChecked">isChecked</param>
|
||||
public CopilotItemViewModel(string name, string filePath, bool isChecked = true)
|
||||
{
|
||||
_name = name;
|
||||
_filePath = filePath;
|
||||
_isChecked = isChecked;
|
||||
}
|
||||
|
||||
private string _filePath;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the original_name.
|
||||
/// </summary>
|
||||
public string FilePath
|
||||
{
|
||||
get => _filePath;
|
||||
set => SetAndNotify(ref _filePath, value);
|
||||
}
|
||||
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetAndNotify(ref _name, value);
|
||||
}
|
||||
|
||||
private bool _isChecked;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether gets or sets whether the key is checked.
|
||||
/// </summary>
|
||||
public bool IsChecked
|
||||
{
|
||||
get => _isChecked;
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _isChecked, value);
|
||||
Instances.CopilotViewModel.SaveCopilotTask();
|
||||
}
|
||||
}
|
||||
|
||||
// 换成图标的话要这个,暂时没用
|
||||
private string _iconPath;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icon path.
|
||||
/// </summary>
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public string IconPath
|
||||
{
|
||||
get => _iconPath;
|
||||
set => SetAndNotify(ref _iconPath, value);
|
||||
}
|
||||
|
||||
private string _token;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the token.
|
||||
/// </summary>
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public string Token
|
||||
{
|
||||
get => _token;
|
||||
set => SetAndNotify(ref _token, value);
|
||||
}
|
||||
|
||||
private string _runStatus;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the running status.
|
||||
/// </summary>
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public string RunStatus
|
||||
{
|
||||
get => _runStatus;
|
||||
set => SetAndNotify(ref _runStatus, value);
|
||||
}
|
||||
|
||||
private int _index = 0;
|
||||
|
||||
public int Index
|
||||
{
|
||||
get => _index;
|
||||
set => SetAndNotify(ref _index, value);
|
||||
}
|
||||
|
||||
public int GetIndex() => Index;
|
||||
}
|
||||
}
|
||||
@@ -21,14 +21,17 @@ using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using HandyControl.Tools.Extension;
|
||||
using MaaWpfGui.Constants;
|
||||
using MaaWpfGui.Helper;
|
||||
using MaaWpfGui.States;
|
||||
using Microsoft.Win32;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Serilog;
|
||||
using Stylet;
|
||||
using DataFormats = System.Windows.Forms.DataFormats;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
namespace MaaWpfGui.ViewModels.UI
|
||||
{
|
||||
@@ -46,6 +49,11 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
/// </summary>
|
||||
public ObservableCollection<LogItemViewModel> LogItemViewModels { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or private sets the view models of Copilot items.
|
||||
/// </summary>
|
||||
public ObservableCollection<CopilotItemViewModel> CopilotItemViewModels { get; private set; } = new ObservableCollection<CopilotItemViewModel>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CopilotViewModel"/> class.
|
||||
/// </summary>
|
||||
@@ -56,6 +64,21 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
AddLog(LocalizationHelper.GetString("CopilotTip"));
|
||||
_runningState = RunningState.Instance;
|
||||
_runningState.IdleChanged += RunningState_IdleChanged;
|
||||
|
||||
var copilotTaskList = ConfigurationHelper.GetValue(ConfigurationKeys.CopilotTaskList, string.Empty);
|
||||
if (!string.IsNullOrEmpty(copilotTaskList))
|
||||
{
|
||||
JArray jArray = JArray.Parse(copilotTaskList);
|
||||
foreach (var item in jArray)
|
||||
{
|
||||
if ((item as JObject).TryGetValue("file_path", out var token) && File.Exists(token.ToString()))
|
||||
{
|
||||
CopilotItemViewModels.Add(new CopilotItemViewModel((string)item["name"], (string)item["file_path"], (bool)item["is_checked"]));
|
||||
}
|
||||
}
|
||||
|
||||
CopilotItemIndexChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void RunningState_IdleChanged(object sender, bool e)
|
||||
@@ -236,6 +259,14 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
if (doc != null && doc.TryGetValue("title", out var titleValue))
|
||||
{
|
||||
title = titleValue.ToString();
|
||||
|
||||
// 为自动作战列表匹配名字
|
||||
var linkParser = new Regex(@"([a-z]{0,3})(\d{0,2})-(EX-)?(\d{1,2})", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
foreach (Match match in linkParser.Matches(title))
|
||||
{
|
||||
CopilotTaskName = match.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (title.Length != 0)
|
||||
@@ -503,6 +534,159 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to use auto-formation.
|
||||
/// </summary>
|
||||
private bool _useCopilotList = false;
|
||||
|
||||
public bool UseCopilotList
|
||||
{
|
||||
get => _useCopilotList;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
_taskType = "Copilot";
|
||||
}
|
||||
|
||||
SetAndNotify(ref _useCopilotList, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to use auto-formation.
|
||||
/// </summary>
|
||||
private string _copilotTaskName = string.Empty;
|
||||
|
||||
public string CopilotTaskName
|
||||
{
|
||||
get => _copilotTaskName;
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _copilotTaskName, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static string copilotJsonDir = "cache/copilot";
|
||||
|
||||
public void AddCopilotTask()
|
||||
{
|
||||
var stage_name = CopilotTaskName.Trim().Replace("突袭", "-Adverse");
|
||||
if (!stage_name.IsNullOrEmpty())
|
||||
{
|
||||
AddCopilotTaskToList(stage_name);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCopilotTask_Adverse()
|
||||
{
|
||||
var stage_name = CopilotTaskName.Trim().Replace("突袭", "-Adverse");
|
||||
if (!stage_name.EndsWith("-Adverse"))
|
||||
{
|
||||
stage_name += "-Adverse";
|
||||
}
|
||||
|
||||
if (!stage_name.IsNullOrEmpty())
|
||||
{
|
||||
AddCopilotTaskToList(stage_name);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCopilotTaskToList(string stage_name)
|
||||
{
|
||||
var jsonPath = $"{copilotJsonDir}/{stage_name}.json";
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(copilotJsonDir);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.Copy(IsDataFromWeb ? TempCopilotFile : Filename, jsonPath, true);
|
||||
var item = new CopilotItemViewModel(stage_name, jsonPath)
|
||||
{
|
||||
Index = CopilotItemViewModels.Count,
|
||||
};
|
||||
CopilotItemViewModels.Add(item);
|
||||
SaveCopilotTask();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
AddLog(LocalizationHelper.GetString("CopilotJsonError"), UiLogColor.Error);
|
||||
Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveCopilotTask()
|
||||
{
|
||||
JArray jArray = new JArray(CopilotItemViewModels.Select(item => new JObject
|
||||
{
|
||||
["name"] = item.Name,
|
||||
["file_path"] = item.FilePath,
|
||||
["is_checked"] = item.IsChecked,
|
||||
}).ToArray());
|
||||
ConfigurationHelper.SetValue(ConfigurationKeys.CopilotTaskList, JsonConvert.SerializeObject(jArray));
|
||||
}
|
||||
|
||||
public void DeleteCopilotTask(int index)
|
||||
{
|
||||
CopilotItemViewModels.RemoveAt(index);
|
||||
CopilotItemIndexChanged();
|
||||
}
|
||||
|
||||
public void CleanUnableCopilotTask()
|
||||
{
|
||||
foreach (var item in CopilotItemViewModels.Where(model => !model.IsChecked).ToList())
|
||||
{
|
||||
CopilotItemViewModels.Remove(item);
|
||||
}
|
||||
|
||||
CopilotItemIndexChanged();
|
||||
}
|
||||
|
||||
public void ClearCopilotTask()
|
||||
{
|
||||
CopilotItemViewModels.Clear();
|
||||
SaveCopilotTask();
|
||||
}
|
||||
|
||||
public void EnterCopilotTask()
|
||||
{
|
||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
for (int i = 0; i < CopilotItemViewModels.Count; i++)
|
||||
{
|
||||
if (CopilotItemViewModels[i].IsChecked)
|
||||
{
|
||||
CopilotItemViewModels[i].IsChecked = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SaveCopilotTask();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新任务顺序
|
||||
/// </summary>
|
||||
public void CopilotItemIndexChanged()
|
||||
{
|
||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
for (int i = 0; i < CopilotItemViewModels.Count; i++)
|
||||
{
|
||||
CopilotItemViewModels[i].Index = i;
|
||||
}
|
||||
|
||||
SaveCopilotTask();
|
||||
});
|
||||
}
|
||||
|
||||
public bool Loop { get; set; }
|
||||
|
||||
private int _loopTimes = int.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.CopilotLoopTimes, "1"));
|
||||
@@ -558,14 +742,52 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
AddLog(errMsg, UiLogColor.Error);
|
||||
}
|
||||
|
||||
bool ret = Instances.AsstProxy.AsstStartCopilot(IsDataFromWeb ? TempCopilotFile : Filename, Form, AddTrust, AddUserAdditional, UserAdditional, _taskType,
|
||||
Loop ? LoopTimes : 1);
|
||||
JArray mUserAdditional = new JArray();
|
||||
Regex regex = new Regex(@"(?<=;)(?<name>[^,;]+)(?:, *(?<skill>\d))? *", RegexOptions.Compiled);
|
||||
MatchCollection matches = regex.Matches(";" + UserAdditional);
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
mUserAdditional.Add(new JObject
|
||||
{
|
||||
["name"] = match.Groups[1].Value.Trim(),
|
||||
["skill"] = match.Groups[2].Value.IsNullOrEmpty() ? 0 : int.Parse(match.Groups[2].Value),
|
||||
});
|
||||
}
|
||||
|
||||
bool ret = true;
|
||||
if (UseCopilotList)
|
||||
{
|
||||
bool startAny = false;
|
||||
foreach (var model in CopilotItemViewModels)
|
||||
{
|
||||
if (model.IsChecked)
|
||||
{
|
||||
ret &= Instances.AsstProxy.AsstStartCopilot(model.FilePath, Form, AddTrust, AddUserAdditional, mUserAdditional, UseCopilotList, model.Name.Replace("-Adverse", string.Empty), model.Name.Contains("-Adverse"), _taskType, Loop ? LoopTimes : 1, false);
|
||||
startAny = true;
|
||||
}
|
||||
}
|
||||
|
||||
ret &= Instances.AsstProxy.AsstStart();
|
||||
if (!startAny)
|
||||
{
|
||||
// 一个都没启动,怎会有如此无聊之人
|
||||
Instances.AsstProxy.AsstStop();
|
||||
_runningState.SetIdle(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret &= Instances.AsstProxy.AsstStartCopilot(IsDataFromWeb ? TempCopilotFile : Filename, Form, AddTrust, AddUserAdditional, mUserAdditional, UseCopilotList, string.Empty, false, _taskType, Loop ? LoopTimes : 1);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
AddLog(LocalizationHelper.GetString("Running"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Instances.AsstProxy.AsstStop();
|
||||
_runningState.SetIdle(true);
|
||||
AddLog(LocalizationHelper.GetString("CopilotFileReadError"), UiLogColor.Error);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
xmlns:constants="clr-namespace:MaaWpfGui.Constants"
|
||||
xmlns:controls="clr-namespace:MaaWpfGui.Styles.Controls"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:dd="urn:gong-wpf-dragdrop"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
xmlns:helper="clr-namespace:MaaWpfGui.Helper"
|
||||
xmlns:local="clr-namespace:MaaWpfGui"
|
||||
@@ -31,7 +32,7 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
<StackPanel
|
||||
Grid.Row="0"
|
||||
Margin="0,30,0,0"
|
||||
Margin="0,10,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
Orientation="Vertical">
|
||||
@@ -43,6 +44,7 @@
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ComboBox
|
||||
Height="30"
|
||||
@@ -54,6 +56,16 @@
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Height="30"
|
||||
hc:BorderElement.CornerRadius="0,0,0,0"
|
||||
hc:IconElement.Geometry="{StaticResource SearchGeometry}"
|
||||
BorderThickness="0,1,1,1"
|
||||
Command="{s:Action SelectFile}"
|
||||
IsEnabled="{Binding Idle}"
|
||||
Style="{StaticResource ButtonDefault}"
|
||||
ToolTip="{DynamicResource SelectTheFileTip}" />
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
Height="30"
|
||||
hc:BorderElement.CornerRadius="0,4,4,0"
|
||||
hc:IconElement.Geometry="{StaticResource PasteGeometry}"
|
||||
BorderThickness="0,1,1,1"
|
||||
@@ -62,90 +74,217 @@
|
||||
Style="{StaticResource ButtonDefault}"
|
||||
ToolTip="{DynamicResource PasteClipboardTip}" />
|
||||
</Grid>
|
||||
<Button
|
||||
Width="120"
|
||||
Height="50"
|
||||
Margin="10"
|
||||
Command="{s:Action SelectFile}"
|
||||
Content="{DynamicResource SelectTheFile}"
|
||||
IsEnabled="{Binding Idle}"
|
||||
ToolTip="{DynamicResource SelectTheFileTip}" />
|
||||
<Grid
|
||||
Margin="0,10,0,0"
|
||||
HorizontalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="100" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<CheckBox
|
||||
<Grid Height="280" Margin="0,5,0,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Grid.Row="0" HorizontalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="100" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<CheckBox
|
||||
HorizontalAlignment="Center"
|
||||
Content="{DynamicResource AutoSquad}"
|
||||
IsChecked="{Binding Form}"
|
||||
IsEnabled="{Binding Idle}"
|
||||
IsHitTestVisible="{Binding Idle}"
|
||||
ToolTip="{DynamicResource AutoSquadTip}" />
|
||||
<CheckBox
|
||||
Grid.Column="1"
|
||||
Margin="10,0,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Content="{DynamicResource AddTrust}"
|
||||
IsChecked="{Binding AddTrust}"
|
||||
IsEnabled="{Binding Idle}"
|
||||
IsHitTestVisible="{Binding Idle}"
|
||||
Visibility="{c:Binding Form}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
Grid.Row="1"
|
||||
Margin="0,10,0,-2"
|
||||
HorizontalAlignment="Center"
|
||||
Content="{DynamicResource AutoSquad}"
|
||||
IsChecked="{Binding Form}"
|
||||
Visibility="{c:Binding Form}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="100" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<CheckBox
|
||||
HorizontalAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
Content="{DynamicResource AddUserAdditional}"
|
||||
IsChecked="{Binding AddUserAdditional}"
|
||||
IsEnabled="{Binding Idle}"
|
||||
IsHitTestVisible="{Binding Idle}"
|
||||
ToolTip="{DynamicResource AddUserAdditionalTip}"
|
||||
Visibility="{c:Binding Form}" />
|
||||
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
MinWidth="150"
|
||||
Margin="5,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
IsEnabled="{c:Binding '(Form) and (Idle)'}"
|
||||
IsHitTestVisible="{Binding AddUserAdditional}"
|
||||
MaxLines="1"
|
||||
Text="{Binding UserAdditional, UpdateSourceTrigger=LostFocus}"
|
||||
ToolTip="{DynamicResource AddUserAdditionalTip}"
|
||||
Visibility="{c:Binding '(Form) and (AddUserAdditional)'}" />
|
||||
</Grid>
|
||||
<CheckBox
|
||||
Grid.Row="2"
|
||||
Margin="0,12,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Content="{DynamicResource UseCopilotList}"
|
||||
IsChecked="{Binding UseCopilotList}"
|
||||
IsEnabled="{Binding Idle}"
|
||||
IsHitTestVisible="{Binding Idle}"
|
||||
ToolTip="{DynamicResource AutoSquadTip}"/>
|
||||
<CheckBox
|
||||
Grid.Column="1"
|
||||
ToolTip="{DynamicResource UseCopilotListTip}" />
|
||||
<Border
|
||||
Grid.Row="3"
|
||||
Width="200"
|
||||
Margin="0,10,0,0"
|
||||
BorderBrush="{DynamicResource BorderBrush}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="4"
|
||||
Visibility="{c:Binding UseCopilotList}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="40" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox
|
||||
x:Name="CopilotList"
|
||||
dd:DragDrop.IsDragSource="{Binding Idle}"
|
||||
dd:DragDrop.IsDropTarget="{Binding Idle}"
|
||||
BorderThickness="0"
|
||||
DragDrop.Drop="{s:Action CopilotItemIndexChanged}"
|
||||
IsEnabled="{c:Binding '(Idle) and (StartEnabled)'}"
|
||||
ItemContainerStyle="{StaticResource CustomListBoxItemStyle}"
|
||||
ItemsSource="{Binding Path=CopilotItemViewModels}"
|
||||
ToolTip="{DynamicResource LabelSequenceTip}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<!--<maa:TextBlock Text="{Binding ID}" />
|
||||
<maa:TextBlock Text=". " />-->
|
||||
<CheckBox
|
||||
Grid.Column="0"
|
||||
Content="{c:Binding Name}"
|
||||
IsChecked="{Binding IsChecked}"
|
||||
IsHitTestVisible="{Binding ElementName=CopilotList, Path=DataContext.Idle}" />
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
hc:IconElement.Geometry="{StaticResource CloseGeometry}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
Command="{s:Action DeleteCopilotTask}"
|
||||
CommandParameter="{c:Binding Index}"
|
||||
Foreground="{DynamicResource SecondaryTextBrush}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<Grid Grid.Row="1" Margin="5,0,2,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="42" />
|
||||
<ColumnDefinition Width="42" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox
|
||||
Margin="0,7,0,5"
|
||||
VerticalContentAlignment="Center"
|
||||
IsEnabled="{Binding Idle}"
|
||||
MaxLines="1"
|
||||
Text="{Binding CopilotTaskName, UpdateSourceTrigger=LostFocus}" />
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Margin="2,0,0,0"
|
||||
hc:IconElement.Geometry="{StaticResource AddGeometry}"
|
||||
Command="{s:Action AddCopilotTask}"
|
||||
IsEnabled="{c:Binding '(Idle) and (StartEnabled)'}"
|
||||
MouseRightButtonUp="{s:Action AddCopilotTask_Adverse}"
|
||||
ToolTip="{DynamicResource CopilotAddTask}" />
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
Margin="2,0,0,0"
|
||||
hc:IconElement.Geometry="{StaticResource ErrorGeometry}"
|
||||
Command="{s:Action ClearCopilotTask}"
|
||||
IsEnabled="{c:Binding '(Idle) and (StartEnabled)'}"
|
||||
MouseRightButtonUp="{s:Action CleanUnableCopilotTask}"
|
||||
ToolTip="{DynamicResource CopilotClearTask}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
<StackPanel
|
||||
Grid.Row="4"
|
||||
Margin="0,5,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Content="{DynamicResource AddTrust}"
|
||||
IsChecked="{Binding AddTrust}"
|
||||
Visibility="{c:Binding Form}"
|
||||
IsEnabled="{Binding Idle}"
|
||||
IsHitTestVisible="{Binding Idle}" Margin="10,0,0,0"/>
|
||||
Orientation="Horizontal"
|
||||
Visibility="{c:Binding !UseCopilotList}">
|
||||
<CheckBox
|
||||
Margin="0,0,10,0"
|
||||
VerticalContentAlignment="Center"
|
||||
Content="{DynamicResource LoopTimes}"
|
||||
IsChecked="{Binding Loop}" />
|
||||
<TextBox
|
||||
Width="60"
|
||||
Height="30"
|
||||
HorizontalContentAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
InputMethod.IsInputMethodEnabled="False"
|
||||
Text="{Binding LoopTimes}" />
|
||||
</StackPanel>
|
||||
|
||||
<controls:TextBlock
|
||||
Grid.Row="5"
|
||||
Margin="5,15,5,5"
|
||||
Block.TextAlignment="Center"
|
||||
Visibility="{c:Binding !UseCopilotList}">
|
||||
<Hyperlink
|
||||
Cursor="Hand"
|
||||
NavigateUri="{Binding Url}"
|
||||
TextDecorations="None">
|
||||
<TextBlock Text="{Binding UrlText}" />
|
||||
</Hyperlink>
|
||||
</controls:TextBlock>
|
||||
<controls:TextBlock
|
||||
Grid.Row="6"
|
||||
Margin="5,5,5,30"
|
||||
Block.TextAlignment="Center"
|
||||
Visibility="{c:Binding !UseCopilotList}">
|
||||
<Hyperlink
|
||||
Cursor="Hand"
|
||||
NavigateUri="{Binding Source={x:Static constants:MaaUrls.MapPrts}}"
|
||||
TextDecorations="None">
|
||||
<TextBlock Text="{DynamicResource MapPrts}" />
|
||||
</Hyperlink>
|
||||
</controls:TextBlock>
|
||||
|
||||
</Grid>
|
||||
<Grid
|
||||
Margin="0,10,0,25"
|
||||
Height="30"
|
||||
HorizontalAlignment="Center">
|
||||
<Grid Margin="0,10,0,0" HorizontalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="100" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<CheckBox
|
||||
HorizontalAlignment="Center"
|
||||
Content="{DynamicResource AddUserAdditional}"
|
||||
IsChecked="{Binding AddUserAdditional}"
|
||||
IsEnabled="{Binding Idle}"
|
||||
IsHitTestVisible="{Binding Idle}"
|
||||
Visibility="{c:Binding Form}"
|
||||
ToolTip="{DynamicResource AddUserAdditionalTip}"/>
|
||||
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
IsEnabled="{c:Binding '(Form) and (Idle)'}"
|
||||
IsHitTestVisible="{Binding AddUserAdditional}"
|
||||
Text="{Binding UserAdditional, UpdateSourceTrigger=LostFocus}"
|
||||
VerticalAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
Visibility="{c:Binding '(Form) and (AddUserAdditional)'}"
|
||||
ToolTip="{DynamicResource AddUserAdditionalTip}"
|
||||
MinWidth="150"
|
||||
MaxLines="1"
|
||||
Margin="5,0,0,0"/>
|
||||
</Grid>
|
||||
|
||||
<StackPanel
|
||||
Margin="10"
|
||||
HorizontalAlignment="Center"
|
||||
IsEnabled="{Binding Idle}"
|
||||
Orientation="Horizontal">
|
||||
<CheckBox
|
||||
Margin="10"
|
||||
VerticalContentAlignment="Center"
|
||||
Content="{DynamicResource LoopTimes}"
|
||||
IsChecked="{Binding Loop}" />
|
||||
<TextBox
|
||||
Width="60"
|
||||
Height="30"
|
||||
HorizontalContentAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
InputMethod.IsInputMethodEnabled="False"
|
||||
Text="{Binding LoopTimes}" />
|
||||
</StackPanel>
|
||||
<Grid Margin="0,10,0,30">
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Width="120"
|
||||
Height="50"
|
||||
Command="{s:Action Start}"
|
||||
@@ -153,28 +292,13 @@
|
||||
IsEnabled="{c:Binding StartEnabled}"
|
||||
Visibility="{c:Binding Idle}" />
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Width="120"
|
||||
Height="50"
|
||||
Command="{s:Action Stop}"
|
||||
Content="{DynamicResource Stop}"
|
||||
Visibility="{c:Binding !Idle}" />
|
||||
</Grid>
|
||||
<controls:TextBlock Margin="5" Block.TextAlignment="Center">
|
||||
<Hyperlink
|
||||
Cursor="Hand"
|
||||
NavigateUri="{Binding Url}"
|
||||
TextDecorations="None">
|
||||
<TextBlock Text="{Binding UrlText}" />
|
||||
</Hyperlink>
|
||||
</controls:TextBlock>
|
||||
<controls:TextBlock Margin="5" Block.TextAlignment="Center">
|
||||
<Hyperlink
|
||||
Cursor="Hand"
|
||||
NavigateUri="{Binding Source={x:Static constants:MaaUrls.MapPrts}}"
|
||||
TextDecorations="None">
|
||||
<TextBlock Text="{DynamicResource MapPrts}" />
|
||||
</Hyperlink>
|
||||
</controls:TextBlock>
|
||||
</StackPanel>
|
||||
|
||||
<Grid Grid.Column="1">
|
||||
|
||||
Reference in New Issue
Block a user