// ==UserScript== // @name Microsoft Bing Rewards每日任务脚本 // @namespace https://greasyfork.org/users/1362311 // @version 4.0.3 // @description 自动完成微软积分每日搜索任务 // @author honguangli // @license MIT // @match https://www.bing.com/* // @match https://cn.bing.com/* // @icon https://www.bing.com/favicon.ico // @run-at document-end // @grant GM_registerMenuCommand // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @downloadURL none // ==/UserScript== (function() { 'use strict'; const pathnames = ['/', '/search']; // 触发搜索页面 const searchTimes = 40; // 自动搜索次数 const searchDelaySecondsMin = 15; // 每次搜索最小延迟时间,单位秒 const searchDelaySecondsMax = 30; // 每次搜索最大延迟时间,单位秒 const searchDelaySecondsFirst = 3; // 首次搜索延迟时间,单位秒,设置为0时立即触发 const closeTaskCardDelaySeconds = 0; // 搜索完成后弹窗自动关闭延迟时间,单位秒,设置为0时需手动关闭 const searchSafeDelayTimes = 4; // 每搜索n次后触发长暂停 const searchSafeDelaySeconds = 10 * 60; // 每次触发长暂停时长,单位秒 const startBtn = true; // 是否在搜索框附近插入任务启动按钮 const startBtnText = '获取积分'; // 任务启动按钮文本 const searchKeySource = ['BaiduHot','TouTiaoHot','DouYinHot', 'WeiBoHot']; // 搜索词条库 const countKey = 'count'; // 计数器 const pointsKey = 'points'; // 积分 const keywordsKey = 'search'; // 搜索词条 const searchParamKey = 'param'; // 搜索参数 let scrollIntervalId = null; // 模拟浏览定时器id let delayIntervalId = null; // 搜索任务倒计时定时器id GM_addStyle('#reward-task { position: fixed; top: 0; left: 0; width: 100%; background-color: rgba(0, 0, 0, .2); z-index: 99999; }'); GM_addStyle('#reward-task > .reward-task-content { width: 608px; margin: calc(50vh - 32px) auto 0; padding: 20px; background-color: #ffffff; border: 1px solid #e4e7ed; border-radius: 20px; color: #303133; overflow: hidden; transition: 0.3s; box-shadow: 0px 0px 12px rgba(0,0,0,0.12); }'); GM_addStyle('#reward-task > .reward-task-content > div { display: flex; align-items: center; column-gap: 20px; }'); GM_addStyle('.reward-task-btn { display: inline-block; line-height: 1; white-space: nowrap; cursor: pointer; background: #fff; border: 1px solid #dcdfe6; -webkit-appearance: none; text-align: center; -webkit-box-sizing: border-box; box-sizing: border-box; outline: 0; margin: 0; -webkit-transition: .1s; transition: .1s; font-weight: 500; padding: 8px 16px; font-size: 14px; border-radius: 4px; color: #606266; background-color: #ffffff; border: 1px solid #dcdfe6; border-color: #dcdfe6; }'); GM_addStyle('.reward-task-btn.warning { color: #fff; background-color: #ebb563; border-color: #ebb563; }'); // 注册菜单 const registerMenuCommand = () => { // 开始 GM_registerMenuCommand('开始', function () { start(); }, 'o'); // 停止 GM_registerMenuCommand('停止', function () { stop(); removeTaskCard(); }, 'o'); }; // 开始 const start = () => { GM_setValue(countKey, 1); GM_setValue(pointsKey, -1); search(); }; // 结束 const stop = () => { GM_setValue(countKey, 0); GM_setValue(pointsKey, -1); clearInterval(scrollIntervalId); }; // 获取词条 const getSearchInfo = () => { return new Promise((resolve, reject) => { const today = new Date(); today.setHours(0); today.setMinutes(0); today.setSeconds(0); today.setMilliseconds(0); let source = Math.floor(Math.random() * searchKeySource.length); const saveConfig = GM_getValue(keywordsKey); // 当日缓存的搜索词还未用完 if (saveConfig && saveConfig.time === today.getTime()) { if (saveConfig.keywords.length > 0) { const keyword = saveConfig.keywords[0]; saveConfig.keywords.splice(0, 1); GM_setValue(keywordsKey, saveConfig); resolve(keyword); } else { source = (saveConfig.source + 1) % searchKeySource.length; } } // 重置配置 const config = { time: today.getTime(), source: source, keywords: [], }; // 获取新词条 fetch('https://api.gumengya.com/Api/' + searchKeySource[config.source]).then( (response) => { if (!response.ok) { throw new Error('获取搜索词条失败'); } return response.json(); } ).then( (data) => { if (data.code !== 200) { throw new Error('获取搜索词条失败'); } config.keywords = data.data.map(item => item.title); const keyword = config.keywords[0]; config.keywords.splice(0, 1); GM_setValue(keywordsKey, config); resolve(keyword); } ).catch((err) => { reject(err); }); }); }; // 搜索 const search = () => { const count = GM_getValue(countKey); if (!count || count <= 0 || count > searchTimes + 1) { stop(); return; } // 延迟时间 const delay = count === 1 ? searchDelaySecondsFirst : Math.floor(Math.random() * (searchDelaySecondsMax - searchDelaySecondsMin + 1)) + searchDelaySecondsMin + (count % searchSafeDelayTimes !== 1 ? 0 : searchSafeDelaySeconds); // 添加任务进度卡片 insertTaskCard(count - 1, delay, () => { // 获取词条 getSearchInfo().then( keyword => { // 更新计数器 GM_setValue(countKey, count+1); const queryForm = document.getElementById('sb_form'); const queryInput = document.getElementById('sb_form_q'); queryInput.value = keyword; const data = new FormData(queryForm); let param = 'rand=' + Math.random(); for (let item of data.entries()) { if (item[0] === 'q') { param += '&q=' + encodeURIComponent(item[1]); } else { param += '&' + item[0] + '=' + item[1]; } } // 更新搜索参数 GM_setValue(searchParamKey, param); // 触发搜索 //queryForm.submit(); location.href = location.origin + '/search?' + param; }).catch( err => { stop(); alert('获取搜索词条失败', err.message); }); }); if (count > searchTimes) { stop(); return; } // 模拟浏览网页 pretendHuman(); }; // 插入开始按钮 const insertStartBtn = () => { if (document.getElementById('reward-task-start')) { document.getElementById('reward-task-start').remove(); } if (!startBtn) { return; } // 获取搜索表单 const queryForm = document.getElementById('sb_form'); // 添加开始按钮 const btn = document.createElement('button'); btn.appendChild(document.createTextNode(startBtnText)); btn.setAttribute('id', 'reward-task-start'); btn.setAttribute('type', 'button'); btn.classList.add('reward-task-btn'); btn.style.setProperty('margin-left', '8px'); btn.style.setProperty('padding', '8px 24px'); btn.style.setProperty('border-radius', '24px'); btn.onclick = function () { start(); }; // 首页表单会重置组件内容,需要等待几秒后再插入 setTimeout( () => { queryForm.appendChild(btn); }, location.pathname !== '/' ? 0 : 5000); }; // 插入搜索任务卡片 const insertTaskCard = (times, delay, finish) => { removeTaskCard(); // 添加搜索任务卡片 const h = `

