NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==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);
}
})();