diff --git a/include/MaaAgentClient/MaaAgentClientAPI.h b/include/MaaAgentClient/MaaAgentClientAPI.h index 5fc837761..132a94ef6 100644 --- a/include/MaaAgentClient/MaaAgentClientAPI.h +++ b/include/MaaAgentClient/MaaAgentClientAPI.h @@ -11,11 +11,10 @@ extern "C" MAA_AGENT_CLIENT_API void MaaAgentClientDestroy(MaaAgentClient* client); + MAA_AGENT_CLIENT_API MaaBool MaaAgentClientBindResource(MaaAgentClient* client, MaaResource* res); MAA_AGENT_CLIENT_API MaaBool MaaAgentClientStartChild(MaaAgentClient* client, const char* child_exec, const MaaStringListBuffer* child_args); - MAA_AGENT_CLIENT_API MaaBool MaaAgentClientBindResource(MaaAgentClient* client, MaaResource* res); - #ifdef __cplusplus } #endif diff --git a/source/MaaAgentClient/API/MaaAgentClient.cpp b/source/MaaAgentClient/API/MaaAgentClient.cpp index 37ce7d6a9..f9f6203c4 100644 --- a/source/MaaAgentClient/API/MaaAgentClient.cpp +++ b/source/MaaAgentClient/API/MaaAgentClient.cpp @@ -24,6 +24,18 @@ void MaaAgentClientDestroy(MaaAgentClient* client) delete client; } +MaaBool MaaAgentClientBindResource(MaaAgentClient* client, MaaResource* res) +{ + LogFunc << VAR_VOIDP(client) << VAR_VOIDP(res); + + if (!client || !res) { + LogError << "handle is null"; + return false; + } + + return client->bind_resource(res); +} + MaaBool MaaAgentClientStartChild(MaaAgentClient* client, const char* child_exec, const MaaStringListBuffer* child_args) { LogFunc << VAR_VOIDP(client) << VAR(child_exec) << VAR(child_args); @@ -44,15 +56,3 @@ MaaBool MaaAgentClientStartChild(MaaAgentClient* client, const char* child_exec, return client->start_clild(MAA_NS::path(child_exec), args); } - -MaaBool MaaAgentClientBindResource(MaaAgentClient* client, MaaResource* res) -{ - LogFunc << VAR_VOIDP(client) << VAR_VOIDP(res); - - if (!client || !res) { - LogError << "handle is null"; - return false; - } - - return client->bind_resource(res); -} diff --git a/source/MaaAgentClient/API/MaaAgentClientTypes.h b/source/MaaAgentClient/API/MaaAgentClientTypes.h index a126130dd..5cf0be6f4 100644 --- a/source/MaaAgentClient/API/MaaAgentClientTypes.h +++ b/source/MaaAgentClient/API/MaaAgentClientTypes.h @@ -7,6 +7,6 @@ struct MaaAgentClient public: virtual ~MaaAgentClient() = default; - virtual bool start_clild(const std::filesystem::path& child_exec, const std::vector& child_args) = 0; virtual bool bind_resource(MaaResource* resource) = 0; + virtual bool start_clild(const std::filesystem::path& child_exec, const std::vector& child_args) = 0; }; diff --git a/source/MaaAgentClient/Client/AgentClient.cpp b/source/MaaAgentClient/Client/AgentClient.cpp index a5ade14de..ba557e6d1 100644 --- a/source/MaaAgentClient/Client/AgentClient.cpp +++ b/source/MaaAgentClient/Client/AgentClient.cpp @@ -1,18 +1,46 @@ #include "AgentClient.h" +#include + +#include + +#include "Common/MaaTypes.h" +#include "MaaAgent/Message.hpp" +#include "Utils/Codec.h" +#include "Utils/Logger.h" +#include "Utils/Platform.h" + MAA_AGENT_CLIENT_NS_BEGIN +#ifdef _WIN32 +std::vector conv_args(const std::vector& args) +{ + std::vector wargs; + for (const auto& arg : args) { + wargs.emplace_back(to_u16(arg)); + } + return wargs; +} +#else +std::vector conv_args(const std::vector& args) +{ + return args; +} +#endif + AgentClient::AgentClient(MaaNotificationCallback notify, void* notify_trans_arg) : notifier_(notify, notify_trans_arg) { LogFunc << VAR_VOIDP(notify) << VAR_VOIDP(notify_trans_arg); } -bool AgentClient::start_clild(const std::filesystem::path& child_exec, const std::vector& child_args) +AgentClient::~AgentClient() { - LogFunc << VAR(child_exec) << VAR(child_args); + LogFunc; - return false; + if (child_ && child_.joinable()) { + child_.join(); + } } bool AgentClient::bind_resource(MaaResource* resource) @@ -24,4 +52,155 @@ bool AgentClient::bind_resource(MaaResource* resource) return true; } +bool AgentClient::start_clild(const std::filesystem::path& child_exec, const std::vector& child_args) +{ + LogFunc << VAR(child_exec) << VAR(child_args); + + if (!resource_) { + LogError << "resource is not bound, please bind resource first"; + return false; + } + + if (child_) { + LogError << "child is already running"; + return false; + } + + std::filesystem::path exec = boost::process::search_path(child_exec); + if (!std::filesystem::exists(exec)) { + LogError << "exec not found" << VAR(child_exec); + return false; + } + + std::string addr = create_socket(); + + std::vector args = child_args; + args.emplace_back(addr); + + child_ = boost::process::child(exec, conv_args(args)); + if (!child_) { + LogError << "failed to start child" << VAR(exec) << VAR(child_args); + return false; + } + + return recv_and_handle_init_msg(); +} + +std::string AgentClient::create_socket() +{ + constexpr std::string_view kAddrFormat = "ipc://maafw-agent-{}"; + std::stringstream ss; + ss << resource_; + std::string addr = std::format(kAddrFormat, std::move(ss).str()); + LogInfo << VAR(addr); + + child_sock_ = zmq::socket_t(child_ctx_, zmq::socket_type::pair); + child_sock_.bind(addr); + + return addr; +} + +std::optional AgentClient::recv() +{ + LogFunc; + + zmq::message_t init_msg; + auto size_opt = child_sock_.recv(init_msg); + if (!size_opt || *size_opt == 0) { + LogError << "failed to recv init_msg"; + return std::nullopt; + } + + const std::string& init_str = init_msg.to_string(); + LogInfo << VAR(init_str); + + auto jopt = json::parse(init_str); + if (!jopt) { + LogError << "failed to parse init_msg"; + return std::nullopt; + } + + return *jopt; +} + +bool AgentClient::recv_and_handle_init_msg() +{ + LogFunc; + + if (!resource_) { + LogError << "resource is not bound"; + return false; + } + + auto msg_opt = recv(); + if (!msg_opt) { + LogError << "failed to recv init_msg"; + return false; + } + + const InitMsg& msg = *msg_opt; + LogInfo << VAR(msg); + + for (const auto& reco : msg.recognitions) { + LogTrace << VAR(reco); + resource_->register_custom_recognition(reco, reco_agent, this); + } + for (const auto& act : msg.actions) { + LogTrace << VAR(act); + resource_->register_custom_action(act, action_agent, this); + } + + return true; +} + +MaaBool AgentClient::reco_agent( + MaaContext* context, + MaaTaskId task_id, + const char* node_name, + const char* custom_recognition_name, + const char* custom_recognition_param, + const MaaImageBuffer* image, + const MaaRect* roi, + void* trans_arg, + MaaRect* out_box, + MaaStringBuffer* out_detail) +{ + if (!trans_arg) { + LogError << "trans_arg is null"; + return false; + } + + AgentClient* pthis = reinterpret_cast(trans_arg); + if (!pthis) { + LogError << "pthis is null"; + return false; + } + + return true; +} + +MaaBool AgentClient::action_agent( + MaaContext* context, + MaaTaskId task_id, + const char* node_name, + const char* custom_action_name, + const char* custom_action_param, + MaaRecoId reco_id, + const MaaRect* box, + void* trans_arg) +{ + if (!trans_arg) { + LogError << "trans_arg is null"; + return false; + } + + AgentClient* pthis = reinterpret_cast(trans_arg); + if (!pthis) { + LogError << "pthis is null"; + return false; + } + + return true; +} + MAA_AGENT_CLIENT_NS_END diff --git a/source/MaaAgentClient/Client/AgentClient.h b/source/MaaAgentClient/Client/AgentClient.h index 61291823b..7c50ef087 100644 --- a/source/MaaAgentClient/Client/AgentClient.h +++ b/source/MaaAgentClient/Client/AgentClient.h @@ -2,8 +2,12 @@ #include +#include +#include + #include "API/MaaAgentClientTypes.h" #include "Conf/Conf.h" +#include "Utils/IOStream/BoostIO.hpp" #include "Utils/MessageNotifier.hpp" MAA_AGENT_CLIENT_NS_BEGIN @@ -12,14 +16,59 @@ class AgentClient : public MaaAgentClient { public: AgentClient(MaaNotificationCallback notify, void* notify_trans_arg); - virtual ~AgentClient() override = default; + virtual ~AgentClient() override; - virtual bool start_clild(const std::filesystem::path& child_exec, const std::vector& child_args) override; virtual bool bind_resource(MaaResource* resource) override; + virtual bool start_clild(const std::filesystem::path& child_exec, const std::vector& child_args) override; + +public: + std::string create_socket(); + + std::optional recv(); + + template + std::optional recv() + { + auto jopt = recv(); + if (!jopt) { + return std::nullopt; + } + const json::value& j = *jopt; + return j.is() ? std::make_optional(j.as()) : std::nullopt; + } + + bool recv_and_handle_init_msg(); + +public: + static MaaBool reco_agent( + MaaContext* context, + MaaTaskId task_id, + const char* node_name, + const char* custom_recognition_name, + const char* custom_recognition_param, + const MaaImageBuffer* image, + const MaaRect* roi, + void* trans_arg, + /* out */ MaaRect* out_box, + /* out */ MaaStringBuffer* out_detail); + + static MaaBool action_agent( + MaaContext* context, + MaaTaskId task_id, + const char* node_name, + const char* custom_action_name, + const char* custom_action_param, + MaaRecoId reco_id, + const MaaRect* box, + void* trans_arg); private: MaaResource* resource_ = nullptr; MessageNotifier notifier_; + boost::process::child child_; + + zmq::context_t child_ctx_; + zmq::socket_t child_sock_; }; MAA_AGENT_CLIENT_NS_END diff --git a/source/MaaFramework/API/MaaContext.cpp b/source/MaaFramework/API/MaaContext.cpp index 49fb5bb98..420d1f7ca 100644 --- a/source/MaaFramework/API/MaaContext.cpp +++ b/source/MaaFramework/API/MaaContext.cpp @@ -1,6 +1,6 @@ #include "MaaFramework/Instance/MaaContext.h" -#include "API/MaaTypes.h" +#include "Common/MaaTypes.h" #include "Utils/Buffer/ImageBuffer.hpp" #include "Utils/Buffer/StringBuffer.hpp" #include "Utils/Logger.h" diff --git a/source/MaaFramework/Controller/ControllerAgent.h b/source/MaaFramework/Controller/ControllerAgent.h index 06f531119..6998e7ffd 100644 --- a/source/MaaFramework/Controller/ControllerAgent.h +++ b/source/MaaFramework/Controller/ControllerAgent.h @@ -8,7 +8,7 @@ #include -#include "API/MaaTypes.h" +#include "Common/MaaTypes.h" #include "Base/AsyncRunner.hpp" #include "Utils/MessageNotifier.hpp" #include "Utils/NoWarningCVMat.hpp" diff --git a/source/MaaFramework/Resource/ResourceMgr.h b/source/MaaFramework/Resource/ResourceMgr.h index c15f842cb..2b767c30e 100644 --- a/source/MaaFramework/Resource/ResourceMgr.h +++ b/source/MaaFramework/Resource/ResourceMgr.h @@ -2,7 +2,7 @@ #include -#include "API/MaaTypes.h" +#include "Common/MaaTypes.h" #include "Base/AsyncRunner.hpp" #include "DefaultPipelineMgr.h" #include "MaaFramework/Instance/MaaResource.h" diff --git a/source/MaaFramework/Task/Component/Actuator.h b/source/MaaFramework/Task/Component/Actuator.h index e10cb3a46..f843b4bb9 100644 --- a/source/MaaFramework/Task/Component/Actuator.h +++ b/source/MaaFramework/Task/Component/Actuator.h @@ -2,7 +2,7 @@ #include -#include "API/MaaTypes.h" +#include "Common/MaaTypes.h" #include "Conf/Conf.h" #include "Controller/ControllerAgent.h" #include "Resource/PipelineTypes.h" diff --git a/source/MaaFramework/Task/Component/CustomAction.h b/source/MaaFramework/Task/Component/CustomAction.h index bf3e93dac..c8c9eab13 100644 --- a/source/MaaFramework/Task/Component/CustomAction.h +++ b/source/MaaFramework/Task/Component/CustomAction.h @@ -2,7 +2,7 @@ #include "Conf/Conf.h" -#include "API/MaaTypes.h" +#include "Common/MaaTypes.h" #include "MaaFramework/MaaDef.h" #include "Resource/ResourceMgr.h" #include "Task/Context.h" diff --git a/source/MaaFramework/Task/Component/CustomRecognition.h b/source/MaaFramework/Task/Component/CustomRecognition.h index f3f8094d8..f27d4df89 100644 --- a/source/MaaFramework/Task/Component/CustomRecognition.h +++ b/source/MaaFramework/Task/Component/CustomRecognition.h @@ -2,7 +2,7 @@ #include -#include "API/MaaTypes.h" +#include "Common/MaaTypes.h" #include "MaaFramework/MaaDef.h" #include "Resource/ResourceMgr.h" #include "Task/Context.h" diff --git a/source/MaaFramework/Task/Component/Recognizer.cpp b/source/MaaFramework/Task/Component/Recognizer.cpp index 174cf767d..f1b5f0a49 100644 --- a/source/MaaFramework/Task/Component/Recognizer.cpp +++ b/source/MaaFramework/Task/Component/Recognizer.cpp @@ -115,7 +115,7 @@ RecoResult Recognizer::template_match(const MAA_VISION_NS::TemplateMatcherParam& using namespace MAA_VISION_NS; if (!resource()) { - LogError << "Resource not binded"; + LogError << "Resource not bound"; return {}; } @@ -151,7 +151,7 @@ RecoResult Recognizer::feature_match(const MAA_VISION_NS::FeatureMatcherParam& p using namespace MAA_VISION_NS; if (!resource()) { - LogError << "Resource not binded"; + LogError << "Resource not bound"; return {}; } @@ -187,7 +187,7 @@ RecoResult Recognizer::color_match(const MAA_VISION_NS::ColorMatcherParam& param using namespace MAA_VISION_NS; if (!resource()) { - LogError << "Resource not binded"; + LogError << "Resource not bound"; return {}; } @@ -213,7 +213,7 @@ RecoResult Recognizer::ocr(const MAA_VISION_NS::OCRerParam& param, const std::st using namespace MAA_VISION_NS; if (!resource()) { - LogError << "Resource not binded or status is null" << VAR(resource()); + LogError << "Resource not bound or status is null" << VAR(resource()); return {}; } @@ -243,7 +243,7 @@ RecoResult Recognizer::nn_classify(const MAA_VISION_NS::NeuralNetworkClassifierP using namespace MAA_VISION_NS; if (!resource()) { - LogError << "Resource not binded"; + LogError << "Resource not bound"; return {}; } @@ -273,7 +273,7 @@ RecoResult Recognizer::nn_detect(const MAA_VISION_NS::NeuralNetworkDetectorParam using namespace MAA_VISION_NS; if (!resource()) { - LogError << "Resource not binded"; + LogError << "Resource not bound"; return {}; } diff --git a/source/MaaFramework/Task/Component/Recognizer.h b/source/MaaFramework/Task/Component/Recognizer.h index 267bb7a19..4d15b367a 100644 --- a/source/MaaFramework/Task/Component/Recognizer.h +++ b/source/MaaFramework/Task/Component/Recognizer.h @@ -2,7 +2,7 @@ #include -#include "API/MaaTypes.h" +#include "Common/MaaTypes.h" #include "Conf/Conf.h" #include "Resource/PipelineTypes.h" #include "Task/Context.h" diff --git a/source/MaaFramework/Task/Context.cpp b/source/MaaFramework/Task/Context.cpp index 61eea7b83..6f4861ee0 100644 --- a/source/MaaFramework/Task/Context.cpp +++ b/source/MaaFramework/Task/Context.cpp @@ -117,7 +117,7 @@ bool Context::override_pipeline(const json::object& pipeline_override) } auto* resource = tasker_->resource(); if (!resource) { - LogError << "resource not binded"; + LogError << "resource not bound"; return false; } auto& default_mgr = resource->default_pipeline(); @@ -189,7 +189,7 @@ std::optional Context::get_pipeline_data(const std::strin } auto* resource = tasker_->resource(); if (!resource) { - LogError << "resource not binded"; + LogError << "resource not bound"; return std::nullopt; } @@ -216,7 +216,7 @@ bool Context::check_pipeline() const } auto* resource = tasker_->resource(); if (!resource) { - LogError << "resource not binded"; + LogError << "resource not bound"; return false; } diff --git a/source/MaaFramework/Task/Context.h b/source/MaaFramework/Task/Context.h index 4fe083a11..42a345d05 100644 --- a/source/MaaFramework/Task/Context.h +++ b/source/MaaFramework/Task/Context.h @@ -3,7 +3,7 @@ #include #include -#include "API/MaaTypes.h" +#include "Common/MaaTypes.h" #include "Conf/Conf.h" #include "Resource/PipelineTypes.h" #include "Tasker/Tasker.h" diff --git a/source/MaaFramework/Task/TaskBase.h b/source/MaaFramework/Task/TaskBase.h index 96aa80470..00e69a1ba 100644 --- a/source/MaaFramework/Task/TaskBase.h +++ b/source/MaaFramework/Task/TaskBase.h @@ -4,7 +4,7 @@ #include -#include "API/MaaTypes.h" +#include "Common/MaaTypes.h" #include "Conf/Conf.h" #include "Context.h" #include "Controller/ControllerAgent.h" diff --git a/source/MaaFramework/Tasker/RuntimeCache.h b/source/MaaFramework/Tasker/RuntimeCache.h index 54a4de8c2..cfdaca7da 100644 --- a/source/MaaFramework/Tasker/RuntimeCache.h +++ b/source/MaaFramework/Tasker/RuntimeCache.h @@ -6,7 +6,7 @@ #include -#include "Task/TaskResultTypes.h" +#include "Common/TaskResultTypes.h" #include "Utils/NoWarningCVMat.hpp" MAA_NS_BEGIN diff --git a/source/MaaFramework/Tasker/Tasker.h b/source/MaaFramework/Tasker/Tasker.h index bdfb96065..dd6dbc5c9 100644 --- a/source/MaaFramework/Tasker/Tasker.h +++ b/source/MaaFramework/Tasker/Tasker.h @@ -5,7 +5,7 @@ #include #include -#include "API/MaaTypes.h" +#include "Common/MaaTypes.h" #include "Base/AsyncRunner.hpp" #include "Controller/ControllerAgent.h" #include "Resource/ResourceMgr.h" diff --git a/source/MaaFramework/API/MaaTypes.h b/source/include/Common/MaaTypes.h similarity index 99% rename from source/MaaFramework/API/MaaTypes.h rename to source/include/Common/MaaTypes.h index efb2b5303..a97caccc0 100644 --- a/source/MaaFramework/API/MaaTypes.h +++ b/source/include/Common/MaaTypes.h @@ -7,8 +7,8 @@ #include +#include "Common/TaskResultTypes.h" #include "MaaFramework/MaaDef.h" -#include "Task/TaskResultTypes.h" #include "Utils/NoWarningCVMat.hpp" struct MaaResource diff --git a/source/MaaFramework/Task/TaskResultTypes.h b/source/include/Common/TaskResultTypes.h similarity index 100% rename from source/MaaFramework/Task/TaskResultTypes.h rename to source/include/Common/TaskResultTypes.h diff --git a/source/include/Conf/Conf.h b/source/include/Conf/Conf.h index b82b2b631..ad3e21708 100644 --- a/source/include/Conf/Conf.h +++ b/source/include/Conf/Conf.h @@ -125,7 +125,13 @@ { #define MAA_PROJECT_INTERFACE_NS_END } -#define MAA_AGENT_CLIENT_NS MAA_NS::AgentClientNS +#define MAA_AGENT_NS MAA_NS::AgentNS +#define MAA_AGENT_NS_BEGIN \ + namespace MAA_AGENT_NS \ + { +#define MAA_AGENT_NS_END } + +#define MAA_AGENT_CLIENT_NS MAA_AGENT_NS::ClientNS #define MAA_AGENT_CLIENT_NS_BEGIN \ namespace MAA_AGENT_CLIENT_NS \ diff --git a/source/include/MaaAgent/Message.hpp b/source/include/MaaAgent/Message.hpp new file mode 100644 index 000000000..a480d7659 --- /dev/null +++ b/source/include/MaaAgent/Message.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +#include "Conf/Conf.h" + +MAA_AGENT_NS_BEGIN + +struct InitMsg +{ + std::string version; + std::vector actions; + std::vector recognitions; + + MEO_JSONIZATION(version, actions, recognitions); +}; + +MAA_AGENT_NS_END