Bilibili Ban Kit

批量ban掉你讨厌的up主

// ==UserScript==
// @name         Bilibili Ban Kit
// @namespace    https://github.com/linyanm
// @version      2024-10-24--01
// @description  批量ban掉你讨厌的up主
// @author       Noir
// @match        *://www.bilibili.com/
// @match        *://www.bilibili.com/?*
// @match        *://www.bilibili.com/index.html
// @match        *://www.bilibili.com/index.html?*
// @match        *://www.bilibili.com/video/*
// @match        *://www.bilibili.com/list/watchlater?*
// @match        *://www.bilibili.com/bangumi/play/*
// @match        *://space.bilibili.com/*
// @icon         https://i0.hdslb.com/bfs/static/jinkela/long/images/favicon.ico
// @grant        GM_registerMenuCommand
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function() {
	'use strict';



	const CACHE = {
			陈三岁恐怖游戏: 3537112840275980,
			吧主甲: 434615,
			晚晚恶霸和小跟班: 253212392,
			电影迷小雅: 395991094,
			真探唐仁杰: 544336675,
			润州镜: 2229752,
			龙崎棒棒糖: 4564056,
			英大吉: 638816489,
			steam情报局: 473519710,
			勾手老大爷邓肯: 24490535,
			红警HBK08: 1629347259,
			小片片说大片: 10119428,
			正说清代十二朝: 1457639978,
			井号5467: 4305299,
			培根悖论唠唠嗑: 386869863,
			南国小豆豆: 10518076,
			胶片看电影: 46545652,
			机智帅气的一炫君: 309134148,
			不搞博士Dcy: 442229,
			黝黑蜗壳天眼老师: 14068111,
			光影笔墨: 269319344,
			迷影至下Filmlast: 942755,
			河畔的伯爵: 1596926736,
			老野心家: 2043926679,
			一碗龙虾汤: 98684196,
			渤海小吏: 504934876,
			风都獭书馆: 145544,
			The梁某人: 1405515989,
			江湖弃子: 1117551831,
			墨染玄黎: 406999290,
			大聪看电影: 253350665,
			抽风crazy: 2728123,
			悬疑MOVIE: 452600545,
			西葛西: 2035005110,
			文西与阿漆: 94281836,
			硬核的HeyMatt: 239688446,
			发光的三极管yoyo: 1135981288,
			南条鸡腿子: 2574869,
			老大南: 483052036,
			老坚果然翁: 284845773,
			影Man未知档案: 13743667,
			AYCS2: 203680252,
			地上足球888: 550674844,
			瓦岗寨主坑爹李: 3948019,
	};
	const NAMES = Object.keys(CACHE).join(',');


	const cache = GM_getValue('cache', CACHE);
	const block = GM_getValue('block', {});

	let blacklist = GM_getValue('blacklist', []);

	GM_registerMenuCommand('配置黑名单', showConfigDialog);

	let container = null;

	function showConfigDialog() {
			if (container) {
					container.remove();
			}
			container = document.createElement('div');
			container.innerHTML = `
					<div style="position: fixed; top: 10%; left: 50%; transform: translateX(-50%);
											background: #fff; border-radius: 10px; box-shadow: 0 0 15px rgba(0,0,0,0.3);
											padding: 20px; z-index: 10000; width: 400px; font-family: Arial;">
							<h3 style="text-align: center; margin-bottom: 10px;">配置拉黑名单</h3>
							<textarea id="batchInput" style="width: 100%; height: 50px; border: 1px solid #ddd;
									border-radius: 5px; padding: 5px;" placeholder="批量输入昵称,用逗号分隔"></textarea>
							<button id="batchAdd" style="margin-top: 10px; width: 100%; padding: 10px;
									background-color: #00a1d6; color: white; border: none; border-radius: 5px;">批量添加</button>
							<button id="initialize" style="margin-top: 10px; width: 100%; padding: 10px;
									background-color: #00a1d6; color: white; border: none; border-radius: 5px;">一键添加畜生名单</button>
							<ul id="blacklist" style="list-style: none; padding: 0; margin-top: 15px; max-height: 200px;
									overflow-y: auto; border: 1px solid #ddd; border-radius: 5px;">
									${blacklist.map((name, i) => `
											<li style="display: flex; justify-content: space-between; align-items: center; padding: 5px;
													border-bottom: 1px solid #f0f0f0;">
													<span id="user-${i}" class="user-name" style="flex: 1;">${name}</span>
													<button data-index="${i}" class="remove-btn" style="color: red; border: none;
															background: none;">删除</button>
											</li>
									`).join('')}
							</ul>
							<!-- <button id="execute" style="margin-top: 10px; width: 100%; padding: 10px; background-color: #00a1d6;
									color: white; border: none; border-radius: 5px;">正义执行</button> -->
							<button id="close" style="margin-top: 5px; width: 100%; padding: 10px; background-color: #ccc;
									color: black; border: none; border-radius: 5px;">关闭</button>
					</div>
			`;
			document.body.appendChild(container);

			// container.querySelector('#execute').addEventListener('click', main);
			container.querySelector('#close').addEventListener('click', () => container.remove());
			container.querySelector('#batchAdd').addEventListener('click', addBatchNames);
			container.querySelector('#initialize').addEventListener('click', initialize);

			container.querySelectorAll('.remove-btn').forEach(btn => {
					btn.addEventListener('click', (e) => {
							const index = e.target.dataset.index;
							const name = blacklist[index];
							delete block[name];
							GM_setValue('block', block);
							blacklist.splice(index, 1);
							showConfigDialog(); // 重新渲染
							saveBlacklist();
					});
			});

			// 检查每个用户的拉黑状态
			blacklist.forEach((name, i) => {
					fetchUID(name).then(uid => {
							if (uid) {
									isBlocked(uid).then(isBlocked => {
											const userElement = document.getElementById(`user-${i}`);
											userElement.style.color = isBlocked ? 'green' : 'red';
											userElement.textContent += isBlocked ? '(已拉黑)' : '(未拉黑)';
									});
							}
					});
			});
	}

	function addBatchNames() {
			const input = document.querySelector('#batchInput').value.trim();
			if (input) {
					const names = input.split(',').map(name => name.trim()).filter(name => name);
					blacklist.push(...names);
					showConfigDialog();
					saveBlacklist();
			}
	}

	function initialize() {
			const names = NAMES.split(',').map(name => name.trim()).filter(name => name);
			blacklist.push(...names);
			showConfigDialog();
			saveBlacklist();
	}

	function saveBlacklist() {
			blacklist = Array.from(new Set(blacklist));
			GM_setValue('blacklist', blacklist);
			main();
	}

	function fetchUID(name) {
			const url = `https://api.bilibili.com/x/web-interface/search/type?search_type=bili_user&keyword=${encodeURIComponent(name)}`;
			return new Promise((resolve, reject) => {
					if (cache[name]) {
							resolve(cache[name]);
							return;
					}
					GM_xmlhttpRequest({
							method: 'GET',
							url: url,
							onload: (response) => {
									try {
											const result = JSON.parse(response.responseText);
											if (result.data && result.data.result.length > 0) {
													const uid = result.data.result[0].mid;
													if (name && uid) {
															cache[name] = uid;
															GM_setValue('cache', cache);
													}
													resolve(uid);
											} else {
													resolve(null);
											}
									} catch (e) {
											reject(e);
									}
							},
							onerror: reject
					});
			});
	}

	function isBlocked(uid) {
			const url = `https://api.bilibili.com/x/relation?fid=${uid}`;
			return new Promise((resolve, reject) => {
					if (block[uid]) {
							resolve(true);
							return;
					}
					GM_xmlhttpRequest({
							method: 'GET',
							url: url,
							onload: (response) => {
									try {
											const result = JSON.parse(response.responseText);
											const blocked = result.data.attribute === 128; // 128 表示已拉黑
											block[uid] = blocked;
											GM_setValue('block', block);
											resolve(blocked)
									} catch (e) {
											reject(e);
									}
							},
							onerror: reject
					});
			});
	}

	async function getUIDsToBlock() {
			const uids = [];
			for (const name of blacklist) {
					const uid = await fetchUID(name);
					if (uid && !(await isBlocked(uid))) {
							uids.push(uid);
					} else {
							// console.log(`用户 ${name} 已经拉黑或未找到,跳过。`);
					}
			}
			return uids;
	}

	function blockUser(uid) {
			const csrfToken = getCsrfToken();
			const extendContent = JSON.stringify({
					entity: "user",
					entity_id: uid,
					fp: `0\u0001900,,1440\u0001Win32\u000120\u00018\u000124\u00011\u0001zh-CN\u00010\u00010,,0,,0\u0001${navigator.userAgent}`
			});

			const formData = new URLSearchParams({
					fid: uid,
					act: "5", // act=5 拉黑
					// act=6 解除拉黑
					re_src: "11",
					gaia_source: "web_main",
					spmid: "333.999.0.0",
					extend_content: extendContent,
					csrf: csrfToken
			}).toString();

			GM_xmlhttpRequest({
					method: 'POST',
					url: 'https://api.bilibili.com/x/relation/modify',
					headers: {
							'Content-Type': 'application/x-www-form-urlencoded',
							'Origin': 'https://www.bilibili.com',
							'Referer': 'https://www.bilibili.com/',
							'Cookie': document.cookie,
					},
					data: formData,
					onload: (response) => {
							if (response.status === 200) {
									console.log(`成功拉黑用户:${uid}`);
							} else {
									console.error(`拉黑失败:${uid}`, response);
							}
					},
					onerror: (error) => console.error(`请求错误:${uid}`, error)
			});
	}

	function getCsrfToken() {
			const match = document.cookie.match(/bili_jct=([a-zA-Z0-9]{32})/);
			return match ? match[1] : '';
	}

	// 主逻辑:过滤后执行批量拉黑
	async function main () {
			const uidsToBlock = await getUIDsToBlock();
			uidsToBlock.forEach((uid, index) => {
					setTimeout(() => {
							blockUser(uid);
							if (container) {
									showConfigDialog();
							}
					}, index * 5000); // 间隔 5 秒避免风控
			});
	}

	main();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址