// ==UserScript==
// @name animestars Auto Helper
// @namespace animestars.org
// @version 2.91
// @description хелпер который помогает определить популярность карты на сайте astars.club
// @author astars lover
// @match https://astars.club/*
// @match https://asstars1.astars.club/*
// @match https://animestars.org/*
// @match https://as1.astars.club/*
// @match https://asstars.tv/*
// @license MIT
// @grant none
// ==/UserScript==
const DELAY = 500; // Задержка между запросами в миллисекундах (по умолчанию 0,5 секунды) не менять чтоб не делать избыточную нагрузку на сайт
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
async function getCount(cardId, type) {
// Определяем текущий домен
const currentDomain = window.location.origin;
let count = 0;
let needResponse = await fetch(`${currentDomain}/cards/${cardId}/users/${type}/`);
if (needResponse.status === 502) {
console.error("Ошибка 502: Остановка выполнения скриптов.");
throw new Error("502 Bad Gateway");
}
let needHtml = '';
let needDoc = '';
if (needResponse.ok) {
needHtml = await needResponse.text();
needDoc = new DOMParser().parseFromString(needHtml, 'text/html');
count = needDoc.querySelectorAll('.profile__friends-item').length;
} else {
return count;
}
const pagination = needDoc.querySelector('.pagination__pages');
if (pagination && count >= 50) {
const lastPageNum = pagination.querySelector('a:last-of-type');
const totalPages = lastPageNum ? parseInt(lastPageNum.innerText, 10) : 1;
if (totalPages > 1) {
count = (totalPages - 1) * 50;
}
needResponse = await fetch(`${currentDomain}/cards/${cardId}/users/${type}/page/${totalPages}`);
if (needResponse.status === 502) {
console.error("Ошибка 502: Остановка выполнения скриптов.");
throw new Error("502 Bad Gateway");
}
if (needResponse.ok) {
needHtml = await needResponse.text();
needDoc = new DOMParser().parseFromString(needHtml, 'text/html');
count += needDoc.querySelectorAll('.profile__friends-item').length;
}
}
return count;
}
async function updateCardInfo(cardId, element) {
// Определяем текущий домен
const currentDomain = window.location.origin;
if (!cardId || !element) {
console.log(cardId, 'updateCardInfo error');
return;
}
try {
console.log(`Обработка карточки с ID: ${cardId}`);
await sleep(DELAY);
// Получение количества "Желающих"
let needCount = await getCount(cardId, 'need');
await sleep(DELAY);
// Получение количества "Готовых поменять"
let tradeCount = await getCount(cardId, 'trade');
await sleep(DELAY);
// Получение популярности и ранга
const popularityResponse = await fetch(`${currentDomain}/cards/${cardId}/users/`);
if (popularityResponse.status === 502) {
console.error("Ошибка 502: Остановка выполнения скриптов.");
throw new Error("502 Bad Gateway");
}
let popularityCount = 0;
let rankText = '';
if (popularityResponse.ok) {
const popularityHtml = await popularityResponse.text();
const popularityDoc = new DOMParser().parseFromString(popularityHtml, 'text/html');
const rankElement = popularityDoc.querySelector('.anime-cards__rank');
if (rankElement) {
rankText = rankElement.textContent.trim();
}
popularityCount = popularityDoc.querySelectorAll('.card-show__owner').length;
const pagination = popularityDoc.querySelector('.pagination__pages');
if (pagination) {
const lastPageNum = pagination.querySelector('a:last-of-type');
const totalPages = lastPageNum ? parseInt(lastPageNum.innerText, 10) : 1;
if (totalPages > 1 && popularityCount >= 35) {
popularityCount = (totalPages - 1) * 35;
const needResponse = await fetch(`${currentDomain}/cards/${cardId}/users/page/${totalPages}`);
if (needResponse.status === 502) {
console.error("Ошибка 502: Остановка выполнения скриптов.");
throw new Error("502 Bad Gateway");
}
if (needResponse.ok) {
popularityCount += (new DOMParser().parseFromString(await needResponse.text(), 'text/html')).querySelectorAll('.card-show__owner').length;
}
}
}
}
// Очистка старой информации
element.querySelector('.link-icon')?.remove();
// Добавление новой информации
const icon = document.createElement('div');
icon.className = 'link-icon';
icon.style.position = 'absolute';
icon.style.top = '10px';
icon.style.right = '10px';
icon.style.backgroundColor = 'rgba(0, 0, 0, 0.6)';
icon.style.color = '#05ed5b';
icon.style.padding = '5px';
icon.style.borderRadius = '5px';
icon.style.fontSize = '8px';
icon.innerHTML = `Ранг: ${rankText}<br>Уже имеют: ${popularityCount}<br>Хотят получить: ${needCount}<br>Готовы поменять: ${tradeCount}`;
element.style.position = 'relative';
element.appendChild(icon);
console.log(cardId, '- ok');
} catch (error) {
console.error(`Ошибка обработки карты ${cardId}:`, error);
// Остановка выполнения скриптов
throw error;
}
}
function removeAllLinkIcons() {
const linkIcons = document.querySelectorAll('.link-icon');
linkIcons.forEach(icon => icon.remove());
}
async function processCards() {
removeMatchingWatchlistItems();
removeAllLinkIcons();
const cards = Array.from(
document.querySelectorAll('.lootbox__card, .anime-cards__item, .trade__inventory-item, .trade__main-item, .card-filter-list__card, .deck__item, .history__body-item, .history__body-item, .card-show__placeholder')
).filter(card => card.offsetParent !== null);
if (cards.length) {
console.log(cards.length, 'cards found');
DLEPush?.info('Обновляю инфу по ' + cards.length + ' картам');
} else {
DLEPush?.error('Карты не найдены на странице');
return;
}
for (const card of cards) {
if (card.classList.contains('trade__inventory-item--lock')) {
console.log('Пропускаем карту с классом trade__inventory-item--lock');
continue; // Пропускаем эту карту
}
let cardId = card.getAttribute('card-id') || card.getAttribute('data-card-id') || card.getAttribute('data-id');
const href = card.getAttribute('href');
if (href) {
let cardIdMatch = href.match(/\/cards\/(\d+)\/users\//);
console.log(cardIdMatch);
if (cardIdMatch) {
cardId = cardIdMatch[1];
}
}
if (cardId) {
await updateCardInfo(cardId, card).catch(error => {
console.error("Остановка из-за критической ошибки:", error.message);
return;
});
} else {
console.log(cardId, 'cardId not found');
console.log(card);
}
if (card.classList.contains('lootbox__card')) {
card.addEventListener('click', removeAllLinkIcons);
}
}
DLEPush?.info('Информация обновлена');
}
function removeMatchingWatchlistItems() {
const watchlistItems = document.querySelectorAll('.watchlist__item');
watchlistItems.forEach(item => {
const episodesText = item.querySelector('.watchlist__episodes')?.textContent.trim();
if (episodesText) {
const matches = episodesText.match(/[\d]+/g);
if (matches) {
const currentEpisode = parseInt(matches[0], 10);
const totalEpisodes = parseInt(matches.length === 4 ? matches[3] : matches[1], 10);
if (currentEpisode === totalEpisodes) {
item.remove();
console.log(`Удалён блок: ${item}`);
}
}
}
});
if (watchlistItems.length) {
DLEPush?.info('Из списка удалены просмотренные аниме');
}
}
function addUpdateButton() {
if (!document.querySelector('#fetchLinksButton')) {
const button = document.createElement('button');
button.id = 'fetchLinksButton';
// Стили кнопки
button.style.position = 'fixed';
button.style.top = '37%';
button.style.right = '1%';
button.style.zIndex = '1000';
button.style.backgroundColor = '#007bff';
button.style.color = '#fff';
button.style.border = 'none';
button.style.borderRadius = '5px';
button.style.padding = '10px 15px';
button.style.cursor = 'pointer';
button.style.boxShadow = '0 2px 5px rgba(0, 0, 0, 0.2)';
// button.style.transform = 'rotate(90deg)';
// Добавляем иконку внутрь кнопки
const icon = document.createElement('span');
icon.className = 'fal fa-rocket';
icon.style.display = 'inline-block';
// icon.style.animation = 'rotateIcon 2s linear infinite'; // Анимация вращения
button.appendChild(icon);
// Обработчик клика
button.addEventListener('click', processCards);
document.body.appendChild(button);
}
}
// Анимация вращения в CSS
const style = document.createElement('style');
style.textContent = `
@keyframes rotateIcon {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.fal.fa-skull {
animation: rotateIcon 2s linear infinite;
}
`;
document.head.appendChild(style);
function clearIcons() {
$('.card-notification')?.first()?.click();
}
function startPing() {
setInterval(() => {
// Получаем значение из глобальной переменной
const userHash = window.dle_login_hash;
if (!userHash) {
console.error("Переменная dle_login_hash не определена.");
return;
}
// Определяем текущий домен
const currentDomain = window.location.origin;
// Формируем URL с учетом userHash
const url = `${currentDomain}/engine/ajax/controller.php?mod=user_count_timer&user_hash=${userHash}`;
// Выполняем GET-запрос
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json(); // Если ответ в формате JSON
})
.then(data => {
console.log("Данные получены:", data); // Обрабатываем полученные данные
})
.catch(error => {
console.error("Ошибка при выполнении запроса:", error);
});
}, 31000); // Интервал проверки — 31 сек
}
function checkCard() {
setInterval(() => {
const currentDateTime = new Date();
const localStorageKey = `checkCardStopped`; // Формат YYYY-MM-DDTHH
if (localStorage.getItem(localStorageKey) === currentDateTime.toISOString().slice(0, 13)) {
console.log("Проверка карты уже остановлена на текущий час.");
return;
}
// Получаем значение из глобальной переменной
const userHash = window.dle_login_hash;
if (!userHash) {
console.error("Переменная dle_login_hash не определена.");
return;
}
// Определяем текущий домен
const currentDomain = window.location.origin;
// Формируем URL с учетом userHash
const url = `${currentDomain}/engine/ajax/controller.php?mod=reward_card&action=check_reward&user_hash=${userHash}`;
// Выполняем GET-запрос
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json(); // Если ответ в формате JSON
})
.then(data => {
if (data.stop_reward === "yes") {
console.log("Проверка карт остановлена на текущий час:", data.reason);
localStorage.setItem(localStorageKey, currentDateTime.toISOString().slice(0, 13));
return;
}
if (!data.cards || !data.cards.owner_id) {
return;
}
const ownerId = data.cards.owner_id;
console.log("owner_id получен:", ownerId); // Выводим owner_id
const url = `${currentDomain}/engine/ajax/controller.php?mod=cards_ajax`;
// Подготавливаем параметры запроса
const postData = new URLSearchParams({
action: "take_card",
owner_id: ownerId
});
// Выполняем POST-запрос
fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: postData.toString() // Передаём параметры в виде строки
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json(); // Если ответ в формате JSON
})
.then(data => {
console.log("Данные получены:", data); // Обрабатываем полученные данные
})
.catch(error => {
console.error("Ошибка при выполнении запроса:", error);
});
})
.catch(error => {
console.error("Ошибка при выполнении запроса:", error);
});
}, 10000); // Интервал проверки — 10 сек
}
Object.defineProperty(window, "loadPacks", {
get: function () {
return function () {
console.log("Нахуй шепот!");
};
},
set: function () {
console.log("Хуй тебе а не шепот");
}
});
(function() {
'use strict';
setInterval(clearIcons, 2000);
startPing();
checkCard();
addUpdateButton();
$('#tg-banner').remove();
localStorage.setItem('notify18', 'closed');
localStorage.setItem('theme','dark');
localStorage.setItem('hideTelegramAs', 'true');
})();