Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/en_us/2.1-Integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@
- [Sample](https://github.com/hanhuoer/maa-framework-java/blob/main/maa-sample/README.md)
- [Unit Testing](https://github.com/hanhuoer/maa-framework-java/blob/main/maa-core/src/test)

## Rust

> ⚠️ **Warning**: This binding was entirely generated by AI and has not been thoroughly tested. Developers should verify its correctness and stability before use.

- Interface Status:
- AI-generated, experimental 🤖
- Sample provided ✔️
- Unit Testing via CI ❌
- Standardized interface ✔️
- Protocol parsing encapsulation ✔️
- [Source](https://github.com/MaaXYZ/MaaFramework/tree/main/source/binding/Rust)
- [Sample](https://github.com/MaaXYZ/MaaFramework/tree/main/source/binding/Rust/examples)

## And More

Language support is inseparable from the contributions of collaborators! If you also want to add an interface of a certain language to MaaFramework, please refer to [Standardized Interface Design](4.2-StandardizedInterfaceDesign.md) and submit a PR to us!
13 changes: 13 additions & 0 deletions docs/zh_cn/2.1-集成文档.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@
- [集成示例](https://github.com/hanhuoer/maa-framework-java/blob/main/maa-sample/README.md)
- [单元测试](https://github.com/hanhuoer/maa-framework-java/blob/main/maa-core/src/test)

## Rust

> ⚠️ **注意**:此绑定完全由 AI 生成,尚未经过充分测试。请开发者在使用时自行验证其正确性和稳定性。

- 接口情况:
- AI 生成,实验性质 🤖
- 提供 sample ✔️
- CI 单元测试 ❌
- 标准化接口 ✔️
- 协议解析封装 ✔️
- [接口源码](https://github.com/MaaXYZ/MaaFramework/tree/main/source/binding/Rust)
- [集成示例](https://github.com/MaaXYZ/MaaFramework/tree/main/source/binding/Rust/examples)

## 还有更多

各语言支持离不开协作者的贡献!若您也想为 MaaFramework 新增某一门语言的接口,请参考 [标准化接口设计](4.2-标准化接口设计.md),并向我们提出 PR!
25 changes: 25 additions & 0 deletions source/binding/Rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "maa-framework"
version = "0.1.0"
edition = "2021"
authors = ["MaaFramework Contributors"]
description = "Rust bindings for MaaFramework"
license = "MIT"
repository = "https://github.com/MaaAssistantArknights/MaaFramework"
keywords = ["maa", "automation", "framework", "binding"]
categories = ["api-bindings", "development-tools"]

[dependencies]
libloading = "0.8"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"
image = { version = "0.24", optional = true }

[features]
default = []
image = ["dep:image"]

[dev-dependencies]
tokio = { version = "1.0", features = ["full"] }

253 changes: 253 additions & 0 deletions source/binding/Rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
# MaaFramework Rust Binding

MaaFramework 的 Rust 语言绑定。

> ⚠️ **Warning**: This binding was entirely generated by AI and has not been thoroughly tested. Developers should verify its correctness and stability before use. Use at your own risk.
>
> ⚠️ **注意**:此绑定完全由 AI 生成,尚未经过充分测试。请开发者在使用时自行验证其正确性和稳定性。

## 安装

在 `Cargo.toml` 中添加依赖:

```toml
[dependencies]
maa-framework = { path = "path/to/binding/Rust" }
```

## 使用示例

### 基本使用

```rust
use maa_framework::*;
use serde_json::json;

fn main() -> Result<()> {
// 加载动态库
load_library("path/to/MaaFramework.dll")?;
load_toolkit("path/to/MaaToolkit.dll")?;

// 设置全局选项
set_log_dir("./log");
set_debug_mode(true);

// 查找 ADB 设备
let devices = Toolkit::find_adb_devices();
if devices.is_empty() {
println!("未找到设备");
return Ok(());
}

let device = &devices[0];
println!("找到设备: {} - {}", device.name, device.address);

// 创建控制器
let controller = AdbController::new(
&device.adb_path,
&device.address,
adb_screencap_method::DEFAULT,
adb_input_method::DEFAULT,
&device.config,
"path/to/MaaAgentBinary",
)?;

// 连接设备
controller.post_connection().wait();
if !controller.connected() {
return Err(MaaError::ConnectionFailed);
}

// 创建资源
let resource = Resource::new()?;
resource.post_bundle("path/to/resource").wait();
Comment on lines +56 to +63
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error propagation operator in the example. The same compilation issue exists here - post_connection() returns Result<CtrlJob>, not CtrlJob, so .wait() cannot be called directly.

Should be:

controller.post_connection()?.wait();

This pattern is repeated throughout the examples in lines 56, 63, 116, 130-147.

Suggested change
controller.post_connection().wait();
if !controller.connected() {
return Err(MaaError::ConnectionFailed);
}
// 创建资源
let resource = Resource::new()?;
resource.post_bundle("path/to/resource").wait();
controller.post_connection()?.wait();
if !controller.connected() {
return Err(MaaError::ConnectionFailed);
}
// 创建资源
let resource = Resource::new()?;
resource.post_bundle("path/to/resource")?.wait();

Copilot uses AI. Check for mistakes.
if !resource.loaded() {
return Err(MaaError::ResourceLoadFailed);
}

// 创建任务器
let mut tasker = Tasker::new()?;
tasker.bind(resource, controller.inner.clone());
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example code at line 70 references controller.inner.clone() but the Controller struct doesn't implement Clone, and the binding design intentionally avoids cloning handles (only one owner should drop the handle). This code will not compile.

The example should pass the controller directly or use a reference pattern:

tasker.bind(resource, controller);

Note: This assumes bind takes ownership of the controller, which appears to be the intended design based on the bind method signature.

Suggested change
tasker.bind(resource, controller.inner.clone());
tasker.bind(resource, controller);

Copilot uses AI. Check for mistakes.

if !tasker.inited() {
return Err(MaaError::OperationFailed("tasker init"));
}

// 执行任务
let job = tasker.post_task("StartUp", &json!({}))?;
job.wait();

if job.succeeded() {
println!("任务执行成功!");
if let Some(detail) = tasker.get_task_detail(job.id())? {
println!("任务入口: {}", detail.entry);
println!("执行节点数: {}", detail.nodes.len());
}
} else {
println!("任务执行失败");
}

Ok(())
}
```

### Win32 控制器

```rust
use maa_framework::*;

fn main() -> Result<()> {
load_library("path/to/MaaFramework.dll")?;
load_toolkit("path/to/MaaToolkit.dll")?;

// 查找桌面窗口
let windows = Toolkit::find_desktop_windows();
let target = windows.iter().find(|w| w.window_name.contains("目标窗口"));

if let Some(window) = target {
let controller = Win32Controller::new(
window.hwnd,
win32_screencap_method::DXGI_DESKTOP_DUP,
win32_input_method::SEIZE,
win32_input_method::SEIZE,
)?;

controller.post_connection().wait();
// ...
}

Ok(())
}
```

### 控制器操作

```rust
use maa_framework::*;

fn controller_demo(controller: &Controller) -> Result<()> {
// 点击
controller.post_click(100, 200).wait();

// 滑动
controller.post_swipe(100, 200, 300, 400, 500).wait();

// 输入文本
controller.post_input_text("Hello")?.wait();

// 截图
controller.post_screencap().wait();
let image = controller.cached_image()?;
println!("截图尺寸: {}x{}", image.width(), image.height());

// 触摸操作
controller.post_touch_down(0, 100, 200, 1).wait();
controller.post_touch_move(0, 150, 250, 1).wait();
controller.post_touch_up(0).wait();

Ok(())
}
```

### 资源管理

```rust
use maa_framework::*;
use serde_json::json;

fn resource_demo() -> Result<()> {
let resource = Resource::new()?;

// 加载资源
resource.post_bundle("./resource").wait();

// 覆盖 pipeline
resource.override_pipeline(&json!({
"MyTask": {
"next": ["TaskA", "TaskB"]
}
}))?;

// 覆盖 next 列表
resource.override_next("MyTask", &["TaskC", "TaskD"])?;

// 获取节点数据
if let Some(data) = resource.get_node_data("MyTask")? {
println!("节点数据: {}", data);
}

// 设置推理设备
resource.use_directml(0);

Ok(())
}
```

## API 参考

### 全局函数

- `load_library(path)` - 加载 MaaFramework 动态库
- `load_toolkit(path)` - 加载 MaaToolkit 动态库
- `version()` - 获取框架版本
- `set_log_dir(path)` - 设置日志目录
- `set_save_draw(enable)` - 设置是否保存识别结果图
- `set_debug_mode(enable)` - 设置调试模式
- `set_stdout_level(level)` - 设置控制台日志级别
- `load_plugin(path)` - 加载插件

### Resource

- `new()` - 创建资源
- `post_bundle(path)` - 异步加载资源
- `override_pipeline(json)` - 覆盖 pipeline
- `override_next(name, list)` - 覆盖 next 列表
- `override_image(name, image)` - 覆盖图片
- `get_node_data(name)` - 获取节点数据
- `loaded()` - 是否加载完成
- `clear()` - 清除资源
- `use_cpu()` / `use_directml()` / `use_coreml()` - 设置推理设备

### Controller

- `post_connection()` - 异步连接
- `post_click(x, y)` - 异步点击
- `post_swipe(x1, y1, x2, y2, duration)` - 异步滑动
- `post_screencap()` - 异步截图
- `post_input_text(text)` - 异步输入文本
- `post_start_app(intent)` / `post_stop_app(intent)` - 启动/停止应用
- `connected()` - 是否已连接
- `cached_image()` - 获取最新截图
- `uuid()` - 获取设备 UUID

### Tasker

- `new()` - 创建任务器
- `bind(resource, controller)` - 绑定资源和控制器
- `inited()` - 是否初始化完成
- `post_task(entry, override)` - 异步执行任务
- `running()` - 是否正在运行
- `post_stop()` - 异步停止
- `get_task_detail(id)` - 获取任务详情
- `get_node_detail(id)` - 获取节点详情
- `get_recognition_detail(id)` - 获取识别详情
- `get_action_detail(id)` - 获取动作详情

### Context

- `run_task(entry, override)` - 同步执行任务
- `run_recognition(entry, image, override)` - 同步执行识别
- `run_action(entry, box, detail, override)` - 同步执行动作
- `override_pipeline(json)` / `override_next(name, list)` - 覆盖配置
- `set_anchor(anchor, node)` / `get_anchor(anchor)` - 锚点操作
- `get_hit_count(node)` / `clear_hit_count(node)` - 命中计数

### Toolkit

- `init_option(path, config)` - 初始化配置
- `find_adb_devices()` - 查找 ADB 设备
- `find_desktop_windows()` - 查找桌面窗口

## 许可证

MIT License
Loading
Loading