diff --git a/resource/config.json b/resource/config.json index 851bc24759..852d4fa5c9 100644 --- a/resource/config.json +++ b/resource/config.json @@ -12,6 +12,8 @@ "adbExtraSwipeDist_Doc": "额外的滑动距离:adb有bug,同样的参数,偶尔会划得非常远。额外做一个短程滑动,把之前的停下来", "adbExtraSwipeDuration": 500, "adbExtraSwipeDuration_Doc": "额外的滑动持续时间:adb有bug,同样的参数,偶尔会划得非常远。额外做一个短程滑动,把之前的停下来。若小于0,则关闭额外滑动功能", + "minitouchExtraSwipeDist": 100, + "minitouchExtraSwipeDuration": 200, "penguinReport": { "Doc": "企鹅物流汇报: https://penguin-stats.cn/", "cmdFormat": "curl -H \"Content-Type: application/json\" -s -S -m 10 -i -d \"[body]\" \"https://penguin-stats.io/PenguinStats/api/v2/report\" --ssl-no-revoke [extra]", diff --git a/resource/tasks.json b/resource/tasks.json index e5ef717601..8a6c5ebc83 100644 --- a/resource/tasks.json +++ b/resource/tasks.json @@ -17,7 +17,7 @@ ], "rectMove_Doc": "滑动终点", "specialParams": [ - 1000, + 200, 1 ], "specialParams_Doc": [ @@ -45,7 +45,7 @@ 100 ], "specialParams": [ - 1000, + 200, 1 ], "next": [ @@ -4403,9 +4403,6 @@ 310, 100, 100 - ], - "specialParams": [ - 300 ] }, "SleepAfterOperListSwipe": { @@ -9239,4 +9236,4 @@ "RoguelikeWaitBattleStart" ] } -} +} \ No newline at end of file diff --git a/src/MeoAssistant/Controller.cpp b/src/MeoAssistant/Controller.cpp index 4d57571888..dfc89176d5 100644 --- a/src/MeoAssistant/Controller.cpp +++ b/src/MeoAssistant/Controller.cpp @@ -35,6 +35,61 @@ #include "Utils/Logger.hpp" #include "Utils/StringMisc.hpp" +struct MinitouchCmd +{ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4996) +#endif + inline static std::string reset() { return "r\n"; } + inline static std::string commit() { return "c\n"; } + inline static std::string down(int x, int y, bool with_commit = true, int wait_ms = 0, int contact = 0, + int pressure = 1) + { + // mac 编不过 + // std::string str = std::format("d {} {} {} {}\n", contact, x, y, pressure); + + char buff[64] = { 0 }; + sprintf(buff, "d %d %d %d %d\n", contact, x, y, pressure); + std::string str = buff; + + if (with_commit) str += commit(); + if (wait_ms) str += wait(wait_ms); + return str; + } + inline static std::string move(int x, int y, bool with_commit = true, int wait_ms = 0, int contact = 0, + int pressure = 1) + { + char buff[64] = { 0 }; + sprintf(buff, "m %d %d %d %d\n", contact, x, y, pressure); + std::string str = buff; + + if (with_commit) str += commit(); + if (wait_ms) str += wait(wait_ms); + return str; + } + inline static std::string up(bool with_commit = true, int contact = 0) + { + char buff[16] = { 0 }; + sprintf(buff, "u %d\n", contact); + std::string str = buff; + + if (with_commit) str += commit(); + return str; + } + inline static std::string wait(int ms) + { + char buff[16] = { 0 }; + sprintf(buff, "w %d\n", ms); + std::string str = buff; + + return str; + } +#ifdef _MSC_VER +#pragma warning(pop) +#endif +}; + asst::Controller::Controller(AsstCallback callback, void* callback_arg) : m_callback(std::move(callback)), m_callback_arg(callback_arg), m_rand_engine(std::random_device {}()) { @@ -449,13 +504,10 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) { LogTraceFunction; Log.info(cmd); - - constexpr int PipeBuffSize = 4096ULL; - m_minitouch_avaiable = false; #ifdef _WIN32 - + constexpr int PipeBuffSize = 4096ULL; SECURITY_ATTRIBUTES sa_attr_rd { .nLength = sizeof(SECURITY_ATTRIBUTES), .lpSecurityDescriptor = nullptr, @@ -468,7 +520,7 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) }; if (!asst::win32::CreateOverlappablePipe(&m_minitouch_parent_wr, &m_minitouch_child_wr, &sa_attr_rd, &sa_attr_wr, - PipeBuffSize, false, false)) { + PipeBuffSize, true, false)) { DWORD err = GetLastError(); Log.error("Failed to create pipe for minitouch, err", err); return false; @@ -487,38 +539,35 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) &m_minitouch_process_info)) { DWORD err = GetLastError(); Log.error("Failed to create process for minitouch, err", err); - CloseHandle(m_minitouch_parent_wr); - CloseHandle(m_minitouch_child_wr); - m_minitouch_parent_wr = INVALID_HANDLE_VALUE; - m_minitouch_child_wr = INVALID_HANDLE_VALUE; + release_minitouch(true); return false; } std::string pipe_str; auto pipe_buffer = std::make_unique(PipeBuffSize); - bool read_end = false; auto start_time = std::chrono::steady_clock::now(); auto check_timeout = [&]() -> bool { using namespace std::chrono_literals; - return std::chrono::steady_clock::now() - start_time < 10s; + return std::chrono::steady_clock::now() - start_time < 3s; }; - while (!need_exit() && !read_end && check_timeout()) { - DWORD peek_num = 0; - DWORD read_num = 0; - while (PeekNamedPipe(m_minitouch_parent_wr, nullptr, 0, nullptr, &peek_num, nullptr) && peek_num > 0) { - if (!ReadFile(m_minitouch_parent_wr, pipe_buffer.get(), PipeBuffSize, &read_num, nullptr)) { - continue; - } - pipe_str.insert(pipe_str.end(), pipe_buffer.get(), pipe_buffer.get() + read_num); - if (pipe_str.empty()) { - continue; - } + std::vector wait_handles; + + OVERLAPPED pipeov { .hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr) }; + std::ignore = ReadFile(m_minitouch_parent_wr, pipe_buffer.get(), PipeBuffSize, nullptr, &pipeov); + + while (!need_exit() && check_timeout()) { + if (pipe_str.find('$') != std::string::npos || pipe_str.find('^') != std::string::npos) { + break; + } + DWORD len = 0; + if (!GetOverlappedResult(m_minitouch_parent_wr, &pipeov, &len, FALSE)) { + continue; + } + pipe_str.insert(pipe_str.end(), pipe_buffer.get(), pipe_buffer.get() + len); + std::ignore = ReadFile(m_minitouch_parent_wr, pipe_buffer.get(), PipeBuffSize, nullptr, &pipeov); + if (!pipe_str.empty()) { Log.info("pipe str", Logger::separator::newline, pipe_str); - if (pipe_str.find('^') != std::string::npos) { - read_end = true; - break; - } } } @@ -527,6 +576,7 @@ bool asst::Controller::call_and_hup_minitouch(const std::string& cmd) size_t e_pos = pipe_str.find('\n', s_pos); if (s_pos == std::string::npos || e_pos == std::string::npos) { Log.error("Failed to find ^ in minitouch pipe"); + release_minitouch(true); return false; } std::string key_info = pipe_str.substr(s_pos + 1, e_pos - s_pos - 1); @@ -573,23 +623,33 @@ bool asst::Controller::input_to_minitouch(const std::string& cmd, int delay_ms) #endif } -void asst::Controller::release_minitouch() +void asst::Controller::release_minitouch(bool force) { LogTraceFunction; - if (!m_minitouch_avaiable) { + if (!m_minitouch_avaiable && !force) { return; } m_minitouch_avaiable = false; #ifdef _WIN32 - CloseHandle(m_minitouch_process_info.hProcess); - CloseHandle(m_minitouch_process_info.hThread); - CloseHandle(m_minitouch_parent_wr); - CloseHandle(m_minitouch_child_wr); - m_minitouch_parent_wr = INVALID_HANDLE_VALUE; - m_minitouch_child_wr = INVALID_HANDLE_VALUE; + if (m_minitouch_process_info.hProcess) { + CloseHandle(m_minitouch_process_info.hProcess); + m_minitouch_process_info.hProcess = nullptr; + } + if (m_minitouch_process_info.hThread) { + CloseHandle(m_minitouch_process_info.hThread); + m_minitouch_process_info.hThread = nullptr; + } + if (m_minitouch_parent_wr) { + CloseHandle(m_minitouch_parent_wr); + m_minitouch_parent_wr = nullptr; + } + if (m_minitouch_child_wr) { + CloseHandle(m_minitouch_child_wr); + m_minitouch_child_wr = nullptr; + } #endif // _WIN32 } @@ -987,8 +1047,9 @@ bool asst::Controller::click_without_scale(const Point& p) if (m_minitouch_avaiable) { int x = static_cast(p.x * m_minitouch_props.x_scaling); int y = static_cast(p.y * m_minitouch_props.y_scaling); - std::string minitouch_cmd = MinitouchCmd::down(x, y) + MinitouchCmd::up(); - return input_to_minitouch(minitouch_cmd, MinitouchCmd::DefaultInterval); + constexpr int WaitMs = 50; + std::string minitouch_cmd = MinitouchCmd::down(x, y, true, WaitMs) + MinitouchCmd::up(); + return input_to_minitouch(minitouch_cmd, WaitMs); } std::string cur_cmd = @@ -1029,54 +1090,68 @@ bool asst::Controller::swipe_without_scale(const Point& p1, const Point& p2, int y1 = std::clamp(y1, 0, m_height - 1); } + const auto& opt = Configer.get_options(); if (m_minitouch_avaiable) { - x1 = static_cast(x1 * m_minitouch_props.x_scaling); - y1 = static_cast(y1 * m_minitouch_props.y_scaling); - x2 = static_cast(x2 * m_minitouch_props.x_scaling); - y2 = static_cast(y2 * m_minitouch_props.y_scaling); - - std::string minitouch_cmd = MinitouchCmd::down(x1, y1); + constexpr int MoveInterval = 1; + std::string minitouch_cmd = + MinitouchCmd::down(static_cast(x1 * m_minitouch_props.x_scaling), + static_cast(m_minitouch_props.y_scaling * y1), true, MoveInterval); if (duration == 0) { - duration = 1000; + duration = 100; } - constexpr int MoveInterval = MinitouchCmd::DefaultInterval; - int move_times = std::max(duration / MoveInterval, 1); - int x_step = (x2 - x1) / move_times; - int y_step = (y2 - y1) / move_times; - // TODO: 加点随机因子,或者改成中间快两头慢 - for (int times = 1; times < move_times; ++times) { - minitouch_cmd += MinitouchCmd::move(x1 + x_step * times, y1 + y_step * times); + auto move_cmd = [&](int _x1, int _y1, int _x2, int _y2, int _duration) -> std::string { + _x1 = static_cast(_x1 * m_minitouch_props.x_scaling); + _y1 = static_cast(_y1 * m_minitouch_props.y_scaling); + _x2 = static_cast(_x2 * m_minitouch_props.x_scaling); + _y2 = static_cast(_y2 * m_minitouch_props.y_scaling); + + int move_times = _duration / MoveInterval; + int x_step = (_x2 - _x1) / move_times; + int y_step = (_y2 - _y1) / move_times; + // TODO: 加点随机因子,或者改成中间快两头慢 + std::string minitouch_cmd; + for (int times = 1; times < move_times; ++times) { + minitouch_cmd += MinitouchCmd::move(_x1 + x_step * times, _y1 + y_step * times, true, MoveInterval); + } + minitouch_cmd += MinitouchCmd::move(_x2, _y2); + return minitouch_cmd; + }; + minitouch_cmd += move_cmd(x1, y1, x2, y2, duration); + + if (extra_swipe && opt.minitouch_extra_swipe_duration > 0) { + minitouch_cmd += + move_cmd(x2, y2, x2, y2 - opt.minitouch_extra_swipe_dist, opt.minitouch_extra_swipe_duration); + duration += opt.minitouch_extra_swipe_duration; } - minitouch_cmd += MinitouchCmd::move(x2, y2); minitouch_cmd += MinitouchCmd::up(); - return input_to_minitouch(minitouch_cmd, duration + MoveInterval); + return input_to_minitouch(minitouch_cmd, duration); } + else { + std::string cur_cmd = + utils::string_replace_all(m_adb.swipe, { + { "[x1]", std::to_string(x1) }, + { "[y1]", std::to_string(y1) }, + { "[x2]", std::to_string(x2) }, + { "[y2]", std::to_string(y2) }, + { "[duration]", duration <= 0 ? "" : std::to_string(duration) }, + }); + bool ret = call_command(cur_cmd).has_value(); - std::string cur_cmd = - utils::string_replace_all(m_adb.swipe, { - { "[x1]", std::to_string(x1) }, - { "[y1]", std::to_string(y1) }, - { "[x2]", std::to_string(x2) }, - { "[y2]", std::to_string(y2) }, - { "[duration]", duration <= 0 ? "" : std::to_string(duration) }, - }); - bool ret = call_command(cur_cmd).has_value(); - - // 额外的滑动:adb有bug,同样的参数,偶尔会划得非常远。额外做一个短程滑动,把之前的停下来 - const auto& opt = Configer.get_options(); - if (!m_minitouch_avaiable && extra_swipe && opt.adb_extra_swipe_duration > 0) { - std::string extra_cmd = utils::string_replace_all( - m_adb.swipe, { - { "[x1]", std::to_string(x2) }, - { "[y1]", std::to_string(y2) }, - { "[x2]", std::to_string(x2) }, - { "[y2]", std::to_string(y2 - opt.adb_extra_swipe_dist /* * m_control_scale*/) }, - { "[duration]", std::to_string(opt.adb_extra_swipe_duration) }, - }); - ret &= call_command(extra_cmd).has_value(); + // 额外的滑动:adb有bug,同样的参数,偶尔会划得非常远。额外做一个短程滑动,把之前的停下来 + if (!m_minitouch_avaiable && extra_swipe && opt.adb_extra_swipe_duration > 0) { + std::string extra_cmd = utils::string_replace_all( + m_adb.swipe, { + { "[x1]", std::to_string(x2) }, + { "[y1]", std::to_string(y2) }, + { "[x2]", std::to_string(x2) }, + { "[y2]", std::to_string(y2 - opt.adb_extra_swipe_dist /* * m_control_scale*/) }, + { "[duration]", std::to_string(opt.adb_extra_swipe_duration) }, + }); + ret &= call_command(extra_cmd).has_value(); + } + return ret; } - return ret; } bool asst::Controller::swipe_without_scale(const Rect& r1, const Rect& r2, int duration, bool extra_swipe) @@ -1363,7 +1438,12 @@ bool asst::Controller::connect(const std::string& adb_path, const std::string& a call_command(minitouch_cmd_rep(adb_cfg.push_minitouch)); call_command(minitouch_cmd_rep(adb_cfg.chmod_minitouch)); - call_and_hup_minitouch(minitouch_cmd_rep(adb_cfg.call_minitouch)); + + std::string call_mt_cmd = minitouch_cmd_rep(adb_cfg.call_minitouch); + // 不知道为啥有时候读不到pipe,重试几次,再不行拉到 + for (int i = 0; i != 5; ++i) { + if (call_and_hup_minitouch(call_mt_cmd)) break; + } } // try to find the fastest way diff --git a/src/MeoAssistant/Controller.h b/src/MeoAssistant/Controller.h index 5ca092ef19..8f4dd676d0 100644 --- a/src/MeoAssistant/Controller.h +++ b/src/MeoAssistant/Controller.h @@ -91,7 +91,7 @@ namespace asst bool call_and_hup_minitouch(const std::string& cmd); bool input_to_minitouch(const std::string& cmd, int delay_ms = 0); - void release_minitouch(); + void release_minitouch(bool force = false); // 转换 data 中的 CRLF 为 LF:有些模拟器自带的 adb,exec-out 输出的 \n 会被替换成 \r\n, // 导致解码错误,所以这里转一下回来(点名批评 mumu 和雷电) @@ -162,8 +162,8 @@ namespace asst bool m_minitouch_avaiable = false; // 状态 #ifdef _WIN32 - HANDLE m_minitouch_parent_wr = INVALID_HANDLE_VALUE; - HANDLE m_minitouch_child_wr = INVALID_HANDLE_VALUE; + HANDLE m_minitouch_parent_wr = nullptr; + HANDLE m_minitouch_child_wr = nullptr; ASST_AUTO_DEDUCED_ZERO_INIT_START PROCESS_INFORMATION m_minitouch_process_info = { nullptr }; ASST_AUTO_DEDUCED_ZERO_INIT_END @@ -201,62 +201,6 @@ namespace asst double y_scaling = 0; } m_minitouch_props; - struct MinitouchCmd - { -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4996) -#endif - inline static constexpr int DefaultInterval = 10; - inline static std::string reset() { return "r\n"; } - inline static std::string commit() { return "c\n"; } - inline static std::string down(int x, int y, bool with_commit = true, bool with_wait = true, - int contact = 0, int pressure = 0) - { - // mac 编不过 - // std::string str = std::format("d {} {} {} {}\n", contact, x, y, pressure); - - char buff[64] = { 0 }; - sprintf(buff, "d %d %d %d %d\n", contact, x, y, pressure); - std::string str = buff; - - if (with_commit) str += commit(); - if (with_wait) str += wait(); - return str; - } - inline static std::string move(int x, int y, bool with_commit = true, bool with_wait = true, - int contact = 0, int pressure = 0) - { - char buff[64] = { 0 }; - sprintf(buff, "m %d %d %d %d\n", contact, x, y, pressure); - std::string str = buff; - - if (with_commit) str += commit(); - if (with_wait) str += wait(); - return str; - } - inline static std::string up(bool with_commit = true, int contact = 0) - { - char buff[16] = { 0 }; - sprintf(buff, "u %d\n", contact); - std::string str = buff; - - if (with_commit) str += commit(); - return str; - } - inline static std::string wait(int ms = DefaultInterval) - { - char buff[16] = { 0 }; - sprintf(buff, "w %d\n", ms); - std::string str = buff; - - return str; - } -#ifdef _MSC_VER -#pragma warning(pop) -#endif - }; - private: #ifdef _WIN32 // for Windows socket diff --git a/src/MeoAssistant/Resource/GeneralConfiger.cpp b/src/MeoAssistant/Resource/GeneralConfiger.cpp index 2367c41a54..1b8ed36f1a 100644 --- a/src/MeoAssistant/Resource/GeneralConfiger.cpp +++ b/src/MeoAssistant/Resource/GeneralConfiger.cpp @@ -15,6 +15,8 @@ bool asst::GeneralConfiger::parse(const json::value& json) // m_options.print_window = options_json.at("printWindow").as_boolean(); m_options.adb_extra_swipe_dist = options_json.get("adbExtraSwipeDist", 100); m_options.adb_extra_swipe_duration = options_json.get("adbExtraSwipeDuration", -1); + m_options.minitouch_extra_swipe_dist = options_json.get("minitouchExtraSwipeDist", 100); + m_options.minitouch_extra_swipe_duration = options_json.get("minitouchExtraSwipeDuration", -1); m_options.penguin_report.cmd_format = options_json.get("penguinReport", "cmdFormat", std::string()); m_options.yituliu_report.cmd_format = options_json.get("yituliuReport", "cmdFormat", std::string()); m_options.depot_export_template.ark_planner = diff --git a/src/MeoAssistant/Resource/GeneralConfiger.h b/src/MeoAssistant/Resource/GeneralConfiger.h index cd7bf390e7..387e46d870 100644 --- a/src/MeoAssistant/Resource/GeneralConfiger.h +++ b/src/MeoAssistant/Resource/GeneralConfiger.h @@ -39,7 +39,9 @@ namespace asst // adb有bug,同样的参数,偶尔会划得非常远。 // 额外做一个短程滑动,把之前的停下来。 // 若小于0,则关闭额外滑动功能。 - PenguinReportCfg penguin_report; // 企鹅物流汇报: + int minitouch_extra_swipe_dist = 0; + int minitouch_extra_swipe_duration = -1; + PenguinReportCfg penguin_report; // 企鹅物流汇报: // 每次到结算界面,汇报掉落数据至企鹅物流 https://penguin-stats.cn/ DepotExportTemplate depot_export_template; // 仓库识别结果导出模板 yituliuReportCfg yituliu_report; // 一图流大数据汇报:目前只有公招功能,https://yituliu.site/maarecruitdata diff --git a/src/MeoAssistant/Task/Sub/BattleProcessTask.cpp b/src/MeoAssistant/Task/Sub/BattleProcessTask.cpp index 0124a9ca15..e55db54315 100644 --- a/src/MeoAssistant/Task/Sub/BattleProcessTask.cpp +++ b/src/MeoAssistant/Task/Sub/BattleProcessTask.cpp @@ -540,7 +540,7 @@ bool asst::BattleProcessTask::oper_deploy(const BattleAction& action) Point end_point = placed_point + (direction * coeff); m_ctrler->swipe(placed_point, end_point, swipe_oper_task_ptr->post_delay); - sleep(Task.get("BattleUseOper")->post_delay); + sleep(use_oper_task_ptr->post_delay); } m_used_opers[iter->first] =