MaaFw 5.0.0a3__py3-none-macosx_13_0_x86_64.whl → 5.0.0b2__py3-none-macosx_13_0_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of MaaFw might be problematic. Click here for more details.

maa/agent/agent_server.py CHANGED
@@ -1,9 +1,8 @@
1
1
  import ctypes
2
- import sys
3
2
 
4
3
  from ..define import *
5
4
  from ..library import Library
6
- from ..buffer import StringBuffer
5
+ from ..event_sink import EventSink
7
6
 
8
7
 
9
8
  class AgentServer:
@@ -88,12 +87,94 @@ class AgentServer:
88
87
  Library.agent_server().MaaAgentServerJoin()
89
88
 
90
89
  @staticmethod
91
- def detach(self) -> None:
90
+ def detach() -> None:
92
91
 
93
92
  AgentServer._set_api_properties()
94
93
 
95
94
  Library.agent_server().MaaAgentServerDetach()
96
95
 
96
+ _sink_holder: Dict[int, "EventSink"] = {}
97
+
98
+ @staticmethod
99
+ def resource_sink():
100
+ def wrapper_sink(sink):
101
+ AgentServer.add_resource_sink(sink=sink())
102
+ return sink
103
+
104
+ return wrapper_sink
105
+
106
+ @staticmethod
107
+ def add_resource_sink(sink: "ResourceEventSink") -> None:
108
+ sink_id = int(
109
+ Library.agent_server().MaaAgentServerAddResourceSink(
110
+ *EventSink._gen_c_param(sink)
111
+ )
112
+ )
113
+ if sink_id == MaaInvalidId:
114
+ return None
115
+
116
+ AgentServer._sink_holder[sink_id] = sink
117
+
118
+ @staticmethod
119
+ def controller_sink():
120
+ def wrapper_sink(sink):
121
+ AgentServer.add_controller_sink(sink=sink())
122
+ return sink
123
+
124
+ return wrapper_sink
125
+
126
+ @staticmethod
127
+ def add_controller_sink(sink: "ControllerEventSink") -> None:
128
+ sink_id = int(
129
+ Library.agent_server().MaaAgentServerAddControllerSink(
130
+ *EventSink._gen_c_param(sink)
131
+ )
132
+ )
133
+ if sink_id == MaaInvalidId:
134
+ return None
135
+
136
+ AgentServer._sink_holder[sink_id] = sink
137
+
138
+ @staticmethod
139
+ def tasker_sink():
140
+ def wrapper_sink(sink):
141
+ AgentServer.add_tasker_sink(sink=sink())
142
+ return sink
143
+
144
+ return wrapper_sink
145
+
146
+ @staticmethod
147
+ def add_tasker_sink(sink: "TaskerEventSink") -> None:
148
+ sink_id = int(
149
+ Library.agent_server().MaaAgentServerAddTaskerSink(
150
+ *EventSink._gen_c_param(sink)
151
+ )
152
+ )
153
+ if sink_id == MaaInvalidId:
154
+ return None
155
+
156
+ AgentServer._sink_holder[sink_id] = sink
157
+
158
+ @staticmethod
159
+ def context_sink():
160
+ def wrapper_sink(sink):
161
+ AgentServer.add_context_sink(sink=sink())
162
+ return sink
163
+
164
+ return wrapper_sink
165
+
166
+ @staticmethod
167
+ def add_context_sink(sink: "ContextEventSink") -> None:
168
+ sink_id = int(
169
+ Library.agent_server().MaaAgentServerAddContextSink(
170
+ *EventSink._gen_c_param(sink)
171
+ )
172
+ )
173
+ if sink_id == MaaInvalidId:
174
+ return None
175
+
176
+ AgentServer._sink_holder[sink_id] = sink
177
+
97
178
  _api_properties_initialized: bool = False
98
179
 
99
180
  @staticmethod
@@ -130,3 +211,27 @@ class AgentServer:
130
211
 
131
212
  Library.agent_server().MaaAgentServerDetach.restype = None
132
213
  Library.agent_server().MaaAgentServerDetach.argtypes = []
