MaaFw 4.4.0b1__py3-none-manylinux2014_x86_64.whl → 5.4.0__py3-none-manylinux2014_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/event_sink.py ADDED
@@ -0,0 +1,103 @@
1
+ import ctypes
2
+ import json
3
+ from abc import ABC
4
+ from typing import Tuple
5
+ from enum import IntEnum
6
+
7
+ from .define import MaaEventCallback
8
+
9
+
10
+ # class NotificationEvent(IntEnum):
11
+ # ResourceLoading = 1
12
+ # ControllerAction = 2
13
+ # TaskerTask = 3
14
+ # TaskNextList = 4
15
+ # TaskRecognition = 5
16
+ # TaskAction = 6
17
+
18
+
19
+ class NotificationType(IntEnum):
20
+ """通知类型枚举 / Notification type enumeration
21
+
22
+ 用于标识事件回调的状态类型。
23
+ Used to identify the status type of event callbacks.
24
+
25
+ Attributes:
26
+ Unknown: 未知类型 / Unknown type
27
+ Starting: 开始 / Starting
28
+ Succeeded: 成功 / Succeeded
29
+ Failed: 失败 / Failed
30
+ """
31
+
32
+ Unknown = 0
33
+ Starting = 1
34
+ Succeeded = 2
35
+ Failed = 3
36
+
37
+
38
+ class EventSink(ABC):
39
+ """事件监听器基类 / Event sink base class
40
+
41
+ 用于接收 MaaFramework 各种事件回调的抽象基类。
42
+ 派生类包括 ResourceEventSink、ControllerEventSink、TaskerEventSink、ContextEventSink。
43
+ Abstract base class for receiving various event callbacks from MaaFramework.
44
+ Derived classes include ResourceEventSink, ControllerEventSink, TaskerEventSink, ContextEventSink.
45
+ """
46
+
47
+ def on_unknown_notification(self, instance, msg: str, details: dict):
48
+ """处理未知类型的通知 / Handle unknown notification
49
+
50
+ 当收到无法识别的通知时调用。
51
+ Called when an unrecognized notification is received.
52
+
53
+ Args:
54
+ instance: 相关实例对象 / Related instance object
55
+ msg: 消息类型 / Message type
56
+ details: 消息详情 / Message details
57
+ """
58
+ pass
59
+
60
+ def _on_raw_notification(self, handle: ctypes.c_void_p, msg: str, details: dict):
61
+ pass
62
+
63
+ @property
64
+ def c_callback(self) -> MaaEventCallback:
65
+ return self._c_sink_agent
66
+
67
+ @property
68
+ def c_callback_arg(self) -> ctypes.c_void_p:
69
+ return ctypes.c_void_p.from_buffer(ctypes.py_object(self))
70
+
71
+ @staticmethod
72
+ def _gen_c_param(
73
+ sink: "EventSink",
74
+ ) -> Tuple[MaaEventCallback, ctypes.c_void_p]:
75
+ return sink.c_callback, sink.c_callback_arg
76
+
77
+ @staticmethod
78
+ def _notification_type(message: str) -> NotificationType:
79
+ if message.endswith(".Starting"):
80
+ return NotificationType.Starting
81
+ elif message.endswith(".Succeeded"):
82
+ return NotificationType.Succeeded
83
+ elif message.endswith(".Failed"):
84
+ return NotificationType.Failed
85
+ else:
86
+ return NotificationType.Unknown
87
+
88
+ @staticmethod
89
+ @MaaEventCallback
90
+ def _c_sink_agent(
91
+ handle: ctypes.c_void_p,
92
+ msg: ctypes.c_char_p,
93
+ details_json: ctypes.c_char_p,
94
+ callback_arg: ctypes.c_void_p,
95
+ ):
96
+ if not callback_arg:
97
+ return
98
+
99
+ self: EventSink = ctypes.cast(callback_arg, ctypes.py_object).value
100
+
101
+ self._on_raw_notification(
102
+ handle, msg.decode(), json.loads(details_json.decode())
103
+ )
maa/job.py CHANGED
@@ -2,6 +2,13 @@ from .define import *
2
2
 
3
3
 
4
4
  class Job:
5
+ """异步作业句柄 / Asynchronous job handle
6
+
7
+ 用于跟踪和管理异步操作的状态,如资源加载、控制器连接等。
8
+ Used to track and manage the status of asynchronous operations
9
+ such as resource loading, controller connection, etc.
10
+ """
11
+
5
12
  _job_id: MaaId
