koishi-plugin-dwrgbwiki 1.2.0 → 1.3.0

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.
Files changed (4) hide show
  1. package/index.js +45 -7
  2. package/lib.js +63 -11
  3. package/package.json +3 -3
  4. package/readme.md +1 -1
package/index.js CHANGED
@@ -25,6 +25,7 @@ const MAIN_HELP = [
25
25
  module.exports = {
26
26
  name: 'dwrgbwiki',
27
27
  description: '第五人格BWIKI编辑组测试用组件,纯AI生成喵',
28
+ inject: ['puppeteer'],
28
29
 
29
30
  Config: Schema.object({
30
31
  dataSource: Schema.union(lib.KNOWN_SOURCES)
@@ -47,14 +48,14 @@ module.exports = {
47
48
  .default(7),
48
49
  width: Schema.number().min(400).max(4000)
49
50
  .description('图片宽度(px),其他指令未单独设置时使用该值')
50
- .default(1000),
51
- mapWidth: Schema.number().min(400).max(4000)
51
+ .default(1300),
52
+ mapWidth: Schema.number().min(0).max(4000)
52
53
  .description('地图指令图片宽度(px),0=使用默认宽度')
53
54
  .default(0),
54
- mimicWidth: Schema.number().min(400).max(4000)
55
+ mimicWidth: Schema.number().min(0).max(4000)
55
56
  .description('模仿者指令图片宽度(px),0=使用默认宽度')
56
57
  .default(0),
57
- badgeWidth: Schema.number().min(400).max(4000)
58
+ badgeWidth: Schema.number().min(0).max(4000)
58
59
  .description('勋章指令图片宽度(px),0=使用默认宽度')
59
60
  .default(0),
60
61
  scale: Schema.number().min(1).max(4)
@@ -63,6 +64,18 @@ module.exports = {
63
64
  timeout: Schema.number().min(3000).max(60000)
64
65
  .description('网络请求超时(毫秒)')
65
66
  .default(15000),
67
+ heartbeatEnable: Schema.boolean()
68
+ .description('启用心跳包定时发送功能')
69
+ .default(false),
70
+ heartbeatServer: Schema.string()
71
+ .description('心跳服务端地址(如 http://192.168.1.10:8080)')
72
+ .default('http://localhost:8080'),
73
+ heartbeatUid: Schema.string()
74
+ .description('心跳 uid(可在指令中修改)')
75
+ .default(''),
76
+ heartbeatInterval: Schema.number().min(5).max(86400)
77
+ .description('心跳发送间隔(秒)')
78
+ .default(60),
66
79
  }),
67
80
 
68
81
  apply(ctx, config) {
@@ -71,6 +84,31 @@ module.exports = {
71
84
  return helpImage(ctx, config, MAIN_HELP)
72
85
  })
73
86
 
87
+ const heartbeat = {
88
+ uid: config.heartbeatUid || '',
89
+ timer: null,
90
+ }
91
+ const sendHeartbeat = async () => {
92
+ if (!heartbeat.uid || !config.heartbeatServer) return
93
+ const url = config.heartbeatServer.replace(/\/+$/, '') + '/api/heartbeat?uid=' + encodeURIComponent(heartbeat.uid)
94
+ const ctrl = new AbortController()
95
+ const timer = setTimeout(() => ctrl.abort(), 10000)
96
+ try {
97
+ await fetch(url, { signal: ctrl.signal })
98
+ } catch (e) {
99
+ ctx.logger('dwrgbwiki').warn('[heartbeat] 发送失败: ' + (e && e.message ? e.message : e))
100
+ } finally {
101
+ clearTimeout(timer)
102
+ }
103
+ }
104
+ const startHeartbeat = () => {
105
+ if (heartbeat.timer) return
106
+ if (!config.heartbeatInterval || config.heartbeatInterval < 5) config.heartbeatInterval = 60
107
+ heartbeat.timer = ctx.setInterval(() => sendHeartbeat(), config.heartbeatInterval * 1000)
108
+ sendHeartbeat()
109
+ }
110
+ if (config.heartbeatEnable) startHeartbeat()
111
+
74
112
  ctx.command('胜率 <角色名> [条件:text]', '查询角色胜率并生成图片')
75
113
  .usage(HELP)
76
114
  .example('胜率 小女孩')
@@ -122,7 +160,7 @@ async function run(ctx, config, collectFn, buildFn, name, cond, widthKey) {
122
160
  const width = (config[widthKey] && config[widthKey] > 0) ? config[widthKey] : config.width
123
161
  const html = buildFn(result, { ...config, avatarBase: result.base, width })
124
162
  const image = await capture(ctx, html, { ...config, width })
125
- return [h.image(image)]
163
+ return [h.image(image, 'image/png')]
126
164
  } catch (e) {
127
165
  ctx.logger('dwrgbwiki').warn(e)
128
166
  return errorImage(ctx, config, '查询失败:' + (e && e.message ? e.message : e))
@@ -134,7 +172,7 @@ async function helpImage(ctx, config, text) {
134
172
  try {
135
173
  const html = lib.buildHelpHtml(text, { ...config, width: config.width })
136
174
  const image = await capture(ctx, html, config)
137
- return [h.image(image)]
175
+ return [h.image(image, 'image/png')]
138
176
  } catch (e) {
139
177
  ctx.logger('dwrgbwiki').warn(e)
140
178
  return text
@@ -146,7 +184,7 @@ async function errorImage(ctx, config, text) {
146
184
  try {
147
185
  const html = lib.buildHelpHtml(text, { ...config, width: config.width })
148
186
  const image = await capture(ctx, html, config)
149
- return [h.image(image)]
187
+ return [h.image(image, 'image/png')]
150
188
  } catch (e) {
151
189
  ctx.logger('dwrgbwiki').warn(e)
152
190
  return text
package/lib.js CHANGED
@@ -1340,27 +1340,79 @@ function buildHelp() {
1340
1340
  }
1341
1341
 
1342
1342
  function buildHelpHtml(text, config) {
1343
- const width = config.width || 1000
1343
+ const width = config.width || 1300
1344
+ const cardW = Math.min(width, 880)
1345
+
1346
+ let hero = '', body = '', titleTaken = false
1347
+ String(text).split('\n').forEach(line => {
1348
+ const raw = String(line).replace(/\r$/, '')
1349
+ const trimmed = raw.trim()
1350
+ if (!titleTaken) {
1351
+ titleTaken = true
1352
+ hero =
1353
+ '<div class="hero-icon">🤖</div>' +
1354
+ '<div class="hero-title">' + esc(trimmed) + '</div>' +
1355
+ '<div class="hero-sub">第五人格 BWIKI 数据查询 · 数据均根据官方小程序数据计算</div>'
1356
+ return
1357
+ }
1358
+ if (!trimmed) { body += '<div class="gap"></div>'; return }
1359
+ if (/^(支持指令|用法|示例):/.test(trimmed)) {
1360
+ body += '<div class="sec">' + esc(trimmed) + '</div>'
1361
+ return
1362
+ }
1363
+ if (/^[ ]{4,}/.test(raw)) {
1364
+ body += '<div class="desc">' + esc(trimmed) + '</div>'
1365
+ return
1366
+ }
1367
+ if (/^[ ]{2}/.test(raw)) {
1368
+ body += '<div class="code">' + esc(trimmed) + '</div>'
1369
+ return
1370
+ }
1371
+ if (/^(排序要素|段位|日期|模式|阵营|赛季)/.test(trimmed) && trimmed.includes(':')) {
1372
+ body += '<div class="param"><span class="param-key">' + esc(trimmed.split(':')[0] + ':') + '</span>' + esc(trimmed.slice(trimmed.indexOf(':') + 1)) + '</div>'
1373
+ return
1374
+ }
1375
+ body += '<div class="line">' + esc(trimmed) + '</div>'
1376
+ })
1377
+
1344
1378
  return `<!DOCTYPE html>
1345
1379
  <html lang="zh-CN">
1346
1380
  <head>
1347
1381
  <meta charset="UTF-8">
1348
1382
  <style>
1349
- :root { --bg:#0d1117; --surface:#161b22; --border:#30363d; --text:#c9d1d9; --text-secondary:#8b949e; --accent:#58a6ff; --card-bg:#1c2333; }
1350
1383
  * { margin:0; padding:0; box-sizing:border-box; }
1351
- body { background:var(--bg); color:var(--text); font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','Microsoft YaHei',sans-serif; padding:16px; }
1352
- .card { background:var(--card-bg); border:1px solid var(--border); border-radius:18px; padding:22px 26px; max-width:${Math.min(width, 720)}px; margin:0 auto; }
1353
- .help-title { font-size:22px; font-weight:700; color:var(--accent); text-align:center; margin-bottom:14px; }
1354
- .help-text { font-size:15px; line-height:1.8; white-space:pre-wrap; word-break:break-all; }
1355
- .foot { text-align:center; color:var(--text-secondary); font-size:12px; margin-top:10px; opacity:.7; }
1384
+ body { font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','Microsoft YaHei',sans-serif; padding:28px 16px; color:#c9d1d9;
1385
+ background:radial-gradient(1200px 500px at 50% -10%, #1b2a4a 0%, #10182b 45%, #0a0e17 100%); }
1386
+ .page { max-width:${cardW}px; margin:0 auto; }
1387
+ .hero { display:flex; flex-direction:column; align-items:center; gap:10px; text-align:center; margin-bottom:22px; }
1388
+ .hero-icon { width:74px; height:74px; border-radius:22px; display:flex; align-items:center; justify-content:center; font-size:40px;
1389
+ background:linear-gradient(135deg, rgba(88,166,255,.18), rgba(210,153,29,.16)); border:1px solid rgba(88,166,255,.35);
1390
+ box-shadow:0 0 36px rgba(88,166,255,.18), inset 0 1px 0 rgba(255,255,255,.08); }
1391
+ .hero-title { font-size:30px; font-weight:800; letter-spacing:1px;
1392
+ background:linear-gradient(90deg, #79c0ff, #ffd76d); -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent; }
1393
+ .hero-sub { font-size:13px; color:#8b949e; }
1394
+ .card { background:rgba(22,27,34,.72); border:1px solid rgba(255,255,255,.09); border-radius:22px; padding:26px 30px;
1395
+ backdrop-filter:blur(8px); box-shadow:0 24px 64px rgba(0,0,0,.45); }
1396
+ .gap { height:8px; }
1397
+ .sec { font-size:16px; font-weight:700; color:#ffd76d; margin:14px 0 8px; display:flex; align-items:center; gap:10px; }
1398
+ .sec::before { content:''; width:4px; height:16px; border-radius:2px; background:linear-gradient(#ffd76d, #ff8c00); flex-shrink:0; }
1399
+ .sec:first-child { margin-top:0; }
1400
+ .line { font-size:14px; line-height:1.9; color:#c9d1d9; }
1401
+ .param { font-size:13.5px; line-height:1.9; color:#c9d1d9; padding:5px 14px; background:rgba(255,255,255,.03); border:1px solid rgba(255,255,255,.06); border-radius:8px; margin:5px 0; }
1402
+ .param-key { color:#ffd76d; font-weight:600; }
1403
+ .desc { font-size:13px; line-height:1.8; color:#8b949e; padding:2px 0 2px 18px; }
1404
+ .code { font-family:'SF Mono',Consolas,'Courier New',monospace; font-size:13.5px; line-height:1.7; color:#79c0ff;
1405
+ background:rgba(88,166,255,.08); border:1px solid rgba(88,166,255,.2); border-radius:8px; padding:6px 14px; margin:5px 0;
1406
+ word-break:break-all; }
1407
+ .foot { text-align:center; color:#8b949e; font-size:12px; margin-top:14px; opacity:.8; }
1356
1408
  </style>
1357
1409
  </head>
1358
1410
  <body>
1359
- <div class="card">
1360
- <div class="help-title">指令帮助</div>
1361
- <div class="help-text">${esc(text)}</div>
1411
+ <div class="page">
1412
+ <div class="hero">${hero}</div>
1413
+ <div class="card">${body}</div>
1414
+ <div class="foot">@夜莺小姐档案馆 · 数据均根据第五人格官方小程序数据计算</div>
1362
1415
  </div>
1363
- <div class="foot">数据均根据第五人格官方小程序数据计算</div>
1364
1416
  </body>
1365
1417
  </html>`
1366
1418
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-dwrgbwiki",
3
- "version": "1.2.0",
4
- "description": "第五人格BWIKI编辑组测试用组件,纯AI生成喵",
3
+ "version": "1.3.0",
4
+ "description": "第五人格BWIKI编辑组测试用插件,所有代码由DeepSeek V4 Flash编写",
5
5
  "main": "index.js",
6
6
  "files": [
7
7
  "index.js",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "koishi": {
23
23
  "description": {
24
- "zh": "第五人格BWIKI编辑组测试用组件,纯AI生成喵"
24
+ "zh": "第五人格BWIKI编辑组测试用插件,所有代码由DeepSeek V4 Flash编写"
25
25
  }
26
26
  }
27
27
  }
package/readme.md CHANGED
@@ -86,7 +86,7 @@ BWIKI机器人
86
86
  | `mapDefaultCamp` | 地图查询默认阵营(1=监管者,2=求生者) | `1` |
87
87
  | `showBadge` | 显示勋章分数据 | `true` |
88
88
  | `badgeDays` | 勋章日增长率天数 | `7` |
89
- | `width` | 图片宽度(px),其他指令未单独设置时使用该值 | `1000` |
89
+ | `width` | 图片宽度(px),其他指令未单独设置时使用该值 | `1300` |
90
90
  | `mapWidth` | 地图指令图片宽度(px),0=使用默认宽度 | `0` |
91
91
  | `mimicWidth` | 模仿者指令图片宽度(px),0=使用默认宽度 | `0` |
92
92
  | `badgeWidth` | 勋章指令图片宽度(px),0=使用默认宽度 | `0` |