Nedo Auto Contest Participation Script

Автоматом заходит в тему с розыгрышем и пролистывает до кнопки участия, после капчи автоматом принимает участие и выходит с темы и заходит в следующую. Сохраняет текущий URL с фильтрами и возвращается к нему после участия.

目前为 2024-11-02 提交的版本。查看 最新版本

// ==UserScript==
// @name         Nedo Auto Contest Participation Script
// @namespace    http://tampermonkey.net/
// @version      1.8
// @description  Автоматом заходит в тему с розыгрышем и пролистывает до кнопки участия, после капчи автоматом принимает участие и выходит с темы и заходит в следующую. Сохраняет текущий URL с фильтрами и возвращается к нему после участия.
// @author       eretly
// @match        https://lolz.live/threads/*
// @match        https://lolz.live/forums/contests/*
// @match        https://lolz.guru/threads/*
// @match        https://lolz.guru/forums/contests/*
// @match        https://zelenka.guru/threads/*
// @match        https://zelenka.guru/forums/contests/*
// @grant        none
// ==/UserScript==
 
(function() {
    'use strict';
 
    // Конфиг
    const CHECK_INTERVAL = 100; // ms
    const PARTICIPATION_WAIT = 3000; // ms, ждем 3 секунды, прежде чем проверять скрытое состояние кнопки (если вы проходите капчу за 1 секунду после захода в тему, то уменьшите)
    const SCROLL_ATTEMPTS = 3; // Количество попыток прокрутки (ненужная хуйня)
    const SCROLL_INTERVAL = 1000; // ms, интервал между попытками прокрутки (тоже ненужная хуйня)
    const SCROLL_OFFSET = 10; // px, Выше (0+) / Ниже (-0) прокручивать страницу
    const DOUBLE_CHECK_DELAY = 500; // ms, задержка перед повторной проверкой скролла (типо если не долистал до конца, чет прогрузилось на странице, через 0.5 сек чекнет и долистает как надо - поставил оптимальное для себя)
    const BEFORE_CLICK_DELAY = 100; // ms, задержка перед нажатием на кнопку
    const AFTER_CLICK_DELAY = 300; // ms, задержка после нажатия на кнопку
 
    const STORAGE_KEY = 'nedoAutoContestListURL';
 
    function saveContestListURL(url) {
        sessionStorage.setItem(STORAGE_KEY, url);
        console.log('Сохранен URL списка конкурсов с фильтрами:', url);
    }
 
    function getSavedContestListURL() {
        return sessionStorage.getItem(STORAGE_KEY);
    }
 
    function getContestListURL() {
        const hostname = window.location.hostname;
        switch (hostname) {
            case 'lolz.live':
                return 'https://lolz.live/forums/contests/';
            case 'lolz.guru':
                return 'https://lolz.guru/forums/contests/';
            case 'zelenka.guru':
                return 'https://zelenka.guru/forums/contests/';
            default:
                console.warn('Неизвестный домен:', hostname);
                return null;
        }
    }
 
    function updateContestListURL() {
        const contestListURL = getContestListURL();
        if (window.location.href.includes(contestListURL)) {
            saveContestListURL(window.location.href);
        }
    }
 
    function clearSavedContestListURL() {
        sessionStorage.removeItem(STORAGE_KEY);
        console.log('Сохраненный URL списка конкурсов удален');
    }
 
    function scrollToElement() {
        const xpath = "/html/body/div[4]/div/div/div/form/ol/li/div[2]/div[3]/article/div";
        let scrollAttempts = 0;
 
        function attemptScroll() {
            const element = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
 
            if (element) {
                const elementRect = element.getBoundingClientRect();
                const absoluteElementTop = elementRect.top + window.pageYOffset;
                const middleOfElement = absoluteElementTop + elementRect.height / 2;
                const scrollTo = middleOfElement - (window.innerHeight / 2) - SCROLL_OFFSET;
 
                window.scrollTo({
                    top: scrollTo,
                    behavior: 'smooth'
                });
                console.log('Прокручено к элементу');
 
                setTimeout(() => {
                    const newElementRect = element.getBoundingClientRect();
                    if (newElementRect.top > SCROLL_OFFSET) {
                        console.log('Элемент не на нужной позиции, корректировка...');
                        window.scrollTo({
                            top: window.pageYOffset + newElementRect.top - SCROLL_OFFSET,
                            behavior: 'smooth'
                        });
                    }
                }, DOUBLE_CHECK_DELAY);
            } else {
                console.log('Элемент не найден, повторная попытка...');
                if (scrollAttempts < SCROLL_ATTEMPTS) {
                    scrollAttempts++;
                    setTimeout(attemptScroll, SCROLL_INTERVAL);
                } else {
                    console.log('Не удалось найти элемент после нескольких попыток');
                }
            }
        }
 
        attemptScroll();
    }
 
    function clickFirstContestLink() {
        const selector = ".discussionListItem a.listBlock.main.PreviewTooltip";
        const link = document.querySelector(selector);
        if (link) {
            console.log('Кликаем по первому конкурсу:', link.href);
            link.click();
        } else {
            console.log('Не найдено ни одного конкурса для участия.');
        }
    }
 
    function waitForParticipateButton() {
        return new Promise((resolve) => {
            const interval = setInterval(() => {
                const participateButton = document.querySelector('a.LztContest--Participate.button:not(.disabled)');
                if (participateButton && participateButton.getAttribute('href').includes('token')) {
                    clearInterval(interval);
                    resolve(participateButton);
                }
            }, CHECK_INTERVAL);
        });
    }
 
    async function participateInContest() {
        console.log('Ожидание доступности кнопки участия...');
        const participateButton = await waitForParticipateButton();
        console.log('Кнопка участия доступна, ожидаем перед кликом...');
 
        await new Promise(resolve => setTimeout(resolve, BEFORE_CLICK_DELAY));
 
        participateButton.click();
        console.log('Кликнули по кнопке участия');
 
        await new Promise(resolve => setTimeout(resolve, AFTER_CLICK_DELAY));
 
        console.log('Участие завершено, возвращаемся к списку конкурсов');
 
        const contestListURL = getSavedContestListURL();
        if (contestListURL) {
            window.location.href = contestListURL;
        } else {
            console.warn('Не удалось определить URL списка конкурсов для возврата.');
        }
    }
 
        const currentURL = window.location.href;
        const contestListURL = getContestListURL();
 
        if (currentURL.includes('/threads/')) {
            console.log('На странице конкурса, начинаем процесс участия...');
            scrollToElement();
 
            setTimeout(participateInContest, PARTICIPATION_WAIT);
        } else if (currentURL.includes(contestListURL)) {
            console.log('На странице списка конкурсов, обновляем URL и кликаем по первому конкурсу...');
            updateContestListURL();
 
            setTimeout(() => {
                clickFirstContestLink();
            }, 100);
        } else {
            console.log('На неизвестной странице, скрипт не активирован.');
        }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址