- // ==UserScript==
- // @name animestars Auto Helper
- // @namespace animestars.org
- // @version 2.96
- // @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));
-
- let cardCounter = 0;
-
- 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());
- }
-
- function getCardsOnPage() {
- return 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);
- }
-
- async function processCards() {
- removeMatchingWatchlistItems();
- removeAllLinkIcons();
-
- const cards = getCardsOnPage();
- let counter = cards.length;
-
- if (counter) {
- console.log(cards.length, 'cards found');
- DLEPush?.info('Обновляю инфу по ' + cards.length + ' картам');
- } else {
- DLEPush?.error('Карты не найдены на странице');
- return;
- }
-
- let buttonId = 'processCards';
- startAnimation(buttonId);
- updateButtonCounter(buttonId, counter);
- 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;
- });
- counter--;
- updateButtonCounter(buttonId, counter);
- } else {
- console.log(cardId, 'cardId not found');
- console.log(card);
- }
-
- if (card.classList.contains('lootbox__card')) {
- card.addEventListener('click', removeAllLinkIcons);
- }
- }
- stopAnimation(buttonId);
- DLEPush?.info('Информация обновлена');
- }
-
- function removeMatchingWatchlistItems() {
- const watchlistItems = document.querySelectorAll('.watchlist__item');
- if (watchlistItems.length == 0) {
- return;
- }
- 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('Из списка удалены просмотренные аниме. В списке осталось ' + document.querySelectorAll('.watchlist__item').length + ' записей.');
- }
- }
-
- function startAnimation(id) {
- $('#' + id + ' span:first').css('animation', 'rotateIcon 2s linear infinite');
- }
-
- function stopAnimation(id) {
- $('#' + id + ' span:first').css('animation', '');
- }
-
- function getButton(id, className, percent, text, clickFunction) {
- const button = document.createElement('button');
- button.id = id;
- button.title = text;
- button.style.position = 'fixed';
- button.style.top = percent + '%';
- 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)';
- const icon = document.createElement('span');
- icon.className = 'fal fa-' + className;
- icon.style.display = 'inline-block';
- button.appendChild(icon);
- const info = document.createElement('span');
- info.id = id + '_counter';
- info.className = 'guest__notification';
- info.style.display = 'none';
- button.appendChild(info);
- button.addEventListener('click', clickFunction);
- return button;
- }
-
- function updateButtonCounter(id, counter) {
- let c = $('#' + id + '_counter');
- c.css('display', counter > 0 ? 'flex' : 'none');
- c.text(counter);
- }
-
- function addUpdateButton() {
- if (!document.querySelector('#fetchLinksButton')) {
- document.body.appendChild(getButton('processCards', 'rocket', 37, 'Сравнить карточки', processCards));
-
- let cards = getCardsOnPage();
- if (cards.length) {
- document.body.appendChild(getButton('readyToCharge', 'circle-check', 50, 'Готов поменять карточки', readyToCharge));
- }
- }
- }
-
- async function readyToCharge() {
- DLEPush.info('Отмечаем все карты на странице как: "Готов обменять" кроме тех что на обмене и заблокированных');
- let cards = getCardsOnPage();
- DLEPush.info('Карт на странице: ' + cards.length);
-
- let counter = cards.length;
- let buttonId = 'readyToCharge';
- startAnimation(buttonId);
- updateButtonCounter(buttonId, counter);
-
- cardCounter = 0;
- 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 readyToChargeCard(cardId);
- counter--;
- updateButtonCounter(buttonId, counter);
- }
- }
- DLEPush.info('Отправили на обмен ' + cardCounter + ' карточек на странице');
- stopAnimation(buttonId);
- }
-
- const readyToChargeCard = async (cardId) => {
- await sleep(DELAY * 2);
- const url = '/engine/ajax/controller.php?mod=trade_ajax';
- const data = {
- action: 'propose_add',
- type: 1,
- card_id: cardId,
- user_hash: dle_login_hash
- };
-
- try {
- const response = await fetch(url, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- },
- body: new URLSearchParams(data).toString()
- });
-
- if (response.ok) {
- const data = await response.json();
- if (data.error) {
- if (data.error == 'Слишком часто, подождите пару секунд и повторите действие') {
- await readyToChargeCard(cardId);
- return;
- }
- cardCounter++;
- return;
- }
- if ( data.status == 'added' ) {
- cardCounter++;
- //console.log('counter: ' + cardCounter);
- }
- if ( data.status == 'deleted' ) {
- await readyToChargeCard(cardId);
- }
-
- //console.log('Ответ сервера:', data);
- } else {
- console.error('Ошибка запроса:', response.status);
- }
- } catch (error) {
- console.error('Ошибка выполнения POST-запроса:', error);
- }
- };
-
- // Анимация вращения в 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();
- checkGiftCard();
- }
-
- function checkGiftCard() {
- var button = $('#gift-icon');
- if (button.length === 0) {
- return;
- }
- var gift_code = button.attr('data-code');
- if ( !gift_code ) return false;
- $.ajax({
- url: '/engine/ajax/controller.php?mod=gift_code_game',
- data:{code: gift_code, user_hash: dle_login_hash},
- dataType: 'json',
- cache: false,
- type: 'post',
- success: function(data) {
- if ( data.status == 'ok' ) {
- DLEPush.info( data.text );
- button.remove();
- }
- }
- });
- }
-
- 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 checkNewCard() {
- 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
-
- if ( data.cards.name ) {
- DLEPush?.info('Получена новая карта "' + data.cards.name + '"');
- }
-
- 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();
- checkNewCard();
-
- sound_notifications = 0;
- addUpdateButton();
- $('#tg-banner').remove();
- localStorage.setItem('notify18', 'closed');
- localStorage.setItem('theme','dark');
- localStorage.setItem('hideTelegramAs', 'true');
- })();