214
+
215
+ Library.agent_server().MaaAgentServerAddResourceSink.restype = MaaSinkId
216
+ Library.agent_server().MaaAgentServerAddResourceSink.argtypes = [
217
+ MaaEventCallback,
218
+ ctypes.c_void_p,
219
+ ]
220
+
221
+ Library.agent_server().MaaAgentServerAddControllerSink.restype = MaaSinkId
222
+ Library.agent_server().MaaAgentServerAddControllerSink.argtypes = [
223
+ MaaEventCallback,
224
+ ctypes.c_void_p,
225
+ ]
226
+
227
+ Library.agent_server().MaaAgentServerAddTaskerSink.restype = MaaSinkId
228
+ Library.agent_server().MaaAgentServerAddTaskerSink.argtypes = [
229
+ MaaEventCallback,
230
+ ctypes.c_void_p,
231
+ ]
232
+
233
+ Library.agent_server().MaaAgentServerAddContextSink.restype = MaaSinkId
234
+ Library.agent_server().MaaAgentServerAddContextSink.argtypes = [
235
+ MaaEventCallback,
236
+ ctypes.c_void_p,
237
+ ]
maa/agent_client.py CHANGED
@@ -3,6 +3,8 @@ import ctypes
3
3
  from .define import *
4
4
  from .library import Library
5
5
  from .resource import Resource
6
+ from .controller import Controller
7
+ from .tasker import Tasker
6
8
  from .buffer import StringBuffer
7
9
 
8
10
 
@@ -47,6 +49,30 @@ class AgentClient:
47
49
  )
48
50
  )
49
51
 
52
+ def register_sink(
53
+ self, resource: Resource, controller: Controller, tasker: Tasker
54
+ ) -> bool:
55
+ # avoid gc
56
+ self._sinks = [resource, controller, tasker]
57
+
58
+ return (
59
+ bool(
60
+ Library.agent_client().MaaAgentClientRegisterResourceSink(
61
+ self._handle, resource._handle
62
+ )
63
+ )
64
+ and bool(
65
+ Library.agent_client().MaaAgentClientRegisterControllerSink(
66
+ self._handle, controller._handle
67
+ )
68
+ )
69
+ and bool(
70
+ Library.agent_client().MaaAgentClientRegisterTaskerSink(
71
+ self._handle, tasker._handle
72
+ )
73
+ )
74
+ )
75
+
50
76
  def connect(self) -> bool:
51
77
  return bool(Library.agent_client().MaaAgentClientConnect(self._handle))
52
78
 
@@ -62,7 +88,11 @@ class AgentClient:
62
88
  return bool(Library.agent_client().MaaAgentClientAlive(self._handle))
63
89
 
64
90
  def set_timeout(self, milliseconds: int) -> bool:
65
- return bool(Library.agent_client().MaaAgentClientSetTimeout(self._handle, ctypes.c_int64(milliseconds)))
91
+ return bool(
92
+ Library.agent_client().MaaAgentClientSetTimeout(
93
+ self._handle, ctypes.c_int64(milliseconds)
94
+ )
95
+ )
66
96
 
67
97
  _api_properties_initialized: bool = False
68
98
 
@@ -96,6 +126,24 @@ class AgentClient:
96
126
  MaaResourceHandle,
97
127
  ]
98
128
 
129
+ Library.agent_client().MaaAgentClientRegisterResourceSink.restype = MaaBool
130
+ Library.agent_client().MaaAgentClientRegisterResourceSink.argtypes = [
131
+ MaaAgentClientHandle,
132
+ MaaResourceHandle,
133
+ ]
134
+
135
+ Library.agent_client().MaaAgentClientRegisterControllerSink.restype = MaaBool
136
+ Library.agent_client().MaaAgentClientRegisterControllerSink.argtypes = [
137
+ MaaAgentClientHandle,
138
+ MaaControllerHandle,
139
+ ]
140
+
141
+ Library.agent_client().MaaAgentClientRegisterTaskerSink.restype = MaaBool
142
+ Library.agent_client().MaaAgentClientRegisterTaskerSink.argtypes = [
143
+ MaaAgentClientHandle,
144
+ MaaTaskerHandle,
145
+ ]
146
+
99
147
  Library.agent_client().MaaAgentClientConnect.restype = MaaBool