6
13
 
7
14
  def __init__(self, job_id: MaaId, status_func, wait_func):
@@ -11,45 +18,114 @@ class Job:
11
18
 
12
19
  @property
13
20
  def job_id(self) -> int:
21
+ """获取作业 ID / Get job ID
22
+
23
+ Returns:
24
+ int: 作业 ID / Job ID
25
+ """
14
26
  return int(self._job_id)
15
27
 
16
28
  def wait(self) -> "Job":
29
+ """等待作业完成 / Wait for job completion
30
+
31
+ 阻塞当前线程直到作业完成
32
+ Blocks the current thread until the job is done
33
+
34
+ Returns:
35
+ Job: 返回自身,支持链式调用 / Returns self for method chaining
36
+ """
17
37
  self._wait_func(self._job_id)
18
38
  return self
19
39
 
20
40
  @property
21
41
  def status(self) -> Status:
42
+ """获取作业状态 / Get job status
43
+
44
+ Returns:
45
+ Status: 作业状态 / Job status
46
+ """
22
47
  return Status(self._status_func(self._job_id))
23
48
 
24
49
  @property
25
50
  def done(self) -> bool:
51
+ """判断作业是否已完成 / Check if job is done
52
+
53
+ Returns:
54
+ bool: 是否已完成(成功或失败) / Whether done (succeeded or failed)
55
+ """
26
56
  return self.status.done
27
57
 
28
58
  @property
29
59
  def succeeded(self) -> bool:
60
+ """判断作业是否成功 / Check if job succeeded
61
+
62
+ Returns:
63
+ bool: 是否成功 / Whether succeeded
64
+ """
30
65
  return self.status.succeeded
31
66
 
32
67
  @property
33
68
  def failed(self) -> bool:
69
+ """判断作业是否失败 / Check if job failed
70
+
71
+ Returns:
72
+ bool: 是否失败 / Whether failed
73
+ """
34
74
  return self.status.failed
35
75
 
36
76
  @property
37
77
  def pending(self) -> bool:
78
+ """判断作业是否等待中 / Check if job is pending
79
+
80
+ Returns:
81
+ bool: 是否等待中 / Whether pending
82
+ """
38
83
  return self.status.pending
39
84
 
40
85
  @property
41
86
  def running(self) -> bool:
87
+ """判断作业是否运行中 / Check if job is running
88
+
89
+ Returns:
90
+ bool: 是否运行中 / Whether running
91
+ """
42
92
  return self.status.running
43
93
 
44
94
 
45
95
  class JobWithResult(Job):
96
+ """带结果的异步作业句柄 / Asynchronous job handle with result
97
+
98
+ 继承自 Job,额外提供获取作业结果的功能。
99
+ Inherits from Job, additionally provides the ability to get job result.
100
+ """
101
+
46
102
  def __init__(self, job_id: MaaId, status_func, wait_func, get_func):
47
103
  super().__init__(job_id, status_func, wait_func)
48
104
  self._get_func = get_func
49
105
 
50
106
  def wait(self) -> "JobWithResult":
107
+ """等待作业完成 / Wait for job completion
108
+
109
+ Returns:
110
+ JobWithResult: 返回自身,支持链式调用 / Returns self for method chaining
111
+ """
51
112
  super().wait()
52
113
  return self
53
114
 
54
- def get(self):
115
+ def get(self, wait: bool = False):
116
+ """获取作业结果 / Get job result
117
+
118
+ Args:
119
+ wait: 是否在获取结果前等待作业完成,默认为 False。建议先显式调用 wait()(或传入 wait=True),
120
+ 确保异步操作已完成后再获取结果 / Whether to wait for job completion before getting result,
121
+ default is False. It's recommended to call wait() first (or pass wait=True) to ensure the
122
+ async operation is finished before getting the result.
123
+
124
+ Returns:
125
+ 作业执行结果,类型取决于具体作业 / Job execution result, type depends on the specific job
126
+ """
127
+
128
+ if wait:
129
+ self.wait()
130
+
55
131
  return self._get_func(self._job_id)
maa/library.py CHANGED
@@ -1,5 +1,4 @@
1
1
  import ctypes
2
- import ctypes.util
3
2
  import pathlib
4
3
  import platform
5
4
  from typing import Optional
@@ -8,6 +7,12 @@ from .define import *
8
7
 
9
8
 
10
9
  class Library:
