您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Dynamically numbers duplicate OC roles based on slot order
当前为
- // ==UserScript==
- // @name OC Role Display
- // @namespace http://tampermonkey.net/
- // @version 1.2.0
- // @description Dynamically numbers duplicate OC roles based on slot order
- // @author Allenone [2033011]
- // @match https://www.torn.com/factions.php?step=your*
- // @icon https://www.google.com/s2/favicons?sz=64&domain=torn.com
- // @grant GM_info
- // @license MIT
- // ==/UserScript==
- (async function() {
- 'use strict';
- let globalObserver = null;
- let processing = false;
- const roleMappings = {};
- const debounceDelay = 200;
- const requestIdleCallback = window.requestIdleCallback || function(callback) {
- return setTimeout(callback, 200);
- };
- function processScenario(element) {
- const ocName = element.querySelector('.panelTitle___aoGuV')?.innerText.trim() || "Unknown";
- const slots = element.querySelectorAll('.wrapper___Lpz_D');
- if (!roleMappings[ocName]) {
- const slotsWithPosition = Array.from(slots).map(slot => {
- const slotFiberKey = Object.keys(slot).find(key => key.startsWith("__reactFiber$"));
- if (!slotFiberKey) return null;
- const fiberNode = slot[slotFiberKey];
- const positionKey = fiberNode.return.key.replace('slot-', '');
- const positionNumber = parseInt(positionKey.match(/P(\d+)/)?.[1] || 0, 10);
- return { slot, positionNumber };
- }).filter(Boolean);
- slotsWithPosition.sort((a, b) => a.positionNumber - b.positionNumber);
- const originalNames = slotsWithPosition.map(({ slot }) => {
- return slot.querySelector('.title___UqFNy')?.innerText.trim() || "Unknown";
- });
- const frequencyMap = originalNames.reduce((acc, name) => {
- acc[name] = (acc[name] || 0) + 1;
- return acc;
- }, {});
- const displayNames = [];
- const countTracker = {};
- originalNames.forEach(name => {
- if (frequencyMap[name] > 1) {
- countTracker[name] = (countTracker[name] || 0) + 1;
- displayNames.push(`${name} ${countTracker[name]}`);
- } else {
- displayNames.push(name);
- }
- });
- roleMappings[ocName] = displayNames;
- }
- slots.forEach(slot => {
- const slotFiberKey = Object.keys(slot).find(key => key.startsWith("__reactFiber$"));
- if (!slotFiberKey) return;
- const fiberNode = slot[slotFiberKey];
- const positionKey = fiberNode.return.key.replace('slot-', '');
- const positionNumber = parseInt(positionKey.match(/P(\d+)/)?.[1] || 0, 10);
- const roleIndex = positionNumber - 1;
- const displayName = roleMappings[ocName][roleIndex];
- const roleElement = slot.querySelector('.title___UqFNy');
- if (displayName && roleElement && roleElement.innerText !== displayName) {
- roleElement.innerText = displayName;
- }
- });
- }
- function doOnHashChange() {
- if (processing) return;
- processing = true;
- requestIdleCallback(() => {
- try {
- const ocElements = document.querySelectorAll('.wrapper___U2Ap7:not(.role-processed)');
- ocElements.forEach(element => {
- element.classList.add('role-processed');
- processScenario(element);
- });
- } finally {
- processing = false;
- }
- });
- }
- function observeButtonContainer() {
- let buttonContainer = document.querySelector('.buttonsContainer___aClaa');
- if (buttonContainer) {
- buttonContainer.addEventListener('click', () => {
- document.querySelectorAll('.wrapper___U2Ap7').forEach(el => {
- el.classList.remove('role-processed');
- });
- doOnHashChange();
- });
- } else {
- setTimeout(observeButtonContainer, 500);
- }
- }
- function setupHashChangeListener() {
- window.addEventListener('hashchange', () => {
- document.querySelectorAll('.wrapper___U2Ap7.role-processed').forEach(el => {
- el.classList.remove('role-processed');
- });
- doOnHashChange();
- });
- }
- function initializeScript() {
- if (globalObserver) globalObserver.disconnect();
- const targetNode = document.querySelector('#factionCrimes-root') || document.body;
- globalObserver = new MutationObserver(debounce(() => {
- if (!document.querySelector('.wrapper___U2Ap7')) return;
- doOnHashChange();
- }, debounceDelay));
- globalObserver.observe(targetNode, {
- childList: true,
- subtree: true,
- attributes: false,
- characterData: false
- });
- doOnHashChange();
- observeButtonContainer();
- setupHashChangeListener();
- }
- function debounce(func, wait) {
- let timeout;
- return function(...args) {
- clearTimeout(timeout);
- timeout = setTimeout(() => func.apply(this, args), wait);
- };
- }
- if (document.readyState === 'complete') {
- initializeScript();
- } else {
- window.addEventListener('load', initializeScript);
- }
- })();