floating-live 0.8.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.
Files changed (57) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +62 -0
  3. package/index.d.ts +2 -0
  4. package/index.js +6 -0
  5. package/package.json +29 -0
  6. package/plugin/acfun/acfunLive.d.ts +74 -0
  7. package/plugin/acfun/acfunLive.js +236 -0
  8. package/plugin/acfun/index.d.ts +3 -0
  9. package/plugin/acfun/index.js +12 -0
  10. package/plugin/bilibili/bilibiliLive.d.ts +58 -0
  11. package/plugin/bilibili/bilibiliLive.js +421 -0
  12. package/plugin/bilibili/index.d.ts +3 -0
  13. package/plugin/bilibili/index.js +12 -0
  14. package/plugin/chat/ChatCommand.d.ts +9 -0
  15. package/plugin/chat/ChatCommand.js +39 -0
  16. package/plugin/chat/ChatFilter.d.ts +9 -0
  17. package/plugin/chat/ChatFilter.js +44 -0
  18. package/plugin/chat/chatProcessor.d.ts +12 -0
  19. package/plugin/chat/chatProcessor.js +24 -0
  20. package/plugin/chatPrint/chatPrint.d.ts +21 -0
  21. package/plugin/chatPrint/chatPrint.js +111 -0
  22. package/plugin/chatPrint/index.d.ts +4 -0
  23. package/plugin/chatPrint/index.js +8 -0
  24. package/plugin/consoleEvent/index.d.ts +3 -0
  25. package/plugin/consoleEvent/index.js +39 -0
  26. package/plugin/msgSave/index.d.ts +4 -0
  27. package/plugin/msgSave/index.js +31 -0
  28. package/plugin/msgSave/msgSave.d.ts +22 -0
  29. package/plugin/msgSave/msgSave.js +40 -0
  30. package/src/controller/Message.d.ts +9 -0
  31. package/src/controller/Message.js +15 -0
  32. package/src/controller/Room.d.ts +32 -0
  33. package/src/controller/Room.js +110 -0
  34. package/src/controller/index.d.ts +39 -0
  35. package/src/controller/index.js +74 -0
  36. package/src/index.d.ts +33 -0
  37. package/src/index.js +50 -0
  38. package/src/lib/Registerable.d.ts +27 -0
  39. package/src/lib/Registerable.js +67 -0
  40. package/src/types/message/AttributeInfo.d.ts +64 -0
  41. package/src/types/message/AttributeInfo.js +2 -0
  42. package/src/types/message/MessageData.d.ts +80 -0
  43. package/src/types/message/MessageData.js +2 -0
  44. package/src/types/message/MessageInfo.d.ts +123 -0
  45. package/src/types/message/MessageInfo.js +2 -0
  46. package/src/types/plugin/Plugin.d.ts +3 -0
  47. package/src/types/plugin/Plugin.js +2 -0
  48. package/src/types/room/LiveInfo.d.ts +24 -0
  49. package/src/types/room/LiveInfo.js +2 -0
  50. package/src/types/room/LiveRoom.d.ts +20 -0
  51. package/src/types/room/LiveRoom.js +2 -0
  52. package/src/types/room/PlatformInfo.d.ts +38 -0
  53. package/src/types/room/PlatformInfo.js +2 -0
  54. package/src/types/room/RoomInfo.d.ts +16 -0
  55. package/src/types/room/RoomInfo.js +2 -0
  56. package/src/utils/getRoomInfo.d.ts +4 -0
  57. package/src/utils/getRoomInfo.js +25 -0
