Torn User ID Extractor

Replace status icon with checkbox and extract user IDs

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name         Torn User ID Extractor
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Replace status icon with checkbox and extract user IDs
// @match        https://www.torn.com/page.php?sid=UserList*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_setClipboard
// ==/UserScript==

(function() {
    'use strict';

    let cachedIDs = GM_getValue('cachedUserIDs', []);

    const HALLOWEEN_COLORS = {
        orange: '#ff6b1a',
        darkOrange: '#cc4c00',
        purple: '#6b1aff',
        darkPurple: '#4c00cc',
        green: '#1aff6b',
        black: '#333333',
    };

    function addCheckboxes() {
        // Find all status icons and replace them
        const statusIcons = document.querySelectorAll('.iconShow[title*="Offline"], .iconShow[title*="Online"], .iconShow[title*="Idle"]');
        statusIcons.forEach(icon => {
            if (!icon.parentElement.querySelector('.user-checkbox')) {
                // Create checkbox
                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.checked = true;
                checkbox.className = 'user-checkbox';
                checkbox.style.cssText = `
                    cursor: pointer;
                    margin: 0;
                    vertical-align: middle;
                `;

                // Replace icon with checkbox
                icon.parentElement.replaceChild(checkbox, icon);
            }
        });
    }

    function extractUserIDs() {
        const userList = document.querySelector('.user-info-list-wrap.bottom-round.cont-gray');
        if (!userList) {
            console.log('User list not found');
            return;
        }

        const userItems = document.querySelectorAll('li[class*="user"]');
        const newIDs = Array.from(userItems)
            .filter(item => {
                const checkbox = item.querySelector('.user-checkbox');
                return checkbox && checkbox.checked;
            })
            .map(item => {
                const match = item.className.match(/user(\d+)/);
                return match ? match[1] : null;
            })
            .filter(id => id !== null);

        // Add new IDs to cache, avoiding duplicates and limiting to 100
        newIDs.forEach(id => {
            if (!cachedIDs.includes(id) && cachedIDs.length < 100) {
                cachedIDs.push(id);
            }
        });

        // Save updated cache
        GM_setValue('cachedUserIDs', cachedIDs);

        // Update counter
        updateCounter();

        // Create a floating message
        showMessage(`${newIDs.length} user IDs extracted. Total cached: ${cachedIDs.length}`);
    }

    function formatAndCopyIDs() {
        const formattedData = {
            target_backup: cachedIDs.slice(0, 100).map(id => ({
                id: parseInt(id),
                notes: "",
                notes_color: ""
            }))
        };

        const jsonString = JSON.stringify(formattedData);
        GM_setClipboard(jsonString);
        console.log('Formatted user data copied to clipboard:', jsonString);

        showMessage(`${formattedData.target_backup.length} user IDs formatted and copied to clipboard!`);
    }

    function showMessage(text) {
        const message = document.createElement('div');
        message.textContent = text;
        message.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background-color: ${HALLOWEEN_COLORS.purple};
            color: black;
            padding: 15px;
            border-radius: 5px;
            z-index: 9999;
            box-shadow: 0 0 10px ${HALLOWEEN_COLORS.orange};
            animation: glow 1s ease-in-out infinite alternate;
        `;

        // Add glow animation
        const style = document.createElement('style');
        style.textContent = `
            @keyframes glow {
                from {
                    box-shadow: 0 0 5px ${HALLOWEEN_COLORS.orange},
                               0 0 10px ${HALLOWEEN_COLORS.orange};
                }
                to {
                    box-shadow: 0 0 10px ${HALLOWEEN_COLORS.purple},
                               0 0 20px ${HALLOWEEN_COLORS.purple};
                }
            }
        `;
        document.head.appendChild(style);

        document.body.appendChild(message);
        setTimeout(() => {
            document.body.removeChild(message);
        }, 3000);
    }

    function updateCounter() {
        counterSpan.textContent = `${cachedIDs.length}/100`;
    }

    function clearCache() {
        cachedIDs = [];
        GM_setValue('cachedUserIDs', cachedIDs);
        updateCounter();
        showMessage("Cache cleared!");
    }

    // Create UI elements with consistent width
    const buttonContainer = document.createElement('div');
    buttonContainer.style.cssText = `
        position: fixed;
        top: 10px;
        right: 10px;
        z-index: 9999;
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        gap: 10px;
    `;

    const baseButtonStyle = `
        padding: 10px;
        width: 200px;
        color: black;
        border: none;
        border-radius: 5px;
        cursor: pointer;
        font-weight: bold;
        transition: all 0.3s ease;
        text-align: center;
        text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
        box-shadow: 0 2px 4px rgba(0,0,0,0.2);
    `;

    const extractButton = document.createElement('button');
    extractButton.textContent = 'Extract Selected User IDs';
    extractButton.style.cssText = `
        ${baseButtonStyle}
        background-color: ${HALLOWEEN_COLORS.orange};
    `;
    extractButton.addEventListener('mouseover', () => {
        extractButton.style.backgroundColor = HALLOWEEN_COLORS.darkOrange;
        extractButton.style.transform = 'translateY(-2px)';
    });
    extractButton.addEventListener('mouseout', () => {
        extractButton.style.backgroundColor = HALLOWEEN_COLORS.orange;
        extractButton.style.transform = 'translateY(0)';
    });
    extractButton.addEventListener('click', extractUserIDs);

    const copyButton = document.createElement('button');
    copyButton.textContent = 'Format and Copy IDs';
    copyButton.style.cssText = `
        ${baseButtonStyle}
        background-color: ${HALLOWEEN_COLORS.purple};
    `;
    copyButton.addEventListener('mouseover', () => {
        copyButton.style.backgroundColor = HALLOWEEN_COLORS.darkPurple;
        copyButton.style.transform = 'translateY(-2px)';
    });
    copyButton.addEventListener('mouseout', () => {
        copyButton.style.backgroundColor = HALLOWEEN_COLORS.purple;
        copyButton.style.transform = 'translateY(0)';
    });
    copyButton.addEventListener('click', formatAndCopyIDs);

    const clearButton = document.createElement('button');
    clearButton.textContent = 'Clear Cache';
    clearButton.style.cssText = `
        ${baseButtonStyle}
        background-color: ${HALLOWEEN_COLORS.green};
    `;
    clearButton.addEventListener('mouseover', () => {
        clearButton.style.backgroundColor = '#008c45';
        clearButton.style.transform = 'translateY(-2px)';
    });
    clearButton.addEventListener('mouseout', () => {
        clearButton.style.backgroundColor = HALLOWEEN_COLORS.green;
        clearButton.style.transform = 'translateY(0)';
    });
    clearButton.addEventListener('click', clearCache);

    const counterSpan = document.createElement('span');
    counterSpan.style.cssText = `
        width: 180px;
        color: white;
        background-color: ${HALLOWEEN_COLORS.black};
        padding: 10px;
        border-radius: 5px;
        text-align: center;
        font-weight: bold;
        box-shadow: 0 2px 4px rgba(0,0,0,0.2);
    `;
    updateCounter();

    buttonContainer.appendChild(extractButton);
    buttonContainer.appendChild(copyButton);
    buttonContainer.appendChild(clearButton);
    buttonContainer.appendChild(counterSpan);
    document.body.appendChild(buttonContainer);

    // Add Halloween style to checkboxes
    const checkboxStyle = document.createElement('style');
    checkboxStyle.textContent = `
        .user-checkbox {
            accent-color: ${HALLOWEEN_COLORS.orange} !important;
            width: 16px;
            height: 16px;
        }
        .user-checkbox:hover {
            transform: scale(1.1);
            transition: transform 0.2s ease;
        }
    `;
    document.head.appendChild(checkboxStyle);

    // Initial setup
    addCheckboxes();

    // Add mutation observer to handle dynamically loaded users
    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            if (mutation.addedNodes && mutation.addedNodes.length > 0) {
                addCheckboxes();
            }
        });
    });

    const userList = document.querySelector('.user-info-list-wrap.bottom-round.cont-gray');
    if (userList) {
        observer.observe(userList, { childList: true, subtree: true });
    }
})();