您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds "Hide" and "Unhide" buttons, filters trades, and tells you have hidden the user in the trade.
// ==UserScript== // @name Add Hide and Unhide Button with Trade Filter // @namespace http://tampermonkey.net/ // @version 1.0 // @description Adds "Hide" and "Unhide" buttons, filters trades, and tells you have hidden the user in the trade. // @author Grance [3487987] // @match *://*.torn.com/* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; // Utility to wait for an element to load function waitForElement(selector, callback, interval = 100, timeout = 10000) { const start = Date.now(); const check = setInterval(() => { const element = document.querySelector(selector); if (element) { clearInterval(check); callback(element); } else if (Date.now() - start > timeout) { clearInterval(check); console.error(`Timeout waiting for element: ${selector}`); } }, interval); } // Function to create the "Hide" button function createHideButton(userId) { const buttonsList = document.querySelector('.buttons-list'); if (!buttonsList || document.getElementById('button-hide')) return; // Prevent duplicates const hideButton = document.createElement('a'); hideButton.id = 'button-hide'; hideButton.href = '#'; hideButton.className = 'profile-button profile-button-hide clickable'; hideButton.setAttribute('aria-label', 'Hide'); hideButton.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" class="default___XXAGt profileButtonIcon svgShadowWhiteFilter___Nse17" fill="rgba(153, 153, 153, 0.4)" stroke="#d4d4d4" stroke-width="2" width="36" height="40" viewBox="0 0 46 46" style="display: block; margin: auto;"> <g transform="translate(1, 1)"> <circle cx="22" cy="25" r="20" fill="none" stroke="black" stroke-width="2"/> <line x1="12" y1="15" x2="32" y2="35" stroke="black" stroke-width="2"/> </g> </svg> `; // Add click event for hiding the user hideButton.addEventListener('click', (event) => { event.preventDefault(); const hiddenList = JSON.parse(localStorage.getItem('hiddenUsers')) || []; if (!hiddenList.includes(userId)) { hiddenList.push(userId); localStorage.setItem('hiddenUsers', JSON.stringify(hiddenList)); alert(`User ${userId} has been hidden.`); replaceWithUnhideButton(userId); // Replace the button with "Unhide" } }); return hideButton; } // Function to create the "Unhide" button function createUnhideButton(userId) { const buttonsList = document.querySelector('.buttons-list'); if (!buttonsList || document.getElementById('button-unhide')) return; // Prevent duplicates const unhideButton = document.createElement('a'); unhideButton.id = 'button-unhide'; unhideButton.href = '#'; unhideButton.className = 'profile-button profile-button-unhide clickable'; unhideButton.setAttribute('aria-label', 'Unhide'); unhideButton.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" class="default___XXAGt profileButtonIcon svgShadowWhiteFilter___Nse17" fill="rgba(153, 153, 153, 0.4)" stroke="#d4d4d4" stroke-width="2" width="40" height="45" viewBox="0 0 46 46" style="display: block; margin: auto;"> <g transform="translate(1, 1)"> <circle cx="22" cy="20" r="20" fill="none" stroke="black" stroke-width="2"/> <line x1="1" y1="20" x2="41" y2="20" stroke="black" stroke-width="2"/> <!-- Horizontal line --> </g> </svg> `; // Add click event for unhiding the user unhideButton.addEventListener('click', (event) => { event.preventDefault(); const hiddenList = JSON.parse(localStorage.getItem('hiddenUsers')) || []; const index = hiddenList.indexOf(userId); if (index !== -1) { hiddenList.splice(index, 1); localStorage.setItem('hiddenUsers', JSON.stringify(hiddenList)); alert(`User ${userId} has been unhidden.`); replaceWithHideButton(userId); // Replace the button with "Hide" } }); return unhideButton; } // Function to replace the button with "Unhide" function replaceWithUnhideButton(userId) { const buttonsList = document.querySelector('.buttons-list'); if (!buttonsList) return; const existingButton = document.getElementById('button-hide'); if (existingButton) { const unhideButton = createUnhideButton(userId); buttonsList.replaceChild(unhideButton, existingButton); } } // Function to replace the button with "Hide" function replaceWithHideButton(userId) { const buttonsList = document.querySelector('.buttons-list'); if (!buttonsList) return; const existingButton = document.getElementById('button-unhide'); if (existingButton) { const hideButton = createHideButton(userId); buttonsList.replaceChild(hideButton, existingButton); } } // Function to add the button to the profile page function addProfileButton() { waitForElement('.buttons-list', (buttonsList) => { // Extract user ID from the profile buttons const userId = buttonsList.querySelector('a')?.id.split('-')[2]; if (!userId) return; // Check if the user is in the hidden list const hiddenList = JSON.parse(localStorage.getItem('hiddenUsers')) || []; if (hiddenList.includes(userId)) { // Add "Unhide" button const unhideButton = createUnhideButton(userId); buttonsList.appendChild(unhideButton); } else { // Add "Hide" button const hideButton = createHideButton(userId); buttonsList.appendChild(hideButton); } }); } function checkHiddenInTrade() { const tradeHeader = document.querySelector('h4.left'); if (!tradeHeader || !tradeHeader.textContent.includes('Trade')) return; // Get user ID from the trade page const userLink = document.querySelector('a.t-blue.h'); const userId = userLink?.href.match(/XID=(\d+)/)?.[1]; if (!userId) return; // Check against the hidden list const hiddenList = JSON.parse(localStorage.getItem('hiddenUsers')) || []; if (hiddenList.includes(userId)) { // Show the warning message let warningMessage = document.getElementById('hidden-warning'); if (!warningMessage) { warningMessage = document.createElement('div'); warningMessage.id = 'hidden-warning'; warningMessage.style.color = 'red'; warningMessage.style.fontWeight = 'bold'; warningMessage.style.fontSize = '24px'; warningMessage.textContent = 'YOU HAVE HIDDEN THIS PERSON'; tradeHeader.parentNode.insertBefore(warningMessage, tradeHeader); } } } // Function to filter trades on the trade page function filterTrades() { waitForElement('.trades-cont.current', (tradeList) => { const hiddenList = JSON.parse(localStorage.getItem('hiddenUsers')) || []; const tradeItems = tradeList.querySelectorAll('li'); tradeItems.forEach((tradeItem) => { const userLink = tradeItem.querySelector('.namet a'); if (userLink) { const userId = userLink.href.split('XID=')[1]; if (hiddenList.includes(userId)) { tradeItem.style.display = 'none'; } } }); }); } // Run checks on initial load and dynamically when the DOM updates function init() { if (window.location.href.includes('trade.php#step')) { checkHiddenInTrade(); // Check for hidden users on the trade page } else if (window.location.href.includes('trade.php')) { filterTrades(); // Check for hidden users on the trade page } else if (window.location.href.includes('profiles.php')) { addProfileButton(); // Check for hidden users on the trade page } } // Observe page changes to re-run the script when navigating dynamically const observer = new MutationObserver(() => { init(); }); observer.observe(document.body, { childList: true, subtree: true }); // Run once on script load init(); })();