10
+ """库加载管理器 / Library loading manager
11
+
12
+ 管理 MaaFramework 各动态库的加载和访问。
13
+ Manages loading and access to MaaFramework dynamic libraries.
14
+ """
15
+
11
16
  _is_agent_server: bool = False
12
17
 
13
18
  _framework: Optional[ctypes.CDLL] = None
@@ -16,9 +21,18 @@ class Library:
16
21
  _agent_server: Optional[ctypes.CDLL] = None
17
22
  _lib_type = None
18
23
 
19
- @staticmethod
20
- def open(path: pathlib.Path, agent_server: bool = False):
21
- if Library._api_properties_initialized:
24
+ @classmethod
25
+ def open(cls, path: pathlib.Path, agent_server: bool = False):
26
+ """打开并加载库 / Open and load libraries
27
+
28
+ Args:
29
+ path: 库文件所在目录 / Directory containing library files
30
+ agent_server: 是否以 AgentServer 模式加载 / Whether to load in AgentServer mode
31
+
32
+ Raises:
33
+ FileNotFoundError: 如果路径不存在
34
+ """
35
+ if cls._api_properties_initialized:
22
36
  return
23
37
 
24
38
  if not path.exists():
@@ -28,9 +42,9 @@ class Library:
28
42
  MACOS = "darwin"
29
43
  LINUX = "linux"
30
44
 
31
- Library._is_agent_server = agent_server
45
+ cls._is_agent_server = agent_server
32
46
 
