koishi-plugin-minecraft-adapter 1.0.8 → 1.0.9
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 +70 -55
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -9,29 +9,52 @@ const rcon_client_1 = require("rcon-client");
|
|
|
9
9
|
const ws_1 = __importDefault(require("ws"));
|
|
10
10
|
const logger = new koishi_1.Logger('minecraft');
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* 将嵌套格式的服务器配置扁平化。
|
|
13
|
+
* 每种嵌套对象(websocket / rcon / chatImage)独立处理,
|
|
14
|
+
* 确保任何混合格式(如扁平 url + 嵌套 rcon)都能正确转换。
|
|
13
15
|
*/
|
|
14
16
|
function flattenServerConfig(server) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
extraHeaders
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
17
|
+
const result = { ...server };
|
|
18
|
+
// ── websocket 嵌套 → 扁平 ──
|
|
19
|
+
if (result.websocket && typeof result.websocket === 'object') {
|
|
20
|
+
const ws = result.websocket;
|
|
21
|
+
if (ws.url !== undefined)
|
|
22
|
+
result.url = ws.url;
|
|
23
|
+
if (ws.accessToken !== undefined)
|
|
24
|
+
result.accessToken = ws.accessToken;
|
|
25
|
+
if (ws.extraHeaders !== undefined)
|
|
26
|
+
result.extraHeaders = ws.extraHeaders;
|
|
27
|
+
delete result.websocket;
|
|
28
|
+
}
|
|
29
|
+
// ── rcon 嵌套 → 扁平 ──
|
|
30
|
+
if (result.rcon && typeof result.rcon === 'object') {
|
|
31
|
+
const rcon = result.rcon;
|
|
32
|
+
const hasRconConfig = rcon.host || rcon.port || rcon.password;
|
|
33
|
+
if (hasRconConfig || rcon.enabled) {
|
|
34
|
+
result.enableRcon = true;
|
|
35
|
+
}
|
|
36
|
+
// 仅在嵌套值实际存在时覆盖,避免用 undefined 覆盖已有值或阻止 Schema 默认值
|
|
37
|
+
if (rcon.host !== undefined)
|
|
38
|
+
result.rconHost = rcon.host;
|
|
39
|
+
if (rcon.port !== undefined)
|
|
40
|
+
result.rconPort = rcon.port;
|
|
41
|
+
if (rcon.password !== undefined)
|
|
42
|
+
result.rconPassword = rcon.password;
|
|
43
|
+
if (rcon.timeout !== undefined)
|
|
44
|
+
result.rconTimeout = rcon.timeout;
|
|
45
|
+
delete result.rcon;
|
|
46
|
+
}
|
|
47
|
+
// ── chatImage 嵌套 → 扁平 ──
|
|
48
|
+
if (result.chatImage && typeof result.chatImage === 'object') {
|
|
49
|
+
const ci = result.chatImage;
|
|
50
|
+
if (ci.enabled !== undefined || ci.defaultImageName) {
|
|
51
|
+
result.enableChatImage = ci.enabled ?? !!ci.defaultImageName;
|
|
52
|
+
}
|
|
53
|
+
if (ci.defaultImageName !== undefined)
|
|
54
|
+
result.chatImageDefaultName = ci.defaultImageName;
|
|
55
|
+
delete result.chatImage;
|
|
33
56
|
}
|
|
34
|
-
return
|
|
57
|
+
return result;
|
|
35
58
|
}
|
|
36
59
|
/**
|
|
37
60
|
* 向后兼容:
|
|
@@ -120,8 +143,7 @@ class MinecraftAdapter extends koishi_1.Adapter {
|
|
|
120
143
|
constructor(ctx, rawConfig) {
|
|
121
144
|
super(ctx);
|
|
122
145
|
try {
|
|
123
|
-
const
|
|
124
|
-
const config = migrateConfig(resolvedConfig);
|
|
146
|
+
const config = migrateConfig(rawConfig);
|
|
125
147
|
this.debug = config.debug ?? false;
|
|
126
148
|
this.detailedLogging = config.detailedLogging ?? false;
|
|
127
149
|
this.tokenizeMode = config.tokenizeMode ?? 'split';
|
|
@@ -395,9 +417,17 @@ class MinecraftAdapter extends koishi_1.Adapter {
|
|
|
395
417
|
async connectRcon(bot) {
|
|
396
418
|
const config = bot.config;
|
|
397
419
|
const selfId = bot.selfId;
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
420
|
+
// rconHost 未配置时,从 WebSocket URL 中提取主机地址作为回退
|
|
421
|
+
let rconHost = config.rconHost;
|
|
422
|
+
if (!rconHost && config.url) {
|
|
423
|
+
try {
|
|
424
|
+
rconHost = new URL(config.url).hostname;
|
|
425
|
+
}
|
|
426
|
+
catch { }
|
|
427
|
+
}
|
|
428
|
+
rconHost = rconHost || '127.0.0.1';
|
|
429
|
+
const rconPort = config.rconPort ?? 25575;
|
|
430
|
+
const rconTimeout = config.rconTimeout ?? 5000;
|
|
401
431
|
if (this.debug) {
|
|
402
432
|
logger.info(`[DEBUG] RCON config for server ${selfId}:`, {
|
|
403
433
|
rconHost: config.rconHost,
|
|
@@ -405,9 +435,8 @@ class MinecraftAdapter extends koishi_1.Adapter {
|
|
|
405
435
|
rconPassword: config.rconPassword ? '***' : undefined,
|
|
406
436
|
rconTimeout: config.rconTimeout,
|
|
407
437
|
enableRcon: config.enableRcon,
|
|
408
|
-
|
|
438
|
+
resolved: `${rconHost}:${rconPort}`,
|
|
409
439
|
});
|
|
410
|
-
logger.info(`[DEBUG] Connecting RCON for server ${selfId} to ${rconHost}:${rconPort}`);
|
|
411
440
|
}
|
|
412
441
|
try {
|
|
413
442
|
const rcon = await this.createRconWithTimeout(rconHost, rconPort, config.rconPassword || '', rconTimeout);
|
|
@@ -1193,34 +1222,20 @@ MinecraftBot.MessageEncoder = MinecraftMessageEncoder;
|
|
|
1193
1222
|
// ============================================================================
|
|
1194
1223
|
// Koishi Schema 配置
|
|
1195
1224
|
// ============================================================================
|
|
1196
|
-
const serverSchema = koishi_1.Schema.
|
|
1197
|
-
koishi_1.Schema.
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
koishi_1.Schema.
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
rconPort: koishi_1.Schema.number().description('RCON 端口').default(25575),
|
|
1211
|
-
rconPassword: koishi_1.Schema.string().description('RCON 密码(留空表示无密码)'),
|
|
1212
|
-
rconTimeout: koishi_1.Schema.number().description('RCON 超时时间(ms)').default(5000),
|
|
1213
|
-
}),
|
|
1214
|
-
koishi_1.Schema.object({}),
|
|
1215
|
-
]),
|
|
1216
|
-
koishi_1.Schema.union([
|
|
1217
|
-
koishi_1.Schema.object({
|
|
1218
|
-
enableChatImage: koishi_1.Schema.const(true).required(),
|
|
1219
|
-
chatImageDefaultName: koishi_1.Schema.string().description('图片在聊天栏中的默认显示名称').default('图片'),
|
|
1220
|
-
}),
|
|
1221
|
-
koishi_1.Schema.object({}),
|
|
1222
|
-
]),
|
|
1223
|
-
]);
|
|
1225
|
+
const serverSchema = koishi_1.Schema.object({
|
|
1226
|
+
selfId: koishi_1.Schema.string().description('机器人 ID(唯一标识)').required(),
|
|
1227
|
+
serverName: koishi_1.Schema.string().description('服务器名称(需与鹊桥 config.yml 中的 server_name 一致)'),
|
|
1228
|
+
url: koishi_1.Schema.string().description('WebSocket 地址(如 ws://127.0.0.1:8080)').required(),
|
|
1229
|
+
accessToken: koishi_1.Schema.string().description('访问令牌(需与鹊桥 config.yml 中的 access_token 一致)'),
|
|
1230
|
+
extraHeaders: koishi_1.Schema.dict(koishi_1.Schema.string()).description('额外请求头'),
|
|
1231
|
+
enableRcon: koishi_1.Schema.boolean().description('启用 RCON 远程命令执行').default(false),
|
|
1232
|
+
rconHost: koishi_1.Schema.string().description('RCON 主机地址(留空则自动取 WebSocket 地址中的主机)'),
|
|
1233
|
+
rconPort: koishi_1.Schema.number().description('RCON 端口').default(25575),
|
|
1234
|
+
rconPassword: koishi_1.Schema.string().description('RCON 密码(留空表示无密码)'),
|
|
1235
|
+
rconTimeout: koishi_1.Schema.number().description('RCON 超时时间(ms)').default(5000),
|
|
1236
|
+
enableChatImage: koishi_1.Schema.boolean().description('启用 ChatImage CICode 图片发送(需客户端安装 ChatImage Mod)').default(false),
|
|
1237
|
+
chatImageDefaultName: koishi_1.Schema.string().description('图片在聊天栏中的默认显示名称').default('图片'),
|
|
1238
|
+
});
|
|
1224
1239
|
(function (MinecraftAdapter) {
|
|
1225
1240
|
MinecraftAdapter.Config = koishi_1.Schema.object({
|
|
1226
1241
|
debug: koishi_1.Schema.boolean().description('启用调试模式,输出详细日志').default(false),
|
package/package.json
CHANGED