feat(PC): 支持 PC 端明日方舟 (#15407)

* feat(controller): 集成 MaaWin32ControlUnit 支持 Win32 窗口截图与控制

- 提取公共滑动插值逻辑到 SwipeHelper.hpp,重构 Minitouch/PlayTools 控制器
- 新增 Win32ControlUnitLoader 动态加载 MaaWin32ControlUnit.dll
- 新增 Win32Controller 实现 ControllerAPI,适配 touch_down/move/up 接口
- 添加 AsstAsyncAttachWindow 公开 API 用于绑定 Win32 窗口
- 添加 Win32 截图/输入方式的类型定义和枚举常量

* feat(api): 增加同步版本的 AsstAttachWindow 接口

模仿 AsstConnect 实现同步绑定 Win32 窗口的接口,方便简单场景下直接调用。
该接口标记为 deprecated,建议使用异步版本 AsstAsyncAttachWindow。

* fix: can build MaaCore

* feat: 完成整体适配

* feat(ci): 添加 MaaFramework Win32ControlUnit 下载步骤

使用 robinraju/release-downloader 从 MaaFramework 最新 release 下载
win-x64 版本并提取 MaaWin32ControlUnit 到构建产物中

* docs: 添加 Win32Controller 调试所需 MaaWin32ControlUnit 的说明

在开发文档的环境配置步骤中说明调试 Win32Controller 需要手动下载
MaaWin32ControlUnit.dll,并欢迎社区贡献自动下载脚本

* fix(i18n): 修改 UseAttachWindowWarning 措辞为"仅供尝鲜"

* fix: 小细节修复

* ci: fix maafw filename

* feat: PC 移至连接配置

* feat: 调整描述

* chore: 调整 PC 在连接配置中的顺序

* feat: 设置指引和开始唤醒界面 PC 选项绑定

---------

Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
This commit is contained in:
MistEO
2026-01-18 21:17:59 +08:00
committed by GitHub
parent 99bde4818e
commit a11660cbac
34 changed files with 2042 additions and 353 deletions

View File

@@ -0,0 +1,119 @@
#ifdef _WIN32
#include "Win32ControlUnitLoader.h"
#include <Windows.h>
#include "Utils/Logger.hpp"
namespace asst
{
Win32ControlUnitLoader::Win32ControlUnitLoader() = default;
Win32ControlUnitLoader::~Win32ControlUnitLoader()
{
unload();
}
bool Win32ControlUnitLoader::load(const std::filesystem::path& dll_path)
{
LogTraceFunction;
if (m_module) {
Log.warn("DLL already loaded");
return true;
}
std::filesystem::path full_path = dll_path;
if (!full_path.has_extension()) {
full_path += ".dll";
}
Log.info("Loading", full_path);
m_module = LoadLibraryW(full_path.wstring().c_str());
if (!m_module) {
DWORD error = GetLastError();
Log.error("Failed to load DLL, error code:", error);
return false;
}
m_get_version = reinterpret_cast<GetVersionFunc>(GetProcAddress(static_cast<HMODULE>(m_module), "MaaWin32ControlUnitGetVersion"));
m_create = reinterpret_cast<CreateFunc>(GetProcAddress(static_cast<HMODULE>(m_module), "MaaWin32ControlUnitCreate"));
m_destroy = reinterpret_cast<DestroyFunc>(GetProcAddress(static_cast<HMODULE>(m_module), "MaaWin32ControlUnitDestroy"));
if (!m_create || !m_destroy) {
Log.error("Failed to get function pointers from DLL");
unload();
return false;
}
if (m_get_version) {
Log.info("MaaWin32ControlUnit version:", m_get_version());
}
return true;
}
void Win32ControlUnitLoader::unload()
{
if (m_module) {
FreeLibrary(static_cast<HMODULE>(m_module));
m_module = nullptr;
}
m_get_version = nullptr;
m_create = nullptr;
m_destroy = nullptr;
}
const char* Win32ControlUnitLoader::get_version() const
{
if (m_get_version) {
return m_get_version();
}
return nullptr;
}
void* Win32ControlUnitLoader::create(
void* hwnd,
Win32ScreencapMethod screencap_method,
Win32InputMethod mouse_method,
Win32InputMethod keyboard_method)
{
LogTraceFunction;
if (!m_create) {
Log.error("DLL not loaded or create function not available");
return nullptr;
}
void* handle = m_create(hwnd, screencap_method, mouse_method, keyboard_method);
if (!handle) {
Log.error("Failed to create Win32ControlUnit");
return nullptr;
}
Log.info("Created Win32ControlUnit:", reinterpret_cast<void*>(handle));
return handle;
}
void Win32ControlUnitLoader::destroy(void* handle)
{
LogTraceFunction;
if (!m_destroy) {
Log.error("DLL not loaded or destroy function not available");
return;
}
if (handle) {
m_destroy(handle);
Log.info("Destroyed Win32ControlUnit:", reinterpret_cast<void*>(handle));
}
}
} // namespace asst
#endif // _WIN32