OC Role Display

Shows role positions

目前為 2025-02-13 提交的版本,檢視 最新版本

// ==UserScript==
// @name         OC Role Display
// @namespace    http://tampermonkey.net/
// @version      1.0.0
// @description  Shows role positions
// @author       Allenone [2033011]
// @match        https://www.torn.com/factions.php?step=your*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=torn.com
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    let buttonObserver;
    let wrapperObserver;

    // Run on page load or hash change
    function doOnHashChange() {
        const ocElements = document.querySelectorAll('.wrapper___U2Ap7');
        if (ocElements.length === 0) return; // Prevent running on empty state
        console.log("Updating roles...", ocElements);

        for (let element of ocElements) {
            const reactFiberKey = Object.keys(element).find(key => key.startsWith("__reactFiber$"));
            if (!reactFiberKey) continue;

            let ocName = element.querySelector('.panelTitle___aoGuV')?.innerText || "Unknown";
            let slots = element.querySelectorAll('.wrapper___Lpz_D');

            for (let slot of slots) {
                const slotFiberKey = Object.keys(slot).find(key => key.startsWith("__reactFiber$"));
                if (!slotFiberKey) continue;

                let roleName = slot.querySelector('.title___UqFNy');

                try {
                    let fiberNode = slot[slotFiberKey];
                    let key = fiberNode.return.key;

                    let roleText = getOCRoles(ocName, key);
                    if (roleText && roleName.innerText !== roleText) {
                        roleName.innerText = roleText;
                        console.log(`Updated ${key} in ${ocName} -> ${roleText}`);
                    }
                } catch (error) {
                    console.error("Error accessing React properties:", error);
                }
            }
        }
    }

    function getOCRoles(name, position) {
        switch (name) {
            case 'Blast From The Past':
                switch (position) {
                    case 'slot-P1': return 'Picklock 1';
                    case 'slot-P6': return 'Picklock 2';
                    default: return;
                }
            case 'Honey Trap':
                switch (position) {
                    case 'slot-P2': return 'Muscle 1';
                    case 'slot-P3': return 'Muscle 2';
                    default: return;
                }
            case 'Stage Fright':
                switch (position) {
                    case 'slot-P2': return 'Muscle 1';
                    case 'slot-P3': return 'Muscle 2';
                    case 'slot-P4': return 'Muscle 3';
                    default: return;
                }
            case 'Break The Bank':
                switch (position) {
                    case 'slot-P2': return 'Muscle 1';
                    case 'slot-P3': return 'Muscle 2';
                    case 'slot-P4': return 'Thief 1';
                    case 'slot-P5': return 'Muscle 3';
                    case 'slot-P6': return 'Thief 2';
                    default: return;
                }
            case 'Snow Blind':
                switch (position) {
                    case 'slot-P3': return 'Muscle 1';
                    case 'slot-P4': return 'Muscle 2';
                    default: return;
                }
            case 'Smoke and Wing Mirrors':
                switch (position) {
                    case 'slot-P3': return 'Hustler 1';
                    case 'slot-P4': return 'Hustler 2';
                    default: return;
                }
            case 'Cash Me If You Can':
                switch (position) {
                    case 'slot-P1': return 'Thief 1';
                    case 'slot-P2': return 'Thief 2';
                    default: return;
                }
            case 'Mob Mentality':
                switch (position) {
                    case 'slot-P1': return 'Looter 1';
                    case 'slot-P2': return 'Looter 2';
                    case 'slot-P3': return 'Looter 3';
                    case 'slot-P4': return 'Looter 4';
                    default: return;
                }
            default:
                return;
        }
    }

    function observeButtonContainer() {
        let buttonContainer = document.querySelector('.buttonsContainer___aClaa');
        if (buttonContainer) {
            buttonContainer.addEventListener('click', () => {
                console.log("Button clicked in buttonsContainer. Waiting for content reload...");

                if (wrapperObserver) wrapperObserver.disconnect();

                waitForElementsToReload('.wrapper___U2Ap7').then(() => {
                    console.log("New elements detected. Refreshing roles...");
                    doOnHashChange();
                });
            });
        } else {
            console.warn("buttonsContainer not found. Retrying in 500ms...");
            setTimeout(observeButtonContainer, 500);
        }
    }

    function waitForElementsToReload(selector) {
        return new Promise(resolve => {
            let checkInterval = setInterval(() => {
                if (!document.querySelector(selector)) {
                    clearInterval(checkInterval);

                    wrapperObserver = new MutationObserver(() => {
                        if (document.querySelectorAll(selector).length > 0) {
                            clearInterval(checkInterval);
                            resolve();
                            wrapperObserver.disconnect();
                        }
                    });

                    wrapperObserver.observe(document.body, { childList: true, subtree: true });
                }
            }, 100); // Check every 100ms if elements have disappeared
        });
    }

    // Ensure page load is complete before starting
    window.addEventListener('load', () => {
        console.log("Page loaded. Refreshing roles...");
        doOnHashChange(); // Run once immediately after page load

        // Start observing button container
        observeButtonContainer();

        // Start observing hash change
        window.addEventListener('hashchange', () => {
            console.log("Hash changed. Refreshing roles...");
            waitForElementsToReload('.wrapper___U2Ap7').then(() => {
                doOnHashChange();
            });
        });
    });

    // Reload after page is fully loaded, and ensure wrapper___U2Ap7 elements are visible.
    function waitForWrapperElements() {
        let wrapperElements = document.querySelectorAll('.wrapper___U2Ap7');
        if (wrapperElements.length > 0) {
            console.log("Initial wrapper elements found. Refreshing roles...");
            doOnHashChange();
        } else {
            setTimeout(waitForWrapperElements, 500); // Wait and check again
        }
    }

    // Initial check after page load
    waitForWrapperElements();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址