Greasy Fork is available in English.
虽然是在纵横交错的宏伟时间跨度里只一刹那的昙花一现,也很庆幸与你跨越光年的相遇。
// ==UserScript== // @name Bilibili live enhanced ban - 增强的哔哩哔哩直播间禁言 // @namespace http://tampermonkey.net/ // @version 2024-03-16 // @description 虽然是在纵横交错的宏伟时间跨度里只一刹那的昙花一现,也很庆幸与你跨越光年的相遇。 // @author NailvCoronation // @match https://live.bilibili.com/* // @icon https://nailv.live/static/images/favicon.ico // @require https://code.jquery.com/jquery-3.7.1.min.js // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_listValues // @license MIT // ==/UserScript== /* #### BILIBILI BILIBILI直播间禁言只能永久禁言、不能控制禁言时长就已经很傻逼了, 但我没想到能有__长了人类大脑的人__能写出更傻逼的API。 禁言时用POST请求,但是参数写在query里; 解禁时还用POST请求,但是参数写在payload里。 我建议写出这个API的人去寻求一下心理治疗。 */ const unbanCheckInterval = 30; // In seconds const banDurations = [1, 3, 7, 30, 365]; // In days const disableAd = false; // Disable ad at the bottom function getCookie(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); } (function() { 'use strict'; var targetUid = 0; var danmakuMenuModified = false; const msInADay = 24 * 60 * 60 * 1000; const roomId = window.location.pathname.split('/').pop(); function banNDays(duration) { fetch('https://api.live.bilibili.com/xlive/web-ucenter/v1/banned/AddSilentUser?' + $.param({ room_id: roomId, tuid: targetUid, mobile_app: 'web', csrf_token: getCookie('bili_jct'), csrf: getCookie('bili_jct'), }), {method: 'POST', credentials: 'include'}) .then((resp) => resp.json()) .then((data) => { if (data.code === 0) { GM_setValue(targetUid, JSON.stringify({banTime: Date.now(), duration, roomId})); } }) } function modifyMenu() { let menu = document.getElementsByClassName('danmaku-menu')[0] let attr = menu.firstChild.getAttributeNames()[0] // Test /* const testMinutes = 3; let newDiv = document.createElement("div"); newDiv.setAttribute(attr, ""); newDiv.classList.add("add-to-black-list"); let newLink = document.createElement("a"); newLink.setAttribute(attr, ""); newLink.classList.add("clickable", "bili-link", "pointer"); let newSpan = document.createElement("span"); newSpan.textContent = "禁言该用户(" + testMinutes + "分钟)"; newLink.addEventListener('click', function() { console.log("Ban " + targetUid + " for " + testMinutes + " minutes"); banNDays(testMinutes * 60 * 1000); document.body.click(); }); newLink.appendChild(newSpan); newDiv.appendChild(newLink); menu.appendChild(newDiv); */ // Add new buttons to danmaku menu banDurations.forEach(duration => { let newDiv = document.createElement("div"); newDiv.setAttribute(attr, ""); newDiv.classList.add("add-to-black-list"); let newLink = document.createElement("a"); newLink.setAttribute(attr, ""); newLink.classList.add("clickable", "bili-link", "pointer"); let newSpan = document.createElement("span"); newSpan.textContent = "禁言该用户(" + duration + "天)"; newLink.addEventListener('click', function() { console.log("Ban " + targetUid + " for " + duration + " days"); banNDays(duration * msInADay); document.body.click(); }); newLink.appendChild(newSpan); newDiv.appendChild(newLink); menu.appendChild(newDiv); }); danmakuMenuModified = true; if (!disableAd) { let newDiv = document.createElement("div"); newDiv.setAttribute(attr, ""); newDiv.classList.add("add-to-black-list"); let newLink = document.createElement("a"); newLink.setAttribute(attr, ""); newLink.classList.add("clickable", "bili-link", "pointer"); newLink.setAttribute("href", "https://live.bilibili.com/25034104"); newLink.setAttribute("target", "_blank"); let newSpan = document.createElement("span"); newSpan.textContent = "关注明前奶绿喵🥰"; newLink.appendChild(newSpan); newDiv.appendChild(newLink); menu.appendChild(newDiv); } } function handleButtonClick(event) { if (event.target.matches('.open-menu')) { if (!danmakuMenuModified) { modifyMenu() } targetUid = event.target.parentElement.parentElement.parentElement.getAttribute('data-uid') } } async function unbanExpiredUsers() { const uids = await GM_listValues(); console.log('Banned users: ' + uids) for (const uid of uids) { const info = JSON.parse(await GM_getValue(uid)); if (info.banTime + info.duration <= Date.now()) { console.log(new Date() + ' - unban user ' + uid) console.log('User banned at ' + new Date(info.banTime)) fetch('https://api.live.bilibili.com/xlive/web-ucenter/v1/banned/DelSilentUser', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, credentials: 'include', body: $.param({ room_id: info.roomId, tuid: uid, csrf_token: getCookie('bili_jct'), csrf: getCookie('bili_jct'), }) }).then((resp) => resp.json()) .then((data) => { if (data.code === 0 || data.code === 1200000 /* already unbanned code */) { GM_deleteValue(uid); } }) } } } unbanExpiredUsers(); window.setInterval(unbanExpiredUsers, unbanCheckInterval * 1000); document.addEventListener("click", handleButtonClick); })();