floating-live 0.11.2 → 0.12.1

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/index.d.ts CHANGED
@@ -3,3 +3,4 @@ export * from "./src/types";
3
3
  export * from "./src/enum";
4
4
  export * from "./src/lib/LiveRoom";
5
5
  export * from "./src/lib/Reglist";
6
+ export * from "./src/utils";
package/index.js CHANGED
@@ -21,3 +21,4 @@ __exportStar(require("./src/types"), exports);
21
21
  __exportStar(require("./src/enum"), exports);
22
22
  __exportStar(require("./src/lib/LiveRoom"), exports);
23
23
  __exportStar(require("./src/lib/Reglist"), exports);
24
+ __exportStar(require("./src/utils"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "floating-live",
3
- "version": "0.11.2",
3
+ "version": "0.12.1",
4
4
  "type": "commonjs",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "dependencies": {
18
18
  "acfun-live-danmaku": "^0.6.1",
19
19
  "axios": "^1.4.0",
20
- "bilibili-live-ws": "^6.0.3",
20
+ "bilibili-live-ws": "^6.3.1",
21
21
  "fs-extra": "^11.1.0"
22
22
  },
23
23
  "devDependencies": {
@@ -1,6 +1,7 @@
1
+ import { RoomDetail } from "./../../src/lib/LiveRoom";
1
2
  import { MedalInfo, UserInfo } from "../..";
2
3
  import AcClient from "acfun-live-danmaku/client";
3
- import { LiveRoom, RoomStatsInfo, RoomViewInfo } from "../..";
4
+ import { LiveRoom, RoomStatsInfo } from "../..";
4
5
  declare type ZtLiveUserInfo = {
5
6
  userIdentity: {
6
7
  managerType?: number;
@@ -20,7 +21,7 @@ declare class acfunLive extends LiveRoom {
20
21
  /** 房间id */
21
22
  readonly id: number;
22
23
  /** 直播展示信息 */
23
- view: RoomViewInfo;
24
+ detail: RoomDetail;
24
25
  /** 直播数据信息 */
25
26
  stats: RoomStatsInfo;
26
27
  /** 主播信息 */
@@ -24,7 +24,7 @@ class acfunLive extends __1.LiveRoom {
24
24
  /** 平台id */
25
25
  this.platform = "acfun";
26
26
  /** 直播展示信息 */
27
- this.view = {
27
+ this.detail = {
28
28
  /** 直播标题 */
29
29
  title: "",
30
30
  /** 分区 */
@@ -60,18 +60,17 @@ class acfunLive extends __1.LiveRoom {
60
60
  get available() {
61
61
  return Boolean(this.client);
62
62
  }
63
- ;
64
63
  async getInfo() {
65
64
  if (!this.client) {
66
- this.client = await (0, acfun_live_danmaku_1.default)(this.id) || null;
65
+ this.client = (await (0, acfun_live_danmaku_1.default)(this.id)) || null;
67
66
  if (this.client) {
68
67
  this.status = __2.RoomStatus.live;
69
68
  this.timestamp = this.client.liveStartTime;
70
- this.view.title = this.client.caption; // bug
71
- this.view.cover = `https://tx2.a.kwimgs.com/bs2/ztlc/cover_${this.client.liveId}_raw.jpg`;
69
+ this.detail.title = this.client.caption; // bug
70
+ this.detail.cover = `https://tx2.a.kwimgs.com/bs2/ztlc/cover_${this.client.liveId}_raw.jpg`;
72
71
  }
73
72
  await fetch(`https://live.acfun.cn/rest/pc-direct/user/userInfo?userId=${this.id}`, {
74
- method: "GET"
73
+ method: "GET",
75
74
  })
76
75
  .then((response) => response.json())
77
76
  .then((res) => {
@@ -114,13 +113,26 @@ class acfunLive extends __1.LiveRoom {
114
113
  //收到的弹幕
115
114
  this.msg_Comment(danmaku);
116
115
  });
117
- client.on("Gift", (gift) => { this.msg_Gift(gift); });
118
- client.on("UserEnterRoom", (entry) => { this.msg_Interact(entry, "entry"); });
119
- client.on("Like", (like) => { this.msg_Interact(like, "like"); });
120
- // client.on("JoinClub", (join: any) => { this.msg_Interact(join, "join"); });
121
- client.on("DisplayInfo", (info) => { this.msg_DisplayInfo(info); });
122
- client.on("LiveClosed", (end) => { this.msg_LiveClosed(); });
123
- client.on("LiveBanned", (end) => { this.msg_LiveBanned(); });
116
+ client.on("Gift", (msg) => {
117
+ this.msg_Gift(msg);
118
+ });
119
+ client.on("UserEnterRoom", (msg) => {
120
+ this.msg_Interact(msg, "entry");
121
+ });
122
+ client.on("Like", (msg) => {
123
+ this.msg_Interact(msg, "like");
124
+ });
125
+ // client.on("UserFollowAuthor", (join: any) => { this.msg_Interact(msg, "follow"); });
126
+ // client.on("JoinClub", (msg: any) => { this.msg_Interact(msg, "join"); });
127
+ client.on("DisplayInfo", (msg) => {
128
+ this.msg_DisplayInfo(msg);
129
+ });
130
+ client.on("LiveClosed", (msg) => {
131
+ this.msg_LiveClosed();
132
+ });
133
+ client.on("LiveBanned", (msg) => {
134
+ this.msg_LiveBanned();
135
+ });
124
136
  this.wsInit = true;
125
137
  }
126
138
  /** 关闭直播间监听 */
@@ -135,7 +147,6 @@ class acfunLive extends __1.LiveRoom {
135
147
  this.close();
136
148
  this.removeAllListeners();
137
149
  }
138
- ;
139
150
  /** 根据守护徽章字符串获取粉丝牌信息 */
140
151
  getMedal(badge) {
141
152
  if (badge) {
@@ -151,44 +162,48 @@ class acfunLive extends __1.LiveRoom {
151
162
  }
152
163
  }
153
164
  getUser(user) {
154
- let identity = null;
165
+ let identity = 0;
155
166
  if (user.userIdentity?.managerType == 1) {
156
- identity = __2.UserAdmin.admin;
167
+ identity = __2.UserType.admin;
157
168
  }
158
169
  else if (parseInt(user.userId) == this.anchor.id) {
159
- identity = __2.UserAdmin.anchor;
170
+ identity = __2.UserType.anchor;
160
171
  }
161
172
  return {
162
173
  name: user.nickname,
163
174
  id: parseInt(user.userId),
164
175
  medal: this.getMedal(user.badge),
165
176
  avatar: user.avatar[0].url,
166
- admin: identity
177
+ type: identity,
167
178
  };
168
179
  }
169
180
  /** 文本信息(Comment) */
170
181
  msg_Comment(data) {
171
- let danmaku = {
182
+ const userInfo = this.getUser(data.userInfo);
183
+ let m = {
172
184
  platform: "acfun",
173
185
  room: this.id,
186
+ id: `${userInfo.id}-${data.sendTimeMs}`,
174
187
  timestamp: parseInt(data.sendTimeMs),
175
188
  type: "chat",
176
189
  info: {
177
190
  content: data.content,
178
- user: this.getUser(data.userInfo),
191
+ user: userInfo,
179
192
  },
180
193
  };
181
- this.emitMsg(danmaku);
194
+ this.emitMsg(m);
182
195
  }
183
196
  /** 礼物信息(Gift) */
184
197
  msg_Gift(data) {
185
- let gift = {
198
+ const userInfo = this.getUser(data.user);
199
+ let m = {
186
200
  platform: "acfun",
187
201
  room: this.id,
188
202
  type: "gift",
203
+ id: `${userInfo.id}-${data.sendTimeMs}`,
189
204
  timestamp: parseInt(data.sendTimeMs),
190
205
  info: {
191
- user: this.getUser(data.user),
206
+ user: userInfo,
192
207
  gift: {
193
208
  name: data.giftName,
194
209
  id: parseInt(data.giftId),
@@ -198,59 +213,67 @@ class acfunLive extends __1.LiveRoom {
198
213
  },
199
214
  },
200
215
  };
201
- this.emitMsg(gift);
216
+ this.emitMsg(m);
202
217
  }
203
218
  /** 互动信息 */
204
219
  msg_Interact(data, type) {
205
- let like = {
220
+ const userInfo = this.getUser(data.userInfo);
221
+ let m = {
206
222
  platform: "acfun",
207
223
  room: this.id,
208
224
  type: type,
225
+ id: `${userInfo.id}-${data.sendTimeMs}`,
209
226
  timestamp: parseInt(data.sendTimeMs),
210
227
  info: {
211
- user: this.getUser(data.userInfo),
228
+ user: userInfo,
212
229
  },
213
230
  };
214
- this.emitMsg(like);
231
+ this.emitMsg(m);
215
232
  }
216
233
  msg_LiveClosed() {
217
- let off = {
234
+ const timestamp = getDateTimestamp();
235
+ let m = {
218
236
  platform: "acfun",
219
237
  room: this.id,
220
238
  type: "live_end",
221
- timestamp: getDateTimestamp(),
239
+ id: `${timestamp}`,
240
+ timestamp: timestamp,
222
241
  info: {
223
- status: __2.RoomStatus.off
224
- }
242
+ status: __2.RoomStatus.off,
243
+ },
225
244
  };
226
245
  this.client = null;
227
- this.emitMsg(off);
246
+ this.emitMsg(m);
228
247
  }
229
248
  msg_LiveBanned() {
230
- let cut = {
249
+ const timestamp = getDateTimestamp();
250
+ let m = {
231
251
  platform: "acfun",
232
252
  room: this.id,
233
253
  type: "live_cut",
234
- timestamp: getDateTimestamp(),
254
+ id: `${timestamp}`,
255
+ timestamp: timestamp,
235
256
  info: {
236
- message: ""
237
- }
257
+ message: "",
258
+ },
238
259
  };
239
260
  this.client = null;
240
- this.emitMsg(cut);
261
+ this.emitMsg(m);
241
262
  }
242
263
  msg_DisplayInfo(data) {
243
- let stats = {
264
+ const timestamp = getDateTimestamp();
265
+ let m = {
244
266
  platform: "acfun",
245
267
  room: this.id,
246
268
  type: "live_stats",
247
- timestamp: getDateTimestamp(),
269
+ id: `${timestamp}`,
270
+ timestamp: timestamp,
248
271
  info: {
249
272
  like: stringToNumber(data.likeCount),
250
273
  online: stringToNumber(data.watchingCount),
251
- }
274
+ },
252
275
  };
253
- this.emitMsg(stats);
276
+ this.emitMsg(m);
254
277
  }
255
278
  }
256
279
  exports.default = acfunLive;
@@ -1,6 +1,6 @@
1
1
  import { UserInfo } from "../..";
2
2
  import { KeepLiveWS } from "bilibili-live-ws";
3
- import { LiveRoom, RoomStatsInfo, RoomViewInfo } from "../..";
3
+ import { LiveRoom, RoomStatsInfo, RoomDetail } from "../..";
4
4
  declare class bilibiliLive extends LiveRoom {
5
5
  /** 平台id */
6
6
  readonly platform: string;
@@ -8,8 +8,8 @@ declare class bilibiliLive extends LiveRoom {
8
8
  readonly id: number;
9
9
  /** 直播间room_id */
10
10
  roomid: number;
11
- /** 展示信息 */
12
- view: RoomViewInfo;
11
+ /** 房间信息 */
12
+ detail: RoomDetail;
13
13
  stats: RoomStatsInfo;
14
14
  /** 房间是否可用 */
15
15
  available: boolean;
@@ -27,7 +27,7 @@ declare class bilibiliLive extends LiveRoom {
27
27
  connectInterval: number;
28
28
  });
29
29
  /** 获取房间信息 */
30
- getInfo(refresh?: boolean): Promise<void>;
30
+ getInfo(): Promise<void>;
31
31
  /** 开启直播间监听 */
32
32
  open(): Promise<void>;
33
33
  /** 连接直播服务端 */
@@ -48,6 +48,7 @@ declare class bilibiliLive extends LiveRoom {
48
48
  msg_WATCHED_CHANGE(msg: any): void;
49
49
  /** 点赞数变化 */
50
50
  msg_LIKE_INFO_V3_UPDATE(msg: any): void;
51
+ msg_ONLINE_RANK_COUNT(msg: any): void;
51
52
  msg_ROOM_BLOCK_MSG(msg: any): void;
52
53
  msg_LIVE(msg: any): void;
53
54
  msg_CUT_OFF(msg: any): void;
@@ -8,6 +8,16 @@ const __2 = require("../..");
8
8
  function getDateTimestamp() {
9
9
  return Math.floor(Date.now() / 1000) * 1000;
10
10
  }
11
+ function getRoomStatus(s) {
12
+ switch (s) {
13
+ case 1:
14
+ return __1.RoomStatus.live;
15
+ case 2:
16
+ return __1.RoomStatus.round;
17
+ default:
18
+ return __1.RoomStatus.off;
19
+ }
20
+ }
11
21
  class bilibiliLive extends __2.LiveRoom {
12
22
  constructor(id, // 房间id
13
23
  open = false, // 生成房间后是否打开
@@ -17,8 +27,8 @@ class bilibiliLive extends __2.LiveRoom {
17
27
  this.platform = "bilibili";
18
28
  /** 直播间room_id */
19
29
  this.roomid = 0;
20
- /** 展示信息 */
21
- this.view = {
30
+ /** 房间信息 */
31
+ this.detail = {
22
32
  /** 直播标题 */
23
33
  title: "",
24
34
  /** 分区 */
@@ -50,19 +60,24 @@ class bilibiliLive extends __2.LiveRoom {
50
60
  }
51
61
  }
52
62
  /** 获取房间信息 */
53
- async getInfo(refresh) {
63
+ async getInfo() {
54
64
  await fetch(`https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=${this.id}`, {
55
- method: "GET"
65
+ method: "GET",
56
66
  }) // 获取直播间信息
57
67
  .then((response) => response.json())
58
68
  .then((res) => {
59
69
  const { room_info, anchor_info, like_info_v3, watched_show } = res.data;
60
70
  this.roomid = room_info.room_id;
61
- this.status = room_info.live_status == 1 ? __1.RoomStatus.live : __1.RoomStatus.off;
62
- this.timestamp = this.status == __1.RoomStatus.live ? room_info.live_start_time * 1000 : refresh ? Date.now() : this.timestamp;
63
- this.view.title = room_info.title;
64
- this.view.area = [room_info.parent_area_name, room_info.area_name];
65
- this.view.cover = room_info.cover;
71
+ this.status = room_info.lock_status
72
+ ? __1.RoomStatus.banned
73
+ : getRoomStatus(room_info.live_status);
74
+ this.timestamp =
75
+ this.status == __1.RoomStatus.live
76
+ ? room_info.live_start_time * 1000
77
+ : this.timestamp;
78
+ this.detail.title = room_info.title;
79
+ this.detail.area = [room_info.parent_area_name, room_info.area_name];
80
+ this.detail.cover = room_info.cover;
66
81
  this.stats.watch = watched_show.num;
67
82
  this.stats.like = like_info_v3.total_likes;
68
83
  this.anchor.id = room_info.uid;
@@ -82,7 +97,7 @@ class bilibiliLive extends __2.LiveRoom {
82
97
  // 如果直播间监听已打开,则返回
83
98
  if (this.opening)
84
99
  return;
85
- await this.getInfo(true);
100
+ await this.getInfo();
86
101
  // 如果直播间不可用,则返回
87
102
  if (!this.available)
88
103
  return;
@@ -94,7 +109,7 @@ class bilibiliLive extends __2.LiveRoom {
94
109
  async createWS() {
95
110
  // 与Websocket服务器连接
96
111
  console.log("[bilibili-live-ws] 开始连接bilibili直播服务器");
97
- this.client = new bilibili_live_ws_1.KeepLiveWS(this.roomid);
112
+ this.client = new bilibili_live_ws_1.KeepLiveWS(this.roomid, { uid: this.anchor.id });
98
113
  let client = this.client;
99
114
  client.interval = this.connectInterval;
100
115
  client.on("open", () => {
@@ -125,6 +140,7 @@ class bilibiliLive extends __2.LiveRoom {
125
140
  client.on("ROOM_CHANGE", this.msg_ROOM_CHANGE.bind(this));
126
141
  client.on("WATCHED_CHANGE", this.msg_WATCHED_CHANGE.bind(this));
127
142
  client.on("LIKE_INFO_V3_UPDATE", this.msg_LIKE_INFO_V3_UPDATE.bind(this));
143
+ client.on("ONLINE_RANK_COUNT", this.msg_ONLINE_RANK_COUNT.bind(this));
128
144
  }
129
145
  /** 关闭直播间监听 */
130
146
  close() {
@@ -136,22 +152,25 @@ class bilibiliLive extends __2.LiveRoom {
136
152
  }
137
153
  /** 获取弹幕消息 */
138
154
  msg_DANMU_MSG(msg) {
139
- let content = msg.info[1];
140
- let mode = msg.info[0][1];
141
- let color = msg.info[0][3];
142
- let uname = msg.info[2][1];
143
- let uid = msg.info[2][0];
144
- let timestamp = msg.info[0][4];
145
- let guard_level = msg.info[7]; // 舰长级别
146
- let extra = JSON.parse(msg.info[0][15].extra);
147
- let medal = (msg.info[3].length) ? {
148
- level: msg.info[3][0],
149
- name: msg.info[3][1],
150
- // user: msg.info[3][2],
151
- id: msg.info[3][12],
152
- membership: msg.info[3][10] || 0,
153
- } : null;
154
- let identity = null;
155
+ const { info, msg_id } = msg;
156
+ let content = info[1];
157
+ let mode = info[0][1];
158
+ let color = info[0][3];
159
+ let uname = info[2][1];
160
+ let uid = info[2][0];
161
+ let timestamp = info[0][4];
162
+ let guard_level = info[7]; // 舰长级别
163
+ let extra = JSON.parse(info[0][15].extra);
164
+ let medal = info[3].length
165
+ ? {
166
+ level: info[3][0],
167
+ name: info[3][1],
168
+ // user: info[3][2],
169
+ id: info[3][12],
170
+ membership: info[3][10] || 0,
171
+ }
172
+ : null;
173
+ let identity = 0;
155
174
  let emoticon = undefined;
156
175
  if (extra.emots) {
157
176
  emoticon = {};
@@ -164,42 +183,48 @@ class bilibiliLive extends __2.LiveRoom {
164
183
  };
165
184
  }
166
185
  }
167
- if (msg.info[2][2]) {
168
- identity = __1.UserAdmin.admin;
186
+ if (info[2][2]) {
187
+ identity = __1.UserType.admin;
169
188
  }
170
189
  else if (uid == this.anchor.id) {
171
- identity = __1.UserAdmin.anchor;
190
+ identity = __1.UserType.anchor;
172
191
  }
173
192
  let danmaku = {
174
193
  platform: "bilibili",
175
194
  room: this.id,
176
195
  type: "chat",
177
196
  timestamp: timestamp,
197
+ id: msg_id,
178
198
  info: {
179
199
  color: color,
180
200
  mode: mode,
181
201
  content: content,
182
- image: msg.info[0][12] ? {
183
- name: content,
184
- id: msg.info[0][13].emoticon_unique,
185
- url: msg.info[0][13].url,
186
- size: msg.info[0][13].width == msg.info[0][13].height ? __1.ImageSize.large : __1.ImageSize.small,
187
- } : undefined,
202
+ image: info[0][12]
203
+ ? {
204
+ name: content,
205
+ id: info[0][13].emoticon_unique,
206
+ url: info[0][13].url,
207
+ size: info[0][13].width == info[0][13].height
208
+ ? __1.ImageSize.large
209
+ : __1.ImageSize.small,
210
+ }
211
+ : undefined,
188
212
  emoticon: emoticon,
189
213
  user: {
190
214
  name: uname,
191
215
  id: uid,
192
216
  medal: medal,
193
217
  membership: guard_level,
194
- admin: identity,
195
- }
196
- }
218
+ type: identity,
219
+ },
220
+ },
197
221
  };
222
+ danmaku.id ?? (danmaku.id = (0, __1.generateId)(danmaku));
198
223
  this.emitMsg(danmaku);
199
224
  }
200
225
  /** 获取互动消息 */
201
226
  msg_INTERACT_WORD(msg) {
202
- const data = msg.data;
227
+ const { data, msg_id, send_time } = msg;
203
228
  let type;
204
229
  switch (data.msg_type) {
205
230
  case 1:
@@ -218,42 +243,49 @@ class bilibiliLive extends __2.LiveRoom {
218
243
  platform: "bilibili",
219
244
  room: this.id,
220
245
  type: type,
221
- timestamp: Math.floor(data.trigger_time / 1000000),
246
+ id: msg_id,
247
+ timestamp: send_time || Math.floor(data.trigger_time / 1000000),
222
248
  info: {
223
249
  user: {
224
250
  name: data.uname,
225
251
  id: data.uid,
226
- medal: (data.fans_medal?.medal_level) ? {
227
- level: data.fans_medal.medal_level,
228
- name: data.fans_medal.medal_name,
229
- id: data.fans_medal.target_id,
230
- membership: data.fans_medal.guard_level,
231
- } : null
232
- }
252
+ medal: data.fans_medal?.medal_level
253
+ ? {
254
+ level: data.fans_medal.medal_level,
255
+ name: data.fans_medal.medal_name,
256
+ id: data.fans_medal.target_id,
257
+ membership: data.fans_medal.guard_level,
258
+ }
259
+ : null,
260
+ },
233
261
  },
234
262
  };
263
+ interact.id ?? (interact.id = (0, __1.generateId)(interact));
235
264
  this.emitMsg(interact);
236
265
  }
237
266
  /** 获取礼物消息 */
238
267
  msg_SEND_GIFT(msg) {
239
- const data = msg.data;
268
+ const { data, msg_id, send_time } = msg;
240
269
  let gift = {
241
270
  platform: "bilibili",
242
271
  room: this.id,
243
272
  type: "gift",
244
- timestamp: data.timestamp * 1000,
273
+ id: msg_id || data.combo_id,
274
+ timestamp: send_time || data.timestamp * 1000,
245
275
  info: {
246
276
  user: {
247
277
  name: data.uname,
248
278
  id: data.uid,
249
- medal: (data.fans_medal && data.fans_medal.medal_level) ? {
250
- level: data.fans_medal.medal_level,
251
- name: data.fans_medal.medal_name,
252
- id: data.fans_medal.target_id,
253
- membership: data.fans_medal.guard_level,
254
- } : null,
279
+ medal: data.fans_medal && data.fans_medal.medal_level
280
+ ? {
281
+ level: data.fans_medal.medal_level,
282
+ name: data.fans_medal.medal_name,
283
+ id: data.fans_medal.target_id,
284
+ membership: data.fans_medal.guard_level,
285
+ }
286
+ : null,
255
287
  membership: data.guard_level,
256
- avatar: data.face
288
+ avatar: data.face,
257
289
  },
258
290
  gift: {
259
291
  name: data.giftName,
@@ -262,20 +294,22 @@ class bilibiliLive extends __2.LiveRoom {
262
294
  value: data.total_coin,
263
295
  currency: data.coin_type,
264
296
  action: data.action,
265
- combo_id: data.batch_combo_id,
266
- }
297
+ comboId: data.batch_combo_id,
298
+ },
267
299
  },
268
300
  };
301
+ gift.id ?? (gift.id = (0, __1.generateId)(gift));
269
302
  this.emitMsg(gift);
270
303
  }
271
304
  /** 获取舰长开通消息 */
272
305
  msg_GUARD_BUY(msg) {
273
- const data = msg.data;
306
+ const { data, msg_id, send_time } = msg;
274
307
  let gift = {
275
308
  platform: "bilibili",
276
309
  room: this.id,
277
310
  type: "membership",
278
- timestamp: data.start_time * 1000,
311
+ id: msg_id,
312
+ timestamp: send_time || data.start_time * 1000,
279
313
  info: {
280
314
  user: {
281
315
  name: data.username,
@@ -294,28 +328,32 @@ class bilibiliLive extends __2.LiveRoom {
294
328
  duration: data.num * 30,
295
329
  },
296
330
  };
331
+ gift.id ?? (gift.id = (0, __1.generateId)(gift));
297
332
  this.emitMsg(gift);
298
333
  }
299
334
  /** 获取醒目留言消息 */
300
335
  msg_SUPER_CHAT_MESSAGE(msg) {
301
- const data = msg.data;
336
+ const { data, msg_id, send_time } = msg;
302
337
  let sc = {
303
338
  platform: "bilibili",
304
339
  room: this.id,
305
340
  type: "superchat",
306
- timestamp: data.ts * 1000,
341
+ id: msg_id,
342
+ timestamp: send_time || data.ts * 1000,
307
343
  info: {
308
344
  id: data.id,
309
345
  user: {
310
346
  name: data.user_info.uname,
311
347
  id: data.uid,
312
348
  avatar: data.user_info.face,
313
- medal: (data.medal_info && data.medal_info.medal_level) ? {
314
- level: data.medal_info.medal_level,
315
- name: data.medal_info.medal_name,
316
- id: data.medal_info.target_id,
317
- membership: data.medal_info.guard_level,
318
- } : null,
349
+ medal: data.medal_info && data.medal_info.medal_level
350
+ ? {
351
+ level: data.medal_info.medal_level,
352
+ name: data.medal_info.medal_name,
353
+ id: data.medal_info.target_id,
354
+ membership: data.medal_info.guard_level,
355
+ }
356
+ : null,
319
357
  membership: data.user_info.guard_level,
320
358
  },
321
359
  content: data.message,
@@ -327,110 +365,145 @@ class bilibiliLive extends __2.LiveRoom {
327
365
  num: data.gift.num,
328
366
  value: data.price * 1000,
329
367
  currency: "gold",
330
- }
368
+ },
331
369
  },
332
370
  };
371
+ sc.id ?? (sc.id = (0, __1.generateId)(sc));
333
372
  this.emitMsg(sc);
334
373
  }
335
374
  /** 观看数变化 */
336
375
  msg_WATCHED_CHANGE(msg) {
337
- const data = msg.data;
376
+ const { data, msg_id, send_time } = msg;
338
377
  const stats = {
339
378
  platform: "bilibili",
340
379
  room: this.id,
341
380
  type: "live_stats",
342
- timestamp: getDateTimestamp(),
381
+ id: msg_id,
382
+ timestamp: send_time || getDateTimestamp(),
343
383
  info: {
344
- watch: data.num
384
+ watch: data.num,
345
385
  },
346
386
  };
387
+ stats.id ?? (stats.id = (0, __1.generateId)(stats));
347
388
  this.emitMsg(stats);
348
389
  }
349
390
  /** 点赞数变化 */
350
391
  msg_LIKE_INFO_V3_UPDATE(msg) {
351
- const data = msg.data;
392
+ const { data, msg_id, send_time } = msg;
352
393
  const stats = {
353
394
  platform: "bilibili",
354
395
  room: this.id,
355
396
  type: "live_stats",
356
- timestamp: getDateTimestamp(),
397
+ id: msg_id,
398
+ timestamp: send_time || getDateTimestamp(),
357
399
  info: {
358
- like: data.click_count
400
+ like: data.click_count,
359
401
  },
360
402
  };
403
+ stats.id ?? (stats.id = (0, __1.generateId)(stats));
361
404
  this.emitMsg(stats);
362
405
  }
406
+ msg_ONLINE_RANK_COUNT(msg) {
407
+ const { data, msg_id, send_time } = msg;
408
+ const stats = {
409
+ platform: "bilibili",
410
+ room: this.id,
411
+ type: "live_stats",
412
+ id: msg_id,
413
+ timestamp: send_time || getDateTimestamp(),
414
+ info: {
415
+ online: data.online_count,
416
+ },
417
+ };
418
+ stats.id ?? (stats.id = (0, __1.generateId)(stats));
419
+ if (data.online_count != null)
420
+ this.emitMsg(stats);
421
+ }
363
422
  msg_ROOM_BLOCK_MSG(msg) {
364
423
  // 禁言
365
- const data = msg.data;
424
+ const { data, msg_id, send_time } = msg;
366
425
  const block = {
367
426
  platform: "bilibili",
368
427
  room: this.id,
369
428
  type: "block",
370
- timestamp: getDateTimestamp(),
429
+ id: msg_id,
430
+ timestamp: send_time || getDateTimestamp(),
371
431
  info: {
372
432
  user: {
373
433
  id: data.uid,
374
- name: data.uname
434
+ name: data.uname,
375
435
  },
376
436
  operator: {
377
- admin: data.operator == 2 ? __1.UserAdmin.anchor : __1.UserAdmin.admin
378
- }
437
+ type: data.operator == 2 ? __1.UserType.anchor : __1.UserType.admin,
438
+ },
379
439
  },
380
440
  };
441
+ block.id ?? (block.id = (0, __1.generateId)(block));
381
442
  this.emitMsg(block);
382
443
  }
383
444
  msg_LIVE(msg) {
445
+ const { data, msg_id, send_time } = msg;
384
446
  // 直播间开播
385
447
  if (msg.live_time) {
386
448
  let live = {
387
449
  platform: "bilibili",
388
450
  room: this.id,
389
451
  type: "live_start",
390
- timestamp: msg.live_time * 1000,
452
+ id: msg_id,
453
+ timestamp: send_time || msg.live_time * 1000,
391
454
  info: {
392
455
  id: msg.live_key.toString(),
393
456
  },
394
457
  };
458
+ live.id ?? (live.id = (0, __1.generateId)(live));
395
459
  this.emitMsg(live);
396
460
  }
397
461
  }
398
462
  msg_CUT_OFF(msg) {
463
+ const { msg_id, send_time } = msg;
399
464
  // 直播间被切断
400
465
  let cut = {
401
466
  platform: "bilibili",
402
467
  room: this.id,
403
468
  type: "live_cut",
404
- timestamp: getDateTimestamp(),
469
+ id: msg_id,
470
+ timestamp: send_time || getDateTimestamp(),
405
471
  info: {
406
472
  message: msg.msg,
407
473
  },
408
474
  };
475
+ cut.id ?? (cut.id = (0, __1.generateId)(cut));
409
476
  this.emitMsg(cut);
410
477
  }
411
478
  msg_PREPARING(msg) {
479
+ const { msg_id, send_time } = msg;
412
480
  let off = {
413
481
  platform: "bilibili",
414
482
  room: this.id,
415
483
  type: "live_end",
416
- timestamp: getDateTimestamp(),
484
+ id: msg_id,
485
+ timestamp: send_time || getDateTimestamp(),
417
486
  info: {
418
- status: msg.round ? __1.RoomStatus.round : __1.RoomStatus.off
419
- }
487
+ status: msg.round ? __1.RoomStatus.round : __1.RoomStatus.off,
488
+ },
420
489
  };
490
+ off.id ?? (off.id = (0, __1.generateId)(off));
421
491
  this.emitMsg(off);
422
492
  }
423
493
  msg_ROOM_CHANGE(msg) {
494
+ const { data, msg_id, send_time } = msg;
424
495
  let change = {
425
496
  platform: "bilibili",
426
497
  room: this.id,
427
- type: "live_view",
428
- timestamp: Date.now(),
498
+ type: "live_detail",
499
+ id: msg_id,
500
+ timestamp: send_time || getDateTimestamp(),
429
501
  info: {
430
- title: msg.data.title,
431
- area: [msg.data.parent_area_name, msg.data.area_name]
432
- }
502
+ title: data.title,
503
+ area: [data.parent_area_name, data.area_name],
504
+ },
433
505
  };
506
+ change.id ?? (change.id = (0, __1.generateId)(change));
434
507
  this.emitMsg(change);
435
508
  }
436
509
  }
@@ -7,15 +7,23 @@ class chatPrint {
7
7
  this.main = main;
8
8
  let hidden = [];
9
9
  this.hideType = new Set(hidden); // 隐藏类型
10
- this.main.on("live_message", (msg) => { this.log(msg); });
10
+ this.main.on("live_message", (msg) => {
11
+ this.log(msg);
12
+ });
11
13
  }
12
14
  /** 获取用户信息 */
13
15
  getUserInfo(message) {
14
16
  let user = message.info.user; // 用户信息
15
17
  let name = `${"\x1b[33m"}${user.name}`; // 用户名
16
- let medal = user.medal ? `${"\x1b[32m"}[${user.medal.name}(${user.medal.level})] ` : ""; // 粉丝牌
17
- let membership = user.membership ? `${"\x1b[36m"}[${this.getPriviliegeName(message.platform, user.membership)}]` : ""; // 特权粉丝
18
- let admin = user.admin ? `${"\x1b[95m"}[${{ [__1.UserAdmin.admin]: "房管", [__1.UserAdmin.anchor]: "主播" }[user.admin]}]` : ""; // 房管
18
+ let medal = user.medal
19
+ ? `${"\x1b[32m"}[${user.medal.name}(${user.medal.level})] `
20
+ : ""; // 粉丝牌
21
+ let membership = user.membership
22
+ ? `${"\x1b[36m"}[${this.getPriviliegeName(message.platform, user.membership)}]`
23
+ : ""; // 特权粉丝
24
+ let admin = user.type
25
+ ? `${"\x1b[95m"}[${{ [__1.UserType.admin]: "房管", [__1.UserType.anchor]: "主播" }[user.type]}]`
26
+ : ""; // 房管
19
27
  return `${medal}${membership}${admin}${name}${"\x1b[0m"}`; //[粉丝牌(等级)] [特权][房管]用户名
20
28
  }
21
29
  /** 获取特权粉丝名称 */
@@ -81,7 +89,9 @@ class chatPrint {
81
89
  }
82
90
  case "block": {
83
91
  let user = this.getUserInfo(message);
84
- let operator = message.info.operator.admin ? { [__1.UserAdmin.admin]: "房管", [__1.UserAdmin.anchor]: "主播" }[message.info.operator.admin] : "管理员";
92
+ let operator = message.info.operator.type
93
+ ? { [__1.UserType.admin]: "房管", [__1.UserType.anchor]: "主播" }[message.info.operator.type]
94
+ : "管理员";
85
95
  console.log(`${user} 已被${operator}禁言`);
86
96
  break;
87
97
  }
package/src/enum.d.ts CHANGED
@@ -25,8 +25,10 @@ export declare enum DanmakuMode {
25
25
  top = 5,
26
26
  right = 6
27
27
  }
28
- /** 管理等级 */
29
- export declare enum UserAdmin {
28
+ /** 用户类型 */
29
+ export declare enum UserType {
30
+ /** 普通观众 */
31
+ normal = 0,
30
32
  /** 房管 */
31
33
  admin = 1,
32
34
  /** 主播 */
package/src/enum.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UserAdmin = exports.DanmakuMode = exports.ImageSize = exports.RoomStatus = void 0;
3
+ exports.UserType = exports.DanmakuMode = exports.ImageSize = exports.RoomStatus = void 0;
4
4
  /** 直播间状态 */
5
5
  var RoomStatus;
6
6
  (function (RoomStatus) {
@@ -31,11 +31,13 @@ var DanmakuMode;
31
31
  DanmakuMode[DanmakuMode["top"] = 5] = "top";
32
32
  DanmakuMode[DanmakuMode["right"] = 6] = "right";
33
33
  })(DanmakuMode = exports.DanmakuMode || (exports.DanmakuMode = {}));
34
- /** 管理等级 */
35
- var UserAdmin;
36
- (function (UserAdmin) {
34
+ /** 用户类型 */
35
+ var UserType;
36
+ (function (UserType) {
37
+ /** 普通观众 */
38
+ UserType[UserType["normal"] = 0] = "normal";
37
39
  /** 房管 */
38
- UserAdmin[UserAdmin["admin"] = 1] = "admin";
40
+ UserType[UserType["admin"] = 1] = "admin";
39
41
  /** 主播 */
40
- UserAdmin[UserAdmin["anchor"] = 2] = "anchor";
41
- })(UserAdmin = exports.UserAdmin || (exports.UserAdmin = {}));
42
+ UserType[UserType["anchor"] = 2] = "anchor";
43
+ })(UserType = exports.UserType || (exports.UserType = {}));
@@ -10,7 +10,7 @@ export interface RoomInfo {
10
10
  /** 房间key */
11
11
  key: string;
12
12
  /** 基本信息 */
13
- view: RoomViewInfo;
13
+ detail: RoomDetail;
14
14
  /** 统计信息 */
15
15
  stats?: RoomStatsInfo;
16
16
  /** 主播信息 */
@@ -29,7 +29,7 @@ export interface RoomInfo {
29
29
  connected: boolean;
30
30
  }
31
31
  /** 房间展示信息 */
32
- export declare type RoomViewInfo = {
32
+ export declare type RoomDetail = {
33
33
  /** 直播标题 */
34
34
  title?: string;
35
35
  /** 分区 */
@@ -54,8 +54,8 @@ export declare abstract class LiveRoom extends EventEmitter implements RoomInfo
54
54
  abstract readonly platform: string;
55
55
  /** 房间id */
56
56
  abstract readonly id: string | number;
57
- /** 基本信息 */
58
- abstract view: RoomViewInfo;
57
+ /** 房间详情 */
58
+ abstract detail: RoomDetail;
59
59
  /** 统计信息 */
60
60
  stats?: RoomStatsInfo;
61
61
  /** 主播信息 */
@@ -29,9 +29,9 @@ class LiveRoom extends events_1.EventEmitter {
29
29
  this.timestamp = msg.timestamp;
30
30
  this.emit("status", enum_1.RoomStatus.live, { timestamp: msg.timestamp, id: msg.info.id });
31
31
  break;
32
- case "live_view":
33
- this.view = Object.assign(this.view, msg.info);
34
- this.emit("view", msg.info);
32
+ case "live_detail":
33
+ this.detail = Object.assign(this.detail, msg.info);
34
+ this.emit("detail", msg.info);
35
35
  break;
36
36
  case "live_stats":
37
37
  this.stats = Object.assign(this.stats, msg.info);
@@ -55,7 +55,7 @@ class LiveRoom extends events_1.EventEmitter {
55
55
  return {
56
56
  platform: this.platform,
57
57
  id: this.id,
58
- view: this.view,
58
+ detail: this.detail,
59
59
  stats: this.stats,
60
60
  anchor: this.anchor,
61
61
  timestamp: this.timestamp,
@@ -53,8 +53,8 @@ class RoomController {
53
53
  this.main.emit("room_info", key, room.info);
54
54
  });
55
55
  // 直播展示信息更改
56
- room.on("view", (data) => {
57
- this.main.emit("room_view", key, data);
56
+ room.on("detail", (data) => {
57
+ this.main.emit("room_detail", key, data);
58
58
  });
59
59
  // 直播状态更改
60
60
  room.on("status", (status, { id, timestamp }) => {
@@ -1,4 +1,4 @@
1
- import { ImageSize, UserAdmin } from "../../enum";
1
+ import { ImageSize, UserType } from "../../enum";
2
2
  /** 用户信息 */
3
3
  export interface UserInfo {
4
4
  /** 用户名 */
@@ -9,8 +9,8 @@ export interface UserInfo {
9
9
  avatar?: string;
10
10
  /** 粉丝勋章 */
11
11
  medal?: MedalInfo | null;
12
- /** 管理等级 */
13
- admin?: UserAdmin | null;
12
+ /** 用户类型 */
13
+ type?: UserType | null;
14
14
  /** 粉丝vip等级 */
15
15
  membership?: boolean | number;
16
16
  /** vip等级 */
@@ -55,13 +55,13 @@ export interface GiftInfo {
55
55
  /** 礼物连击数 */
56
56
  combo?: string;
57
57
  /** 礼物连击id */
58
- combo_id?: string;
58
+ comboId?: string;
59
59
  /** 人民币价值 */
60
60
  cny?: number;
61
61
  /** 行为 */
62
62
  action?: string;
63
63
  /** 随机礼物信息 */
64
- blind_gift?: GiftInfo;
64
+ blindGift?: GiftInfo;
65
65
  /** 图片信息 */
66
66
  image?: string;
67
67
  }
@@ -1,6 +1,7 @@
1
- import { RoomInfo } from './../../lib/LiveRoom';
2
- import { DanmakuMode, RoomStatus, UserAdmin } from '../../enum';
3
- import { RoomViewInfo, RoomStatsInfo } from "../../lib/LiveRoom";
1
+ import { UserType } from "./../../enum";
2
+ import { RoomInfo } from "./../../lib/LiveRoom";
3
+ import { DanmakuMode, RoomStatus } from "../../enum";
4
+ import { RoomDetail, RoomStatsInfo } from "../../lib/LiveRoom";
4
5
  import { UserInfo, GiftInfo, ImageInfo } from "./AttributeInfo";
5
6
  declare type MessageBase = {
6
7
  /** 平台名称 */
@@ -11,6 +12,8 @@ declare type MessageBase = {
11
12
  type: string;
12
13
  /** 时间戳 */
13
14
  timestamp: number;
15
+ /** 消息id */
16
+ id: string;
14
17
  /** 其他属性 */
15
18
  [attr: string]: any;
16
19
  };
@@ -28,7 +31,7 @@ export declare type MessageExt<T extends MessageInterface, E extends {
28
31
  info: E;
29
32
  };
30
33
  /** 文本聊天消息 */
31
- export declare type MessageChat = MessageBase & {
34
+ export interface MessageChat extends MessageBase {
32
35
  type: "chat";
33
36
  info: {
34
37
  /** 用户信息 */
@@ -50,9 +53,9 @@ export declare type MessageChat = MessageBase & {
50
53
  /** 标签信息 */
51
54
  tag?: string;
52
55
  };
53
- };
56
+ }
54
57
  /** 礼物消息 */
55
- export declare type MessageGift = MessageBase & {
58
+ export interface MessageGift extends MessageBase {
56
59
  type: "gift";
57
60
  info: {
58
61
  /** 用户信息 */
@@ -60,9 +63,9 @@ export declare type MessageGift = MessageBase & {
60
63
  /** 礼物信息 */
61
64
  gift: GiftInfo;
62
65
  };
63
- };
66
+ }
64
67
  /** 互动消息(进入直播间、点赞、关注、分享、加入粉丝团) */
65
- export declare type MessageInteract = MessageBase & {
68
+ export interface MessageInteract extends MessageBase {
66
69
  type: "entry" | "like" | "follow" | "share" | "join";
67
70
  info: {
68
71
  /** 用户信息 */
@@ -70,9 +73,9 @@ export declare type MessageInteract = MessageBase & {
70
73
  /** 信息标签 */
71
74
  tag?: string | boolean;
72
75
  };
73
- };
76
+ }
74
77
  /** 粉丝vip开通消息 */
75
- export declare type MessageMembership = MessageBase & {
78
+ export interface MessageMembership extends MessageBase {
76
79
  type: "membership";
77
80
  info: {
78
81
  /** 用户信息 */
@@ -86,13 +89,13 @@ export declare type MessageMembership = MessageBase & {
86
89
  /** 持续时间(天数) */
87
90
  duration: number;
88
91
  };
89
- };
92
+ }
90
93
  /** 粉丝vip开通消息 */
91
- export declare type MessageSuperchat = MessageBase & {
94
+ export interface MessageSuperchat extends MessageBase {
92
95
  type: "superchat";
93
96
  info: {
94
97
  /** 留言id */
95
- id?: string;
98
+ id: string;
96
99
  /** 用户信息 */
97
100
  user: UserInfo;
98
101
  /** 文本内容 */
@@ -104,35 +107,35 @@ export declare type MessageSuperchat = MessageBase & {
104
107
  /** (SC)持续时间 */
105
108
  duration: number;
106
109
  };
107
- };
110
+ }
108
111
  /** 禁言消息 */
109
- export declare type MessageBlock = MessageBase & {
112
+ export interface MessageBlock extends MessageBase {
110
113
  type: "block";
111
114
  info: {
112
115
  /** 用户信息 */
113
116
  user: UserInfo;
114
117
  /** 操作者 */
115
118
  operator: UserInfo | {
116
- admin: null | UserAdmin;
119
+ type: null | UserType;
117
120
  };
118
121
  };
119
- };
122
+ }
120
123
  /** 直播开播消息 */
121
- export declare type MessageLiveStart = MessageBase & {
124
+ export interface MessageLiveStart extends MessageBase {
122
125
  type: "live_start";
123
126
  info: {
124
127
  /** 直播id */
125
128
  id: string;
126
129
  };
127
- };
130
+ }
128
131
  /** 直播切断消息 */
129
- export declare type MessageLiveCut = MessageBase & {
132
+ export interface MessageLiveCut extends MessageBase {
130
133
  type: "live_cut";
131
134
  info: {
132
135
  /** 切断消息 */
133
136
  message: string;
134
137
  };
135
- };
138
+ }
136
139
  /** 获取房间信息 */
137
140
  export interface MessageRoomInfo extends MessageBase {
138
141
  type: "room_info";
@@ -140,24 +143,24 @@ export interface MessageRoomInfo extends MessageBase {
140
143
  info: RoomInfo;
141
144
  }
142
145
  /** 直播数据更新 */
143
- export declare type MessageLiveStats = MessageBase & {
146
+ export interface MessageLiveStats extends MessageBase {
144
147
  type: "live_stats";
145
148
  info: RoomStatsInfo;
146
- };
149
+ }
147
150
  /** 直播展示信息更新 */
148
- export declare type MessageLiveView = MessageBase & {
149
- type: "live_view";
150
- info: RoomViewInfo;
151
- };
151
+ export interface MessageLiveDetail extends MessageBase {
152
+ type: "live_detail";
153
+ info: RoomDetail;
154
+ }
152
155
  /** 直播结束 */
153
- export declare type MessageLiveEnd = MessageBase & {
156
+ export interface MessageLiveEnd extends MessageBase {
154
157
  type: "live_end";
155
158
  info: {
156
159
  /** 直播状态 */
157
160
  status: RoomStatus;
158
161
  };
159
- };
160
- declare type AllMessageType = MessageChat | MessageGift | MessageInteract | MessageMembership | MessageSuperchat | MessageBlock | MessageLiveStart | MessageLiveEnd | MessageLiveCut | MessageLiveView | MessageLiveStats;
162
+ }
163
+ declare type AllMessageType = MessageChat | MessageGift | MessageInteract | MessageMembership | MessageSuperchat | MessageBlock | MessageLiveStart | MessageLiveEnd | MessageLiveCut | MessageLiveDetail | MessageLiveStats;
161
164
  export declare type MessageData<T extends AllMessageType["type"] = AllMessageType["type"]> = AllMessageType & {
162
165
  type: T;
163
166
  };
package/src/utils.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { MessageData } from './types/message/MessageData';
2
+ export declare function generateId(msg: MessageData): string;
package/src/utils.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateId = void 0;
4
+ function generateId(msg) {
5
+ switch (msg.type) {
6
+ case "gift":
7
+ return `gift:${msg.info.user.id}-${msg.timestamp}`;
8
+ case "superchat":
9
+ return `superchat:${msg.info.id}`;
10
+ case "membership":
11
+ return `membership:${msg.info.user.id}-${msg.info.level || 0}-${msg.timestamp}`;
12
+ default:
13
+ if (/^live_/.test(msg.type)) {
14
+ return `${msg.type}:${msg.platform}:${msg.room}-${msg.timestamp}`;
15
+ }
16
+ else {
17
+ return `${msg.type}:${msg.info.user?.id || 0}-${msg.timestamp}`;
18
+ }
19
+ }
20
+ }
21
+ exports.generateId = generateId;