100
148
  Library.agent_client().MaaAgentClientConnect.argtypes = [
101
149
  MaaAgentClientHandle,
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
maa/bin/libMaaUtils.dylib CHANGED
Binary file
Binary file
maa/context.py CHANGED
@@ -34,6 +34,15 @@ class Context:
34
34
  def run_task(
35
35
  self, entry: str, pipeline_override: Dict = {}
36
36
  ) -> Optional[TaskDetail]:
37
+ """同步执行任务 / Synchronously execute task
38
+
39
+ Args:
40
+ entry: 任务入口 / Task entry
41
+ pipeline_override: 用于覆盖的 json / JSON for overriding
42
+
43
+ Returns:
44
+ Optional[TaskDetail]: 任务详情,执行失败则返回 None / Task detail, or None if execution failed
45
+ """
37
46
  task_id = int(
38
47
  Library.framework().MaaContextRunTask(
39
48
  self._handle, *Context._gen_post_param(entry, pipeline_override)
@@ -50,6 +59,19 @@ class Context:
50
59
  image: numpy.ndarray,
51
60
  pipeline_override: Dict = {},
52
61
  ) -> Optional[RecognitionDetail]:
62
+ """同步执行识别逻辑 / Synchronously execute recognition logic
63
+
64
+ 不会执行后续操作, 不会执行后续 next
65
+ Will not execute subsequent operations or next steps
66
+
67
+ Args:
68
+ entry: 任务名 / Task name
69
+ image: 前序截图 / Previous screenshot
70
+ pipeline_override: 用于覆盖的 json / JSON for overriding
71
+
72
+ Returns:
73
+ Optional[RecognitionDetail]: 识别详情,执行失败则返回 None / Recognition detail, or None if execution failed
74
+ """
53
75
  image_buffer = ImageBuffer()
54
76
  image_buffer.set(image)
55
77
  reco_id = int(
@@ -71,6 +93,20 @@ class Context:
71
93
  reco_detail: str = "",
72
94
  pipeline_override: Dict = {},
73
95
  ) -> Optional[NodeDetail]:
96
+ """同步执行操作逻辑 / Synchronously execute action logic
97
+
98
+ 不会执行后续 next
99
+ Will not execute subsequent next steps
100
+
101
+ Args:
102
+ entry: 任务名 / Task name
103
+ box: 前序识别位置 / Previous recognition position
104
+ reco_detail: 前序识别详情 / Previous recognition details
105
+ pipeline_override: 用于覆盖的 json / JSON for overriding
106
+
107
+ Returns:
108
+ Optional[NodeDetail]: 节点详情,执行失败则返回 None / Node detail, or None if execution failed
109
+ """
74
110
  rect = RectBuffer()
75
111
  rect.set(box)
76
112
 
@@ -89,6 +125,14 @@ class Context:
89
125
  return self.tasker.get_node_detail(node_id)
90
126
 
91
127
  def override_pipeline(self, pipeline_override: Dict) -> bool:
128
+ """覆盖 pipeline / Override pipeline_override
129
+
130
+ Args:
131
+ pipeline_override: 用于覆盖的 json / JSON for overriding
132
+
133
+ Returns:
134
+ bool: 是否成功 / Whether successful
135
+ """
92
136
  pipeline_json = json.dumps(pipeline_override, ensure_ascii=False)
93
137
 
94
138
  return bool(
@@ -99,6 +143,18 @@ class Context:
99
143
  )
100
144
 
101
145
  def override_next(self, name: str, next_list: List[str]) -> bool:
146
+ """覆盖任务的 next 列表 / Override the next list of task
147
+
148
+ 如果节点不存在,此方法会失败
149
+ This method will fail if the node does not exist
150
+
151
+ Args:
152
+ name: 任务名 / Task name
153
+ next_list: next 列表 / Next list
154
+
155
+ Returns:
156
+ bool: 成功返回 True,如果节点不存在则返回 False / Returns True on success, False if node does not exist
157
+ """
102
158
  list_buffer = StringListBuffer()
103
159
  list_buffer.set(next_list)
104
160
 
@@ -108,7 +164,34 @@ class Context:
108
164
  )
109
165
  )
110
166
 
167
+ def override_image(self, image_name: str, image: numpy.ndarray) -> bool:
168
+ """覆盖图片 / Override the image corresponding to image_name
169
+
170
+ Args:
171
+ image_name: 图片名 / Image name
172
+ image: 图片数据 / Image data
173
+
174
+ Returns:
175
+ bool: 是否成功 / Whether successful
176
+ """
177
+ image_buffer = ImageBuffer()
178
+ image_buffer.set(image)
179
+
180
+ return bool(
181
+ Library.framework().MaaContextOverrideImage(
182
+ self._handle, image_name.encode(), image_buffer._handle
183
+ )
184
+ )
185
+
111
186
  def get_node_data(self, name: str) -> Optional[Dict]:
