koishi-plugin-gl-bot 0.0.7 → 0.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.
Files changed (49) hide show
  1. package/dist/index.js +1 -1
  2. package/lib/constants/index.d.ts +1 -0
  3. package/lib/constants/index.js +4 -0
  4. package/lib/gl/index.d.ts +83 -0
  5. package/lib/gl/index.js +51 -0
  6. package/lib/gl/type.d.ts +0 -0
  7. package/lib/gl/type.js +0 -0
  8. package/lib/index.d.ts +2 -5
  9. package/lib/index.js +6 -0
  10. package/lib/mcsManager/api.d.ts +25 -0
  11. package/lib/mcsManager/api.js +96 -0
  12. package/lib/mcsManager/bot.d.ts +14 -0
  13. package/lib/mcsManager/bot.js +42 -0
  14. package/lib/mcsManager/commands/base.d.ts +2 -0
  15. package/lib/mcsManager/commands/base.js +6 -0
  16. package/lib/mcsManager/commands/index.d.ts +7 -0
  17. package/lib/mcsManager/commands/index.js +13 -0
  18. package/lib/mcsManager/commands/reset.d.ts +12 -0
  19. package/lib/mcsManager/commands/reset.js +45 -0
  20. package/lib/mcsManager/config.d.ts +18 -0
  21. package/lib/mcsManager/config.js +24 -0
  22. package/lib/mcsManager/constants.d.ts +8 -0
  23. package/lib/mcsManager/constants.js +12 -0
  24. package/lib/mcsManager/index.d.ts +26 -0
  25. package/lib/mcsManager/index.js +21 -0
  26. package/lib/mcsManager/instance.d.ts +16 -0
  27. package/lib/mcsManager/instance.js +18 -0
  28. package/lib/mcsManager/panel.d.ts +24 -0
  29. package/lib/mcsManager/panel.js +121 -0
  30. package/lib/mcsManager/type.d.ts +115 -0
  31. package/lib/mcsManager/type.js +2 -0
  32. package/lib/mcsManager/ws.d.ts +24 -0
  33. package/lib/mcsManager/ws.js +116 -0
  34. package/lib/queQiao/index.d.ts +108 -0
  35. package/lib/queQiao/index.js +437 -0
  36. package/lib/queQiao/locale/en-US.json +1 -0
  37. package/lib/queQiao/locale/en-US.yml +9 -0
  38. package/lib/queQiao/locale/zh-CN.json +1 -0
  39. package/lib/queQiao/locale/zh-CN.yml +9 -0
  40. package/lib/queQiao/mcwss.d.ts +61 -0
  41. package/lib/queQiao/mcwss.js +260 -0
  42. package/lib/queQiao/values.d.ts +72 -0
  43. package/lib/queQiao/values.js +155 -0
  44. package/lib/utils/game.mc.d.ts +4 -0
  45. package/lib/utils/game.mc.js +29 -0
  46. package/lib/utils/index.d.ts +1 -0
  47. package/lib/utils/index.js +17 -0
  48. package/package.json +14 -4
  49. package/src/index.ts +0 -20
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractAndRemoveColor = extractAndRemoveColor;
4
+ const koishi_1 = require("koishi");
5
+ const ws_1 = require("ws");
6
+ const values_1 = require("./values");
7
+ // import zhCN from "./locale/zh-CN.json";
8
+ // import enUS from "./locale/en-US.json";
9
+ const zhCN = require('./locale/zh-CN.json');
10
+ const enUS = require('./locale/en-US.json');
11
+ class McWss {
12
+ constructor(ctx, cfg) {
13
+ this.logger = new koishi_1.Logger('Minecraft-sync-msg-Wss');
14
+ this.connectedClients = new Set();
15
+ this.conf = cfg;
16
+ this.ctx = ctx;
17
+ ctx.on('ready', async () => {
18
+ this.ctx.i18n.define('zh-CN', zhCN);
19
+ this.ctx.i18n.define('en-US', enUS);
20
+ this.wss = new ws_1.WebSocketServer({ host: cfg.wsHost, port: cfg.wsPort });
21
+ ctx.logger.info(`Websocket服务器已启动 ws://${cfg.wsHost}:${cfg.wsPort}`);
22
+ // 设置 WebSocket 连接处理
23
+ this.setupWebSocketHandlers();
24
+ });
25
+ // 设置消息处理(只需要一次)
26
+ this.setupMessageHandler();
27
+ ctx.on('dispose', async () => {
28
+ if (this.wss) {
29
+ this.wss.close();
30
+ }
31
+ this.connectedClients.clear();
32
+ });
33
+ }
34
+ setupWebSocketHandlers() {
35
+ this.wss.on('connection', (ws, req) => {
36
+ const msgData = {
37
+ api: 'broadcast',
38
+ data: {
39
+ message: [
40
+ {
41
+ text: extractAndRemoveColor(this.conf.joinMsg).output,
42
+ color: extractAndRemoveColor(this.conf.joinMsg).color
43
+ ? extractAndRemoveColor(this.conf.joinMsg).color
44
+ : 'gold',
45
+ },
46
+ ],
47
+ },
48
+ };
49
+ ws.send(JSON.stringify(msgData));
50
+ this.ctx.logger.success('客户端连接成功!');
51
+ const headers = req.headers;
52
+ // 验证 Token
53
+ if (!this.verifyHeaders(headers).valid) {
54
+ this.ctx.logger.error('请求头验证失败!');
55
+ if (!this.conf.hideConnect) {
56
+ this.ctx.bots.forEach(async (bot) => {
57
+ const channels = this.conf.sendToChannel
58
+ .filter(str => str.includes(`${bot.platform}`))
59
+ .map(str => str.replace(`${bot.platform}:`, ''));
60
+ bot.broadcast(channels, 'Websocket请求头验证失败!', 0);
61
+ });
62
+ }
63
+ ws.close(1008, 'Invalid header!');
64
+ return;
65
+ }
66
+ if (!this.conf.hideConnect) {
67
+ this.ctx.bots.forEach(async (bot) => {
68
+ const channels = this.conf.sendToChannel
69
+ .filter(str => str.includes(`${bot.platform}`))
70
+ .map(str => str.replace(`${bot.platform}:`, ''));
71
+ if (!this.conf.hideConnect) {
72
+ bot.broadcast(channels, 'Websocket客户端连接成功!', 0);
73
+ }
74
+ });
75
+ }
76
+ // 添加到连接的客户端集合
77
+ this.connectedClients.add(ws);
78
+ // 当收到客户端消息时触发
79
+ ws.on('message', async (buffer) => {
80
+ this.ctx.logger.info(`收到来自客户端的消息: ${buffer.toString()}`);
81
+ const data = JSON.parse(buffer.toString());
82
+ const eventName = data.event_name
83
+ ? (0, values_1.getListeningEvent)(data.event_name)
84
+ : '';
85
+ if (!(0, values_1.getSubscribedEvents)(this.conf.event).includes(eventName)) {
86
+ return;
87
+ }
88
+ // let sendMsg = getSubscribedEvents(this.conf.event).includes(eventName)? `[${data.server_name}](${eventTrans[eventName].name}) ${eventTrans[eventName].action? data.player?.nickname+' ':''}${(eventTrans[eventName].action? eventTrans[eventName].action+' ':'')}${data.message? data.message:''}`:''
89
+ // let sendMsg:any = h.unescape(sendMsg).replaceAll('&amp;','&').replaceAll(/<\/?template>/gi,'').replaceAll(/§./g,'')
90
+ let sendMsg = koishi_1.h
91
+ .unescape(data.message ? data.message : '')
92
+ .replaceAll('&amp;', '&')
93
+ .replaceAll(/<\/?template>/gi, '')
94
+ .replaceAll(/§./g, '');
95
+ sendMsg = sendMsg.replaceAll(/<json.*\/>/gi, '<json消息>');
96
+ const imageMatch = sendMsg.match(/(https?|file):\/\/.*\.(jpg|jpeg|webp|ico|gif|jfif|bmp|png)/gi);
97
+ const sendImage = imageMatch?.[0];
98
+ if (sendImage) {
99
+ sendMsg = sendMsg.replace(sendImage, `<img src="${sendImage}" />`);
100
+ }
101
+ sendMsg = this.ctx.i18n.render([this.conf.locale ? this.conf.locale : 'zh-CN'], [`minecraft-sync-msg.action.${eventName}`], [data.player?.nickname, sendMsg]);
102
+ if (data.server_name) {
103
+ this.ctx.bots.forEach(async (bot) => {
104
+ const channels = this.conf.sendToChannel
105
+ .filter(str => str.includes(`${bot.platform}`))
106
+ .map(str => str.replace(`${bot.platform}:`, ''));
107
+ if (sendMsg) {
108
+ bot.broadcast(channels, sendMsg, 0);
109
+ }
110
+ });
111
+ }
112
+ });
113
+ ws.on('error', err => {
114
+ if (!this.conf.hideConnect) {
115
+ this.ctx.bots.forEach(async (bot) => {
116
+ const channels = this.conf.sendToChannel
117
+ .filter(str => str.includes(`${bot.platform}`))
118
+ .map(str => str.replace(`${bot.platform}:`, ''));
119
+ bot.broadcast(channels, '与Websocket客户端断通信时发生错误!', 0);
120
+ });
121
+ }
122
+ this.ctx.logger.error('与Websocket客户端断通信时发生错误!' + err);
123
+ });
124
+ // 当客户端断开连接时触发
125
+ ws.on('close', () => {
126
+ this.connectedClients.delete(ws);
127
+ if (!this.conf.hideConnect) {
128
+ this.ctx.bots.forEach(async (bot) => {
129
+ const channels = this.conf.sendToChannel
130
+ .filter(str => str.includes(`${bot.platform}`))
131
+ .map(str => str.replace(`${bot.platform}:`, ''));
132
+ bot.broadcast(channels, '与Websocket客户端断开连接!', 0);
133
+ });
134
+ }
135
+ this.ctx.logger.error('非正常与Websocket客户端断开连接!');
136
+ });
137
+ });
138
+ }
139
+ setupMessageHandler() {
140
+ let imgurl = '<unknown image url>';
141
+ this.ctx.on('message', async (session) => {
142
+ // this.ctx.logger.info(`收到聊天消息: ${session.content} 来自 ${session.platform}:${session.channelId}`);
143
+ if (session.content.includes('<img') &&
144
+ koishi_1.h.select(session.content, 'img')[0]?.type === 'img' &&
145
+ koishi_1.h.select(session.content, 'img')[0]?.attrs?.src) {
146
+ imgurl = koishi_1.h.select(session.content, 'img')[0].attrs.src;
147
+ }
148
+ if (this.conf.sendToChannel.includes(`${session.platform}:${session.channelId}`) ||
149
+ session.platform === 'sandbox') {
150
+ if (session.content.startsWith(this.conf.sendprefix) &&
151
+ session.content !== this.conf.sendprefix) {
152
+ const msg = session.content
153
+ .replaceAll('&amp;', '&')
154
+ .replaceAll(/<\/?template>/gi, '')
155
+ .replace(this.conf.sendprefix, '')
156
+ .replaceAll(/<json.*\/>/gi, '<json消息>')
157
+ .replaceAll(/<video.*\/>/gi, '<视频消息>')
158
+ .replaceAll(/<audio.*\/>/gi, '<音频消息>')
159
+ .replaceAll(/<img.*\/>/gi, `[[CICode,url=${imgurl}]]`)
160
+ .replaceAll(/<at.*\/>/gi, `@[${koishi_1.h.select(session.content, 'at')[0]?.attrs?.name
161
+ ? koishi_1.h.select(session.content, 'at')[0]?.attrs?.name
162
+ : koishi_1.h.select(session.content, 'at')[0]?.attrs?.id}]`);
163
+ if (this.connectedClients.size > 0) {
164
+ const msgData = {
165
+ api: 'broadcast',
166
+ data: {
167
+ message: [
168
+ {
169
+ // text: `(${session.platform})[${session.event.user.name}] ` + extractAndRemoveColor(msg).output,
170
+ text: this.ctx.i18n
171
+ .render([this.conf.locale ? this.conf.locale : 'zh-CN'], ['minecraft-sync-msg.message.MCReceivePrefix'], [session.platform, session.userId])
172
+ .map(element => element.attrs?.content)
173
+ .join('') + extractAndRemoveColor(msg).output,
174
+ color: extractAndRemoveColor(msg).color
175
+ ? extractAndRemoveColor(msg).color
176
+ : 'white',
177
+ },
178
+ ],
179
+ },
180
+ };
181
+ let sent = false;
182
+ this.connectedClients.forEach(client => {
183
+ if (client.readyState === ws_1.WebSocket.OPEN) {
184
+ try {
185
+ client.send(JSON.stringify(msgData));
186
+ sent = true;
187
+ }
188
+ catch (err) {
189
+ this.ctx.logger.error(`聊天消息发送到WebSocket客户端失败: ${err}`);
190
+ }
191
+ }
192
+ });
193
+ if (!sent) {
194
+ session.send('发送失败! 没有可用的WebSocket连接。');
195
+ }
196
+ }
197
+ else {
198
+ session.send('发送失败! 没有可用的WebSocket连接。');
199
+ }
200
+ }
201
+ }
202
+ });
203
+ }
204
+ verifyHeaders(headers) {
205
+ const authHeader = headers['authorization'];
206
+ const selfNameHeader = headers['x-self-name'];
207
+ const clientOriginHeader = headers['x-client-origin'];
208
+ // 验证 Token
209
+ if (!authHeader) {
210
+ this.logger.error('Missing authorization header');
211
+ return { valid: false };
212
+ }
213
+ const token = authHeader.split(' ')[1];
214
+ if (token !== this.conf.Token) {
215
+ this.logger.error('Token is invalid!');
216
+ return { valid: false };
217
+ }
218
+ // 验证 x-self-name
219
+ if (!selfNameHeader) {
220
+ this.logger.error('Missing x-self-name header');
221
+ return { valid: false };
222
+ }
223
+ const decodedSelfName = decodeURIComponent(selfNameHeader);
224
+ if (decodedSelfName !== this.conf.serverName) {
225
+ this.logger.error('Invalid x-self-name');
226
+ return { valid: false };
227
+ }
228
+ // 获取 x-client-origin
229
+ const clientOrigin = clientOriginHeader;
230
+ return { valid: true, clientOrigin };
231
+ }
232
+ }
233
+ function extractAndRemoveColor(input) {
234
+ const regex = /&(\w+)&/;
235
+ const match = input.match(regex);
236
+ if (match) {
237
+ const color = match[1];
238
+ const output = input.replace(regex, '');
239
+ return { output, color };
240
+ }
241
+ return { output: input, color: '' };
242
+ }
243
+ (function (McWss) {
244
+ McWss.Config = koishi_1.Schema.intersect([
245
+ values_1.WsConf,
246
+ koishi_1.Schema.object({
247
+ sendToChannel: koishi_1.Schema.array(String).description('消息发送到目标群组格式{paltform}:{groupId}'),
248
+ sendprefix: koishi_1.Schema.string()
249
+ .default('.#')
250
+ .description('消息发送前缀(不可与命令发送前缀相同)'),
251
+ hideConnect: koishi_1.Schema.boolean()
252
+ .default(true)
253
+ .description('关闭连接成功/失败提示'),
254
+ locale: koishi_1.Schema.union(['zh-CN', 'en-US'])
255
+ .default('zh-CN')
256
+ .description('本地化语言选择,zh_CN为中文,en-US为英文'),
257
+ }).description('基础配置'),
258
+ ]);
259
+ })(McWss || (McWss = {}));
260
+ exports.default = McWss;
@@ -0,0 +1,72 @@
1
+ import { Schema } from 'koishi';
2
+ export declare enum mcEvent {
3
+ AsyncPlayerChatEvent = 1,
4
+ PlayerCommandPreprocessEvent = 2,
5
+ PlayerDeathEvent = 4,
6
+ PlayerJoinEvent = 8,
7
+ PlayerQuitEvent = 16
8
+ }
9
+ export interface WsConf {
10
+ wsServer: boolean | string;
11
+ wsHost: string;
12
+ wsPort: number;
13
+ Token: string;
14
+ serverName: string;
15
+ joinMsg: string;
16
+ event: mcEvent;
17
+ maxReconnectCount: number;
18
+ maxReconnectInterval: number;
19
+ }
20
+ export declare const WsConf: Schema<Schemastery.ObjectS<{
21
+ wsServer: Schema<"客户端" | "服务端", "客户端" | "服务端">;
22
+ wsHost: Schema<string, string>;
23
+ wsPort: Schema<number, number>;
24
+ Token: Schema<string, string>;
25
+ serverName: Schema<string, string>;
26
+ joinMsg: Schema<string, string>;
27
+ event: Schema<number | readonly ("AsyncPlayerChatEvent" | "PlayerCommandPreprocessEvent" | "PlayerDeathEvent" | "PlayerJoinEvent" | "PlayerQuitEvent")[], number>;
28
+ maxReconnectCount: Schema<number, number>;
29
+ maxReconnectInterval: Schema<number, number>;
30
+ }>, Schemastery.ObjectT<{
31
+ wsServer: Schema<"客户端" | "服务端", "客户端" | "服务端">;
32
+ wsHost: Schema<string, string>;
33
+ wsPort: Schema<number, number>;
34
+ Token: Schema<string, string>;
35
+ serverName: Schema<string, string>;
36
+ joinMsg: Schema<string, string>;
37
+ event: Schema<number | readonly ("AsyncPlayerChatEvent" | "PlayerCommandPreprocessEvent" | "PlayerDeathEvent" | "PlayerJoinEvent" | "PlayerQuitEvent")[], number>;
38
+ maxReconnectCount: Schema<number, number>;
39
+ maxReconnectInterval: Schema<number, number>;
40
+ }>>;
41
+ export interface RconConf {
42
+ rconEnable: boolean;
43
+ rconServerHost: string;
44
+ rconServerPort: number;
45
+ rconPassword: string;
46
+ alluser: boolean;
47
+ superuser: string[];
48
+ commonCmd: string[];
49
+ cannotCmd: string[];
50
+ }
51
+ export declare const RconConf: Schema<Schemastery.ObjectS<{
52
+ rconEnable: Schema<boolean, boolean>;
53
+ rconServerHost: Schema<string, string>;
54
+ rconServerPort: Schema<number, number>;
55
+ rconPassword: Schema<string, string>;
56
+ alluser: Schema<boolean, boolean>;
57
+ superuser: Schema<string[], string[]>;
58
+ commonCmd: Schema<string[], string[]>;
59
+ cannotCmd: Schema<string[], string[]>;
60
+ }>, Schemastery.ObjectT<{
61
+ rconEnable: Schema<boolean, boolean>;
62
+ rconServerHost: Schema<string, string>;
63
+ rconServerPort: Schema<number, number>;
64
+ rconPassword: Schema<string, string>;
65
+ alluser: Schema<boolean, boolean>;
66
+ superuser: Schema<string[], string[]>;
67
+ commonCmd: Schema<string[], string[]>;
68
+ cannotCmd: Schema<string[], string[]>;
69
+ }>>;
70
+ export declare const eventList: string[];
71
+ export declare function getSubscribedEvents(binaryInput: number): string[];
72
+ export declare function getListeningEvent(input: string | string[]): string;
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.eventList = exports.RconConf = exports.WsConf = exports.mcEvent = void 0;
4
+ exports.getSubscribedEvents = getSubscribedEvents;
5
+ exports.getListeningEvent = getListeningEvent;
6
+ const koishi_1 = require("koishi");
7
+ // 放在主逻辑里面很碍眼的东西
8
+ var mcEvent;
9
+ (function (mcEvent) {
10
+ mcEvent[mcEvent["AsyncPlayerChatEvent"] = 1] = "AsyncPlayerChatEvent";
11
+ mcEvent[mcEvent["PlayerCommandPreprocessEvent"] = 2] = "PlayerCommandPreprocessEvent";
12
+ mcEvent[mcEvent["PlayerDeathEvent"] = 4] = "PlayerDeathEvent";
13
+ mcEvent[mcEvent["PlayerJoinEvent"] = 8] = "PlayerJoinEvent";
14
+ mcEvent[mcEvent["PlayerQuitEvent"] = 16] = "PlayerQuitEvent";
15
+ })(mcEvent || (exports.mcEvent = mcEvent = {}));
16
+ exports.WsConf = koishi_1.Schema.object({
17
+ wsServer: koishi_1.Schema.union(['客户端', '服务端'])
18
+ .default('客户端')
19
+ .description('Websocket端选择'),
20
+ wsHost: koishi_1.Schema.string()
21
+ .default('127.0.0.1')
22
+ .description('websocket服务器的地址(服务器监听地址)'),
23
+ wsPort: koishi_1.Schema.number()
24
+ .default(8080)
25
+ .description('websocket服务器的端口(服务器监听端口)'),
26
+ Token: koishi_1.Schema.string().description('websocket服务器的验证Token'),
27
+ serverName: koishi_1.Schema.string().description('鹊桥配置文件中对应的server_name'),
28
+ joinMsg: koishi_1.Schema.string()
29
+ .default('[客户端] 连接成功!')
30
+ .description('连接服务的成功时发送的消息(&颜色单词&可以设置颜色)'),
31
+ event: koishi_1.Schema.bitset(mcEvent).description('选择需要监听的事件'),
32
+ maxReconnectCount: koishi_1.Schema.number()
33
+ .default(20)
34
+ .description('[仅客户端生效]客户端最大重连次数'),
35
+ maxReconnectInterval: koishi_1.Schema.number()
36
+ .default(60000)
37
+ .description('[仅客户端生效]客户端单次重连时间(ms)'),
38
+ })
39
+ .collapse()
40
+ .description('Websocket配置');
41
+ exports.RconConf = koishi_1.Schema.object({
42
+ rconEnable: koishi_1.Schema.boolean().default(true).description('开启RCON功能'),
43
+ rconServerHost: koishi_1.Schema.string()
44
+ .default('127.0.0.1')
45
+ .description('rcon服务器地址'),
46
+ rconServerPort: koishi_1.Schema.number()
47
+ .default(25575)
48
+ .description('rcon服务器地址端口'),
49
+ rconPassword: koishi_1.Schema.string()
50
+ .role('secret')
51
+ .description('rcon服务器的密码(推荐设置)'),
52
+ alluser: koishi_1.Schema.boolean()
53
+ .default(false)
54
+ .description('所有用户可用(开启后下面的配置失效)'),
55
+ superuser: koishi_1.Schema.array(String).description('超级用户的ID,可以使用RCON所有命令'),
56
+ commonCmd: koishi_1.Schema.array(String)
57
+ .default(['list', 'spigot:tps'])
58
+ .description('普通用户可以使用的命令'),
59
+ cannotCmd: koishi_1.Schema.array(String)
60
+ .default(['restart', 'stop'])
61
+ .description('不能使用的命令'),
62
+ })
63
+ .collapse()
64
+ .description('RCON配置');
65
+ exports.eventList = [
66
+ 'AsyncPlayerChatEvent',
67
+ 'PlayerCommandPreprocessEvent',
68
+ 'PlayerDeathEvent',
69
+ 'PlayerJoinEvent',
70
+ 'PlayerQuitEvent',
71
+ ];
72
+ // export const eventTrans = {
73
+ // AsyncPlayerChatEvent: {
74
+ // name: "聊天信息",
75
+ // action: '说'
76
+ // },
77
+ // PlayerCommandPreprocessEvent: {
78
+ // name: "玩家命令执行事件",
79
+ // action: "发送了命令"
80
+ // },
81
+ // PlayerDeathEvent: {
82
+ // name: "玩家死亡事件",
83
+ // action: null
84
+ // },
85
+ // PlayerJoinEvent: {
86
+ // name: "玩家加入事件",
87
+ // action: "加入了服务器"
88
+ // },
89
+ // PlayerQuitEvent: {
90
+ // name: "玩家退出事件",
91
+ // action: "离开了服务器"
92
+ // }
93
+ // }
94
+ // 事件映射
95
+ function getSubscribedEvents(binaryInput) {
96
+ const subscribedEvents = [];
97
+ const eventValues = Object.values(mcEvent).filter(value => typeof value === 'number');
98
+ const eventNames = Object.keys(mcEvent).filter(key => isNaN(Number(key)));
99
+ for (let i = 0; i < eventValues.length; i++) {
100
+ if ((binaryInput & eventValues[i]) !== 0) {
101
+ subscribedEvents.push(eventNames[i]);
102
+ }
103
+ }
104
+ return subscribedEvents;
105
+ }
106
+ // 事件映射变量
107
+ const eventMap = {
108
+ AsyncPlayerChatEvent: 'AsyncPlayerChatEvent',
109
+ ServerMessageEvent: 'AsyncPlayerChatEvent',
110
+ ServerChatEvent: 'AsyncPlayerChatEvent',
111
+ NeoServerChatEvent: 'AsyncPlayerChatEvent',
112
+ MinecraftPlayerChatEvent: 'AsyncPlayerChatEvent',
113
+ BaseChatEvent: 'AsyncPlayerChatEvent',
114
+ PlayerChatEvent: 'AsyncPlayerChatEvent',
115
+ PlayerCommandPreprocessEvent: 'PlayerCommandPreprocessEvent',
116
+ ServerCommandMessageEvent: 'PlayerCommandPreprocessEvent',
117
+ CommandEvent: 'PlayerCommandPreprocessEvent',
118
+ NeoCommandEvent: 'PlayerCommandPreprocessEvent',
119
+ BasePlayerCommandEvent: 'PlayerCommandPreprocessEvent',
120
+ PlayerCommandEvent: 'PlayerCommandPreprocessEvent',
121
+ PlayerDeathEvent: 'PlayerDeathEvent', // Spigot 与 Forge 同名
122
+ NeoPlayerDeathEvent: 'PlayerDeathEvent',
123
+ ServerLivingEntityAfterDeathEvent: 'PlayerDeathEvent',
124
+ BaseDeathEvent: 'PlayerDeathEvent',
125
+ PlayerJoinEvent: 'PlayerJoinEvent',
126
+ ServerPlayConnectionJoinEvent: 'PlayerJoinEvent',
127
+ PlayerLoggedInEvent: 'PlayerJoinEvent',
128
+ NeoPlayerLoggedInEvent: 'PlayerJoinEvent',
129
+ MinecraftPlayerJoinEvent: 'PlayerJoinEvent',
130
+ BaseJoinEvent: 'PlayerJoinEvent',
131
+ PlayerQuitEvent: 'PlayerQuitEvent',
132
+ ServerPlayConnectionDisconnectEvent: 'PlayerQuitEvent',
133
+ PlayerLoggedOutEvent: 'PlayerQuitEvent',
134
+ NeoPlayerLoggedOutEvent: 'PlayerQuitEvent',
135
+ MinecraftPlayerQuitEvent: 'PlayerQuitEvent',
136
+ BaseQuitEvent: 'PlayerQuitEvent',
137
+ VelocityDisconnectEvent: 'PlayerQuitEvent',
138
+ VelocityCommandExecuteEvent: 'PlayerCommandPreprocessEvent',
139
+ VelocityLoginEvent: 'PlayerJoinEvent',
140
+ VelocityPlayerChatEvent: 'AsyncPlayerChatEvent',
141
+ };
142
+ // 监听映射
143
+ function getListeningEvent(input) {
144
+ if (typeof input === 'string') {
145
+ input = [input];
146
+ }
147
+ const uniqueEvents = new Set();
148
+ for (const event of input) {
149
+ if (eventMap[event]) {
150
+ uniqueEvents.add(eventMap[event]);
151
+ }
152
+ }
153
+ // 如果有多个映射结果,返回第一个
154
+ return Array.from(uniqueEvents)[0];
155
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * 清洗数据防止QQ脏数据发送到游戏内
3
+ */
4
+ export declare const clearSessionContentToMcMessage: (content: string) => string;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clearSessionContentToMcMessage = void 0;
4
+ const koishi_1 = require("koishi");
5
+ /**
6
+ * 清洗数据防止QQ脏数据发送到游戏内
7
+ */
8
+ const clearSessionContentToMcMessage = (content) => {
9
+ // let imgurl = '<unknown image url>';
10
+ if (content.includes('<img')
11
+ // &&
12
+ // h.select(content, "img")[0]?.type === "img" &&
13
+ // h.select(content, "img")[0]?.attrs?.src
14
+ ) {
15
+ // imgurl = h.select(content, "img")[0].attrs.src;
16
+ return content.replaceAll(/<img.*\/>/gi, `[图片]`);
17
+ }
18
+ return (content
19
+ .replaceAll('&amp;', '&')
20
+ .replaceAll(/<\/?template>/gi, '')
21
+ .replaceAll(/<json.*\/>/gi, '<json消息>')
22
+ .replaceAll(/<video.*\/>/gi, '<视频消息>')
23
+ .replaceAll(/<audio.*\/>/gi, '<音频消息>')
24
+ // .replaceAll(/<img.*\/>/gi, `[[CICode,url=${imgurl}]]`)
25
+ .replaceAll(/<at.*\/>/gi, `@[${koishi_1.h.select(content, 'at')[0]?.attrs?.name
26
+ ? koishi_1.h.select(content, 'at')[0]?.attrs?.name
27
+ : koishi_1.h.select(content, 'at')[0]?.attrs?.id}]`));
28
+ };
29
+ exports.clearSessionContentToMcMessage = clearSessionContentToMcMessage;
@@ -0,0 +1 @@
1
+ export * from './game.mc';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./game.mc"), exports);
package/package.json CHANGED
@@ -1,17 +1,20 @@
1
1
  {
2
2
  "name": "koishi-plugin-gl-bot",
3
3
  "description": "GleamSlime Koishi Rebot Plugins",
4
- "version": "0.0.7",
5
- "main": "src/index.ts",
4
+ "version": "0.0.9",
5
+ "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "contributors": [
8
8
  "GleamSlime <gleamslime@163.com>"
9
9
  ],
10
10
  "scripts": {
11
- "build": "tsc -p ."
11
+ "format": "prettier --write .",
12
+ "lint": "eslint .",
13
+ "fl": "prettier --write . && eslint . --fix",
14
+ "build:console": "koishi-console build",
15
+ "build": "tsc -p tsconfig.test.json && cp -r src/queQiao/locale lib/queQiao/ || true"
12
16
  },
13
17
  "files": [
14
- "src",
15
18
  "lib",
16
19
  "dist"
17
20
  ],
@@ -25,6 +28,7 @@
25
28
  ],
