您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
B站直播间同接数显示,弹幕HOOK框架
当前为
// ==UserScript== // @name BiliOnlineHook // @description B站直播间同接数显示,弹幕HOOK框架 // @namespace http://tampermonkey.net/ // @version 0.1.2 // @author jeffz615 // @match *://live.bilibili.com/* // @match *://live.bilibili.com/blanc/* // @icon https://live.bilibili.com/favicon.ico // @run-at document-start // @sandbox raw // @license MIT // ==/UserScript== (function () { 'use strict'; function hook_wrapper() { let g_rank_count = 0; let g_online_count = 0; function on_online_rank_count(obj) { const rank_count = obj.data.count; const online_count = obj.data.online_count; let flag = false; if (rank_count && rank_count !== g_rank_count) { g_rank_count = rank_count; flag = true; } if (online_count && online_count !== g_online_count) { g_online_count = online_count; flag = true; } if (flag) { const showers = document.querySelectorAll("#rank-list-ctnr-box > div.tabs > ul > li.item"); if (showers.length > 0) { const origin_text = showers[0].innerText.split('(')[0]; showers[0].innerText = origin_text + '(' + g_rank_count + '/' + g_online_count + ')'; showers[0].setAttribute('title', '除号左边是贡献值非0人数,右边是所有人数。' + (g_online_count === 0 ? '' : ('计算结果:' + (g_rank_count / g_online_count * 100).toFixed(2) + '%'))); } } } function on_send_gift(obj) { function calc_total_price(obj) { return obj.data.coin_type === 'gold' ? (obj.data.total_coin / 1000).toFixed(2) : '0.00'; } console.debug('[BiliOnlineHook] SEND_GIFT', obj.data.uid, obj.data.uname, obj.data.action, obj.data.giftName, 'x', obj.data.num, calc_total_price(obj)); } function on_danmu_msg(obj) { if (obj.info.length === 0 || obj.info[0].length <= 16 || obj.info[0][16].activity_identity !== '') { return; } /* uid, uname, msg */ console.debug('[BiliOnlineHook] DANMU_MSG', obj.info[2][0], obj.info[2][1], obj.info[1]); } function on_guard_buy(obj) { /* uid, username, num, price, gift_name */ console.debug('[BiliOnlineHook] GUARD_BUY', obj.data.uid, obj.data.username, obj.data.num, obj.data.price, obj.data.gift_name); } function on_super_chat_message(obj) { /* uid, uname, message, price, rmb */ console.debug('[BiliOnlineHook] SUPER_CHAT_MESSAGE', obj.data.uid, obj.data.uname, obj.data.message, obj.data.price, obj.data.rmb); } function on_interact_word(obj) { /* uid, uname */ console.debug('[BiliOnlineHook] INTERACT_WORD', obj.data.uid, obj.data.uname); } function on_entry_effect(obj) { /* uid, uinfo */ console.debug('[BiliOnlineHook] ENTRY_EFFECT', obj.data.uid, obj.data.uinfo.base.name); } function on_raw(obj) { console.debug('[BiliOnlineHook]', obj); } const cb_map = { "ONLINE_RANK_COUNT": on_online_rank_count, "SEND_GIFT": on_send_gift, "DANMU_MSG": on_danmu_msg, "GUARD_BUY": on_guard_buy, "SUPER_CHAT_MESSAGE": on_super_chat_message, "ENTRY_EFFECT": on_entry_effect, "INTERACT_WORD": on_interact_word, }; function check_stack() { const callstack = new Error().stack.split("\n"); if (callstack.length < 4) { return false; } for (let call_func of callstack.slice(3)) { if (call_func.includes(".convertToObject ")) { continue; } else if (call_func.includes(".onMessage ")) { return true; } break; } return false; } const origin_parse = JSON.parse; JSON.parse = function (...args) { let result = origin_parse.apply(this, args); if (result.cmd && check_stack()) { const cb_func = cb_map[result.cmd]; try { if (cb_func) cb_func(result); } catch (err) { } } return result; } } hook_wrapper(); })();