您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Modern, highly configurable cleaner for the TorrentBD shoutbox. Hide system messages, all user messages, and specific User IDs.
// ==UserScript== // @name TorrentBD Shoutbox Cleaner (Enhanced) // @namespace N/A // @version 1.1 // @description Modern, highly configurable cleaner for the TorrentBD shoutbox. Hide system messages, all user messages, and specific User IDs. // @author Sumbul⚡(UI by Gojuuroku & original script by LittleFox) // @license MIT // @icon https://s14.gifyu.com/images/bTqsQ.png // @match https://*.torrentbd.com/* // @match https://*.torrentbd.net/* // @match https://*.torrentbd.org/* // @match https://*.torrentbd.me/* // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // ==/UserScript== (function () { 'use strict'; const systemFilters = { torrent: { phrase: "New Torrent :", label: "New Torrents" }, forumPost: { phrase: "New Forum Post", label: "New Forum Posts" }, forumTopic: { phrase: "New Forum Topic", label: "New Forum Topics" }, request: { phrase: "New Request :", label: "New Requests" } }; function checkShoutbox() { const shoutItems = document.querySelectorAll(".shout-item"); const isEnabled = GM_getValue('sbc_enabled', true); const systemFilterStates = {}; for (const key in systemFilters) { systemFilterStates[key] = GM_getValue(`sbc_filter_${key}`, true); } const hideAllUsers = GM_getValue('sbc_hide_all_users', false); const blockUsersEnabled = GM_getValue('sbc_block_users_enabled', true); const blockedUserIDs = GM_getValue('sbc_blocked_user_ids', []).filter(Boolean); shoutItems.forEach((item) => { item.style.display = ""; if (!isEnabled) return; const textField = item.querySelector(".shout-text"); if (!textField) return; const lowerCaseText = textField.textContent.toLowerCase(); let shouldHide = false; let isSystemMessage = false; let systemMessageType = null; for (const key in systemFilters) { if (lowerCaseText.includes(systemFilters[key].phrase.toLowerCase())) { isSystemMessage = true; systemMessageType = key; break; } } if (isSystemMessage) { if (systemFilterStates[systemMessageType]) { shouldHide = true; } } else { if (hideAllUsers) { shouldHide = true; } else if (blockUsersEnabled && blockedUserIDs.length > 0) { const idElement = item.querySelector('.shout-user [data-tid]'); const userID = idElement ? idElement.getAttribute('data-tid') : null; if (userID && blockedUserIDs.includes(userID)) { shouldHide = true; } } } if (shouldHide) { item.style.display = "none"; } }); } function createSettingsUI() { if (document.querySelector("#sbc-modal-wrapper")) return; const uiWrapper = document.createElement("div"); uiWrapper.id = "sbc-modal-wrapper"; uiWrapper.style.display = "none"; uiWrapper.innerHTML = ` <div id="sbc-container"> <div id="sbc-header"> <h1>🧹 Shoutbox Cleaner</h1> <p>Hide unwanted messages from the shoutbox</p> <button id="sbc-close-btn" title="Close">×</button> </div> <div id="sbc-content"> <div class="sbc-setting-row sbc-master-switch"> <label for="sbc-enabled-switch">Enable Cleaner</label> <label class="sbc-switch"><input type="checkbox" id="sbc-enabled-switch"><span class="sbc-slider"></span></label> </div> <hr class="sbc-divider"> <div class="sbc-section"> <h2 class="sbc-section-header">Hide system messages</h2> <div class="sbc-setting-row"> <label for="sbc-hide-all-users-switch">New Messages</label> <label class="sbc-switch"><input type="checkbox" id="sbc-hide-all-users-switch"><span class="sbc-slider"></span></label> </div> ${Object.keys(systemFilters).map(key => `<div class="sbc-setting-row"><label for="sbc_filter_${key}">${systemFilters[key].label}</label><label class="sbc-switch"><input type="checkbox" id="sbc_filter_${key}"><span class="sbc-slider"></span></label></div>`).join("")} </div> <hr class="sbc-divider"> <div class="sbc-section"> <h2 class="sbc-section-header">Custom Filters</h2> <div class="sbc-form-group"> <div class="sbc-setting-row"> <label for="sbc-block-users-switch">Block by User ID</label> <label class="sbc-switch"><input type="checkbox" id="sbc-block-users-switch"><span class="sbc-slider"></span></label> </div> <textarea id="sbc-blocked-user-ids" placeholder=""></textarea> </div> </div> </div> </div>`; document.body.appendChild(uiWrapper); const elements = { enabledSwitch: document.getElementById('sbc-enabled-switch'), hideAllUsersSwitch: document.getElementById('sbc-hide-all-users-switch'), blockUsersSwitch: document.getElementById('sbc-block-users-switch'), blockedUserIDsArea: document.getElementById('sbc-blocked-user-ids'), contentContainer: document.getElementById('sbc-content'), closeBtn: document.getElementById('sbc-close-btn') }; const loadSettings = () => { const isEnabled = GM_getValue('sbc_enabled', true); elements.enabledSwitch.checked = isEnabled; // The content container itself is no longer grayed out, only its child sections const sections = elements.contentContainer.querySelectorAll('.sbc-section'); sections.forEach(section => { section.style.opacity = isEnabled ? '1' : '0.5'; section.style.pointerEvents = isEnabled ? 'auto' : 'none'; }); for (const key in systemFilters) { document.getElementById(`sbc_filter_${key}`).checked = GM_getValue(`sbc_filter_${key}`, true); } elements.hideAllUsersSwitch.checked = GM_getValue('sbc_hide_all_users', false); const blockUsersEnabled = GM_getValue('sbc_block_users_enabled', true); elements.blockUsersSwitch.checked = blockUsersEnabled; elements.blockedUserIDsArea.disabled = !blockUsersEnabled; elements.blockedUserIDsArea.value = GM_getValue('sbc_blocked_user_ids', []).join('\n'); }; elements.enabledSwitch.addEventListener('change', () => { const isEnabled = elements.enabledSwitch.checked; GM_setValue('sbc_enabled', isEnabled); const sections = elements.contentContainer.querySelectorAll('.sbc-section'); sections.forEach(section => { section.style.opacity = isEnabled ? '1' : '0.5'; section.style.pointerEvents = isEnabled ? 'auto' : 'none'; }); checkShoutbox(); }); for (const key in systemFilters) { document.getElementById(`sbc_filter_${key}`).addEventListener('change', (e) => { GM_setValue(`sbc_filter_${key}`, e.target.checked); checkShoutbox(); }); } elements.hideAllUsersSwitch.addEventListener('change', (e) => { GM_setValue('sbc_hide_all_users', e.target.checked); checkShoutbox(); }); elements.blockUsersSwitch.addEventListener('change', (e) => { const isChecked = e.target.checked; GM_setValue('sbc_block_users_enabled', isChecked); elements.blockedUserIDsArea.disabled = !isChecked; checkShoutbox(); }); elements.blockedUserIDsArea.addEventListener('input', () => { GM_setValue('sbc_blocked_user_ids', elements.blockedUserIDsArea.value.split('\n').map(u => u.trim())); checkShoutbox(); }); elements.closeBtn.addEventListener('click', () => { uiWrapper.style.display = 'none'; }); uiWrapper.addEventListener('click', (e) => { if (e.target.id === 'sbc-modal-wrapper') { uiWrapper.style.display = 'none'; } }); loadSettings(); return { uiWrapper, loadSettings }; } function addSettingsButton() { const { uiWrapper, loadSettings } = createSettingsUI(); const titleElement = document.querySelector('#shoutbox-container .content-title h6.left'); if (titleElement && !document.querySelector("#sbc-settings-btn")) { const btn = document.createElement("div"); btn.id = "sbc-settings-btn"; btn.title = "Shoutbox Cleaner Settings"; btn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path fill-rule="evenodd" d="M14.457 1.314a1.5 1.5 0 0 1 2.112 1.056l.106.425a1.5 1.5 0 0 0 1.341 1.033l.443.044a1.5 1.5 0 0 1 1.579 1.95l-.17.426a1.5 1.5 0 0 0 .618 1.51l.36.27a1.5 1.5 0 0 1 .18 2.23l-.282.376a1.5 1.5 0 0 0 0 1.732l.282.376a1.5 1.5 0 0 1-.18 2.23l-.36.27a1.5 1.5 0 0 0-.618 1.51l.17.426a1.5 1.5 0 0 1-1.58 1.95l-.443.044a1.5 1.5 0 0 0-1.34 1.033l-.107.425a1.5 1.5 0 0 1-2.112 1.056L9.6 22.32a1.5 1.5 0 0 0-1.2 0L3.957 23.686a1.5 1.5 0 0 1-2.112-1.056l-.106-.425a1.5 1.5 0 0 0-1.341-1.033l-.443-.044a1.5 1.5 0 0 1-1.579-1.95l.17-.426a1.5 1.5 0 0 0-.618-1.51l-.36-.27a1.5 1.5 0 0 1-.18-2.23l.282-.376a1.5 1.5 0 0 0 0-1.732l-.282-.376a1.5 1.5 0 0 1 .18-2.23l.36-.27a1.5 1.5 0 0 0 .618-1.51l-.17-.426A1.5 1.5 0 0 1 .71 3.91l.443-.044A1.5 1.5 0 0 0 2.494 2.83l.107-.425a1.5 1.5 0 0 1 2.112-1.056L9.6 1.68a1.5 1.5 0 0 0 1.2 0l3.657-1.424ZM9.25 12.5a.75.75 0 0 0 0 1.5h10.5a.75.75 0 0 0 0-1.5H9.25Z" clip-rule="evenodd" /></svg>`; btn.addEventListener("click", (e) => { e.stopPropagation(); loadSettings(); uiWrapper.style.display = "flex"; }); titleElement.style.display = 'flex'; titleElement.style.alignItems = 'center'; titleElement.appendChild(btn); } } GM_addStyle(` #sbc-modal-wrapper { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; position: fixed; z-index: 9998; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.6); display: none; justify-content: center; align-items: center; backdrop-filter: blur(4px); } #sbc-container { background-color: #2c2c2c; color: #e0e0e0; border: 1px solid #4a4a4a; border-radius: 16px; width: 90%; max-width: 420px; box-shadow: 0 10px 30px rgba(0,0,0,0.5); display: flex; flex-direction: column; max-height: 90vh; } #sbc-header { padding: 24px; text-align: center; position: relative; flex-shrink: 0; } #sbc-header h1 { font-size: 24px; font-weight: 700; color: #fff; margin: 0 0 8px 0; } #sbc-header p { font-size: 14px; color: #a0a0a0; margin: 0; } #sbc-close-btn { position: absolute; top: 8px; right: 12px; border: none; background: none; color: #888; cursor: pointer; font-size: 28px; font-weight: bold; transition: color .2s; padding: 4px; line-height: 1; } #sbc-close-btn:hover { color: #fff; } #sbc-content { padding: 24px; overflow-y: auto; } .sbc-section { transition: opacity 0.3s ease; } .sbc-form-group { margin-bottom: 20px; } #sbc-content label { font-weight: 500; color: #CFCFCF; font-size: 14px; } .sbc-setting-row > label:first-child { flex-grow: 1; } textarea { width: 100%; height: 100px; resize: vertical; background-color: #202020; border: 1px solid #555; border-radius: 8px; padding: 10px; font-size: 14px; box-sizing: border-box; margin-top: 8px; transition: opacity 0.3s; } textarea:disabled { opacity: 0.5; cursor: not-allowed; } textarea:focus { outline: none; border-color: #888; } .sbc-section-header { font-size: 12px; text-transform: uppercase; color: #888; margin: 0 0 16px 0; letter-spacing: 0.5px; } .sbc-divider { border: none; border-top: 1px solid #444; margin: 20px 0; } .sbc-setting-row { display: flex; justify-content: space-between; align-items: center; padding: 4px 0; } .sbc-master-switch { padding-bottom: 0; } .sbc-master-switch label:first-child { font-size: 16px; font-weight: 600; color: #fff; } .sbc-switch { position: relative; display: inline-block; width: 44px; height: 24px; flex-shrink: 0; cursor: pointer; } .sbc-switch input { opacity: 0; width: 0; height: 0; } .sbc-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #555; transition: .4s; border-radius: 24px; } .sbc-slider:before { position: absolute; content: ""; height: 18px; width: 18px; left: 3px; bottom: 3px; background-color: white; transition: .4s; border-radius: 50%; } input:checked + .sbc-slider { background-color: #14a76c; } input:checked + .sbc-slider:before { transform: translateX(20px); } #sbc-settings-btn { cursor: pointer; margin-left: 10px; display: inline-flex; align-items: center; color: #9e9e9e; transition: color .2s ease; } #sbc-settings-btn:hover { color: #fff; } `); window.addEventListener('load', () => { addSettingsButton(); const shoutContainer = document.querySelector("#shouts-container"); if (shoutContainer) { const observer = new MutationObserver(checkShoutbox); observer.observe(shoutContainer, { childList: true, subtree: true }); checkShoutbox(); } else { let retries = 0; const fallbackInterval = setInterval(() => { const dynamicShoutContainer = document.querySelector("#shouts-container"); if (dynamicShoutContainer) { clearInterval(fallbackInterval); const observer = new MutationObserver(checkShoutbox); observer.observe(dynamicShoutContainer, { childList: true, subtree: true }); checkShoutbox(); } retries++; if (retries > 20) { clearInterval(fallbackInterval); } }, 500); } }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址