187
+ """获取任务当前的定义 / Get the current definition of task
188
+
189
+ Args:
190
+ name: 任务名 / Task name
191
+
192
+ Returns:
193
+ Optional[Dict]: 任务定义字典,如果不存在则返回 None / Task definition dict, or None if not exists
194
+ """
112
195
  string_buffer = StringBuffer()
113
196
  if not Library.framework().MaaContextGetNodeData(
114
197
  self._handle, name.encode(), string_buffer._handle
@@ -134,9 +217,22 @@ class Context:
134
217
 
135
218
  @property
136
219
  def tasker(self) -> Tasker:
220
+ """获取实例 / Get instance
221
+
222
+ Returns:
223
+ Tasker: 实例对象 / Instance object
224
+ """
137
225
  return self._tasker
138
226
 
139
227
  def get_task_job(self) -> JobWithResult:
228
+ """获取对应任务号的任务作业 / Get task job for corresponding task id
229
+
230
+ Returns:
231
+ JobWithResult: 任务作业对象 / Task job object
232
+
233
+ Raises:
234
+ ValueError: 如果任务 id 为 None
235
+ """
140
236
  task_id = Library.framework().MaaContextGetTaskId(self._handle)
141
237
  if not task_id:
142
238
  raise ValueError("task_id is None")
@@ -144,6 +240,14 @@ class Context:
144
240
  return self.tasker._gen_task_job(task_id)
145
241
 
146
242
  def clone(self) -> "Context":
243
+ """复制上下文 / Clone context
244
+
245
+ Returns:
246
+ Context: 复制的上下文对象 / Cloned context object
247
+
248
+ Raises:
249
+ ValueError: 如果克隆失败
250
+ """
147
251
  cloned_handle = Library.framework().MaaContextClone(self._handle)
148
252
  if not cloned_handle:
149
253
  raise ValueError("cloned_handle is None")
@@ -213,6 +317,13 @@ class Context:
213
317
  MaaStringListBufferHandle,
214
318
  ]
215
319
 
320
+ Library.framework().MaaContextOverrideImage.restype = MaaBool
321
+ Library.framework().MaaContextOverrideImage.argtypes = [
322
+ MaaContextHandle,
323
+ ctypes.c_char_p,
324
+ MaaImageBufferHandle,
325
+ ]
326
+
216
327
  Library.framework().MaaContextGetNodeData.restype = MaaBool
217
328
  Library.framework().MaaContextGetNodeData.argtypes = [
218
329
  MaaContextHandle,
@@ -247,7 +358,7 @@ class ContextEventSink(EventSink):
247
358
 
248
359
  def on_node_next_list(
249
360
  self,
250
- context: "Context",
361
+ context: Context,
251
362
  noti_type: NotificationType,
252
363
  detail: NodeNextListDetail,
253
364
  ):
@@ -262,7 +373,7 @@ class ContextEventSink(EventSink):
262
373
 
263
374
  def on_node_recognition(
264
375
  self,
265
- context: "Context",
376
+ context: Context,
266
377
  noti_type: NotificationType,
267
378
  detail: NodeRecognitionDetail,
268
379
  ):
@@ -276,14 +387,19 @@ class ContextEventSink(EventSink):
276
387
  focus: Any
277
388
 
278
389
  def on_node_action(
279
- self, context: "Context", noti_type: NotificationType, detail: NodeActionDetail
390
+ self, context: Context, noti_type: NotificationType, detail: NodeActionDetail
280
391
  ):
281
392
  pass
282
393
 
283
- def on_raw_notification(self, handle: ctypes.c_void_p, msg: str, details: dict):
394
+ def on_raw_notification(self, context: Context, msg: str, details: dict):
395
+ pass
396
+
397
+ def _on_raw_notification(self, handle: ctypes.c_void_p, msg: str, details: dict):
398
+
284
399
  context = Context(handle=handle)
285
- noti_type = EventSink._notification_type(msg)
400
+ self.on_raw_notification(context, msg, details)
286
401
 
402
+ noti_type = EventSink._notification_type(msg)
287
403
  if msg.startswith("Node.NextList"):
288
404
  detail = self.NodeNextListDetail(
289
405
  task_id=details["task_id"],