koishi-plugin-minecraft-adapter 0.4.1 → 0.4.3
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.d.ts +8 -0
- package/lib/index.js +48 -3
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -96,6 +96,14 @@ declare namespace MinecraftService {
|
|
|
96
96
|
};
|
|
97
97
|
/** 调试开关:启用后打印详细日志 */
|
|
98
98
|
debug?: boolean;
|
|
99
|
+
/** 适配器兼容选项 */
|
|
100
|
+
adapterCompat?: {
|
|
101
|
+
/**
|
|
102
|
+
* 将 chat 事件注入 Koishi 的 message 管线(平台 minecraft)
|
|
103
|
+
* 提供在真正的 Adapter 完成前的临时方案
|
|
104
|
+
*/
|
|
105
|
+
injectMessage?: boolean;
|
|
106
|
+
};
|
|
99
107
|
}
|
|
100
108
|
const Config: Schema<Config>;
|
|
101
109
|
}
|
package/lib/index.js
CHANGED
|
@@ -287,9 +287,31 @@ class MinecraftService extends koishi_1.Service {
|
|
|
287
287
|
const mapped = mapQueqiaoEvent(type, payload);
|
|
288
288
|
this.dlog('ws.dispatch', { type: mapped.type, payload: mapped.payload });
|
|
289
289
|
this.ctx.emit(`minecraft/${mapped.type}`, mapped.payload);
|
|
290
|
+
// 实验性:将聊天注入 Koishi 标准消息事件,便于指令触发
|
|
291
|
+
if (this.config.adapterCompat?.injectMessage && mapped.type === 'chat') {
|
|
292
|
+
const hasBot = Array.isArray(this.ctx.bots) && this.ctx.bots.some((b) => b.platform === 'minecraft');
|
|
293
|
+
if (hasBot) {
|
|
294
|
+
const userId = mapped.payload.player || 'player';
|
|
295
|
+
const content = String(mapped.payload.message ?? '');
|
|
296
|
+
const session = {
|
|
297
|
+
platform: 'minecraft',
|
|
298
|
+
selfId: this.config.websocket?.serverName || 'minecraft',
|
|
299
|
+
timestamp: Date.now(),
|
|
300
|
+
type: 'message',
|
|
301
|
+
subtype: 'private',
|
|
302
|
+
userId,
|
|
303
|
+
username: userId,
|
|
304
|
+
channelId: `mc:${userId}`,
|
|
305
|
+
guildId: 'minecraft',
|
|
306
|
+
content,
|
|
307
|
+
};
|
|
308
|
+
this.dlog('inject.message', { session: { ...session, content: truncate(session.content, 200) } });
|
|
309
|
+
this.ctx.emit('message', session);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
290
312
|
}
|
|
291
313
|
catch (e) {
|
|
292
|
-
logger.warn('WS
|
|
314
|
+
logger.warn('WS 处理失败: ' + e?.message);
|
|
293
315
|
}
|
|
294
316
|
});
|
|
295
317
|
ws.on('close', () => {
|
|
@@ -512,6 +534,9 @@ function escapeForMc(text) {
|
|
|
512
534
|
authority: koishi_1.Schema.number().description('执行这些指令所需的权限等级').default(2),
|
|
513
535
|
}).description('命令设置').default({ enabled: true, authority: 2 }),
|
|
514
536
|
debug: koishi_1.Schema.boolean().description('启用详细调试日志(仅用于排错,生产环境建议关闭)').default(false),
|
|
537
|
+
adapterCompat: koishi_1.Schema.object({
|
|
538
|
+
injectMessage: koishi_1.Schema.boolean().description('将 chat 事件注入 Koishi 的 message 管线(平台 minecraft)').default(true),
|
|
539
|
+
}).description('适配器兼容选项').default({ injectMessage: true }),
|
|
515
540
|
});
|
|
516
541
|
})(MinecraftService || (MinecraftService = {}));
|
|
517
542
|
exports.default = MinecraftService;
|
|
@@ -554,9 +579,29 @@ function mapQueqiaoEvent(type, data) {
|
|
|
554
579
|
case 'advancement':
|
|
555
580
|
case 'advancement_earned':
|
|
556
581
|
return { type: 'advancement', payload: { player: data.player || data.name, advancement: data.advancement || data.key, raw: data } };
|
|
557
|
-
default:
|
|
558
|
-
return { type, payload: data };
|
|
559
582
|
}
|
|
583
|
+
// 回退:QueQiao 标准格式
|
|
584
|
+
if (data?.post_type === 'message') {
|
|
585
|
+
if (data.sub_type === 'chat' || data.event_name?.toLowerCase()?.includes('chatevent')) {
|
|
586
|
+
const playerName = data.player?.nickname || data.player?.name || data.player?.display_name || data.name;
|
|
587
|
+
return { type: 'chat', payload: { player: playerName, message: data.message || data.text, raw: data } };
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
if (data?.post_type === 'notice') {
|
|
591
|
+
if (data.sub_type === 'join' || data.event_name?.toLowerCase()?.includes('loggedinevent')) {
|
|
592
|
+
const playerName = data.player?.nickname || data.player?.name || data.player?.display_name || data.name;
|
|
593
|
+
return { type: 'join', payload: { player: playerName, raw: data } };
|
|
594
|
+
}
|
|
595
|
+
if (data.sub_type === 'quit' || data.event_name?.toLowerCase()?.includes('loggedoutevent')) {
|
|
596
|
+
const playerName = data.player?.nickname || data.player?.name || data.player?.display_name || data.name;
|
|
597
|
+
return { type: 'leave', payload: { player: playerName, raw: data } };
|
|
598
|
+
}
|
|
599
|
+
if (data.sub_type === 'achievement' || data.event_name?.toLowerCase()?.includes('advancement')) {
|
|
600
|
+
const playerName = data.player?.nickname || data.player?.name || data.player?.display_name || data.name;
|
|
601
|
+
return { type: 'advancement', payload: { player: playerName, advancement: data.advancement?.name || data.advancement?.key, raw: data } };
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return { type, payload: data };
|
|
560
605
|
}
|
|
561
606
|
function buildWsOutboundPayload(config, api, data) {
|
|
562
607
|
// 参考 QueQiao 的 WS 入站接口语义,采用 { api, data } 基本结构
|