whynotsoido / Дубликатор имен

// ==UserScript==
// @name         Дубликатор имен
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  описание
// @author       whynotsoido
// @match        https://catwar.su/cw3*
// @match        https://catwar.net/cw3*
// @grant        none
// @license      MIT
// @iconURL      https://images.vfl.ru/ii/1503327298/d171c5d8/18322770_m.png
// ==/UserScript==

(function() {
    'use strict';

    // Карта запахов
    const odorMap = {
        1: ['#e5871a', '⚡'],
        2: ['#10d9ec', '💨'],
        3: ['#142fd3', '🌊'],
        4: ['#671bd5', '✨'],
        6: ['#21130d', ''],
        9: ['#21130d', ''],
        77: ['#21130d', 'Бот'],
        11: ['#1c3445', '⛰️'],
        19: ['#474b60', '❄️'],
        28: ['#f4983c', '🏡']
    };

    let cellCache = new Map();

    function getOdorInfo(cell) {
        const odorImg = cell.querySelector('img[src*="odoroj/"]');
        if (!odorImg) return null;

        const match = odorImg.src.match(/odoroj\/(\d+)\./);
        return match ? odorMap[parseInt(match[1])] || ['', ''] : null;
    }

    function getPlayerName(cell) {
        const catLink = cell.querySelector('a[href^="/cat"]');
        return catLink ? catLink.textContent.trim() : null;
    }

    function getOnlineStatusElement(cell) {
        const onlineSpan = cell.querySelector('span.online');
        if (!onlineSpan) return null;

        return {
            element: onlineSpan.cloneNode(true),
            text: onlineSpan.textContent.trim(),
            color: getComputedStyle(onlineSpan).color
        };
    }

    function getCellKey(cell) {
        const name = getPlayerName(cell);
        const statusElement = getOnlineStatusElement(cell);
        const statusText = statusElement ? statusElement.text : '';
        const odorImg = cell.querySelector('img[src*="odoroj/"]');
        const odorSrc = odorImg ? odorImg.src : '';

        return `${name}|${statusText}|${odorSrc}`;
    }

    function updatePlayerInfo() {
        const cells = document.querySelectorAll('#cages td');
        let needsUpdate = false;

        cells.forEach((cell, index) => {
            const currentKey = getCellKey(cell);
            const cachedKey = cellCache.get(index);

            if (currentKey !== cachedKey) {
                cellCache.set(index, currentKey);
                needsUpdate = true;

                const oldContainer = cell.querySelector('.cw-player-info');
                if (oldContainer) {
                    oldContainer.remove();
                }

                const playerName = getPlayerName(cell);
                const statusElement = getOnlineStatusElement(cell);
                const odorInfo = getOdorInfo(cell);

                if (playerName && statusElement) {
                    createPlayerInfo(cell, playerName, statusElement, odorInfo);
                }
            }
        });

        return needsUpdate;
    }

    function createPlayerInfo(cell, playerName, statusElement, odorInfo) {
        const container = document.createElement('div');
        container.className = 'cw-player-info';

        // стили
        container.style.cssText = `
            position: absolute;
            bottom: 8px;
            left: 50%;
            transform: translateX(-50%);
            text-align: center;
            z-index: 100;
            background: rgba(255, 255, 255, 0.95);
            padding: 4px 8px;
            border-radius: 10px;
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
            border: 1px solid #ddd;
            font-family: Arial, sans-serif;
            min-width: 70px;
            pointer-events: none;
            transition: opacity 0.3s ease;
        `;

        //  имя
        const nameDiv = document.createElement('div');
        nameDiv.style.cssText = `
            font-size: 10px;
            font-weight: bold;
            margin-bottom: 2px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            max-width: 150px;
            pointer-events: none;
        `;

        if (odorInfo && odorInfo[0]) {
            nameDiv.style.color = odorInfo[0];
        }

        let nameText = playerName;
        if (odorInfo && odorInfo[1]) {
            nameText += ` [${odorInfo[1]}]`;
        }
        nameDiv.textContent = nameText;

        const statusDiv = document.createElement('div');
        statusDiv.style.cssText = `
            font-size: 11px;
            font-weight: bold;
            pointer-events: none;
        `;

        statusDiv.style.color = statusElement.color;
        statusDiv.appendChild(statusElement.element);

        container.appendChild(nameDiv);
        container.appendChild(statusDiv);


        cell.addEventListener('mouseenter', function() {
            container.style.opacity = '0'; // полупрозрачн
        });

        cell.addEventListener('mouseleave', function() {
            container.style.opacity = '1'; // непрозрачность
        });

        if (getComputedStyle(cell).position === 'static') {
            cell.style.position = 'relative';
        }

        cell.appendChild(container);
    }

    function init() {
        setTimeout(() => {
            const cells = document.querySelectorAll('#cages td');
            cells.forEach((cell, index) => {
                cellCache.set(index, getCellKey(cell));

                const playerName = getPlayerName(cell);
                const statusElement = getOnlineStatusElement(cell);
                const odorInfo = getOdorInfo(cell);

                if (playerName && statusElement) {
                    createPlayerInfo(cell, playerName, statusElement, odorInfo);
                }
            });

            setInterval(() => {
                updatePlayerInfo();
            }, 100);

        }, 100);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            setTimeout(init, 500);
        });
    } else {
        setTimeout(init, 500);
    }

})();