@floating-live/bilibili 0.15.2 → 0.16.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.
package/parser.ts DELETED
@@ -1,433 +0,0 @@
1
- import { UserType, ImageSize, RoomStatus } from "floating-live/enums";
2
- import { ImageInfo, Message, RoomInfo } from "floating-live/types";
3
- import { generateId } from "floating-live/utils";
4
- import { BilibiliRoomInfo, RawInfo, RawMessage } from "./types";
5
- type ParsingFunction<T extends RawMessage.All> = {
6
- [K in T["cmd"]]: (msg: any, room?: RoomInfo) => Message.All | undefined;
7
- };
8
-
9
- // utils
10
-
11
- // 获取当前时间戳,以替代无法从数据中获取时间戳的情况,精度为1s
12
- function getDateTimestamp() {
13
- return Math.floor(Date.now() / 1000) * 1000;
14
- }
15
-
16
- const parsingFunction: ParsingFunction<RawMessage.All> = {
17
- DANMU_MSG: (msg: RawMessage.DANMU_MSG, room) => {
18
- const { info, msg_id } = msg;
19
- let content = info[1];
20
- let mode = info[0][1];
21
- let color = info[0][3];
22
- let uname = info[2][1];
23
- let uid = info[2][0];
24
- let timestamp = info[0][4];
25
- let guard_level = info[7]; // 舰长级别
26
- let extra = JSON.parse(info[0][15].extra);
27
- let medal =
28
- info[3][0] != null
29
- ? {
30
- level: info[3][0],
31
- name: info[3][1],
32
- // user: info[3][2],
33
- id: info[3][12],
34
- membership: info[3][10] || 0,
35
- }
36
- : null;
37
- let identity: null | UserType = 0;
38
- let emoticon: { [key: string]: ImageInfo } | undefined = undefined;
39
- if (extra.emots) {
40
- emoticon = {};
41
- for (let key in extra.emots) {
42
- let emotItem = extra.emots[key];
43
- emoticon[key] = {
44
- id: emotItem.emoticon_unique,
45
- url: emotItem.url,
46
- name: emotItem.emoji,
47
- };
48
- }
49
- }
50
- if (info[2][2]) {
51
- identity = UserType.admin;
52
- } else if (uid === room?.anchor.id) {
53
- identity = UserType.anchor;
54
- }
55
- let danmaku: Message.Comment = {
56
- platform: "bilibili",
57
- room: room?.id || 0,
58
- type: "comment",
59
- timestamp: timestamp,
60
- id: msg_id!,
61
- info: {
62
- color: color,
63
- mode: mode,
64
- content: content,
65
- image: info[0][12]
66
- ? {
67
- name: content,
68
- id: info[0][13].emoticon_unique,
69
- url: info[0][13].url,
70
- size:
71
- info[0][13].width == info[0][13].height
72
- ? ImageSize.large
73
- : ImageSize.small,
74
- }
75
- : undefined,
76
- emoticon: emoticon,
77
- user: {
78
- name: uname,
79
- id: uid,
80
- medal: medal,
81
- membership: guard_level,
82
- type: identity,
83
- },
84
- },
85
- };
86
- danmaku.id ??= generateId(danmaku);
87
- return danmaku;
88
- },
89
- INTERACT_WORD: (msg: RawMessage.INTERACT_WORD, room) => {
90
- const { data, msg_id, send_time } = msg;
91
- let type: "entry" | "follow" | "share";
92
- switch (data.msg_type) {
93
- case 1:
94
- type = "entry"; // 进入直播间
95
- break;
96
- case 2:
97
- type = "follow"; // 关注直播间
98
- break;
99
- case 3:
100
- type = "share"; // 分享直播间
101
- break;
102
- default:
103
- return;
104
- }
105
- let interact: Message.Interact = {
106
- platform: "bilibili",
107
- room: room?.id || 0,
108
- type: type,
109
- id: msg_id!,
110
- timestamp: send_time || Math.floor(data.trigger_time / 1000000),
111
- info: {
112
- user: {
113
- name: data.uname,
114
- id: data.uid,
115
- medal: data.fans_medal?.medal_level
116
- ? {
117
- level: data.fans_medal.medal_level,
118
- name: data.fans_medal.medal_name,
119
- id: data.fans_medal.target_id,
120
- membership: data.fans_medal.guard_level,
121
- }
122
- : null,
123
- },
124
- },
125
- };
126
- interact.id ??= generateId(interact);
127
- return interact;
128
- },
129
- SEND_GIFT: (msg: RawMessage.SEND_GIFT, room) => {
130
- const { data, msg_id, send_time } = msg;
131
- let gift: Message.Gift = {
132
- platform: "bilibili",
133
- room: room?.id || 0,
134
- type: "gift",
135
- id: msg_id || data.combo_id,
136
- timestamp: send_time || data.timestamp * 1000,
137
- info: {
138
- user: {
139
- name: data.uname,
140
- id: data.uid,
141
- medal:
142
- data.fans_medal && data.fans_medal.medal_level
143
- ? {
144
- level: data.fans_medal.medal_level,
145
- name: data.fans_medal.medal_name,
146
- id: data.fans_medal.target_id,
147
- membership: data.fans_medal.guard_level,
148
- }
149
- : null,
150
- membership: data.guard_level,
151
- avatar: data.face,
152
- },
153
- gift: {
154
- name: data.giftName,
155
- id: data.giftId,
156
- num: data.num,
157
- value: data.total_coin,
158
- currency: data.coin_type,
159
- action: data.action,
160
- comboId: data.batch_combo_id,
161
- },
162
- },
163
- };
164
- gift.id ??= generateId(gift);
165
- return gift;
166
- },
167
- GUARD_BUY: (msg: RawMessage.GUARD_BUY, room) => {
168
- const { data, msg_id, send_time } = msg;
169
- let gift: Message.Membership = {
170
- platform: "bilibili",
171
- room: room?.id || 0,
172
- type: "membership",
173
- id: msg_id!,
174
- timestamp: send_time || data.start_time * 1000,
175
- info: {
176
- user: {
177
- name: data.username,
178
- id: data.uid,
179
- membership: data.guard_level,
180
- },
181
- gift: {
182
- name: data.gift_name,
183
- id: data.gift_id,
184
- num: data.num,
185
- value: data.price,
186
- currency: "gold",
187
- },
188
- name: data.gift_name,
189
- level: data.guard_level,
190
- duration: data.num * 30,
191
- },
192
- };
193
- gift.id ??= generateId(gift);
194
- return gift;
195
- },
196
- SUPER_CHAT_MESSAGE: (msg: RawMessage.SUPER_CHAT_MESSAGE, room) => {
197
- const { data, msg_id, send_time } = msg;
198
- let sc: Message.Superchat = {
199
- platform: "bilibili",
200
- room: room?.id || 0,
201
- type: "superchat",
202
- id: msg_id!,
203
- timestamp: send_time || data.ts * 1000,
204
- info: {
205
- id: data.id,
206
- user: {
207
- name: data.user_info.uname,
208
- id: data.uid,
209
- avatar: data.user_info.face,
210
- medal:
211
- data.medal_info && data.medal_info.medal_level
212
- ? {
213
- level: data.medal_info.medal_level,
214
- name: data.medal_info.medal_name,
215
- id: data.medal_info.target_id,
216
- membership: data.medal_info.guard_level,
217
- }
218
- : null,
219
- membership: data.user_info.guard_level,
220
- },
221
- content: data.message, // 文字
222
- color: data.background_bottom_color, // 颜色
223
- duration: data.time * 1000, // 持续时间(ms)
224
- gift: {
225
- id: data.gift.gift_id,
226
- name: data.gift.gift_name,
227
- num: data.gift.num,
228
- value: data.price * 1000, // 花费
229
- currency: "gold",
230
- },
231
- },
232
- };
233
- sc.id ??= generateId(sc);
234
- return sc;
235
- },
236
- WATCHED_CHANGE: (msg: RawMessage.WATCHED_CHANGE, room) => {
237
- const { data, msg_id, send_time } = msg;
238
- const stats: Message.LiveStats = {
239
- platform: "bilibili",
240
- room: room?.id || 0,
241
- type: "live_stats",
242
- id: msg_id!,
243
- timestamp: send_time || getDateTimestamp(),
244
- info: {
245
- view: data.num,
246
- },
247
- };
248
- stats.id ??= generateId(stats);
249
- return stats;
250
- },
251
- LIKE_INFO_V3_UPDATE: (msg: RawMessage.LIKE_INFO_V3_UPDATE, room) => {
252
- const { data, msg_id, send_time } = msg;
253
- const stats: Message.LiveStats = {
254
- platform: "bilibili",
255
- room: room?.id || 0,
256
- type: "live_stats",
257
- id: msg_id!,
258
- timestamp: send_time || getDateTimestamp(),
259
- info: {
260
- like: data.click_count,
261
- },
262
- };
263
- stats.id ??= generateId(stats);
264
- return stats;
265
- },
266
- ONLINE_RANK_COUNT: (msg: RawMessage.ONLINE_RANK_COUNT, room) => {
267
- const { data, msg_id, send_time } = msg;
268
- if (data.online_count == null) return;
269
- const stats: Message.LiveStats = {
270
- platform: "bilibili",
271
- room: room?.id || 0,
272
- type: "live_stats",
273
- id: msg_id!,
274
- timestamp: send_time || getDateTimestamp(),
275
- info: {
276
- online: data.online_count,
277
- },
278
- };
279
- stats.id ??= generateId(stats);
280
- return stats;
281
- },
282
- ROOM_BLOCK_MSG: (msg: RawMessage.ROOM_BLOCK_MSG, room) => {
283
- const { data, msg_id, send_time } = msg;
284
- const block: Message.Block = {
285
- platform: "bilibili",
286
- room: room?.id || 0,
287
- type: "block",
288
- id: msg_id!,
289
- timestamp: send_time || getDateTimestamp(),
290
- info: {
291
- user: {
292
- id: data.uid,
293
- name: data.uname,
294
- },
295
- operator: {
296
- type: data.operator == 2 ? UserType.anchor : UserType.admin,
297
- },
298
- },
299
- };
300
- block.id ??= generateId(block);
301
- return block;
302
- },
303
- LIVE: (msg: RawMessage.LIVE, room) => {
304
- const { msg_id, send_time } = msg;
305
- // 直播间开播
306
- if (msg.live_time) {
307
- let live: Message.LiveStart = {
308
- platform: "bilibili",
309
- room: room?.id || 0,
310
- type: "live_start",
311
- id: msg_id!,
312
- timestamp: send_time || msg.live_time * 1000,
313
- info: {
314
- id: msg.live_key.toString(),
315
- },
316
- };
317
- live.id ??= generateId(live);
318
- return live;
319
- }
320
- },
321
- CUT_OFF: (msg: RawMessage.CUT_OFF, room) => {
322
- const { msg_id, send_time } = msg;
323
- // 直播间被切断
324
- let cut: Message.LiveCut = {
325
- platform: "bilibili",
326
- room: room?.id || 0,
327
- type: "live_cut",
328
- id: msg_id!,
329
- timestamp: send_time || getDateTimestamp(),
330
- info: {
331
- message: msg.msg,
332
- },
333
- };
334
- cut.id ??= generateId(cut);
335
- return cut;
336
- },
337
- PREPARING: (msg: RawMessage.PREPARING, room) => {
338
- const { msg_id, send_time } = msg;
339
- let off: Message.LiveEnd = {
340
- platform: "bilibili",
341
- room: room?.id || 0,
342
- type: "live_end",
343
- id: msg_id!,
344
- timestamp: send_time || getDateTimestamp(),
345
- info: {
346
- status: msg.round ? RoomStatus.round : RoomStatus.off,
347
- },
348
- };
349
- off.id ??= generateId(off);
350
- return off;
351
- },
352
- ROOM_CHANGE: (msg: RawMessage.ROOM_CHANGE, room) => {
353
- const { data, msg_id, send_time } = msg;
354
- let change: Message.LiveDetail = {
355
- platform: "bilibili",
356
- room: room?.id || 0,
357
- type: "live_detail",
358
- id: msg_id!,
359
- timestamp: send_time || getDateTimestamp(),
360
- info: {
361
- title: data.title,
362
- area: [data.parent_area_name, data.area_name],
363
- },
364
- };
365
- change.id ??= generateId(change);
366
- return change;
367
- },
368
- ANCHOR_LOT_START: (msg: RawMessage.ANCHOR_LOT_START, room) => {
369
- const { data, msg_id, send_time } = msg;
370
- let m: Message.Lottery = {
371
- platform: "bilibili",
372
- room: room?.id || 0,
373
- type: "lottery",
374
- timestamp: send_time || data.current_time * 1000,
375
- id: msg_id!,
376
- info: {
377
- id: data.id,
378
- award: {
379
- name: data.award_name,
380
- num: data.award_num,
381
- image: data.award_image,
382
- id: -1,
383
- value: 0,
384
- currency: "",
385
- },
386
- },
387
- };
388
- return m;
389
- },
390
- };
391
-
392
- /** 转换bilibili直播弹幕为floating通用格式 */
393
- export function parseMessage(
394
- data: RawMessage.All,
395
- room?: BilibiliRoomInfo
396
- ): Message.All | undefined {
397
- return parsingFunction[data.cmd]?.(data, room);
398
- }
399
-
400
- /** 转换bilibili直播间信息为floating通用格式 */
401
- export function parseInfo(data: RawInfo): BilibiliRoomInfo {
402
- const { room_info, anchor_info, like_info_v3, watched_show }: RawInfo = data;
403
- return {
404
- platform: "bilibili",
405
- id: room_info.room_id,
406
- roomId: room_info.room_id,
407
- shortId: room_info.short_id,
408
- key: `bilibili:${room_info.room_id}`,
409
- detail: {
410
- title: room_info.title,
411
- area: [room_info.parent_area_name, room_info.area_name],
412
- cover: room_info.cover,
413
- },
414
- anchor: {
415
- id: room_info.uid,
416
- name: anchor_info.base_info.uname,
417
- avatar: anchor_info.base_info.face,
418
- },
419
- stats: {
420
- view: watched_show.num,
421
- like: like_info_v3.total_likes,
422
- },
423
- liveId: room_info.live_id_str,
424
- available: room_info.lock_status ? false : true,
425
- status: room_info.lock_status ? RoomStatus.banned : room_info.live_status,
426
- timestamp:
427
- room_info.live_status == RoomStatus.live
428
- ? room_info.live_start_time * 1000
429
- : 0,
430
- opened: false,
431
- connection: 0,
432
- };
433
- }
package/plugin.ts DELETED
@@ -1,103 +0,0 @@
1
- import type { FloatingLive, PlatformInfo } from "floating-live";
2
- import { RoomBilibili, RoomOptions } from "./room";
3
- import {
4
- checkLoginQRcode,
5
- generateLoginQRcode,
6
- getBuvid,
7
- getInfoByRoom,
8
- getLoginUid,
9
- } from "./utils";
10
- import { parseInfo } from "./parser";
11
-
12
- interface BilibiliLoginInfo {
13
- credentials: string;
14
- tokens: {
15
- /** 用户uid */
16
- userId: number;
17
- /** buvid */
18
- buvid: string;
19
- };
20
- userId: number;
21
- }
22
-
23
- declare module "floating-live" {
24
- interface FloatingCommandMap {
25
- "bilibili.credentials.check": (
26
- credentials: string
27
- ) => Promise<BilibiliLoginInfo>;
28
- "bilibili.login.qrcode.get": () => Promise<{ key: string; url: string }>;
29
- "bilibili.login.qrcode.poll": (
30
- key: string
31
- ) => Promise<{ status: number; credentials?: string }>;
32
- }
33
- }
34
-
35
- const platformInfo: PlatformInfo = {
36
- name: "bilibili",
37
- membership: {
38
- id: "guard",
39
- name: "大航海",
40
- level: ["", "总督", "提督", "舰长"],
41
- },
42
- gift: {
43
- action: "投喂",
44
- },
45
- currency: {
46
- silver: {
47
- name: "银瓜子",
48
- ratio: 1,
49
- },
50
- gold: {
51
- name: "电池",
52
- ratio: 100,
53
- money: 1000,
54
- },
55
- },
56
- stats: {
57
- view: "看过",
58
- online: "在线",
59
- like: "点赞",
60
- },
61
- };
62
-
63
- export class PluginBilibili {
64
- static pluginName = "bilibili";
65
- constructor(main: FloatingLive) {
66
- main.command.register(
67
- "bilibili.room.create",
68
- (id: string | number, options?: RoomOptions) => {
69
- return new RoomBilibili(Number(id), options);
70
- }
71
- );
72
- main.command.register("bilibili.room.info", async (id: string | number) => {
73
- const rawInfo = await getInfoByRoom(parseInt("" + id));
74
- return parseInfo(rawInfo);
75
- });
76
-
77
- main.command.register("bilibili.credentials.check", async (credentials) => {
78
- const buvid = (await getBuvid(credentials)) || "";
79
- const userId = await getLoginUid(credentials);
80
- return {
81
- credentials,
82
- tokens: {
83
- userId,
84
- buvid,
85
- },
86
- userId,
87
- };
88
- });
89
-
90
- main.manifest.register("platform", "bilibili", platformInfo);
91
-
92
- main.command.register("bilibili.login.qrcode.get", () => {
93
- return generateLoginQRcode();
94
- });
95
-
96
- main.command.register("bilibili.login.qrcode.poll", async (key) => {
97
- const [status, credentials] = await checkLoginQRcode(key);
98
- return { status, credentials };
99
- });
100
- }
101
- }
102
-
103
- export default PluginBilibili;