@sophiacyl/dsh-plugin-waves 0.0.0-stage → 0.1.0-beta.2
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.
- package/DSH-GO-VERIFICATION.md +57 -0
- package/ICON.png +0 -0
- package/LICENSE +674 -0
- package/README.md +251 -2
- package/cordis.patch.yml +8 -0
- package/install.ps1 +0 -0
- package/install.sh +209 -0
- package/lib/client.js +1511 -0
- package/lib/host/aliashint.js +70 -0
- package/lib/host/attachments.js +25 -0
- package/lib/host/command.js +34 -0
- package/lib/host/consts.js +16 -0
- package/lib/host/dataguide.js +35 -0
- package/lib/host/imagebridge.js +41 -0
- package/lib/host/native-result.js +91 -0
- package/lib/host/native.js +191 -0
- package/lib/host/proxy.js +59 -0
- package/lib/host/results.js +67 -0
- package/lib/host/service.js +263 -0
- package/lib/host/tool.js +185 -0
- package/lib/host/troubleshoot.js +31 -0
- package/lib/host/worldbook.js +80 -0
- package/lib/index.js +74 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +136 -4
- package/service/ICON.png +0 -0
- package/service/ai/AI_DATA.md +221 -0
- package/service/knowledge/additional/manual.jsonl +5 -0
- package/service/knowledge/wiki/baike.jsonl +1231 -0
- package/service/knowledge/wiki/chengjiu.jsonl +36 -0
- package/service/knowledge/wiki/gonglve.jsonl +383 -0
- package/service/knowledge/wiki/huodong.jsonl +427 -0
- package/service/knowledge/wiki/renwu.jsonl +412 -0
- package/service/knowledge/wiki/tujian.jsonl +2889 -0
- package/service/knowledge/wiki/zixun.jsonl +47 -0
- package/service/plugins/__init__.py +0 -0
- package/service/pyproject.toml +40 -0
- package/service/rover/__init__.py +0 -0
- package/service/rover/ai_core/__init__.py +0 -0
- package/service/rover/ai_core/models.py +50 -0
- package/service/rover/ai_core/rag/__init__.py +5 -0
- package/service/rover/ai_core/rag/knowledge.py +23 -0
- package/service/rover/ai_core/register.py +86 -0
- package/service/rover/ai_core/resource.py +6 -0
- package/service/rover/ai_core/skills/__init__.py +0 -0
- package/service/rover/ai_core/skills/operations.py +8 -0
- package/service/rover/api.py +720 -0
- package/service/rover/api_render.py +161 -0
- package/service/rover/app_life.py +154 -0
- package/service/rover/aps.py +47 -0
- package/service/rover/avatar.py +85 -0
- package/service/rover/bot.py +133 -0
- package/service/rover/builtin.py +152 -0
- package/service/rover/cards/__init__.py +26 -0
- package/service/rover/cards/_shared.py +129 -0
- package/service/rover/cards/char_list.py +258 -0
- package/service/rover/cards/char_panel.py +1353 -0
- package/service/rover/cards/echo_list.py +206 -0
- package/service/rover/cards/matrix_roles.py +25 -0
- package/service/rover/cards/rank_boards.py +714 -0
- package/service/rover/cards/rank_total.py +664 -0
- package/service/rover/compat.py +215 -0
- package/service/rover/config.py +163 -0
- package/service/rover/custom_panel.py +220 -0
- package/service/rover/data_store.py +31 -0
- package/service/rover/gss.py +19 -0
- package/service/rover/handler.py +191 -0
- package/service/rover/help/__init__.py +0 -0
- package/service/rover/help/draw_new_plugin_help.py +332 -0
- package/service/rover/help/model.py +16 -0
- package/service/rover/help/utils.py +7 -0
- package/service/rover/hooks.py +420 -0
- package/service/rover/html_actions.py +236 -0
- package/service/rover/i18n.py +19 -0
- package/service/rover/knowledge.py +235 -0
- package/service/rover/logger.py +102 -0
- package/service/rover/main.py +33 -0
- package/service/rover/media.py +222 -0
- package/service/rover/message_models.py +23 -0
- package/service/rover/models.py +92 -0
- package/service/rover/native_media.py +64 -0
- package/service/rover/ocr.py +79 -0
- package/service/rover/pool.py +43 -0
- package/service/rover/restart.py +36 -0
- package/service/rover/segment.py +143 -0
- package/service/rover/server.py +131 -0
- package/service/rover/status/__init__.py +0 -0
- package/service/rover/status/models.py +10 -0
- package/service/rover/status/plugin_status.py +17 -0
- package/service/rover/subscribe.py +148 -0
- package/service/rover/sv.py +403 -0
- package/service/rover/templates/char_list.html +182 -0
- package/service/rover/templates/char_panel.html +465 -0
- package/service/rover/templates/echo_list.html +221 -0
- package/service/rover/templates/rank_all_total.html +193 -0
- package/service/rover/templates/rank_board.html +107 -0
- package/service/rover/templates/rank_level_total.html +57 -0
- package/service/rover/templates/rank_matrix_total.html +66 -0
- package/service/rover/templates/rank_phantom_total.html +180 -0
- package/service/rover/templates/rank_slash_total.html +38 -0
- package/service/rover/trigger.py +98 -0
- package/service/rover/utils/__init__.py +0 -0
- package/service/rover/utils/boardcast/__init__.py +0 -0
- package/service/rover/utils/boardcast/models.py +15 -0
- package/service/rover/utils/cookie_manager/__init__.py +0 -0
- package/service/rover/utils/cookie_manager/qrlogin.py +24 -0
- package/service/rover/utils/database/__init__.py +0 -0
- package/service/rover/utils/database/base_models.py +1771 -0
- package/service/rover/utils/database/models.py +80 -0
- package/service/rover/utils/database/startup.py +60 -0
- package/service/rover/utils/default_bg/bg.jpg +0 -0
- package/service/rover/utils/download_resource/__init__.py +0 -0
- package/service/rover/utils/download_resource/download_core.py +164 -0
- package/service/rover/utils/download_resource/download_file.py +46 -0
- package/service/rover/utils/fonts/__init__.py +0 -0
- package/service/rover/utils/fonts/fonts.py +33 -0
- package/service/rover/utils/image/__init__.py +0 -0
- package/service/rover/utils/image/convert.py +51 -0
- package/service/rover/utils/image/image_tools.py +30 -0
- package/service/rover/utils/image/utils.py +70 -0
- package/service/rover/utils/plugins_config/__init__.py +0 -0
- package/service/rover/utils/plugins_config/gs_config.py +506 -0
- package/service/rover/utils/plugins_config/models.py +182 -0
- package/service/rover/web_app.py +3 -0
- package/service/rover/webconsole/__init__.py +0 -0
- package/service/rover/webconsole/mount_app.py +26 -0
- package/service/tools/migrate.py +351 -0
- package/service/tools/regression.py +87 -0
- package/service/tools/smoke.py +63 -0
- package/service/tools/update_plugins.py +212 -0
- package/service/tools/verify_actions.py +104 -0
- package/service/tools/verify_card.py +82 -0
- package/service/tools/wwdata.py +665 -0
- package/tests/compat.test.js +181 -0
- package/tests/imagebridge.test.js +58 -0
- package/tests/media.test.js +68 -0
- package/tests/native.test.js +127 -0
- package/tests/runtime.test.js +69 -0
- package/tests/service.test.js +48 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
from typing import Dict, Literal, Optional, Sequence, Union
|
|
2
|
+
|
|
3
|
+
from rover.models import Event
|
|
4
|
+
from rover.utils.database.models import Subscribe
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class RoverSubscribeManager:
|
|
8
|
+
async def add_subscribe(
|
|
9
|
+
self,
|
|
10
|
+
subscribe_type: Literal["session", "single"],
|
|
11
|
+
task_name: str,
|
|
12
|
+
event: Event,
|
|
13
|
+
extra_message: Optional[str] = None,
|
|
14
|
+
uid: Optional[str] = None,
|
|
15
|
+
extra_data: Optional[str] = None,
|
|
16
|
+
):
|
|
17
|
+
"""📝简单介绍:
|
|
18
|
+
|
|
19
|
+
该方法允许向数据库添加一个订阅信息的持久化保存
|
|
20
|
+
|
|
21
|
+
注意`subscribe_type`参数必须为`session`或`single`
|
|
22
|
+
|
|
23
|
+
`session`模式下, 订阅都将在每个有效的session(group或direct)内独立存在 (公告推送)
|
|
24
|
+
|
|
25
|
+
`single`模式下, 同个session(group)可能同时存在多个订阅 (签到任务)
|
|
26
|
+
|
|
27
|
+
🌱参数:
|
|
28
|
+
|
|
29
|
+
🔹subscribe_type (`Literal['session', 'single']`):
|
|
30
|
+
'session'模式: 同个group/user下只存在一条订阅
|
|
31
|
+
'single'模式: 同个group下存在多条订阅, 同个user只存在一条订阅
|
|
32
|
+
|
|
33
|
+
🔹task_name (`str`):
|
|
34
|
+
订阅名称
|
|
35
|
+
|
|
36
|
+
🔹event (`Event`):
|
|
37
|
+
事件Event
|
|
38
|
+
|
|
39
|
+
🔹extra_message (`Optional[str]`, 默认是 `None`):
|
|
40
|
+
额外想要保存的信息, 例如推送信息或者数值阈值
|
|
41
|
+
|
|
42
|
+
🚀使用范例:
|
|
43
|
+
|
|
44
|
+
`await gs_subscribe.add_subscribe('single', '签到', event)`
|
|
45
|
+
"""
|
|
46
|
+
opt: Dict[str, Union[str, int, None]] = {
|
|
47
|
+
"bot_id": event.bot_id,
|
|
48
|
+
"task_name": task_name,
|
|
49
|
+
"uid": uid,
|
|
50
|
+
"WS_BOT_ID": event.WS_BOT_ID,
|
|
51
|
+
}
|
|
52
|
+
if subscribe_type == "session" and event.user_type == "group":
|
|
53
|
+
opt["group_id"] = event.group_id
|
|
54
|
+
opt["user_type"] = event.user_type
|
|
55
|
+
else:
|
|
56
|
+
opt["user_id"] = event.user_id
|
|
57
|
+
|
|
58
|
+
condi = await Subscribe.data_exist(
|
|
59
|
+
**opt,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
if not condi:
|
|
63
|
+
await Subscribe.full_insert_data(
|
|
64
|
+
user_id=event.user_id,
|
|
65
|
+
bot_id=event.bot_id,
|
|
66
|
+
group_id=event.group_id,
|
|
67
|
+
task_name=task_name,
|
|
68
|
+
bot_self_id=event.bot_self_id,
|
|
69
|
+
user_type=event.user_type,
|
|
70
|
+
extra_message=extra_message,
|
|
71
|
+
WS_BOT_ID=event.WS_BOT_ID,
|
|
72
|
+
uid=uid,
|
|
73
|
+
extra_data=extra_data,
|
|
74
|
+
msg_id=event.msg_id,
|
|
75
|
+
)
|
|
76
|
+
else:
|
|
77
|
+
upd = {}
|
|
78
|
+
for i in [
|
|
79
|
+
"user_id",
|
|
80
|
+
"bot_id",
|
|
81
|
+
"group_id",
|
|
82
|
+
"bot_self_id",
|
|
83
|
+
"user_type",
|
|
84
|
+
"WS_BOT_ID",
|
|
85
|
+
"msg_id",
|
|
86
|
+
]:
|
|
87
|
+
if i not in opt:
|
|
88
|
+
upd[i] = event.__getattribute__(i)
|
|
89
|
+
|
|
90
|
+
upd["extra_message"] = extra_message
|
|
91
|
+
upd["extra_data"] = extra_data
|
|
92
|
+
|
|
93
|
+
await Subscribe.update_data_by_data(
|
|
94
|
+
opt,
|
|
95
|
+
upd,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
async def get_subscribe(
|
|
99
|
+
self,
|
|
100
|
+
task_name: str,
|
|
101
|
+
user_id: Optional[str] = None,
|
|
102
|
+
bot_id: Optional[str] = None,
|
|
103
|
+
user_type: Optional[str] = None,
|
|
104
|
+
uid: Optional[str] = None,
|
|
105
|
+
WS_BOT_ID: Optional[str] = None,
|
|
106
|
+
):
|
|
107
|
+
params = {
|
|
108
|
+
"task_name": task_name,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if user_id and bot_id and user_type:
|
|
112
|
+
params["user_id"] = user_id
|
|
113
|
+
params["bot_id"] = bot_id
|
|
114
|
+
params["user_type"] = user_type
|
|
115
|
+
|
|
116
|
+
if uid:
|
|
117
|
+
params["uid"] = uid
|
|
118
|
+
|
|
119
|
+
if WS_BOT_ID:
|
|
120
|
+
params["WS_BOT_ID"] = WS_BOT_ID
|
|
121
|
+
|
|
122
|
+
all_data: Optional[Sequence[Subscribe]] = await Subscribe.select_rows(distinct=False, **params)
|
|
123
|
+
return all_data
|
|
124
|
+
|
|
125
|
+
async def delete_subscribe(
|
|
126
|
+
self,
|
|
127
|
+
subscribe_type: Literal["session", "single"],
|
|
128
|
+
task_name: str,
|
|
129
|
+
event: Event,
|
|
130
|
+
uid: Optional[str] = None,
|
|
131
|
+
WS_BOT_ID: Optional[str] = None,
|
|
132
|
+
):
|
|
133
|
+
params = {
|
|
134
|
+
"task_name": task_name,
|
|
135
|
+
}
|
|
136
|
+
if uid:
|
|
137
|
+
params["uid"] = uid
|
|
138
|
+
|
|
139
|
+
if WS_BOT_ID:
|
|
140
|
+
params["WS_BOT_ID"] = WS_BOT_ID
|
|
141
|
+
|
|
142
|
+
if subscribe_type == "session" and event.user_type == "group":
|
|
143
|
+
await Subscribe.delete_row(group_id=event.group_id, **params)
|
|
144
|
+
else:
|
|
145
|
+
await Subscribe.delete_row(user_id=event.user_id, **params)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
gs_subscribe = RoverSubscribeManager()
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
"""功能注册。插件用 Plugins/SV 声明命令, 触发器按前缀展开后进 SL 供分发器遍历。"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import traceback
|
|
6
|
+
from copy import deepcopy
|
|
7
|
+
from functools import wraps
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Callable, Dict, List, Literal, Optional, Set, Tuple, Union
|
|
10
|
+
|
|
11
|
+
from rover.logger import logger
|
|
12
|
+
from rover.models import Event
|
|
13
|
+
from rover.trigger import Trigger, TriggerType
|
|
14
|
+
|
|
15
|
+
_SERVICE_ROOT = Path(__file__).resolve().parents[1]
|
|
16
|
+
_PLUGINS_DIR = _SERVICE_ROOT / "plugins"
|
|
17
|
+
|
|
18
|
+
# file/meta/message 匹配不读 prefix, 展开只会产生等价副本导致重复执行
|
|
19
|
+
_PREFIXLESS_TYPES = frozenset({"file", "meta", "message"})
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class SVList:
|
|
23
|
+
def __init__(self):
|
|
24
|
+
self.lst: Dict[str, SV] = {}
|
|
25
|
+
self.plugins: Dict[str, Plugins] = {}
|
|
26
|
+
self.detail_lst: Dict[Plugins, List[SV]] = {}
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def get_lst(self):
|
|
30
|
+
return self.lst
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
SL = SVList()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _configured_prefix() -> Optional[List[str]]:
|
|
37
|
+
"""命令前缀由本地配置统一决定; 逗号分隔多个, 空表示不需要前缀。"""
|
|
38
|
+
import re
|
|
39
|
+
|
|
40
|
+
from rover.config import core_config
|
|
41
|
+
|
|
42
|
+
value = core_config.get_config("command_prefix")
|
|
43
|
+
if not isinstance(value, str):
|
|
44
|
+
return None
|
|
45
|
+
return [p for p in (x.strip() for x in re.split(r"[,,]", value)) if p]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _sv_overrides(sv_name: str) -> Dict:
|
|
49
|
+
from rover.config import core_config
|
|
50
|
+
|
|
51
|
+
table = core_config.get_config("sv")
|
|
52
|
+
if isinstance(table, dict):
|
|
53
|
+
one = table.get(sv_name)
|
|
54
|
+
if isinstance(one, dict):
|
|
55
|
+
return one
|
|
56
|
+
return {}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _caller_plugin_name() -> str:
|
|
60
|
+
"""插件名取 plugins 下一级目录名, 与上游的注册名一致。"""
|
|
61
|
+
for frame in reversed(traceback.extract_stack()[:-1]):
|
|
62
|
+
try:
|
|
63
|
+
rel = Path(frame.filename).resolve().relative_to(_PLUGINS_DIR)
|
|
64
|
+
except (ValueError, OSError):
|
|
65
|
+
continue
|
|
66
|
+
if rel.parts:
|
|
67
|
+
return rel.parts[0]
|
|
68
|
+
return "XutheringWavesUID"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def modify_func(func):
|
|
72
|
+
@wraps(func)
|
|
73
|
+
async def wrapper(bot, event: Event):
|
|
74
|
+
try:
|
|
75
|
+
return await func(bot, event)
|
|
76
|
+
except Exception as e:
|
|
77
|
+
logger.error(f"执行命令 {event.command} 时出现错误")
|
|
78
|
+
logger.exception(e)
|
|
79
|
+
|
|
80
|
+
return wrapper
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class Plugins:
|
|
84
|
+
def __new__(cls, *args, **kwargs):
|
|
85
|
+
name = args[0] if len(args) >= 1 else kwargs.get("name")
|
|
86
|
+
if name is None:
|
|
87
|
+
raise ValueError("Plugins.name is None!")
|
|
88
|
+
if name in SL.plugins and not kwargs.get("force"):
|
|
89
|
+
return SL.plugins[name]
|
|
90
|
+
_plugin = super().__new__(cls)
|
|
91
|
+
_plugin.__init__(*args, **kwargs)
|
|
92
|
+
SL.plugins[name] = _plugin
|
|
93
|
+
return _plugin
|
|
94
|
+
|
|
95
|
+
def __hash__(self) -> int:
|
|
96
|
+
return hash(f"{self.name}{self.priority}{self.pm}{self.area}")
|
|
97
|
+
|
|
98
|
+
def __eq__(self, other):
|
|
99
|
+
if isinstance(other, Plugins):
|
|
100
|
+
return (self.name, self.pm, self.priority) == (other.name, other.pm, other.priority)
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
def __init__(
|
|
104
|
+
self,
|
|
105
|
+
name: str = "",
|
|
106
|
+
pm: int = 6,
|
|
107
|
+
priority: int = 5,
|
|
108
|
+
enabled: bool = True,
|
|
109
|
+
area: Literal["GROUP", "DIRECT", "ALL", "SV"] = "SV",
|
|
110
|
+
black_list: List = [],
|
|
111
|
+
white_list: List = [],
|
|
112
|
+
sv: Dict = {},
|
|
113
|
+
prefix: Union[List[str], str] = [],
|
|
114
|
+
force_prefix: List[str] = [],
|
|
115
|
+
disable_force_prefix: bool = False,
|
|
116
|
+
allow_empty_prefix: Optional[bool] = None,
|
|
117
|
+
force: bool = False,
|
|
118
|
+
alias: List[str] = [],
|
|
119
|
+
):
|
|
120
|
+
if isinstance(prefix, str):
|
|
121
|
+
prefix = [prefix]
|
|
122
|
+
configured = _configured_prefix()
|
|
123
|
+
if configured is not None:
|
|
124
|
+
force_prefix = configured
|
|
125
|
+
prefix = []
|
|
126
|
+
disable_force_prefix = False
|
|
127
|
+
allow_empty_prefix = not configured
|
|
128
|
+
if allow_empty_prefix is None:
|
|
129
|
+
_pf = [p for p in prefix + force_prefix if p != ""]
|
|
130
|
+
allow_empty_prefix = not _pf
|
|
131
|
+
|
|
132
|
+
self.name = name
|
|
133
|
+
self.priority = priority
|
|
134
|
+
self.enabled = enabled
|
|
135
|
+
self.pm = pm
|
|
136
|
+
self.black_list = black_list
|
|
137
|
+
self.area = area
|
|
138
|
+
self.white_list = white_list
|
|
139
|
+
self.sv: Dict[str, SV] = {}
|
|
140
|
+
self.prefix = prefix
|
|
141
|
+
self.allow_empty_prefix = allow_empty_prefix
|
|
142
|
+
self.force_prefix = force_prefix
|
|
143
|
+
self.disable_force_prefix = disable_force_prefix
|
|
144
|
+
self.alias = alias
|
|
145
|
+
|
|
146
|
+
def set(self, is_lazy: bool = True, **kwargs):
|
|
147
|
+
for var, value in kwargs.items():
|
|
148
|
+
setattr(self, var, value)
|
|
149
|
+
|
|
150
|
+
def enable(self):
|
|
151
|
+
self.set(enabled=True)
|
|
152
|
+
|
|
153
|
+
def disable(self):
|
|
154
|
+
self.set(enabled=False)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class SV:
|
|
158
|
+
is_initialized = False
|
|
159
|
+
|
|
160
|
+
def __new__(cls, *args, **kwargs):
|
|
161
|
+
name = args[0] if len(args) >= 1 else kwargs.get("name")
|
|
162
|
+
if name is None:
|
|
163
|
+
raise ValueError("SV.name is None!")
|
|
164
|
+
if name in SL.lst:
|
|
165
|
+
return SL.lst[name]
|
|
166
|
+
_sv = super().__new__(cls)
|
|
167
|
+
SL.lst[name] = _sv
|
|
168
|
+
return _sv
|
|
169
|
+
|
|
170
|
+
def __init__(
|
|
171
|
+
self,
|
|
172
|
+
name: str = "",
|
|
173
|
+
pm: int = 6,
|
|
174
|
+
priority: int = 5,
|
|
175
|
+
enabled: bool = True,
|
|
176
|
+
area: Literal["GROUP", "DIRECT", "ALL"] = "ALL",
|
|
177
|
+
black_list: List = [],
|
|
178
|
+
white_list: List = [],
|
|
179
|
+
):
|
|
180
|
+
if self.is_initialized:
|
|
181
|
+
return
|
|
182
|
+
self.name = name
|
|
183
|
+
self.TL: Dict[str, Dict[str, Trigger]] = {}
|
|
184
|
+
self.is_initialized = True
|
|
185
|
+
self.self_plugin_name = plugins_name = _caller_plugin_name()
|
|
186
|
+
|
|
187
|
+
if plugins_name in SL.plugins:
|
|
188
|
+
plugins = SL.plugins[plugins_name]
|
|
189
|
+
else:
|
|
190
|
+
plugins = Plugins(name=plugins_name)
|
|
191
|
+
|
|
192
|
+
self.plugins = plugins
|
|
193
|
+
self.priority = priority
|
|
194
|
+
self.enabled = enabled
|
|
195
|
+
self.pm = pm
|
|
196
|
+
self.black_list = black_list
|
|
197
|
+
self.area = area
|
|
198
|
+
self.white_list = white_list
|
|
199
|
+
|
|
200
|
+
for key, value in _sv_overrides(name).items():
|
|
201
|
+
if hasattr(self, key):
|
|
202
|
+
setattr(self, key, value)
|
|
203
|
+
|
|
204
|
+
plugins.sv[name] = self
|
|
205
|
+
SL.detail_lst.setdefault(plugins, [])
|
|
206
|
+
if self not in SL.detail_lst[plugins]:
|
|
207
|
+
SL.detail_lst[plugins].append(self)
|
|
208
|
+
|
|
209
|
+
def set(self, is_lazy: bool = True, **kwargs):
|
|
210
|
+
for var, value in kwargs.items():
|
|
211
|
+
setattr(self, var, value)
|
|
212
|
+
|
|
213
|
+
def enable(self):
|
|
214
|
+
self.set(enabled=True)
|
|
215
|
+
|
|
216
|
+
def disable(self):
|
|
217
|
+
self.set(enabled=False)
|
|
218
|
+
|
|
219
|
+
def _on(
|
|
220
|
+
self,
|
|
221
|
+
type: TriggerType,
|
|
222
|
+
keyword: Union[str, Tuple[str, ...]],
|
|
223
|
+
block: bool = False,
|
|
224
|
+
to_me: bool = False,
|
|
225
|
+
prefix: bool = True,
|
|
226
|
+
to_ai: str = "",
|
|
227
|
+
):
|
|
228
|
+
def deco(func: Callable) -> Callable:
|
|
229
|
+
keyword_list = (keyword,) if isinstance(keyword, str) else keyword
|
|
230
|
+
|
|
231
|
+
_pp = deepcopy(self.plugins.prefix)
|
|
232
|
+
if "" in _pp:
|
|
233
|
+
_pp.remove("")
|
|
234
|
+
if not self.plugins.disable_force_prefix:
|
|
235
|
+
_pp.extend(self.plugins.force_prefix)
|
|
236
|
+
if self.plugins.allow_empty_prefix:
|
|
237
|
+
_pp.append("")
|
|
238
|
+
_pp = list(set(_pp))
|
|
239
|
+
|
|
240
|
+
for _k in keyword_list:
|
|
241
|
+
if _k in self.TL:
|
|
242
|
+
continue
|
|
243
|
+
if type not in self.TL:
|
|
244
|
+
self.TL[type] = {}
|
|
245
|
+
if prefix and _pp and type not in _PREFIXLESS_TYPES:
|
|
246
|
+
for _p in _pp:
|
|
247
|
+
self.TL[type][_p + _k] = Trigger(
|
|
248
|
+
type, _k, modify_func(func), _p, block, to_me
|
|
249
|
+
)
|
|
250
|
+
else:
|
|
251
|
+
self.TL[type][_k] = Trigger(type, _k, modify_func(func), "", block, to_me)
|
|
252
|
+
|
|
253
|
+
if to_ai.strip():
|
|
254
|
+
AI_COMMANDS.append(
|
|
255
|
+
{
|
|
256
|
+
"sv": self.name,
|
|
257
|
+
"plugin": self.self_plugin_name,
|
|
258
|
+
"type": type,
|
|
259
|
+
"keyword": list(keyword_list),
|
|
260
|
+
"desc": to_ai.strip(),
|
|
261
|
+
}
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
@wraps(func)
|
|
265
|
+
async def wrapper(bot, msg) -> Optional[Callable]:
|
|
266
|
+
return await func(bot, msg)
|
|
267
|
+
|
|
268
|
+
return wrapper
|
|
269
|
+
|
|
270
|
+
return deco
|
|
271
|
+
|
|
272
|
+
def on_fullmatch(
|
|
273
|
+
self,
|
|
274
|
+
keyword: Union[str, Tuple[str, ...]],
|
|
275
|
+
block: bool = False,
|
|
276
|
+
to_me: bool = False,
|
|
277
|
+
prefix: bool = True,
|
|
278
|
+
to_ai: str = "",
|
|
279
|
+
) -> Callable:
|
|
280
|
+
return self._on("fullmatch", keyword, block, to_me, prefix, to_ai=to_ai)
|
|
281
|
+
|
|
282
|
+
def on_prefix(
|
|
283
|
+
self,
|
|
284
|
+
keyword: Union[str, Tuple[str, ...]],
|
|
285
|
+
block: bool = False,
|
|
286
|
+
to_me: bool = False,
|
|
287
|
+
prefix: bool = True,
|
|
288
|
+
to_ai: str = "",
|
|
289
|
+
) -> Callable:
|
|
290
|
+
return self._on("prefix", keyword, block, to_me, prefix, to_ai=to_ai)
|
|
291
|
+
|
|
292
|
+
def on_suffix(
|
|
293
|
+
self,
|
|
294
|
+
keyword: Union[str, Tuple[str, ...]],
|
|
295
|
+
block: bool = False,
|
|
296
|
+
to_me: bool = False,
|
|
297
|
+
prefix: bool = True,
|
|
298
|
+
to_ai: str = "",
|
|
299
|
+
) -> Callable:
|
|
300
|
+
return self._on("suffix", keyword, block, to_me, prefix, to_ai=to_ai)
|
|
301
|
+
|
|
302
|
+
def on_keyword(
|
|
303
|
+
self,
|
|
304
|
+
keyword: Union[str, Tuple[str, ...]],
|
|
305
|
+
block: bool = False,
|
|
306
|
+
to_me: bool = False,
|
|
307
|
+
prefix: bool = True,
|
|
308
|
+
to_ai: str = "",
|
|
309
|
+
) -> Callable:
|
|
310
|
+
return self._on("keyword", keyword, block, to_me, prefix, to_ai=to_ai)
|
|
311
|
+
|
|
312
|
+
def on_command(
|
|
313
|
+
self,
|
|
314
|
+
keyword: Union[str, Tuple[str, ...]],
|
|
315
|
+
block: bool = False,
|
|
316
|
+
to_me: bool = False,
|
|
317
|
+
prefix: bool = True,
|
|
318
|
+
to_ai: str = "",
|
|
319
|
+
) -> Callable:
|
|
320
|
+
return self._on("command", keyword, block, to_me, prefix, to_ai=to_ai)
|
|
321
|
+
|
|
322
|
+
def on_file(
|
|
323
|
+
self,
|
|
324
|
+
file_type: Union[str, Tuple[str, ...]],
|
|
325
|
+
block: bool = False,
|
|
326
|
+
to_me: bool = False,
|
|
327
|
+
prefix: bool = False,
|
|
328
|
+
to_ai: str = "",
|
|
329
|
+
) -> Callable:
|
|
330
|
+
return self._on("file", file_type, block, to_me, prefix, to_ai=to_ai)
|
|
331
|
+
|
|
332
|
+
def on_regex(
|
|
333
|
+
self,
|
|
334
|
+
pattern: Union[str, Tuple[str, ...]],
|
|
335
|
+
block: bool = False,
|
|
336
|
+
to_me: bool = False,
|
|
337
|
+
prefix: bool = True,
|
|
338
|
+
to_ai: str = "",
|
|
339
|
+
) -> Callable:
|
|
340
|
+
return self._on("regex", pattern, block, to_me, prefix, to_ai=to_ai)
|
|
341
|
+
|
|
342
|
+
def on_message(
|
|
343
|
+
self,
|
|
344
|
+
block: bool = False,
|
|
345
|
+
to_me: bool = False,
|
|
346
|
+
to_ai: str = "",
|
|
347
|
+
) -> Callable:
|
|
348
|
+
return self._on("message", "message", block, to_me, prefix=False, to_ai=to_ai)
|
|
349
|
+
|
|
350
|
+
def on_meta(
|
|
351
|
+
self,
|
|
352
|
+
event_name: Union[str, Tuple[str, ...]],
|
|
353
|
+
block: bool = False,
|
|
354
|
+
) -> Callable:
|
|
355
|
+
return self._on("meta", event_name, block=block, to_me=False, prefix=False)
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
AI_COMMANDS: List[Dict] = []
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def get_plugin_prefixs(plugin_name: str) -> List[str]:
|
|
362
|
+
plugin = SL.plugins.get(plugin_name)
|
|
363
|
+
if plugin is None:
|
|
364
|
+
raise ValueError(f"插件{plugin_name}不存在!")
|
|
365
|
+
return plugin.prefix
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def get_plugin_prefix(plugin_name: str) -> str:
|
|
369
|
+
return get_plugin_prefixs(plugin_name)[0]
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def get_plugin_force_prefixs(plugin_name: str) -> List[str]:
|
|
373
|
+
plugin = SL.plugins.get(plugin_name)
|
|
374
|
+
if plugin is None:
|
|
375
|
+
raise ValueError(f"插件{plugin_name}不存在!")
|
|
376
|
+
return plugin.force_prefix
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def get_plugin_force_prefix(plugin_name: str) -> str:
|
|
380
|
+
return get_plugin_force_prefixs(plugin_name)[0]
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
def get_plugin_available_prefix(plugin_name: str) -> str:
|
|
384
|
+
plugin = SL.plugins.get(plugin_name)
|
|
385
|
+
if plugin is None:
|
|
386
|
+
raise ValueError(f"插件{plugin_name}不存在!")
|
|
387
|
+
if not plugin.disable_force_prefix and plugin.force_prefix:
|
|
388
|
+
return plugin.force_prefix[0]
|
|
389
|
+
if plugin.disable_force_prefix and plugin.prefix:
|
|
390
|
+
return plugin.prefix[0]
|
|
391
|
+
return ""
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
def all_prefixes() -> List[str]:
|
|
395
|
+
out: List[str] = []
|
|
396
|
+
for plugin in SL.plugins.values():
|
|
397
|
+
if not plugin.disable_force_prefix:
|
|
398
|
+
out.extend(plugin.force_prefix)
|
|
399
|
+
out.extend(p for p in plugin.prefix if p)
|
|
400
|
+
# 去重但保序: 配置里写在前面的就排在前面, 卡片上生成的命令才不会每次重启换一个前缀
|
|
401
|
+
seen: Set[str] = set()
|
|
402
|
+
ordered = [p for p in out if not (p in seen or seen.add(p))]
|
|
403
|
+
return sorted(ordered, key=len, reverse=True)
|