From a48ca93ea674067af07577836dfe24830d97ef55 Mon Sep 17 00:00:00 2001 From: nekosu Date: Fri, 30 Aug 2024 00:09:59 +0800 Subject: [PATCH] feat: basic impl cli --- .vscode/launch.json | 13 +- include/MaaPI/MaaPIAPI.h | 3 +- sample/.gitignore | 2 + source/CMakeLists.txt | 1 - source/MaaPI/API/MaaPi.cpp | 13 +- source/MaaPI/CLI/CMakeLists.txt | 6 +- source/MaaPI/CLI/interactor.cpp | 489 ++++++++++++++++++++++++++++++++ source/MaaPI/CLI/interactor.h | 67 +++++ source/MaaPI/CLI/main.cpp | 61 ++-- source/MaaPI/Impl/PIClient.cpp | 1 + source/MaaPI/Impl/PIConfig.cpp | 6 +- source/MaaPI/Impl/PIConfig.h | 2 +- source/MaaPI/Impl/PIData.cpp | 10 +- source/MaaPI/Impl/PIData.h | 2 + source/MaaPI/Impl/PIRuntime.cpp | 28 +- source/MaaPI/Impl/PIRuntime.h | 3 +- source/include/PI/Types.h | 3 +- 17 files changed, 658 insertions(+), 52 deletions(-) create mode 100644 source/MaaPI/CLI/interactor.cpp create mode 100644 source/MaaPI/CLI/interactor.h diff --git a/.vscode/launch.json b/.vscode/launch.json index 1ac14f86b..cf7ffb169 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -17,7 +17,7 @@ "MIMode": "lldb" }, { - "name": "Pi sample", + "name": "MaaPICli", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/build/bin/Debug/sample_pi", @@ -28,6 +28,17 @@ "externalConsole": false, "MIMode": "lldb" }, + { + "name": "MaaPICli - Win", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/build/bin/Debug/MaaPICli.exe", + "args": ["."], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/sample", + "environment": [], + "console": "externalTerminal" + }, { "type": "lldb", "request": "launch", diff --git a/include/MaaPI/MaaPIAPI.h b/include/MaaPI/MaaPIAPI.h index b18dd413f..f5069e1af 100644 --- a/include/MaaPI/MaaPIAPI.h +++ b/include/MaaPI/MaaPIAPI.h @@ -22,7 +22,8 @@ extern "C" MAA_PI_API MaaController* MaaPIRuntimeGetController(MaaPIRuntime* rt); MAA_PI_API MaaResource* MaaPIRuntimeGetResource(MaaPIRuntime* rt); MAA_PI_API MaaTasker* MaaPIRuntimeGetTasker(MaaPIRuntime* rt); - MAA_PI_API MaaBool MaaPIRuntimeSetup(MaaPIRuntime* rt, MaaPIData* data, MaaPIConfig* cfg, MaaNotificationCallback cb, void* cb_arg); + MAA_PI_API MaaBool MaaPIRuntimeBind(MaaPIRuntime* rt, MaaPIData* data, MaaPIConfig* cfg); + MAA_PI_API MaaBool MaaPIRuntimeSetup(MaaPIRuntime* rt, MaaNotificationCallback cb, void* cb_arg); MAA_PI_API MaaPIClient* MaaPIClientCreate(const char* locale, MaaPIClientHandler handler, void* handler_arg); MAA_PI_API void MaaPIClientDestroy(MaaPIClient* client); diff --git a/sample/.gitignore b/sample/.gitignore index d344ba6b0..02109de26 100644 --- a/sample/.gitignore +++ b/sample/.gitignore @@ -1 +1,3 @@ config.json +pi_config.json +maa_option.json diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index d998c9279..4cebc630d 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -15,7 +15,6 @@ endif() add_subdirectory(LibraryHolder) add_subdirectory(MaaFramework) add_subdirectory(MaaToolkit) -add_subdirectory(MaaProjectInterface) add_subdirectory(MaaPI) add_subdirectory(binding) diff --git a/source/MaaPI/API/MaaPi.cpp b/source/MaaPI/API/MaaPi.cpp index 2f930b4a0..90f6270d5 100644 --- a/source/MaaPI/API/MaaPi.cpp +++ b/source/MaaPI/API/MaaPi.cpp @@ -106,13 +106,22 @@ MaaTasker* MaaPIRuntimeGetTasker(MaaPIRuntime* rt) return rt->get_tasker(); } -MaaBool MaaPIRuntimeSetup(MaaPIRuntime* rt, MaaPIData* data, MaaPIConfig* cfg, MaaNotificationCallback cb, void* cb_arg) +MaaBool MaaPIRuntimeBind(MaaPIRuntime* rt, MaaPIData* data, MaaPIConfig* cfg) { if (!rt || !data || !cfg) { return false; } - return rt->setup(data, cfg, cb, cb_arg); + return rt->bind(data, cfg); +} + +MaaBool MaaPIRuntimeSetup(MaaPIRuntime* rt, MaaNotificationCallback cb, void* cb_arg) +{ + if (!rt) { + return false; + } + + return rt->setup(cb, cb_arg); } MaaPIClient* MaaPIClientCreate(const char* locale, MaaPIClientHandler handler, void* handler_arg) diff --git a/source/MaaPI/CLI/CMakeLists.txt b/source/MaaPI/CLI/CMakeLists.txt index a25360e1b..3c34db26a 100644 --- a/source/MaaPI/CLI/CMakeLists.txt +++ b/source/MaaPI/CLI/CMakeLists.txt @@ -1,2 +1,4 @@ -add_executable(MaaPICli main.cpp) -target_link_libraries(MaaPICli MaaPI HeaderOnlyLibraries) +add_executable(MaaPICli main.cpp interactor.cpp) +target_link_libraries(MaaPICli MaaPI MaaUtils HeaderOnlyLibraries) + +target_include_directories(MaaPICli PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${MAA_PRIVATE_INC} ${MAA_PUBLIC_INC}) diff --git a/source/MaaPI/CLI/interactor.cpp b/source/MaaPI/CLI/interactor.cpp new file mode 100644 index 000000000..5cb8483e2 --- /dev/null +++ b/source/MaaPI/CLI/interactor.cpp @@ -0,0 +1,489 @@ +#include "interactor.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "Buffer/BufferTypes.hpp" +#include "Buffer/StringBuffer.hpp" +#include "MaaFramework/Utility/MaaBuffer.h" +#include "MaaPI/MaaPIAPI.h" +#include "MaaToolkit/AdbDevice/MaaToolkitAdbDevice.h" +#include "MaaToolkit/DesktopWindow/MaaToolkitDesktopWindow.h" +#include "Utils/Codec.h" +#include "Utils/Logger.h" +#include "Utils/Platform.h" +#include "Utils/ScopeLeave.hpp" + +// return [1, size] +std::vector input_multi_impl(size_t size, std::string_view prompt) +{ + std::vector values; + + auto fail = [&]() { + std::cout << std::format("Invalid value, {} [1-{}]: ", prompt, size); + values.clear(); + }; + + while (true) { + std::cin.sync(); + std::string buffer; + std::getline(std::cin, buffer); + + if (buffer.empty()) { + fail(); + continue; + } + + if (!std::ranges::all_of(buffer, [](char c) { return std::isdigit(c) || std::isspace(c); })) { + fail(); + continue; + } + + std::istringstream iss(buffer); + size_t val = 0; + while (iss >> val) { + if (val == 0 || val > size) { + fail(); + break; + } + values.emplace_back(static_cast(val)); + } + break; + } + + return values; +} + +// return [1, size] +int input(size_t size, std::string_view prompt = "Please input") +{ + std::cout << std::format("{} [1-{}]: ", prompt, size); + + auto fail = [&]() { + std::cout << std::format("Invalid value, {} [1-{}]: ", prompt, size); + }; + + int val = 0; + while (true) { + auto values = input_multi_impl(size, prompt); + if (values.size() != 1) { + fail(); + continue; + } + val = values.front(); + break; + } + std::cout << "\n"; + + return val; +} + +std::vector input_multi(size_t size, std::string_view prompt = "Please input multiple") +{ + std::cout << std::format("{} [1-{}]: ", prompt, size); + auto values = input_multi_impl(size, prompt); + std::cout << "\n"; + return values; +} + +void clear_screen() +{ +#ifdef _WIN32 + std::ignore = system("cls"); +#else + std::ignore = system("clear"); +#endif +} + +std::optional read_file(const std::filesystem::path& filepath) +{ + std::ifstream ifs(filepath, std::ios::in); + if (!ifs.is_open()) { + return std::nullopt; + } + std::ostringstream oss; + oss << ifs.rdbuf(); + ifs.close(); + return oss.str(); +} + +Interactor::Interactor() +{ + data_ = MaaPIDataCreate(); + config_ = MaaPIConfigCreate(); + runtime_ = MaaPIRuntimeCreate(); + MaaPIRuntimeBind(runtime_, data_, config_); + client_ = MaaPIClientCreate("zh-Hans", &Interactor::on_maafw_client_handler, this); +} + +bool Interactor::load(const std::filesystem::path& project_dir) +{ + LogFunc << VAR(project_dir); + + project_dir_ = project_dir; + + auto data_json = read_file(project_dir / "pi.json"); + if (!data_json) { + LogError << "Failed to read pi.json"; + mpause(); + return false; + } + + if (!MaaPIDataLoad(data_, data_json->c_str(), MAA_NS::path_to_utf8_string(project_dir).c_str())) { + LogError << "Failed to load pi.json"; + mpause(); + return false; + } + + auto gen_def = true; + auto config_json = read_file(project_dir / "pi_config.json"); + if (config_json) { + if (MaaPIConfigLoad(config_, data_, config_json->c_str())) { + gen_def = false; + } + else { + LogWarn << "Failed to load pi_config.json"; + } + } + if (gen_def) { + if (!MaaPIConfigGenDef(config_, data_)) { + LogError << "Failed to generate default pi_config.json"; + return false; + } + } + + save_config(); + + return true; +} + +void Interactor::interact() +{ + while (true) { + print_config(); + if (!interact_once()) { + break; + } + save_config(); + } +} + +bool Interactor::run() +{ + if (!MaaPIRuntimeSetup(runtime_, &Interactor::on_maafw_notify, this)) { + LogError << "Failed to generate runtime"; + return false; + } + + bool ret = MaaPIClientPerform(client_, runtime_, MaaPIClientAction_LaunchTask); + + if (!ret) { + std::cout << "### Failed to run tasks ###\n\n"; + } + else { + std::cout << "### All tasks have been completed ###\n\n"; + } + + return ret; +} + +void Interactor::print_config() const +{ + clear_screen(); + + welcome(); + std::cout << "### Current configuration ###\n\n"; + + // std::cout << "Controller:\n\n"; + // std::cout << "\t" << MAA_NS::utf8_to_crt(config_.configuration().controller.name) << "\n"; + + // switch (config_.configuration().controller.type_enum) { + // case InterfaceData::Controller::Type::Adb: + // std::cout << MAA_NS::utf8_to_crt(std::format( + // "\t\t{}\n\t\t{}\n", + // MaaNS::path_to_utf8_string(config_.configuration().adb.adb_path), + // config_.configuration().adb.address)); + // break; + // case InterfaceData::Controller::Type::Win32: + // if (config_.configuration().win32.hwnd) { + // std::cout << MAA_NS::utf8_to_crt(std::format("\t\t{}\n", format_win32_config(config_.configuration().win32))); + // } + // break; + // default: + // LogError << "Unknown controller type"; + // break; + // } + + // std::cout << "\n"; + + // std::cout << "Resource:\n\n"; + // std::cout << "\t" << MAA_NS::utf8_to_crt(config_.configuration().resource) << "\n\n"; + + // std::cout << "Tasks:\n\n"; + // print_config_tasks(false); +} + +void Interactor::welcome() const +{ + // if (config_.interface_data().message.empty()) { + // std::cout << "Welcome to use Maa Project Interface CLI!\n"; + // } + // else { + // std::cout << MAA_NS::utf8_to_crt(config_.interface_data().message) << "\n"; + // } + std::cout << "MaaFramework: " << MAA_VERSION << "\n\n"; + + // std::cout << "Version: " << MAA_NS::utf8_to_crt(config_.interface_data().version) << "\n\n"; +} + +bool Interactor::interact_once() +{ + std::cout << "### Select action ###\n\n"; + std::cout << "\t1. Switch controller\n"; + std::cout << "\t2. Switch resource\n"; + std::cout << "\t3. Add task\n"; + std::cout << "\t4. Move task\n"; + std::cout << "\t5. Delete task\n"; + std::cout << "\t6. Run tasks\n"; + std::cout << "\t7. Exit\n"; + std::cout << "\n"; + + int action = input(7); + + switch (action) { + case 1: + select_controller(); + break; + case 2: + select_resource(); + break; + case 3: + add_task(); + break; + case 4: + move_task(); + break; + case 5: + delete_task(); + break; + case 6: + run(); + mpause(); + break; + case 7: + return false; + } + + return true; +} + +void Interactor::select_controller() +{ + std::cout << "### Select controller ###\n\n"; + + client_handler_ = [&](const auto& info) -> int32_t { + for (size_t i = 0; i < info.choices.size(); i++) { + std::cout << MAA_NS::utf8_to_crt(std::format("{}: {}", i + 1, info.choices[i].choice)) << std::endl; + } + return input(info.choices.size()) - 1; + }; + + MaaPIClientPerform(client_, runtime_, MaaPIClientAction_SelectController); +} + +void Interactor::select_resource() +{ + std::cout << "### Select resource ###\n\n"; + + client_handler_ = [&](const auto& info) -> int32_t { + for (size_t i = 0; i < info.choices.size(); i++) { + std::cout << MAA_NS::utf8_to_crt(std::format("{}: {}", i + 1, info.choices[i].choice)) << std::endl; + } + return input(info.choices.size()) - 1; + }; + + MaaPIClientPerform(client_, runtime_, MaaPIClientAction_SelectResource); +} + +void Interactor::add_task() +{ + // using namespace MAA_PROJECT_INTERFACE_NS; + + // const auto& all_data_tasks = config_.interface_data().task; + // if (all_data_tasks.empty()) { + // LogError << "Task is empty"; + // return; + // } + + // std::cout << "### Add task ###\n\n"; + // for (size_t i = 0; i < all_data_tasks.size(); ++i) { + // std::cout << MAA_NS::utf8_to_crt(std::format("\t{}. {}\n", i + 1, all_data_tasks[i].name)); + // } + // std::cout << "\n"; + // auto input_indexes = input_multi(all_data_tasks.size()); + + // for (int index : input_indexes) { + // const auto& data_task = all_data_tasks[index - 1]; + + // std::vector config_options; + // for (const auto& option_name : data_task.option) { + // if (!config_.interface_data().option.contains(option_name)) { + // LogError << "Option not found" << VAR(option_name); + // return; + // } + + // const auto& opt = config_.interface_data().option.at(option_name); + + // if (!opt.default_case.empty()) { + // config_options.emplace_back(Configuration::Option { option_name, opt.default_case }); + // continue; + // } + // std::cout << MAA_NS::utf8_to_crt(std::format("\n\n## Input option of \"{}\" for \"{}\" ##\n\n", option_name, + // data_task.name)); for (size_t i = 0; i < opt.cases.size(); ++i) { + // std::cout << MAA_NS::utf8_to_crt(std::format("\t{}. {}\n", i + 1, opt.cases[i].name)); + // } + // std::cout << "\n"; + + // int case_index = input(opt.cases.size()) - 1; + // config_options.emplace_back(Configuration::Option { option_name, opt.cases[case_index].name }); + // } + + // config_.configuration().task.emplace_back(Configuration::Task { .name = data_task.name, .option = std::move(config_options) }); + // } +} + +void Interactor::edit_task() +{ + // TODO +} + +void Interactor::delete_task() +{ + // using namespace MAA_PROJECT_INTERFACE_NS; + + // auto& all_config_tasks = config_.configuration().task; + // if (all_config_tasks.empty()) { + // LogError << "Task is empty"; + // return; + // } + + // std::cout << "### Delete task ###\n\n"; + + // print_config_tasks(); + + // auto input_indexes = input_multi(all_config_tasks.size()); + + // std::unordered_set indexes(input_indexes.begin(), input_indexes.end()); + // std::vector sorted_indexes(indexes.begin(), indexes.end()); + // std::sort(sorted_indexes.begin(), sorted_indexes.end(), std::greater()); + + // for (int index : sorted_indexes) { + // all_config_tasks.erase(all_config_tasks.begin() + index - 1); + // } +} + +void Interactor::move_task() +{ + // using namespace MAA_PROJECT_INTERFACE_NS; + + // auto& all_config_tasks = config_.configuration().task; + // if (all_config_tasks.empty()) { + // LogError << "Task is empty"; + // return; + // } + + // std::cout << "### Move task ###\n\n"; + + // print_config_tasks(true); + + // int from_index = input(all_config_tasks.size(), "From") - 1; + // int to_index = input(all_config_tasks.size(), "To") - 1; + + // auto task = std::move(all_config_tasks[from_index]); + // all_config_tasks.erase(all_config_tasks.begin() + from_index); + // all_config_tasks.insert(all_config_tasks.begin() + to_index, std::move(task)); +} + +void Interactor::print_config_tasks(bool with_index) const +{ + std::ignore = with_index; + // auto& all_config_tasks = config_.configuration().task; + + // for (size_t i = 0; i < all_config_tasks.size(); ++i) { + // const auto& task = all_config_tasks[i]; + // if (with_index) { + // std::cout << MAA_NS::utf8_to_crt(std::format("\t{}. {}\n", i + 1, task.name)); + // } + // else { + // std::cout << MAA_NS::utf8_to_crt(std::format("\t- {}\n", task.name)); + // } + + // for (const auto& [key, value] : task.option) { + // std::cout << "\t\t- " << MAA_NS::utf8_to_crt(key) << ": " << MAA_NS::utf8_to_crt(value) << "\n"; + // } + // } + // std::cout << "\n"; +} + +void Interactor::mpause() const +{ + std::cout << "\nPress Enter to continue..."; + std::cin.sync(); + std::cin.get(); +} + +bool Interactor::save_config() const +{ + MaaStringBuffer* str = MaaStringBufferCreate(); + OnScopeLeave([str]() { MaaStringBufferDestroy(str); }); + if (!MaaPIConfigSave(config_, str)) { + LogError << "Failed to serialize pi_config.json"; + return false; + } + std::ofstream ofs(project_dir_ / "pi_config.json"); + ofs << str->get(); + return true; +} + +void Interactor::on_maafw_notify(const char* msg, const char* details_json, void* callback_arg) +{ + Interactor* pthis = static_cast(callback_arg); + std::ignore = pthis; + + std::string entry = json::parse(details_json).value_or(json::value())["entry"].as_string(); + std::cout << MAA_NS::utf8_to_crt(std::format("on_maafw_notify: {} {}", msg, entry)) << std::endl; +} + +int32_t Interactor::on_maafw_client_handler( + MaaPIClient* client, + MaaPIClientAction action, + MaaStringListBuffer* choice, + MaaStringListBuffer* details, + void* arg) +{ + std::ignore = client; + std::ignore = action; + + auto self = reinterpret_cast(arg); + + if (!self->client_handler_) { + return -1; + } + + ClientHandleInfo info; + + auto count = choice->size(); + for (size_t i = 0; i < count; i++) { + info.choices.push_back({ + choice->at(i).get(), + json::parse(details->at(i).get())->as_object(), + }); + } + + return self->client_handler_(info); +} diff --git a/source/MaaPI/CLI/interactor.h b/source/MaaPI/CLI/interactor.h new file mode 100644 index 000000000..75d2afd7a --- /dev/null +++ b/source/MaaPI/CLI/interactor.h @@ -0,0 +1,67 @@ +#pragma once + +#include "MaaFramework/MaaDef.h" +#include "MaaPI/MaaPIAPI.h" + +#include +#include +#include + +class Interactor +{ +public: + Interactor(); + + bool load(const std::filesystem::path& project_dir); + void print_config() const; + void interact(); + bool run(); + +private: + void welcome() const; + bool interact_once(); + + void select_controller(); + void select_resource(); + void add_task(); + void edit_task(); + void delete_task(); + void move_task(); + + void print_config_tasks(bool with_index = true) const; + + void mpause() const; + bool save_config() const; + + static void on_maafw_notify(const char* msg, const char* details_json, void* callback_arg); + // static std::string format_win32_config(const MAA_PROJECT_INTERFACE_NS::Configuration::Win32Config& win32_config); + static int32_t on_maafw_client_handler( + MaaPIClient* client, + MaaPIClientAction action, + MaaStringListBuffer* choice, + MaaStringListBuffer* details, + void* arg); + +private: + std::filesystem::path project_dir_; + + MaaPIData* data_; + MaaPIConfig* config_; + MaaPIRuntime* runtime_; + MaaPIClient* client_; + + // MAA_PROJECT_INTERFACE_NS::Configurator config_; + + struct ClientHandleInfo + { + struct ChoiceInfo + { + std::string choice; + json::object detail; + }; + + std::vector choices; + }; + + std::function client_handler_; +}; diff --git a/source/MaaPI/CLI/main.cpp b/source/MaaPI/CLI/main.cpp index 4420bc9cf..c8fe36e95 100644 --- a/source/MaaPI/CLI/main.cpp +++ b/source/MaaPI/CLI/main.cpp @@ -1,36 +1,51 @@ -#include -#include #include #include #include #include #include -int main() +#include "MaaFramework/MaaAPI.h" +#include "MaaPI/MaaPIAPI.h" +#include "MaaToolkit/MaaToolkitAPI.h" +#include "Utils/Platform.h" +#include "Utils/Runtime.h" + +#include "interactor.h" + +int main(int argc, char* argv[]) { - std::ifstream interface_json("sample/pi.json"); - std::ostringstream interface_ss; - interface_ss << interface_json.rdbuf(); - - std::string interface = interface_ss.str(); - auto data = MaaPIDataCreate(); - if (!MaaPIDataLoad(data, interface.c_str(), "sample/resource")) { - std::cout << "Load interface failed" << std::endl; - return 1; + auto root = MAA_NS::library_dir(); + + if (argc > 1) { + root = argv[1]; + } + + std::string user_path = MAA_NS::path_to_utf8_string(root); + + MaaToolkitConfigInitOption(user_path.c_str(), "{}"); + + Interactor interactor; + + if (!interactor.load(root)) { + return -1; } - auto cfg = MaaPIConfigCreate(); - if (!MaaPIConfigGenDef(cfg, data)) { - std::cout << "Generate default config failed" << std::endl; - return 1; + bool direct = false; + for (int i = 1; i < argc; ++i) { + if (std::string_view(argv[i]) != "-d") { + continue; + } + direct = true; + break; } - auto sbuf = MaaStringBufferCreate(); - if (!MaaPIConfigSave(cfg, sbuf)) { - std::cout << "Save config failed" << std::endl; - return 1; + + if (direct) { + interactor.print_config(); + bool ret = interactor.run(); + + return ret ? 0 : -1; } - std::string config(MaaStringBufferGet(sbuf), MaaStringBufferSize(sbuf)); - std::ofstream config_json("sample/config.json"); - config_json << config << std::endl; + interactor.interact(); + return 0; } diff --git a/source/MaaPI/Impl/PIClient.cpp b/source/MaaPI/Impl/PIClient.cpp index bd130640c..996020ead 100644 --- a/source/MaaPI/Impl/PIClient.cpp +++ b/source/MaaPI/Impl/PIClient.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include "Buffer/StringBuffer.hpp" diff --git a/source/MaaPI/Impl/PIConfig.cpp b/source/MaaPI/Impl/PIConfig.cpp index 2a69dd055..c61b273a4 100644 --- a/source/MaaPI/Impl/PIConfig.cpp +++ b/source/MaaPI/Impl/PIConfig.cpp @@ -1,9 +1,10 @@ #include "Impl/PIConfig.h" -#include "Impl/PIData.h" -#include "PI/Types.h" #include +#include "Impl/PIData.h" +#include "PI/Types.h" + MAA_PI_NS_BEGIN bool PIConfig::load(MaaPIData* _data, std::string_view json) @@ -181,6 +182,7 @@ bool PIConfig::save(std::string& json) result.adb = *adb; } else if (auto desktop = std::get_if(&controller_info_)) { + std::ignore = desktop; result.desktop = { 0 }; } result.resource = resource_->name; diff --git a/source/MaaPI/Impl/PIConfig.h b/source/MaaPI/Impl/PIConfig.h index cf88dea52..eeb63b24f 100644 --- a/source/MaaPI/Impl/PIConfig.h +++ b/source/MaaPI/Impl/PIConfig.h @@ -32,7 +32,7 @@ class PIConfig : public MaaPIConfig }; PIData::TaskInfo* task_ = nullptr; - std::vector option_; + std::vector option_ = {}; }; virtual bool load(MaaPIData* data, std::string_view json) override; diff --git a/source/MaaPI/Impl/PIData.cpp b/source/MaaPI/Impl/PIData.cpp index 1c9698b2e..9a6144ea5 100644 --- a/source/MaaPI/Impl/PIData.cpp +++ b/source/MaaPI/Impl/PIData.cpp @@ -109,14 +109,16 @@ bool PIData::ControllerInfo::DesktopInfo::from(const DataJson::Controller::Deskt try { class_regex = std::regex(cfg.class_regex); } - catch (std::regex_error err) { + catch (const std::regex_error& err) { + std::ignore = err; return false; } try { window_regex = std::regex(cfg.window_regex); } - catch (std::regex_error err) { + catch (const std::regex_error& err) { + std::ignore = err; return false; } @@ -218,6 +220,8 @@ bool PIData::OptionInfo::from(const DataJson::Option& cfg) bool PIData::load(std::string_view json, std::string_view path) { + resource_root_ = path; + auto json_value = json::parse(json); if (!json_value) { return false; @@ -257,7 +261,7 @@ bool PIData::load(std::string_view json, std::string_view path) } for (const auto& res : data.resource) { ResourceInfo info; - if (!info.from(res, path)) { + if (!info.from(res, resource_root_)) { return false; } resource_[res.name] = std::move(info); diff --git a/source/MaaPI/Impl/PIData.h b/source/MaaPI/Impl/PIData.h index 3be8ac6c2..b02681e15 100644 --- a/source/MaaPI/Impl/PIData.h +++ b/source/MaaPI/Impl/PIData.h @@ -72,6 +72,8 @@ class PIData : public MaaPIData virtual bool load(std::string_view json, std::string_view path) override; private: + std::string resource_root_; + std::unordered_map controller_; std::vector controller_order_; std::unordered_map resource_; diff --git a/source/MaaPI/Impl/PIRuntime.cpp b/source/MaaPI/Impl/PIRuntime.cpp index 57331a435..21b481324 100644 --- a/source/MaaPI/Impl/PIRuntime.cpp +++ b/source/MaaPI/Impl/PIRuntime.cpp @@ -5,7 +5,19 @@ MAA_PI_NS_BEGIN -bool PIRuntime::setup(MaaPIData* _data, MaaPIConfig* _config, MaaNotificationCallback cb, void* cb_arg) +bool PIRuntime::bind(MaaPIData* _data, MaaPIConfig* _config) +{ + auto data = dynamic_cast(_data); + auto config = dynamic_cast(_config); + if (!(data && config)) { + return false; + } + data_ = data; + config_ = config; + return true; +} + +bool PIRuntime::setup(MaaNotificationCallback cb, void* cb_arg) { auto discard = [&]() { if (tasker_) { @@ -23,20 +35,8 @@ bool PIRuntime::setup(MaaPIData* _data, MaaPIConfig* _config, MaaNotificationCal controller_ = nullptr; resource_ = nullptr; tasker_ = nullptr; - - data_ = nullptr; - config_ = nullptr; }; - auto data = dynamic_cast(_data); - auto config = dynamic_cast(_config); - if (!(data && config)) { - discard(); - return false; - } - data_ = data; - config_ = config; - if (auto adb_cfg = std::get_if(&config_->controller_info_)) { if (auto adb = std::get_if(&config_->controller_->info)) { controller_ = MaaAdbControllerCreate( @@ -45,7 +45,7 @@ bool PIRuntime::setup(MaaPIData* _data, MaaPIConfig* _config, MaaNotificationCal adb->screencap, adb->input, (adb->config | adb_cfg->config).to_string().c_str(), - "", // TODO: where + path_to_utf8_string(path(data_->resource_root_) / "MaaAgentBinary").c_str(), cb, cb_arg); } diff --git a/source/MaaPI/Impl/PIRuntime.h b/source/MaaPI/Impl/PIRuntime.h index ae00cd06c..c46da4fe6 100644 --- a/source/MaaPI/Impl/PIRuntime.h +++ b/source/MaaPI/Impl/PIRuntime.h @@ -13,7 +13,8 @@ class PIRuntime : public MaaPIRuntime friend class PIClient; public: - virtual bool setup(MaaPIData* data, MaaPIConfig* config, MaaNotificationCallback cb, void* cb_arg) override; + virtual bool bind(MaaPIData* data, MaaPIConfig* config) override; + virtual bool setup(MaaNotificationCallback cb, void* cb_arg) override; virtual MaaController* get_controller() override; virtual MaaResource* get_resource() override; virtual MaaTasker* get_tasker() override; diff --git a/source/include/PI/Types.h b/source/include/PI/Types.h index 32425f0ae..9dfb9f3e3 100644 --- a/source/include/PI/Types.h +++ b/source/include/PI/Types.h @@ -165,7 +165,8 @@ struct MaaPIRuntime public: virtual ~MaaPIRuntime() = default; - virtual bool setup(MaaPIData* data, MaaPIConfig* config, MaaNotificationCallback cb, void* cb_arg) = 0; + virtual bool bind(MaaPIData* data, MaaPIConfig* config) = 0; + virtual bool setup(MaaNotificationCallback cb, void* cb_arg) = 0; virtual MaaController* get_controller() = 0; virtual MaaResource* get_resource() = 0; virtual MaaTasker* get_tasker() = 0;