koishi-plugin-dew-bot 1.0.244 → 1.0.245
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/lib/index.js
CHANGED
|
@@ -721,6 +721,11 @@ function pageCommand(command) {
|
|
|
721
721
|
return command.startsWith("/") ? command : `/${command}`;
|
|
722
722
|
}
|
|
723
723
|
__name(pageCommand, "pageCommand");
|
|
724
|
+
function inlineCommandUrl(command) {
|
|
725
|
+
const encoded = encodeURIComponent(pageCommand(command)).replace(/[!'()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
726
|
+
return `mqqapi://aio/inlinecmd?command=${encoded}&enter=true&reply=false`;
|
|
727
|
+
}
|
|
728
|
+
__name(inlineCommandUrl, "inlineCommandUrl");
|
|
724
729
|
function pageCommandLines(nav) {
|
|
725
730
|
return [
|
|
726
731
|
...nav.previousCommand ? [`上一页:${pageCommand(nav.previousCommand)}`] : [],
|
|
@@ -729,23 +734,67 @@ function pageCommandLines(nav) {
|
|
|
729
734
|
}
|
|
730
735
|
__name(pageCommandLines, "pageCommandLines");
|
|
731
736
|
function renderQQPageMarkdown(data, showGreeting, showCommands) {
|
|
737
|
+
const nav = data.pageNav;
|
|
738
|
+
const entryCommands = new Map(nav?.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
732
739
|
const sections = [];
|
|
740
|
+
const bodyLines = [];
|
|
741
|
+
const numberedLines = [];
|
|
742
|
+
const flushBody = /* @__PURE__ */ __name(() => {
|
|
743
|
+
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
744
|
+
}, "flushBody");
|
|
745
|
+
const flushNumbered = /* @__PURE__ */ __name(() => {
|
|
746
|
+
if (numberedLines.length) sections.push(numberedLines.splice(0).join("\n"));
|
|
747
|
+
}, "flushNumbered");
|
|
748
|
+
const flush = /* @__PURE__ */ __name(() => {
|
|
749
|
+
flushNumbered();
|
|
750
|
+
flushBody();
|
|
751
|
+
}, "flush");
|
|
752
|
+
let hasPageSummary = false;
|
|
733
753
|
if (showGreeting) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
734
|
-
for (const item of data.line) {
|
|
754
|
+
for (const [lineIndex, item] of data.line.entries()) {
|
|
735
755
|
switch (item.type) {
|
|
736
756
|
case 0 /* title */:
|
|
757
|
+
flush();
|
|
737
758
|
sections.push(`### ${escapeMarkdown(item.content)}`);
|
|
738
759
|
break;
|
|
739
|
-
case 1 /* line */:
|
|
740
|
-
|
|
760
|
+
case 1 /* line */: {
|
|
761
|
+
const numbered = /^\[(\d+)\]\s*([^\r\n]+)$/.exec(item.content);
|
|
762
|
+
if (numbered) {
|
|
763
|
+
flushBody();
|
|
764
|
+
const command = entryCommands.get(lineIndex);
|
|
765
|
+
const label = escapeMarkdown(numbered[2]);
|
|
766
|
+
const name2 = command ? `[${label}](${inlineCommandUrl(command)})` : label;
|
|
767
|
+
numberedLines.push(`${numbered[1]}. ${name2}`);
|
|
768
|
+
break;
|
|
769
|
+
}
|
|
770
|
+
flushNumbered();
|
|
771
|
+
if (/^\[指令\]相关指令$/.test(item.content)) {
|
|
772
|
+
flushBody();
|
|
773
|
+
sections.push(`更多操作:[指令](${inlineCommandUrl("指令")})`);
|
|
774
|
+
break;
|
|
775
|
+
}
|
|
776
|
+
const page = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/.exec(item.content);
|
|
777
|
+
if (page && nav) {
|
|
778
|
+
flushBody();
|
|
779
|
+
sections.push(`**第 ${nav.current} / ${nav.total} 页${page[1] ? ` · 共 ${page[1]} ${page[2]}` : ""}**`);
|
|
780
|
+
hasPageSummary = true;
|
|
781
|
+
break;
|
|
782
|
+
}
|
|
783
|
+
bodyLines.push(escapeMarkdown(item.content));
|
|
741
784
|
break;
|
|
785
|
+
}
|
|
742
786
|
case 2 /* error */:
|
|
787
|
+
flush();
|
|
743
788
|
sections.push(`❌ 出错了!错误原因:${escapeMarkdown(item.content)},请反馈至联系开发者`);
|
|
744
789
|
break;
|
|
745
790
|
}
|
|
746
791
|
}
|
|
747
|
-
|
|
748
|
-
|
|
792
|
+
flush();
|
|
793
|
+
if (nav && !hasPageSummary) sections.push(`**第 ${nav.current} / ${nav.total} 页**`);
|
|
794
|
+
if (showCommands && nav) {
|
|
795
|
+
const commands = pageCommandLines(nav);
|
|
796
|
+
if (commands.length) sections.push(`**翻页指令**
|
|
797
|
+
${commands.map(escapeMarkdown).join(" \n")}`);
|
|
749
798
|
}
|
|
750
799
|
return sections.join("\n\n") || " ";
|
|
751
800
|
}
|
|
@@ -783,14 +832,16 @@ async function sendQQPage(session, data, withKeyboard) {
|
|
|
783
832
|
const nav = data.pageNav;
|
|
784
833
|
const buttons = withKeyboard ? buttonsFor(nav, data.userId, session.isDirect) : [];
|
|
785
834
|
const markdown = renderQQPageMarkdown(data, session.event?.channel?.type === 0, buttons.length === 0);
|
|
835
|
+
const hasEntries = !!nav.entries?.length;
|
|
836
|
+
const hasInlineHelp = data.line.some((item) => item.type === 1 /* line */ && item.content === "[指令]相关指令");
|
|
786
837
|
const request = {
|
|
787
838
|
// With msg_type=2, QQ requires the ordinary content field to be empty.
|
|
788
839
|
content: "",
|
|
789
840
|
msg_type: 2,
|
|
790
841
|
markdown: {
|
|
791
|
-
content:
|
|
842
|
+
content: !session.isDirect && (buttons.length || hasEntries || hasInlineHelp) ? `${markdown}
|
|
792
843
|
|
|
793
|
-
|
|
844
|
+
点击后如未自动发送,请点发送。` : markdown
|
|
794
845
|
},
|
|
795
846
|
...buttons.length ? { keyboard: { content: { rows: [{ buttons }] } } } : {}
|
|
796
847
|
};
|
|
@@ -912,7 +963,7 @@ var import_tsrpc = require("tsrpc");
|
|
|
912
963
|
|
|
913
964
|
// src/shared/bot/serviceProto.ts
|
|
914
965
|
var serviceProto = {
|
|
915
|
-
"version":
|
|
966
|
+
"version": 10,
|
|
916
967
|
"services": [
|
|
917
968
|
{
|
|
918
969
|
"id": 0,
|
|
@@ -1665,6 +1716,33 @@ var serviceProto = {
|
|
|
1665
1716
|
"type": "String"
|
|
1666
1717
|
},
|
|
1667
1718
|
"optional": true
|
|
1719
|
+
},
|
|
1720
|
+
{
|
|
1721
|
+
"id": 4,
|
|
1722
|
+
"name": "entries",
|
|
1723
|
+
"type": {
|
|
1724
|
+
"type": "Array",
|
|
1725
|
+
"elementType": {
|
|
1726
|
+
"type": "Interface",
|
|
1727
|
+
"properties": [
|
|
1728
|
+
{
|
|
1729
|
+
"id": 0,
|
|
1730
|
+
"name": "lineIndex",
|
|
1731
|
+
"type": {
|
|
1732
|
+
"type": "Number"
|
|
1733
|
+
}
|
|
1734
|
+
},
|
|
1735
|
+
{
|
|
1736
|
+
"id": 1,
|
|
1737
|
+
"name": "viewCommand",
|
|
1738
|
+
"type": {
|
|
1739
|
+
"type": "String"
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
]
|
|
1743
|
+
}
|
|
1744
|
+
},
|
|
1745
|
+
"optional": true
|
|
1668
1746
|
}
|
|
1669
1747
|
]
|
|
1670
1748
|
},
|
|
@@ -114,6 +114,11 @@ export interface PageNavData {
|
|
|
114
114
|
total: number;
|
|
115
115
|
previousCommand?: string;
|
|
116
116
|
nextCommand?: string;
|
|
117
|
+
/** 可点击的列表行;lineIndex 是 IMessage.line 的零起始位置。 */
|
|
118
|
+
entries?: Array<{
|
|
119
|
+
lineIndex: number;
|
|
120
|
+
viewCommand: string;
|
|
121
|
+
}>;
|
|
117
122
|
}
|
|
118
123
|
/** 下发给客户端的消息主体 **/
|
|
119
124
|
export interface IMessage {
|
package/package.json
CHANGED
|
@@ -44,6 +44,14 @@ export function pageCommand(command: string): string {
|
|
|
44
44
|
return command.startsWith('/') ? command : `/${command}`
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function inlineCommandUrl(command: string): string {
|
|
48
|
+
// encodeURIComponent leaves parentheses unescaped, which would close the
|
|
49
|
+
// surrounding Markdown link if an item ID ever contained one.
|
|
50
|
+
const encoded = encodeURIComponent(pageCommand(command)).replace(/[!'()*]/g, character =>
|
|
51
|
+
`%${character.charCodeAt(0).toString(16).toUpperCase()}`)
|
|
52
|
+
return `mqqapi://aio/inlinecmd?command=${encoded}&enter=true&reply=false`
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
export function pageCommandLines(nav: PageNavData): string[] {
|
|
48
56
|
return [
|
|
49
57
|
...(nav.previousCommand ? [`上一页:${pageCommand(nav.previousCommand)}`] : []),
|
|
@@ -52,23 +60,65 @@ export function pageCommandLines(nav: PageNavData): string[] {
|
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
export function renderQQPageMarkdown(data: MsgMessage, showGreeting: boolean, showCommands: boolean): string {
|
|
63
|
+
const nav = data.pageNav
|
|
64
|
+
const entryCommands = new Map(nav?.entries?.map(entry => [entry.lineIndex, entry.viewCommand]) ?? [])
|
|
55
65
|
const sections: string[] = []
|
|
66
|
+
const bodyLines: string[] = []
|
|
67
|
+
const numberedLines: string[] = []
|
|
68
|
+
const flushBody = () => {
|
|
69
|
+
if (bodyLines.length) sections.push(bodyLines.splice(0).join(' \n'))
|
|
70
|
+
}
|
|
71
|
+
const flushNumbered = () => {
|
|
72
|
+
if (numberedLines.length) sections.push(numberedLines.splice(0).join('\n'))
|
|
73
|
+
}
|
|
74
|
+
const flush = () => { flushNumbered(); flushBody() }
|
|
75
|
+
let hasPageSummary = false
|
|
56
76
|
if (showGreeting) sections.push(escapeMarkdown('Ciallo~(∠・ω< )'))
|
|
57
|
-
for (const item of data.line) {
|
|
77
|
+
for (const [lineIndex, item] of data.line.entries()) {
|
|
58
78
|
switch (item.type) {
|
|
59
79
|
case MessageType.title:
|
|
80
|
+
flush()
|
|
60
81
|
sections.push(`### ${escapeMarkdown(item.content)}`)
|
|
61
82
|
break
|
|
62
|
-
case MessageType.line:
|
|
63
|
-
|
|
83
|
+
case MessageType.line: {
|
|
84
|
+
const numbered = /^\[(\d+)\]\s*([^\r\n]+)$/.exec(item.content)
|
|
85
|
+
if (numbered) {
|
|
86
|
+
flushBody()
|
|
87
|
+
const command = entryCommands.get(lineIndex)
|
|
88
|
+
const label = escapeMarkdown(numbered[2])
|
|
89
|
+
const name = command
|
|
90
|
+
? `[${label}](${inlineCommandUrl(command)})`
|
|
91
|
+
: label
|
|
92
|
+
numberedLines.push(`${numbered[1]}. ${name}`)
|
|
93
|
+
break
|
|
94
|
+
}
|
|
95
|
+
flushNumbered()
|
|
96
|
+
if (/^\[指令\]相关指令$/.test(item.content)) {
|
|
97
|
+
flushBody()
|
|
98
|
+
sections.push(`更多操作:[指令](${inlineCommandUrl('指令')})`)
|
|
99
|
+
break
|
|
100
|
+
}
|
|
101
|
+
const page = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/.exec(item.content)
|
|
102
|
+
if (page && nav) {
|
|
103
|
+
flushBody()
|
|
104
|
+
sections.push(`**第 ${nav.current} / ${nav.total} 页${page[1] ? ` · 共 ${page[1]} ${page[2]}` : ''}**`)
|
|
105
|
+
hasPageSummary = true
|
|
106
|
+
break
|
|
107
|
+
}
|
|
108
|
+
bodyLines.push(escapeMarkdown(item.content))
|
|
64
109
|
break
|
|
110
|
+
}
|
|
65
111
|
case MessageType.error:
|
|
112
|
+
flush()
|
|
66
113
|
sections.push(`❌ 出错了!错误原因:${escapeMarkdown(item.content)},请反馈至联系开发者`)
|
|
67
114
|
break
|
|
68
115
|
}
|
|
69
116
|
}
|
|
70
|
-
|
|
71
|
-
|
|
117
|
+
flush()
|
|
118
|
+
if (nav && !hasPageSummary) sections.push(`**第 ${nav.current} / ${nav.total} 页**`)
|
|
119
|
+
if (showCommands && nav) {
|
|
120
|
+
const commands = pageCommandLines(nav)
|
|
121
|
+
if (commands.length) sections.push(`**翻页指令** \n${commands.map(escapeMarkdown).join(' \n')}`)
|
|
72
122
|
}
|
|
73
123
|
return sections.join('\n\n') || ' '
|
|
74
124
|
}
|
|
@@ -108,13 +158,15 @@ export async function sendQQPage(session: Session, data: MsgMessage, withKeyboar
|
|
|
108
158
|
const nav = data.pageNav!
|
|
109
159
|
const buttons = withKeyboard ? buttonsFor(nav, data.userId, session.isDirect) : []
|
|
110
160
|
const markdown = renderQQPageMarkdown(data, session.event?.channel?.type === 0, buttons.length === 0)
|
|
161
|
+
const hasEntries = !!nav.entries?.length
|
|
162
|
+
const hasInlineHelp = data.line.some(item => item.type === MessageType.line && item.content === '[指令]相关指令')
|
|
111
163
|
const request: QQRequest = {
|
|
112
164
|
// With msg_type=2, QQ requires the ordinary content field to be empty.
|
|
113
165
|
content: '',
|
|
114
166
|
msg_type: 2,
|
|
115
167
|
markdown: {
|
|
116
|
-
content: buttons.length
|
|
117
|
-
? `${markdown}\n\n
|
|
168
|
+
content: !session.isDirect && (buttons.length || hasEntries || hasInlineHelp)
|
|
169
|
+
? `${markdown}\n\n点击后如未自动发送,请点发送。`
|
|
118
170
|
: markdown,
|
|
119
171
|
},
|
|
120
172
|
...(buttons.length ? { keyboard: { content: { rows: [{ buttons }] } } } : {}),
|
|
@@ -20,7 +20,7 @@ export interface ServiceType {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const serviceProto: ServiceProto<ServiceType> = {
|
|
23
|
-
"version":
|
|
23
|
+
"version": 10,
|
|
24
24
|
"services": [
|
|
25
25
|
{
|
|
26
26
|
"id": 0,
|
|
@@ -773,6 +773,33 @@ export const serviceProto: ServiceProto<ServiceType> = {
|
|
|
773
773
|
"type": "String"
|
|
774
774
|
},
|
|
775
775
|
"optional": true
|
|
776
|
+
},
|
|
777
|
+
{
|
|
778
|
+
"id": 4,
|
|
779
|
+
"name": "entries",
|
|
780
|
+
"type": {
|
|
781
|
+
"type": "Array",
|
|
782
|
+
"elementType": {
|
|
783
|
+
"type": "Interface",
|
|
784
|
+
"properties": [
|
|
785
|
+
{
|
|
786
|
+
"id": 0,
|
|
787
|
+
"name": "lineIndex",
|
|
788
|
+
"type": {
|
|
789
|
+
"type": "Number"
|
|
790
|
+
}
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
"id": 1,
|
|
794
|
+
"name": "viewCommand",
|
|
795
|
+
"type": {
|
|
796
|
+
"type": "String"
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
]
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
"optional": true
|
|
776
803
|
}
|
|
777
804
|
]
|
|
778
805
|
},
|
package/src/shared/face/index.ts
CHANGED