@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
package/package.json
CHANGED
|
@@ -1,6 +1,138 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sophiacyl/dsh-plugin-waves",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0-beta.2",
|
|
4
|
+
"license": "GPL-3.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "鸣潮 dsh-go 原生测试适配:查询、面板、练度与设置;基于 Loping151/dsh-plugin-waves",
|
|
7
|
+
"main": "lib/index.js",
|
|
8
|
+
"files": [
|
|
9
|
+
"lib",
|
|
10
|
+
"locale",
|
|
11
|
+
"cordis.patch.yml",
|
|
12
|
+
"install.sh",
|
|
13
|
+
"install.ps1",
|
|
14
|
+
"ICON.png",
|
|
15
|
+
"service/rover",
|
|
16
|
+
"service/tools",
|
|
17
|
+
"service/ai",
|
|
18
|
+
"service/knowledge",
|
|
19
|
+
"service/pyproject.toml",
|
|
20
|
+
"service/ICON.png",
|
|
21
|
+
"service/plugins/__init__.py",
|
|
22
|
+
"DSH-GO-VERIFICATION.md",
|
|
23
|
+
"tests"
|
|
24
|
+
],
|
|
25
|
+
"exports": {
|
|
26
|
+
".": "./lib/index.js",
|
|
27
|
+
"./client": "./lib/client.js",
|
|
28
|
+
"./package.json": "./package.json",
|
|
29
|
+
"./locale/*.json": "./locale/*.json"
|
|
30
|
+
},
|
|
31
|
+
"dsh": {
|
|
32
|
+
"bundle": {
|
|
33
|
+
"patch": "./cordis.patch.yml"
|
|
34
|
+
},
|
|
35
|
+
"client": {
|
|
36
|
+
"platform": "web"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"dshGo": {
|
|
40
|
+
"v": 1,
|
|
41
|
+
"title": {
|
|
42
|
+
"zh": "鸣潮",
|
|
43
|
+
"en": "Waves"
|
|
44
|
+
},
|
|
45
|
+
"icon": "star",
|
|
46
|
+
"assets": "service/data/media",
|
|
47
|
+
"capabilities": [
|
|
48
|
+
"files"
|
|
49
|
+
],
|
|
50
|
+
"contributes": {
|
|
51
|
+
"composer.actions": [
|
|
52
|
+
{
|
|
53
|
+
"id": "waves-open",
|
|
54
|
+
"label": "鸣潮",
|
|
55
|
+
"icon": "star",
|
|
56
|
+
"effect": {
|
|
57
|
+
"type": "open",
|
|
58
|
+
"page": "panel:waves-home"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"panels": [
|
|
63
|
+
{
|
|
64
|
+
"id": "waves-home",
|
|
65
|
+
"title": "鸣潮查询",
|
|
66
|
+
"icon": "star",
|
|
67
|
+
"placement": [
|
|
68
|
+
"session.tab",
|
|
69
|
+
"features",
|
|
70
|
+
"chat.panel"
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"id": "waves-settings",
|
|
75
|
+
"title": "鸣潮设置",
|
|
76
|
+
"icon": "settings",
|
|
77
|
+
"placement": [
|
|
78
|
+
"features"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "waves-edit",
|
|
83
|
+
"title": "修改设置",
|
|
84
|
+
"icon": "edit",
|
|
85
|
+
"placement": [
|
|
86
|
+
"session.tab"
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
"minApp": "1.0.13"
|
|
92
|
+
},
|
|
93
|
+
"peerDependencies": {
|
|
94
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
95
|
+
"@deepseek-ai/dsh-tools": "^0.1.0-rc.7 || ^0.2.0-rc.2 || 0.2.2-rc.1",
|
|
96
|
+
"@deepseek-ai/dsh-llm": "^0.1.0-rc.7 || ^0.2.0-rc.2 || 0.2.2-rc.1",
|
|
97
|
+
"@deepseek-ai/dsh-commands": "^0.1.0-rc.7 || ^0.2.0-rc.2 || 0.2.2-rc.1",
|
|
98
|
+
"@deepseek-ai/dsh-attachment": "^0.1.0-rc.7 || ^0.2.0-rc.2 || 0.2.2-rc.1"
|
|
99
|
+
},
|
|
100
|
+
"peerDependenciesMeta": {
|
|
101
|
+
"@deepseek-ai/cordis": {
|
|
102
|
+
"optional": true
|
|
103
|
+
},
|
|
104
|
+
"@deepseek-ai/dsh-tools": {
|
|
105
|
+
"optional": true
|
|
106
|
+
},
|
|
107
|
+
"@deepseek-ai/dsh-llm": {
|
|
108
|
+
"optional": true
|
|
109
|
+
},
|
|
110
|
+
"@deepseek-ai/dsh-commands": {
|
|
111
|
+
"optional": true
|
|
112
|
+
},
|
|
113
|
+
"@deepseek-ai/dsh-attachment": {
|
|
114
|
+
"optional": true
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"scripts": {
|
|
118
|
+
"test": "node --test tests/*.test.js"
|
|
119
|
+
},
|
|
120
|
+
"engines": {
|
|
121
|
+
"node": "^22.19.0 || >=24.2.0",
|
|
122
|
+
"dsh": "^0.1.0-rc.7 || ^0.2.0-rc.2 || 0.2.2-rc.1"
|
|
123
|
+
},
|
|
124
|
+
"icon": "./ICON.png",
|
|
125
|
+
"publishConfig": {
|
|
126
|
+
"access": "public",
|
|
127
|
+
"registry": "https://registry.npmjs.org",
|
|
128
|
+
"tag": "beta"
|
|
129
|
+
},
|
|
130
|
+
"repository": {
|
|
131
|
+
"type": "git",
|
|
132
|
+
"url": "git+https://github.com/Sophiacyl/dsh-plugin-waves.git"
|
|
133
|
+
},
|
|
134
|
+
"homepage": "https://github.com/Sophiacyl/dsh-plugin-waves/tree/release/npm",
|
|
135
|
+
"bugs": {
|
|
136
|
+
"url": "https://github.com/Sophiacyl/dsh-plugin-waves/issues"
|
|
137
|
+
}
|
|
138
|
+
}
|
package/service/ICON.png
ADDED
|
Binary file
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# 鸣潮数据与脚本指南
|
|
2
|
+
|
|
3
|
+
本地存了什么、怎么读、怎么用插件自带的评分内核自己算。
|
|
4
|
+
出图和常规查询走 waves 工具下命令;要精确数值或跨角色统筹,按这份写脚本。
|
|
5
|
+
|
|
6
|
+
## 铁律
|
|
7
|
+
|
|
8
|
+
- **不改用户数据**。`service/data/` 只读,包括 `players/`、`*.db`、`config.json`、`show/`。
|
|
9
|
+
不要写、不要删、不要"顺手修一下"。改配置只能由用户在设置页点,改账号数据只能由用户发命令。
|
|
10
|
+
- 要写东西就用 `wwdata.scratch()`(系统临时目录下的 `dsh-waves-scratch/`,会建好并返回路径):
|
|
11
|
+
模拟数据、中间结果、脚本产物都落这里。沙箱只放行临时目录和工作区,别往 data 里写。
|
|
12
|
+
- sqlite 只能只读打开:`sqlite3.connect("file:...?mode=ro&immutable=1", uri=True)`。
|
|
13
|
+
服务正在写这个库,用读写连接会把它写坏。
|
|
14
|
+
- **数据旧了就先刷新再读**。每份数据都带时间戳,见下节。刷新靠跑命令,不是自己去动文件。
|
|
15
|
+
|
|
16
|
+
## 数据新鲜度
|
|
17
|
+
|
|
18
|
+
| 想要的东西 | 文件 | 刷新命令 |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| 角色面板 | `players/<uid>/rawData.json.gz` | `ww刷新面板`(全量,慢)/ `ww刷新<角色>面板` |
|
|
21
|
+
| 账号概览 | `players/<uid>/baseInfo.json` | `ww查询` |
|
|
22
|
+
| 矩阵 | `players/<uid>/matrixData.json.gz` | `ww矩阵` |
|
|
23
|
+
| 深塔 | `players/<uid>/rover.json.gz` | `ww深塔` |
|
|
24
|
+
| 冥海 | `players/<uid>/slashData.json.gz` | `ww海墟` |
|
|
25
|
+
| 抽卡 | `players/<uid>/gacha_logs.json.gz` | `ww抽卡记录` |
|
|
26
|
+
|
|
27
|
+
挑战数据里有 `record_time`(秒级时间戳),面板数据看文件 mtime。
|
|
28
|
+
距离用户提及超过一两天、或者用户刚说"我又打了一轮",先用 waves 工具跑一次对应命令读取拉取数据。
|
|
29
|
+
|
|
30
|
+
## 起手式
|
|
31
|
+
|
|
32
|
+
跑脚本用服务自己的解释器(Linux/macOS:`<service>/.venv/bin/python`,Windows:`<service>/.venv/Scripts/python.exe`),
|
|
33
|
+
系统 python 缺依赖,评分相关的接口会直接报错。
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
import sys; sys.path.insert(0, "<service>/tools") # <service> 见工具说明里的绝对路径
|
|
37
|
+
import wwdata as w
|
|
38
|
+
|
|
39
|
+
uid = w.default_uid() # 当前默认账号(wavesbind 里的第一个)
|
|
40
|
+
w.bound_uids() # 绑过的全部账号
|
|
41
|
+
w.base_info(uid) # 名字/等级/世界等级/激活天数
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`wwdata` 只读,且已经把 gzip、别名、评分模板这些琐事包好了。直接读 json 也行,但别绕过只读约束。
|
|
45
|
+
|
|
46
|
+
跑脚本不需要沙箱升级:读 data、写 scratch 都在默认权限内,shell 工具别带
|
|
47
|
+
`sandbox_permissions`/`justification` 参数(同级升级会被拒,空 justification 会报错)。
|
|
48
|
+
Windows 下控制台输出中文会乱码:结果写成 UTF-8 文件到 `wwdata.scratch()` 再读回来,别依赖 stdout。
|
|
49
|
+
|
|
50
|
+
## 角色与练度
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
w.roster(uid) # 紧凑一行式: "卡提希娅 Lv90 6链 不屈命定之冠5阶 声骸176.7"
|
|
54
|
+
w.roster(uid, 10) # 只要练度最高的 10 个
|
|
55
|
+
|
|
56
|
+
w.roles(uid) # 完整结构, 需要逐项判断时才用
|
|
57
|
+
# {'id','name','level','attribute','chain'(链数),'weapon':{'name','level','reson'},
|
|
58
|
+
# 'skills':{'常态攻击':10,...},'echo_score','sonatas':{'沉日劫明':5}}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
只想知道"有谁、练到什么程度"就用 `roster`;四五十个角色的 `roles` 全量结构没必要整份摊开。
|
|
62
|
+
|
|
63
|
+
**练度不一是常态**,给建议前先看清:`level`、`chain`、`weapon.reson`(谐振阶数)、`skills`、`echo_score`。
|
|
64
|
+
一个 0 链 90 级配专武的角色和一个 6 链 70 级配三星武器的,不能当同一个东西排。
|
|
65
|
+
|
|
66
|
+
名字/别名(别自己猜简称):
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
w.resolve("洛可可") # 别名 → 正式名,认不出返回 None
|
|
70
|
+
w.resolve_sonata("暗套") # 套装别名 → 正式名
|
|
71
|
+
w.name(1507) # 角色 id → 名字
|
|
72
|
+
w.char_id("椿") # 名字 → id
|
|
73
|
+
w.id2name() # 全表,够用就别再去读 alias 文件
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
别名原始表在 `data/XutheringWavesUID/alias/`(`char_alias.json`、`sonata_alias.json`、`echo_alias.json`、
|
|
77
|
+
`weapon_alias.json`),只有 `w.resolve` 认不出来时才需要翻。
|
|
78
|
+
|
|
79
|
+
角色图鉴(detail_json 的精简视图,富文本标记已剥掉,只传有效信息):
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
w.char_info("菲比") # 属性/武器型/星级/技能/共鸣链, 纯文本
|
|
83
|
+
w.char_info("菲比", parts=["stats"]) # 附成长数值(还可加 "ascensions")
|
|
84
|
+
w.detail_file("weapon", "苍鳞千嶂") # char/weapon/echo/sonata 源文件路径
|
|
85
|
+
w.clean_text(s) # 自己读源文件时剥 <span style=...> 等标记
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
要抠 `char_info` 没带出来的原始字段(成长曲线细节、技能树 param 等)才去读 `detail_file` 指向的源文件。
|
|
89
|
+
|
|
90
|
+
用户话里出现别名时,插件会在上下文尾部补一条对照("暗套→沉日劫明"这种)。那是按子串匹配来的,
|
|
91
|
+
可能误命中,别当成用户已经确认的指代;拿不准就按用户原话问一句。
|
|
92
|
+
|
|
93
|
+
## 声骸与评分
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
w.echoes(uid) # 全部已装备声骸拉平成一张表
|
|
97
|
+
w.echoes(uid, sonata="沉日劫明") # 按套装筛
|
|
98
|
+
w.echoes(uid, char="椿") # 按角色筛
|
|
99
|
+
# 每项: owner/owner_id/slot/cost/level/sonata/echo/main/subs/raw
|
|
100
|
+
|
|
101
|
+
w.score(uid, "洛可可", echo) # 把这件放到洛可可的评分模板下打分 → {score,grade,template,char}
|
|
102
|
+
w.total_score(uid, "椿", echo_list)
|
|
103
|
+
w.calc_temp(uid, "椿") # 该角色当前的评分模板(词条权重)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
分数来自插件自带的评分内核(各角色模板不同),**不是伤害模拟**。要伤害对比就跑 `ww<角色>伤害`。
|
|
107
|
+
|
|
108
|
+
只有已装备的声骸会出现在数据里;仓库里没戴的读不到。
|
|
109
|
+
|
|
110
|
+
## 场景一:优化矩阵配队
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
ms = w.matrix_summary(uid)
|
|
114
|
+
# {'record_time', 'reward', 'total_reward',
|
|
115
|
+
# 'modes':[{'mode_id','rank','score','pass_boss','boss_count','round',
|
|
116
|
+
# 'teams':[{'roles':['赞妮','菲比','白芷'],'pass_boss','boss_count','buffs':[...]}]}],
|
|
117
|
+
# 'stage_roles': {'1_0': ['赞妮','菲比','白芷'], ...}} # 各层实到阵容
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
做法:
|
|
121
|
+
|
|
122
|
+
0. **先核对周期**:`w.challenge_periods()` 拿当期开始时间,与 `matrix_summary` 的 `record_time`
|
|
123
|
+
比对。record_time 早于当期 start = 上一期数据,只能当历史参考;`ww矩阵` 提示"暂无数据" =
|
|
124
|
+
已换期且新一期没打(不是 bug,见 kb"挑战周期")。当期 boss/可多次上场角色**没有接口可查**
|
|
125
|
+
(矩阵接口只回个人战绩,wiki 活动说明只有时间条件):用户没打新一期就把所缺信息一次列全
|
|
126
|
+
请用户从游戏里带出来,别拆成多轮。目标不用问,默认冲总分最高。配队硬约束见 kb"矩阵配队规则"。
|
|
127
|
+
1. `matrix_summary` 看哪层卡住(`pass_boss < boss_count`)、当前用了谁、这层的 buff 是什么。
|
|
128
|
+
2. `roles(uid)` 拿全部持有角色和练度,注意别推荐没有的角色,也别把低练度角色当核心。
|
|
129
|
+
3. buff 描述里往往点名了机制(异常效应、虚湮、共鸣解放等),据此决定配队方向。
|
|
130
|
+
4. 需要版本环境/流行配队时可以联网查,但**必须回到第 2 步过滤成用户真有的角色**,
|
|
131
|
+
并按练度给出"现在能上的"和"值得练的"两档。
|
|
132
|
+
5. 想验证输出强度,对候选主 C 跑 `ww<角色>伤害` 看期望伤害。
|
|
133
|
+
|
|
134
|
+
## 场景二:一套声骸在多角色间怎么分
|
|
135
|
+
|
|
136
|
+
沉日劫明这类套装会被丹瑾、弗洛洛、椿、洛可可、坎特蕾拉、千咲等多人共用,但吃的词条不一样,
|
|
137
|
+
所以同一件在不同人身上分数差很多,互换有可能双赢。但注意不是随便换,需要受到装配cost<=12且同套装(不论2、3还是5件套)内声骸不能重复,
|
|
138
|
+
且注意部分角色使用3+2搭配等,比如千咲/弗洛洛可能只有2件是沉日劫明,另外3件由于跨套装一般不考虑更换
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
w.sonata_pool(uid, "沉日劫明") # {角色: [该套装的声骸...]}
|
|
142
|
+
w.cross_scores(uid, "沉日劫明") # 每件 × 每个候选角色的交叉分,按"换人能涨多少"排序
|
|
143
|
+
w.swap_gains(uid, "沉日劫明") # 直接给出总分净增益为正的两两互换(只在 cost 相同的件之间)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`cross_scores` 是证据,`swap_gains` 是结论。`swap_gains` 空不代表没优化空间——
|
|
147
|
+
它只换 cost 相同的件;`cross_scores` 里 `gain_vs_owner` 高但换不动的,通常是槽位 cost 对不上,
|
|
148
|
+
这种要在建议里说清楚("这件在弗洛洛身上更值,但他没有 4c 槽")。
|
|
149
|
+
|
|
150
|
+
想把候选角色扩到还没戴这套的人:`w.cross_scores(uid, "沉日劫明", chars=["千咲", "坎特蕾拉"])`。
|
|
151
|
+
|
|
152
|
+
### 把截图里的声骸也放进池子
|
|
153
|
+
|
|
154
|
+
`ww评分 <角色><cost>c(主词条)` 带图(调 waves 工具时设 with_image=true)走远端识图评分,回的是一张卡片;
|
|
155
|
+
卡片会被本地 OCR,词条名与数值就在返回的 summary"图片文字(OCR)"里。
|
|
156
|
+
要让新声骸参与本地推演,把词条转录出来自己造一件——优先从评分卡的 OCR 文字里抄;
|
|
157
|
+
OCR 缺漏或没走评分时,能读图的路由用读图工具读上下文提示给的暂存路径,都不行就让用户打字发来,
|
|
158
|
+
别凭空编数值:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
new = w.make_echo(
|
|
162
|
+
cost=4, sonata="沉日劫明", echo_name="无冠者",
|
|
163
|
+
main=[("攻击", "18.0%"), ("暴击伤害", "44.0%")],
|
|
164
|
+
subs=[("暴击", "8.1%"), ("攻击", "11.6%"), ("共鸣效率", "8.4%"),
|
|
165
|
+
("重击伤害加成", "9.9%"), ("攻击", "40")],
|
|
166
|
+
)
|
|
167
|
+
for c in ["椿", "洛可可", "弗洛洛"]:
|
|
168
|
+
print(c, w.score(uid, c, new))
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
词条名和值照抄面板原文(带 `%` 就带上)。
|
|
172
|
+
|
|
173
|
+
### 重组出一张完整面板卡
|
|
174
|
+
|
|
175
|
+
打分归打分,想让用户直观看到"换完之后面板长什么样",用 `waves_panel` 工具(不是命令):
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{ "char": "椿",
|
|
179
|
+
"echoes": [
|
|
180
|
+
{ "slot": 1, "from": { "char": "洛可可", "slot": 2 } },
|
|
181
|
+
{ "slot": 2, "name": "无冠者", "cost": 4, "sonata": "沉日劫明",
|
|
182
|
+
"main": [["暴击", "22.0%"], ["攻击", "150"]],
|
|
183
|
+
"subs": [["暴击伤害", "21.0%"], ["攻击", "11.6%"]] }
|
|
184
|
+
],
|
|
185
|
+
"change": "换6链" }
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
- 没列到的槽位保持该角色当前装备;`from` 引用别人正在装备的那件,自定义件词条照抄原文。
|
|
189
|
+
- cost 只能 1/3/4,总和 ≤12;`change` 走换装文本管线(换链/武器/等级/技能/主词条)。
|
|
190
|
+
- 只在本地渲染出卡:不写 `players/`、不进总排行上传队列。别把假设数据说成用户真实面板。
|
|
191
|
+
|
|
192
|
+
## 游戏常识知识库
|
|
193
|
+
|
|
194
|
+
库洛 wiki 文本(图鉴/攻略/百科/活动/任务/剧情)已在本地,按"条目/小节"粒度存放,
|
|
195
|
+
纯文本、图片以 `` 内嵌——要展示图片直接把 url 给用户。
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
w.kb("虚湮效应") # 词法检索小节 → [{id,entry,title,tags,score,snippet}]
|
|
199
|
+
w.kb("配队", tags=["玩法攻略"]) # 按 tags/source 收窄
|
|
200
|
+
w.kb_get("wiki-xxx#2") # 小节 id → 该小节
|
|
201
|
+
w.kb_get("wiki-xxx") # entry id → 整条(全部小节)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
先 `kb` 看 snippet 定位到小节,通常小节就够了;要上下文再用 entry id 取整条,别整库摊开。
|
|
205
|
+
用户话里首次提到角色名/机制词时,插件会自动附带该条目的首个小节(每会话每条只附一次,
|
|
206
|
+
标注"仅供参考");那只是字面命中,后续要引用细节自己再 `kb`/`kb_get`。
|
|
207
|
+
|
|
208
|
+
## 直接读文件
|
|
209
|
+
|
|
210
|
+
`wwdata` 没覆盖到的,自己读也行,路径都在 `data/XutheringWavesUID/`:
|
|
211
|
+
|
|
212
|
+
- `resource/map/detail_json/char/<角色id>.json` 角色详情:技能树、共鸣链、成长曲线、属性
|
|
213
|
+
- `resource/map/detail_json/` 下还有 `weapon`、`echo`、`sonata`、`forte`、`material`、`challenge`
|
|
214
|
+
- `resource/map/CharId2Data.json`、`id2name.json`
|
|
215
|
+
- `players/<uid>/state.json` 每个角色的查看/刷新次数(用户最近在关注谁)
|
|
216
|
+
- `players/<uid>/gachaStats.json` 各卡池 `total/avg/remain/up_count`
|
|
217
|
+
|
|
218
|
+
## 跑命令
|
|
219
|
+
|
|
220
|
+
要刷新数据、要出图、要用插件已有的分析(伤害、优化建议、练度、排行),
|
|
221
|
+
直接调 waves 工具下命令,别自己重写一遍。命令清单看 `ww帮助`,或工具说明里的常用列表。
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
{"id": "add-cycle#0", "entry": "add-cycle", "entry_title": "挑战周期", "section_title": "周期规则", "title": "挑战周期/周期规则", "tags": ["游戏机制", "深塔", "冥歌海墟", "终焉矩阵"], "tier": "core", "source": "manual@2026-08-30", "triggers": ["挑战周期", "深塔周期", "海墟周期", "矩阵周期", "换期", "第几期"], "content": "深塔与冥歌海墟每 28 天一期,终焉矩阵名义 42 天一期但实际会提前几天、按锚点人工校准;换期边界都在当天 04:00(UTC+8)。基准锚点(与插件 wutheringwaves_abyss/period.py 同源,人工维护):\n- 深塔:2025-11-10 04:00 = 第 29 期开始,此后每 28 天一期。\n- 冥歌海墟:2025-11-24 04:00 = 第 11 期开始,此后每 28 天一期。\n- 终焉矩阵:第4期 2026-05-07、第5期 2026-06-14、第6期 2026-07-17、第7期 2026-08-27(均 04:00 开始);第 7 期之后按 42 天外推,实际可能提前,以游戏内为准。\n当前期号与起止时间用脚本取:w.challenge_periods() → {tower/slash/matrix: {period, start, next, days}}。"}
|
|
2
|
+
{"id": "add-record-missing#0", "entry": "add-record-missing", "entry_title": "挑战记录缺失", "section_title": "含义与处理", "title": "挑战记录缺失/含义与处理", "tags": ["游戏机制", "深塔", "冥歌海墟", "终焉矩阵"], "tier": "core", "source": "manual@2026-08-30", "triggers": ["暂无数据", "记录缺失", "没有数据", "查不到记录", "没有记录"], "content": "查询深塔/海墟/矩阵时提示\"暂无数据\"、记录缺失或变空,通常不是故障,而是挑战已换期:官方接口只保留当期记录,旧一期数据在换期时清空,用户新一期还没打就是空的。此时应告知用户挑战已更新、打完新一期再查,不要当成 bug 去修。\n本地缓存(players/<uid>/matrixData 等)可能还是上一期的:先用 w.challenge_periods() 拿当期开始时间,与数据里的 record_time 比对——record_time 早于当期 start 就是上一期数据,只能当历史参考,绝不能当作当期现状来分析。当期的 boss/增幅回路/可多次上场角色没有接口可查(详见 kb\"矩阵配队规则\"),把所缺信息一次列全请用户从游戏里带出来。"}
|
|
3
|
+
{"id": "add-tower-rules#0", "entry": "add-tower-rules", "entry_title": "深塔配队规则", "section_title": "规则", "title": "深塔配队规则/规则", "tags": ["游戏机制", "深塔", "配队"], "tier": "core", "source": "manual@2026-08-30", "triggers": ["深塔配队", "疲劳度", "疲劳机制"], "content": "深塔配队规则(人工维护):\n- 角色有疲劳度机制:出战会累积疲劳,复用同一角色打多层/多塔要考虑疲劳带来的减益。\n- 声骸可以复用:不同队伍之间可以共用同一套声骸,配装不受队伍互斥限制。"}
|
|
4
|
+
{"id": "add-slash-rules#0", "entry": "add-slash-rules", "entry_title": "海墟配队规则", "section_title": "规则", "title": "海墟配队规则/规则", "tags": ["游戏机制", "冥歌海墟", "配队"], "tier": "core", "source": "manual@2026-08-30", "triggers": ["海墟配队", "上下半场"], "content": "冥歌海墟配队规则(人工维护):同一场的上下半场在开打前一次性选好角色,因此这 6 个角色互斥(上下半不能用同一人),且 6 人之间无法互换声骸和武器。给海墟配队建议时要按\"一场 6 个不同角色、装备各自固定\"来排。"}
|
|
5
|
+
{"id": "add-matrix-rules#0", "entry": "add-matrix-rules", "entry_title": "矩阵配队规则", "section_title": "规则", "title": "矩阵配队规则/规则", "tags": ["游戏机制", "终焉矩阵", "配队"], "tier": "core", "source": "manual@2026-08-30", "triggers": ["上场两次", "上场次数", "多次上场", "当期矩阵", "矩阵配队"], "content": "终焉矩阵配队规则(人工维护):\n- 所有队伍之间不能互换任何声骸和武器:一个角色带什么装备就全程固定,跨队共用装备不可行。\n- 同一角色默认整期只能上场一次;只有少数角色可以上场 2 次(当期指定,需要查当期信息确认是谁)。\n- 部分增幅回路(buff)也可能让角色获得当期多次上场的资格。\n- 因此矩阵配队是全局分配问题:主力角色和好声骸要在十几支队伍间统筹,不能按\"每队独立最优\"来排。当期可多次上场的角色名单以游戏内为准。\n- 目标不用问:矩阵默认奔着总分最高去,\"少队精打\"还是\"多队铺开\"是由练度和当期规则算出来的手段,不是要用户选的偏好。用户主动说了别的目标(如省时间)才改。\n- 当期特殊规则(本期 boss 及属性/抗性、可多次上场角色名单、当期增幅侧重)**没有接口可查**:矩阵接口只回个人战绩,wiki 活动说明也只有时间和开放条件。用户没打新一期时,直接说明\"这些要你从游戏里带出来\",并把要问的内容一次列全,别拆成多轮追问。"}
|