Greasy Fork

Greasy Fork is available in English.

B站直播间添加个人主页连结到用户名

B站直播间添加个人主页连结到礼物/醒目留言/观众进入讯息的用户名上

当前为 2021-01-25 提交的版本,查看 最新版本

// ==UserScript==
// @name         B站直播间添加个人主页连结到用户名
// @namespace    http://tampermonkey.net/
// @version      0.0.1
// @description  B站直播间添加个人主页连结到礼物/醒目留言/观众进入讯息的用户名上
// @author       Eric Lam
// @include      /https?:\/\/live\.bilibili\.com\/(blanc\/)?\d+\??.*/
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/pako.min.js
// @require      http://greasyfork.icu/scripts/417560-bliveproxy/code/bliveproxy.js?version=875812
// @grant        none
// ==/UserScript==



(async function() {
    'use strict';

    const nameMap = new Map()

    const config = { attributes: false, childList: true, subtree: true }

    const sc = launchSuperChat(nameMap, config)

    const gift = launchSendGift(nameMap, config)

    const enter = launchEnterMessage(nameMap, config)

    await Promise.all([sc, gift, enter])

})();

async function launchEnterMessage(map, config){
   bliveproxy.addCommandHandler('INTERACT_WORD', ({data}) => {
     const {uid, uname} = data
     console.debug(`[from enter] name: ${uname}; uid: ${uid}`)
     map.set(uname, uid)
   })

   const observer = function(list, o){
     for(const mu of list){
         for (const node of mu.addedNodes){
            handle(node, 'span.interact-name', map)
         }
      }
   }

   // observe for mutation link
    new MutationObserver(observer).observe($('#brush-prompt')[0], config)
    console.log('started enter message observing')
   //
}

async function launchSendGift(map, config){

    bliveproxy.addCommandHandler('SEND_GIFT', ({data}) => {
     const {uid, uname} = data
     console.debug(`[from gift] name: ${uname}; uid: ${uid}`)
     map.set(uname, uid)
   })

   const observer = function(list, o){
      for(const mu of list){
         for (const node of mu.addedNodes){
            handle(node, 'span.username', map)
         }
      }
   }

   const observerBubble = function(list, o){
      for(const mu of list){
         for (const node of mu.addedNodes){
            handle(node, 'div.user-name', map)
         }
      }
   }

    // observe for mutation link
    new MutationObserver(observer).observe($('#chat-items')[0], config)
    new MutationObserver(observer).observe($('#penury-gift-msg')[0], config)

    while($('.bubble-list').length == 0){
      await sleep(500)
    }

    new MutationObserver(observerBubble).observe($('.bubble-list')[0], config)
    console.log('started gift observing')
    //

}

async function launchSuperChat(map, config){

    // websocket
    bliveproxy.addCommandHandler('SUPER_CHAT_MESSAGE', ({data}) => {
       const uid = data.uid
       const name = data.user_info.uname
       console.debug(`[from superchat] name: ${name}; uid: ${uid}`)
       map.set(name, uid)
    })
    //

    // get current superchat
    const scList = window.__NEPTUNE_IS_MY_WAIFU__.roomInfoRes.data.super_chat_info.message_list

    for (const data of scList){
        const uid = data.uid
        const name = data.user_info.uname
        console.debug(`[from old sc list] name: ${name}; uid: ${uid}`)
        map.set(name, uid)
    }
    //

   const observer = function(list, o){
      for(const mu of list){
         for (const node of mu.addedNodes){
            handle(node, '.name', map)
         }
      }
    }

   const superChatPanelO = new MutationObserver(observer)

   const panelExist = () => $('.pay-note-panel').length > 0

   let launched = false


   while (!panelExist()){
     await sleep('500')
   }

    // observe for mutation link
    setInterval(() => {
      if (panelExist()){
          if (launched) return
          superChatPanelO.observe($('.pay-note-panel')[0], config)
          console.log('started superchat observing')
          launched = true
      }else{
          if (!launched) return
          superChatPanelO.disconnect()
          console.log('stopped superchat observing')
          launched = false
      }
    }, 1000)

}

function handle(node, element, map){
   const name = $(node).find(element)
   if (name.length == 0) return
   const uname = name[0].innerText
   const uid = map.get(uname)
   if (!uid) {
      console.warn(`找不到 ${uname} 用户的 uid`)
      return
   }
   name[0].innerHTML = `<a href="https://space.bilibili.com/${uid}" target="_blank" style="color: inherit;text-decoration: inherit;">${uname}</a>`
}

async function sleep(ms){
  return new Promise((res,) => setInterval(res,ms))
}