Greasy Fork

Greasy Fork is available in English.

Microsoft Rewards 自动获取搜索积分

MIANKRAM

当前为 2025-12-11 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Microsoft Rewards 自动获取搜索积分
// @namespace    http://tampermonkey.net/
// @version      1.4.3
// @description  MIANKRAM
// @author       自动完成Microsoft Rewards每日搜索任务,显示今日积分获取进度,自动计算搜索次数,积分等级1和等级2均可使用
// @match        *://*/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_openInTab
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_addValueChangeListener
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// @license      apache 2.0
// ==/UserScript==
 
(function () {
    'use strict';
 
    if (window.self !== window.top) return;
 
    const CONFIG = {
        rewardsUrl: "https://rewards.bing.com/redeem/pointsbreakdown",
        searchBaseUrl: "https://www.bing.com/search?q=",
        weiboApi: "https://weibo.com/ajax/side/hotSearch",
        keys: {
            l1: 'rewardsPointsLevel1',
            l2: 'rewardsPointsLevel2',
            status: 'rewardsGlobalStatus',
            trigger: 'rewardsStartSignal',
            total: 'rewardsTotalPoints' 
        },
        selectors: {
            total: "#rh_rwm > div > span.points-container",
            l1_pc: "#userPointsBreakdown > div > div:nth-child(2) > div > div > div > div.pointsDetail > mee-rewards-user-points-details > div > div > div > div > p.pointsDetail.c-subheading-3.ng-binding",
            l2_pc: "#userPointsBreakdown > div > div:nth-child(2) > div > div:nth-child(1) > div > div.pointsDetail > mee-rewards-user-points-details > div > div > div > div > p.pointsDetail.c-subheading-3.ng-binding",
            l2_mobile: "#userPointsBreakdown > div > div:nth-child(2) > div > div:nth-child(2) > div > div.pointsDetail > mee-rewards-user-points-details > div > div > div > div > p.pointsDetail.c-subheading-3.ng-binding"
        }
    };
 
    const INSTANCE_ID = Math.random().toString(36).substr(2, 9);
 
    let state = {
        isRunning: false,
        isRemoteRunning: false,
        hotWords: [],
        timers: {
            search: null,
            countdown: null,
            slaveCountdown: null,
            sync: null,
            heartbeat: null
        }
    };
 
    const FALLBACK_KEYWORDS = [
        "2025科技趋势", "Surface新款", "Python教程", "天气预报", "健康食谱",
        "股市行情", "新能源车", "ChatGPT技巧", "旅游攻略", "电影推荐",
        "SpaceX发射", "AI发展", "量子计算", "亚运会", "华为Mate60",
        "油价调整", "社保查询", "个税计算", "考研资料", "公务员考试"
    ];
 
    if (location.href.startsWith(CONFIG.rewardsUrl)) {
        const checkExist = setInterval(function () {
            const l1El = document.querySelector(CONFIG.selectors.l1_pc);
            const l2PcEl = document.querySelector(CONFIG.selectors.l2_pc);
            const l2MobEl = document.querySelector(CONFIG.selectors.l2_mobile);
 
            if (l1El || (l2PcEl && l2MobEl)) {
                clearInterval(checkExist);
 
                setTimeout(() => {
                    const finalL1El = document.querySelector(CONFIG.selectors.l1_pc);
                    const finalL2PcEl = document.querySelector(CONFIG.selectors.l2_pc);
                    const finalL2MobEl = document.querySelector(CONFIG.selectors.l2_mobile);
 
                    let dataToSave = {};
                    
                    if (finalL2PcEl && finalL2MobEl) {
                        dataToSave = {
                            level: 2,
                            pc: finalL2PcEl.innerText,
                            mobile: finalL2MobEl.innerText,
                            timestamp: Date.now()
                        };
                        GM_setValue(CONFIG.keys.l2, dataToSave);
                        GM_setValue(CONFIG.keys.l1, null);
                    } else if (finalL1El) {
                        dataToSave = {
                            level: 1,
                            pc: finalL1El.innerText,
                            timestamp: Date.now()
                        };
                        GM_setValue(CONFIG.keys.l1, dataToSave);
                        GM_setValue(CONFIG.keys.l2, null);
                    }
                    window.close();
                }, 5000);
            }
        }, 500);
        setTimeout(() => clearInterval(checkExist), 20000);
        return;
    }
 
    function updateTotalPointsFromBing() {
        if (!location.hostname.includes('bing.com')) return;
        const totalEl = document.querySelector(CONFIG.selectors.total);
        if (totalEl) {
            const pointsText = totalEl.innerText.trim();
            if (pointsText !== "" && pointsText.match(/^\d+$/)) {
                GM_setValue(CONFIG.keys.total, {
                    points: pointsText,
                    timestamp: Date.now()
                });
                console.log(`[Rewards] 总积分更新: ${pointsText}`);
                updateUI();
            }
        }
    }
 
    function fetchHotSearchKeywords() {
        GM_xmlhttpRequest({
            method: "GET",
            url: CONFIG.weiboApi,
            onload: function (response) {
                try {
                    const json = JSON.parse(response.responseText);
                    if (json?.data?.realtime) {
                        const words = json.data.realtime.map(item => item.word_scheme || item.word);
                        state.hotWords = [...new Set([...words, ...FALLBACK_KEYWORDS])].sort(() => Math.random() - 0.5);
                    } else throw new Error();
                } catch (e) { state.hotWords = [...FALLBACK_KEYWORDS].sort(() => Math.random() - 0.5); }
            },
            onerror: function () { state.hotWords = [...FALLBACK_KEYWORDS].sort(() => Math.random() - 0.5); }
        });
    }
 
    function getNextKeyword() {
        if (!state.hotWords || state.hotWords.length === 0) state.hotWords = [...FALLBACK_KEYWORDS].sort(() => Math.random() - 0.5);
        return state.hotWords.shift();
    }
 
    function parsePoints(str) {
        if (!str) return { current: 0, max: 0, remaining: 0, percent: 0 };
        const parts = str.split('/');
        if (parts.length !== 2) return { current: 0, max: 0, remaining: 0, percent: 0 };
        const current = parseInt(parts[0].replace(/[^0-9]/g, '')) || 0;
        const max = parseInt(parts[1].replace(/[^0-9]/g, '')) || 0;
        return { current, max, remaining: Math.ceil((max - current) / 3), percent: max > 0 ? (current / max) * 100 : 0 };
    }
 
    function getRemainingTasks() {
        const l1 = GM_getValue(CONFIG.keys.l1);
        const l2 = GM_getValue(CONFIG.keys.l2);
 
        const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
 
        if (l2) {
            if (isMobile) {
                return parsePoints(l2.mobile).remaining;
            } else {
                return parsePoints(l2.pc).remaining;
            }
        } else if (l1) {
            return parsePoints(l1.pc).remaining;
        }
        return 0;
    }
 
    function performSearch() {
        if (!location.hostname.includes('bing.com')) return;
 
        updateTotalPointsFromBing();
 
        const keyword = getNextKeyword();
        const sbInput = document.getElementById('sb_form_q');
        const sbForm = document.getElementById('sb_form');
        const sbGo = document.getElementById('sb_form_go') || document.getElementById('search_icon');
 
        if (sbInput) {
            let lastValue = sbInput.value;
            sbInput.value = keyword;
            const tracker = sbInput._valueTracker;
            if (tracker) tracker.setValue(lastValue);
            sbInput.dispatchEvent(new Event('input', { bubbles: true }));
            sbInput.dispatchEvent(new Event('change', { bubbles: true }));
 
            const titleEl = document.querySelector('.neon-title');
            if (titleEl) {
                titleEl.innerText = `搜: ${keyword.substring(0, 6)}...`;
                setTimeout(() => titleEl.innerText = "Microsoft Rewards", 5000);
            }
            setTimeout(() => {
                if (sbGo) sbGo.click();
                else if (sbForm) sbForm.submit();
            }, 300 + Math.random() * 200);
        }
    }
 
    function startLoop() {
        if (state.isRunning || state.isRemoteRunning) return;
 
        if (!location.hostname.includes('bing.com')) {
            console.log("[Rewards] 启动器模式:发送启动信号并打开新标签页...");
            GM_setValue(CONFIG.keys.trigger, Date.now());
            if (state.hotWords.length === 0) fetchHotSearchKeywords();
            const keyword = getNextKeyword();
            const url = CONFIG.searchBaseUrl + encodeURIComponent(keyword);
            GM_openInTab(url, { active: true, insert: true });
            state.isRemoteRunning = true;
            togglePanel(true);
            updateUI();
            return;
        }
 
        console.log("[Rewards] 工作模式:开始执行任务循环");
        state.isRunning = true;
        updateGlobalStatus(true, Date.now() + 60000);
        togglePanel(true);
        updateUI();
        if (state.hotWords.length === 0) fetchHotSearchKeywords();
        performSearch();
 
        updateRemainingDisplay(getRemainingTasks() - 1);
 
        if (state.timers.sync) clearInterval(state.timers.sync);
 
        state.timers.sync = setInterval(() => {
            GM_openInTab(CONFIG.rewardsUrl, { active: false, insert: true });
        }, 30000); 
 
        const schedule = () => {
            if (!state.isRunning) return;
            const remaining = getRemainingTasks();
 
            if (remaining <= 0) { stopLoop(true); return; }
 
            const delay = Math.floor(Math.random() * (120 - 80 + 1)) + 80;
            const targetTime = Date.now() + (delay * 1000);
 
            updateGlobalStatus(true, targetTime);
            if (state.timers.heartbeat) clearInterval(state.timers.heartbeat);
            state.timers.heartbeat = setInterval(() => { updateGlobalStatus(true, targetTime); }, 5000);
 
            if (state.timers.countdown) clearInterval(state.timers.countdown);
            state.timers.countdown = setInterval(() => {
                const left = Math.ceil((targetTime - Date.now()) / 1000);
                updateTimerDisplay(left);
                if (Date.now() >= targetTime) {
                    clearInterval(state.timers.countdown);
                    if (state.isRunning) {
                        performSearch();
                        schedule();
                    }
                }
            }, 1000);
        };
        schedule();
    }
 
    function updateGlobalStatus(isRunning, nextSearchTime = 0) {
        GM_setValue(CONFIG.keys.status, {
            isRunning: isRunning,
            owner: isRunning ? INSTANCE_ID : null,
            timestamp: Date.now(),
            nextSearchTime: nextSearchTime
        });
    }
 
    function stopLoop(completed = false) {
        console.log("[Rewards] 停止任务");
        state.isRunning = false;
 
        const currentStatus = GM_getValue(CONFIG.keys.status);
        if (currentStatus && currentStatus.owner === INSTANCE_ID) {
            updateGlobalStatus(false);
        } else if (!completed) {
            updateGlobalStatus(false);
        }
 
        if (state.timers.countdown) clearInterval(state.timers.countdown);
        if (state.timers.sync) clearInterval(state.timers.sync);
        if (state.timers.heartbeat) clearInterval(state.timers.heartbeat);
 
        updateTimerDisplay(completed ? "完成" : "已停止");
        updateUI(completed);
    }
 
    window.addEventListener('beforeunload', () => { });
 
    GM_addValueChangeListener(CONFIG.keys.status, (name, oldVal, newVal, remote) => {
        if (newVal && newVal.isRunning) {
            if (newVal.owner !== INSTANCE_ID) {
                if (state.isRunning) stopLoop(false);
                if (!state.isRemoteRunning) togglePanel(true);
                state.isRemoteRunning = true;
                if (newVal.nextSearchTime) startSlaveCountdown(newVal.nextSearchTime);
                updateUI();
            }
        } else {
            state.isRemoteRunning = false;
            if (state.isRunning) stopLoop(false);
            stopSlaveCountdown();
            updateUI();
        }
    });
 
    function startSlaveCountdown(targetTime) {
        if (state.timers.slaveCountdown) clearInterval(state.timers.slaveCountdown);
        const updateSlaveTimer = () => {
            const left = Math.ceil((targetTime - Date.now()) / 1000);
            updateTimerDisplay(left > 0 ? left : 0);
        };
        updateSlaveTimer();
        state.timers.slaveCountdown = setInterval(updateSlaveTimer, 1000);
    }
 
    function stopSlaveCountdown() {
        if (state.timers.slaveCountdown) clearInterval(state.timers.slaveCountdown);
        updateTimerDisplay("待机");
    }
 
    function updateTimerDisplay(val) {
        const el = document.getElementById('neon-timer');
        if (el) el.innerText = typeof val === 'number' ? `${val}s` : val;
    }
 
    function updateRemainingDisplay(val) {
        const el = document.getElementById('neon-remaining');
        if (el) el.innerText = val > 0 ? val : 0;
    }
 
    function togglePanel(show) {
        const panel = document.getElementById('neon-panel');
        if (panel) {
            if (show) panel.classList.add('show');
            else panel.classList.remove('show');
        }
    }
 
    GM_addStyle(`
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&display=swap');
        :root { --neon-bg: rgba(20, 20, 25, 0.75); --neon-border: rgba(255, 255, 255, 0.1); --neon-primary: #00f2ea; --neon-secondary: #ff0055; --neon-text: #ffffff; --glass-blur: blur(16px); }
        #neon-fab { position: fixed; bottom: 30px; right: 30px; width: 50px; height: 50px; background: var(--neon-bg); backdrop-filter: var(--glass-blur); border: 1px solid var(--neon-border); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 10000; box-shadow: 0 8px 32px rgba(0,0,0,0.3); transition: all 0.3s; }
        #neon-fab:hover { transform: scale(1.1); border-color: var(--neon-primary); box-shadow: 0 0 15px rgba(0, 242, 234, 0.3); }
        #neon-fab svg { width: 24px; height: 24px; fill: var(--neon-primary); }
        #neon-panel { position: fixed; bottom: 90px; right: 30px; width: 300px; background: var(--neon-bg); backdrop-filter: var(--glass-blur); border: 1px solid var(--neon-border); border-radius: 16px; padding: 20px; z-index: 10000; font-family: 'Inter', sans-serif; color: var(--neon-text); box-shadow: 0 16px 48px rgba(0,0,0,0.4); opacity: 0; visibility: hidden; transform: translateY(20px) scale(0.95); transition: all 0.3s; pointer-events: none; }
        #neon-panel.show { opacity: 1; visibility: visible; transform: translateY(0) scale(1); pointer-events: auto; }
        .neon-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 1px solid rgba(255,255,255,0.05); padding-bottom: 10px; }
        .neon-title { font-weight: 800; font-size: 14px; background: linear-gradient(90deg, #fff, #bbb); -webkit-background-clip: text; -webkit-text-fill-color: transparent; max-width: 160px; }
        .neon-controls { display: flex; align-items: center; gap: 10px; }
        .neon-refresh { font-size: 12px; color: #a0a0a0; cursor: pointer; transition: color 0.2s; }
        .neon-refresh:hover { color: var(--neon-primary); }
        .neon-close { font-size: 20px; color: #a0a0a0; cursor: pointer; line-height: 1; transition: color 0.2s; font-family: sans-serif; }
        .neon-close:hover { color: var(--neon-secondary); }
        .neon-row { margin-bottom: 12px; }
        .neon-label-row { display: flex; justify-content: space-between; font-size: 12px; color: #a0a0a0; margin-bottom: 4px; }
        .neon-progress-bg { width: 100%; height: 4px; background: rgba(255,255,255,0.05); border-radius: 2px; overflow: hidden; }
        .neon-progress-bar { height: 100%; background: linear-gradient(90deg, var(--neon-primary), #00c2ff); width: 0%; transition: width 0.6s ease; box-shadow: 0 0 8px rgba(0, 242, 234, 0.4); }
        .neon-dashboard { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 20px; }
        .neon-card { background: rgba(255,255,255,0.03); border-radius: 12px; padding: 10px; text-align: center; position: relative; }
        .neon-card.wide { grid-column: span 2; display: flex; align-items: center; justify-content: space-between; padding: 10px 20px; }
        .neon-card.wide .neon-card-val { margin-top: 0; font-size: 24px; color: #ffeb3b; text-shadow: 0 0 10px rgba(255, 235, 59, 0.3); }
        .neon-card-label { font-size: 11px; color: #a0a0a0; text-transform: uppercase; letter-spacing: 1px; }
        .neon-card-val { font-size: 20px; font-weight: 800; margin-top: 5px; color: var(--neon-primary); }
        #neon-action-btn { width: 100%; margin-top: 20px; padding: 12px; background: var(--neon-primary); color: #000; font-weight: 800; border: none; border-radius: 8px; cursor: pointer; transition: all 0.2s; text-transform: uppercase; font-size: 12px; letter-spacing: 1px; }
        #neon-action-btn:hover { box-shadow: 0 0 20px rgba(0, 242, 234, 0.5); transform: translateY(-1px); }
        #neon-action-btn:disabled { background: #333; color: #666; cursor: not-allowed; box-shadow: none; transform: none; }
        .neon-pulse { position: absolute; top: 5px; right: 5px; width: 8px; height: 8px; border-radius: 50%; background: var(--neon-secondary); opacity: 0.2; transition: all 0.3s; }
        .neon-pulse.active { opacity: 1; box-shadow: 0 0 10px var(--neon-secondary); }
    `);
 
    function createUI() {
        if (document.getElementById('neon-fab')) return;
        const fab = document.createElement('div');
        fab.id = 'neon-fab';
        fab.innerHTML = `<svg viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z"/></svg>`;
        document.body.appendChild(fab);
 
        const panel = document.createElement('div');
        panel.id = 'neon-panel';
        panel.innerHTML = `
            <div class="neon-header">
                <span class="neon-title">Microsoft Rewards</span>
                <div class="neon-controls">
                    <span class="neon-refresh" id="neon-refresh" title="同步数据">手动同步</span>
                    <span class="neon-close" id="neon-close" title="隐藏面板">×</span>
                </div>
            </div>
            <div id="neon-content"><div style="text-align:center; color:#666; font-size:12px; padding:20px;">正在初始化...</div></div>
            <div class="neon-dashboard">
                <div class="neon-card wide">
                    <div class="neon-card-label">总积分 BALANCE</div>
                    <div class="neon-card-val" id="neon-total-points">--</div>
                </div>
                <div class="neon-card"><div class="neon-pulse"></div><div class="neon-card-label">本设备剩余</div><div class="neon-card-val" id="neon-remaining">--</div></div>
                <div class="neon-card"><div class="neon-card-label">下次搜索</div><div class="neon-card-val" id="neon-timer" style="color:#fff;">--</div></div>
            </div>
            <button id="neon-action-btn">开始运行</button>
        `;
        document.body.appendChild(panel);
 
        fab.addEventListener('click', () => panel.classList.toggle('show'));
        document.getElementById('neon-refresh').addEventListener('click', () => {
            GM_openInTab(CONFIG.rewardsUrl, { active: false, insert: true });
        });
 
        document.getElementById('neon-close').addEventListener('click', (e) => {
            e.stopPropagation();
            panel.classList.remove('show');
        });
 
        document.addEventListener('click', (e) => {
            if (!panel.contains(e.target) && !fab.contains(e.target) && panel.classList.contains('show')) panel.classList.remove('show');
        });
        updateUI();
    }
 
    function updateUI(isCompleted = false) {
        const container = document.getElementById('neon-content');
        if (!container) return;
 
        const l1 = GM_getValue(CONFIG.keys.l1);
        const l2 = GM_getValue(CONFIG.keys.l2);
        const totalPointsData = GM_getValue(CONFIG.keys.total); 
        const remaining = getRemainingTasks();
        const remainingEl = document.getElementById('neon-remaining');
        if (remainingEl) remainingEl.innerText = remaining;
 
        const totalEl = document.getElementById('neon-total-points');
        if (totalEl) {
            let totalTxt = "--";
            if (totalPointsData && totalPointsData.points) totalTxt = totalPointsData.points;
            totalEl.innerText = totalTxt;
        }
 
        let html = '';
        if (l2) {
            const pc = parsePoints(l2.pc);
            const mob = parsePoints(l2.mobile);
            const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
            const pcStyle = !isMobile ? 'color:#fff; font-weight:bold;' : 'color:#a0a0a0;';
            const mobStyle = isMobile ? 'color:#fff; font-weight:bold;' : 'color:#a0a0a0;';
 
            html += `
                <div class="neon-row"><div class="neon-label-row"><span style="${pcStyle}">PC 端 ${!isMobile ? '(当前)' : ''}</span> <span>${l2.pc}</span></div><div class="neon-progress-bg"><div class="neon-progress-bar" style="width:${pc.percent}%"></div></div></div>
                <div class="neon-row"><div class="neon-label-row"><span style="${mobStyle}">移动端 ${isMobile ? '(当前)' : ''}</span> <span>${l2.mobile}</span></div><div class="neon-progress-bg"><div class="neon-progress-bar" style="width:${mob.percent}%; background: linear-gradient(90deg, #ff0055, #ff5e00);"></div></div></div>
            `;
        } else if (l1) {
            const pc = parsePoints(l1.pc);
            html += `<div class="neon-row"><div class="neon-label-row"><span>积分进度</span> <span>${l1.pc}</span></div><div class="neon-progress-bg"><div class="neon-progress-bar" style="width:${pc.percent}%"></div></div></div>`;
        } else {
            html = `<div style="text-align:center; color:#aaa; font-size:12px; padding:10px;">暂无 PC/移动端积分数据 (点击手动同步)</div>`;
        }
        container.innerHTML = html;
 
        const btn = document.getElementById('neon-action-btn');
        const newBtn = btn.cloneNode(true);
        btn.parentNode.replaceChild(newBtn, btn);
 
        if (state.isRunning) {
            newBtn.innerText = "停止运行";
            newBtn.disabled = false;
            newBtn.style.opacity = "1";
            newBtn.style.background = "var(--neon-secondary)";
            newBtn.style.color = "#fff";
            newBtn.onclick = () => stopLoop(false);
        } else if (state.isRemoteRunning) {
            newBtn.innerText = "停止 (后台运行中)";
            newBtn.disabled = false;
            newBtn.style.opacity = "1";
            newBtn.style.background = "#555";
            newBtn.onclick = () => stopLoop(false);
        } else if (isCompleted || (remaining <= 0 && (l1 || l2))) {
            newBtn.innerText = "当前设备任务完成";
            newBtn.disabled = true;
            newBtn.style.background = "rgba(255,255,255,0.1)";
            newBtn.style.color = "#aaa";
        } else {
            newBtn.innerText = "开始运行";
            newBtn.disabled = false;
            newBtn.style.opacity = "1";
            newBtn.style.background = "var(--neon-primary)";
            newBtn.style.color = "#000";
            newBtn.onclick = startLoop;
        }
    }
 
    GM_addValueChangeListener(CONFIG.keys.l1, () => updateUI());
    GM_addValueChangeListener(CONFIG.keys.l2, () => updateUI());
    GM_addValueChangeListener(CONFIG.keys.total, () => updateUI()); 
 
    window.addEventListener('load', () => {
        createUI();
        fetchHotSearchKeywords();
        
        if (location.hostname.includes('bing.com')) {
            setTimeout(updateTotalPointsFromBing, 2000); 
        }
 
 
        const triggerTime = GM_getValue(CONFIG.keys.trigger);
        if (triggerTime && (Date.now() - triggerTime < 15000)) {
            if (location.hostname.includes("bing.com")) {
                console.log("[Rewards] 检测到启动信号,本页面接管任务...");
                GM_setValue(CONFIG.keys.trigger, 0);
                setTimeout(startLoop, 1000);
                return;
            }
        }
 
        const currentStatus = GM_getValue(CONFIG.keys.status);
        if (currentStatus && currentStatus.isRunning && currentStatus.owner !== INSTANCE_ID) {
            if (Date.now() - currentStatus.timestamp < 180000) {
                state.isRemoteRunning = true;
                if (currentStatus.nextSearchTime) startSlaveCountdown(currentStatus.nextSearchTime);
                updateUI();
            } else {
                updateGlobalStatus(false);
            }
        }
        
        setTimeout(() => {
            if (!GM_getValue(CONFIG.keys.l1) && !GM_getValue(CONFIG.keys.l2)) {
                GM_openInTab(CONFIG.rewardsUrl, { active: false, insert: true });
            }
        }, 1500);
    });
 
})();