@dsh-plugin/dsh-synapse 0.1.0-dev.41044228975 → 0.1.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.
- package/LICENSE +661 -661
- package/README.md +0 -14
- package/package.json +1 -1
- package/vendor/gugle-chat-bot/LICENSE +661 -661
- package/vendor/gugle-chat-bot/package.json +57 -57
- package/vendor/gugle-chat-bot/src/allow-rule.yml +9345 -9345
- package/vendor/gugle-chat-bot/src/api.json +4284 -4284
- package/vendor/gugle-chat-bot/src/command/index.ts +141 -141
- package/vendor/gugle-chat-bot/src/config/features.ts +547 -547
- package/vendor/gugle-chat-bot/src/config/index.ts +184 -184
- package/vendor/gugle-chat-bot/src/config/manager.ts +356 -356
- package/vendor/gugle-chat-bot/src/constants/index.ts +13 -13
- package/vendor/gugle-chat-bot/src/custom.ts +548 -548
- package/vendor/gugle-chat-bot/src/event/index.ts +118 -118
- package/vendor/gugle-chat-bot/src/features/admin/index.ts +414 -414
- package/vendor/gugle-chat-bot/src/features/bili/image/impl/video.ts +39 -39
- package/vendor/gugle-chat-bot/src/features/bili/image/index.ts +37 -37
- package/vendor/gugle-chat-bot/src/features/bili/index.ts +65 -65
- package/vendor/gugle-chat-bot/src/features/bili/template/style/video.css +97 -97
- package/vendor/gugle-chat-bot/src/features/bili/template/video.html +56 -56
- package/vendor/gugle-chat-bot/src/features/discord-bridge/index.ts +1128 -1128
- package/vendor/gugle-chat-bot/src/features/discord-bridge/markdown.ts +105 -105
- package/vendor/gugle-chat-bot/src/features/discord-bridge/slash.ts +355 -355
- package/vendor/gugle-chat-bot/src/features/discord-bridge/source.ts +96 -96
- package/vendor/gugle-chat-bot/src/features/discord-bridge/template/message.html +14 -14
- package/vendor/gugle-chat-bot/src/features/discord-bridge/template/style/message.css +144 -144
- package/vendor/gugle-chat-bot/src/features/github/api.ts +93 -93
- package/vendor/gugle-chat-bot/src/features/github/binding.ts +161 -161
- package/vendor/gugle-chat-bot/src/features/github/image/impl/issue.ts +132 -132
- package/vendor/gugle-chat-bot/src/features/github/image/impl/pr.ts +144 -144
- package/vendor/gugle-chat-bot/src/features/github/image/impl/release.ts +160 -160
- package/vendor/gugle-chat-bot/src/features/github/image/index.ts +310 -310
- package/vendor/gugle-chat-bot/src/features/github/index.ts +302 -302
- package/vendor/gugle-chat-bot/src/features/github/template/issue.html +118 -118
- package/vendor/gugle-chat-bot/src/features/github/template/pull_request.html +125 -125
- package/vendor/gugle-chat-bot/src/features/github/template/release.html +53 -53
- package/vendor/gugle-chat-bot/src/features/github/template/style/issue.css +468 -468
- package/vendor/gugle-chat-bot/src/features/github/template/style/pull_request.css +468 -468
- package/vendor/gugle-chat-bot/src/features/github/template/style/release.css +412 -412
- package/vendor/gugle-chat-bot/src/features/hermes/client.ts +184 -184
- package/vendor/gugle-chat-bot/src/features/hermes/config.ts +210 -210
- package/vendor/gugle-chat-bot/src/features/hermes/context.ts +67 -67
- package/vendor/gugle-chat-bot/src/features/hermes/history.ts +86 -86
- package/vendor/gugle-chat-bot/src/features/hermes/index.ts +1533 -1533
- package/vendor/gugle-chat-bot/src/features/hermes/message.ts +319 -319
- package/vendor/gugle-chat-bot/src/features/hermes/reaction.ts +181 -181
- package/vendor/gugle-chat-bot/src/features/hermes/render.ts +118 -118
- package/vendor/gugle-chat-bot/src/features/hermes/reply-units.ts +331 -331
- package/vendor/gugle-chat-bot/src/features/hermes/skills.ts +406 -406
- package/vendor/gugle-chat-bot/src/features/hermes/template/approval.html +30 -30
- package/vendor/gugle-chat-bot/src/features/hermes/template/progress.html +21 -21
- package/vendor/gugle-chat-bot/src/features/hermes/template/style/approval.css +81 -81
- package/vendor/gugle-chat-bot/src/features/hermes/template/style/progress.css +120 -120
- package/vendor/gugle-chat-bot/src/features/hermes/trigger.ts +86 -86
- package/vendor/gugle-chat-bot/src/features/hermes/types.ts +327 -327
- package/vendor/gugle-chat-bot/src/features/management/index.ts +156 -156
- package/vendor/gugle-chat-bot/src/features/minecraft/index.ts +127 -127
- package/vendor/gugle-chat-bot/src/features/modrinth/index.ts +71 -71
- package/vendor/gugle-chat-bot/src/features/parentheses/index.ts +117 -117
- package/vendor/gugle-chat-bot/src/features/peak-valley-timer/index.ts +451 -451
- package/vendor/gugle-chat-bot/src/features/poke/index.ts +24 -24
- package/vendor/gugle-chat-bot/src/features/version-tracker/index.ts +77 -77
- package/vendor/gugle-chat-bot/src/features/welcome/index.ts +57 -57
- package/vendor/gugle-chat-bot/src/github-ip.json +5814 -5814
- package/vendor/gugle-chat-bot/src/image/index.ts +278 -278
- package/vendor/gugle-chat-bot/src/index.ts +695 -695
- package/vendor/gugle-chat-bot/src/logger/index.ts +54 -54
- package/vendor/gugle-chat-bot/src/result.json +359 -359
- package/vendor/gugle-chat-bot/src/type/bili.d.ts +825 -825
- package/vendor/gugle-chat-bot/src/type/event.d.ts +146 -146
- package/vendor/gugle-chat-bot/src/type/github.d.ts +446 -446
- package/vendor/gugle-chat-bot/src/type/index.d.ts +254 -254
- package/vendor/gugle-chat-bot/tsconfig.json +46 -46
- package/scripts/dump-npm-latest.mjs +0 -30
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
import axios, { AxiosResponse } from 'axios';
|
|
2
|
-
import { Message } from '@/type';
|
|
3
|
-
import { getFeatureGroups } from '@/config/features';
|
|
4
|
-
import { checkReleasedVersion, parseMavenLastUpdated } from '@/features/version-tracker';
|
|
5
|
-
import { QQBot } from '@/index';
|
|
6
|
-
|
|
7
|
-
export declare type ModrinthVersion = {
|
|
8
|
-
success: boolean;
|
|
9
|
-
latest: string;
|
|
10
|
-
/** Maven <lastUpdated>(14 位 YYYYMMDDHHmmss)/ 13 位毫秒时间戳 / ISO,解析为毫秒;无则 0 */
|
|
11
|
-
lastUpdated: number;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export class ModrinthAPI {
|
|
15
|
-
public static async getModVersion(slug: string): Promise<ModrinthVersion> {
|
|
16
|
-
try {
|
|
17
|
-
const res: AxiosResponse<string> = await axios.get(
|
|
18
|
-
`https://api.modrinth.com/maven/maven/modrinth/${slug}/maven-metadata.xml`
|
|
19
|
-
);
|
|
20
|
-
const xml = res.data;
|
|
21
|
-
|
|
22
|
-
// Parse XML to extract latest version
|
|
23
|
-
const latestMatch = xml.match(/<latest>(.*?)<\/latest>/);
|
|
24
|
-
if (!latestMatch || !latestMatch[1]) {
|
|
25
|
-
return {
|
|
26
|
-
success: false,
|
|
27
|
-
latest: '',
|
|
28
|
-
lastUpdated: 0
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Parse <lastUpdated>(标准 Maven 元数据时间戳,单调递增)
|
|
33
|
-
const lastUpdatedMatch = xml.match(/<lastUpdated>(.*?)<\/lastUpdated>/);
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
success: true,
|
|
37
|
-
latest: latestMatch[1],
|
|
38
|
-
lastUpdated: parseMavenLastUpdated(lastUpdatedMatch?.[1] || '')
|
|
39
|
-
};
|
|
40
|
-
} catch (_) {
|
|
41
|
-
return {
|
|
42
|
-
success: false,
|
|
43
|
-
latest: '',
|
|
44
|
-
lastUpdated: 0
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public static checkVersion(bot: QQBot, slug: string, name: string) {
|
|
50
|
-
ModrinthAPI.getModVersion(slug).then(version => {
|
|
51
|
-
if (!version.success) return;
|
|
52
|
-
// 用 Maven lastUpdated 时间戳单调性判断新发布,避免 CDN 缓存抖动重复发送
|
|
53
|
-
checkReleasedVersion(`modrinth:${slug}`, version.latest, version.lastUpdated).then((shouldNotify: boolean) => {
|
|
54
|
-
if (!shouldNotify) return;
|
|
55
|
-
const msg: Message[] = [
|
|
56
|
-
{
|
|
57
|
-
type: 'text',
|
|
58
|
-
data: {
|
|
59
|
-
text: `${name}更新了!
|
|
60
|
-
· 最新版本:${version.latest}
|
|
61
|
-
· 下载直链:https://api.modrinth.com/maven/maven/modrinth/${slug}/${version.latest}/${slug}-${version.latest}.jar`
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
];
|
|
65
|
-
for (const listener of getFeatureGroups('modrinth')) {
|
|
66
|
-
bot.sendGroupMsg(listener, msg);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
1
|
+
import axios, { AxiosResponse } from 'axios';
|
|
2
|
+
import { Message } from '@/type';
|
|
3
|
+
import { getFeatureGroups } from '@/config/features';
|
|
4
|
+
import { checkReleasedVersion, parseMavenLastUpdated } from '@/features/version-tracker';
|
|
5
|
+
import { QQBot } from '@/index';
|
|
6
|
+
|
|
7
|
+
export declare type ModrinthVersion = {
|
|
8
|
+
success: boolean;
|
|
9
|
+
latest: string;
|
|
10
|
+
/** Maven <lastUpdated>(14 位 YYYYMMDDHHmmss)/ 13 位毫秒时间戳 / ISO,解析为毫秒;无则 0 */
|
|
11
|
+
lastUpdated: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export class ModrinthAPI {
|
|
15
|
+
public static async getModVersion(slug: string): Promise<ModrinthVersion> {
|
|
16
|
+
try {
|
|
17
|
+
const res: AxiosResponse<string> = await axios.get(
|
|
18
|
+
`https://api.modrinth.com/maven/maven/modrinth/${slug}/maven-metadata.xml`
|
|
19
|
+
);
|
|
20
|
+
const xml = res.data;
|
|
21
|
+
|
|
22
|
+
// Parse XML to extract latest version
|
|
23
|
+
const latestMatch = xml.match(/<latest>(.*?)<\/latest>/);
|
|
24
|
+
if (!latestMatch || !latestMatch[1]) {
|
|
25
|
+
return {
|
|
26
|
+
success: false,
|
|
27
|
+
latest: '',
|
|
28
|
+
lastUpdated: 0
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Parse <lastUpdated>(标准 Maven 元数据时间戳,单调递增)
|
|
33
|
+
const lastUpdatedMatch = xml.match(/<lastUpdated>(.*?)<\/lastUpdated>/);
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
success: true,
|
|
37
|
+
latest: latestMatch[1],
|
|
38
|
+
lastUpdated: parseMavenLastUpdated(lastUpdatedMatch?.[1] || '')
|
|
39
|
+
};
|
|
40
|
+
} catch (_) {
|
|
41
|
+
return {
|
|
42
|
+
success: false,
|
|
43
|
+
latest: '',
|
|
44
|
+
lastUpdated: 0
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public static checkVersion(bot: QQBot, slug: string, name: string) {
|
|
50
|
+
ModrinthAPI.getModVersion(slug).then(version => {
|
|
51
|
+
if (!version.success) return;
|
|
52
|
+
// 用 Maven lastUpdated 时间戳单调性判断新发布,避免 CDN 缓存抖动重复发送
|
|
53
|
+
checkReleasedVersion(`modrinth:${slug}`, version.latest, version.lastUpdated).then((shouldNotify: boolean) => {
|
|
54
|
+
if (!shouldNotify) return;
|
|
55
|
+
const msg: Message[] = [
|
|
56
|
+
{
|
|
57
|
+
type: 'text',
|
|
58
|
+
data: {
|
|
59
|
+
text: `${name}更新了!
|
|
60
|
+
· 最新版本:${version.latest}
|
|
61
|
+
· 下载直链:https://api.modrinth.com/maven/maven/modrinth/${slug}/${version.latest}/${slug}-${version.latest}.jar`
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
];
|
|
65
|
+
for (const listener of getFeatureGroups('modrinth')) {
|
|
66
|
+
bot.sendGroupMsg(listener, msg);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
import { GroupMessageWSMSG, Message, TextMessage } from '@/type';
|
|
2
|
-
import { getFeatureGroups } from '@/config/features';
|
|
3
|
-
|
|
4
|
-
export class ParenthesesMatching {
|
|
5
|
-
static readonly bracketPairs: Record<string, string> = {};
|
|
6
|
-
static readonly closingBrackets: Set<string> = new Set();
|
|
7
|
-
static readonly bracketTypeMap: Record<string, string> = {};
|
|
8
|
-
static readonly reversePairs: Record<string, string> = {};
|
|
9
|
-
|
|
10
|
-
static {
|
|
11
|
-
ParenthesesMatching.add('()', 'paren');
|
|
12
|
-
ParenthesesMatching.add('()', 'full width paren');
|
|
13
|
-
ParenthesesMatching.add('⁽⁾', 'superscript paren');
|
|
14
|
-
ParenthesesMatching.add('₍₎', 'subscript paren');
|
|
15
|
-
ParenthesesMatching.add('︵︶', 'vertical paren');
|
|
16
|
-
ParenthesesMatching.add('[]', 'square');
|
|
17
|
-
ParenthesesMatching.add('[]', 'full width square');
|
|
18
|
-
ParenthesesMatching.add('【】', 'solid square');
|
|
19
|
-
ParenthesesMatching.add('〖〗', 'hollow square');
|
|
20
|
-
ParenthesesMatching.add('︗︘', 'vertical hollow square');
|
|
21
|
-
ParenthesesMatching.add('︻︼', 'vertical solid square');
|
|
22
|
-
ParenthesesMatching.add('{}', 'brace');
|
|
23
|
-
ParenthesesMatching.add('﹛﹜', 'full width brace');
|
|
24
|
-
ParenthesesMatching.add('︷︸', 'vertical brace');
|
|
25
|
-
ParenthesesMatching.add('<>', 'angle');
|
|
26
|
-
ParenthesesMatching.add('‹›', 'angle');
|
|
27
|
-
ParenthesesMatching.add('︿﹀', 'vertical angle');
|
|
28
|
-
ParenthesesMatching.add('“”', 'full width quote');
|
|
29
|
-
ParenthesesMatching.add('‘’', 'full width single quote');
|
|
30
|
-
ParenthesesMatching.add('「」', 'traditional quote');
|
|
31
|
-
ParenthesesMatching.add('『』', 'hollow traditional quote');
|
|
32
|
-
ParenthesesMatching.add('⎡⎦', 'long traditional quote');
|
|
33
|
-
ParenthesesMatching.add('⎣⎤', 'reverse traditional quote');
|
|
34
|
-
ParenthesesMatching.add('﹁﹂', 'vertical traditional quote');
|
|
35
|
-
ParenthesesMatching.add('﹃﹄', 'vertical hollow traditional quote');
|
|
36
|
-
ParenthesesMatching.add('《》', 'book');
|
|
37
|
-
ParenthesesMatching.add('︽︾', 'vertical book');
|
|
38
|
-
ParenthesesMatching.add('〔〕', 'hexagonal');
|
|
39
|
-
ParenthesesMatching.add('︹︺', 'vertical hexagonal');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
static add(bracket: string, type: string) {
|
|
43
|
-
if (bracket.length !== 2) return;
|
|
44
|
-
const left = bracket[0];
|
|
45
|
-
const right = bracket[1];
|
|
46
|
-
if (!left || !right) return;
|
|
47
|
-
ParenthesesMatching.bracketPairs[left] = right;
|
|
48
|
-
ParenthesesMatching.closingBrackets.add(right);
|
|
49
|
-
ParenthesesMatching.bracketTypeMap[left] = type;
|
|
50
|
-
ParenthesesMatching.bracketTypeMap[right] = type;
|
|
51
|
-
ParenthesesMatching.reversePairs[right] = left;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
public static parenthesesMatching(msg: GroupMessageWSMSG, sentMessage: Message[]) {
|
|
55
|
-
if (!getFeatureGroups('parentheses').includes(msg.group_id)) return;
|
|
56
|
-
const receivedMessage: TextMessage[] = [];
|
|
57
|
-
msg.message.forEach(message => {
|
|
58
|
-
if (message.type != 'text') return;
|
|
59
|
-
receivedMessage.push(message);
|
|
60
|
-
});
|
|
61
|
-
const stack: { char: string; position: number }[] = [];
|
|
62
|
-
const strMsg = receivedMessage.map(msg => msg.data.text).join(' ');
|
|
63
|
-
for (let i = 0; i < strMsg.length; i++) {
|
|
64
|
-
const char: string = strMsg[i]!;
|
|
65
|
-
if (ParenthesesMatching.bracketPairs[char]) {
|
|
66
|
-
stack.push({ char, position: i });
|
|
67
|
-
} else if (ParenthesesMatching.closingBrackets.has(char)) {
|
|
68
|
-
const expected = ParenthesesMatching.reversePairs[char];
|
|
69
|
-
const charType = ParenthesesMatching.bracketTypeMap[char];
|
|
70
|
-
if (stack.length > 0 && stack[stack.length - 1]!.char === expected) {
|
|
71
|
-
stack.pop();
|
|
72
|
-
} else {
|
|
73
|
-
let errorMsg = `括号匹配错误:第 ${i + 1} 个字符 '${char}' `;
|
|
74
|
-
if (stack.length === 0) {
|
|
75
|
-
let errorType = '括号';
|
|
76
|
-
let errorDirection = '左';
|
|
77
|
-
if (charType && charType.endsWith('quote')) errorType = '引号';
|
|
78
|
-
if (charType && charType.startsWith('vertical')) errorDirection = '上';
|
|
79
|
-
errorMsg += `没有对应的${errorDirection}${errorType}`;
|
|
80
|
-
} else {
|
|
81
|
-
const topBracket = stack[stack.length - 1]!;
|
|
82
|
-
const expectedClosing = ParenthesesMatching.bracketPairs[topBracket.char];
|
|
83
|
-
const topType = ParenthesesMatching.bracketTypeMap[topBracket.char];
|
|
84
|
-
const currentType = ParenthesesMatching.bracketTypeMap[char];
|
|
85
|
-
|
|
86
|
-
if (topType !== currentType) {
|
|
87
|
-
errorMsg += `与第 ${topBracket.position + 1} 个字符 '${topBracket.char}' 类型不匹配,期望 '${expectedClosing}'`;
|
|
88
|
-
} else {
|
|
89
|
-
errorMsg += `位置错误`;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
sentMessage.push({
|
|
94
|
-
type: 'text',
|
|
95
|
-
data: {
|
|
96
|
-
text: errorMsg
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
let result = '';
|
|
105
|
-
while (stack.length > 0) {
|
|
106
|
-
const leftBracket = stack.pop()!;
|
|
107
|
-
result += ParenthesesMatching.bracketPairs[leftBracket.char];
|
|
108
|
-
}
|
|
109
|
-
if (result.trim().length == 0) return;
|
|
110
|
-
sentMessage.push({
|
|
111
|
-
type: 'text',
|
|
112
|
-
data: {
|
|
113
|
-
text: result
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
}
|
|
1
|
+
import { GroupMessageWSMSG, Message, TextMessage } from '@/type';
|
|
2
|
+
import { getFeatureGroups } from '@/config/features';
|
|
3
|
+
|
|
4
|
+
export class ParenthesesMatching {
|
|
5
|
+
static readonly bracketPairs: Record<string, string> = {};
|
|
6
|
+
static readonly closingBrackets: Set<string> = new Set();
|
|
7
|
+
static readonly bracketTypeMap: Record<string, string> = {};
|
|
8
|
+
static readonly reversePairs: Record<string, string> = {};
|
|
9
|
+
|
|
10
|
+
static {
|
|
11
|
+
ParenthesesMatching.add('()', 'paren');
|
|
12
|
+
ParenthesesMatching.add('()', 'full width paren');
|
|
13
|
+
ParenthesesMatching.add('⁽⁾', 'superscript paren');
|
|
14
|
+
ParenthesesMatching.add('₍₎', 'subscript paren');
|
|
15
|
+
ParenthesesMatching.add('︵︶', 'vertical paren');
|
|
16
|
+
ParenthesesMatching.add('[]', 'square');
|
|
17
|
+
ParenthesesMatching.add('[]', 'full width square');
|
|
18
|
+
ParenthesesMatching.add('【】', 'solid square');
|
|
19
|
+
ParenthesesMatching.add('〖〗', 'hollow square');
|
|
20
|
+
ParenthesesMatching.add('︗︘', 'vertical hollow square');
|
|
21
|
+
ParenthesesMatching.add('︻︼', 'vertical solid square');
|
|
22
|
+
ParenthesesMatching.add('{}', 'brace');
|
|
23
|
+
ParenthesesMatching.add('﹛﹜', 'full width brace');
|
|
24
|
+
ParenthesesMatching.add('︷︸', 'vertical brace');
|
|
25
|
+
ParenthesesMatching.add('<>', 'angle');
|
|
26
|
+
ParenthesesMatching.add('‹›', 'angle');
|
|
27
|
+
ParenthesesMatching.add('︿﹀', 'vertical angle');
|
|
28
|
+
ParenthesesMatching.add('“”', 'full width quote');
|
|
29
|
+
ParenthesesMatching.add('‘’', 'full width single quote');
|
|
30
|
+
ParenthesesMatching.add('「」', 'traditional quote');
|
|
31
|
+
ParenthesesMatching.add('『』', 'hollow traditional quote');
|
|
32
|
+
ParenthesesMatching.add('⎡⎦', 'long traditional quote');
|
|
33
|
+
ParenthesesMatching.add('⎣⎤', 'reverse traditional quote');
|
|
34
|
+
ParenthesesMatching.add('﹁﹂', 'vertical traditional quote');
|
|
35
|
+
ParenthesesMatching.add('﹃﹄', 'vertical hollow traditional quote');
|
|
36
|
+
ParenthesesMatching.add('《》', 'book');
|
|
37
|
+
ParenthesesMatching.add('︽︾', 'vertical book');
|
|
38
|
+
ParenthesesMatching.add('〔〕', 'hexagonal');
|
|
39
|
+
ParenthesesMatching.add('︹︺', 'vertical hexagonal');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static add(bracket: string, type: string) {
|
|
43
|
+
if (bracket.length !== 2) return;
|
|
44
|
+
const left = bracket[0];
|
|
45
|
+
const right = bracket[1];
|
|
46
|
+
if (!left || !right) return;
|
|
47
|
+
ParenthesesMatching.bracketPairs[left] = right;
|
|
48
|
+
ParenthesesMatching.closingBrackets.add(right);
|
|
49
|
+
ParenthesesMatching.bracketTypeMap[left] = type;
|
|
50
|
+
ParenthesesMatching.bracketTypeMap[right] = type;
|
|
51
|
+
ParenthesesMatching.reversePairs[right] = left;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public static parenthesesMatching(msg: GroupMessageWSMSG, sentMessage: Message[]) {
|
|
55
|
+
if (!getFeatureGroups('parentheses').includes(msg.group_id)) return;
|
|
56
|
+
const receivedMessage: TextMessage[] = [];
|
|
57
|
+
msg.message.forEach(message => {
|
|
58
|
+
if (message.type != 'text') return;
|
|
59
|
+
receivedMessage.push(message);
|
|
60
|
+
});
|
|
61
|
+
const stack: { char: string; position: number }[] = [];
|
|
62
|
+
const strMsg = receivedMessage.map(msg => msg.data.text).join(' ');
|
|
63
|
+
for (let i = 0; i < strMsg.length; i++) {
|
|
64
|
+
const char: string = strMsg[i]!;
|
|
65
|
+
if (ParenthesesMatching.bracketPairs[char]) {
|
|
66
|
+
stack.push({ char, position: i });
|
|
67
|
+
} else if (ParenthesesMatching.closingBrackets.has(char)) {
|
|
68
|
+
const expected = ParenthesesMatching.reversePairs[char];
|
|
69
|
+
const charType = ParenthesesMatching.bracketTypeMap[char];
|
|
70
|
+
if (stack.length > 0 && stack[stack.length - 1]!.char === expected) {
|
|
71
|
+
stack.pop();
|
|
72
|
+
} else {
|
|
73
|
+
let errorMsg = `括号匹配错误:第 ${i + 1} 个字符 '${char}' `;
|
|
74
|
+
if (stack.length === 0) {
|
|
75
|
+
let errorType = '括号';
|
|
76
|
+
let errorDirection = '左';
|
|
77
|
+
if (charType && charType.endsWith('quote')) errorType = '引号';
|
|
78
|
+
if (charType && charType.startsWith('vertical')) errorDirection = '上';
|
|
79
|
+
errorMsg += `没有对应的${errorDirection}${errorType}`;
|
|
80
|
+
} else {
|
|
81
|
+
const topBracket = stack[stack.length - 1]!;
|
|
82
|
+
const expectedClosing = ParenthesesMatching.bracketPairs[topBracket.char];
|
|
83
|
+
const topType = ParenthesesMatching.bracketTypeMap[topBracket.char];
|
|
84
|
+
const currentType = ParenthesesMatching.bracketTypeMap[char];
|
|
85
|
+
|
|
86
|
+
if (topType !== currentType) {
|
|
87
|
+
errorMsg += `与第 ${topBracket.position + 1} 个字符 '${topBracket.char}' 类型不匹配,期望 '${expectedClosing}'`;
|
|
88
|
+
} else {
|
|
89
|
+
errorMsg += `位置错误`;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
sentMessage.push({
|
|
94
|
+
type: 'text',
|
|
95
|
+
data: {
|
|
96
|
+
text: errorMsg
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let result = '';
|
|
105
|
+
while (stack.length > 0) {
|
|
106
|
+
const leftBracket = stack.pop()!;
|
|
107
|
+
result += ParenthesesMatching.bracketPairs[leftBracket.char];
|
|
108
|
+
}
|
|
109
|
+
if (result.trim().length == 0) return;
|
|
110
|
+
sentMessage.push({
|
|
111
|
+
type: 'text',
|
|
112
|
+
data: {
|
|
113
|
+
text: result
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|