33
- if not Library.is_agent_server():
47
+ if not cls.is_agent_server():
34
48
  framework_library = {
35
49
  WINDOWS: "MaaFramework.dll",
36
50
  MACOS: "libMaaFramework.dylib",
@@ -57,73 +71,127 @@ class Library:
57
71
  platform_type = platform.system().lower()
58
72
 
59
73
  if platform_type == WINDOWS:
60
- Library._lib_type = ctypes.WinDLL
74
+ cls._lib_type = ctypes.WinDLL
61
75
  else:
62
- Library._lib_type = ctypes.CDLL
76
+ cls._lib_type = ctypes.CDLL
77
+
78
+ if cls._lib_type is None:
79
+ raise
63
80
 
64
- if not Library.is_agent_server():
65
- Library.framework_libpath = path / framework_library[platform_type]
66
- Library.agent_client_libpath = path / agent_client_library[platform_type]
81
+ if not cls.is_agent_server():
82
+ cls.framework_libpath = path / framework_library[platform_type]
83
+ cls.agent_client_libpath = path / agent_client_library[platform_type]
67
84
  else:
68
- Library.agent_server_libpath = path / agent_server_library[platform_type]
85
+ cls.agent_server_libpath = path / agent_server_library[platform_type]
69
86
 
70
- Library.toolkit_libpath = path / toolkit_library[platform_type]
87
+ cls.toolkit_libpath = path / toolkit_library[platform_type]
71
88
 
72
- @staticmethod
73
- def framework() -> ctypes.CDLL:
74
- if not Library.is_agent_server():
75
- if not Library._framework:
76
- Library._framework = Library._lib_type(str(Library.framework_libpath)) # type: ignore
89
+ @classmethod
90
+ def framework(cls) -> Union["ctypes.CDLL", "ctypes.WinDLL"]:
91
+ """获取 MaaFramework 库 / Get MaaFramework library
77
92
 
78
- return Library._framework
93
+ Returns:
94
+ (ctypes.CDLL | ctypes.WinDLL): MaaFramework 动态库对象 / MaaFramework dynamic library object
95
+ """
96
+ if cls._lib_type is None:
97
+ raise RuntimeError("Library._lib_type is None!")
98
+
99
+ if not cls.is_agent_server():
100
+ if not cls._framework:
101
+ cls._framework = cls._lib_type(str(cls.framework_libpath))
102
+
103
+ if cls._framework is None:
104
+ raise RuntimeError("Library._framework is None!")
105
+
106
+ return cls._framework
79
107
  else:
80
- return Library.agent_server()
108
+ return cls.agent_server()
109
+
110
+ @classmethod
111
+ def toolkit(cls) -> Union["ctypes.CDLL", "ctypes.WinDLL"]:
112
+ """获取 MaaToolkit 库 / Get MaaToolkit library
81
113
 
82
- @staticmethod
83
- def toolkit() -> ctypes.CDLL:
84
- if not Library._toolkit:
85
- Library._toolkit = Library._lib_type(str(Library.toolkit_libpath)) # type: ignore
114
+ Returns:
115
+ (ctypes.CDLL | ctypes.WinDLL): MaaFramework 动态库对象 / MaaFramework dynamic library object
116
+ """
117
+ if cls._lib_type is None:
118
+ raise RuntimeError("Library._lib_type is None!")
86
119
 
87
- return Library._toolkit
120
+ if not cls._toolkit:
121
+ cls._toolkit = cls._lib_type(str(cls.toolkit_libpath))
88
122
 
89
- @staticmethod
90
- def agent_client() -> ctypes.CDLL:
91
- if Library.is_agent_server():
123
+ return cls._toolkit
124
+
125
+ @classmethod
126
+ def agent_client(cls) -> Union["ctypes.CDLL", "ctypes.WinDLL"]:
127
+ """获取 MaaAgentClient 库 / Get MaaAgentClient library
128
+
129
+ Returns:
130
+ (ctypes.CDLL | ctypes.WinDLL): MaaFramework 动态库对象 / MaaFramework dynamic library object
131
+
132
+ Raises:
133
+ ValueError: 如果在 AgentServer 模式下调用
134
+ """
135
+ if cls._lib_type is None:
136
+ raise RuntimeError("Library._lib_type is None!")
137
+
138
+ if cls.is_agent_server():
92
139
  raise ValueError("Agent server is not available in the current context.")
93
140
 
94
- if not Library._agent_client:
95
- Library._agent_client = Library._lib_type(str(Library.agent_client_libpath)) # type: ignore
141
+ if not cls._agent_client:
142
+ cls._agent_client = cls._lib_type(str(cls.agent_client_libpath))
143
+
144
+ return cls._agent_client
96
145
 
97
- return Library._agent_client
146
+ @classmethod
147
+ def agent_server(cls) -> Union["ctypes.CDLL", "ctypes.WinDLL"]:
148
+ """获取 MaaAgentServer 库 / Get MaaAgentServer library
98
149
 
99
- @staticmethod
100
- def agent_server() -> ctypes.CDLL:
101
- if not Library.is_agent_server():
150
+ Returns:
151
+ (ctypes.CDLL | ctypes.WinDLL): MaaAgentServer 动态库对象 / MaaAgentServer dynamic library object
152
+
153
+ Raises:
154
+ ValueError: 如果不在 AgentServer 模式下调用
155
+ """
156
+ if cls._lib_type is None:
157
+ raise RuntimeError("Library._lib_type is None!")
158
+
159
+ if not cls.is_agent_server():
102
160
  raise ValueError("Agent client is not available in the current context.")
103
161
 
104
- if not Library._agent_server:
105
- Library._agent_server = Library._lib_type(str(Library.agent_server_libpath)) # type: ignore
162
+ if not cls._agent_server:
163
+ cls._agent_server = cls._lib_type(str(cls.agent_server_libpath))
164
+
165
+ return cls._agent_server
166
+
167
+ @classmethod
168
+ def is_agent_server(cls) -> bool:
169
+ """判断是否为 AgentServer 模式 / Check if in AgentServer mode
106
170
 
107
- return Library._agent_server
171
+ Returns:
172
+ bool: 是否为 AgentServer 模式 / Whether in AgentServer mode
173
+ """
174
+ return cls._is_agent_server
108
175
 
109
- @staticmethod
110
- def is_agent_server() -> bool:
111
- return Library._is_agent_server
176
+ @classmethod
177
+ def version(cls) -> str:
178
+ """获取 MaaFramework 版本 / Get MaaFramework version
112
179
 
113
- @staticmethod
114
- def version() -> str:
115
- Library._set_api_properties()
180
+ Returns:
181
+ str: 版本字符串 / Version string
182
+ """
183
+ cls._set_api_properties()
116
184
 
117
- return Library.framework().MaaVersion().decode()
185
+ return cls.framework().MaaVersion().decode()
118
186
 
119
187
  _api_properties_initialized: bool = False
120
188
 
121
- @staticmethod
122
- def _set_api_properties():
123
- if Library._api_properties_initialized:
189
+ @classmethod
190
+ def _set_api_properties(cls):
191
+ if cls._api_properties_initialized:
124
192
  return
125
193
 
126
- Library._api_properties_initialized = True
194
+ cls._api_properties_initialized = True
127
195
 
128
- Library.framework().MaaVersion.restype = ctypes.c_char_p
129
- Library.framework().MaaVersion.argtypes = []
196
+ cls.framework().MaaVersion.restype = ctypes.c_char_p
197
+ cls.framework().MaaVersion.argtypes = []