From 312ac0a277cd61d3debc8546bedbe5422c584fe1 Mon Sep 17 00:00:00 2001 From: MistEO Date: Fri, 11 Oct 2024 20:41:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81mumu=E5=90=8E?= =?UTF-8?q?=E5=8F=B0=E4=BF=9D=E6=B4=BB=EF=BC=8C=E9=80=9A=E8=BF=87=E5=8C=85?= =?UTF-8?q?=E5=90=8D=E8=8E=B7=E5=8F=96display=5Fid=20(#10713)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 支持mumu后台保活,通过包名获取display_id * perf: 调整mumu extras需要的信息 * perf: 适配UI * fix: build error * feat: 每次截图前都获取display id * feat: 每次启动app重新获取display id * fix: 修复mumu保活多屏幕时分辨率错误 * chore: Auto update by pre-commit hooks [skip changelog] --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- resource/config.json | 4 +- src/MaaCore/Controller/AdbController.cpp | 237 +++++++++--------- src/MaaCore/Controller/AdbController.h | 28 +-- src/MaaCore/Controller/MumuExtras.cpp | 82 +++--- src/MaaCore/Controller/MumuExtras.h | 11 +- .../ViewModels/UI/SettingsViewModel.cs | 65 ++--- .../ConnectSettingsUserControl.xaml | 16 -- 7 files changed, 208 insertions(+), 235 deletions(-) diff --git a/resource/config.json b/resource/config.json index 924627ef67..a7a5059704 100644 --- a/resource/config.json +++ b/resource/config.json @@ -103,7 +103,9 @@ }, { "configName": "MuMuEmulator12", - "baseConfig": "General" + "baseConfig": "General", + "display": "[Adb] -s [AdbSerial] shell \"dumpsys window displays | grep -o -E cur=+[^\\ ]+ | tail -n 1 | grep -o -E [0-9]+\"", + "orientation": "[Adb] -s [AdbSerial] shell \"dumpsys input | grep SurfaceOrientation | tail -n 1 | grep -m 1 -o -E [0-9]\"" }, { "configName": "LDPlayer", diff --git a/src/MaaCore/Controller/AdbController.cpp b/src/MaaCore/Controller/AdbController.cpp index 2db136cd2a..23a3be0fee 100644 --- a/src/MaaCore/Controller/AdbController.cpp +++ b/src/MaaCore/Controller/AdbController.cpp @@ -23,9 +23,9 @@ #include -asst::AdbController::AdbController(const AsstCallback& callback, Assistant* inst, PlatformType type) - : InstHelper(inst) - , m_callback(callback) +asst::AdbController::AdbController(const AsstCallback& callback, Assistant* inst, PlatformType type) : + InstHelper(inst), + m_callback(callback) { LogTraceFunction; @@ -51,8 +51,7 @@ asst::AdbController::~AdbController() release(); } -std::optional - asst::AdbController::reconnect(const std::string& cmd, int64_t timeout, bool recv_by_socket) +std::optional asst::AdbController::reconnect(const std::string& cmd, int64_t timeout, bool recv_by_socket) { LogTraceFunction; @@ -78,8 +77,7 @@ std::optional if (need_exit()) { break; } - auto reconnect_ret = - call_command(m_adb.connect, 60LL * 1000, false /* 禁止重连避免无限递归 */); + auto reconnect_ret = call_command(m_adb.connect, 60LL * 1000, false /* 禁止重连避免无限递归 */); if (need_exit()) { break; } @@ -89,8 +87,7 @@ std::optional is_reconnect_success = reconnect_str.find("error") == std::string::npos; } if (is_reconnect_success) { - auto recall_ret = - call_command(cmd, timeout, false /* 禁止重连避免无限递归 */, recv_by_socket); + auto recall_ret = call_command(cmd, timeout, false /* 禁止重连避免无限递归 */, recv_by_socket); if (recall_ret) { // 重连并成功执行了 reconnect_info["what"] = "Reconnected"; @@ -135,8 +132,7 @@ std::optional asst::AdbController::call_command( std::optional exit_res; - exit_res = - m_platform_io->call_command(cmd, recv_by_socket, pipe_data, sock_data, timeout, start_time); + exit_res = m_platform_io->call_command(cmd, recv_by_socket, pipe_data, sock_data, timeout, start_time); if (!exit_res) { Log.warn("Call `", cmd, "` failed"); @@ -199,9 +195,32 @@ void asst::AdbController::callback(AsstMsg msg, const json::value& details) } } -void asst::AdbController::init_mumu_extras(const AdbCfg& adb_cfg [[maybe_unused]]) +int asst::AdbController::get_mumu_index(const std::string& address) +{ + LogTrace << VAR(address); + + auto pos = address.find(":"); + if (pos == std::string::npos) { + Log.error("address is invalid", address); + return 0; + } + + std::string port_str = address.substr(pos + 1); + if (port_str.empty() || !ranges::all_of(port_str, [](const char& c) -> bool { return std::isdigit(c); })) { + Log.error("port is invalid", port_str); + return 0; + } + int port = std::stoi(port_str); + int mumu_index = (port - 16384) / 32; // must be int + LogInfo << VAR(port_str) << VAR(port) << VAR(mumu_index); + return mumu_index; +} + +void asst::AdbController::init_mumu_extras(const AdbCfg& adb_cfg, const std::string& address) { #if !ASST_WITH_EMULATOR_EXTRAS + std::ignore = adb_cfg; + std::ignore = address; Log.error("MaaCore is not compiled with ASST_WITH_EMULATOR_EXTRAS"); #else if (adb_cfg.extras.empty()) { @@ -209,10 +228,21 @@ void asst::AdbController::init_mumu_extras(const AdbCfg& adb_cfg [[maybe_unused] return; } + set_mumu_package(adb_cfg.extras.get("client_type", "")); + std::filesystem::path mumu_path = utils::path(adb_cfg.extras.get("path", "")); - int mumu_index = adb_cfg.extras.get("index", 0); - int mumu_display = adb_cfg.extras.get("display", 0); - m_mumu_extras.init(mumu_path, mumu_index, mumu_display); + m_mumu_extras.init(mumu_path, get_mumu_index(address)); +#endif +} + +void asst::AdbController::set_mumu_package(const std::string& client_type) +{ +#if !ASST_WITH_EMULATOR_EXTRAS + std::ignore = client_type; + Log.error("MaaCore is not compiled with ASST_WITH_EMULATOR_EXTRAS"); +#else + std::string package_name = Config.get_package_name(client_type).value_or(""); + m_mumu_extras.set_package_name(package_name); #endif } @@ -267,9 +297,13 @@ bool asst::AdbController::start_game(const std::string& client_type) if (!package_name) { return false; } - std::string cur_cmd = - utils::string_replace_all(m_adb.start, "[PackageName]", package_name.value()); - return call_command(cur_cmd).has_value(); + + std::string cur_cmd = utils::string_replace_all(m_adb.start, "[PackageName]", package_name.value()); + bool ret = call_command(cur_cmd).has_value(); + + set_mumu_package(client_type); + + return ret; } bool asst::AdbController::stop_game(const std::string& client_type) @@ -281,9 +315,12 @@ bool asst::AdbController::stop_game(const std::string& client_type) if (!package_name) { return false; } - std::string cur_cmd = - utils::string_replace_all(m_adb.stop, "[PackageName]", package_name.value()); - return call_command(cur_cmd).has_value(); + std::string cur_cmd = utils::string_replace_all(m_adb.stop, "[PackageName]", package_name.value()); + bool ret = call_command(cur_cmd).has_value(); + + set_mumu_package(""); + + return ret; } bool asst::AdbController::click(const Point& p) @@ -292,9 +329,8 @@ bool asst::AdbController::click(const Point& p) Log.error("click point out of range"); } - std::string cur_cmd = utils::string_replace_all( - m_adb.click, - { { "[x]", std::to_string(p.x) }, { "[y]", std::to_string(p.y) } }); + std::string cur_cmd = + utils::string_replace_all(m_adb.click, { { "[x]", std::to_string(p.x) }, { "[y]", std::to_string(p.y) } }); return call_command(cur_cmd).has_value(); } @@ -320,9 +356,7 @@ bool asst::AdbController::swipe( const auto& opt = Config.get_options(); std::string duration_str = - duration <= 0 - ? "" - : std::to_string(static_cast(duration * opt.adb_swipe_duration_multiplier)); + duration <= 0 ? "" : std::to_string(static_cast(duration * opt.adb_swipe_duration_multiplier)); std::string cur_cmd = utils::string_replace_all( m_adb.swipe, { @@ -418,22 +452,16 @@ bool asst::AdbController::screencap(cv::Mat& image_payload, bool allow_reconnect return false; } // assuming little endian - uint32_t w = static_cast(static_cast(data[0])) << 0 - | static_cast(static_cast(data[1])) << 8 - | static_cast(static_cast(data[2])) << 16 - | static_cast(static_cast(data[3])) << 24; - uint32_t h = static_cast(static_cast(data[4])) << 0 - | static_cast(static_cast(data[5])) << 8 - | static_cast(static_cast(data[6])) << 16 - | static_cast(static_cast(data[7])) << 24; + uint32_t w = static_cast(static_cast(data[0])) << 0 | + static_cast(static_cast(data[1])) << 8 | + static_cast(static_cast(data[2])) << 16 | + static_cast(static_cast(data[3])) << 24; + uint32_t h = static_cast(static_cast(data[4])) << 0 | + static_cast(static_cast(data[5])) << 8 | + static_cast(static_cast(data[6])) << 16 | + static_cast(static_cast(data[7])) << 24; if (int(w) != m_width || int(h) != m_height) { - Log.error( - "Size from image header", - w, - h, - "does not match the size of screen", - m_width, - m_height); + Log.error("Size from image header", w, h, "does not match the size of screen", m_width, m_height); return false; } size_t std_size = 4ULL * m_width * m_height; @@ -476,8 +504,8 @@ bool asst::AdbController::screencap(cv::Mat& image_payload, bool allow_reconnect clear_lf_info(); auto start_time = steady_clock::now(); - if (m_support_socket && m_server_started - && screencap(m_adb.screencap_raw_by_nc, decode_raw, allow_reconnect, true, 5000)) { + if (m_support_socket && m_server_started && + screencap(m_adb.screencap_raw_by_nc, decode_raw, allow_reconnect, true, 5000)) { auto duration = duration_cast(steady_clock::now() - start_time); if (duration < min_cost) { m_adb.screencap_method = AdbProperty::ScreencapMethod::RawByNc; @@ -524,8 +552,7 @@ bool asst::AdbController::screencap(cv::Mat& image_payload, bool allow_reconnect if (m_mumu_extras.inited()) { start_time = steady_clock::now(); if (m_mumu_extras.screencap()) { - auto duration = - duration_cast(steady_clock::now() - start_time); + auto duration = duration_cast(steady_clock::now() - start_time); if (duration < min_cost) { m_adb.screencap_method = AdbProperty::ScreencapMethod::MumuExtras; m_inited = true; @@ -551,7 +578,6 @@ bool asst::AdbController::screencap(cv::Mat& image_payload, bool allow_reconnect else { Log.info("LDExtras is not supported"); } - } #endif @@ -565,12 +591,7 @@ bool asst::AdbController::screencap(cv::Mat& image_payload, bool allow_reconnect { AdbProperty::ScreencapMethod::LDExtras, "LDExtras" }, #endif }; - Log.info( - "The fastest way is", - MethodName.at(m_adb.screencap_method), - ", cost:", - min_cost.count(), - "ms"); + Log.info("The fastest way is", MethodName.at(m_adb.screencap_method), ", cost:", min_cost.count(), "ms"); if (m_adb.screencap_method != AdbProperty::ScreencapMethod::UnknownYet) { json::value info = json::object { { "uuid", m_uuid }, @@ -594,8 +615,7 @@ bool asst::AdbController::screencap(cv::Mat& image_payload, bool allow_reconnect screencap_ret = screencap(m_adb.screencap_raw_by_nc, decode_raw, allow_reconnect, true); break; case AdbProperty::ScreencapMethod::RawWithGzip: - screencap_ret = - screencap(m_adb.screencap_raw_with_gzip, decode_raw_with_gzip, allow_reconnect); + screencap_ret = screencap(m_adb.screencap_raw_with_gzip, decode_raw_with_gzip, allow_reconnect); break; case AdbProperty::ScreencapMethod::Encode: screencap_ret = screencap(m_adb.screencap_encode, decode_encode, allow_reconnect); @@ -659,8 +679,7 @@ bool asst::AdbController::screencap(cv::Mat& image_payload, bool allow_reconnect { "max", screencap_cost_max }, { "avg", filtered_count > 0 - ? std::accumulate(filtered_cost.begin(), filtered_cost.end(), 0ll) - / filtered_count + ? std::accumulate(filtered_cost.begin(), filtered_cost.end(), 0ll) / filtered_count : -1 }, } }, }; @@ -701,8 +720,7 @@ bool asst::AdbController::screencap( } if (decode_func(data)) [[likely]] { - if (m_adb.screencap_end_of_line == AdbProperty::ScreencapEndOfLine::UnknownYet) - [[unlikely]] { + if (m_adb.screencap_end_of_line == AdbProperty::ScreencapEndOfLine::UnknownYet) [[unlikely]] { Log.info("screencap_end_of_line is LF"); m_adb.screencap_end_of_line = AdbProperty::ScreencapEndOfLine::LF; } @@ -736,10 +754,7 @@ bool asst::AdbController::screencap( return true; } -bool asst::AdbController::connect( - const std::string& adb_path, - const std::string& address, - const std::string& config) +bool asst::AdbController::connect(const std::string& adb_path, const std::string& address, const std::string& config) { LogTraceFunction; @@ -766,11 +781,10 @@ bool asst::AdbController::connect( auto adb_ret = Config.get_adb_cfg(config); if (!adb_ret) { - json::value info = get_info_json() - | json::object { - { "what", "ConnectFailed" }, - { "why", "ConfigNotFound" }, - }; + json::value info = get_info_json() | json::object { + { "what", "ConnectFailed" }, + { "why", "ConfigNotFound" }, + }; callback(AsstMsg::ConnectionInfo, info); #ifdef ASST_DEBUG return false; @@ -812,7 +826,8 @@ bool asst::AdbController::connect( if (devices_ret) { const auto& devices_str = devices_ret.value(); const std::regex address_regex(m_adb.address_regex); - for (std::sregex_iterator iter(devices_str.begin(), devices_str.end(), address_regex), end; iter != end; ++iter) { + for (std::sregex_iterator iter(devices_str.begin(), devices_str.end(), address_regex), end; iter != end; + ++iter) { if (iter->size() > 1 && iter->str(1) == address) { need_connect = false; break; @@ -822,11 +837,10 @@ bool asst::AdbController::connect( // 如果不包含 `:` 且需要连接,connect 命令也不会成功 if (address.find(':') == std::string::npos && need_connect) { - json::value info = get_info_json() - | json::object { - { "what", "ConnectFailed" }, - { "why", "Address does not contain ':' and no devices found" }, - }; + json::value info = get_info_json() | json::object { + { "what", "ConnectFailed" }, + { "why", "Address does not contain ':' and no devices found" }, + }; callback(AsstMsg::ConnectionInfo, info); return false; } @@ -834,25 +848,23 @@ bool asst::AdbController::connect( // TODO: adb lite server 尚未实现,第一次连接需要执行一次 adb.exe 启动 daemon m_adb.connect = cmd_replace(adb_cfg.connect); m_adb.release = cmd_replace(adb_cfg.release); - auto connect_ret = - call_command(m_adb.connect, 60LL * 1000, false /* adb 连接时不允许重试 */); + auto connect_ret = call_command(m_adb.connect, 60LL * 1000, false /* adb 连接时不允许重试 */); bool is_connect_success = false; if (connect_ret) { auto& connect_str = connect_ret.value(); // 检查连接字符串是否包含 "connected" is_connect_success = connect_str.find("connected") != std::string::npos; // NOTE:这玩意啥都没干,有什么用吗? - if (connect_str.find("daemon started successfully") != std::string::npos - && connect_str.find("daemon still not running") == std::string::npos) { + if (connect_str.find("daemon started successfully") != std::string::npos && + connect_str.find("daemon still not running") == std::string::npos) { } } if (!is_connect_success && need_connect) { - json::value info = get_info_json() - | json::object { - { "what", "ConnectFailed" }, - { "why", "Connection command failed to exec" }, - }; + json::value info = get_info_json() | json::object { + { "what", "ConnectFailed" }, + { "why", "Connection command failed to exec" }, + }; callback(AsstMsg::ConnectionInfo, info); return false; } @@ -864,14 +876,12 @@ bool asst::AdbController::connect( /* get uuid (imei) */ { - auto uuid_ret = - call_command(cmd_replace(adb_cfg.uuid), 20000, false /* adb 连接时不允许重试 */); + auto uuid_ret = call_command(cmd_replace(adb_cfg.uuid), 20000, false /* adb 连接时不允许重试 */); if (!uuid_ret) { - json::value info = get_info_json() - | json::object { - { "what", "ConnectFailed" }, - { "why", "Uuid command failed to exec" }, - }; + json::value info = get_info_json() | json::object { + { "what", "ConnectFailed" }, + { "why", "Uuid command failed to exec" }, + }; callback(AsstMsg::ConnectionInfo, info); return false; } @@ -880,11 +890,10 @@ bool asst::AdbController::connect( std::erase_if(uuid_str, [](char c) { return !std::isdigit(c) && !std::isalpha(c); }); m_uuid = std::move(uuid_str); - json::value info = get_info_json() - | json::object { - { "what", "UuidGot" }, - { "why", "" }, - }; + json::value info = get_info_json() | json::object { + { "what", "UuidGot" }, + { "why", "" }, + }; info["details"]["uuid"] = m_uuid; callback(AsstMsg::ConnectionInfo, info); } @@ -892,11 +901,10 @@ bool asst::AdbController::connect( { auto version_ret = call_command(cmd_replace(adb_cfg.version)); if (!version_ret) { - json::value info = get_info_json() - | json::object { - { "what", "ConnectFailed" }, - { "why", "Android version command failed to exec" }, - }; + json::value info = get_info_json() | json::object { + { "what", "ConnectFailed" }, + { "why", "Android version command failed to exec" }, + }; callback(AsstMsg::ConnectionInfo, info); return false; } @@ -937,11 +945,10 @@ bool asst::AdbController::connect( { auto display_ret = call_command(cmd_replace(adb_cfg.display)); if (!display_ret) { - json::value info = get_info_json() - | json::object { - { "what", "ConnectFailed" }, - { "why", "Display command failed to exec" }, - }; + json::value info = get_info_json() | json::object { + { "what", "ConnectFailed" }, + { "why", "Display command failed to exec" }, + }; callback(AsstMsg::ConnectionInfo, info); return false; } @@ -953,11 +960,10 @@ bool asst::AdbController::connect( m_width = (std::max)(size_value1, size_value2); m_height = (std::min)(size_value1, size_value2); - json::value info = get_info_json() - | json::object { - { "what", "ResolutionGot" }, - { "why", "" }, - }; + json::value info = get_info_json() | json::object { + { "what", "ResolutionGot" }, + { "why", "" }, + }; info["details"] |= json::object { { "width", m_width }, @@ -980,11 +986,10 @@ bool asst::AdbController::connect( } { - json::value info = get_info_json() - | json::object { - { "what", "Connected" }, - { "why", "" }, - }; + json::value info = get_info_json() | json::object { + { "what", "Connected" }, + { "why", "" }, + }; callback(AsstMsg::ConnectionInfo, info); } @@ -1032,7 +1037,7 @@ bool asst::AdbController::connect( } if (config == "MuMuEmulator12") { - init_mumu_extras(adb_cfg); + init_mumu_extras(adb_cfg, address); } else if (config == "LDPlayer") { init_ld_extras(adb_cfg); diff --git a/src/MaaCore/Controller/AdbController.h b/src/MaaCore/Controller/AdbController.h index 6aae708e28..a0081bf147 100644 --- a/src/MaaCore/Controller/AdbController.h +++ b/src/MaaCore/Controller/AdbController.h @@ -12,14 +12,12 @@ #include "Common/AsstMsg.h" #include "Config/GeneralConfig.h" #include "InstHelper.h" -#include "MumuExtras.h" #include "LDExtras.h" +#include "MumuExtras.h" namespace asst { -class AdbController - : public ControllerAPI - , protected InstHelper +class AdbController : public ControllerAPI, protected InstHelper { public: AdbController(const AsstCallback& callback, Assistant* inst, PlatformType type); @@ -27,10 +25,7 @@ public: AdbController(AdbController&&) = delete; virtual ~AdbController(); - virtual bool connect( - const std::string& adb_path, - const std::string& address, - const std::string& config) override; + virtual bool connect(const std::string& adb_path, const std::string& address, const std::string& config) override; virtual void set_kill_adb_on_exit(bool enable) noexcept override; @@ -58,17 +53,11 @@ public: double slope_out = 1, bool with_pause = false) override; - virtual bool inject_input_event([[maybe_unused]] const InputEvent& event) override - { - return false; - } + virtual bool inject_input_event([[maybe_unused]] const InputEvent& event) override { return false; } virtual bool press_esc() override; - virtual ControlFeat::Feat support_features() const noexcept override - { - return ControlFeat::NONE; - } + virtual ControlFeat::Feat support_features() const noexcept override { return ControlFeat::NONE; } virtual std::pair get_screen_res() const noexcept override; @@ -84,8 +73,7 @@ protected: bool allow_reconnect = true, bool recv_by_socket = false); - virtual std::optional - reconnect(const std::string& cmd, int64_t timeout, bool recv_by_socket); + virtual std::optional reconnect(const std::string& cmd, int64_t timeout, bool recv_by_socket); void release(); @@ -103,7 +91,9 @@ protected: virtual void clear_info() noexcept; void callback(AsstMsg msg, const json::value& details); - void init_mumu_extras(const AdbCfg& adb_cfg); + static int get_mumu_index(const std::string& address); + void init_mumu_extras(const AdbCfg& adb_cfg, const std::string& address); + void set_mumu_package(const std::string& client_type); void init_ld_extras(const AdbCfg& adb_cfg); // 转换 data 中的 CRLF 为 LF:有些模拟器自带的 adb,exec-out 输出的 \n 会被替换成 \r\n, diff --git a/src/MaaCore/Controller/MumuExtras.cpp b/src/MaaCore/Controller/MumuExtras.cpp index e797ad12a5..815c19ce9c 100644 --- a/src/MaaCore/Controller/MumuExtras.cpp +++ b/src/MaaCore/Controller/MumuExtras.cpp @@ -12,13 +12,9 @@ MumuExtras::~MumuExtras() uninit(); } -bool MumuExtras::init( - const std::filesystem::path& mumu_path, - int mumu_inst_index, - int mumu_display_id) +bool MumuExtras::init(const std::filesystem::path& mumu_path, int mumu_inst_index) { - bool same = mumu_path == mumu_path_ && mumu_inst_index == mumu_inst_index_ - && mumu_display_id == mumu_display_id_; + bool same = mumu_path == mumu_path_ && mumu_inst_index == mumu_inst_index_; if (same && inited_) { return true; @@ -26,13 +22,24 @@ bool MumuExtras::init( mumu_path_ = mumu_path; mumu_inst_index_ = mumu_inst_index; - mumu_display_id_ = mumu_display_id; inited_ = load_mumu_library() && connect_mumu() && init_screencap(); return inited_; } +void MumuExtras::set_package_name(const std::string& package_name) +{ + display_id_cache_ = std::nullopt; + + if (package_name.empty()) { + package_name_ = kDefaultPackage; + } + else { + package_name_ = package_name; + } +} + bool MumuExtras::reload() { inited_ = load_mumu_library() && connect_mumu() && init_screencap(); @@ -53,18 +60,18 @@ std::optional MumuExtras::screencap() return std::nullopt; } + int display_id = get_display_id(); int ret = capture_display_func_( mumu_handle_, - mumu_display_id_, + display_id, static_cast(display_buffer_.size()), &display_width_, &display_height_, display_buffer_.data()); if (ret) { - LogError << "Failed to capture display" << VAR(ret) << VAR(mumu_handle_) - << VAR(mumu_display_id_) << VAR(display_buffer_.size()) << VAR(display_width_) - << VAR(display_height_); + LogError << "Failed to capture display" << VAR(ret) << VAR(mumu_handle_) << VAR(display_id) + << VAR(display_buffer_.size()) << VAR(display_width_) << VAR(display_height_); return std::nullopt; } @@ -98,6 +105,12 @@ bool MumuExtras::load_mumu_library() return false; } + get_display_id_func_ = get_function(kGetDisplayIdFuncName); + if (!get_display_id_func_) { + LogError << "Failed to get function" << VAR(kGetDisplayIdFuncName); + return false; + } + capture_display_func_ = get_function(kCaptureDisplayFuncName); if (!capture_display_func_) { LogError << "Failed to get function" << VAR(kCaptureDisplayFuncName); @@ -110,29 +123,25 @@ bool MumuExtras::load_mumu_library() return false; } - input_event_touch_down_func_ = - get_function(kInputEventTouchDownFuncName); + input_event_touch_down_func_ = get_function(kInputEventTouchDownFuncName); if (!input_event_touch_down_func_) { LogError << "Failed to get function" << VAR(kInputEventTouchDownFuncName); return false; } - input_event_touch_up_func_ = - get_function(kInputEventTouchUpFuncName); + input_event_touch_up_func_ = get_function(kInputEventTouchUpFuncName); if (!input_event_touch_up_func_) { LogError << "Failed to get function" << VAR(kInputEventTouchUpFuncName); return false; } - input_event_key_down_func_ = - get_function(kInputEventKeyDownFuncName); + input_event_key_down_func_ = get_function(kInputEventKeyDownFuncName); if (!input_event_key_down_func_) { LogError << "Failed to get function" << VAR(kInputEventKeyDownFuncName); return false; } - input_event_key_up_func_ = - get_function(kInputEventKeyUpFuncName); + input_event_key_up_func_ = get_function(kInputEventKeyUpFuncName); if (!input_event_key_up_func_) { LogError << "Failed to get function" << VAR(kInputEventKeyUpFuncName); return false; @@ -151,9 +160,7 @@ bool MumuExtras::connect_mumu() } std::u16string u16path = mumu_path_.u16string(); - std::wstring wpath( - std::make_move_iterator(u16path.begin()), - std::make_move_iterator(u16path.end())); + std::wstring wpath(std::make_move_iterator(u16path.begin()), std::make_move_iterator(u16path.end())); mumu_handle_ = connect_func_(wpath.c_str(), mumu_inst_index_); @@ -167,23 +174,19 @@ bool MumuExtras::connect_mumu() bool MumuExtras::init_screencap() { - if (!capture_display_func_) { - LogError << "capture_display_func_ is null"; + if (!capture_display_func_ || !get_display_id_func_) { + LogError << "capture_display_func_ or get_display_id_func_ is null"; return false; } - int ret = capture_display_func_( - mumu_handle_, - mumu_display_id_, - 0, - &display_width_, - &display_height_, - nullptr); + int display_id = get_display_id(); + LogInfo << "Get display id" << VAR(display_id); + + int ret = capture_display_func_(mumu_handle_, display_id, 0, &display_width_, &display_height_, nullptr); // mumu 的文档给错了,这里 0 才是成功 if (ret) { - LogError << "Failed to capture display" << VAR(ret) << VAR(mumu_handle_) - << VAR(mumu_display_id_); + LogError << "Failed to capture display" << VAR(ret) << VAR(mumu_handle_) << VAR(display_id); return false; } @@ -202,5 +205,18 @@ void MumuExtras::disconnect_mumu() } } +int MumuExtras::get_display_id() +{ + if (!display_id_cache_) { + if (!get_display_id_func_) { + LogError << "get_display_id_func_ is null"; + return 0; + } + display_id_cache_ = get_display_id_func_(mumu_handle_, package_name_.c_str(), 0); + } + + return *display_id_cache_; } +} // namespace asst + #endif diff --git a/src/MaaCore/Controller/MumuExtras.h b/src/MaaCore/Controller/MumuExtras.h index 2a9c32da7b..339c8fb503 100644 --- a/src/MaaCore/Controller/MumuExtras.h +++ b/src/MaaCore/Controller/MumuExtras.h @@ -24,7 +24,8 @@ public: bool inited() const { return inited_; } - bool init(const std::filesystem::path& mumu_path, int mumu_inst_index, int mumu_display_id); + bool init(const std::filesystem::path& mumu_path, int mumu_inst_index); + void set_package_name(const std::string& package_name); bool reload(); void uninit(); @@ -35,11 +36,15 @@ private: bool connect_mumu(); bool init_screencap(); void disconnect_mumu(); + int get_display_id(); private: std::filesystem::path mumu_path_; int mumu_inst_index_ = 0; - int mumu_display_id_ = 0; + // mumu 的约定,default 给的是最前端 tab + inline static std::string kDefaultPackage = "default"; + std::string package_name_ = kDefaultPackage; + std::optional display_id_cache_; int mumu_handle_ = 0; int display_width_ = 0; @@ -51,6 +56,7 @@ private: private: inline static const std::string kConnectFuncName = "nemu_connect"; inline static const std::string kDisconnectFuncName = "nemu_disconnect"; + inline static const std::string kGetDisplayIdFuncName = "nemu_get_display_id"; inline static const std::string kCaptureDisplayFuncName = "nemu_capture_display"; inline static const std::string kInputTextFuncName = "nemu_input_text"; inline static const std::string kInputEventTouchDownFuncName = "nemu_input_event_touch_down"; @@ -61,6 +67,7 @@ private: private: std::function connect_func_; std::function disconnect_func_; + std::function get_display_id_func_; std::function capture_display_func_; std::function input_text_func_; std::function input_event_touch_down_func_; diff --git a/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs b/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs index c076f37012..7faee01208 100644 --- a/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs +++ b/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs @@ -12,6 +12,7 @@ // #nullable enable + using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -1557,7 +1558,7 @@ namespace MaaWpfGui.ViewModels.UI /// public string ServerType => _serverMapping[ClientType]; - #endregion + #endregion 启动设置 #region 基建设置 @@ -1972,7 +1973,7 @@ namespace MaaWpfGui.ViewModels.UI #endregion 设置页面列表和滚动视图联动绑定 - #endregion + #endregion 基建设置 #region 肉鸽设置 @@ -2586,7 +2587,7 @@ namespace MaaWpfGui.ViewModels.UI } } - #endregion + #endregion 肉鸽设置 #region 生息演算设置 @@ -2692,7 +2693,7 @@ namespace MaaWpfGui.ViewModels.UI } } - #endregion + #endregion 生息演算设置 #region 信用相关设置 @@ -2944,7 +2945,7 @@ namespace MaaWpfGui.ViewModels.UI } } - #endregion + #endregion 信用相关设置 #region 领取奖励设置 @@ -3054,7 +3055,7 @@ namespace MaaWpfGui.ViewModels.UI } } - #endregion + #endregion 领取奖励设置 #region 定时设置 @@ -3211,7 +3212,7 @@ namespace MaaWpfGui.ViewModels.UI } } - #endregion + #endregion 定时设置 #region 刷理智设置 @@ -3401,7 +3402,7 @@ namespace MaaWpfGui.ViewModels.UI } } - #endregion + #endregion 刷理智设置 #region 自动公招设置 @@ -3618,7 +3619,7 @@ namespace MaaWpfGui.ViewModels.UI } } - #endregion + #endregion 自动公招设置 #region 软件更新设置 @@ -3968,7 +3969,7 @@ namespace MaaWpfGui.ViewModels.UI Instances.WindowManager.ShowWindow(Instances.VersionUpdateViewModel); } - #endregion + #endregion 软件更新设置 #region 连接设置 @@ -4249,38 +4250,6 @@ namespace MaaWpfGui.ViewModels.UI } } - private string _index = ConfigurationHelper.GetValue(ConfigurationKeys.MuMu12Index, "0"); - - /// - /// Gets or sets the index of the emulator. - /// - public string Index - { - get => _index; - set - { - Instances.AsstProxy.Connected = false; - SetAndNotify(ref _index, value); - ConfigurationHelper.SetValue(ConfigurationKeys.MuMu12Index, value); - } - } - - private string _display = ConfigurationHelper.GetValue(ConfigurationKeys.MuMu12Display, "0"); - - /// - /// Gets or sets the display of the emulator. - /// - public string Display - { - get => _display; - set - { - Instances.AsstProxy.Connected = false; - SetAndNotify(ref _display, value); - ConfigurationHelper.SetValue(ConfigurationKeys.MuMu12Display, _display); - } - } - public string Config { get @@ -4293,8 +4262,7 @@ namespace MaaWpfGui.ViewModels.UI var configObject = new JObject { ["path"] = EmulatorPath, - ["index"] = int.TryParse(Index, out var indexParse) ? indexParse : 0, - ["display"] = int.TryParse(Display, out var displayParse) ? displayParse : 0, + ["client_type"] = Instances.SettingsViewModel.ClientType, }; return JsonConvert.SerializeObject(configObject); } @@ -5020,7 +4988,7 @@ namespace MaaWpfGui.ViewModels.UI public bool AdbReplaced { get; set; } = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.AdbReplaced, bool.FalseString)); - #endregion + #endregion 连接设置 #region 界面设置 @@ -5428,6 +5396,7 @@ namespace MaaWpfGui.ViewModels.UI case "OperNameLanguageClient": ConfigurationHelper.SetValue(ConfigurationKeys.OperNameLanguage, value); break; + case "OperNameLanguageMAA": default: ConfigurationHelper.SetValue(ConfigurationKeys.OperNameLanguage, "OperNameLanguageMAA"); @@ -5482,7 +5451,7 @@ namespace MaaWpfGui.ViewModels.UI } } - #endregion + #endregion 界面设置 #region HotKey @@ -5516,7 +5485,7 @@ namespace MaaWpfGui.ViewModels.UI } } - #endregion + #endregion HotKey #region 配置 @@ -5589,7 +5558,7 @@ namespace MaaWpfGui.ViewModels.UI } } - #endregion + #endregion 配置 #region SettingsGuide diff --git a/src/MaaWpfGui/Views/UserControl/ConnectSettingsUserControl.xaml b/src/MaaWpfGui/Views/UserControl/ConnectSettingsUserControl.xaml index 5492c050e2..498ebc2ed3 100644 --- a/src/MaaWpfGui/Views/UserControl/ConnectSettingsUserControl.xaml +++ b/src/MaaWpfGui/Views/UserControl/ConnectSettingsUserControl.xaml @@ -140,22 +140,6 @@ HorizontalAlignment="Center" Orientation="Horizontal" Visibility="{c:Binding MuMuEmulator12Extras.Enable}"> - -