Files
MaaAssistantArknights/src/MaaCore/Controller/SwipeHelper.hpp
MistEO a11660cbac 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>
2026-01-18 21:17:59 +08:00

138 lines
3.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <cmath>
#include <functional>
#include "Common/AsstTypes.h"
namespace asst
{
// 三次样条插值函数,用于生成平滑的滑动曲线
// slope_0: 起点斜率slope_1: 终点斜率t: 插值进度 [0, 1]
inline double cubic_spline(double slope_0, double slope_1, double t)
{
const double a = slope_0;
const double b = -(2 * slope_0 + slope_1 - 3);
const double c = -(-slope_0 - slope_1 + 2);
return a * t + b * std::pow(t, 2) + c * std::pow(t, 3);
}
// 滑动插值执行器
// MoveFunc: bool(int x, int y) - 移动到指定位置的回调,返回 false 表示失败
// BoundsCheckFunc: bool(int x, int y) - 边界检查回调,返回 true 表示在边界内
template <typename MoveFunc, typename BoundsCheckFunc>
bool interpolate_swipe(
int x1,
int y1,
int x2,
int y2,
int duration,
int interval,
double slope_in,
double slope_out,
MoveFunc&& move_func,
BoundsCheckFunc&& bounds_check)
{
for (int cur_time = interval; cur_time < duration; cur_time += interval) {
double progress = cubic_spline(slope_in, slope_out, static_cast<double>(cur_time) / duration);
int cur_x = static_cast<int>(std::lerp(static_cast<double>(x1), static_cast<double>(x2), progress));
int cur_y = static_cast<int>(std::lerp(static_cast<double>(y1), static_cast<double>(y2), progress));
if (!bounds_check(cur_x, cur_y)) {
continue;
}
if (!move_func(cur_x, cur_y)) {
return false;
}
}
// 确保到达终点(如果在边界内)
if (bounds_check(x2, y2)) {
if (!move_func(x2, y2)) {
return false;
}
}
return true;
}
// 简化版本:不需要边界检查
template <typename MoveFunc>
bool interpolate_swipe(
int x1,
int y1,
int x2,
int y2,
int duration,
int interval,
double slope_in,
double slope_out,
MoveFunc&& move_func)
{
return interpolate_swipe(
x1,
y1,
x2,
y2,
duration,
interval,
slope_in,
slope_out,
std::forward<MoveFunc>(move_func),
[](int, int) { return true; });
}
// 带暂停检测的滑动插值执行器(用于 MinitouchController 的 swipe_with_pause 功能)
// PauseCheckFunc: bool(int cur_x, int cur_y, int start_x, int start_y) - 检查是否需要暂停
// PauseFunc: void() - 执行暂停操作
template <typename MoveFunc, typename BoundsCheckFunc, typename PauseCheckFunc, typename PauseFunc>
bool interpolate_swipe_with_pause(
int x1,
int y1,
int x2,
int y2,
int duration,
int interval,
double slope_in,
double slope_out,
MoveFunc&& move_func,
BoundsCheckFunc&& bounds_check,
PauseCheckFunc&& pause_check,
PauseFunc&& pause_func)
{
bool pause_triggered = false;
for (int cur_time = interval; cur_time < duration; cur_time += interval) {
double progress = cubic_spline(slope_in, slope_out, static_cast<double>(cur_time) / duration);
int cur_x = static_cast<int>(std::lerp(static_cast<double>(x1), static_cast<double>(x2), progress));
int cur_y = static_cast<int>(std::lerp(static_cast<double>(y1), static_cast<double>(y2), progress));
// 检查是否需要触发暂停
if (!pause_triggered && pause_check(cur_x, cur_y, x1, y1)) {
pause_triggered = true;
pause_func();
}
if (!bounds_check(cur_x, cur_y)) {
continue;
}
if (!move_func(cur_x, cur_y)) {
return false;
}
}
// 确保到达终点(如果在边界内)
if (bounds_check(x2, y2)) {
if (!move_func(x2, y2)) {
return false;
}
}
return true;
}
} // namespace asst