1use serde::{Deserialize, Serialize};
2
3use crate::{error::Error, instance::MaaInstance, internal, maa_bool, string, MaaResult};
4
5#[cfg(feature = "win32")]
6use crate::controller::win32::MaaWin32Hwnd;
7
8#[cfg(feature = "adb")]
9use crate::controller::adb::MaaAdbControllerType;
10
11pub struct MaaToolkit;
12
13impl MaaToolkit {
14 #[deprecated(since = "0.4.0", note = "Use `MaaToolkit::new_with_options` instead")]
20 pub fn new() -> MaaResult<Self> {
21 let toolkit_init_ret = unsafe { internal::MaaToolkitInit() };
22
23 if !maa_bool!(toolkit_init_ret) {
24 return Err(Error::MaaToolkitInitError);
25 }
26
27 Ok(Self)
28 }
29
30 pub fn new_with_options<T: Serialize>(user_path: String, config: T) -> MaaResult<Self> {
31 let user_path = internal::to_cstring(&user_path);
32 let config = internal::to_cstring(&serde_json::to_string(&config).unwrap());
33
34 let toolkit_init_ret = unsafe { internal::MaaToolkitInitOptionConfig(user_path, config) };
35
36 if !maa_bool!(toolkit_init_ret) {
37 return Err(Error::MaaToolkitInitError);
38 }
39
40 Ok(Self)
41 }
42
43 #[cfg(feature = "adb")]
49 #[doc(cfg(feature = "adb"))]
50 pub fn find_adb_device(&self) -> MaaResult<Vec<AdbDeviceInfo>> {
51 let ret = unsafe { internal::MaaToolkitPostFindDevice() };
52
53 if !maa_bool!(ret) {
54 return Err(Error::MaaToolkitPostFindDeviceError);
55 }
56
57 let device_count = unsafe { internal::MaaToolkitWaitForFindDeviceToComplete() };
58
59 self.get_adb_devices_info(device_count)
60 }
61
62 #[cfg(feature = "adb")]
68 #[doc(cfg(feature = "adb"))]
69 pub fn find_adb_device_with_adb(&self, adb_path: &str) -> MaaResult<Vec<AdbDeviceInfo>> {
70 let adb_path = internal::to_cstring(adb_path);
71 let ret = unsafe { internal::MaaToolkitPostFindDeviceWithAdb(adb_path) };
72
73 if !maa_bool!(ret) {
74 return Err(Error::MaaToolkitPostFindDeviceError);
75 }
76
77 let device_count = unsafe { internal::MaaToolkitWaitForFindDeviceToComplete() };
78
79 self.get_adb_devices_info(device_count)
80 }
81
82 #[cfg(feature = "adb")]
83 #[doc(cfg(feature = "adb"))]
84 fn get_adb_devices_info(&self, device_count: u64) -> MaaResult<Vec<AdbDeviceInfo>> {
85 let mut devices = Vec::with_capacity(device_count as usize);
86
87 for i in 0..device_count {
88 let name = unsafe { internal::MaaToolkitGetDeviceName(i) };
89 let adb_path = unsafe { internal::MaaToolkitGetDeviceAdbPath(i) };
90 let adb_serial = unsafe { internal::MaaToolkitGetDeviceAdbSerial(i) };
91 let adb_controller_type = unsafe { internal::MaaToolkitGetDeviceAdbControllerType(i) };
92 let adb_config = unsafe { internal::MaaToolkitGetDeviceAdbConfig(i) };
93
94 let name = string!(name);
95 let adb_path = string!(adb_path);
96 let adb_serial = string!(adb_serial);
97 let adb_config = string!(adb_config);
98 let adb_controller_type = MaaAdbControllerType::try_from(adb_controller_type)?;
99
100 devices.push(AdbDeviceInfo {
101 name,
102 adb_path,
103 adb_serial,
104 adb_controller_type,
105 adb_config,
106 });
107 }
108
109 Ok(devices)
110 }
111
112 pub fn register_custom_recognizer_executor<T>(
113 &self,
114 handle: MaaInstance<T>,
115 recognizer_name: &str,
116 recognizer_exec_path: &str,
117 recognizer_exec_params: Vec<String>,
118 ) -> MaaResult<()> {
119 let recognizer_name = internal::to_cstring(recognizer_name);
120 let recognizer_exec_path = internal::to_cstring(recognizer_exec_path);
121
122 let param_size = recognizer_exec_params.len() as u64;
123 let mut params: Vec<_> = recognizer_exec_params
124 .into_iter()
125 .map(|s| internal::to_cstring(&s))
126 .collect();
127 params.shrink_to_fit();
128 let params_ptr = params.as_ptr();
129 std::mem::forget(params);
130
131 let ret = unsafe {
132 internal::MaaToolkitRegisterCustomRecognizerExecutor(
133 *handle,
134 recognizer_name,
135 recognizer_exec_path,
136 params_ptr,
137 param_size,
138 )
139 };
140
141 if !maa_bool!(ret) {
142 return Err(Error::MaaToolkitRegisterCustomRecognizerExecutorError);
143 }
144
145 Ok(())
146 }
147
148 pub fn unregister_custom_recognizer_executor<T>(
149 &self,
150 handle: MaaInstance<T>,
151 recognizer_name: &str,
152 ) -> MaaResult<()> {
153 let recognizer_name = internal::to_cstring(recognizer_name);
154
155 let ret = unsafe {
156 internal::MaaToolkitUnregisterCustomRecognizerExecutor(*handle, recognizer_name)
157 };
158
159 if !maa_bool!(ret) {
160 return Err(Error::MaaToolkitUnregisterCustomRecognizerExecutorError);
161 }
162
163 Ok(())
164 }
165
166 pub fn register_custom_action_executor<T>(
167 &self,
168 handle: MaaInstance<T>,
169 action_name: &str,
170 action_exec_path: &str,
171 action_exec_params: Vec<String>,
172 ) -> MaaResult<()> {
173 let action_name = internal::to_cstring(action_name);
174 let action_exec_path = internal::to_cstring(action_exec_path);
175
176 let param_size = action_exec_params.len() as u64;
177 let mut params: Vec<_> = action_exec_params
178 .into_iter()
179 .map(|s| internal::to_cstring(&s))
180 .collect();
181 params.shrink_to_fit();
182 let params_ptr = params.as_ptr();
183 std::mem::forget(params);
184
185 let ret = unsafe {
186 internal::MaaToolkitRegisterCustomActionExecutor(
187 *handle,
188 action_name,
189 action_exec_path,
190 params_ptr,
191 param_size,
192 )
193 };
194
195 if !maa_bool!(ret) {
196 return Err(Error::MaaToolkitRegisterCustomRecognizerExecutorError);
197 }
198
199 Ok(())
200 }
201
202 pub fn unregister_custom_action_executor<T>(
203 &self,
204 handle: MaaInstance<T>,
205 action_name: &str,
206 ) -> MaaResult<()> {
207 let action_name = internal::to_cstring(action_name);
208
209 let ret =
210 unsafe { internal::MaaToolkitUnregisterCustomActionExecutor(*handle, action_name) };
211
212 if !maa_bool!(ret) {
213 return Err(Error::MaaToolkitUnregisterCustomRecognizerExecutorError);
214 }
215
216 Ok(())
217 }
218
219 #[cfg(feature = "win32")]
226 #[doc(cfg(feature = "win32"))]
227 pub fn find_win32_window(
228 &self,
229 class_name: &str,
230 window_name: &str,
231 find: bool,
232 ) -> Vec<MaaWin32Hwnd> {
233 let class_name = internal::to_cstring(class_name);
234 let window_name = internal::to_cstring(window_name);
235
236 let hwnd_count = unsafe {
237 if find {
238 internal::MaaToolkitFindWindow(class_name, window_name)
239 } else {
240 internal::MaaToolkitSearchWindow(class_name, window_name)
241 }
242 };
243
244 let mut hwnds = Vec::with_capacity(hwnd_count as usize);
245
246 for i in 0..hwnd_count {
247 let hwnd = unsafe { internal::MaaToolkitGetWindow(i) };
248 hwnds.push(MaaWin32Hwnd(hwnd));
249 }
250
251 hwnds
252 }
253
254 #[cfg(feature = "win32")]
255 #[doc(cfg(feature = "win32"))]
256 pub fn get_cursor_window(&self) -> MaaWin32Hwnd {
257 let hwnd = unsafe { internal::MaaToolkitGetCursorWindow() };
258 MaaWin32Hwnd(hwnd)
259 }
260
261 #[cfg(feature = "win32")]
262 #[doc(cfg(feature = "win32"))]
263 pub fn get_desktop_window(&self) -> MaaWin32Hwnd {
264 let hwnd = unsafe { internal::MaaToolkitGetDesktopWindow() };
265 MaaWin32Hwnd(hwnd)
266 }
267
268 #[cfg(feature = "win32")]
269 #[doc(cfg(feature = "win32"))]
270 pub fn get_foreground_window(&self) -> MaaWin32Hwnd {
271 let hwnd = unsafe { internal::MaaToolkitGetForegroundWindow() };
272 MaaWin32Hwnd(hwnd)
273 }
274
275 #[cfg(feature = "win32")]
276 #[doc(cfg(feature = "win32"))]
277 pub fn list_windows(&self) -> Vec<MaaWin32Hwnd> {
278 let hwnd_count = unsafe { internal::MaaToolkitListWindows() };
279 let mut hwnds = Vec::with_capacity(hwnd_count as usize);
280
281 for i in 0..hwnd_count {
282 let hwnd = unsafe { internal::MaaToolkitGetWindow(i) };
283 hwnds.push(MaaWin32Hwnd(hwnd));
284 }
285
286 hwnds
287 }
288}
289
290unsafe impl Send for MaaToolkit {}
291unsafe impl Sync for MaaToolkit {}
292
293#[derive(Serialize, Deserialize)]
294#[cfg(feature = "adb")]
295pub struct AdbDeviceInfo {
296 pub name: String,
297 pub adb_path: String,
298 pub adb_serial: String,
299 pub adb_controller_type: MaaAdbControllerType,
300 pub adb_config: String,
301}