您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A script that lets you add, store, and delete friends on Torn with custom descriptions.
当前为
// ==UserScript== // @name TORN Friend Extender // @namespace http://tampermonkey.net/ // @version 1.0.0 // @author Clyoth // @description A script that lets you add, store, and delete friends on Torn with custom descriptions. // @match https://www.torn.com/* // @icon https://play-lh.googleusercontent.com/BkaIDbibtUpGcziVQsgCya-eC7oxTUHL5G8m8v3XW3S11_-GZEItaxzeXxhKmoAiX8x6 // @license MIT // @grant none // ==/UserScript== (function () { const apiKey = 'INSERT_YOUR_API_KEY_HERE'; const FRIENDS_STORAGE_KEY = 'tornFriendList'; let addButtonAdded = false; const style = document.createElement('style'); style.textContent = ` .add-button { padding: 12px 20px; background-color: #3b3b3b; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 14px; transition: background-color 0.3s ease, transform 0.2s ease; margin-top: 4px; width: auto; text-align: center; } .add-button:hover { background-color: #5c5c5c; transform: scale(1.05); } #friendForm { padding: 20px; border-radius: 8px; margin-top: 10px; color: white; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); background-color: #2c2f33; } #friendForm h3 { margin-top:4px; } #friendDataForm input[type="text"] { width: 30%; padding: 8px; margin-top: 8px; border: 2px solid #555; border-radius: 5px; background-color: #444; color: white; font-size: 12px; } #friendDataForm label { font-weight: bold; display: block; margin-bottom: 4px; color: #d3d3d3; } #friendDataForm button { padding: 8px 16px; background-color: #3b3b3b; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 12px; margin-top: 10px; transition: background-color 0.3s ease; } #friendDataForm button:hover { background-color: #5c5c5c; } #friendDataForm #cancelForm { background-color: #8b0000; margin-left: 10px; } #friendDataForm #cancelForm:hover { background-color: #b22222; } `; document.head.appendChild(style); function loadFriends() { const storedFriends = localStorage.getItem(FRIENDS_STORAGE_KEY); return storedFriends ? JSON.parse(storedFriends) : []; } function saveFriends(friends) { localStorage.setItem(FRIENDS_STORAGE_KEY, JSON.stringify(friends)); } function createForm() { if (document.getElementById('friendForm')) return; const formHTML = ` <div id="friendForm" style="padding: 10px; background-color: #323233; border-radius: 5px; margin-top: 10px;"> <h3>Add Friend</h3> <form id="friendDataForm"> <label for="friendId">ID:</label> <input type="text" id="friendId" name="id" required /><br><br> <label for="friendDescription">Description:</label> <input type="text" id="friendDescription" name="description" maxlength="40"/><br><br> <button type="submit">Fetch and Add Friend</button> <button type="button" id="cancelForm">Cancel</button> </form> </div> `; const formContainer = document.createElement('div'); formContainer.innerHTML = formHTML; const paginationWrapper = document.querySelector('.pagination-wrapper'); if (paginationWrapper) { paginationWrapper.appendChild(formContainer); } else { console.error('pagination-wrapper not found.'); } document.getElementById('cancelForm').addEventListener('click', () => { formContainer.remove(); }); document.getElementById('friendDataForm').addEventListener('submit', async (event) => { event.preventDefault(); const friendId = document.getElementById('friendId').value; const description = document.getElementById('friendDescription').value || 'None'; const friendData = await fetchFriendData(friendId, description); if (friendData) { const friends = loadFriends(); friends.push(friendData); saveFriends(friends); addFriendToList(friendData); } formContainer.remove(); }); } async function fetchFriendData(id, description) { try { const response = await fetch(`https://api.torn.com/user/${id}?selections=profile&key=${apiKey}`); const data = await response.json(); if (data.error) { alert(`Error: ${data.error.code} - ${data.error.error}`); return null; } return { id: id, name: data.name, level: data.level, status: data.status.description, profileUrl: `/profiles.php?XID=${id}`, description: description }; } catch (error) { console.error("Failed to fetch friend data:", error); alert("Failed to fetch friend data. Please check the console for details."); return null; } } function addFriendButton() { if (addButtonAdded) return; const addButton = document.createElement('button'); addButton.textContent = 'Add Friend by ID'; addButton.addEventListener('click', createForm); addButton.classList.add('add-button'); const paginationWrapper = document.querySelector('.pagination-wrapper'); if (paginationWrapper && !paginationWrapper.contains(addButton)) { paginationWrapper.appendChild(addButton); addButtonAdded = true; } } function addFriendToList(friendData) { const targetUL = document.querySelector(".user-info-blacklist-wrap"); if (targetUL) { if (targetUL.querySelector(`[data-id="${friendData.id}"]`)) return; const newLI = document.createElement("li"); newLI.setAttribute('data-id', friendData.id); newLI.innerHTML = ` <div class="delete"> <i class="delete-user"></i> </div> <div class="acc-wrapper"> <div class="expander left"> <span class="honor-text-wrap blue big" style="display: block; text-align: center; width: 100%;"> <a href="${friendData.profileUrl}" title="${friendData.name} [${friendData.id}]" style="text-decoration: none; color:white;"> ${friendData.name} </a> </span> <div class="d-hide expand right"> <i class="collapse-arrow"></i> </div> </div> <div class="acc-body"> <div class="level left"> <span class="d-hide bold">Level:</span> ${friendData.level} </div> <div class="status left"> <span class="d-hide bold">Status:</span> <div class="status-description">${friendData.status}</div> </div> <div class="description"> <div class="left"></div> <div class="text left t-overflow">${friendData.description}</div> </div> </div> </div> `; targetUL.appendChild(newLI); const deleteButton = newLI.querySelector('.delete-user'); deleteButton.addEventListener('click', () => deleteFriend(friendData.id, newLI)); } } function deleteFriend(id, listItem) { listItem.remove(); const friends = loadFriends().filter(friend => friend.id !== id); saveFriends(friends); } function loadAndDisplayFriends() { const friends = loadFriends(); friends.forEach(friendData => { addFriendToList(friendData); }); } const observer = new MutationObserver(() => { if (document.querySelector('.pagination-wrapper')) { addFriendButton(); } if (document.querySelector('.user-info-blacklist-wrap')) { loadAndDisplayFriends(); } }); observer.observe(document.body, { childList: true, subtree: true }); })();