koishi-plugin-dew-bot 1.0.245 → 1.0.246

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/README.md CHANGED
@@ -21,3 +21,33 @@ plugins:
21
21
  | 服务器地址 | 游戏服 WebSocket 地址 | `ws://dew-v7-test:3021` |
22
22
 
23
23
  插件会忽略机器人自己发出的消息,避免回显再次上传形成循环。
24
+
25
+ ## 发布到 npm
26
+
27
+ 在 `bot/external/dew-bot` 目录执行:
28
+
29
+ ```bash
30
+ npm run release
31
+ ```
32
+
33
+ 脚本会先从 `bot` 工作区执行 `npm run build -- dew-bot`,构建成功后运行 `npm version patch --no-git-tag-version --workspaces=false`,再以 `public` 权限和 `latest` 标签发布到 `https://registry.npmjs.org`。例如 `1.0.245` 会提升为 `1.0.246`,不会创建 Git 提交或标签。发布前需已安装工作区依赖,并登录有该包发布权限的 npm 账号:
34
+
35
+ ```bash
36
+ npm login --registry=https://registry.npmjs.org
37
+ ```
38
+
39
+ 仅构建并检查包内容,执行:
40
+
41
+ ```bash
42
+ npm run release:check
43
+ ```
44
+
45
+ 这相当于 `npm run release -- --dry-run`,会真实构建并执行 `npm pack --dry-run`,不会提升版本号、生成压缩包或发布到 npm。
46
+
47
+ 构建失败时脚本会停止,版本不递增。若递增后发布失败,本地保留新版本,脚本会以非零退出码结束并打印当前版本及重试命令;在插件目录确认该版本的发布状态后,可重试同一版本:
48
+
49
+ ```bash
50
+ npm publish --workspaces=false --access=public --tag=latest --registry=https://registry.npmjs.org
51
+ ```
52
+
53
+ 重试发布时不要再次运行 `npm run release`,否则会再次递增版本。
package/lib/index.js CHANGED
@@ -736,47 +736,63 @@ __name(pageCommandLines, "pageCommandLines");
736
736
  function renderQQPageMarkdown(data, showGreeting, showCommands) {
737
737
  const nav = data.pageNav;
738
738
  const entryCommands = new Map(nav?.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
739
+ const listPattern = /^\[(\d+)\]\s*([^\r\n]+)$/;
740
+ const pagePattern = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/;
741
+ const title = data.line.find((item) => item.type === 0 /* title */);
742
+ const summaryLine = data.line.find((item) => item.type === 1 /* line */ && pagePattern.test(item.content));
743
+ const summary = summaryLine && pagePattern.exec(summaryLine.content);
744
+ const listCount = data.line.filter((item) => item.type === 1 /* line */ && listPattern.test(item.content)).length;
745
+ const count = summary?.[1] ?? (nav?.total === 1 ? String(listCount) : void 0);
746
+ const countUnit = summary?.[2] ?? "项";
747
+ const isLeaderboardDirectory = !!nav?.entries?.length && nav.entries.every((entry) => /^排行榜查看\s/.test(entry.viewCommand));
739
748
  const sections = [];
740
749
  const bodyLines = [];
741
- const numberedLines = [];
750
+ const listLines = [];
742
751
  const flushBody = /* @__PURE__ */ __name(() => {
743
752
  if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
744
753
  }, "flushBody");
745
- const flushNumbered = /* @__PURE__ */ __name(() => {
746
- if (numberedLines.length) sections.push(numberedLines.splice(0).join("\n"));
747
- }, "flushNumbered");
754
+ const flushList = /* @__PURE__ */ __name(() => {
755
+ if (listLines.length) sections.push(listLines.splice(0).join(" \n"));
756
+ }, "flushList");
748
757
  const flush = /* @__PURE__ */ __name(() => {
749
- flushNumbered();
758
+ flushList();
750
759
  flushBody();
751
760
  }, "flush");
752
761
  let hasPageSummary = false;
762
+ let hasHelp = false;
763
+ let pageFooter;
753
764
  if (showGreeting) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
754
765
  for (const [lineIndex, item] of data.line.entries()) {
755
766
  switch (item.type) {
756
767
  case 0 /* title */:
757
768
  flush();
758
- sections.push(`### ${escapeMarkdown(item.content)}`);
769
+ if (isLeaderboardDirectory) {
770
+ sections.push(`## ${item.content.includes("🏆") ? "" : "🏆 "}${escapeMarkdown(item.content)}`);
771
+ sections.push(`> 共 ${nav.entries.length} 个榜单 · 点击榜名查看`);
772
+ } else {
773
+ sections.push(`**${escapeMarkdown(item.content)}${count !== void 0 ? ` · ${count} ${countUnit}` : ""}**`);
774
+ }
759
775
  break;
760
776
  case 1 /* line */: {
761
- const numbered = /^\[(\d+)\]\s*([^\r\n]+)$/.exec(item.content);
762
- if (numbered) {
777
+ const listEntry = listPattern.exec(item.content);
778
+ if (listEntry) {
763
779
  flushBody();
764
780
  const command = entryCommands.get(lineIndex);
765
- const label = escapeMarkdown(numbered[2]);
781
+ const label = escapeMarkdown(listEntry[2]);
766
782
  const name2 = command ? `[${label}](${inlineCommandUrl(command)})` : label;
767
- numberedLines.push(`${numbered[1]}. ${name2}`);
783
+ listLines.push(`${escapeMarkdown(`[${listEntry[1]}]`)} ${name2}`);
768
784
  break;
769
785
  }
770
- flushNumbered();
786
+ flushList();
771
787
  if (/^\[指令\]相关指令$/.test(item.content)) {
772
788
  flushBody();
773
- sections.push(`更多操作:[指令](${inlineCommandUrl("指令")})`);
789
+ hasHelp = true;
774
790
  break;
775
791
  }
776
- const page = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/.exec(item.content);
792
+ const page = pagePattern.exec(item.content);
777
793
  if (page && nav) {
778
794
  flushBody();
779
- sections.push(`**第 ${nav.current} / ${nav.total} 页${page[1] ? ` · 共 ${page[1]} ${page[2]}` : ""}**`);
795
+ pageFooter = `**第 ${nav.current} / ${nav.total} 页${!title && page[1] ? ` · 共 ${page[1]} ${page[2]}` : ""}**`;
780
796
  hasPageSummary = true;
781
797
  break;
782
798
  }
@@ -790,7 +806,14 @@ function renderQQPageMarkdown(data, showGreeting, showCommands) {
790
806
  }
791
807
  }
792
808
  flush();
793
- if (nav && !hasPageSummary) sections.push(`**第 ${nav.current} / ${nav.total} 页**`);
809
+ if (nav && !hasPageSummary && (nav.total > 1 || nav.previousCommand || nav.nextCommand))
810
+ pageFooter = `**第 ${nav.current} / ${nav.total} 页**`;
811
+ const helpLink = hasHelp ? `[指令](${inlineCommandUrl("指令")})` : void 0;
812
+ const footer = pageFooter ? [pageFooter, helpLink].filter(Boolean).join(" · ") : helpLink ? `更多操作:${helpLink}` : void 0;
813
+ if (footer) {
814
+ if (isLeaderboardDirectory) sections.push("***");
815
+ sections.push(footer);
816
+ }
794
817
  if (showCommands && nav) {
795
818
  const commands = pageCommandLines(nav);
796
819
  if (commands.length) sections.push(`**翻页指令**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-dew-bot",
3
3
  "description": "连游戏服,把聊天消息交给服务器处理",
4
- "version": "1.0.245",
4
+ "version": "1.0.246",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
@@ -9,6 +9,10 @@
9
9
  "src",
10
10
  "assets"
11
11
  ],
12
+ "scripts": {
13
+ "release": "node scripts/release.cjs",
14
+ "release:check": "node scripts/release.cjs --dry-run"
15
+ },
12
16
  "license": "MIT",
13
17
  "keywords": [
14
18
  "chatbot",
@@ -62,46 +62,63 @@ export function pageCommandLines(nav: PageNavData): string[] {
62
62
  export function renderQQPageMarkdown(data: MsgMessage, showGreeting: boolean, showCommands: boolean): string {
63
63
  const nav = data.pageNav
64
64
  const entryCommands = new Map(nav?.entries?.map(entry => [entry.lineIndex, entry.viewCommand]) ?? [])
65
+ const listPattern = /^\[(\d+)\]\s*([^\r\n]+)$/
66
+ const pagePattern = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/
67
+ const title = data.line.find(item => item.type === MessageType.title)
68
+ const summaryLine = data.line.find(item => item.type === MessageType.line && pagePattern.test(item.content))
69
+ const summary = summaryLine && pagePattern.exec(summaryLine.content)
70
+ const listCount = data.line.filter(item => item.type === MessageType.line && listPattern.test(item.content)).length
71
+ const count = summary?.[1] ?? (nav?.total === 1 ? String(listCount) : undefined)
72
+ const countUnit = summary?.[2] ?? '项'
73
+ const isLeaderboardDirectory = !!nav?.entries?.length
74
+ && nav.entries.every(entry => /^排行榜查看\s/.test(entry.viewCommand))
65
75
  const sections: string[] = []
66
76
  const bodyLines: string[] = []
67
- const numberedLines: string[] = []
77
+ const listLines: string[] = []
68
78
  const flushBody = () => {
69
79
  if (bodyLines.length) sections.push(bodyLines.splice(0).join(' \n'))
70
80
  }
71
- const flushNumbered = () => {
72
- if (numberedLines.length) sections.push(numberedLines.splice(0).join('\n'))
81
+ const flushList = () => {
82
+ if (listLines.length) sections.push(listLines.splice(0).join(' \n'))
73
83
  }
74
- const flush = () => { flushNumbered(); flushBody() }
84
+ const flush = () => { flushList(); flushBody() }
75
85
  let hasPageSummary = false
86
+ let hasHelp = false
87
+ let pageFooter: string | undefined
76
88
  if (showGreeting) sections.push(escapeMarkdown('Ciallo~(∠・ω< )'))
77
89
  for (const [lineIndex, item] of data.line.entries()) {
78
90
  switch (item.type) {
79
91
  case MessageType.title:
80
92
  flush()
81
- sections.push(`### ${escapeMarkdown(item.content)}`)
93
+ if (isLeaderboardDirectory) {
94
+ sections.push(`## ${item.content.includes('🏆') ? '' : '🏆 '}${escapeMarkdown(item.content)}`)
95
+ sections.push(`> 共 ${nav!.entries!.length} 个榜单 · 点击榜名查看`)
96
+ } else {
97
+ sections.push(`**${escapeMarkdown(item.content)}${count !== undefined ? ` · ${count} ${countUnit}` : ''}**`)
98
+ }
82
99
  break
83
100
  case MessageType.line: {
84
- const numbered = /^\[(\d+)\]\s*([^\r\n]+)$/.exec(item.content)
85
- if (numbered) {
101
+ const listEntry = listPattern.exec(item.content)
102
+ if (listEntry) {
86
103
  flushBody()
87
104
  const command = entryCommands.get(lineIndex)
88
- const label = escapeMarkdown(numbered[2])
105
+ const label = escapeMarkdown(listEntry[2])
89
106
  const name = command
90
107
  ? `[${label}](${inlineCommandUrl(command)})`
91
108
  : label
92
- numberedLines.push(`${numbered[1]}. ${name}`)
109
+ listLines.push(`${escapeMarkdown(`[${listEntry[1]}]`)} ${name}`)
93
110
  break
94
111
  }
95
- flushNumbered()
112
+ flushList()
96
113
  if (/^\[指令\]相关指令$/.test(item.content)) {
97
114
  flushBody()
98
- sections.push(`更多操作:[指令](${inlineCommandUrl('指令')})`)
115
+ hasHelp = true
99
116
  break
100
117
  }
101
- const page = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/.exec(item.content)
118
+ const page = pagePattern.exec(item.content)
102
119
  if (page && nav) {
103
120
  flushBody()
104
- sections.push(`**第 ${nav.current} / ${nav.total} 页${page[1] ? ` · 共 ${page[1]} ${page[2]}` : ''}**`)
121
+ pageFooter = `**第 ${nav.current} / ${nav.total} 页${!title && page[1] ? ` · 共 ${page[1]} ${page[2]}` : ''}**`
105
122
  hasPageSummary = true
106
123
  break
107
124
  }
@@ -115,7 +132,16 @@ export function renderQQPageMarkdown(data: MsgMessage, showGreeting: boolean, sh
115
132
  }
116
133
  }
117
134
  flush()
118
- if (nav && !hasPageSummary) sections.push(`**第 ${nav.current} / ${nav.total} 页**`)
135
+ if (nav && !hasPageSummary && (nav.total > 1 || nav.previousCommand || nav.nextCommand))
136
+ pageFooter = `**第 ${nav.current} / ${nav.total} 页**`
137
+ const helpLink = hasHelp ? `[指令](${inlineCommandUrl('指令')})` : undefined
138
+ const footer = pageFooter
139
+ ? [pageFooter, helpLink].filter(Boolean).join(' · ')
140
+ : helpLink ? `更多操作:${helpLink}` : undefined
141
+ if (footer) {
142
+ if (isLeaderboardDirectory) sections.push('***')
143
+ sections.push(footer)
144
+ }
119
145
  if (showCommands && nav) {
120
146
  const commands = pageCommandLines(nav)
121
147
  if (commands.length) sections.push(`**翻页指令** \n${commands.map(escapeMarkdown).join(' \n')}`)