@@ -0,0 +1,421 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const bilibili_live_ws_1 = require("bilibili-live-ws");
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const events_1 = require("events");
9
+ class bilibiliLive extends events_1.EventEmitter {
10
+ constructor(id, // 房间id
11
+ open = false, // 生成房间后是否打开
12
+ config) {
13
+ super();
14
+ /** 平台id */
15
+ this.platform = "bilibili";
16
+ /** 直播间room_id */
17
+ this.roomid = 0;
18
+ /** 直播信息 */
19
+ this.live = {
20
+ /** 直播标题 */
21
+ title: "",
22
+ /** 分区 */
23
+ area: [],
24
+ /** 封面url */
25
+ cover: "",
26
+ /** 直播状态 */
27
+ status: "off",
28
+ /** 开始直播时间 */
29
+ start_time: 0
30
+ };
31
+ this.cover = "";
32
+ /** 主播信息 */
33
+ this.anchor = { name: "", id: 0 };
34
+ /** 直播间是否可用 */
35
+ this.available = false;
36
+ /** 直播间弹幕api模块 */
37
+ this.client = null;
38
+ /** 是否为持续监听状态 */
39
+ this.opening = false;
40
+ this.id = id; // 直播间号
41
+ this.connectInterval = config?.connectInterval || 100;
42
+ this.getInfo().then(() => {
43
+ if (open)
44
+ this.open();
45
+ });
46
+ }
47
+ /** 获取房间信息 */
48
+ async getInfo() {
49
+ await axios_1.default
50
+ .get(`https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=${this.id}`) // 获取直播间信息
51
+ .then((res) => {
52
+ let data = res.data.data;
53
+ this.roomid = data.room_info.room_id;
54
+ this.live.status = data.room_info.live_status == 1 ? "live" : "off";
55
+ this.live.start_time = this.live.status == "live" ? data.room_info.live_start_time * 1000 : 0;
56
+ this.live.title = data.room_info.title;
57
+ this.anchor.id = data.room_info.uid;
58
+ this.anchor.name = data.anchor_info.base_info.uname;
59
+ this.anchor.avatar = data.anchor_info.base_info.face;
60
+ this.live.area = [data.room_info.parent_area_name, data.room_info.area_name];
61
+ this.cover = data.room_info.cover;
62
+ this.available = true;
63
+ })
64
+ .catch((error) => {
65
+ console.error(error);
66
+ });
67
+ console.log("[bilibiliLive] 已获取房间信息");
68
+ this.emit("info");
69
+ }
70
+ /** 开启直播间监听 */
71
+ async open() {
72
+ if (this.opening || !this.available)
73
+ return;
74
+ if (!this.roomid) {
75
+ console.log("[bilibili-live-ws] 未获取直播间room_id属性");
76
+ return;
77
+ }
78
+ this.opening = true;
79
+ this.createWS();
80
+ this.emit("open");
81
+ }
82
+ /** 连接直播服务端 */
83
+ async createWS() {
84
+ // 与Websocket服务器连接
85
+ console.log("[bilibili-live-ws] 开始连接bilibili直播服务器");
86
+ this.client = new bilibili_live_ws_1.KeepLiveWS(this.roomid);
87
+ let client = this.client;
88
+ client.interval = this.connectInterval;
89
+ client.on("open", () => {
90
+ console.log("[bilibili-live-ws] 已连接bilibili直播服务器");
91
+ this.emit("connect");
92
+ });
93
+ client.on("close", () => {
94
+ console.log("[bilibili-live-ws] 与bilibili直播服务器的连接已关闭");
95
+ this.emit("disconnect");
96
+ });
97
+ client.on("live", () => {
98
+ console.log("[bilibili-live-ws] 目标房间连接成功");
99
+ });
100
+ client.on("msg", (data) => {
101
+ this.emitOrigin(data);
102
+ });
103
+ client.on("DANMU_MSG", this.msg_DANMU_MSG.bind(this));
104
+ //client.on("ENTRY_EFFECT", this.msg_ENTRY_EFFECT.bind(this));
105
+ client.on("INTERACT_WORD", this.msg_INTERACT_WORD.bind(this));
106
+ client.on("SEND_GIFT", this.msg_SEND_GIFT.bind(this));
107
+ client.on("GUARD_BUY", this.msg_GUARD_BUY.bind(this));
108
+ //client.on('COMBO_SEND', this.msg_COMBO_SEND.bind(this))
109
+ client.on("ROOM_BLOCK_MSG", this.msg_ROOM_BLOCK_MSG.bind(this));
110
+ client.on("SUPER_CHAT_MESSAGE", this.msg_SUPER_CHAT_MESSAGE.bind(this));
111
+ client.on("CUT_OFF", this.msg_CUT_OFF.bind(this));
112
+ client.on("PREPARING", this.msg_PREPARING.bind(this));
113
+ client.on("LIVE", this.msg_LIVE.bind(this));
114
+ }
115
+ close() {
116
+ if (!this.opening)
117
+ return;
118
+ this.opening = false;
119
+ this.client?.close();
120
+ this.emit("close");
121
+ }
122
+ destory() {
123
+ this.close();
124
+ this.removeAllListeners();
125
+ }
126
+ emitMsg(data) {
127
+ // 一般消息
128
+ this.emit("msg", data);
129
+ }
130
+ emitOrigin(data) {
131
+ // 源消息
132
+ this.emit("origin", data);
133
+ }
134
+ getDanmakuMode(n) {
135
+ switch (n) {
136
+ case 1:
137
+ return "left";
138
+ case 4:
139
+ return "bottom";
140
+ case 5:
141
+ return "top";
142
+ default:
143
+ return "left";
144
+ }
145
+ }
146
+ /** 获取弹幕消息 */
147
+ msg_DANMU_MSG(msg) {
148
+ let text = msg.info[1];
149
+ let mode = this.getDanmakuMode(msg.info[0][1]);
150
+ let color = msg.info[0][3];
151
+ let uname = msg.info[2][1];
152
+ let uid = msg.info[2][0];
153
+ let timestamp = msg.info[0][4];
154
+ let guard_level = msg.info[7]; // 舰长级别
155
+ let medal = (msg.info[3].length) ? {
156
+ level: msg.info[3][0],
157
+ name: msg.info[3][1],
158
+ // user: msg.info[3][2],
159
+ id: msg.info[3][12],
160
+ privilege: msg.info[3][10] || 0,
161
+ } : null;
162
+ let admin = undefined;
163
+ if (msg.info[2][2]) {
164
+ admin = 2;
165
+ }
166
+ else if (uid == this.anchor.id) {
167
+ admin = 1;
168
+ }
169
+ let danmaku;
170
+ if (msg.info[0][12]) {
171
+ danmaku = {
172
+ platform: "bilibili",
173
+ room: this.id,
174
+ type: "image",
175
+ local_timestamp: new Date().valueOf(),
176
+ info: {
177
+ timestamp: timestamp,
178
+ mode: mode,
179
+ image: {
180
+ name: text,
181
+ id: msg.info[0][13].emoticon_unique,
182
+ url: msg.info[0][13].url,
183
+ size: [msg.info[0][13].width, msg.info[0][13].height],
184
+ },
185
+ user: {
186
+ name: uname,
187
+ id: uid,
188
+ medal: medal,
189
+ privilege: guard_level,
190
+ admin: admin,
191
+ }
192
+ }
193
+ };
194
+ }
195
+ else {
196
+ danmaku = {
197
+ platform: "bilibili",
198
+ room: this.id,
199
+ type: "text",
200
+ local_timestamp: new Date().valueOf(),
201
+ info: {
202
+ timestamp: timestamp,
203
+ text: text,
204
+ color: color,
205
+ mode: mode,
206
+ user: {
207
+ name: uname,
208
+ id: uid,
209
+ medal: medal,
210
+ privilege: guard_level,
211
+ admin: admin,
212
+ }
213
+ },
214
+ };
215
+ }
216
+ this.emitMsg(danmaku);
217
+ }
218
+ /** 获取互动消息 */
219
+ msg_INTERACT_WORD(msg) {
220
+ let data = msg.data;
221
+ let type;
222
+ switch (data.msg_type) {
223
+ case 1:
224
+ type = "entry"; // 进入直播间
225
+ break;
226
+ case 2:
227
+ type = "follow"; // 关注直播间
228
+ break;
229
+ case 3:
230
+ type = "share"; // 分享直播间
231
+ break;
232
+ default:
233
+ return;
234
+ }
235
+ let interact = {
236
+ platform: "bilibili",
237
+ room: this.id,
238
+ type: type,
239
+ local_timestamp: new Date().valueOf(),
240
+ info: {
241
+ timestamp: Math.floor(data.trigger_time / 1000000),
242
+ user: {
243
+ name: data.uname,
244
+ id: data.uid,
245
+ medal: (data.fans_medal && data.fans_medal.medal_level) ? {
246
+ level: data.fans_medal.medal_level,
247
+ name: data.fans_medal.medal_name,
248
+ id: data.fans_medal.target_id,
249
+ privilege: data.fans_medal.guard_level,
250
+ } : null
251
+ }
252
+ },
253
+ };
254
+ this.emitMsg(interact);
255
+ }
256
+ /** 获取礼物消息 */
257
+ msg_SEND_GIFT(msg) {
258
+ let data = msg.data;
259
+ let gift = {
260
+ platform: "bilibili",
261
+ room: this.id,
262
+ type: "gift",
263
+ local_timestamp: new Date().valueOf(),
264
+ info: {
265
+ timestamp: data.timestamp * 1000,
266
+ user: {
267
+ name: data.uname,
268
+ id: data.uid,
269
+ medal: (data.fans_medal && data.fans_medal.medal_level) ? {
270
+ level: data.fans_medal.medal_level,
271
+ name: data.fans_medal.medal_name,
272
+ id: data.fans_medal.target_id,
273
+ privilege: data.fans_medal.guard_level,
274
+ } : null,
275
+ privilege: data.guard_level,
276
+ avatar: data.face
277
+ },
278
+ gift: {
279
+ name: data.giftName,
280
+ id: data.giftId,
281
+ num: data.num,
282
+ value: data.total_coin,
283
+ currency: data.coin_type,
284
+ action: data.action,
285
+ combo_id: data.batch_combo_id,
286
+ }
287
+ },
288
+ };
289
+ this.emitMsg(gift);
290
+ }
291
+ /** 获取舰长开通消息 */
292
+ msg_GUARD_BUY(msg) {
293
+ let data = msg.data;
294
+ let gift = {
295
+ platform: "bilibili",
296
+ room: this.id,
297
+ type: "privilege",
298
+ local_timestamp: new Date().valueOf(),
299
+ info: {
300
+ timestamp: data.start_time * 1000,
301
+ user: {
302
+ name: data.username,
303
+ id: data.uid,
304
+ privilege: data.guard_level,
305
+ },
306
+ gift: {
307
+ name: data.gift_name,
308
+ id: data.gift_id,
309
+ num: data.num,
310
+ value: data.price,
311
+ currency: "gold",
312
+ },
313
+ name: data.gift_name,
314
+ level: data.guard_level,
315
+ duration: data.num * 30,
316
+ },
317
+ };
318
+ this.emitMsg(gift);
319
+ }
320
+ /** 获取醒目留言消息 */
321
+ msg_SUPER_CHAT_MESSAGE(msg) {
322
+ let data = msg.data;
323
+ let sc = {
324
+ platform: "bilibili",
325
+ room: this.id,
326
+ type: "superchat",
327
+ local_timestamp: new Date().valueOf(),
328
+ info: {
329
+ id: data.id,
330
+ timestamp: data.ts * 1000,
331
+ user: {
332
+ name: data.user_info.uname,
333
+ id: data.uid,
334
+ avatar: data.user_info.face,
335
+ medal: (data.medal_info && data.medal_info.medal_level) ? {
336
+ level: data.medal_info.medal_level,
337
+ name: data.medal_info.medal_name,
338
+ id: data.medal_info.target_id,
339
+ privilege: data.medal_info.guard_level,
340
+ } : null,
341
+ privilege: data.user_info.guard_level,
342
+ },
343
+ text: data.message,
344
+ color: data.background_bottom_color,
345
+ duration: data.time * 1000,
346
+ gift: {
347
+ id: data.gift.gift_id,
348
+ name: data.gift.gift_name,
349
+ num: data.gift.num,
350
+ value: data.price * 1000,
351
+ currency: "gold",
352
+ }
353
+ },
354
+ };
355
+ this.emitMsg(sc);
356
+ }
357
+ msg_ROOM_BLOCK_MSG(msg) {
358
+ // 禁言
359
+ let data = msg.data;
360
+ let block = {
361
+ platform: "bilibili",
362
+ room: this.id,
363
+ type: "block",
364
+ local_timestamp: new Date().valueOf(),
365
+ info: {
366
+ user: {
367
+ id: data.uid,
368
+ name: data.uname
369
+ },
370
+ operator: {
371
+ admin: data.operator == 2 ? 1 : 2
372
+ }
373
+ },
374
+ };
375
+ this.emitMsg(block);
376
+ }
377
+ msg_LIVE(msg) {
378
+ // 直播间开播
379
+ if (msg.live_time) {
380
+ let live = {
381
+ platform: "bilibili",
382
+ room: this.id,
383
+ type: "live_start",
384
+ local_timestamp: new Date().valueOf(),
385
+ info: {
386
+ start_time: msg.live_time * 1000,
387
+ },
388
+ };
389
+ this.live.status = "live";
390
+ this.emitMsg(live);
391
+ }
392
+ }
393
+ msg_CUT_OFF(msg) {
394
+ // 直播间被切断
395
+ let cut = {
396
+ platform: "bilibili",
397
+ room: this.id,
398
+ type: "live_cut",
399
+ local_timestamp: new Date().valueOf(),
400
+ info: {
401
+ message: msg.msg,
402
+ },
403
+ };
404
+ this.live.status = "off";
405
+ this.emitMsg(cut);
406
+ }
407
+ msg_PREPARING(msg) {
408
+ let off = {
409
+ platform: "bilibili",
410
+ room: this.id,
411
+ type: "live_end",
412
+ local_timestamp: new Date().valueOf(),
413
+ info: {
414
+ status: msg.round ? "round" : "off"
415
+ }
416
+ };
417
+ this.live.status = msg.round ? "round" : "off";
418
+ this.emitMsg(off);
419
+ }
420
+ }
421
+ exports.default = bilibiliLive;
@@ -0,0 +1,3 @@
1
+ import FloatingLive from "../../src/index";
2
+ declare const _default: (ctx: FloatingLive) => void;
3
+ export = _default;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const bilibiliLive_1 = __importDefault(require("./bilibiliLive"));
6
+ module.exports = (ctx) => {
7
+ ctx.helper.roomGenerator.register("bilibili", (id, open) => {
8
+ let key = `bilibili:${Number(id)}`;
9
+ let room = new bilibiliLive_1.default(Number(id), open);
10
+ return { key, room };
11
+ });
12
+ };
@@ -0,0 +1,9 @@
1
+ import { MessageData } from "../../src/types/message/MessageData";
2
+ import ChatProcessor from "./chatProcessor";
3
+ declare class ChatCommand {
4
+ chatProcessor: ChatProcessor;
5
+ filterList: any[];
6
+ constructor(chatProcessor: ChatProcessor, filterList: any[]);
7
+ process(msg: MessageData): void;
8
+ }
9
+ export default ChatCommand;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class ChatCommand {
4
+ constructor(chatProcessor, filterList) {
5
+ this.chatProcessor = chatProcessor;
6
+ this.filterList = filterList;
7
+ }
8
+ process(msg) {
9
+ if (msg.type == "text" && !msg.block) {
10
+ let text = msg.info.text;
11
+ let filterList = this.filterList;
12
+ for (let g = 0; g < filterList.length; g++) {
13
+ let rule = filterList[g];
14
+ if (rule.pattern.test(text)) {
15
+ let command = {
16
+ platform: msg.platform,
17
+ type: "command",
18
+ command: rule.command,
19
+ timestamp: msg.local_timestamp,
20
+ info: {
21
+ type: "text",
22
+ user: msg.info.user,
23
+ },
24
+ data: {},
25
+ };
26
+ if (rule.callback) {
27
+ rule.callback(msg, command, rule.pattern);
28
+ }
29
+ msg.command = {
30
+ command: command.command,
31
+ data: command.data
32
+ };
33
+ this.chatProcessor.emit("command", command);
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ exports.default = ChatCommand;
@@ -0,0 +1,9 @@
1
+ import { MessageData } from "../../src/types/message/MessageData";
2
+ import ChatProcessor from "./ChatProcessor";
3
+ declare class ChatFilter {
4
+ chatProcessor: ChatProcessor;
5
+ filterList: any[];
6
+ constructor(chatProcessor: ChatProcessor, filterList: any[]);
7
+ process(msg: MessageData): void;
8
+ }
9
+ export default ChatFilter;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class ChatFilter {
4
+ constructor(chatProcessor, filterList) {
5
+ this.chatProcessor = chatProcessor;
6
+ this.filterList = filterList;
7
+ }
8
+ process(msg) {
9
+ if (msg.type == "text" && msg.info.text) {
10
+ let text = msg.info.text;
11
+ let filterList = this.filterList;
12
+ fgroup: for (let g = 0; g < filterList.length; g++) {
13
+ let group = filterList[g];
14
+ if (group.open) {
15
+ for (let i = 0; i < group.keyword.length; i++) {
16
+ if (text.includes(group.keyword[i])) {
17
+ let keyword = group.keyword[i];
18
+ msg.block = {
19
+ type: group.type,
20
+ name: group.name,
21
+ keyword: keyword,
22
+ mode: group.mode,
23
+ };
24
+ switch (group.mode) {
25
+ case "hide": {
26
+ msg.block.reason = group.reason;
27
+ break;
28
+ }
29
+ case "replace": {
30
+ msg.block.reason = group.reason;
31
+ msg.block.replace = group.replace;
32
+ break;
33
+ }
34
+ }
35
+ this.chatProcessor.emit("filter", msg);
36
+ break fgroup;
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ exports.default = ChatFilter;
@@ -0,0 +1,12 @@
1
+ /// <reference types="node" />
2
+ import ChatFilter from "./ChatFilter";
3
+ import ChatCommand from "./ChatCommand";
4
+ import { EventEmitter } from "events";
5
+ import { MessageData } from "../../src/types/message/MessageData";
6
+ declare class ChatProcessor extends EventEmitter {
7
+ filter: ChatFilter;
8
+ command: ChatCommand;
9
+ constructor();
10
+ process(msg: MessageData): void;
11
+ }
12
+ export default ChatProcessor;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ChatFilter_1 = __importDefault(require("./ChatFilter"));
7
+ const ChatCommand_1 = __importDefault(require("./ChatCommand"));
8
+ const events_1 = require("events");
9
+ let commandList = [];
10
+ let filterList = [];
11
+ class ChatProcessor extends events_1.EventEmitter {
12
+ constructor() {
13
+ super();
14
+ this.filter = new ChatFilter_1.default(this, filterList);
15
+ this.command = new ChatCommand_1.default(this, commandList);
16
+ }
17
+ process(msg) {
18
+ if (this.filter)
19
+ this.filter.process(msg);
20
+ if (this.command)
21
+ this.command.process(msg);
22
+ }
23
+ }
24
+ exports.default = ChatProcessor;
@@ -0,0 +1,21 @@
1
+ import FloatingLiving from "../..";
2
+ import { UserInfo } from "../../src/types/message/AttributeInfo";
3
+ import { MessageType } from "../../src/types/message/MessageData";
4
+ declare class chatPrint {
5
+ /** 主模块 */
6
+ main: FloatingLiving;
7
+ hideType: Set<string>;
8
+ constructor(main: FloatingLiving);
9
+ /** 获取用户信息 */
10
+ getUserInfo(message: {
11
+ platform: string;
12
+ info: {
13
+ user: UserInfo;
14
+ };
15
+ }): string;
16
+ /** 获取特权粉丝名称 */
17
+ getPriviliegeName(platform: string, level: number | boolean): string | number | boolean;
18
+ /** 记录在控制台上 */
19
+ log(message: MessageType): void;
20
+ }
21
+ export default chatPrint;