Greasy Fork

Greasy Fork is available in English.

Microsoft Bing Rewards 自动搜索助手

自动完成 Microsoft Rewards 在必应(Bing)上的每日搜索任务,带有可配置的UI界面,模拟人工操作以提高安全性。目前最稳定的脚本,全自动完成电脑端90分任务。

// ==UserScript==
// @name         Microsoft Bing Rewards 自动搜索助手
// @name:en      Microsoft Bing Rewards Auto Searcher
// @namespace    WretchedSniper
// @version      1.1.2
// @description  自动完成 Microsoft Rewards 在必应(Bing)上的每日搜索任务,带有可配置的UI界面,模拟人工操作以提高安全性。目前最稳定的脚本,全自动完成电脑端90分任务。
// @description:en  Automatically completes Microsoft Rewards daily search tasks on Bing. Features a configurable UI and mimics human behavior for better safety.
// @author       WretchedSniper
// @match        *://*.bing.com/*
// @grant        none
// @run-at       document-end
// @license      MIT
// @icon         https://www.bing.com/favicon.ico
// ==/UserScript==

(function () {
    'use strict';

    // 存储搜索词和当前进度
    let mainPageSearchTerms = []; // 主页面搜索词
    let iframeSearchTerms = []; // iframe搜索词
    let usedSearchTerms = []; // 已使用的搜索词
    let currentProgress = {
        current: 0,
        total: 0,
        lastChecked: 0, // 上次检查时的进度
        completed: false, // 任务是否已完成
        noProgressCount: 0 // 连续未增加进度的次数
    };
    let isSearching = false;
    let countdownTimer = null;

    // 配置参数
    const config = {
        restTime: 5 * 60, // 无进度时休息时间(秒)
        scrollTime: 10, // 滚动时间(秒)
        waitTime: 10, // 获取进度后等待时间(秒)
        searchInterval: [5, 10], // 搜索间隔范围(秒)
        maxNoProgressCount: 3 // 连续多少次不增加分数才休息
    };

    // 工作状态
    const searchState = {
        currentAction: 'idle', // 当前动作:idle, searching, scrolling, checking, waiting, resting
        countdown: 0, // 倒计时
        needRest: false, // 是否需要休息
        isCollapsed: false // UI是否折叠
    };

    // 创建UI控件
    function createUI() {
        const container = document.createElement('div');
        container.id = 'rewards-helper-container';
        container.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background-color: white;
            border: 1px solid #ddd;
            border-radius: 5px;
            padding: 10px;
            z-index: 10000;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            width: 300px;
        `;

        const header = document.createElement('div');
        header.style.cssText = `
            font-weight: bold;
            margin-bottom: 10px;
            border-bottom: 1px solid #ddd;
            padding-bottom: 5px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            cursor: move;
        `;

        const headerTitle = document.createElement('span');
        headerTitle.textContent = 'Microsoft Rewards 助手';
        header.appendChild(headerTitle);

        const controlsContainer = document.createElement('div');
        controlsContainer.style.display = 'flex';
        controlsContainer.style.alignItems = 'center';

        // --- 广告区域 ---
        const adContainer = document.createElement('div');
        adContainer.style.cssText = 'position: relative; margin-right: 15px;';

        const adTrigger = document.createElement('span');
        adTrigger.textContent = '领红包';
        adTrigger.style.cssText = 'cursor: pointer; font-size: 12px; color: #f44336; font-weight: bold;';

        const qrCodeImageUrls = [
            'https://image.baidu.com/search/down?url=https://wx2.sinaimg.cn/mw690/006nCHZDgy1i2fa24fhc5j30u017jage.jpg',
            'https://image.baidu.com/search/down?url=https://wx1.sinaimg.cn/mw690/006nCHZDgy1i2fay7ltqdj30u017jn67.jpg'
        ];

        const qrCodeContainer = document.createElement('div');
        qrCodeContainer.style.cssText = `
            display: none;
            position: absolute;
            background-color: white;
            padding: 5px;
            border: 1px solid #ccc;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0,0,0,0.2);
            z-index: 10002;
            flex-direction: column;
            gap: 5px;
        `;

        qrCodeImageUrls.forEach(url => {
            if (!url.startsWith('//')) { // 忽略被注释掉的链接
                const img = document.createElement('img');
                img.src = url;
                img.style.cssText = `
                    width: 225px;
                    height: auto;
                    display: block;
                `;
                qrCodeContainer.appendChild(img);
            }
        });

        adTrigger.addEventListener('mouseenter', () => {
            // Set default position (below and centered) before showing
            qrCodeContainer.style.top = '100%';
            qrCodeContainer.style.bottom = 'auto';
            qrCodeContainer.style.left = '50%';
            qrCodeContainer.style.right = 'auto';
            qrCodeContainer.style.transform = 'translateX(-50%)';

            qrCodeContainer.style.display = 'flex';

            setTimeout(() => {
                if (qrCodeContainer.childElementCount === 0) return;

                const containerRect = qrCodeContainer.getBoundingClientRect();
                const viewportWidth = window.innerWidth;
                const viewportHeight = window.innerHeight;

                // Check vertical overflow
                if (containerRect.bottom > viewportHeight) {
                    qrCodeContainer.style.top = 'auto';
                    qrCodeContainer.style.bottom = '100%';
                }

                // Must re-get rect after potential vertical adjustment
                const finalContainerRect = qrCodeContainer.getBoundingClientRect();

                // Check horizontal overflow
                if (finalContainerRect.right > viewportWidth) {
                    qrCodeContainer.style.left = 'auto';
                    qrCodeContainer.style.right = '0';
                    qrCodeContainer.style.transform = 'none';
                } else if (finalContainerRect.left < 0) {
                    qrCodeContainer.style.left = '0';
                    qrCodeContainer.style.right = 'auto';
                    qrCodeContainer.style.transform = 'none';
                }
            }, 0);
        });

        adTrigger.addEventListener('mouseleave', () => {
            qrCodeContainer.style.display = 'none';
            // Reset position so it can be recalculated next time
            qrCodeContainer.style.top = '';
            qrCodeContainer.style.bottom = '';
            qrCodeContainer.style.left = '';
            qrCodeContainer.style.right = '';
            qrCodeContainer.style.transform = '';
        });

        adContainer.appendChild(adTrigger);
        adContainer.appendChild(qrCodeContainer);
        controlsContainer.appendChild(adContainer);

        const minimizeBtn = document.createElement('span');
        minimizeBtn.id = 'minimize-btn';
        minimizeBtn.textContent = '折叠';
        minimizeBtn.style.cssText = `
            cursor: pointer;
            font-size: 14px;
            margin-right: 8px;
        `;
        minimizeBtn.onclick = toggleCollapse;
        controlsContainer.appendChild(minimizeBtn);

        const closeBtn = document.createElement('span');
        closeBtn.textContent = '×';
        closeBtn.style.cssText = `
            cursor: pointer;
            font-size: 18px;
        `;
        closeBtn.onclick = function () {
            container.style.display = 'none';
        };
        controlsContainer.appendChild(closeBtn);
        header.appendChild(controlsContainer);

        const content = document.createElement('div');
        content.id = 'rewards-helper-content';
        content.style.cssText = `
            margin-bottom: 10px;
        `;

        const progress = document.createElement('div');
        progress.id = 'rewards-progress';
        progress.textContent = '进度: 加载中...';
        content.appendChild(progress);

        const searchStatus = document.createElement('div');
        searchStatus.id = 'search-status';
        searchStatus.style.cssText = `
            margin-top: 5px;
            font-style: italic;
        `;
        content.appendChild(searchStatus);

        const countdown = document.createElement('div');
        countdown.id = 'countdown';
        countdown.style.cssText = `
            margin-top: 5px;
            font-weight: bold;
            color: #0078d4;
        `;
        content.appendChild(countdown);

        const searchTermsContainer = document.createElement('div');
        searchTermsContainer.id = 'rewards-search-terms-container';
        searchTermsContainer.style.cssText = `
            margin-top: 10px;
            max-height: 200px;
            overflow-y: auto;
        `;

        const mainTermsTitle = document.createElement('div');
        mainTermsTitle.textContent = '主页面搜索词:';
        mainTermsTitle.style.fontWeight = 'bold';
        searchTermsContainer.appendChild(mainTermsTitle);

        const mainTerms = document.createElement('div');
        mainTerms.id = 'main-search-terms';
        mainTerms.style.cssText = `
            margin-bottom: 10px;
            padding-left: 10px;
        `;
        searchTermsContainer.appendChild(mainTerms);

        const iframeTermsTitle = document.createElement('div');
        iframeTermsTitle.textContent = '侧栏中推荐的搜索词:';
        iframeTermsTitle.style.fontWeight = 'bold';
        searchTermsContainer.appendChild(iframeTermsTitle);

        const iframeTerms = document.createElement('div');
        iframeTerms.id = 'iframe-search-terms';
        iframeTerms.style.cssText = `
            padding-left: 10px;
        `;
        searchTermsContainer.appendChild(iframeTerms);

        content.appendChild(searchTermsContainer);

        const configSection = document.createElement('div');
        configSection.id = 'rewards-config-section';
        configSection.style.cssText = `
            margin-top: 10px;
            border-top: 1px solid #ddd;
            padding-top: 10px;
        `;

        const configTitle = document.createElement('div');
        configTitle.textContent = '配置参数:';
        configTitle.style.fontWeight = 'bold';
        configSection.appendChild(configTitle);

        const configForm = document.createElement('div');
        configForm.style.cssText = `
            display: grid;
            grid-template-columns: auto auto;
            gap: 5px;
            margin-top: 5px;
        `;

        // 添加休息时间配置
        configForm.innerHTML += `
            <label for="rest-time">休息时间(分):</label>
            <input type="number" id="rest-time" value="${config.restTime / 60}" min="1" max="30" style="width: 50px;">
            
            <label for="scroll-time">滚动时间(秒):</label>
            <input type="number" id="scroll-time" value="${config.scrollTime}" min="3" max="30" style="width: 50px;">
            
            <label for="wait-time">等待时间(秒):</label>
            <input type="number" id="wait-time" value="${config.waitTime}" min="3" max="30" style="width: 50px;">
            
            <label for="max-no-progress">容错次数:</label>
            <input type="number" id="max-no-progress" value="${config.maxNoProgressCount}" min="1" max="10" style="width: 50px;">
        `;

        configSection.appendChild(configForm);

        // 添加输入框变化事件监听
        setTimeout(() => {
            const restTimeInput = document.getElementById('rest-time');
            const scrollTimeInput = document.getElementById('scroll-time');
            const waitTimeInput = document.getElementById('wait-time');
            const maxNoProgressInput = document.getElementById('max-no-progress');

            if (restTimeInput) {
                restTimeInput.addEventListener('change', () => {
                    const restTime = parseInt(restTimeInput.value) || 5;
                    config.restTime = restTime * 60;
                    updateStatus('休息时间已更新: ' + restTime + '分钟');
                });
            }

            if (scrollTimeInput) {
                scrollTimeInput.addEventListener('change', () => {
                    const scrollTime = parseInt(scrollTimeInput.value) || 10;
                    config.scrollTime = scrollTime;
                    updateStatus('滚动时间已更新: ' + scrollTime + '秒');
                });
            }

            if (waitTimeInput) {
                waitTimeInput.addEventListener('change', () => {
                    const waitTime = parseInt(waitTimeInput.value) || 10;
                    config.waitTime = waitTime;
                    updateStatus('等待时间已更新: ' + waitTime + '秒');
                });
            }

            if (maxNoProgressInput) {
                maxNoProgressInput.addEventListener('change', () => {
                    const maxNoProgressCount = parseInt(maxNoProgressInput.value) || 3;
                    config.maxNoProgressCount = maxNoProgressCount;
                    updateStatus('容错次数已更新: ' + maxNoProgressCount + '次');
                });
            }
        }, 1000);

        content.appendChild(configSection);

        const buttonsContainer = document.createElement('div');
        buttonsContainer.id = 'rewards-buttons-container';
        buttonsContainer.style.cssText = `
            display: flex;
            justify-content: center;
            margin-top: 10px;
        `;

        const startSearchBtn = document.createElement('button');
        startSearchBtn.id = 'start-search-btn';
        startSearchBtn.textContent = '开始自动搜索';
        startSearchBtn.style.cssText = `
            padding: 5px 10px;
            cursor: pointer;
            background-color: #0078d4;
            color: white;
            border: none;
            border-radius: 3px;
            width: 100%;
        `;
        startSearchBtn.onclick = function () {
            if (!isSearching) {
                startAutomatedSearch();
            } else {
                stopAutomatedSearch();
            }
        };
        buttonsContainer.appendChild(startSearchBtn);

        container.appendChild(header);
        container.appendChild(content);
        container.appendChild(buttonsContainer);
        document.body.appendChild(container);
        makeDraggable(container, header);
    }

    // 让UI窗口可拖动
    function makeDraggable(container, header) {
        let offsetX, offsetY;
        let isDragging = false;

        const onMouseDown = (e) => {
            // 如果点击的是按钮(它们有自己的pointer光标),则不触发拖动
            if (window.getComputedStyle(e.target).cursor === 'pointer') {
                return;
            }

            isDragging = true;

            // 从'right'定位切换到'left'定位
            if (container.style.right) {
                container.style.left = container.offsetLeft + 'px';
                container.style.right = '';
            }

            offsetX = e.clientX - container.offsetLeft;
            offsetY = e.clientY - container.offsetTop;

            document.body.style.userSelect = 'none';
            document.addEventListener('mousemove', onMouseMove);
            document.addEventListener('mouseup', onMouseUp, { once: true }); // Use {once: true} for cleanup
        };

        const onMouseMove = (e) => {
            if (!isDragging) return;

            container.style.top = (e.clientY - offsetY) + 'px';
            container.style.left = (e.clientX - offsetX) + 'px';
        };

        const onMouseUp = () => {
            isDragging = false;
            document.body.style.userSelect = '';
            document.removeEventListener('mousemove', onMouseMove);
        };

        header.addEventListener('mousedown', onMouseDown);
    }

    // 更新状态显示
    function updateStatus(message) {
        const statusElement = document.getElementById('search-status');
        if (statusElement) {
            statusElement.textContent = message;
        }
        console.log(message);
    }

    // 切换UI折叠状态
    function toggleCollapse() {
        searchState.isCollapsed = !searchState.isCollapsed;

        const searchTermsContainer = document.getElementById('rewards-search-terms-container');
        const configSection = document.getElementById('rewards-config-section');
        const buttonsContainer = document.getElementById('rewards-buttons-container');
        const minimizeBtn = document.getElementById('minimize-btn');

        if (searchState.isCollapsed) {
            // 折叠
            if (searchTermsContainer) searchTermsContainer.style.display = 'none';
            if (configSection) configSection.style.display = 'none';
            if (buttonsContainer) buttonsContainer.style.display = 'none';
            if (minimizeBtn) minimizeBtn.textContent = '展开';
        } else {
            // 展开
            if (searchTermsContainer) searchTermsContainer.style.display = 'block';
            if (configSection) configSection.style.display = 'block';
            if (buttonsContainer) buttonsContainer.style.display = 'flex';
            if (minimizeBtn) minimizeBtn.textContent = '折叠';
        }
    }

    // 更新倒计时显示
    function updateCountdown(seconds, action) {
        const countdownElement = document.getElementById('countdown');
        if (countdownElement) {
            if (seconds > 0) {
                let actionText = '';
                switch (action) {
                    case 'scrolling': actionText = '滚动中'; break;
                    case 'waiting': actionText = '等待中'; break;
                    case 'resting': actionText = '休息中'; break;
                    case 'checking': actionText = '检查中'; break;
                    default: actionText = '倒计时';
                }
                countdownElement.textContent = `${actionText}: ${seconds}秒`;
                countdownElement.style.display = 'block';
            } else {
                countdownElement.style.display = 'none';
            }
        }
    }

    // 点击打开侧边栏
    function openRewardsSidebar() {
        const pointsContainer = document.querySelector('.points-container');
        if (pointsContainer) {
            pointsContainer.click();
            console.log('已点击积分按钮,正在打开侧边栏...');
            return true;
        } else {
            console.log('未找到积分按钮');
            return false;
        }
    }

    // 从iframe中获取数据
    function getDataFromIframe() {
        const iframe = document.querySelector('iframe');
        if (!iframe) {
            console.log('未找到iframe');
            return false;
        }

        try {
            const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
            console.log('成功访问iframe文档');

            // 获取进度 - 检查任务完成的几种可能情况
            // 1. 检查包含"你已获得 X 积分"文本的元素
            const allElements = iframeDoc.querySelectorAll('*');
            for (let element of allElements) {
                const text = element.textContent || '';
                if (text.includes('你已获得') && text.includes('积分')) {
                    console.log(`找到完成文本: "${text}"`);
                    const match = text.match(/你已获得\s*(\d+)\s*积分/);
                    if (match) {
                        const totalPoints = parseInt(match[1]);
                        currentProgress.current = totalPoints;
                        currentProgress.total = totalPoints;
                        currentProgress.completed = true;

                        document.getElementById('rewards-progress').textContent = `进度: ${totalPoints}/${totalPoints} (已完成)`;
                        console.log(`搜索任务已完成! 总积分: ${totalPoints}`);
                        return true;
                    }
                }
            }

            // 2. 特定检查promo-title类
            const promoTitleElements = iframeDoc.querySelectorAll('.promo-title');
            if (promoTitleElements.length > 0) {
                for (let element of promoTitleElements) {
                    const text = element.textContent || '';
                    console.log(`找到promo-title元素: "${text}"`);
                    if (text.includes('已获得')) {
                        const match = text.match(/已获得\s*(\d+)\s*积分/);
                        if (match) {
                            const totalPoints = parseInt(match[1]);
                            currentProgress.current = totalPoints;
                            currentProgress.total = totalPoints;
                            currentProgress.completed = true;

                            document.getElementById('rewards-progress').textContent = `进度: ${totalPoints}/${totalPoints} (已完成)`;
                            console.log(`搜索任务已完成! 总积分: ${totalPoints}`);
                            return true;
                        }
                    }
                }
            }

            // 3. 检查是否有"Offer not Completed"的标识
            const offerElements = iframeDoc.querySelectorAll('[aria-label="Offer not Completed"]');
            if (offerElements.length > 0) {
                console.log('找到"Offer not Completed"元素,但仍需检查是否实际完成');
                // 即使有这个标识,也可能已经完成,所以继续检查
                for (let element of offerElements) {
                    const text = element.textContent || '';
                    if (text.includes('已获得') && text.includes('积分')) {
                        console.log(`找到完成文本: "${text}"`);
                        const match = text.match(/已获得\s*(\d+)\s*积分/);
                        if (match) {
                            const totalPoints = parseInt(match[1]);
                            currentProgress.current = totalPoints;
                            currentProgress.total = totalPoints;
                            currentProgress.completed = true;

                            document.getElementById('rewards-progress').textContent = `进度: ${totalPoints}/${totalPoints} (已完成)`;
                            console.log(`搜索任务已完成! 总积分: ${totalPoints}`);
                            return true;
                        }
                    }
                }
            }

            // 如果未完成,获取正常进度
            const progressElement = iframeDoc.querySelector('.daily_search_row span:last-child');
            if (progressElement) {
                const progress = progressElement.textContent;
                document.getElementById('rewards-progress').textContent = '进度: ' + progress;
                console.log('搜索进度: ' + progress);

                // 解析进度数字
                const match = progress.match(/(\d+)\/(\d+)/);
                if (match) {
                    const current = parseInt(match[1]);
                    currentProgress.total = parseInt(match[2]);

                    // 检查进度是否增加
                    if (currentProgress.lastChecked > 0 && current <= currentProgress.lastChecked && isSearching) {
                        console.log(`进度未增加: ${current} <= ${currentProgress.lastChecked},已连续 ${currentProgress.noProgressCount + 1} 次未增加`);
                        currentProgress.noProgressCount++;

                        // 只有当连续多次未增加进度时才休息
                        if (currentProgress.noProgressCount >= config.maxNoProgressCount) {
                            searchState.needRest = true;
                            console.log(`达到最大容错次数 ${config.maxNoProgressCount},需要休息`);
                        }
                    } else if (current > currentProgress.lastChecked) {
                        // 进度增加,重置计数器
                        console.log(`进度增加: ${current} > ${currentProgress.lastChecked},重置未增加计数`);
                        currentProgress.noProgressCount = 0;
                    }

                    currentProgress.current = current;
                    currentProgress.lastChecked = current;

                    // 检查是否完成
                    if (current >= currentProgress.total) {
                        currentProgress.completed = true;
                        console.log(`进度数字表明任务已完成: ${current}/${currentProgress.total}`);
                    }
                }
            } else {
                console.log('未找到进度元素');
            }

            // 获取iframe中的搜索词
            const searchTermsContainer = iframeDoc.querySelector('.ss_items_wrapper');
            if (searchTermsContainer) {
                const terms = [];
                const spans = searchTermsContainer.querySelectorAll('span');
                spans.forEach(span => {
                    terms.push(span.textContent);
                });

                // 保存到iframe搜索词变量
                iframeSearchTerms = [...terms];

                const termsContainer = document.getElementById('iframe-search-terms');
                termsContainer.innerHTML = '';
                terms.forEach(term => {
                    const termElem = document.createElement('div');
                    termElem.textContent = term;
                    termsContainer.appendChild(termElem);
                });
                console.log('找到iframe搜索词: ' + terms.length + '个');
            } else {
                console.log('未找到iframe搜索词容器');
            }

            return true;
        } catch (e) {
            console.log('读取iframe内容出错: ' + e.message);
            return false;
        }
    }

    // 从主文档中获取搜索词
    function getSearchTermsFromMainDoc() {
        const suggestionsContainer = document.querySelector('.richrsrailsugwrapper');
        if (suggestionsContainer) {
            const terms = [];
            const suggestions = suggestionsContainer.querySelectorAll('.richrsrailsuggestion_text');
            suggestions.forEach(suggestion => {
                terms.push(suggestion.textContent);
            });

            // 保存到主页面搜索词变量
            mainPageSearchTerms = [...terms];

            const termsContainer = document.getElementById('main-search-terms');
            termsContainer.innerHTML = '';
            terms.forEach(term => {
                const termElem = document.createElement('div');
                termElem.textContent = term;
                termsContainer.appendChild(termElem);
            });
            console.log('找到主页面搜索词: ' + terms.length + '个');
            return true;
        } else {
            console.log('未找到主页面搜索词');
            return false;
        }
    }

    // 获取Rewards数据
    function getRewardsData(callback) {
        updateStatus('正在获取奖励数据...');
        if (openRewardsSidebar()) {
            // 等待iframe加载
            setTimeout(() => {
                const iframeLoaded = getDataFromIframe();
                const mainTermsLoaded = getSearchTermsFromMainDoc();

                if (!iframeLoaded && !mainTermsLoaded) {
                    updateStatus('获取数据失败,请重试');
                } else {
                    updateStatus('数据获取成功');
                    if (currentProgress.completed) {
                        updateStatus('搜索任务已完成!');
                        if (isSearching) {
                            showCompletionNotification();
                            stopAutomatedSearch();
                        }
                    }
                }

                // 如果检测到需要休息,并且正在搜索
                if (searchState.needRest && isSearching) {
                    startResting();
                } else if (callback) {
                    callback();
                }
            }, 1500);
        } else {
            updateStatus('未找到积分按钮,请确保已登录');
            if (callback) callback();
        }
    }

    // 开始休息
    function startResting() {
        searchState.needRest = false;
        // 重置未增加计数
        currentProgress.noProgressCount = 0;
        updateStatus(`连续 ${config.maxNoProgressCount} 次搜索无进度,休息 ${config.restTime / 60} 分钟后继续`);
        startCountdown(config.restTime, 'resting', () => {
            updateStatus('休息结束,继续搜索');
            setTimeout(performNextSearch, 1000);
        });
    }

    // 获取搜索词(优先主页面,其次iframe)
    function getSearchTerm() {
        // 创建可用搜索词数组(排除已使用的搜索词)
        let availableMainTerms = mainPageSearchTerms.filter(term => !usedSearchTerms.includes(term));
        let availableIframeTerms = iframeSearchTerms.filter(term => !usedSearchTerms.includes(term));

        // 如果所有搜索词都已使用过,重置已使用列表
        if (availableMainTerms.length === 0 && availableIframeTerms.length === 0 &&
            (mainPageSearchTerms.length > 0 || iframeSearchTerms.length > 0)) {
            console.log('所有搜索词已用完,重置已使用列表');
            usedSearchTerms = [];
            availableMainTerms = [...mainPageSearchTerms];
            availableIframeTerms = [...iframeSearchTerms];
        }

        // 优先使用主页面搜索词
        if (availableMainTerms.length > 0) {
            const randomIndex = Math.floor(Math.random() * availableMainTerms.length);
            const term = availableMainTerms[randomIndex];
            // 添加到已使用列表
            usedSearchTerms.push(term);
            console.log(`选择搜索词: ${term} (主页面,还有 ${availableMainTerms.length - 1} 个未使用)`);
            return {
                term: term,
                source: '主页面'
            };
        }
        // 如果主页面没有搜索词,使用iframe搜索词
        else if (availableIframeTerms.length > 0) {
            const randomIndex = Math.floor(Math.random() * availableIframeTerms.length);
            const term = availableIframeTerms[randomIndex];
            // 添加到已使用列表
            usedSearchTerms.push(term);
            console.log(`选择搜索词: ${term} (iframe,还有 ${availableIframeTerms.length - 1} 个未使用)`);
            return {
                term: term,
                source: 'iframe'
            };
        }

        // 如果都没有搜索词,返回null
        return null;
    }

    // 执行搜索
    function performSearch(term) {
        if (!term) return false;

        const searchBox = document.querySelector('#sb_form_q');
        if (searchBox) {
            // 填入搜索词
            searchBox.value = term;

            // 提交搜索
            const searchForm = document.querySelector('#sb_form');
            if (searchForm) {
                searchForm.submit();
                return true;
            }
        }
        return false;
    }

    // 模拟滚动
    function simulateScrolling(callback) {
        updateStatus('正在滚动页面...');
        searchState.currentAction = 'scrolling';

        // 开始倒计时
        startCountdown(config.scrollTime, 'scrolling', callback);

        // 模拟随机滚动
        const scrollInterval = setInterval(() => {
            // 随机滚动距离
            const scrollAmount = Math.floor(Math.random() * 300) + 100;
            const scrollDirection = Math.random() > 0.3 ? 1 : -1; // 70%向下,30%向上

            window.scrollBy(0, scrollAmount * scrollDirection);

            // 如果当前动作不是滚动,停止滚动
            if (searchState.currentAction !== 'scrolling') {
                clearInterval(scrollInterval);
            }
        }, 1000);

        // 滚动结束后停止滚动
        setTimeout(() => {
            clearInterval(scrollInterval);
        }, config.scrollTime * 1000);
    }

    // 检查进度
    function checkProgress(callback) {
        updateStatus('正在检查搜索进度...');
        searchState.currentAction = 'checking';

        if (openRewardsSidebar()) {
            setTimeout(() => {
                getDataFromIframe();
                // 同时从主页面获取搜索词
                getSearchTermsFromMainDoc();

                if (currentProgress.completed) {
                    showCompletionNotification();
                    updateStatus('搜索任务已完成!');
                    stopAutomatedSearch();
                    return;
                }

                if (searchState.needRest) {
                    startResting();
                } else if (callback) {
                    callback();
                }
            }, 1500);
        } else {
            updateStatus('无法打开侧边栏检查进度');
            if (callback) callback();
        }
    }

    // 等待下一次搜索
    function waitForNextSearch() {
        updateStatus('等待下一次搜索...');
        startCountdown(config.waitTime, 'waiting', performNextSearch);
    }

    // 执行下一次搜索
    function performNextSearch() {
        // 如果不在搜索状态,停止
        if (!isSearching) return;

        // 计算还需要搜索的次数
        const remainingSearches = currentProgress.total - currentProgress.current;
        if (remainingSearches <= 0 || currentProgress.completed) {
            showCompletionNotification();
            updateStatus('搜索任务已完成!');
            stopAutomatedSearch();
            return;
        }

        // 先更新搜索词列表,然后再获取搜索词
        updateStatus('获取最新搜索词...');
        getSearchTermsFromMainDoc();

        // 获取搜索词
        const searchTermObj = getSearchTerm();

        if (!searchTermObj) {
            updateStatus('没有可用的搜索词,获取数据...');
            getRewardsData(() => {
                // 重新检查是否有搜索词
                const newSearchTermObj = getSearchTerm();
                if (newSearchTermObj) {
                    // 有搜索词,重新执行搜索
                    setTimeout(performNextSearch, 1000);
                } else {
                    updateStatus('无法获取搜索词,停止搜索');
                    stopAutomatedSearch();
                }
            });
            return;
        }

        const { term, source } = searchTermObj;
        updateStatus(`正在搜索: ${term} (${source}搜索词) [剩余:${remainingSearches}]`);

        if (performSearch(term)) {
            // 搜索成功后模拟滚动
            setTimeout(() => {
                simulateScrolling(() => {
                    // 滚动结束后检查进度
                    checkProgress(() => {
                        // 检查进度后等待下一次搜索
                        waitForNextSearch();
                    });
                });
            }, 2000);
        } else {
            updateStatus('搜索失败,请检查网页状态');
            // 3秒后重试
            setTimeout(performNextSearch, 3000);
        }
    }

    // 开始自动搜索
    function startAutomatedSearch() {
        // 首先检查是否有搜索词,如果没有就获取
        if (mainPageSearchTerms.length === 0 && iframeSearchTerms.length === 0) {
            updateStatus('获取搜索词中...');
            getRewardsData(() => {
                if (mainPageSearchTerms.length === 0 && iframeSearchTerms.length === 0) {
                    alert('没有搜索词,无法开始搜索');
                    return;
                } else {
                    // 有搜索词,开始搜索
                    startSearchProcess();
                }
            });
        } else {
            startSearchProcess();
        }
    }

    // 开始搜索流程
    function startSearchProcess() {
        isSearching = true;
        searchState.needRest = false;
        currentProgress.noProgressCount = 0;  // 重置未增加计数
        usedSearchTerms = []; // 重置已使用搜索词列表
        document.getElementById('start-search-btn').textContent = '停止搜索';
        document.getElementById('start-search-btn').style.backgroundColor = '#d83b01';
        updateStatus('自动搜索已开始...');

        // 计算还需要搜索的次数
        const remainingSearches = currentProgress.total - currentProgress.current;
        if (remainingSearches <= 0 || currentProgress.completed) {
            updateStatus('搜索任务已完成!');
            stopAutomatedSearch();
            return;
        }

        // 开始第一次搜索
        performNextSearch();
    }

    // 停止自动搜索
    function stopAutomatedSearch() {
        // 清除倒计时
        if (countdownTimer) {
            clearInterval(countdownTimer);
            countdownTimer = null;
        }

        isSearching = false;
        searchState.currentAction = 'idle';
        searchState.needRest = false;
        currentProgress.noProgressCount = 0;  // 重置未增加计数
        usedSearchTerms = []; // 重置已使用搜索词列表
        updateCountdown(0, '');

        document.getElementById('start-search-btn').textContent = '开始自动搜索';
        document.getElementById('start-search-btn').style.backgroundColor = '#0078d4';
        updateStatus('搜索已停止');
    }

    // 显示完成通知
    function showCompletionNotification() {
        // 创建通知元素
        const notification = document.createElement('div');
        notification.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: #0078d4;
            color: white;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.2);
            z-index: 10001;
            text-align: center;
            font-size: 16px;
        `;
        notification.innerHTML = `
            <div style="font-weight: bold; margin-bottom: 10px; font-size: 18px;">任务完成!</div>
            <div>已完成所有 ${currentProgress.total} 次搜索任务</div>
            <button id="notification-close" style="
                margin-top: 15px;
                padding: 5px 15px;
                background-color: white;
                color: #0078d4;
                border: none;
                border-radius: 3px;
                cursor: pointer;
            ">关闭</button>
        `;
        document.body.appendChild(notification);

        // 添加关闭按钮事件
        document.getElementById('notification-close').addEventListener('click', function () {
            notification.remove();
        });

        // 10秒后自动关闭
        setTimeout(() => {
            if (document.body.contains(notification)) {
                notification.remove();
            }
        }, 10000);
    }

    // 开始倒计时
    function startCountdown(seconds, action, callback) {
        // 清除现有倒计时
        if (countdownTimer) {
            clearInterval(countdownTimer);
            countdownTimer = null;
        }

        searchState.currentAction = action;
        searchState.countdown = seconds;

        updateCountdown(seconds, action);

        countdownTimer = setInterval(() => {
            searchState.countdown--;
            updateCountdown(searchState.countdown, action);

            if (searchState.countdown <= 0) {
                clearInterval(countdownTimer);
                countdownTimer = null;
                if (callback) callback();
            }
        }, 1000);
    }

    // 在页面加载完成后初始化
    window.addEventListener('load', function () {
        console.log('Microsoft Rewards 助手已加载');
        createUI();
        // 初始获取数据
        setTimeout(() => {
            getRewardsData();
        }, 2000);
    });
})();