Pride Vote

xxxxx

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

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

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

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

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

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Pride Vote
// @namespace    http://tampermonkey.net/
// @version      1.4
// @description  xxxxx
// @author       B
// @match        https://awards.bangkokpride.org/*
// @icon         https://awards.bangkokpride.org/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // ========== 弹窗拦截 ==========
    const originalAlert = window.alert;
    window.alert = function(message) {
        console.log("拦截弹窗:", message);
        return;
    };

    if (window.XMLHttpRequest) {
        const originalSend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.send = function(body) {
            this.addEventListener('load', function() {
                if (this.status === 200) {
                    console.log("AJAX请求成功");
                }
            });
            return originalSend.apply(this, arguments);
        };
    }

    const originalFetch = window.fetch;
    window.fetch = async function(...args) {
        const response = await originalFetch.apply(this, args);
        if (response.ok) {
            console.log("Fetch请求成功");
        }
        return response;
    };

    // ========== 全局配置 ==========
    const config = {
        baseDelay: () => Math.random() * 500 + 500,
        postVoteDelay: () => Math.random() * 100 + 500,
        checkInterval: 1000,
        timeout: 180000,
        verificationCheckInterval: 500,
        verificationTimeout: 10000
    };

    // ========== 数据管理 ==========
    function clearSessionData() {
        document.cookie.split(";").forEach(cookie => {
            const [name] = cookie.trim().split("=");
            document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
        });
        localStorage.clear();
        sessionStorage.clear();
        console.log('已清除所有会话数据');
    }

    // ========== 验证检查模块 ==========
    function checkVerification() {
        try {
            const tokenInput = document.querySelector('input[name="cf-turnstile-response"]');
            return Boolean(tokenInput?.value?.length > 100);
        } catch (e) {
            console.log("验证检查异常:", e.message);
            return false;
        }
    }

    function verificationMonitor() {
        return new Promise((resolve) => {
            console.log("启动验证监控...");

            const finalCheck = () => {
                const result = checkVerification();
                console.log(`验证状态: ${result ? "✅ 通过" : "❌ 未通过"}`);
                return result;
            };

            // 立即执行首次检查
            if (finalCheck()) return resolve(true);

            // 设置轮询检查
            const interval = setInterval(() => {
                if (finalCheck()) {
                    clearInterval(interval);
                    clearTimeout(timeout);
                    resolve(true);
                }
            }, config.verificationCheckInterval);

            // 设置超时终止
            const timeout = setTimeout(() => {
                clearInterval(interval);
                console.log("验证监控超时");
                resolve(false);
            }, config.verificationTimeout);
        });
    }

    // ========== 首页监控 ==========
    function setupHomepageMonitoring() {
        let timeoutId = null;

        function handleTimeout() {
            console.log('操作超时');
            clearSessionData();
            window.location.reload();
        }

        function checkElements() {
            const voteButton = document.querySelector('section.py-4 button.bg-\\[\\#FF6699\\] a[href="/en/vote/"]');
            if (voteButton) {
                console.log('发现有效投票按钮');
                clearTimeout(timeoutId);
                voteButton.click();
                return true;
            }

            const waitDiv = document.querySelector('section.py-4 div.bg-gray-500');
            if (waitDiv?.textContent.includes('Wait another')) {
                console.log('检测到投票冷却');
                clearSessionData();
                window.location.reload();
                return true;
            }

            return false;
        }

        if (checkElements()) return;

        const intervalId = setInterval(() => {
            if (checkElements()) clearInterval(intervalId);
        }, config.checkInterval);

        timeoutId = setTimeout(() => {
            clearInterval(intervalId);
            handleTimeout();
        }, config.timeout);

        const observer = new MutationObserver(mutations => {
            if (checkElements()) observer.disconnect();
        });
        observer.observe(document, { childList: true, subtree: true });
    }

    // ========== 自动化投票 ==========
    const random = {
        string: (min, max) => {
    const length = Math.floor(Math.random() * (max - min + 1)) + min;
    return Array.from({length}, () =>
        String.fromCharCode(97 + Math.floor(Math.random() * 26))
    ).join(''); // ✅ 添加分号并修正语法
},
        year: () => Math.floor(Math.random() * (2000 - 1980 + 1)) + 1980,
        country: () => ["Afghanistan", "Bahrain", "Brazil", "Sudan", "Belize",
                      "Georgia", "France", "Austria", "Benin", "Comoros",
                      "Chad", "Fiji", "Thailand"][Math.floor(Math.random() * 13)],
        email: () => `${random.string(5,8)}${Math.floor(Math.random()*1000)}@${['gmail','qq','yahoo','outlook','163','hotmail','sina','126','sohu'][Math.floor(Math.random()*4)]}.com`
    };

    function waitForElm(selector) {
        return new Promise(resolve => {
            if (document.querySelector(selector)) return resolve(document.querySelector(selector));
            const observer = new MutationObserver(() => {
                if (document.querySelector(selector)) {
                    resolve(document.querySelector(selector));
                    observer.disconnect();
                }
            });
            observer.observe(document.body, { childList: true, subtree: true });
        });
    }

    const selectors = {
        firstCategory: {
            button: '//section[3]//button[contains(@class,"px-3 py-1")]',
            option: '//section[3]//label[3]//span[contains(@class,"text-lg")]'
        },
        secondCategory: {
            button: '//section[6]//button[contains(@class,"px-3 py-1")]',
            option: '//section[6]//label[8]//span[contains(@class,"text-lg")]'
        }
    };

    function xpathSelector(xpath) {
        return document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
    }

    async function selectOptions() {
        // 第一个奖项
        let cat1Btn = xpathSelector(selectors.firstCategory.button);
        if (cat1Btn) {
            cat1Btn.click();
            await new Promise(r => setTimeout(r, 500));
            let opt1 = xpathSelector(selectors.firstCategory.option);
            if (opt1) opt1.closest('label').click();
        }

        await new Promise(r => setTimeout(r, 300));

        // 第二个奖项
        let cat2Btn = xpathSelector(selectors.secondCategory.button);
        if (cat2Btn) {
            cat2Btn.click();
            await new Promise(r => setTimeout(r, 500));
            let opt2 = xpathSelector(selectors.secondCategory.option);
            if (opt2) opt2.closest('label').click();
        }

        // 新增:选择后等待1秒
        await new Promise(r => setTimeout(r, 1000));
    }

    async function fillForm() {
        const fieldDelay = () => Math.random() * 10 + 10;

        async function fillField(id, value) {
            const el = document.getElementById(id);
            if (!el) return;

            el.focus();
            await new Promise(r => setTimeout(r, fieldDelay()));

            el.value = '';
            el.dispatchEvent(new Event('input', { bubbles: true }));
            await new Promise(r => setTimeout(r, fieldDelay()));

            for (const char of value.split('')) {
                el.value += char;
                el.dispatchEvent(new Event('input', { bubbles: true }));
                await new Promise(r => setTimeout(r, fieldDelay()));
            }

            el.dispatchEvent(new Event('change', { bubbles: true }));
            el.dispatchEvent(new Event('blur', { bubbles: true }));
            await new Promise(r => setTimeout(r, fieldDelay()));
        }

        await fillField('firstName', random.string(3, 5));
        await fillField('lastName', random.string(3, 5));
        await fillField('birthYear', random.year().toString());
        await fillField('gender', 'Female');
        await fillField('country', random.country().toUpperCase());
        await fillField('email', random.email());
    }

    // ========== 主控制流程 ==========
    async function main() {
        if (location.pathname === '/en/') {
            setupHomepageMonitoring();
            return;
        }

        if (location.pathname === '/en/vote/') {
            try {
                await waitForElm('#firstName');
                await fillForm();
                await selectOptions();

                // 验证状态监控
                const isVerified = await verificationMonitor();

                if (isVerified) {
                    const voteButton = document.querySelector('button[class*="bg-[#FF6699]"]');
                    if (voteButton) {
                        console.log('执行投票提交...');
                        voteButton.click();
                        await new Promise(r => setTimeout(r, config.postVoteDelay()));
                        window.location.href = '/en/';
                    }
                } else {
                    console.log('验证未通过,刷新页面...');
                    window.location.reload();
                }
            } catch (error) {
                console.error('投票流程异常:', error);
                window.location.reload();
            }
        }
    }

    // ========== 脚本启动器 ==========
    if (document.readyState === 'complete') main();
    else window.addEventListener('load', main);
})();