26
29
  "devDependencies": {
27
30
  "@koishijs/client": "^5.30.11",
31
+ "@types/lodash-es": "^4",
28
32
  "typescript": "^5.9.3"
29
33
  },
30
34
  "peerDependencies": {
@@ -35,5 +39,11 @@
35
39
  "description": {
36
40
  "zh": "GleamSlime Koishi 兽耳咖啡厅插件"
37
41
  }
42
+ },
43
+ "dependencies": {
44
+ "lodash-es": "^4.17.22",
45
+ "rcon-client": "^4.2.5",
46
+ "socket.io-client": "^4.8.2",
47
+ "ws": "^8.18.3"
38
48
  }
39
49
  }
package/src/index.ts DELETED
@@ -1,20 +0,0 @@
1
- import { Context, Schema } from "koishi";
2
- import { resolve } from "path";
3
- import {} from "@koishijs/plugin-console";
4
-
5
- export const name = "gl-bot";
6
-
7
- export interface Config {}
8
-
9
- export const Config: Schema<Config> = Schema.object({});
10
-
11
- export function apply(ctx: Context) {
12
- ctx.inject(["console"], (ctx) => {
13
- ctx.on("message", (session) => {
14
- console.log(session.content);
15
- if (session.content === "天王盖地虎") {
16
- session.send("宝塔镇河妖");
17
- }
18
- });
19
- });
20
- }