// ==UserScript==
// @name Really sympathies Full Stat
// @namespace http://tampermonkey.net/
// @version 3.8
// @description Добавляет отображение симпатий без розыгрышей через /, + отображает в профиле + отслеживает новые сообщения в темах + последние 7 дней + лайки и последние 7 дней
// @author Lotti, Punsh, eretly
// @match https://lolz.live/*
// @match https://lolz.guru/*
// @match https://zelenka.guru/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=lolz.live
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const html = document.createElement("div");
function formatNumber(num) {
num = Number(num);
if (isNaN(num)) return "0";
if (num < 10000) return num.toString();
return num.toString().replace(/\B(?=(\d{3})(?!\d))/g, " ");
}
function getBaseURL() {
return window.location.origin;
}
function shouldRunScript() {
const userCounters = document.querySelector('.userCounters');
if (userCounters) {
const hasThumbsUpIcon = userCounters.querySelector('.userCounterIcon.fa-thumbs-up');
if (hasThumbsUpIcon) return true;
}
const hasLikeIcon = document.querySelector('.like2Icon, .fa-thumbs-up');
return !!hasLikeIcon;
}
function updateUserSympathies(user) {
if (shouldRunScript()) return;
const link = user.querySelector("span a.username");
if (!link) return;
const userUrl = link.getAttribute("href");
fetch(`${getBaseURL()}/${userUrl}`).then(resul => resul.text().then(htmlText => {
let noReaction = 0;
const html = document.createElement("div");
html.innerHTML = htmlText;
const countElement = html.querySelector(".count");
if (!countElement) return;
const reaction = Number(countElement.textContent.replace(/\s+/g, ""));
fetch(`${getBaseURL()}/${userUrl}likes?type=gotten&content_type=post&stats=1`).then(resul => resul.text().then(htmlText => {
html.innerHTML = htmlText;
const allReaction = html.querySelectorAll(".node");
allReaction.forEach(el => {
const mutedElement = el.querySelector(".muted");
if (mutedElement && mutedElement.textContent.toLowerCase().includes("розыгрыш")) {
const counterElement = el.querySelector(".counter");
if (counterElement) {
noReaction += Number(counterElement.textContent.replace(/\s+/g, ""));
}
}
});
fetch(`${getBaseURL()}/${userUrl}likes`).then(resp => resp.text().then(likesHtml => {
const likesContainer = document.createElement("div");
likesContainer.innerHTML = likesHtml;
const pageDescription = likesContainer.querySelector("#pageDescription");
let last7DaysCount = 0;
if (pageDescription) {
const statsText = pageDescription.textContent;
const match = statsText.match(/Набрано за последние 7 дней - (\d+)/);
if (match && match[1]) {
last7DaysCount = parseInt(match[1]);
}
}
const adjustedCount = reaction - noReaction;
const element = `<i class="userCounterIcon fas fa-heart"></i>${formatNumber(reaction)} / ${formatNumber(adjustedCount)} / ${formatNumber(last7DaysCount)}`;
const counterContainer = user.querySelector(".userCounters span") || document.createElement("span");
counterContainer.classList.add("userCounter", "item", "muted");
counterContainer.innerHTML = element;
if (!user.querySelector(".userCounters span")) {
user.querySelector(".userCounters").appendChild(counterContainer);
}
}));
}));
}));
}
function updateUserLikes2(user) {
if (!shouldRunScript()) return;
const link = user.querySelector("span a.username");
if (!link) return;
const userUrl = link.getAttribute("href");
fetch(`${getBaseURL()}/${userUrl}`)
.then(resul => resul.text())
.then(htmlText => {
const html = document.createElement("div");
html.innerHTML = htmlText;
const likesElement = html.querySelector('a.page_counter[href$="likes2"]');
if (!likesElement) {
console.log("Элемент с лайками (likes2) не найден на странице пользователя.");
return;
}
const countElement = likesElement.querySelector(".count");
if (!countElement) {
console.log("Элемент .count не найден внутри элемента с лайками.");
return;
}
const likes2 = Number(countElement.textContent.replace(/\s+/g, ""));
fetch(`${getBaseURL()}/${userUrl}likes2`)
.then(resp => resp.text())
.then(likes2Html => {
const likes2Container = document.createElement("div");
likes2Container.innerHTML = likes2Html;
const pageDescription = likes2Container.querySelector("#pageDescription");
let last7DaysCount = 0;
if (pageDescription) {
const statsText = pageDescription.textContent;
const match = statsText.match(/Набрано за последние 7 дней - (\d+)/);
if (match && match[1]) {
last7DaysCount = parseInt(match[1]);
}
}
const element = `<i class="userCounterIcon fas fa-thumbs-up"></i>${formatNumber(likes2)} / ${formatNumber(last7DaysCount)}`;
const counterContainer = user.querySelector(".userCounters span") || document.createElement("span");
counterContainer.classList.add("userCounter", "item", "muted");
counterContainer.innerHTML = element;
if (!user.querySelector(".userCounters span")) {
user.querySelector(".userCounters").appendChild(counterContainer);
}
});
})
.catch(error => {
console.error("Ошибка при обработке страницы пользователя:", error);
});
}
function initUserCounters(user) {
if (shouldRunScript()) {
updateUserLikes2(user);
} else {
updateUserSympathies(user);
}
}
const users = document.querySelectorAll('.user');
users.forEach(user => initUserCounters(user));
// Розыгрыши симпы
function updateContestUserStats() {
const userItems = document.querySelectorAll('.memberListItem');
userItems.forEach(item => {
const userStatCounters = item.querySelector('.userStatCounters');
if (!userStatCounters) return;
const likeCounter = userStatCounters.querySelector('.counter:first-child .count');
if (!likeCounter) return;
const likesText = likeCounter.textContent.trim();
const totalLikes = parseInt(likesText.replace(/\s+/g, ""));
if (isNaN(totalLikes)) {
console.error("Could not parse likes count:", likesText);
return;
}
const usernameLink = item.querySelector('h3.username a');
if (!usernameLink) return;
const userUrl = usernameLink.getAttribute('href');
if (!userUrl) return;
fetch(`${getBaseURL()}/${userUrl}`).then(response => {
if (!response.ok) return null;
return response.text();
}).then(htmlText => {
if (!htmlText) return;
let noReaction = 0;
const tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlText;
fetch(`${getBaseURL()}/${userUrl}likes?type=gotten&content_type=post&stats=1`).then(response => {
if (!response.ok) return null;
return response.text();
}).then(likesHtml => {
if (!likesHtml) return;
tempDiv.innerHTML = likesHtml;
const allReaction = tempDiv.querySelectorAll(".node");
allReaction.forEach(el => {
const muted = el.querySelector(".muted");
if (muted && muted.textContent.toLowerCase().includes("розыгрыш")) {
const counter = el.querySelector(".counter");
if (counter) {
const raffleCount = parseInt(counter.textContent.replace(/\s+/g, ""));
if (!isNaN(raffleCount)) {
noReaction += raffleCount;
}
}
}
});
fetch(`${getBaseURL()}/${userUrl}likes`).then(response => {
if (!response.ok) return null;
return response.text();
}).then(profileLikesHtml => {
if (!profileLikesHtml) return;
tempDiv.innerHTML = profileLikesHtml;
const pageDescription = tempDiv.querySelector("#pageDescription");
let last7DaysCount = 0;
if (pageDescription) {
const statsText = pageDescription.textContent;
const match = statsText.match(/Набрано за последние 7 дней - (\d+)/);
if (match && match[1]) {
last7DaysCount = parseInt(match[1]);
}
}
const adjustedCount = totalLikes - noReaction;
console.debug("Likes calculation:", {
totalLikes,
noReaction,
adjustedCount,
last7DaysCount
});
likeCounter.textContent = `${formatNumber(totalLikes)} / ${formatNumber(adjustedCount)} / ${formatNumber(last7DaysCount)}`;
}).catch(err => console.error("Error fetching likes page:", err));
}).catch(err => console.error("Error fetching raffle reactions:", err));
}).catch(err => console.error("Error fetching user profile:", err));
});
}
// Розыгрыши лайки
function updateContestUserLikes2() {
const userItems = document.querySelectorAll('.memberListItem');
userItems.forEach(item => {
const userStatCounters = item.querySelector('.userStatCounters');
if (!userStatCounters) return;
const like2Counter = userStatCounters.querySelector('.counter:nth-child(2) .count');
if (!like2Counter) return;
const likes2Text = like2Counter.textContent.trim();
const totalLikes2 = parseInt(likes2Text.replace(/\s+/g, ""));
if (isNaN(totalLikes2)) {
console.error("Could not parse likes2 count:", likes2Text);
return;
}
const usernameLink = item.querySelector('h3.username a');
if (!usernameLink) return;
const userUrl = usernameLink.getAttribute('href');
if (!userUrl) return;
fetch(`${getBaseURL()}/${userUrl}`).then(response => {
if (!response.ok) return null;
return response.text();
}).then(htmlText => {
if (!htmlText) return;
const tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlText;
fetch(`${getBaseURL()}/${userUrl}likes2`).then(response => {
if (!response.ok) return null;
return response.text();
}).then(likes2Html => {
if (!likes2Html) return;
tempDiv.innerHTML = likes2Html;
const pageDescription = tempDiv.querySelector("#pageDescription");
let last7DaysCount = 0;
if (pageDescription) {
const statsText = pageDescription.textContent;
const match = statsText.match(/Набрано за последние 7 дней - (\d+)/);
if (match && match[1]) {
last7DaysCount = parseInt(match[1]);
}
}
like2Counter.textContent = `${formatNumber(totalLikes2)} / ${formatNumber(last7DaysCount)}`;
}).catch(err => console.error("Error fetching likes2 page:", err));
}).catch(err => console.error("Error fetching user profile:", err));
});
}
// Мини профиль (обсервер)
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.classList && node.classList.contains("message")) {
const user = node.querySelector(".userText");
if (user) {
updateUserSympathies(user);
updateUserLikes2(user);
}
}
if (node.classList && node.classList.contains("memberListItem") && window.location.href.includes("contest-users")) {
setTimeout(() => {
updateContestUserStats();
updateContestUserLikes2();
}, 10);
}
if (node.classList && (node.classList.contains("memberCard") || node.classList.contains("memberCardInner"))) {
processMemberCard(node);
} else if (node.nodeType === 1) {
const memberCards = node.querySelectorAll(".memberCard, .memberCardInner");
memberCards.forEach(card => {
processMemberCard(card);
});
}
});
});
});
function processMemberCard(card) {
const usernameElement = card.querySelector(".username.NoOverlay, .username a");
if (!usernameElement) return;
const link = usernameElement.getAttribute("href");
if (!link) return;
updateMemberCardStats(card, link);
}
// Симпы и лайки мини профиль
function updateMemberCardStats(card, userLink) {
const stats = {
likes: {
totalReactions: 0,
noReaction: 0,
last7DaysCount: 0,
processed: false
},
likes2: {
totalReactions: 0,
noReaction: 0,
last7DaysCount: 0,
processed: false
}
};
const likeCounter = card.querySelector("a.counter[href$='likes'] .count");
const likes2Counter = card.querySelector("a.counter[href$='likes2'] .count");
if (likeCounter) {
stats.likes.totalReactions = Number(likeCounter.textContent.replace(/\s+/g, "")) || 0;
}
if (likes2Counter) {
stats.likes2.totalReactions = Number(likes2Counter.textContent.replace(/\s+/g, "")) || 0;
}
fetch(`${getBaseURL()}/${userLink}`).then(response => {
if (!response.ok) return null;
return response.text();
}).then(profileHtml => {
if (!profileHtml) return;
fetchLikesData('likes');
fetchLikesData('likes2');
}).catch(err => console.error("Error fetching user profile:", err));
function fetchLikesData(likesType) {
fetch(`${getBaseURL()}/${userLink}${likesType}?type=gotten&content_type=post&stats=1`).then(resul => {
return resul.text();
}).then(htmlText => {
const tempDiv = document.createElement("div");
tempDiv.innerHTML = htmlText;
const allReaction = tempDiv.querySelectorAll(".node");
allReaction.forEach(el => {
const mutedElement = el.querySelector(".muted");
if (mutedElement && mutedElement.textContent.toLowerCase().includes("розыгрыш")) {
const counterElement = el.querySelector(".counter");
if (counterElement) {
stats[likesType].noReaction += Number(counterElement.textContent.replace(/\s+/g, ""));
}
}
});
fetch(`${getBaseURL()}/${userLink}${likesType}`).then(resp => {
return resp.text();
}).then(likesHtml => {
const likesContainer = document.createElement("div");
likesContainer.innerHTML = likesHtml;
const pageDescription = likesContainer.querySelector("#pageDescription");
if (pageDescription) {
const statsText = pageDescription.textContent;
const match = statsText.match(/Набрано за последние 7 дней - (\d+)/);
if (match && match[1]) {
stats[likesType].last7DaysCount = parseInt(match[1]);
}
}
stats[likesType].processed = true;
updateUIIfReady();
}).catch(err => console.error(`Error fetching ${likesType} page:`, err));
}).catch(err => console.error(`Error fetching raffle reactions for ${likesType}:`, err));
}
function updateUIIfReady() {
if (!stats.likes.processed || !stats.likes2.processed) {
return; // Ждем, пока оба будут готовы
}
if (likeCounter) {
const adjustedCount = stats.likes.totalReactions - stats.likes.noReaction;
likeCounter.innerHTML = `${formatNumber(stats.likes.totalReactions)} / ${formatNumber(adjustedCount)} / ${formatNumber(stats.likes.last7DaysCount)}`;
}
if (likes2Counter) {
const adjustedCount2 = stats.likes2.totalReactions - stats.likes2.noReaction;
likes2Counter.innerHTML = `${formatNumber(stats.likes2.totalReactions)} / ${formatNumber(stats.likes2.last7DaysCount)}`;
}
}
}
observer.observe(document.body, {
childList: true,
subtree: true
});
document.querySelectorAll(".userText").forEach(user => {
updateUserSympathies(user);
updateUserLikes2(user);
});
if (window.location.href.includes("contest-users")) {
setTimeout(() => {
updateContestUserStats();
updateContestUserLikes2();
}, 200);
}
// Профиль симпы
function updateProfileSympathies() {
const profileCounter = document.querySelector('a.page_counter[href$="likes"] .count');
if (profileCounter) {
const profileSympathies = Number(profileCounter.textContent.replace(/\s+/g, ""));
let noReaction = 0;
const currentPath = window.location.pathname;
const likesPath = currentPath + (currentPath.endsWith('/') ? '' : '/') + 'likes';
fetch(window.location.href + 'likes?type=gotten&content_type=post&stats=1').then(resul => {
resul.text().then(htmlText => {
html.innerHTML = htmlText;
const allReaction = html.querySelectorAll(".node");
allReaction.forEach(el => {
const mutedElement = el.querySelector(".muted");
if (mutedElement && mutedElement.textContent.toLowerCase().includes("розыгрыш")) {
const counterElement = el.querySelector(".counter");
if (counterElement) {
noReaction += Number(counterElement.textContent.replace(/\s+/g, ""));
}
}
});
fetch(`${getBaseURL()}${likesPath}`).then(resp => resp.text().then(likesHtml => {
const likesContainer = document.createElement("div");
likesContainer.innerHTML = likesHtml;
const pageDescription = likesContainer.querySelector("#pageDescription");
let last7DaysCount = 0;
if (pageDescription) {
const statsText = pageDescription.textContent;
const match = statsText.match(/Набрано за последние 7 дней - (\d+)/);
if (match && match[1]) {
last7DaysCount = parseInt(match[1]);
}
}
const adjustedCount = profileSympathies - noReaction;
profileCounter.innerHTML = `<i class="counterIcon likeCounterIcon"></i>${formatNumber(profileSympathies)} / ${formatNumber(adjustedCount)} / ${formatNumber(last7DaysCount)}`;
}));
});
});
}
}
// Профиль лайки
function updateProfileLikes2() {
const profileCounter = document.querySelector('a.page_counter[href$="likes2"] .count');
if (profileCounter) {
const profileLikes2 = Number(profileCounter.textContent.replace(/\s+/g, ""));
const currentPath = window.location.pathname;
const likes2Path = currentPath + (currentPath.endsWith('/') ? '' : '/') + 'likes2';
fetch(`${getBaseURL()}${likes2Path}`).then(resp => resp.text().then(likes2Html => {
const likes2Container = document.createElement("div");
likes2Container.innerHTML = likes2Html;
const pageDescription = likes2Container.querySelector("#pageDescription");
let last7DaysCount = 0;
if (pageDescription) {
const statsText = pageDescription.textContent;
const match = statsText.match(/Набрано за последние 7 дней - (\d+)/);
if (match && match[1]) {
last7DaysCount = parseInt(match[1]);
}
}
profileCounter.innerHTML = `<i class="counterIcon like2Icon"></i>${formatNumber(profileLikes2)} / ${formatNumber(last7DaysCount)}`;
}));
}
}
updateProfileSympathies();
updateProfileLikes2();
})();