animestars Auto Helper

хелпер который помогает определить популярность карты на сайте astars.club

目前為 2025-01-31 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         animestars Auto Helper
// @namespace    animestars.org
// @version      2.89
// @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);

    console.log(cards.length, 'cards found');

    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);
        }
    }
}

function removeMatchingWatchlistItems() {
    const movieRatedList = document.querySelector('.movie-rated__list');
    if (movieRatedList) {
        // Устанавливаем фон красным
        movieRatedList.style.backgroundColor = 'red';
    }

    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 (movieRatedList) {
        // Устанавливаем фон зелёным на 2 секунды, затем убираем фон
        movieRatedList.style.backgroundColor = 'green';
        setTimeout(() => {
            movieRatedList.style.backgroundColor = '';
        }, 3000);
    }
}

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-skull';
        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_${currentDateTime.toISOString().slice(0, 13)}`; // Формат YYYY-MM-DDTHH

        if (localStorage.getItem(localStorageKey)) {
            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, "true");
                    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();
})();