您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Checks if a user is banned on Bitcointalk.
当前为
// ==UserScript== // @name Bitcointalk Banned Users Checker // @namespace http://tampermonkey.net/ // @version 1.1 // @description Checks if a user is banned on Bitcointalk. // @author promise444c5 // @match https://bitcointalk.org/index.php?action=profile* // @match https://bitcointalk.org/index.php?topic=* // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @connect loyce.club // ==/UserScript== (function () { "use strict"; const BANNED_LIST_URL = "https://loyce.club/bans/usernames.txt"; const CACHE_KEY_DATA = "bannedUsersData"; const CACHE_KEY_TIMESTAMP = "bannedUsersTimestamp"; const CACHE_DURATION_MS = 24 * 60 * 60 * 1000; // cache for 1 day (24 hours) let bannedUsers = []; let scriptError = false; function parseBannedUsers(text) { const users = []; if (!text) return users; text.split("\n").forEach((line) => { const trimmedLine = line.trim(); if (trimmedLine) { const parts = trimmedLine.split(":"); if (parts.length === 2 && parts[0] && parts[1]) { users.push({ username: parts[1].trim(), userId: parts[0].trim() }); } else { console.warn( `Bitcointalk Ban Checker: Skipping malformed line: ${trimmedLine}` ); } } }); return users; } function applyBan() { if (scriptError || bannedUsers.length === 0) { console.log( "Bitcointalk Ban Checker: Skipping application due to error or empty list." ); return; } console.log( `Bitcointalk Ban Checker: Applying Ban on ${bannedUsers.length} banned users.` ); const currentUrl = window.location.href; const isProfilePage = currentUrl.includes("action=profile"); const isThreadPage = currentUrl.includes("topic="); // Add CSS style to the page const style = document.createElement("style"); style.textContent = ` .banned-user-text { text-decoration: line-through; color: red; } .banned-label { background-color: red; color: white; font-size: 10px; padding: 1px 3px; border-radius: 3px; margin-left: 5px; font-weight: bold; display: inline-block; vertical-align: middle; } `; document.head.appendChild(style); if (isProfilePage) { console.log("Bitcointalk Ban Checker: Running on profile page."); let profileUsernameElement = null; // Find the 'Name:' cell and get the next sibling cell which contains the username document.querySelectorAll("td.windowbg table td").forEach((td) => { const boldElement = td.querySelector("b"); if (boldElement && boldElement.textContent.trim() === "Name:") { profileUsernameElement = td.nextElementSibling; console.log( "Bitcointalk Ban Checker: Found potential username TD element." ); } }); if (profileUsernameElement) { let profileUsername = profileUsernameElement.textContent.trim(); console.log( `Bitcointalk Ban Checker: Checking profile username: ${profileUsername}` ); // Check if the username exists in the bannedUsers array const isBanned = bannedUsers.find( (user) => user.username === profileUsername ); if (isBanned) { let banMessage = `User ${profileUsername} is listed as banned.`; // Create and insert the ban status message below the username row let banStatusElement = document.createElement("div"); banStatusElement.style.color = "red"; banStatusElement.style.fontWeight = "bold"; banStatusElement.style.marginTop = "5px"; banStatusElement.textContent = banMessage; let usernameRow = profileUsernameElement.closest("tr"); if (usernameRow && usernameRow.parentNode) { let newRow = document.createElement("tr"); let newCell = document.createElement("td"); newCell.colSpan = 2; newCell.appendChild(banStatusElement); newRow.appendChild(newCell); usernameRow.parentNode.insertBefore( newRow, usernameRow.nextSibling ); console.log( "Bitcointalk Ban Checker: Inserted ban status message row." ); } else { console.warn( "Bitcointalk Ban Checker: Could not find username row to insert message." ); } // Check if label already exists to prevent duplicates on potential re-runs (though unlikely on profile) if (!profileUsernameElement.querySelector(".banned-label")) { const bannedLabel = document.createElement("span"); bannedLabel.textContent = "BANNED"; bannedLabel.classList.add("banned-label"); // Append the label to the TD containing the username profileUsernameElement.appendChild(bannedLabel); console.log( "Bitcointalk Ban Checker: Appended BANNED label to username TD." ); // The following lines attempt to wrap the text and re-append the label, profileUsernameElement.childNodes[0].nodeValue = profileUsernameElement.childNodes[0].nodeValue + " "; // Add space before label - This assumes first child is text node profileUsernameElement.innerHTML = `<span class="banned-user-text">${profileUsername}</span>`; // Wrap text - This overwrites existing content including the label just added profileUsernameElement.appendChild(bannedLabel); } } else { console.log( `Bitcointalk Ban Checker: User ${profileUsername} is not listed as banned.` ); } } else { console.log( "Bitcointalk Ban Checker: Could not find username element on profile page using the 'Name:' label." ); } } else if (isThreadPage) { console.log("Bitcointalk Ban Checker: Running on thread page."); function checkBannedUsersOnThread() { const postElements = document.querySelectorAll(".windowbg, .windowbg2"); let bannedFound = 0; postElements.forEach((post) => { const usernameElement = post.querySelector(".poster_info b a"); if (!usernameElement) return; // Check if style already applied to prevent redundant checks/updates if (usernameElement.style.textDecoration === "line-through") return; const username = usernameElement.textContent.trim(); // Check if the username exists in the bannedUsers array const isBanned = bannedUsers.find( (user) => user.username === username ); if (isBanned) { // Apply styles directly to the <a> tag usernameElement.style.textDecoration = "line-through"; usernameElement.style.color = "red"; // create a label next to the username link if (!usernameElement.parentNode.querySelector(".banned-label")) { const bannedLabel = document.createElement("span"); bannedLabel.textContent = "BANNED"; bannedLabel.classList.add("banned-label"); usernameElement.parentNode.insertBefore( bannedLabel, usernameElement.nextSibling ); bannedFound++; console.log( `Bitcointalk Ban Checker: Added BANNED label for ${username}.` ); } } }); if (bannedFound > 0) { console.log( `Bitcointalk Ban Checker: Found ${bannedFound} banned occurence` ); } } // Initial check checkBannedUsersOnThread(); } } /* ** Fetch and cache list, ** Used in the main script execution */ const fetchAndCacheList = () => { console.log("Bitcointalk Ban Checker: Fetching fresh banned users list..."); //Modified header const reqHeader = { "User-Agent": "UserScript/1.0", Accept: "text/plain", "Accept-Language": "en", Referer: "", }; GM_xmlhttpRequest({ method: "GET", url: BANNED_LIST_URL, headers: reqHeader, timeout: 5000, // 5 seconds timeout onload: (response) => { if (response.status >= 200 && response.status < 300) { const fetchedText = response.responseText; bannedUsers = parseBannedUsers(fetchedText); GM_setValue(CACHE_KEY_DATA, fetchedText); // Store raw text GM_setValue(CACHE_KEY_TIMESTAMP, Date.now()); console.log( `Bitcointalk Ban Checker: Successfully fetched and cached ${bannedUsers.length} users.` ); applyBan(); } else { console.error( `Bitcointalk Ban Checker: Failed to fetch list. Status: ${response.status}` ); scriptError = true; // use stale cache if available? applyBan(); } }, onerror: function (error) { console.error( "Bitcointalk Ban Checker: Network error fetching list.", error ); scriptError = true; }, }); }; /* --- Main Script Execution ---*/ const cachedTimestamp = GM_getValue(CACHE_KEY_TIMESTAMP, 0); const cachedData = GM_getValue(CACHE_KEY_DATA, null); const now = Date.now(); if (cachedData && now - cachedTimestamp < CACHE_DURATION_MS) { console.log("Bitcointalk Ban Checker: Using cached banned users list."); bannedUsers = parseBannedUsers(cachedData); applyBan(); } else { if (cachedData) { console.log("Bitcointalk Ban Checker: Cache expired, fetching new list."); // Use stale data immediately while fetching in background bannedUsers = parseBannedUsers(cachedData); applyBan(); fetchAndCacheList(); // Fetch new list in background } else { console.log("Bitcointalk Ban Checker: No cache found, fetching list."); fetchAndCacheList(); // Fetch list } } })();