butterbot-python 3.1.0.dev1__py3-none-any.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.
- butterbot/__init__.py +15 -0
- butterbot/app/__init__.py +41 -0
- butterbot/app/bot_app.py +374 -0
- butterbot/app/config.py +156 -0
- butterbot/app/source_manager.py +367 -0
- butterbot/core/__init__.py +46 -0
- butterbot/core/api/__init__.py +9 -0
- butterbot/core/api/base_api.py +32 -0
- butterbot/core/context/README.md +1 -0
- butterbot/core/context/__init__.py +9 -0
- butterbot/core/context/api_registry.py +109 -0
- butterbot/core/context/app_context.py +51 -0
- butterbot/core/context/config_provider.py +14 -0
- butterbot/core/data/__init__.py +15 -0
- butterbot/core/data/base_data.py +29 -0
- butterbot/core/data/base_model.py +197 -0
- butterbot/core/event/README.md +1 -0
- butterbot/core/event/__init__.py +10 -0
- butterbot/core/event/event.py +27 -0
- butterbot/core/event/event_bus.py +276 -0
- butterbot/core/event/subscriber.py +130 -0
- butterbot/core/exceptions.py +90 -0
- butterbot/core/filter/__init__.py +11 -0
- butterbot/core/filter/base_filter.py +74 -0
- butterbot/core/source/README.md +1 -0
- butterbot/core/source/__init__.py +9 -0
- butterbot/core/source/base_source.py +134 -0
- butterbot/core/types/__init__.py +9 -0
- butterbot/core/types/base_type.py +74 -0
- butterbot/sources/__init__.py +1 -0
- butterbot/sources/bilibili/README.md +10 -0
- butterbot/sources/bilibili/__init__.py +20 -0
- butterbot/sources/bilibili/api/__init__.py +5 -0
- butterbot/sources/bilibili/api/bili_api.py +123 -0
- butterbot/sources/bilibili/data/__init__.py +52 -0
- butterbot/sources/bilibili/data/danmaku_gift_data.py +135 -0
- butterbot/sources/bilibili/data/danmaku_guard_data.py +54 -0
- butterbot/sources/bilibili/data/danmaku_msg_data.py +71 -0
- butterbot/sources/bilibili/data/dto/__init__.py +59 -0
- butterbot/sources/bilibili/data/dto/danmaku_gift_dto.py +193 -0
- butterbot/sources/bilibili/data/dto/danmaku_guard_buy_dto.py +54 -0
- butterbot/sources/bilibili/data/dto/danmaku_msg_dto.py +123 -0
- butterbot/sources/bilibili/data/dto/dynamic_dto.py +276 -0
- butterbot/sources/bilibili/data/dto/live_room_dto.py +169 -0
- butterbot/sources/bilibili/data/dto/video_part_dto.py +18 -0
- butterbot/sources/bilibili/data/dynamic_data.py +362 -0
- butterbot/sources/bilibili/data/live_room_data.py +162 -0
- butterbot/sources/bilibili/data/video_part.py +46 -0
- butterbot/sources/bilibili/source/__init__.py +15 -0
- butterbot/sources/bilibili/source/base_polling_source.py +130 -0
- butterbot/sources/bilibili/source/bili_danmaku_source.py +230 -0
- butterbot/sources/bilibili/source/bili_dynamic_source.py +135 -0
- butterbot/sources/bilibili/source/bili_live_source.py +137 -0
- butterbot/sources/bilibili/types/__init__.py +11 -0
- butterbot/sources/bilibili/types/bili_type.py +32 -0
- butterbot/sources/napcat/README.md +10 -0
- butterbot/sources/napcat/__init__.py +20 -0
- butterbot/sources/napcat/api/__init__.py +3 -0
- butterbot/sources/napcat/api/napcat_api.py +316 -0
- butterbot/sources/napcat/data/__init__.py +179 -0
- butterbot/sources/napcat/data/event_data.py +441 -0
- butterbot/sources/napcat/data/segment_data.py +432 -0
- butterbot/sources/napcat/events.py +91 -0
- butterbot/sources/napcat/filters/__init__.py +19 -0
- butterbot/sources/napcat/filters/filters.py +202 -0
- butterbot/sources/napcat/source/__init__.py +5 -0
- butterbot/sources/napcat/source/napcat_source.py +58 -0
- butterbot/sources/napcat/types/__init__.py +5 -0
- butterbot/sources/napcat/types/napcat_type.py +61 -0
- butterbot/utils/README.md +15 -0
- butterbot/utils/__init__.py +11 -0
- butterbot/utils/data_pair.py +27 -0
- butterbot/utils/logging_config.py +521 -0
- butterbot/utils/terminal.py +308 -0
- butterbot/utils/websocket.py +1270 -0
- butterbot_python-3.1.0.dev1.dist-info/METADATA +769 -0
- butterbot_python-3.1.0.dev1.dist-info/RECORD +79 -0
- butterbot_python-3.1.0.dev1.dist-info/WHEEL +4 -0
- butterbot_python-3.1.0.dev1.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from .api import (
|
|
2
|
+
NapcatApi,
|
|
3
|
+
NapcatConfig,
|
|
4
|
+
)
|
|
5
|
+
from .source import (
|
|
6
|
+
NapcatSource,
|
|
7
|
+
)
|
|
8
|
+
from .types import (
|
|
9
|
+
NapcatType,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
# API类
|
|
14
|
+
"NapcatApi",
|
|
15
|
+
"NapcatConfig",
|
|
16
|
+
# 事件源类
|
|
17
|
+
"NapcatSource",
|
|
18
|
+
# 数据类型类
|
|
19
|
+
"NapcatType",
|
|
20
|
+
]
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
from collections.abc import Awaitable, Callable
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from logging import getLogger
|
|
6
|
+
from typing import Any
|
|
7
|
+
from uuid import uuid4
|
|
8
|
+
|
|
9
|
+
from butterbot.core.api import BaseApi
|
|
10
|
+
from butterbot.core.context import ApiRegistry
|
|
11
|
+
from butterbot.utils import AsyncWebSocketClient, ListenerId, MessageType
|
|
12
|
+
from butterbot.utils.websocket import ListenerClosedError, ListenerEvictedError
|
|
13
|
+
|
|
14
|
+
_log = getLogger("NapcatApi")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class NapcatConfig:
|
|
19
|
+
"""Napcat 客户端配置
|
|
20
|
+
|
|
21
|
+
Attributes:
|
|
22
|
+
url: WebSocket 连接地址
|
|
23
|
+
token: 认证 Token(可选)
|
|
24
|
+
heartbeat: 心跳间隔(秒)
|
|
25
|
+
reconnect_attempts: 重连尝试次数
|
|
26
|
+
receive_timeout: 接收超时时间(秒)
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
url: str
|
|
30
|
+
"""WebSocket 连接地址"""
|
|
31
|
+
token: str | None = None
|
|
32
|
+
"""认证 Token(可选)"""
|
|
33
|
+
heartbeat: float = 30.0
|
|
34
|
+
"""心跳间隔(秒)"""
|
|
35
|
+
reconnect_attempts: int = 5
|
|
36
|
+
"""重连尝试次数"""
|
|
37
|
+
receive_timeout: float = 60.0
|
|
38
|
+
"""接收超时时间(秒)"""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class NapcatClient:
|
|
42
|
+
"""Napcat WebSocket 客户端,用于与 Napcat QQ Bot 进行通信"""
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def create(cls, config: NapcatConfig) -> "NapcatClient":
|
|
46
|
+
"""从配置创建 NapcatClient 实例
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
config: napcat 配置
|
|
50
|
+
"""
|
|
51
|
+
napcat_config: NapcatConfig = config
|
|
52
|
+
headers = {}
|
|
53
|
+
|
|
54
|
+
if napcat_config.token:
|
|
55
|
+
headers["Authorization"] = napcat_config.token
|
|
56
|
+
|
|
57
|
+
return cls(
|
|
58
|
+
url=napcat_config.url,
|
|
59
|
+
headers=headers,
|
|
60
|
+
heartbeat=napcat_config.heartbeat,
|
|
61
|
+
reconnect_attempts=napcat_config.reconnect_attempts,
|
|
62
|
+
receive_timeout=napcat_config.receive_timeout,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def __init__(
|
|
66
|
+
self,
|
|
67
|
+
url: str,
|
|
68
|
+
headers: dict[str, str] | None = None,
|
|
69
|
+
heartbeat: float = 30.0,
|
|
70
|
+
reconnect_attempts: int = 5,
|
|
71
|
+
receive_timeout: float = 60.0,
|
|
72
|
+
):
|
|
73
|
+
"""初始化 Napcat 客户端
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
url: WebSocket 连接地址
|
|
77
|
+
headers: 请求头,通常包含 Authorization
|
|
78
|
+
heartbeat: 心跳间隔
|
|
79
|
+
reconnect_attempts: 重连尝试次数
|
|
80
|
+
receive_timeout: 接收超时时间
|
|
81
|
+
"""
|
|
82
|
+
self.url = url
|
|
83
|
+
self._handler: Callable[[dict[str, Any]], Awaitable[None]] | None = None
|
|
84
|
+
self.timeout = receive_timeout
|
|
85
|
+
self.client = AsyncWebSocketClient(
|
|
86
|
+
uri=url,
|
|
87
|
+
logger=_log,
|
|
88
|
+
headers=headers or {},
|
|
89
|
+
heartbeat=heartbeat,
|
|
90
|
+
reconnect_attempts=reconnect_attempts,
|
|
91
|
+
receive_timeout=receive_timeout,
|
|
92
|
+
)
|
|
93
|
+
self._task: asyncio.Task | None = None
|
|
94
|
+
self._listener_id: ListenerId | None = None
|
|
95
|
+
self._pending_requests: dict[str, asyncio.Future[dict[str, Any]]] = {}
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def pending_requests(self) -> int:
|
|
99
|
+
"""当前等待 echo 响应的请求数量."""
|
|
100
|
+
return len(self._pending_requests)
|
|
101
|
+
|
|
102
|
+
def set_handler(self, handler: Callable[[dict[str, Any]], Awaitable[None]]):
|
|
103
|
+
"""设置消息处理函数
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
handler: 消息处理函数,必须是异步函数,接受一个 dict 参数
|
|
107
|
+
"""
|
|
108
|
+
if not asyncio.iscoroutinefunction(handler):
|
|
109
|
+
raise TypeError("handler must be an async function")
|
|
110
|
+
self._handler = handler
|
|
111
|
+
|
|
112
|
+
async def start(self):
|
|
113
|
+
"""启动客户端并创建监听器"""
|
|
114
|
+
if not self._handler:
|
|
115
|
+
raise RuntimeError(
|
|
116
|
+
"消息处理函数未设置,请先调用 set_handler() 设置处理函数"
|
|
117
|
+
)
|
|
118
|
+
await self.client.start()
|
|
119
|
+
self._listener_id = await self.client.create_listener()
|
|
120
|
+
self._task = asyncio.create_task(self._process_messages())
|
|
121
|
+
_log.info("Napcat client started with listener: %s", self._listener_id)
|
|
122
|
+
|
|
123
|
+
async def stop(self):
|
|
124
|
+
"""停止客户端(幂等,可被 on_stop 与 ApiRegistry.aclose_all 重复调用)"""
|
|
125
|
+
pending = list(self._pending_requests.values())
|
|
126
|
+
self._pending_requests.clear()
|
|
127
|
+
for future in pending:
|
|
128
|
+
if not future.done():
|
|
129
|
+
future.cancel()
|
|
130
|
+
|
|
131
|
+
task = self._task
|
|
132
|
+
self._task = None
|
|
133
|
+
if task and not task.done():
|
|
134
|
+
try:
|
|
135
|
+
task.cancel()
|
|
136
|
+
await task
|
|
137
|
+
except asyncio.CancelledError:
|
|
138
|
+
# 任务被取消是预期行为,忽略异常
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
listener_id = self._listener_id
|
|
142
|
+
self._listener_id = None
|
|
143
|
+
if listener_id:
|
|
144
|
+
await self.client.remove_listener(listener_id)
|
|
145
|
+
|
|
146
|
+
await self.client.stop()
|
|
147
|
+
_log.info("Napcat client stopped")
|
|
148
|
+
|
|
149
|
+
async def send_request(self, message: dict) -> dict | None:
|
|
150
|
+
"""发送请求到服务器
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
message: 请求内容,Dict
|
|
154
|
+
"""
|
|
155
|
+
echo = str(uuid4())
|
|
156
|
+
payload = dict(message)
|
|
157
|
+
payload["echo"] = echo
|
|
158
|
+
future = asyncio.get_running_loop().create_future()
|
|
159
|
+
self._pending_requests[echo] = future
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
_log.debug("发送请求: action=%s, echo=%s", payload.get("action"), echo)
|
|
163
|
+
await self.client.send(payload)
|
|
164
|
+
_log.debug("发送请求%s", echo)
|
|
165
|
+
return await asyncio.wait_for(future, timeout=self.timeout)
|
|
166
|
+
except asyncio.CancelledError:
|
|
167
|
+
_log.debug("请求 %s 被取消", echo)
|
|
168
|
+
raise
|
|
169
|
+
finally:
|
|
170
|
+
registered = self._pending_requests.pop(echo, None)
|
|
171
|
+
if registered is not None and not registered.done():
|
|
172
|
+
registered.cancel()
|
|
173
|
+
|
|
174
|
+
def _resolve_response(self, data: dict[str, Any]) -> bool:
|
|
175
|
+
"""按 echo 将响应投递给对应请求.
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
找到仍在等待的请求并完成其 Future 时返回 ``True``。
|
|
179
|
+
"""
|
|
180
|
+
echo = data.get("echo")
|
|
181
|
+
if echo is None:
|
|
182
|
+
return False
|
|
183
|
+
future = self._pending_requests.get(str(echo))
|
|
184
|
+
if future is None or future.done():
|
|
185
|
+
return False
|
|
186
|
+
future.set_result(data)
|
|
187
|
+
return True
|
|
188
|
+
|
|
189
|
+
async def _get_message(
|
|
190
|
+
self, listener_id: ListenerId | None = None
|
|
191
|
+
) -> tuple[Any, MessageType]:
|
|
192
|
+
"""获取一条消息(阻塞)
|
|
193
|
+
Returns:
|
|
194
|
+
(消息内容, 消息类型) 元组
|
|
195
|
+
"""
|
|
196
|
+
_listener_id = self._listener_id if listener_id is None else listener_id
|
|
197
|
+
assert _listener_id is not None, "Listener not available"
|
|
198
|
+
return await self.client.get_message(_listener_id, self.timeout)
|
|
199
|
+
|
|
200
|
+
async def _process_messages(self):
|
|
201
|
+
"""持续处理消息(事件循环)"""
|
|
202
|
+
_log.info("Started processing messages")
|
|
203
|
+
|
|
204
|
+
try:
|
|
205
|
+
while self.client.running:
|
|
206
|
+
try:
|
|
207
|
+
message, msg_type = await self._get_message()
|
|
208
|
+
|
|
209
|
+
if msg_type == MessageType.Text:
|
|
210
|
+
# 解析 JSON 消息
|
|
211
|
+
try:
|
|
212
|
+
data: dict = json.loads(message)
|
|
213
|
+
if data.get("echo") is not None:
|
|
214
|
+
if not self._resolve_response(data):
|
|
215
|
+
_log.debug(
|
|
216
|
+
"收到无等待者的响应: echo=%s", data.get("echo")
|
|
217
|
+
)
|
|
218
|
+
# 带 echo 的响应不进入事件 handler
|
|
219
|
+
continue
|
|
220
|
+
_log.debug(data)
|
|
221
|
+
# noinspection PyCallingNonCallable
|
|
222
|
+
assert self._handler is not None
|
|
223
|
+
await self._handler(
|
|
224
|
+
data
|
|
225
|
+
) # post_type: ignore (运行时设置 handler)
|
|
226
|
+
except json.JSONDecodeError:
|
|
227
|
+
_log.error("Failed to parse message: %s", message)
|
|
228
|
+
except Exception as e:
|
|
229
|
+
_log.error("Handler error: %s", e)
|
|
230
|
+
elif msg_type == MessageType.Close:
|
|
231
|
+
_log.warning("Received close message")
|
|
232
|
+
break
|
|
233
|
+
|
|
234
|
+
except TimeoutError:
|
|
235
|
+
# 超时是正常的,继续等待
|
|
236
|
+
continue
|
|
237
|
+
except (ListenerClosedError, ListenerEvictedError) as e:
|
|
238
|
+
# 监听器已关闭或被驱逐:这条 while 再转下去只会立刻拿到
|
|
239
|
+
# 同一个异常,变成不带任何 sleep 的 100% CPU 空转。
|
|
240
|
+
_log.warning("监听器不可用,停止消息处理: %s", e)
|
|
241
|
+
break
|
|
242
|
+
except Exception as e:
|
|
243
|
+
_log.error("Error processing message: %s", e)
|
|
244
|
+
except asyncio.CancelledError:
|
|
245
|
+
# 任务被取消(stop() 调用),优雅退出
|
|
246
|
+
_log.info("Message processing stopped")
|
|
247
|
+
|
|
248
|
+
async def __aenter__(self):
|
|
249
|
+
"""异步上下文管理器入口"""
|
|
250
|
+
await self.start()
|
|
251
|
+
return self
|
|
252
|
+
|
|
253
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
254
|
+
"""异步上下文管理器出口"""
|
|
255
|
+
await self.stop()
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class NapcatApi(BaseApi):
|
|
259
|
+
"""Napcat API,提供与 Napcat QQ Bot 交互的接口"""
|
|
260
|
+
|
|
261
|
+
@classmethod
|
|
262
|
+
def create(cls, ctx: ApiRegistry, config_key: str = "napcat") -> "NapcatApi":
|
|
263
|
+
"""
|
|
264
|
+
从上下文创建 NapcatApi 实例
|
|
265
|
+
Args:
|
|
266
|
+
ctx: API 上下文
|
|
267
|
+
config_key: 配置键
|
|
268
|
+
|
|
269
|
+
Raises:
|
|
270
|
+
ConfigError: 缺少 ``config_key`` 对应的 napcat 配置。
|
|
271
|
+
napcat 必须有 url/token 才能连接,配置缺失时用 require_config
|
|
272
|
+
直接报错,而不是把 None 一路带到深处变成
|
|
273
|
+
``AttributeError: 'NoneType' object has no attribute 'token'``。
|
|
274
|
+
"""
|
|
275
|
+
return cls(ctx.require_config(config_key))
|
|
276
|
+
|
|
277
|
+
def __init__(self, config: NapcatConfig):
|
|
278
|
+
self.client = NapcatClient.create(config)
|
|
279
|
+
|
|
280
|
+
async def aclose(self) -> None:
|
|
281
|
+
"""释放 WebSocket 连接与后台任务(由 ApiRegistry.aclose_all 调用)."""
|
|
282
|
+
await self.client.stop()
|
|
283
|
+
|
|
284
|
+
def set_handler(self, handler: Callable[[dict[str, Any]], Awaitable[None]]):
|
|
285
|
+
"""设置消息处理函数"""
|
|
286
|
+
self.client.set_handler(handler)
|
|
287
|
+
|
|
288
|
+
async def start(self):
|
|
289
|
+
"""启动客户端"""
|
|
290
|
+
await self.client.start()
|
|
291
|
+
|
|
292
|
+
async def stop(self):
|
|
293
|
+
"""停止客户端"""
|
|
294
|
+
await self.client.stop()
|
|
295
|
+
|
|
296
|
+
def get_metrics(self) -> dict:
|
|
297
|
+
"""获取客户端指标"""
|
|
298
|
+
return self.client.client.get_metrics()
|
|
299
|
+
|
|
300
|
+
async def send_request(self, message: dict) -> dict | None:
|
|
301
|
+
"""发送请求到服务器"""
|
|
302
|
+
return await self.client.send_request(message)
|
|
303
|
+
|
|
304
|
+
# ================== 业务接口 ================== #
|
|
305
|
+
|
|
306
|
+
async def send_group_message(
|
|
307
|
+
self, group_id: int, message: list[dict]
|
|
308
|
+
) -> dict | None:
|
|
309
|
+
"""发送群消息"""
|
|
310
|
+
results = await self.send_request(
|
|
311
|
+
{
|
|
312
|
+
"action": "send_group_msg",
|
|
313
|
+
"params": {"group_id": group_id, "message": message},
|
|
314
|
+
}
|
|
315
|
+
)
|
|
316
|
+
return results
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"""
|
|
2
|
+
NapCat OneBot11 数据模型
|
|
3
|
+
|
|
4
|
+
包含消息段和事件的数据模型定义
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .event_data import (
|
|
8
|
+
EmojiLike,
|
|
9
|
+
FileInfo,
|
|
10
|
+
# 嵌套数据类
|
|
11
|
+
FriendSender,
|
|
12
|
+
GroupSender,
|
|
13
|
+
HeartbeatStatus,
|
|
14
|
+
# 事件基类
|
|
15
|
+
NapcatData,
|
|
16
|
+
NapcatFriendAddNoticeData,
|
|
17
|
+
NapcatFriendRecallNoticeData,
|
|
18
|
+
NapcatFriendRequestData,
|
|
19
|
+
NapcatGroupAdminNoticeData,
|
|
20
|
+
NapcatGroupBanNoticeData,
|
|
21
|
+
NapcatGroupCardNoticeData,
|
|
22
|
+
NapcatGroupDecreaseNoticeData,
|
|
23
|
+
NapcatGroupEssenceNoticeData,
|
|
24
|
+
NapcatGroupIncreaseNoticeData,
|
|
25
|
+
NapcatGroupMessageData,
|
|
26
|
+
NapcatGroupMessageSentData,
|
|
27
|
+
NapcatGroupMsgEmojiLikeNoticeData,
|
|
28
|
+
NapcatGroupRecallNoticeData,
|
|
29
|
+
NapcatGroupRequestData,
|
|
30
|
+
NapcatGroupUploadNoticeData,
|
|
31
|
+
NapcatHeartbeatMetaData,
|
|
32
|
+
NapcatHonorNotifyData,
|
|
33
|
+
NapcatLifecycleMetaData,
|
|
34
|
+
NapcatLuckyKingNotifyData,
|
|
35
|
+
# 消息事件
|
|
36
|
+
NapcatMessageData,
|
|
37
|
+
NapcatMessageSentData,
|
|
38
|
+
# 元事件
|
|
39
|
+
NapcatMetaData,
|
|
40
|
+
# 通知事件
|
|
41
|
+
NapcatNoticeData,
|
|
42
|
+
NapcatNotifyData,
|
|
43
|
+
NapcatPokeNotifyData,
|
|
44
|
+
NapcatPrivateMessageData,
|
|
45
|
+
NapcatPrivateMessageSentData,
|
|
46
|
+
NapcatReactionNoticeData,
|
|
47
|
+
# 请求事件
|
|
48
|
+
NapcatRequestData,
|
|
49
|
+
)
|
|
50
|
+
from .segment_data import (
|
|
51
|
+
AnonymousData,
|
|
52
|
+
AnonymousNode,
|
|
53
|
+
AtData,
|
|
54
|
+
AtNode,
|
|
55
|
+
ContactData,
|
|
56
|
+
ContactNode,
|
|
57
|
+
DiceData,
|
|
58
|
+
DiceNode,
|
|
59
|
+
FaceData,
|
|
60
|
+
FaceNode,
|
|
61
|
+
FileData,
|
|
62
|
+
FileNode,
|
|
63
|
+
ForwardData,
|
|
64
|
+
ForwardNode,
|
|
65
|
+
ImageData,
|
|
66
|
+
ImageNode,
|
|
67
|
+
JsonData,
|
|
68
|
+
JsonNode,
|
|
69
|
+
LocationData,
|
|
70
|
+
LocationNode,
|
|
71
|
+
# 消息段基类与子类
|
|
72
|
+
MessageNode,
|
|
73
|
+
MusicData,
|
|
74
|
+
MusicNode,
|
|
75
|
+
NodeData,
|
|
76
|
+
NodeNode,
|
|
77
|
+
PokeData,
|
|
78
|
+
PokeNode,
|
|
79
|
+
RecordData,
|
|
80
|
+
RecordNode,
|
|
81
|
+
ReplyData,
|
|
82
|
+
ReplyNode,
|
|
83
|
+
RpsData,
|
|
84
|
+
RpsNode,
|
|
85
|
+
ShakeData,
|
|
86
|
+
ShakeNode,
|
|
87
|
+
ShareData,
|
|
88
|
+
ShareNode,
|
|
89
|
+
# 嵌套数据类
|
|
90
|
+
TextData,
|
|
91
|
+
TextNode,
|
|
92
|
+
VideoData,
|
|
93
|
+
VideoNode,
|
|
94
|
+
XmlData,
|
|
95
|
+
XmlNode,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
__all__ = [
|
|
99
|
+
"AnonymousData",
|
|
100
|
+
"AnonymousNode",
|
|
101
|
+
"AtData",
|
|
102
|
+
"AtNode",
|
|
103
|
+
"ContactData",
|
|
104
|
+
"ContactNode",
|
|
105
|
+
"DiceData",
|
|
106
|
+
"DiceNode",
|
|
107
|
+
"EmojiLike",
|
|
108
|
+
"FaceData",
|
|
109
|
+
"FaceNode",
|
|
110
|
+
"FileData",
|
|
111
|
+
"FileInfo",
|
|
112
|
+
"FileNode",
|
|
113
|
+
"ForwardData",
|
|
114
|
+
"ForwardNode",
|
|
115
|
+
# event_data
|
|
116
|
+
"FriendSender",
|
|
117
|
+
"GroupSender",
|
|
118
|
+
"HeartbeatStatus",
|
|
119
|
+
"ImageData",
|
|
120
|
+
"ImageNode",
|
|
121
|
+
"JsonData",
|
|
122
|
+
"JsonNode",
|
|
123
|
+
"LocationData",
|
|
124
|
+
"LocationNode",
|
|
125
|
+
"MessageNode",
|
|
126
|
+
"MusicData",
|
|
127
|
+
"MusicNode",
|
|
128
|
+
"NapcatData",
|
|
129
|
+
"NapcatFriendAddNoticeData",
|
|
130
|
+
"NapcatFriendRecallNoticeData",
|
|
131
|
+
"NapcatFriendRequestData",
|
|
132
|
+
"NapcatGroupAdminNoticeData",
|
|
133
|
+
"NapcatGroupBanNoticeData",
|
|
134
|
+
"NapcatGroupCardNoticeData",
|
|
135
|
+
"NapcatGroupDecreaseNoticeData",
|
|
136
|
+
"NapcatGroupEssenceNoticeData",
|
|
137
|
+
"NapcatGroupIncreaseNoticeData",
|
|
138
|
+
"NapcatGroupMessageData",
|
|
139
|
+
"NapcatGroupMessageSentData",
|
|
140
|
+
"NapcatGroupMsgEmojiLikeNoticeData",
|
|
141
|
+
"NapcatGroupRecallNoticeData",
|
|
142
|
+
"NapcatGroupRequestData",
|
|
143
|
+
"NapcatGroupUploadNoticeData",
|
|
144
|
+
"NapcatHeartbeatMetaData",
|
|
145
|
+
"NapcatHonorNotifyData",
|
|
146
|
+
"NapcatLifecycleMetaData",
|
|
147
|
+
"NapcatLuckyKingNotifyData",
|
|
148
|
+
"NapcatMessageData",
|
|
149
|
+
"NapcatMessageSentData",
|
|
150
|
+
"NapcatMetaData",
|
|
151
|
+
"NapcatNoticeData",
|
|
152
|
+
"NapcatNotifyData",
|
|
153
|
+
"NapcatPokeNotifyData",
|
|
154
|
+
"NapcatPrivateMessageData",
|
|
155
|
+
"NapcatPrivateMessageSentData",
|
|
156
|
+
"NapcatReactionNoticeData",
|
|
157
|
+
"NapcatRequestData",
|
|
158
|
+
"NodeData",
|
|
159
|
+
"NodeNode",
|
|
160
|
+
"PokeData",
|
|
161
|
+
"PokeNode",
|
|
162
|
+
"RecordData",
|
|
163
|
+
"RecordNode",
|
|
164
|
+
"ReplyData",
|
|
165
|
+
"ReplyNode",
|
|
166
|
+
"RpsData",
|
|
167
|
+
"RpsNode",
|
|
168
|
+
"ShakeData",
|
|
169
|
+
"ShakeNode",
|
|
170
|
+
"ShareData",
|
|
171
|
+
"ShareNode",
|
|
172
|
+
# segment_data
|
|
173
|
+
"TextData",
|
|
174
|
+
"TextNode",
|
|
175
|
+
"VideoData",
|
|
176
|
+
"VideoNode",
|
|
177
|
+
"XmlData",
|
|
178
|
+
"XmlNode",
|
|
179
|
+
]
|