Greasy Fork

Greasy Fork is available in English.

原神激励领奖

B站原神激励活动自动领奖脚本,支持自动解锁按钮、可调节点击间隔、智能停止检测,提供一键控制和优雅的消息提示系统

当前为 2025-06-07 提交的版本,查看 最新版本

// ==UserScript==
// @name         原神激励领奖
// @namespace    http://tampermonkey.net/
// @version      2025-06-19
// @description  B站原神激励活动自动领奖脚本,支持自动解锁按钮、可调节点击间隔、智能停止检测,提供一键控制和优雅的消息提示系统
// @author       You
// @match        https://www.bilibili.com/blackboard/new-award-exchange.html*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=bilibili.com
// @license      MIT
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    let clickInterval = null;
    let isAutoClicking = false;
    let clickIntervalMs = 500; // Default click interval
    let timeUpdateInterval = null;
    let errorCheckInterval = null;
    let autoTriggerInterval = null;
    let autoVerifyEnabled = true; // Default enabled for auto verification click
    let autoRefreshEnabled = false; // Default disabled for auto refresh
    let hasAutoVerifyClicked = false; // Track if auto verify click has been done

    // List of stop texts
    const stopTexts = ["查看奖励", "每日库存已达上限", "暂无领取资格"];

    // Message container for stacking notifications
    let messageContainer = null;

    // Load saved click interval from localStorage
    function loadClickInterval() {
        const saved = localStorage.getItem('auto-click-interval');
        if (saved && [100, 200, 500, 800, 1000].includes(parseInt(saved))) {
            clickIntervalMs = parseInt(saved);
        } else {
            // If no valid saved value, save the current default to localStorage
            saveClickInterval(clickIntervalMs);
        }
    }

    // Save click interval to localStorage
    function saveClickInterval(interval) {
        localStorage.setItem('auto-click-interval', interval.toString());
    }

    // Load saved settings from localStorage
    function loadSettings() {
        const autoVerify = localStorage.getItem('auto-verify-enabled');
        if (autoVerify !== null) {
            autoVerifyEnabled = autoVerify === 'true';
        }
        
        const autoRefresh = localStorage.getItem('auto-refresh-enabled');
        if (autoRefresh !== null) {
            autoRefreshEnabled = autoRefresh === 'true';
        }
    }

    // Save settings to localStorage
    function saveSettings() {
        localStorage.setItem('auto-verify-enabled', autoVerifyEnabled.toString());
        localStorage.setItem('auto-refresh-enabled', autoRefreshEnabled.toString());
    }

    // Check for page activity state and auto-click for verification
    function checkAutoVerifyClick() {
        if (!autoVerifyEnabled || hasAutoVerifyClicked) return;
        
        const button = document.querySelector("#app > div > div.home-wrap.select-disable > section.tool-wrap > div.button.exchange-button");
        if (button && !button.classList.contains('disable')) {
            // Skip auto verification if button already shows "查看奖励"
            if (button.textContent.trim() === "查看奖励") {
                console.log('Skipping auto verification: button shows "查看奖励"');
                hasAutoVerifyClicked = true; // Mark as done to prevent further checks
                return;
            }
            
            // Page seems to be in active state, do one verification click
            console.log('Auto verification click triggered');
            showMessage('自动验证点击已执行', 'info');
            button.click();
            hasAutoVerifyClicked = true;
        }
    }

    // Check for auto refresh at 00:59:59
    function checkAutoRefresh() {
        if (!autoRefreshEnabled) return;
        
        const now = new Date();
        const hours = now.getHours();
        const minutes = now.getMinutes();
        const seconds = now.getSeconds();
        
        // Check if time is 00:59:59
        if (hours === 0 && minutes === 59 && seconds === 59) {
            console.log('Auto refresh triggered at 00:59:59');
            showMessage('到达刷新时间,正在刷新页面...', 'info');
            
            // Stop all intervals before refresh
            if (errorCheckInterval) clearInterval(errorCheckInterval);
            if (timeUpdateInterval) clearInterval(timeUpdateInterval);
            if (clickInterval) clearInterval(clickInterval);
            if (autoTriggerInterval) clearInterval(autoTriggerInterval);
            
            setTimeout(() => {
                window.location.reload();
            }, 1000);
        }
    }

    // Function to create real-time clock display
    function createRealTimeClock() {
        // Create clock container
        const clockContainer = document.createElement('div');
        clockContainer.id = 'real-time-clock';
        clockContainer.style.cssText = `
            background: linear-gradient(135deg, rgba(74, 144, 226, 0.9), rgba(126, 208, 255, 0.9));
            color: #FFFFFF;
            padding: 12px 16px;
            border-radius: 8px;
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
            text-align: center;
            border: 1px solid rgba(255, 255, 255, 0.3);
            box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
            backdrop-filter: blur(8px);
            min-width: 160px;
            margin-bottom: 8px;
        `;

        // Create time display element (first line)
        const timeDisplay = document.createElement('div');
        timeDisplay.id = 'time-display';
        timeDisplay.style.cssText = `
            font-size: 16px;
            font-weight: 600;
            line-height: 1.2;
            text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
            margin-bottom: 2px;
        `;
        timeDisplay.textContent = '00:00:00.000';

        // Create date display element (second line)
        const dateDisplay = document.createElement('div');
        dateDisplay.id = 'date-display';
        dateDisplay.style.cssText = `
            font-size: 12px;
            font-weight: 400;
            opacity: 0.9;
            text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
        `;
        dateDisplay.textContent = '2025-01-07';

        clockContainer.appendChild(timeDisplay);
        clockContainer.appendChild(dateDisplay);

        // Create verification notice
        const noticeContainer = document.createElement('div');
        noticeContainer.id = 'verification-notice';
        noticeContainer.style.cssText = `
            background: linear-gradient(135deg, rgba(116, 185, 255, 0.9), rgba(162, 210, 255, 0.9));
            color: #1a365d;
            padding: 8px 12px;
            border-radius: 6px;
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
            text-align: center;
            border: 1px solid rgba(255, 255, 255, 0.3);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            backdrop-filter: blur(6px);
            min-width: 160px;
            margin-bottom: 8px;
        `;

        const noticeText = document.createElement('div');
        noticeText.style.cssText = `
            font-size: 11px;
            font-weight: 500;
            line-height: 1.3;
            text-shadow: 0 1px 2px rgba(255, 255, 255, 0.5);
        `;
        noticeText.innerHTML = '💡 请先手动领奖一次<br>通过验证码检测';

        noticeContainer.appendChild(noticeText);

        // Create container for both
        const rightSideContainer = document.createElement('div');
        rightSideContainer.id = 'right-side-container';
        rightSideContainer.style.cssText = `
            position: fixed;
            top: 20px;
            right: 220px;
            z-index: 9998;
            display: flex;
            flex-direction: column;
        `;

        rightSideContainer.appendChild(clockContainer);
        rightSideContainer.appendChild(noticeContainer);

        // Create hidden iframe to load bjtime.net
        const iframe = document.createElement('iframe');
        iframe.src = 'https://www.bjtime.net/';
        iframe.style.cssText = `
            position: absolute;
            top: -9999px;
            left: -9999px;
            width: 1px;
            height: 1px;
            border: none;
            opacity: 0;
            pointer-events: none;
        `;
        iframe.id = 'time-iframe';

        document.body.appendChild(rightSideContainer);
        document.body.appendChild(iframe);

        // Handle iframe load
        iframe.onload = function() {
            try {
                startTimeUpdater(iframe, timeDisplay, dateDisplay);
            } catch (error) {
                console.log('Failed to access iframe content, using local time');
                startLocalTimeUpdater(timeDisplay, dateDisplay);
            }
        };

        // Fallback to local time if iframe fails to load
        iframe.onerror = function() {
            console.log('Failed to load bjtime.net, using local time');
            startLocalTimeUpdater(timeDisplay, dateDisplay);
        };

        // Timeout fallback
        setTimeout(() => {
            if (timeDisplay.textContent === '00:00:00.000') {
                console.log('Timeout loading bjtime.net, using local time');
                startLocalTimeUpdater(timeDisplay, dateDisplay);
            }
        }, 5000);
    }

    // Function to start time updater using iframe
    function startTimeUpdater(iframe, timeDisplay, dateDisplay) {
        timeUpdateInterval = setInterval(() => {
            try {
                const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
                const timeElement = iframeDoc.querySelector('#cTime');
                
                if (timeElement && timeElement.textContent) {
                    const fullTime = timeElement.textContent;
                    updateTimeDisplay(fullTime, timeDisplay, dateDisplay);
                } else {
                    // Fallback to local time if can't find element
                    updateLocalTime(timeDisplay, dateDisplay);
                }
            } catch (error) {
                // Cross-origin error, fallback to local time
                updateLocalTime(timeDisplay, dateDisplay);
            }
        }, 100); // Update every 100ms
    }

    // Function to start local time updater
    function startLocalTimeUpdater(timeDisplay, dateDisplay) {
        timeUpdateInterval = setInterval(() => {
            updateLocalTime(timeDisplay, dateDisplay);
        }, 100);
    }

    // Function to update time display with parsed time
    function updateTimeDisplay(fullTime, timeDisplay, dateDisplay) {
        // Parse time string like "2025-01-07 14:30:25.123"
        const parts = fullTime.split(' ');
        if (parts.length >= 2) {
            dateDisplay.textContent = parts[0]; // Date part
            timeDisplay.textContent = parts[1]; // Time part
        } else {
            // Fallback to local time if parsing fails
            updateLocalTime(timeDisplay, dateDisplay);
        }
    }

    // Function to update with local time
    function updateLocalTime(timeDisplay, dateDisplay) {
        const now = new Date();
        const dateString = now.getFullYear() + '-' + 
                          String(now.getMonth() + 1).padStart(2, '0') + '-' + 
                          String(now.getDate()).padStart(2, '0');
        const timeString = String(now.getHours()).padStart(2, '0') + ':' + 
                          String(now.getMinutes()).padStart(2, '0') + ':' + 
                          String(now.getSeconds()).padStart(2, '0') + '.' + 
                          String(now.getMilliseconds()).padStart(3, '0');
        
        dateDisplay.textContent = dateString;
        timeDisplay.textContent = timeString;
    }

    // Function to create message container
    function createMessageContainer() {
        if (!messageContainer) {
            messageContainer = document.createElement('div');
            messageContainer.id = 'message-container';
            messageContainer.style.cssText = `
                position: fixed;
                top: 140px;
                right: 220px;
                z-index: 10000;
                display: flex;
                flex-direction: column;
                gap: 10px;
                pointer-events: none;
            `;
            document.body.appendChild(messageContainer);
        }
        return messageContainer;
    }

    // Function to show non-blocking message notification
    function showMessage(message, type = 'info') {
        const container = createMessageContainer();
        
        const notification = document.createElement('div');
        notification.textContent = message;
        notification.style.cssText = `
            padding: 12px 20px;
            background-color: ${type === 'error' ? '#FF6B6B' : type === 'success' ? '#51CF66' : '#339AF0'};
            color: white;
            border-radius: 8px;
            font-size: 14px;
            font-weight: bold;
            box-shadow: 0 4px 12px rgba(0,0,0,0.3);
            max-width: 300px;
            word-wrap: break-word;
            transform: translateX(100%);
            opacity: 0;
            transition: all 0.3s ease-out;
            pointer-events: auto;
        `;
        
        container.appendChild(notification);
        
        // Trigger slide-in animation
        setTimeout(() => {
            notification.style.transform = 'translateX(0)';
            notification.style.opacity = '1';
        }, 10);
        
        // Auto remove after 3 seconds
        setTimeout(() => {
            notification.style.transform = 'translateX(100%)';
            notification.style.opacity = '0';
            setTimeout(() => {
                if (notification.parentNode) {
                    notification.remove();
                }
            }, 300);
        }, 3000);
    }

    // Function to remove disable class from button
    function removeDisableClass() {
        const button = document.querySelector("#app > div > div.home-wrap.select-disable > section.tool-wrap > div.button.exchange-button");
        if (button) {
            button.classList.remove("disable");
            console.log("Disable class removed from button");
        }
    }

    // Function to start/stop auto clicking
    function toggleAutoClick() {
        const button = document.querySelector("#app > div > div.home-wrap.select-disable > section.tool-wrap > div.button.exchange-button");
        
        if (isAutoClicking) {
            // Stop clicking
            if (clickInterval) {
                clearInterval(clickInterval);
                clickInterval = null;
            }
            isAutoClicking = false;
            updateControlButton();
            showMessage("已停止自动领奖", "info");
            return;
        }

        if (!button) {
            showMessage("找不到领奖按钮!", "error");
            return;
        }

        // Start clicking
        isAutoClicking = true;
        updateControlButton();
        showMessage(`开始自动领奖 (${clickIntervalMs}ms间隔)`, "success");

        clickInterval = setInterval(() => {
            if (button) {
                // Check if button text is in stopTexts
                if (stopTexts.includes(button.textContent.trim())) {
                    clearInterval(clickInterval);
                    clickInterval = null;
                    isAutoClicking = false;
                    updateControlButton();
                    showMessage(`已停止领奖!原因:${button.textContent.trim()}`, "info");
                    return;
                }
                button.click();
            } else {
                clearInterval(clickInterval);
                clickInterval = null;
                isAutoClicking = false;
                updateControlButton();
            }
        }, clickIntervalMs); // Use selected interval

        // Stop clicking after 30 seconds for safety
        setTimeout(() => {
            if (clickInterval) {
                clearInterval(clickInterval);
                clickInterval = null;
                isAutoClicking = false;
                updateControlButton();
                showMessage("自动领奖已超时停止", "info");
            }
        }, 30000);
    }

    // Function to create and add control button
    function createControlButton() {
        const controlButton = document.createElement("button");
        controlButton.id = "auto-click-control";
        controlButton.textContent = "开始自动领奖";
        controlButton.style.cssText = `
            width: 100%;
            padding: 10px 15px;
            background-color: #00A1D6;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-size: 14px;
            font-weight: bold;
            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
            margin-bottom: 8px;
        `;
        
        controlButton.addEventListener("click", toggleAutoClick);
        
        // Add hover effect
        controlButton.addEventListener("mouseenter", function() {
            this.style.backgroundColor = "#0088CC";
        });
        controlButton.addEventListener("mouseleave", function() {
            this.style.backgroundColor = isAutoClicking ? "#FF6B6B" : "#00A1D6";
        });

        return controlButton;
    }

    // Function to update control button text and style
    function updateControlButton() {
        const controlButton = document.getElementById("auto-click-control");
        if (controlButton) {
            if (isAutoClicking) {
                controlButton.textContent = "停止自动领奖";
                controlButton.style.backgroundColor = "#FF6B6B";
            } else {
                controlButton.textContent = "开始自动领奖";
                controlButton.style.backgroundColor = "#00A1D6";
            }
        }
    }

    // Function to create interval selector
    function createIntervalSelector() {
        const selectorContainer = document.createElement("div");
        selectorContainer.style.cssText = `
            display: flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 8px;
        `;

        const label = document.createElement("label");
        label.textContent = "间隔:";
        label.style.cssText = `
            color: #333;
            font-size: 12px;
            font-weight: bold;
            text-shadow: 1px 1px 2px rgba(255,255,255,0.8);
            min-width: 35px;
        `;

        const selector = document.createElement("select");
        selector.id = "interval-selector";
        selector.style.cssText = `
            padding: 4px 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
            background-color: white;
            font-size: 12px;
            cursor: pointer;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            flex: 1;
        `;

        // Add options
        const options = [
            { value: 100, text: "100ms (极快)" },
            { value: 200, text: "200ms (快)" },
            { value: 500, text: "500ms (中)" },
            { value: 800, text: "800ms (慢)" },
            { value: 1000, text: "1000ms (很慢)" }
        ];

        options.forEach(option => {
            const optionElement = document.createElement("option");
            optionElement.value = option.value;
            optionElement.textContent = option.text;
            if (option.value === clickIntervalMs) {
                optionElement.selected = true;
            }
            selector.appendChild(optionElement);
        });

        // Handle selection change
        selector.addEventListener("change", function() {
            clickIntervalMs = parseInt(this.value);
            saveClickInterval(clickIntervalMs);
            showMessage(`点击间隔已设置为 ${clickIntervalMs}ms`, "info");
            
            // If currently auto clicking, restart with new interval
            if (isAutoClicking) {
                toggleAutoClick(); // Stop
                setTimeout(() => {
                    toggleAutoClick(); // Start with new interval
                }, 100);
            }
        });

        selectorContainer.appendChild(label);
        selectorContainer.appendChild(selector);
        return selectorContainer;
    }

    // Function to create tooltip
    function createTooltip(text) {
        const tooltip = document.createElement('div');
        tooltip.style.cssText = `
            position: absolute;
            background: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 8px 12px;
            border-radius: 4px;
            font-size: 11px;
            white-space: nowrap;
            z-index: 10001;
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.3s ease;
            bottom: 100%;
            right: 0;
            margin-bottom: 5px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.3);
        `;
        tooltip.textContent = text;
        return tooltip;
    }

    // Function to create switch button control
    function createSwitchControl(id, labelText, isChecked, onChange, tooltipText) {
        const container = document.createElement("div");
        container.style.cssText = `
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 8px;
            user-select: none;
            position: relative;
        `;

        const label = document.createElement("span");
        label.textContent = labelText;
        label.style.cssText = `
            color: #333;
            font-size: 12px;
            font-weight: bold;
            text-shadow: 1px 1px 2px rgba(255,255,255,0.8);
        `;

        // Create switch button
        const switchButton = document.createElement("div");
        switchButton.id = id;
        switchButton.style.cssText = `
            position: relative;
            width: 44px;
            height: 24px;
            background-color: ${isChecked ? '#4CAF50' : '#ccc'};
            border-radius: 24px;
            cursor: pointer;
            transition: background-color 0.3s ease;
            box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
        `;

        // Create switch thumb
        const switchThumb = document.createElement("div");
        switchThumb.style.cssText = `
            position: absolute;
            top: 2px;
            left: ${isChecked ? '22px' : '2px'};
            width: 20px;
            height: 20px;
            background-color: white;
            border-radius: 50%;
            transition: left 0.3s ease;
            box-shadow: 0 2px 4px rgba(0,0,0,0.2);
        `;

        switchButton.appendChild(switchThumb);

        // Create tooltip if provided
        if (tooltipText) {
            const tooltip = createTooltip(tooltipText);
            container.appendChild(tooltip);

            // Add tooltip events
            switchButton.addEventListener("mouseenter", function() {
                this.style.transform = 'scale(1.05)';
                tooltip.style.opacity = '1';
            });
            switchButton.addEventListener("mouseleave", function() {
                this.style.transform = 'scale(1)';
                tooltip.style.opacity = '0';
            });
        } else {
            // Add hover effect without tooltip
            switchButton.addEventListener("mouseenter", function() {
                this.style.transform = 'scale(1.05)';
            });
            switchButton.addEventListener("mouseleave", function() {
                this.style.transform = 'scale(1)';
            });
        }

        // Add click handler
        let currentState = isChecked;
        switchButton.addEventListener("click", function() {
            currentState = !currentState;
            
            // Update visual state
            switchButton.style.backgroundColor = currentState ? '#4CAF50' : '#ccc';
            switchThumb.style.left = currentState ? '22px' : '2px';
            
            // Call onChange with new state
            onChange.call({ checked: currentState });
        });

        container.appendChild(label);
        container.appendChild(switchButton);
        return container;
    }

    // Function to create main control panel
    function createControlPanel() {
        const panel = document.createElement("div");
        panel.id = "control-panel";
        panel.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 9999;
            background: rgba(255, 255, 255, 0.95);
            padding: 12px;
            border-radius: 8px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.3);
            min-width: 180px;
            display: flex;
            flex-direction: column;
        `;

        // Add control button
        const controlButton = createControlButton();
        panel.appendChild(controlButton);

        // Add interval selector
        const intervalSelector = createIntervalSelector();
        panel.appendChild(intervalSelector);

        // Add auto verify switch
        const autoVerifyControl = createSwitchControl(
            "auto-verify-switch",
            "自动验证",
            autoVerifyEnabled,
            function() {
                autoVerifyEnabled = this.checked;
                saveSettings();
                showMessage(`自动验证已${autoVerifyEnabled ? '开启' : '关闭'}`, "info");
                if (!autoVerifyEnabled) {
                    hasAutoVerifyClicked = false; // Reset if disabled
                }
            },
            "页面活跃后自动点击一次领奖按钮,用于通过验证码检测"
        );
        panel.appendChild(autoVerifyControl);

        // Add auto refresh switch
        const autoRefreshControl = createSwitchControl(
            "auto-refresh-switch",
            "定时刷新",
            autoRefreshEnabled,
            function() {
                autoRefreshEnabled = this.checked;
                saveSettings();
                showMessage(`定时刷新已${autoRefreshEnabled ? '开启' : '关闭'} (00:59:59)`, "info");
            },
            "每天00:59:59时自动刷新页面,适用于跨天活动"
        );
        panel.appendChild(autoRefreshControl);

        document.body.appendChild(panel);
    }

    // Function to check for auto-trigger condition
    function checkAutoTrigger() {
        // Don't auto-trigger if already clicking
        if (isAutoClicking) return;
        
        const button = document.querySelector("#app > div > div.home-wrap.select-disable > section.tool-wrap > div.button.exchange-button");
        if (button && button.textContent.trim() === "领取奖励") {
            console.log('Auto-trigger detected: button text is "领取奖励"');
            showMessage('检测到"领取奖励",自动开始领奖', 'success');
            
            // Small delay to ensure message is visible
            setTimeout(() => {
                toggleAutoClick();
            }, 500);
        }
    }

    // Function to start auto-trigger monitoring
    function startAutoTriggerMonitoring() {
        // Check every 2 seconds for auto-trigger condition
        autoTriggerInterval = setInterval(() => {
            checkAutoTrigger();
            checkAutoVerifyClick(); // Also check for auto verify click
            checkAutoRefresh(); // Also check for auto refresh
        }, 2000);
    }

    // Function to check for page load error dialog
    function checkForErrorDialog() {
        const errorDialog = document.querySelector('body > div.v-dialog > div.v-dialog__wrap > div > div.v-dialog__body');
        if (errorDialog) {
            console.log('Error dialog detected, refreshing page...');
            showMessage('检测到页面错误,正在刷新...', 'info');
            
            // Stop all intervals before refresh
            if (errorCheckInterval) {
                clearInterval(errorCheckInterval);
            }
            if (timeUpdateInterval) {
                clearInterval(timeUpdateInterval);
            }
            if (clickInterval) {
                clearInterval(clickInterval);
            }
            if (autoTriggerInterval) {
                clearInterval(autoTriggerInterval);
            }
            
            // Refresh page after a short delay
            setTimeout(() => {
                window.location.reload();
            }, 1000);
            
            return true;
        }
        return false;
    }

    // Function to start error monitoring
    function startErrorMonitoring() {
        // Check immediately
        if (checkForErrorDialog()) return;
        
        // Check every 1 second permanently
        errorCheckInterval = setInterval(() => {
            checkForErrorDialog();
        }, 1000);
    }

    // Initialize when page loads
    function init() {
        // Wait for page to fully load
        setTimeout(() => {
            loadClickInterval(); // Load saved click interval
            loadSettings();
            removeDisableClass();
            createControlPanel();
            createRealTimeClock();
            startErrorMonitoring();
            startAutoTriggerMonitoring();
            console.log("Auto-click userscript initialized");
        }, 100);
    }

    // Run initialization when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

    // Also remove disable class periodically in case it gets re-added
    // setInterval(removeDisableClass, 2000);

})();