UNPKG

@xyself/blivedm-js

Version:

B站直播弹幕库的Node.js实现 (CommonJS版本)

310 lines (264 loc) 10.3 kB
class BaseHandler { constructor() { this.CMD_CALLBACK_DICT = { 'DANMU_MSG': this._on_danmaku.bind(this), 'SEND_GIFT': this._on_gift.bind(this), 'GUARD_BUY': this._on_buy_guard.bind(this), 'USER_TOAST_V2': this._on_user_toast_v2.bind(this), 'SUPER_CHAT_MESSAGE': this._on_super_chat.bind(this), 'SUPER_CHAT_MESSAGE_DELETE': this._on_super_chat_delete.bind(this), 'LIKE_INFO_V3_UPDATE': this._on_like.bind(this), 'LIKE_INFO_V3_CLICK': this._on_like_click.bind(this), 'INTERACT_WORD': this._on_interact_word.bind(this), 'ENTRY_EFFECT': this._on_entry_effect.bind(this), 'COMBO_SEND': this._on_combo_send.bind(this), 'HOT_RANK_CHANGED': this._on_hot_rank_changed.bind(this), 'HOT_RANK_CHANGED_V2': this._on_hot_rank_changed_v2.bind(this), 'LIVE': this._on_live.bind(this), 'LIVE_INTERACTIVE_GAME': this._on_live_interactive_game.bind(this), 'NOTICE_MSG': this._on_notice_msg.bind(this), 'ONLINE_RANK_TOP3': this._on_online_rank_top3.bind(this), 'PK_BATTLE_END': this._on_pk_battle_end.bind(this), 'PK_BATTLE_FINAL_PROCESS': this._on_pk_battle_final_process.bind(this), 'PK_BATTLE_PROCESS': this._on_pk_battle_process.bind(this), 'PK_BATTLE_PROCESS_NEW': this._on_pk_battle_process_new.bind(this), 'PK_BATTLE_SETTLE': this._on_pk_battle_settle.bind(this), 'PK_BATTLE_SETTLE_USER': this._on_pk_battle_settle_user.bind(this), 'PK_BATTLE_SETTLE_V2': this._on_pk_battle_settle_v2.bind(this), 'PREPARING': this._on_preparing.bind(this), 'ROOM_REAL_TIME_MESSAGE_UPDATE': this._on_room_real_time_message_update.bind(this), 'SUPER_CHAT_MESSAGE_JPN': this._on_super_chat_jpn.bind(this), 'USER_TOAST_MSG': this._on_user_toast_msg.bind(this), 'WIDGET_BANNER': this._on_widget_banner.bind(this), 'OTHER_SLICE_LOADING_RESULT': this._on_other_slice_loading_result.bind(this), 'DM_INTERACTION': this._on_dm_interaction.bind(this) }; // 添加消息缓存用于去重 this._messageCache = new Map(); } /** * 客户端连接成功 * @param {BLiveClient} client 客户端实例 */ on_client_start(client) { // 可以重写此方法 } /** * 客户端断开连接 * @param {BLiveClient} client 客户端实例 */ on_client_stop(client) { // 可以重写此方法 } /** * 收到心跳包 * @param {BLiveClient} client 客户端实例 * @param {HeartbeatMessage} message 心跳消息 */ _on_heartbeat(client, message) { // 心跳包不输出 } /** * 消息去重检查 * @param {string} key 消息的唯一标识 * @param {number} timeout 去重超时时间(毫秒) * @returns {boolean} 如果是重复消息返回true */ _isDuplicateMessage(key, timeout = 3000) { const now = Date.now(); const lastTime = this._messageCache.get(key); if (lastTime && now - lastTime < timeout) { return true; } this._messageCache.set(key, now); return false; } /** * 收到弹幕 * @param {BLiveClient} client 客户端实例 * @param {DanmakuMessage} message 弹幕消息 */ _on_danmaku(client, message) { const key = `danmaku_${message.timestamp}_${message.uid}_${message.msg}`; if (this._isDuplicateMessage(key)) return; console.log(`[${client.roomId}] ${message.uname}${message.msg}`); } /** * 收到礼物 * @param {BLiveClient} client 客户端实例 * @param {GiftMessage} message 礼物消息 */ _on_gift(client, message) { const key = `gift_${message.uid}_${message.giftId}_${message.timestamp}`; if (this._isDuplicateMessage(key)) return; let medal_str = ''; if (message.medal_info && message.medal_info.medal_level > 0) { medal_str = `[${message.medal_info.medal_name}${message.medal_info.medal_level}]`; } console.log(`[${client.roomId}] ${message.uname}${medal_str} 赠送 ${message.giftName}x${message.num} (${message.coinType === 'gold' ? '金瓜子' : '银瓜子'}x${message.totalCoin})`); } /** * 用户上舰 * @param {BLiveClient} client 客户端实例 * @param {GuardBuyMessage} message 上舰消息 */ _on_buy_guard(client, message) { console.log(`[${client.roomId}] ${message.username} 上舰,guard_level=${message.guardLevel}`); } /** * 醒目留言 * @param {BLiveClient} client 客户端实例 * @param {SuperChatMessage} message SC消息 */ _on_super_chat(client, message) { console.log(`[${client.roomId}] 醒目留言 ¥${message.price} ${message.uname}${message.message}`); } _on_super_chat_delete(client, message) { // 可以重写此方法 } _on_like(client, message) { // 可以重写此方法 } /** * 用户进入直播间 * @param {BLiveClient} client 客户端实例 * @param {InteractWordMessage} message 进房消息 */ _on_interact_word(client, message) { const key = `interact_${message.uid}_${message.msgType}_${message.timestamp}`; if (this._isDuplicateMessage(key)) return; let medal_str = ''; if (message.fans_medal && message.fans_medal.medal_level > 0) { medal_str = `[${message.fans_medal.medal_name}${message.fans_medal.medal_level}]`; } let action = ''; switch (message.msgType) { case 1: action = '进入房间'; break; case 2: action = '关注了主播'; break; case 3: action = '分享了直播间'; break; case 4: action = '特别关注了主播'; break; case 5: action = '与主播互粉了'; break; case 6: action = '为主播点赞了'; break; } if (action) { console.log(`[${client.roomId}] ${message.uname}${medal_str} ${action}`); } } /** * 用户进入特效 * @param {BLiveClient} client 客户端实例 * @param {EntryEffectMessage} message 进入特效消息 */ _on_entry_effect(client, message) { // 不输出进入特效信息 } /** * 用户点赞 * @param {BLiveClient} client 客户端实例 * @param {LikeClickMessage} message 点赞消息 */ _on_like_click(client, message) { const key = `like_${message.uid}_${Date.now()}`; if (this._isDuplicateMessage(key)) return; let medal_str = ''; if (message.fans_medal && message.fans_medal.medal_level > 0) { medal_str = `[${message.fans_medal.medal_name}${message.fans_medal.medal_level}]`; } console.log(`[${client.roomId}] ${message.uname}${medal_str} 为主播点赞了`); } _on_user_toast_v2(client, message) { console.log(`[${client.roomId}] ${message.username} 上舰,guard_level=${message.guard_level}`); } _on_combo_send(client, message) { // 连击礼物,不输出 } _on_hot_rank_changed(client, message) { // 热门榜单变化,不输出 } _on_hot_rank_changed_v2(client, message) { // 热门榜单变化v2,不输出 } _on_live(client, message) { // 直播状态变化,不输出 } _on_live_interactive_game(client, message) { // 直播互动游戏,不输出 } _on_notice_msg(client, message) { const key = `notice_${message.msg_common}`; if (this._isDuplicateMessage(key)) return; if (message.msg_common) { console.log(`[${client.roomId}] 系统通知: ${message.msg_common}`); } } _on_online_rank_top3(client, message) { // 在线排名前三,不输出 } _on_pk_battle_end(client, message) { // PK结束,不输出 } _on_pk_battle_final_process(client, message) { // PK决赛进程,不输出 } _on_pk_battle_process(client, message) { // PK进程,不输出 } _on_pk_battle_process_new(client, message) { // 新版PK进程,不输出 } _on_pk_battle_settle(client, message) { // PK结算,不输出 } _on_pk_battle_settle_user(client, message) { // PK用户结算,不输出 } _on_pk_battle_settle_v2(client, message) { // PK结算v2,不输出 } _on_preparing(client, message) { // 直播准备中,不输出 } _on_room_real_time_message_update(client, message) { const key = `room_update_${message.roomid}_${message.fans}`; if (this._isDuplicateMessage(key)) return; if (message.fans) { console.log(`[${client.roomId}] 粉丝数: ${message.fans}`); } } _on_super_chat_jpn(client, message) { // 日语SC,按普通SC处理 this._on_super_chat(client, message); } _on_user_toast_msg(client, message) { // 用户提示消息,不输出 } _on_widget_banner(client, message) { // 横幅组件,不输出 } _on_other_slice_loading_result(client, message) { // 其他分片加载结果,不输出 } /** * 连续点赞消息 * @param {BLiveClient} client 客户端实例 * @param {DmInteractionMessage} message 连续点赞消息 */ _on_dm_interaction(client, message) { // 连续点赞消息,不输出 } } module.exports = { BaseHandler };