Greasy Fork

Greasy Fork is available in English.

Microsoft Rewards 自动搜索助手

自动完成 Microsoft Rewards 在必应(Bing)上的每日搜索任务,带有可配置的UI界面,模拟人工操作以提高安全性。

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

在您安装前,Greasy Fork 希望您知道此脚本声明其包含了一些负面功能。这些功能也许会使脚本作者获利,而不能给您带来任何直接的金钱收益。

此脚本会在您访问的网站中插入广告

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Microsoft Rewards 自动搜索助手
// @name:en      Microsoft Rewards Auto Searcher
// @namespace    WretchedSniper
// @version      1.1.0
// @description  自动完成 Microsoft Rewards 在必应(Bing)上的每日搜索任务,带有可配置的UI界面,模拟人工操作以提高安全性。
// @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/*
// @antifeature  ads
// @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 = 'iframe中的搜索词:';
        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);
    });
})();