// ==UserScript== // @name Bilibili直播自动点赞 // @description Bilibili进入直播间后自动点赞. // @version 1.2.0 // @namespace https://github.com/AliubYiero/TamperMonkeyScripts // @author Yiero // @run-at document-body // @grant GM_addStyle // @grant GM_getValue // @grant GM_xmlhttpRequest // @match https://live.bilibili.com/* // @connect api.bilibili.com // @connect api.live.bilibili.com // ==/UserScript== /* ==UserConfig== 配置项: likeAnimationStat: title: 点赞动画状态 (默认关闭) description: 显示点赞后的动画效果 type: checkbox default: false displayLikeText: title: 点赞数量文本状态 (默认开启) description: 显示点赞数量文本 type: checkbox default: true likeClickDelayMinRange: title: 点赞随机时间延迟 (ms) , 最小随机时间 (无法少于500ms) description: 点赞延迟 (ms) type: number default: 2000 likeClickDelayMaxRange: title: 点赞随机时间延迟 (ms) , 最大随机时间 description: 点赞延迟 (ms) type: number default: 5000 onlyLikeFollow: title: 仅点赞关注用户 description: 仅点赞关注用户 type: checkbox default: true ==/UserConfig== */ const getRoomId = () => { const roodId = new URL(document.URL).pathname.split("/").find((item) => /^\d+$/.test(item)) || 0; return Number(roodId); }; const fetch = (config) => { let { url, param, method = "GET", data } = config; const urlParam = new URLSearchParams(param).toString(); if (urlParam) { url = `${url}?${urlParam}`; } return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method, url, headers: { "Content-Type": "application/json" }, data: JSON.stringify(data), onload(response) { try { const res = JSON.parse(response.response); setTimeout(() => { resolve(res); }, 500); } catch (e) { reject(e); } } }); }); }; const api_GetRoomInfo = (roomId) => { return fetch({ url: "https://api.live.bilibili.com/room/v1/Room/get_info", param: { room_id: roomId }, method: "GET" }); }; const api_GetUserCardInfo = (uid) => { return fetch({ url: "https://api.bilibili.com/x/web-interface/card", param: { mid: uid } }); }; const getFollowInfo = async (roomId) => { const uid = await api_GetRoomInfo(roomId).then((res) => res.data.uid); return api_GetUserCardInfo(uid).then((res) => res.data.following); }; const randomRange = (min, max) => { min = Math.max(500, min); max = Math.max(min, max); return min + Math.floor(Math.random() * (max - min + 1)); }; const clickLike = () => { const key = new KeyboardEvent("keydown", { key: "k", repeat: true }); window.dispatchEvent(key); }; (async function() { const displayLikeAnimation = !GM_getValue("\u914D\u7F6E\u9879.likeAnimationStat", false); const displayLikeText = GM_getValue("\u914D\u7F6E\u9879.displayLikeText", true); const likeClickRange = [ GM_getValue("\u914D\u7F6E\u9879.likeClickDelayMinRange", 2e3), GM_getValue("\u914D\u7F6E\u9879.likeClickDelayMaxRange", 5e3) ]; const onlyLikeFollow = GM_getValue("\u914D\u7F6E\u9879.onlyLikeFollow", true); if (onlyLikeFollow) { const roomId = getRoomId(); const isFollow = await getFollowInfo(roomId); if (!isFollow) { return; } } if (displayLikeAnimation || displayLikeText) { let css = ""; displayLikeAnimation && (css += `[id^="like-animation"] {display: none !important;}`); displayLikeText && (css += `${".like-text".repeat(15)} {display: inline !important;}`); GM_addStyle(css); } const propSelectorList = [".medalAb", ".emoticons", '.gift-panel-box[style=""]']; setInterval(() => { if (propSelectorList.some((selector) => document.querySelector(selector))) { return; } clickLike(); }, randomRange(...likeClickRange)); })();