您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
B 站进入直播间时自动换上主播对应的牌子
// ==UserScript== // @name B 站直播自动换牌子 (切窗口自动换) // @namespace http://tampermonkey.net/ // @version 0.3.2 // @description B 站进入直播间时自动换上主播对应的牌子 // @match https://live.bilibili.com/* // @run-at document-start // @license MIT // ==/UserScript== (async function() { 'use strict'; // 换牌子 const wear = (medal_id, token) => { const xhr = new XMLHttpRequest() xhr.responseType = 'json' xhr.withCredentials=true xhr.open("POST","https://api.live.bilibili.com/xlive/web-room/v1/fansMedal/wear") xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded") xhr.send(`medal_id=${medal_id}&csrf_token=${token}&csrf=${token}`) } // 获取Cookies const get_cookies = () => { let cookies = {} let cookies_array = document.cookie.split('; ') for (const prop of cookies_array) { let [k, v] = prop.split('=') cookies[k] = v } return cookies; } // 获取直播间详细信息 const get_info = (liveroom_id) => { return new Promise((res, rej) => { let xhr = new XMLHttpRequest() xhr.responseType = 'json' xhr.withCredentials = true xhr.onreadystatechange = () => { if(xhr.readyState === 4) { if(xhr.status === 200) { res(xhr.response) }else { rej('error') } } } xhr.open("GET", `https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByUser?room_id=${liveroom_id}&from=0`) xhr.send() }) } // 获取牌子列表 const get_medal_list = (uid) => { return new Promise((res, rej) => { const xhr = new XMLHttpRequest() xhr.responseType = 'json' xhr.withCredentials = true xhr.onreadystatechange = () => { if(xhr.readyState === 4) { if(xhr.status === 200) { res(xhr.response) }else { rej('error') } } } xhr.open("GET", `https://api.live.bilibili.com/xlive/web-ucenter/user/MedalWall?target_id=${uid}`) xhr.send() }) } const cookies = get_cookies(); const csrfToken = cookies['bili_jct']; const liveroomId = parseInt(window.location.pathname.split('/').pop()); const userInfo = await get_info(liveroomId); const userId = userInfo.data.info.uid; const upId = userInfo.data.medal.up_medal.uid; // 获取直播间牌子 const medalId = await get_medal_list(userId).then(res => { for (const prop of res.data.list) { if (upId == prop['medal_info']['target_id']) { return prop['medal_info']['medal_id'] } } }); console.info(`Lengyue Medal: user ${userId}, room ${liveroomId}, up ${upId}, medal ${medalId}`); const getInfoAndWear = async () => { const userInfo = await get_info(liveroomId); const weared = userInfo.data.medal.curr_weared.target_id; if (weared != upId) { wear(medalId, csrfToken); console.info(`Lengyue Medal: weared`); } } await getInfoAndWear(); const getMedalStatus = async (loading, go_wear) => { const medalContent = document.querySelector("div.medal-section > span > div > div > span.fans-medal-content"); const level = document.querySelector("div.medal-section > span > div > div.fans-medal-level"); if (loading) medalContent.innerText = "Loading"; const userInfo = await get_info(userId); const currentMedal = userInfo.data.medal.curr_weared; medalContent.innerText = currentMedal.medal_name; level.innerText = currentMedal.level; if (go_wear && currentMedal.target_id != upId) { wear(medalId, csrfToken); console.info(`Lengyue Medal: weared`); await getMedalStatus(); } }; window.addEventListener('focus', () => getMedalStatus(true, true)); setInterval(() => getMedalStatus(false, false), 5*1000); })();