@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,206 @@
|
|
|
1
|
+
"""声骸仓库卡片: 原 PIL 版声骸列表改为 HTML 输出, 版式照搬 350x600 卡格与 4 列网格。"""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import importlib
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, List, Tuple
|
|
7
|
+
|
|
8
|
+
from rover.logger import logger
|
|
9
|
+
|
|
10
|
+
TEMPLATE = "echo_list.html"
|
|
11
|
+
TEMPLATES_DIR = Path(__file__).resolve().parents[1] / "templates"
|
|
12
|
+
|
|
13
|
+
# 卡格几何, 与 PIL 版逐项对齐
|
|
14
|
+
CARD_W, CARD_H = 350, 600
|
|
15
|
+
COL_PITCH, ROW_PITCH = 390, 570
|
|
16
|
+
COLUMNS = 4
|
|
17
|
+
PROP_TOP, PROP_PITCH = 217, 55
|
|
18
|
+
|
|
19
|
+
_env = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _template():
|
|
23
|
+
global _env
|
|
24
|
+
if _env is None:
|
|
25
|
+
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
|
26
|
+
|
|
27
|
+
_env = Environment(
|
|
28
|
+
loader=FileSystemLoader(str(TEMPLATES_DIR)),
|
|
29
|
+
autoescape=select_autoescape(["html"]),
|
|
30
|
+
)
|
|
31
|
+
return _env.get_template(TEMPLATE)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _css_color(value: Any) -> str:
|
|
35
|
+
"""词条配色在插件里是颜色名或 RGB 元组。"""
|
|
36
|
+
if isinstance(value, (tuple, list)):
|
|
37
|
+
parts = list(value)[:3]
|
|
38
|
+
return "rgb({}, {}, {})".format(*parts)
|
|
39
|
+
return str(value)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _font_css_url(render_utils) -> str:
|
|
43
|
+
css = render_utils._FONTS_DIR / render_utils._FONT_CSS_NAME
|
|
44
|
+
if css.exists():
|
|
45
|
+
return f"{render_utils._get_local_base_url()}/waves/fonts/{render_utils._FONT_CSS_NAME}"
|
|
46
|
+
return render_utils._get_font_css_url()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _build_context(module, image, render_utils, account_info, avatar, echo_assets, page, max_page, user_pref) -> Dict:
|
|
50
|
+
texture = module.TEXT_PATH
|
|
51
|
+
# 同一素材在 20 张卡里反复出现, 统一收进 CSS 类, 元素只带类名
|
|
52
|
+
assets: List[str] = []
|
|
53
|
+
classes: Dict[Tuple, str] = {}
|
|
54
|
+
|
|
55
|
+
def asset_class(key: Tuple, make) -> str:
|
|
56
|
+
if key not in classes:
|
|
57
|
+
assets.append(make())
|
|
58
|
+
classes[key] = f"a{len(assets) - 1}"
|
|
59
|
+
return classes[key]
|
|
60
|
+
|
|
61
|
+
echoes: List[Dict] = []
|
|
62
|
+
for index, asset in enumerate(echo_assets):
|
|
63
|
+
echo = asset["echo"]
|
|
64
|
+
phantom = echo.phantom
|
|
65
|
+
icon = asset["phantom_icon"]
|
|
66
|
+
|
|
67
|
+
title = f"sh_title_{echo.score_bg}.png"
|
|
68
|
+
if not (texture / title).exists():
|
|
69
|
+
title = "sh_title_c.png"
|
|
70
|
+
|
|
71
|
+
props = []
|
|
72
|
+
for i, prop in enumerate(echo.props):
|
|
73
|
+
prop_img = asset["prop_imgs"][i]
|
|
74
|
+
props.append(
|
|
75
|
+
{
|
|
76
|
+
"icon_class": asset_class(
|
|
77
|
+
("prop", prop.attributeName),
|
|
78
|
+
lambda img=prop_img: image.pil_to_b64(img.resize((40, 40)), quality=80),
|
|
79
|
+
),
|
|
80
|
+
"name": prop.attributeName[:6],
|
|
81
|
+
"value": prop.attributeValue,
|
|
82
|
+
"name_color": _css_color(echo.name_colors[i]),
|
|
83
|
+
"value_color": _css_color(echo.num_colors[i]),
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
echoes.append(
|
|
88
|
+
{
|
|
89
|
+
"left": COL_PITCH * (index % COLUMNS),
|
|
90
|
+
"top": ROW_PITCH * (index // COLUMNS),
|
|
91
|
+
"title_class": asset_class(("title", title), lambda: image.img_to_b64(texture / title)),
|
|
92
|
+
"role_class": asset_class(
|
|
93
|
+
("role", echo.roleId),
|
|
94
|
+
lambda: image.pil_to_b64(asset["role_avatar"], quality=80),
|
|
95
|
+
),
|
|
96
|
+
"icon_class": asset_class(
|
|
97
|
+
("phantom", phantom.phantomProp.phantomId),
|
|
98
|
+
lambda: image.pil_to_b64(icon.resize((100, 100)), quality=80),
|
|
99
|
+
),
|
|
100
|
+
"fetter_class": asset_class(
|
|
101
|
+
("fetter", phantom.fetterDetail.name),
|
|
102
|
+
lambda: image.pil_to_b64(asset["fetter_icon"].resize((50, 50)), quality=80),
|
|
103
|
+
),
|
|
104
|
+
# 角标原本贴在整图 (205, 0) 处, 缩到 100x100 后按比例给百分比
|
|
105
|
+
"fetter_left": 205 / max(icon.width, 1) * 100,
|
|
106
|
+
"fetter_size": 50 / max(icon.width, 1) * 100,
|
|
107
|
+
"name": phantom.phantomProp.name.replace("·", " ").replace("(", " ").replace(")", ""),
|
|
108
|
+
"level": phantom.level,
|
|
109
|
+
"score": echo.score,
|
|
110
|
+
"cost": phantom.cost,
|
|
111
|
+
"props": props,
|
|
112
|
+
"command": f"{module.PREFIX}{echo.roleName}面板" if echo.roleName else "",
|
|
113
|
+
}
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
rows = (len(echoes) + COLUMNS - 1) // COLUMNS
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
"font_css_url": _font_css_url(render_utils),
|
|
120
|
+
"bg_url": image.pil_to_b64(image.get_waves_bg(bg="bg3", crop=False), quality=75),
|
|
121
|
+
"footer_url": render_utils.get_footer_b64(footer_type="white") or "",
|
|
122
|
+
"sh_bg_url": image.img_to_b64(texture / "sh_bg.png"),
|
|
123
|
+
"promote_url": image.img_to_b64(texture / "promote_icon.png"),
|
|
124
|
+
"avatar_url": image.pil_to_b64(avatar, quality=80),
|
|
125
|
+
"assets": assets,
|
|
126
|
+
"user_name": account_info.name[:10],
|
|
127
|
+
"user_id": module.hide_uid(account_info.id, user_pref=user_pref),
|
|
128
|
+
"level": account_info.level,
|
|
129
|
+
"world_level": account_info.worldLevel,
|
|
130
|
+
"show_stats": account_info.is_full,
|
|
131
|
+
"page_text": f"第{page}/{max_page}页" if page > 1 else "",
|
|
132
|
+
"card_w": CARD_W,
|
|
133
|
+
"card_h": CARD_H,
|
|
134
|
+
"prop_top": PROP_TOP,
|
|
135
|
+
"prop_gap": PROP_PITCH - 40,
|
|
136
|
+
"grid_w": COL_PITCH * (COLUMNS - 1) + CARD_W,
|
|
137
|
+
"grid_h": ROW_PITCH * max(rows - 1, 0) + CARD_H,
|
|
138
|
+
"echoes": echoes,
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _patch_echo_list(module) -> None:
|
|
143
|
+
from rover.html_actions import annotate_html
|
|
144
|
+
from rover.media import HtmlBytes
|
|
145
|
+
|
|
146
|
+
original = module._compose_echo_list
|
|
147
|
+
package = module.__name__.rsplit(".", 2)[0]
|
|
148
|
+
image = importlib.import_module(f"{package}.utils.image")
|
|
149
|
+
render_utils = importlib.import_module(f"{package}.utils.render_utils")
|
|
150
|
+
|
|
151
|
+
async def compose(
|
|
152
|
+
account_info,
|
|
153
|
+
avatar,
|
|
154
|
+
avatar_ring,
|
|
155
|
+
echo_assets,
|
|
156
|
+
page,
|
|
157
|
+
max_page,
|
|
158
|
+
user_pref,
|
|
159
|
+
title_bar_logo,
|
|
160
|
+
):
|
|
161
|
+
try:
|
|
162
|
+
context = await asyncio.to_thread(
|
|
163
|
+
_build_context,
|
|
164
|
+
module,
|
|
165
|
+
image,
|
|
166
|
+
render_utils,
|
|
167
|
+
account_info,
|
|
168
|
+
avatar,
|
|
169
|
+
echo_assets,
|
|
170
|
+
page,
|
|
171
|
+
max_page,
|
|
172
|
+
user_pref,
|
|
173
|
+
)
|
|
174
|
+
html = annotate_html(_template().render(**context), TEMPLATE, context)
|
|
175
|
+
logger.info(f"[声骸仓库] {len(html) / 1024 / 1024:.2f}MB")
|
|
176
|
+
return HtmlBytes(html, TEMPLATE)
|
|
177
|
+
except Exception as e:
|
|
178
|
+
logger.error(f"[声骸仓库] HTML 渲染失败, 回退原图: {e}")
|
|
179
|
+
return await original(
|
|
180
|
+
account_info,
|
|
181
|
+
avatar,
|
|
182
|
+
avatar_ring,
|
|
183
|
+
echo_assets,
|
|
184
|
+
page,
|
|
185
|
+
max_page,
|
|
186
|
+
user_pref,
|
|
187
|
+
title_bar_logo,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
module._compose_echo_list = compose
|
|
191
|
+
|
|
192
|
+
original_convert = module.convert_img
|
|
193
|
+
|
|
194
|
+
async def convert_img(img, *args, **kwargs):
|
|
195
|
+
if isinstance(img, HtmlBytes):
|
|
196
|
+
return img
|
|
197
|
+
return await original_convert(img, *args, **kwargs)
|
|
198
|
+
|
|
199
|
+
module.convert_img = convert_img
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
PATCHES = {
|
|
203
|
+
"XutheringWavesUID": {
|
|
204
|
+
"wutheringwaves_echo.draw_echo_list": _patch_echo_list,
|
|
205
|
+
},
|
|
206
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""矩阵卡的角色 id。
|
|
2
|
+
|
|
3
|
+
上游给模板的角色项只有图标和命座, 没有 id, 点击注解就无从下手。
|
|
4
|
+
构图时每个真实角色都会取一次流派徽标, 借这一步把 id 顺手记下来。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from rover.logger import logger
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _patch(m) -> None:
|
|
11
|
+
original = m.get_skill_branch_emblem_b64
|
|
12
|
+
|
|
13
|
+
def get_skill_branch_emblem_b64(role_id, branch_index):
|
|
14
|
+
from rover.html_actions import record_role_id
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
record_role_id(role_id)
|
|
18
|
+
except Exception as e:
|
|
19
|
+
logger.debug(f"[鸣潮·交互] 矩阵角色 id 记录失败: {e}")
|
|
20
|
+
return original(role_id, branch_index)
|
|
21
|
+
|
|
22
|
+
m.get_skill_branch_emblem_b64 = get_skill_branch_emblem_b64
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
PATCHES = {"XutheringWavesUID": {"wutheringwaves_abyss.draw_matrix_card": _patch}}
|