Skip to content

Commit

Permalink
feat: 新增动作 Command (#463)
Browse files Browse the repository at this point in the history
@MaaXYZ/binding-developers  来看看怎么样=。=
  • Loading branch information
MistEO authored Dec 18, 2024
1 parent ba23fcc commit ab75da5
Show file tree
Hide file tree
Showing 13 changed files with 389 additions and 22 deletions.
57 changes: 56 additions & 1 deletion docs/en_us/3.1-PipelineProtocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ This loop continues until the "next" of a task is empty, which signifies that th
- `action`: *string*
Action to execute. Optional, default is `DoNothing`.
Possible values: `DoNothing` | `Click` | `Swipe` | `MultiSwipe` | `Key` | `InputText` | `StartApp` | `StopApp` | `StopTask` | `Custom`.
Possible values: `DoNothing` | `Click` | `Swipe` | `MultiSwipe` | `Key` | `InputText` | `StartApp` | `StopApp` | `StopTask` | `Command` | `Custom`.
See [Action Types](#action-types) for details.
- `next`: *string* | *list<string, >*
Expand Down Expand Up @@ -553,6 +553,61 @@ Additional properties for this action:

Stops the current task chain (the individual task chain passed to MaaTaskerPostPipeline).

### `Command`

Execute a command.

This action attribute requires additional fields:

- `exec`: *string*
The path of the program to be executed. Required.

- `args`: *list<string,>*
The arguments to be executed. Optional.
supports runtime parameters replacement:

- `{ENTRY}`: Entry name.
- `{NODE}`: Node name.
- `{IMAGE}`: The path to the file where the screenshot is saved. The file is deleted before the process exits. Please copy it by yourself if you want to save it permanently.
- `{BOX}`: Identify the hit target, the format is `[x, y, w, h]`.
- `{RESOURCE_DIR}`: The path of the resource folder loaded last time.
- `{LIBRARY_DIR}`: The path of the folder where the MaaFW library is located.

- `detach`: *bool*
Detach the child process, that is, do not wait for the child process to complete, and directly continue with the subsequent tasks. Optional, default false.

Example:

```jsonc
{
"TaskA": {
"action": "Command",
"exec": "Python",
"args": [
"{RESOURCE_DIR}/my_script/test.py"
"Haha",
"{IMAGE}",
"{NODE}",
"{BOX}"
]
},
"TaskB": {
"action": "Command",
"exec": "{RESOURCE_DIR}/my_exec/my_exec.exe"
}
}
```

The actual command is:

```bash
# TaskA
Python C:/MaaXXX/resource/my_script/test.py Haha C:/temp/123.png TaskA [0,0,0,0]
# TaskB
C:/MaaXXX/resource/my_exec/my_exec.exe
```

### `Custom`

Execute the action handle passed in through the `MaaResourceRegisterCustomAction` interface
Expand Down
57 changes: 56 additions & 1 deletion docs/zh_cn/3.1-任务流水线协议.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Orange 的 next 中,
- `action`: *string*
执行的动作。可选,默认 `DoNothing` 。
可选的值:`DoNothing` | `Click` | `Swipe` | `MultiSwipe` | `Key` | `InputText` | `StartApp` | `StopApp` | `StopTask` | `Custom`
可选的值:`DoNothing` | `Click` | `Swipe` | `MultiSwipe` | `Key` | `InputText` | `StartApp` | `StopApp` | `StopTask` | `Command` | `Custom`
详见 [动作类型](#动作类型)。
- `next` : *string* | *list<string, >*
Expand Down Expand Up @@ -563,6 +563,61 @@ Orange 的 next 中,
停止当前任务链(MaaTaskerPostPipeline 传入的单个任务链)。
### `Command`
执行命令。
该动作属性需额外部分字段:
- `exec`: *string*
执行的程序路径。必选。
- `args`: *list<string,>*
执行的参数。可选。
支持部分运行期参数替换:
- `{ENTRY}`: 任务入口名。
- `{NODE}`: 当前任务名。
- `{IMAGE}`: 截图保存到文件的路径。该文件在进程退出前删除,若要持久保存请自行复制。
- `{BOX}`: 识别命中的目标,格式为 `[x, y, w, h]`。
- `{RESOURCE_DIR}`: 最后一次加载的资源文件夹路径。
- `{LIBRARY_DIR}`: MaaFW 库所在的文件夹路径。
- `detach`: *bool*
分离子进程,即不等待子进程执行完成,直接继续之后后面的任务。可选,默认 false。
举例:
```jsonc
{
"TaskA": {
"action": "Command",
"exec": "Python",
"args": [
"{RESOURCE_DIR}/my_script/test.py"
"Haha",
"{IMAGE}",
"{NODE}",
"{BOX}"
]
},
"TaskB": {
"action": "Command",
"exec": "{RESOURCE_DIR}/my_exec/my_exec.exe"
}
}
```
实际将会执行命令
```bash
# TaskA
Python C:/MaaXXX/resource/my_script/test.py Haha C:/temp/123.png TaskA [0,0,0,0]
# TaskB
C:/MaaXXX/resource/my_exec/my_exec.exe
```
### `Custom`
执行通过 `MaaResourceRegisterCustomAction` 接口传入的动作句柄。
Expand Down
15 changes: 4 additions & 11 deletions source/MaaAdbControlUnit/Base/ProcessArgvGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,15 @@ std::optional<ProcessArgvGenerator::ProcessArgv> ProcessArgvGenerator::gen(const
string_replace_all_(s, replacement);
}

std::filesystem::path abs_path;
if (auto raw_path = MAA_NS::path(res.front()); raw_path.is_absolute()) {
abs_path = raw_path;
}
else {
abs_path = boost::process::search_path(raw_path);
}

if (!std::filesystem::exists(abs_path)) {
LogError << "exec path not exists" << VAR(abs_path);
std::filesystem::path exec = boost::process::search_path(path(res.front()));
if (!std::filesystem::exists(exec)) {
LogError << "exec path not exists" << VAR(res.front()) << VAR(exec);
return std::nullopt;
}

auto args = std::vector(std::make_move_iterator(res.begin() + 1), std::make_move_iterator(res.end()));

return ProcessArgv { .exec = std::move(abs_path), .args = std::move(args) };
return ProcessArgv { .exec = std::move(exec), .args = std::move(args) };
}

MAA_CTRL_UNIT_NS_END
2 changes: 2 additions & 0 deletions source/MaaFramework/Resource/DefaultPipelineMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ bool DefaultPipelineMgr::parse_action(const json::value& input)
{ "startapp", Type::StartApp },
{ "StopApp", Type::StopApp },
{ "stopapp", Type::StopApp },
{ "Command", Type::Command },
{ "command", Type::Command },
{ "Custom", Type::Custom },
{ "custom", Type::Custom },
{ "StopTask", Type::StopTask },
Expand Down
36 changes: 34 additions & 2 deletions source/MaaFramework/Resource/PipelineResMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,8 @@ bool PipelineResMgr::parse_action(
{ "startapp", Type::StartApp },
{ "StopApp", Type::StopApp },
{ "stopapp", Type::StopApp },
{ "Command", Type::Command },
{ "command", Type::Command },
{ "Custom", Type::Custom },
{ "custom", Type::Custom },
{ "StopTask", Type::StopTask },
Expand Down Expand Up @@ -1176,7 +1178,8 @@ bool PipelineResMgr::parse_action(
return parse_multi_swipe(
input,
std::get<MultiSwipeParam>(out_param),
same_type ? std::get<MultiSwipeParam>(parent_param) : default_multi, default_single);
same_type ? std::get<MultiSwipeParam>(parent_param) : default_multi,
default_single);
} break;

case Type::Key: {
Expand All @@ -1203,14 +1206,23 @@ bool PipelineResMgr::parse_action(
return parse_app_info(input, std::get<AppParam>(out_param), same_type ? std::get<AppParam>(parent_param) : default_param);
} break;

case Type::Command: {
auto default_param = default_mgr.get_action_param<CommandParam>(Type::Command);
out_param = default_param;
return parse_command_param(
input,
std::get<CommandParam>(out_param),
same_type ? std::get<CommandParam>(parent_param) : default_param);
} break;

case Type::Custom: {
auto default_param = default_mgr.get_action_param<CustomParam>(Type::Custom);
out_param = default_param;
return parse_custom_action_param(
input,
std::get<CustomParam>(out_param),
same_type ? std::get<CustomParam>(parent_param) : default_param);
}
} break;

case Type::StopTask:
out_param = {};
Expand Down Expand Up @@ -1326,6 +1338,26 @@ bool PipelineResMgr::parse_app_info(const json::value& input, Action::AppParam&
return true;
}

bool PipelineResMgr::parse_command_param(const json::value& input, Action::CommandParam& output, const Action::CommandParam& default_value)
{
if (!get_and_check_value(input, "exec", output.exec, default_value.exec)) {
LogError << "failed to get_and_check_value exec" << VAR(input);
return false;
}

if (!get_and_check_value_or_array(input, "args", output.args, default_value.args)) {
LogError << "failed to get_and_check_value args" << VAR(input);
return false;
}

if (!get_and_check_value(input, "detach", output.detach, default_value.detach)) {
LogError << "failed to get_and_check_value detach" << VAR(input);
return false;
}

return true;
}

bool PipelineResMgr::parse_custom_action_param(
const json::value& input,
Action::CustomParam& output,
Expand Down
1 change: 1 addition & 0 deletions source/MaaFramework/Resource/PipelineResMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class PipelineResMgr : public NonCopyable
static bool parse_press_key(const json::value& input, Action::KeyParam& output, const Action::KeyParam& default_value);
static bool parse_input_text(const json::value& input, Action::TextParam& output, const Action::TextParam& default_value);
static bool parse_app_info(const json::value& input, Action::AppParam& output, const Action::AppParam& default_value);
static bool parse_command_param(const json::value& input, Action::CommandParam& output, const Action::CommandParam& default_value);
static bool parse_custom_action_param(const json::value& input, Action::CustomParam& output, const Action::CustomParam& default_value);

static bool parse_wait_freezes_param(
Expand Down
10 changes: 9 additions & 1 deletion source/MaaFramework/Resource/PipelineTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ enum class Type
Text,
StartApp,
StopApp,
Command,
Custom,
StopTask,
};
Expand Down Expand Up @@ -95,14 +96,21 @@ struct AppParam
std::string package;
};

struct CommandParam
{
std::string exec;
std::vector<std::string> args;
bool detach = false;
};

struct CustomParam
{
std::string name;
json::value custom_param;
Target target;
};

using Param = std::variant<std::monostate, ClickParam, SwipeParam, MultiSwipeParam, KeyParam, TextParam, AppParam, CustomParam>;
using Param = std::variant<std::monostate, ClickParam, SwipeParam, MultiSwipeParam, KeyParam, TextParam, AppParam, CommandParam, CustomParam>;
} // namespace Action

struct WaitFreezesParam
Expand Down
2 changes: 2 additions & 0 deletions source/MaaFramework/Resource/ResourceMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class ResourceMgr : public MaaResource

const auto& default_pipeline() const { return default_pipeline_; }

const std::vector<std::filesystem::path>& paths() const { return paths_; }

CustomRecognitionSession custom_recognition(const std::string& name) const;
CustomActionSession custom_action(const std::string& name) const;

Expand Down
32 changes: 31 additions & 1 deletion source/MaaFramework/Task/Component/Actuator.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Actuator.h"

#include "CommandAction.h"
#include "Controller/ControllerAgent.h"
#include "CustomAction.h"
#include "Utils/Logger.h"
Expand All @@ -13,7 +14,7 @@ Actuator::Actuator(Tasker* tasker, Context& context)
{
}

bool Actuator::run(const cv::Rect& reco_hit, MaaRecoId reco_id, const PipelineData& pipeline_data)
bool Actuator::run(const cv::Rect& reco_hit, MaaRecoId reco_id, const PipelineData& pipeline_data, const std::string& entry)
{
using namespace MAA_RES_NS::Action;
LogFunc << VAR(pipeline_data.name);
Expand Down Expand Up @@ -52,6 +53,9 @@ bool Actuator::run(const cv::Rect& reco_hit, MaaRecoId reco_id, const PipelineDa
case Type::StopApp:
ret = stop_app(std::get<AppParam>(pipeline_data.action_param));
break;
case Type::Command:
ret = command(std::get<CommandParam>(pipeline_data.action_param), reco_hit, pipeline_data.name, entry);
break;
case Type::Custom:
ret = custom_action(std::get<CustomParam>(pipeline_data.action_param), reco_hit, reco_id, pipeline_data.name);
break;
Expand Down Expand Up @@ -217,6 +221,32 @@ bool Actuator::stop_app(const MAA_RES_NS::Action::AppParam& param)
return controller()->stop_app(param.package);
}

bool Actuator::command(
const MAA_RES_NS::Action::CommandParam& param,
const cv::Rect& box,
const std::string& name,
const std::string& entry)
{
if (!controller()) {
LogError << "Controller is null";
return false;
}
auto* resource = tasker_ ? tasker_->resource() : nullptr;
if (!resource) {
LogError << "Resource is null";
return false;
}

CommandAction::Runtime rt {
.resource_paths = resource->paths(),
.entry = entry,
.node = name,
.image = controller()->cached_image(),
.box = box,
};
return CommandAction().run(param, rt);
}

bool Actuator::custom_action(const MAA_RES_NS::Action::CustomParam& param, const cv::Rect& box, MaaRecoId reco_id, const std::string& name)
{
if (!tasker_) {
Expand Down
6 changes: 2 additions & 4 deletions source/MaaFramework/Task/Component/Actuator.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#pragma once

#include <stack>
#include <string_view>

#include <meojson/json.hpp>

#include "API/MaaTypes.h"
Expand All @@ -23,7 +20,7 @@ class Actuator
public:
Actuator(Tasker* tasker, Context& context);

bool run(const cv::Rect& reco_hit, MaaRecoId reco_id, const PipelineData& pipeline_data);
bool run(const cv::Rect& reco_hit, MaaRecoId reco_id, const PipelineData& pipeline_data, const std::string& entry);

private:
bool click(const MAA_RES_NS::Action::ClickParam& param, const cv::Rect& box);
Expand All @@ -34,6 +31,7 @@ class Actuator

bool start_app(const MAA_RES_NS::Action::AppParam& param);
bool stop_app(const MAA_RES_NS::Action::AppParam& param);
bool command(const MAA_RES_NS::Action::CommandParam& param, const cv::Rect& box, const std::string& name, const std::string& entry);
bool custom_action(const MAA_RES_NS::Action::CustomParam& param, const cv::Rect& box, MaaRecoId reco_id, const std::string& name);

void wait_freezes(const MAA_RES_NS::WaitFreezesParam& param, const cv::Rect& box);
Expand Down
Loading

0 comments on commit ab75da5

Please sign in to comment.