dsh-fish-buddy 0.7.9 → 0.8.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 (3) hide show
  1. package/README.md +10 -0
  2. package/lib/host.js +111 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -31,6 +31,16 @@
31
31
 
32
32
  ## 装好之后怎么配
33
33
 
34
+ **先把插件装上**(已经发布到 npm,不用 git):
35
+
36
+ ```bash
37
+ dsh plugin --profile desktop add dsh-fish-buddy
38
+ ```
39
+
40
+ > 也可以在 npm 上直接看到这个包(含历史版本):<https://www.npmjs.com/package/dsh-fish-buddy>
41
+
42
+ 装完**重启一次 DSH**;挂件那个 exe 另外去 [Releases](https://github.com/Yuuyuko-uu/dsh-fish-buddy/releases) 下。
43
+
34
44
  **DSH 设置 → 鱼搭子**(第一栏):
35
45
 
36
46
  | 项 | 填什么 |
package/lib/host.js CHANGED
@@ -84,6 +84,25 @@ const 默认配置 = {
84
84
  *
85
85
  * 返回 `{ 删了, 剩 }`;目录还不存在也算正常(返回 0/0)。
86
86
  */
87
+
88
+ /**
89
+ * ⭐ 1.6.0:哪些图该拼 —— **只拼 1 分钟以前的**,老的够 2 张就拼。
90
+ * 刚截的那张(还有她自己截图说话发的那张)一律不拼,单发。
91
+ * 纯函数,方便单测。
92
+ */
93
+ export function 该拼哪几张(张们, 现在毫秒) {
94
+ const 现在_ = Number.isFinite(Number(现在毫秒)) ? Number(现在毫秒) : Date.now()
95
+ const 老的 = []
96
+ const 新的 = []
97
+ for (const x of (Array.isArray(张们) ? 张们 : [])) {
98
+ if (!x || !x.路) continue
99
+ const 时 = Number((x && x.时) || 0)
100
+ if (时 > 0 && 现在_ - 时 >= 60 * 1000) 老的.push(x)
101
+ else 新的.push(x)
102
+ }
103
+ return { 老的, 新的, 该拼: 老的.length >= 2 }
104
+ }
105
+
87
106
  export function 清旧截图(目录, 保留天 = 0, 最多张 = 0, 现在毫秒 = Date.now()) {
88
107
  const 结果 = { 删了: 0, 剩: 0 }
89
108
  let 名们 = []
@@ -753,7 +772,28 @@ export function apply(ctx, inlineConfig) {
753
772
  const 图路 = await 问挂件要张图()
754
773
  if (图路) 张们 = [{ 路: 图路, 时: 现在() }]
755
774
  }
756
- for (const x of 张们) {
775
+ // ⭐ 1.6.0:**只拼 1 分钟以前的**,够 2 张就拼;刚截的那张单发不拼
776
+ const 分 = 该拼哪几张(张们, 现在())
777
+ let 拼好了 = false
778
+ if (分.该拼) {
779
+ const 拼这几张 = 分.老的.slice(-3)
780
+ const 拼图 = await 请挂件拼图(拼这几张)
781
+ if (拼图) {
782
+ try {
783
+ 内容.push({ type: 'text', text: '(这 ' + 拼这几张.length + ' 张画面拼成了一张,从上到下;每格左上角是多久前)' })
784
+ 内容.push(await 做图片块从字节(Buffer.from(拼图, 'base64'), '游戏画面'))
785
+ 拼好了 = true
786
+ } catch (error) {
787
+ 记账('拼好的那张没贴进去(退回单张):' + 说(error))
788
+ }
789
+ }
790
+ if (拼好了) {
791
+ for (const x of 分.老的.slice(0, -3)) {
792
+ try { 内容.push(await 做图片块(x.路, '游戏画面')) } catch (error) {}
793
+ }
794
+ }
795
+ }
796
+ for (const x of (拼好了 ? 分.新的 : 张们)) {
757
797
  if (!x || !x.路) continue
758
798
  const 差 = Math.abs(现在() - Number(x.时 || 0))
759
799
  if (差 > 45000) 内容.push({ type: 'text', text: '(下面这张是 ' + 多久前(x.时) + '的画面)' })
@@ -1385,6 +1425,48 @@ export function apply(ctx, inlineConfig) {
1385
1425
  * ⭐ 1.0.5:图片块要**先存成附件**,再引用它。
1386
1426
  * 宿主只认 `{ type:'image', attachment: { attachmentId, … } }`。
1387
1427
  */
1428
+
1429
+ /** 请挂件把几张拼成一竖条,返回 base64;不成返回空串 */
1430
+ const 请挂件拼图 = async (张们) => {
1431
+ if (!Array.isArray(张们) || 张们.length < 2) return ''
1432
+ const 控 = new AbortController()
1433
+ const 停 = setTimeout(() => 控.abort(), 15000)
1434
+ try {
1435
+ const r = await fetch(挂件基址() + '/hands/stitch', {
1436
+ method: 'POST',
1437
+ headers: { 'content-type': 'application/json' },
1438
+ body: JSON.stringify({ 帧们: 张们.map((x) => ({ 路径: x.路, 标: '· ' + 多久前(x.时) })) }),
1439
+ signal: 控.signal,
1440
+ })
1441
+ clearTimeout(停)
1442
+ if (!r.ok) return ''
1443
+ const j = await r.json()
1444
+ if (!j || !j.ok || !j.图片) {
1445
+ 记账('拼图没成:' + String((j && j.说) || '挂件没回图片'))
1446
+ return ''
1447
+ }
1448
+ return String(j.图片)
1449
+ } catch (error) {
1450
+ 记账('拼图请求失败:' + String((error && error.message) || error))
1451
+ return ''
1452
+ } finally {
1453
+ clearTimeout(停)
1454
+ }
1455
+ }
1456
+
1457
+ const 做图片块从字节 = async (字节, 名) => {
1458
+ const 附件服务 = 取服务('attachments')
1459
+ if (!附件服务 || typeof 附件服务.saveImage !== 'function') {
1460
+ throw new Error('这个宿主没给 attachments 服务,图片发不进去')
1461
+ }
1462
+ const ref = await 附件服务.saveImage({
1463
+ data: new Uint8Array(字节),
1464
+ mediaType: 'image/jpeg',
1465
+ name: 名 || '画面',
1466
+ })
1467
+ return { type: 'image', attachment: ref }
1468
+ }
1469
+
1388
1470
  const 做图片块 = async (路, 名) => {
1389
1471
  const 附件服务 = 取服务('attachments')
1390
1472
  if (!附件服务 || typeof 附件服务.saveImage !== 'function') {
@@ -1456,15 +1538,35 @@ export function apply(ctx, inlineConfig) {
1456
1538
  try {
1457
1539
  // ⭐ 0.6.0:可以带**多张**(攒着的几张一起给);不是刚截的,前面标一句「几分钟前」
1458
1540
  const 内容 = [{ type: 'text', text: 话 || '(看这个)' }]
1459
- const 张们 = Array.isArray(路们) ? 路们 : [{ 路: 路们, 时: 现在() }]
1460
- for (const x of 张们) {
1461
- const 路 = typeof x === 'string' ? x : x && x.路
1462
- if (!路) continue
1463
- const 时 = typeof x === 'string' ? 现在() : (x && x.时) || 现在()
1541
+ const 原们 = Array.isArray(路们) ? 路们 : [{ 路: 路们, 时: 现在() }]
1542
+ const 张们 = 原们.map((x) => (typeof x === 'string' ? { 路: x, 时: 现在() } : { 路: x && x.路, 时: (x && x.时) || 现在() }))
1543
+ .filter((x) => x.路)
1544
+ // ⭐ 1.6.0:**只拼 1 分钟以前的**,够 2 张就拼;刚截的那张(还有她自己截图发的那张)单发不拼
1545
+ const 分 = 该拼哪几张(张们, 现在())
1546
+ let 拼好了 = false
1547
+ if (分.该拼) {
1548
+ const 拼这几张 = 分.老的.slice(-3) // 最多拼 3 张(取最新的 3 张老图;2 张就全带上)
1549
+ const 拼图 = await 请挂件拼图(拼这几张)
1550
+ if (拼图) {
1551
+ try {
1552
+ 内容.push({ type: 'text', text: '(这 ' + 拼这几张.length + ' 张画面拼成了一张,从上到下;每格左上角是多久前)' })
1553
+ 内容.push(await 做图片块从字节(Buffer.from(拼图, 'base64'), '说话时的画面'))
1554
+ 拼好了 = true
1555
+ } catch (error) {
1556
+ 记账('拼好的那张没贴进去(退回单张):' + 说(error))
1557
+ }
1558
+ }
1559
+ if (拼好了) {
1560
+ for (const x of 分.老的.slice(0, -3)) {
1561
+ try { 内容.push(await 做图片块(x.路, '说话时的画面')) } catch (error) {}
1562
+ }
1563
+ }
1564
+ }
1565
+ for (const x of (拼好了 ? 分.新的 : 张们)) {
1464
1566
  try {
1465
- const 差 = Math.abs(现在() - Number(时 || 0))
1466
- if (差 > 45000) 内容.push({ type: 'text', text: '(上面那张是 ' + 多久前(时) + '的画面)' })
1467
- 内容.push(await 做图片块(路, '说话时的画面'))
1567
+ const 差 = Math.abs(现在() - Number(x.时 || 0))
1568
+ if (差 > 45000) 内容.push({ type: 'text', text: '(上面那张是 ' + 多久前(x.时) + '的画面)' })
1569
+ 内容.push(await 做图片块(x.路, '说话时的画面'))
1468
1570
  } catch (error) {
1469
1571
  记账('这一张没拼进去(' + 说(error) + ')')
1470
1572
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-fish-buddy",
3
- "version": "0.7.9",
3
+ "version": "0.8.0",
4
4
  "description": "鱼搭子 · DSH 这半边:桌面小挂件说的话送进你绑定的会话,她的回话再递回挂件。挂件是独立程序,这里只负责接线。",
5
5
  "license": "MIT",
6
6
  "type": "module",