当前积分:${ getCurrPoints() }

已获得积分:${ getTaskPoints() }

进度:${ times } / ${ searchTimes }

${ times >= searchTimes ? `已完成${ closeTaskCardDelaySeconds > 0 ? ',' + closeTaskCardDelaySeconds + '秒后自动关闭' : '' }` : `等待时间: ${ delay } 秒 ` }

${ times >= searchTimes ? '' : '' }
`; document.body.insertAdjacentHTML('beforeEnd', h); // 停止按钮 const btnStop = document.querySelector('#reward-task-stop'); if (btnStop) { btnStop.onclick = () => { stop(); removeTaskCard(); }; } // 关闭按钮 const btnCancel = document.querySelector('#reward-task-cancel'); if (btnCancel) { btnCancel.onclick = () => { stop(); removeTaskCard(); }; } // 任务完成,自动延迟关闭任务窗口 if (times >= searchTimes && closeTaskCardDelaySeconds > 0) { setTimeout( () => { removeTaskCard(); }, closeTaskCardDelaySeconds * 1000); } // 倒计时 // 任务完成后再执行10次以便获取积分信息 let remainDelay = times >= searchTimes ? 10 : delay; delayIntervalId = setInterval(() => { remainDelay--; if (remainDelay < 0) { clearInterval(delayIntervalId); return; } // 更新积分 const domCurrPoints = document.getElementById('reward-points'); const domTaskPoints = document.getElementById('task-points'); domCurrPoints.innerText = `当前积分:${ getCurrPoints() }`; domTaskPoints.innerText = `已获得积分:${ getTaskPoints() }`; // 任务已完成 if (times >= searchTimes) { return; } // 倒计时完成 if (remainDelay === 0) { clearInterval(delayIntervalId); finish(); return; } // 更新倒计时 const domDelay = document.getElementById('reward-task-delay'); if (!domDelay) { return; } domDelay.innerText = `等待时间: ${ remainDelay } 秒`; }, 1000); }; // 移除搜索任务卡片 const removeTaskCard = () => { clearInterval(delayIntervalId); if (!document.getElementById('reward-task')) { return; } document.getElementById('reward-task').remove(); }; // 模拟浏览网页 const pretendHuman = () => { clearInterval(scrollIntervalId); window.scrollTo({ top: 0, behavior: 'smooth' }); // 启用定时器缓慢滑动到底部,期间随机触发停留和向上滑动,完成滑动到底部后再次滑动到顶部后停止滑动 scrollIntervalId = setInterval(() => { if (document.documentElement.scrollTop >= document.documentElement.scrollHeight - document.documentElement.clientHeight) { clearInterval(scrollIntervalId); window.scrollTo({ top: 0, behavior: 'smooth' }); return; } const number = Math.floor(Math.random() * 10) + 1; if (number < 3) { window.scrollTo({ top: document.documentElement.scrollTop - 200, behavior: 'smooth' }); } else if (number > 5) { window.scrollTo({ top: document.documentElement.scrollTop + 100, behavior: 'smooth' }); } }, 500); }; // 获取当前积分 const getCurrPoints = () => { const pointsContainer = document.querySelector('#rh_rwm .points-container'); if (!pointsContainer) { return null; } let pointsStr = ''; if (!pointsContainer.classList.contains('balance-animation')) { pointsStr = pointsContainer.innerText.trim(); } else { pointsStr = document.documentElement.style.getPropertyValue('--rw-gp-balance-to'); } const points = parseInt(pointsStr); if (isNaN(points)) { return null; } return points; }; // 计算已取得积分 const getTaskPoints = () => { const currPoints = getCurrPoints(); if (currPoints === null) { return 0; } let startPoints = GM_getValue(pointsKey); if (startPoints === -1) { GM_setValue(pointsKey, currPoints); return 0; } return currPoints - startPoints; }; // 仅在匹配的页面触发 if (pathnames.includes(location.pathname)) { registerMenuCommand(); insertStartBtn(); // 判断是否处于任务页面 const searchParam = GM_getValue(searchParamKey); if (location.search.replace('?', '') === searchParam) { search(); } } })();