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 +108 -3
- maa/agent_client.py +49 -1
- maa/bin/libMaaAdbControlUnit.dylib +0 -0
- maa/bin/libMaaAgentClient.dylib +0 -0
- maa/bin/libMaaAgentServer.dylib +0 -0
- maa/bin/libMaaCustomControlUnit.dylib +0 -0
- maa/bin/libMaaFramework.dylib +0 -0
- maa/bin/libMaaToolkit.dylib +0 -0
- maa/bin/libMaaUtils.dylib +0 -0
- maa/bin/plugins/libMaaPluginDemo.dylib +0 -0
- maa/context.py +121 -5
- maa/controller.py +253 -4
- maa/define.py +168 -4
- maa/event_sink.py +2 -2
- maa/pipeline.py +32 -0
- maa/resource.py +195 -5
- maa/tasker.py +272 -5
- maa/toolkit.py +22 -0
- {maafw-5.0.0a3.dist-info → maafw-5.0.0b2.dist-info}/METADATA +31 -20
- maafw-5.0.0b2.dist-info/RECORD +32 -0
- maa/bin/libMaaDbgControlUnit.dylib +0 -0
- maafw-5.0.0a3.dist-info/RECORD +0 -32
- {maafw-5.0.0a3.dist-info → maafw-5.0.0b2.dist-info}/WHEEL +0 -0
- {maafw-5.0.0a3.dist-info → maafw-5.0.0b2.dist-info}/licenses/LICENSE.md +0 -0
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 ..
|
|
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(
|
|
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(
|
|
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
|
maa/bin/libMaaAgentClient.dylib
CHANGED
|
Binary file
|
maa/bin/libMaaAgentServer.dylib
CHANGED
|
Binary file
|
|
Binary file
|
maa/bin/libMaaFramework.dylib
CHANGED
|
Binary file
|
maa/bin/libMaaToolkit.dylib
CHANGED
|
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:
|
|
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:
|
|
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:
|
|
390
|
+
self, context: Context, noti_type: NotificationType, detail: NodeActionDetail
|
|
280
391
|
):
|
|
281
392
|
pass
|
|
282
393
|
|
|
283
|
-
def on_raw_notification(self,
|
|
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
|
-
|
|
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"],
|