mioku-plugin-mc 4.0.0 → 4.0.2
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/core/rcon.ts +1 -1
- package/index.ts +64 -68
- package/package.json +2 -48
- package/play/ai/prompt.ts +1 -1
- package/play/config.ts +6 -4
- package/play/debug/commands.ts +3 -3
- package/play/index.ts +9 -9
- package/play/types.ts +12 -7
- package/skills/mc.ts +2 -2
- package/utils/command-router.ts +0 -51
package/core/rcon.ts
CHANGED
package/index.ts
CHANGED
|
@@ -6,7 +6,6 @@ import { createPlayManager } from "./play";
|
|
|
6
6
|
import { createMcSkill } from "./skills/mc";
|
|
7
7
|
import { handleDebugCommand } from "./play/debug/commands";
|
|
8
8
|
import { createServerManager } from "./utils/server-manager";
|
|
9
|
-
import { parseMcCommand } from "./utils/command-router";
|
|
10
9
|
import { handleStatus } from "./handlers/status";
|
|
11
10
|
import { handleSync } from "./handlers/sync";
|
|
12
11
|
import { handleReconnect } from "./handlers/reconnect";
|
|
@@ -21,8 +20,6 @@ import type { McConfig } from "./types";
|
|
|
21
20
|
|
|
22
21
|
export default definePlugin({
|
|
23
22
|
name: "mc",
|
|
24
|
-
version: "1.0.0",
|
|
25
|
-
description: "Minecraft服务器与QQ群消息互通插件",
|
|
26
23
|
|
|
27
24
|
async setup(ctx: MiokuContext) {
|
|
28
25
|
const configService = getService(ctx, Services.Config);
|
|
@@ -66,18 +63,15 @@ export default definePlugin({
|
|
|
66
63
|
|
|
67
64
|
ctx.handle("message", async (event) => {
|
|
68
65
|
const text = ctx.text(event).trim();
|
|
69
|
-
const groupId =
|
|
70
|
-
"group_id" in event && typeof event.group_id === "number"
|
|
71
|
-
? event.group_id
|
|
72
|
-
: undefined;
|
|
66
|
+
const groupId = String(event.group_id ?? "").trim() || undefined;
|
|
73
67
|
|
|
74
68
|
if (groupId) {
|
|
75
69
|
const reply = await handleDebugCommand({
|
|
76
70
|
text,
|
|
77
|
-
|
|
71
|
+
isMaster: ctx.isMaster?.(event) ?? false,
|
|
78
72
|
debugEnabled: playConfigHandler.getConfig().debug.enabled,
|
|
79
73
|
playManager,
|
|
80
|
-
groupId
|
|
74
|
+
groupId,
|
|
81
75
|
});
|
|
82
76
|
if (reply !== null) {
|
|
83
77
|
await event.reply(reply);
|
|
@@ -85,60 +79,64 @@ export default definePlugin({
|
|
|
85
79
|
}
|
|
86
80
|
}
|
|
87
81
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (!parsed || parsed.action === "") {
|
|
91
|
-
if (groupId) {
|
|
92
|
-
playManager.onQqMessage(event);
|
|
93
|
-
await forwardToMc(ctx, event, config, configHandler, serverManager);
|
|
94
|
-
}
|
|
95
|
-
return;
|
|
82
|
+
if (groupId) {
|
|
83
|
+
await forwardToMc(ctx, event, config, configHandler, serverManager);
|
|
96
84
|
}
|
|
85
|
+
});
|
|
97
86
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
87
|
+
const replyWithEvent = (event: import("mioku").MessageEvent) =>
|
|
88
|
+
async (msg: string) => {
|
|
89
|
+
await event.reply(msg);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
ctx.command({
|
|
93
|
+
id: "mc-status",
|
|
94
|
+
name: "mc-status",
|
|
95
|
+
prefixes: ["/", "."],
|
|
96
|
+
match: /^mc\s+状态\s*$/,
|
|
97
|
+
permission: "master",
|
|
98
|
+
description: "查看所有已配置服务器的WebSocket连接状态,包括连接中、已断开等",
|
|
99
|
+
async handler({ event }) {
|
|
100
|
+
await handleStatus(serverManager, config, replyWithEvent(event));
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
ctx.command({
|
|
105
|
+
id: "mc-sync-on",
|
|
106
|
+
name: "mc-sync-on",
|
|
107
|
+
prefixes: ["/", "."],
|
|
108
|
+
match: /^mc\s+开启同步(?:\s+(.+))?$/,
|
|
109
|
+
description: "开启指定服务器的群聊消息同步功能,开启后该服务器可接收和发送群聊消息",
|
|
110
|
+
usage: ".mc 开启同步 <服务器名称>",
|
|
111
|
+
permission: "master",
|
|
112
|
+
async handler({ event, args }) {
|
|
113
|
+
await handleSync(args[0], true, serverManager, configHandler, config, replyWithEvent(event));
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
ctx.command({
|
|
118
|
+
id: "mc-sync-off",
|
|
119
|
+
name: "mc-sync-off",
|
|
120
|
+
prefixes: ["/", "."],
|
|
121
|
+
match: /^mc\s+关闭同步(?:\s+(.+))?$/,
|
|
122
|
+
description: "关闭指定服务器的群聊消息同步功能,关闭后该服务器不再接收和发送群聊消息",
|
|
123
|
+
usage: ".mc 关闭同步 <服务器名称>",
|
|
124
|
+
permission: "master",
|
|
125
|
+
async handler({ event, args }) {
|
|
126
|
+
await handleSync(args[0], false, serverManager, configHandler, config, replyWithEvent(event));
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
ctx.command({
|
|
131
|
+
id: "mc-reconnect",
|
|
132
|
+
name: "mc-reconnect",
|
|
133
|
+
prefixes: ["/", "."],
|
|
134
|
+
match: /^mc\s+重连\s*$/,
|
|
135
|
+
permission: "master",
|
|
136
|
+
description: "断开并重新建立所有服务器的WebSocket连接,用于连接异常时手动恢复",
|
|
137
|
+
async handler({ event }) {
|
|
138
|
+
await handleReconnect(serverManager, replyWithEvent(event));
|
|
139
|
+
},
|
|
142
140
|
});
|
|
143
141
|
|
|
144
142
|
ctx.logger.info("Minecraft插件加载成功");
|
|
@@ -197,12 +195,10 @@ async function forwardToMc(
|
|
|
197
195
|
const text = ctx.text(event);
|
|
198
196
|
ctx.logger.debug(`[MC] 收到群消息 group=${event.group_id} text=${text}`);
|
|
199
197
|
|
|
200
|
-
|
|
201
|
-
if (!
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
198
|
+
const groupId = String(event.group_id ?? "").trim();
|
|
199
|
+
if (!groupId) return;
|
|
204
200
|
|
|
205
|
-
const servers = configHandler.getServersForGroup(
|
|
201
|
+
const servers = configHandler.getServersForGroup(groupId);
|
|
206
202
|
if (servers.length === 0) return;
|
|
207
203
|
|
|
208
204
|
const msgList = Array.isArray(event.message)
|
|
@@ -219,7 +215,7 @@ async function forwardToMc(
|
|
|
219
215
|
const isAllowed = isCommandAllowed(
|
|
220
216
|
commandText,
|
|
221
217
|
server,
|
|
222
|
-
ctx.
|
|
218
|
+
ctx.isMaster?.(event) ?? false,
|
|
223
219
|
event.user_id ?? "",
|
|
224
220
|
);
|
|
225
221
|
|
|
@@ -252,4 +248,4 @@ async function forwardToMc(
|
|
|
252
248
|
ctx.logger.error(`[MC] 发送到服务器 ${server.server_name} 失败: ${err}`);
|
|
253
249
|
}
|
|
254
250
|
}
|
|
255
|
-
}
|
|
251
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mioku-plugin-mc",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "Minecraft与QQ群消息互通插件,支持服务器状态监控与RCON命令",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -15,53 +15,7 @@
|
|
|
15
15
|
"services": [
|
|
16
16
|
"config",
|
|
17
17
|
"ai"
|
|
18
|
-
]
|
|
19
|
-
"accessHooks": [
|
|
20
|
-
{
|
|
21
|
-
"id": "/mc 状态",
|
|
22
|
-
"match": "/^\\/mc\\s*状态/"
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"id": "/mc 开启同步",
|
|
26
|
-
"match": "/^\\/mc\\s*开启同步/"
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"id": "/mc 关闭同步",
|
|
30
|
-
"match": "/^\\/mc\\s*关闭同步/"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"id": "/mc 重连",
|
|
34
|
-
"match": "/^\\/mc\\s*重连/"
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
"help": {
|
|
38
|
-
"title": "Minecraft",
|
|
39
|
-
"description": "Minecraft服务器与QQ群消息互通插件,支持服务器状态监控与RCON命令",
|
|
40
|
-
"commands": [
|
|
41
|
-
{
|
|
42
|
-
"cmd": "/mc 状态",
|
|
43
|
-
"desc": "查看所有已配置服务器的WebSocket连接状态,包括连接中、已断开等",
|
|
44
|
-
"role": "master"
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"cmd": "/mc 开启同步",
|
|
48
|
-
"desc": "开启指定服务器的群聊消息同步功能,开启后该服务器可接收和发送群聊消息",
|
|
49
|
-
"usage": "/mc 开启同步 <服务器名称>",
|
|
50
|
-
"role": "master"
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"cmd": "/mc 关闭同步",
|
|
54
|
-
"desc": "关闭指定服务器的群聊消息同步功能,关闭后该服务器不再接收和发送群聊消息",
|
|
55
|
-
"usage": "/mc 关闭同步 <服务器名称>",
|
|
56
|
-
"role": "master"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"cmd": "/mc 重连",
|
|
60
|
-
"desc": "断开并重新建立所有服务器的WebSocket连接,用于连接异常时手动恢复",
|
|
61
|
-
"role": "master"
|
|
62
|
-
}
|
|
63
|
-
]
|
|
64
|
-
}
|
|
18
|
+
]
|
|
65
19
|
},
|
|
66
20
|
"dependencies": {
|
|
67
21
|
"@cikeyqi/queqiao-node-sdk": "^0.1.3",
|
package/play/ai/prompt.ts
CHANGED
|
@@ -126,7 +126,7 @@ function describeTerminator(t: WorkTerminator): string {
|
|
|
126
126
|
export function buildSessionFacts(input: {
|
|
127
127
|
serverName: string;
|
|
128
128
|
username: string;
|
|
129
|
-
groupId:
|
|
129
|
+
groupId: string;
|
|
130
130
|
maxPlayMs: number;
|
|
131
131
|
allowedCommands: string[];
|
|
132
132
|
}): string {
|
package/play/config.ts
CHANGED
|
@@ -27,10 +27,12 @@ export function createPlayConfigHandler(configService: ConfigService | undefined
|
|
|
27
27
|
return currentConfig.servers.find((s) => s.id === id) ?? null;
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
const findBinding = (groupId:
|
|
31
|
-
const gid =
|
|
32
|
-
if (!
|
|
33
|
-
return
|
|
30
|
+
const findBinding = (groupId: string | number): GroupBinding | null => {
|
|
31
|
+
const gid = String(groupId ?? "").trim();
|
|
32
|
+
if (!gid) return null;
|
|
33
|
+
return (
|
|
34
|
+
currentConfig.groups.find((g) => String(g.groupId) === gid) ?? null
|
|
35
|
+
);
|
|
34
36
|
};
|
|
35
37
|
|
|
36
38
|
return { register, getConfig, findServer, findBinding };
|
package/play/debug/commands.ts
CHANGED
|
@@ -2,10 +2,10 @@ import type { PlayManager } from "../index";
|
|
|
2
2
|
|
|
3
3
|
export interface DebugCommandContext {
|
|
4
4
|
text: string;
|
|
5
|
-
|
|
5
|
+
isMaster: boolean;
|
|
6
6
|
debugEnabled: boolean;
|
|
7
7
|
playManager: PlayManager;
|
|
8
|
-
groupId:
|
|
8
|
+
groupId: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
const OVERLAY_NAMES = ["defend", "auto_eat"];
|
|
@@ -78,7 +78,7 @@ function parseBundleArgs(arg: string): ParsedBundleArgs | null {
|
|
|
78
78
|
export async function handleDebugCommand(
|
|
79
79
|
ctx: DebugCommandContext,
|
|
80
80
|
): Promise<string | null> {
|
|
81
|
-
if (!ctx.debugEnabled || !ctx.
|
|
81
|
+
if (!ctx.debugEnabled || !ctx.isMaster) return null;
|
|
82
82
|
const text = ctx.text.trim();
|
|
83
83
|
if (!text.startsWith("/")) return null;
|
|
84
84
|
const head = text.split(/\s+/)[0]?.toLowerCase();
|
package/play/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ export class PlayManager {
|
|
|
41
41
|
private readonly configService: ConfigService | undefined;
|
|
42
42
|
private readonly playConfigHandler: PlayConfigHandler;
|
|
43
43
|
private readonly syncConfigHandler: ConfigHandler;
|
|
44
|
-
private readonly sessions = new Map<
|
|
44
|
+
private readonly sessions = new Map<string, PlaySession>();
|
|
45
45
|
private mainInstance?: AIInstance;
|
|
46
46
|
private workInstance?: AIInstance;
|
|
47
47
|
|
|
@@ -100,7 +100,7 @@ export class PlayManager {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
async enter(
|
|
103
|
-
groupId:
|
|
103
|
+
groupId: string,
|
|
104
104
|
serverId: string,
|
|
105
105
|
opts: { debug?: boolean } = {},
|
|
106
106
|
): Promise<PlayEnterResult> {
|
|
@@ -180,7 +180,7 @@ export class PlayManager {
|
|
|
180
180
|
return { success: true, serverId: server.id, message: `已进入 ${server.name}${mode}` };
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
async exit(groupId:
|
|
183
|
+
async exit(groupId: string): Promise<PlayExitResult> {
|
|
184
184
|
const session = this.sessions.get(groupId);
|
|
185
185
|
if (!session || session.isStopped) {
|
|
186
186
|
return { success: false, message: "当前没有进行中的 mc 会话" };
|
|
@@ -191,8 +191,8 @@ export class PlayManager {
|
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
onQqMessage(event: any): void {
|
|
194
|
-
const groupId =
|
|
195
|
-
if (!
|
|
194
|
+
const groupId = String(event?.group_id ?? "").trim();
|
|
195
|
+
if (!groupId) return;
|
|
196
196
|
const session = this.sessions.get(groupId);
|
|
197
197
|
if (!session || session.isStopped) return;
|
|
198
198
|
const text = String(event?.raw_message ?? event?.message ?? "").trim();
|
|
@@ -206,7 +206,7 @@ export class PlayManager {
|
|
|
206
206
|
return [...this.sessions.values()].map((s) => s.getStatus());
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
getActiveSession(groupId:
|
|
209
|
+
getActiveSession(groupId: string): PlaySession | undefined {
|
|
210
210
|
const s = this.sessions.get(groupId);
|
|
211
211
|
return s && !s.isStopped ? s : undefined;
|
|
212
212
|
}
|
|
@@ -231,7 +231,7 @@ export function createPlayManager(opts: PlayManagerOptions): PlayManager {
|
|
|
231
231
|
function detectQqAtBot(
|
|
232
232
|
event: any,
|
|
233
233
|
botName: string,
|
|
234
|
-
botSelfId:
|
|
234
|
+
botSelfId: string | undefined,
|
|
235
235
|
): boolean {
|
|
236
236
|
const lower = String(event?.raw_message ?? event?.message ?? "").toLowerCase();
|
|
237
237
|
if (botName && lower.includes(botName.toLowerCase())) return true;
|
|
@@ -239,8 +239,8 @@ function detectQqAtBot(
|
|
|
239
239
|
for (const segment of event.message) {
|
|
240
240
|
if (!segment || typeof segment !== "object") continue;
|
|
241
241
|
if (segment.type !== "at") continue;
|
|
242
|
-
const
|
|
243
|
-
if (
|
|
242
|
+
const target = String(segment.data?.qq ?? segment.data?.target ?? "").trim();
|
|
243
|
+
if (target && target === botSelfId) return true;
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
return false;
|
package/play/types.ts
CHANGED
|
@@ -12,8 +12,8 @@ export interface PlayServerConfig {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export interface GroupBinding {
|
|
15
|
-
groupId:
|
|
16
|
-
botSelfId:
|
|
15
|
+
groupId: string;
|
|
16
|
+
botSelfId: string;
|
|
17
17
|
allowedServerIds: string[];
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -73,8 +73,8 @@ export type MainLoopTrigger =
|
|
|
73
73
|
export interface PlaySessionStatus {
|
|
74
74
|
serverId: string;
|
|
75
75
|
serverName: string;
|
|
76
|
-
groupId:
|
|
77
|
-
botSelfId:
|
|
76
|
+
groupId: string;
|
|
77
|
+
botSelfId: string;
|
|
78
78
|
startedAt: number;
|
|
79
79
|
connected: boolean;
|
|
80
80
|
currentBehavior: string | null;
|
|
@@ -182,6 +182,11 @@ function asStringList(value: unknown): string[] {
|
|
|
182
182
|
return [];
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
function asId(value: unknown, fallback = ""): string {
|
|
186
|
+
const text = String(value ?? "").trim();
|
|
187
|
+
return text.length > 0 ? text : fallback;
|
|
188
|
+
}
|
|
189
|
+
|
|
185
190
|
function asNumber(value: unknown, fallback: number): number {
|
|
186
191
|
const n = Number(value);
|
|
187
192
|
return Number.isFinite(n) ? n : fallback;
|
|
@@ -212,8 +217,8 @@ function normalizeServer(raw: any): PlayServerConfig {
|
|
|
212
217
|
|
|
213
218
|
function normalizeBinding(raw: any): GroupBinding {
|
|
214
219
|
return {
|
|
215
|
-
groupId:
|
|
216
|
-
botSelfId:
|
|
220
|
+
groupId: asId(raw?.groupId ?? raw?.group_id),
|
|
221
|
+
botSelfId: asId(raw?.botSelfId ?? raw?.bot_self_id),
|
|
217
222
|
allowedServerIds: asStringList(raw?.allowedServerIds ?? raw?.allowed_server_ids),
|
|
218
223
|
};
|
|
219
224
|
}
|
|
@@ -225,7 +230,7 @@ export function normalizePlayConfig(raw: any): PlayConfig {
|
|
|
225
230
|
const groups = Array.isArray(raw?.groups)
|
|
226
231
|
? raw?.groups
|
|
227
232
|
.map(normalizeBinding)
|
|
228
|
-
.filter((g: GroupBinding) => g.groupId > 0 && g.botSelfId > 0)
|
|
233
|
+
.filter((g: GroupBinding) => g.groupId.length > 0 && g.botSelfId.length > 0)
|
|
229
234
|
: [];
|
|
230
235
|
const perm: PlayToolPermission =
|
|
231
236
|
raw?.toolPermission === "owner" ||
|
package/skills/mc.ts
CHANGED
|
@@ -29,8 +29,8 @@ export function createMcSkill(playManager: PlayManager): AISkill {
|
|
|
29
29
|
},
|
|
30
30
|
handler: async (args: any, runtimeCtx?: any) => {
|
|
31
31
|
const event = runtimeCtx?.event || runtimeCtx?.rawEvent;
|
|
32
|
-
const groupId =
|
|
33
|
-
if (!
|
|
32
|
+
const groupId = String(event?.group_id ?? "").trim();
|
|
33
|
+
if (!groupId) {
|
|
34
34
|
return { error: "无法识别当前群,请在群聊中调用" };
|
|
35
35
|
}
|
|
36
36
|
|
package/utils/command-router.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
export interface ParsedCommand {
|
|
2
|
-
action: string;
|
|
3
|
-
args: string[];
|
|
4
|
-
raw: string;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function parseMcCommand(text: string): ParsedCommand | null {
|
|
8
|
-
const trimmed = text.trim();
|
|
9
|
-
if (!trimmed.startsWith("/mc")) return null;
|
|
10
|
-
|
|
11
|
-
const remainder = trimmed.slice(3).trim();
|
|
12
|
-
if (!remainder) {
|
|
13
|
-
return { action: "", args: [], raw: "" };
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// split into action and args
|
|
17
|
-
const parts = remainder.split(/\s+/);
|
|
18
|
-
const action = parts[0] || "";
|
|
19
|
-
const args = parts.slice(1);
|
|
20
|
-
|
|
21
|
-
return { action, args, raw: remainder };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function matchMcCommand(
|
|
25
|
-
text: string,
|
|
26
|
-
pattern: RegExp
|
|
27
|
-
): RegExpMatchArray | null {
|
|
28
|
-
const parsed = parseMcCommand(text);
|
|
29
|
-
if (!parsed) return null;
|
|
30
|
-
return parsed.raw.match(pattern);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function buildStatusReply(
|
|
34
|
-
serverName: string,
|
|
35
|
-
status: string,
|
|
36
|
-
displayName?: string
|
|
37
|
-
): string {
|
|
38
|
-
const name = displayName || serverName;
|
|
39
|
-
const icon = status === "connected" ? "在线" : status === "connecting" ? "连接中" : "离线";
|
|
40
|
-
return `[${name}] ${icon}`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export function buildSyncReply(
|
|
44
|
-
serverName: string,
|
|
45
|
-
enabled: boolean,
|
|
46
|
-
displayName?: string
|
|
47
|
-
): string {
|
|
48
|
-
const name = displayName || serverName;
|
|
49
|
-
const action = enabled ? "开启" : "关闭";
|
|
50
|
-
return `${action}了服务器 ${name} 的同步`;
|
|
51
|
-
}
|