// ==UserScript== // @name Microsoft Bing Rewards 每日任务脚本(合并版) // @version V3.2.3 // @description 基于“怀沙2049”+Soul233,自动完成微软 Rewards 每日搜索:60% 诗词(hitokoto)、30% 热门词、10% 默认词,支持混淆、防封号、启动确认与停止提示。 // @author Soul233 & AI // @match https://*.bing.com/* // @exclude https://rewards.bing.com/* // @license GNU GPLv3 // @icon https://www.bing.com/favicon.ico // @connect gumengya.com // @connect v1.hitokoto.cn // @run-at document-end // @grant GM_registerMenuCommand // @grant GM_addStyle // @grant GM_openInTab // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @namespace https://scriptcat.org/zh-CN/script-show-page/3356 // ==/UserScript== /* --------------------------- 全局变量配置 --------------------------- */ var max_rewards = 40; // 每日总搜索次数 var pause_time = 0.5 * 60 * 1000; // 每执行 5 次搜索后暂停 0.5 分钟 var search_words = []; // 存放将要执行搜索的关键词 var appkey = ""; // 从 https://www.gmya.net/api 申请 /* -------- 热门词接口配置 -------- */ var HOT_WORDS_APIS = "https://api.gmya.net/Api/"; var KEYWORDS_SOURCE = ['BaiduHot', 'TouTiaoHot', 'DouYinHot', 'WeiBoHot']; var current_source_index = 0; /* -------- 默认搜索词(兜底) -------- */ var DEFAULT_SEARCH_WORDS = [ "盛年不重来,一日难再晨", "千里之行,始于足下", "少年易学老难成,一寸光阴不可轻", "敏而好学,不耻下问", "海内存知已,天涯若比邻", "三人行,必有我师焉", "莫愁前路无知已,天下谁人不识君", "人生贵相知,何用金与钱", "天生我材必有用", "海纳百川有容乃大;壁立千仞无欲则刚", "穷则独善其身,达则兼济天下", "读书破万卷,下笔如有神", "学而不思则罔,思而不学则殆", "一年之计在于春,一日之计在于晨", "莫等闲,白了少年头,空悲切", "少壮不努力,老大徒伤悲", "一寸光阴一寸金,寸金难买寸光阴", "近朱者赤,近墨者黑", "吾生也有涯,而知也无涯", "纸上得来终觉浅,绝知此事要躬行", "学无止境", "己所不欲,勿施于人", "天将降大任于斯人也", "鞠躬尽瘁,死而后已", "书到用时方恨少", "天下兴亡,匹夫有责", "人无远虑,必有近忧", "为中华之崛起而读书", "一日无书,百事荒废", "岂能尽如人意,但求无愧我心", "人生自古谁无死,留取丹心照汗青", "生于忧患,死于安乐", "言必信,行必果", "夫君子之行,静以修身,俭以养德", "老骥伏枥,志在千里", "一日不读书,胸臆无佳想", "王侯将相宁有种乎", "淡泊以明志,宁静而致远", "卧龙跃马终黄土" ]; /* -------- Hitokoto 诗词接口 -------- */ var HITOKOTO_API = "https://v1.hitokoto.cn/?c=i&encode=text"; /* ======================= 工具函数 ======================= */ /** * 从 Hitokoto 获取一条随机诗词。 * @returns {Promise} */ async function getHitokotoWord() { const resp = await fetch(HITOKOTO_API); if (!resp.ok) throw new Error("Hitokoto API 请求失败:" + resp.status); return await resp.text(); } /** * 轮询多个热门词源直至成功,否则返回默认词。 * @returns {Promise} */ async function getHotWords() { if (!appkey) { console.warn("⚠️ 未填写 appkey,热门词接口可能不可用。请前往 https://www.gmya.net/api 申请。"); } while (current_source_index < KEYWORDS_SOURCE.length) { const source = KEYWORDS_SOURCE[current_source_index]; const url = appkey ? `${HOT_WORDS_APIS}${source}?format=json&appkey=${appkey}` : `${HOT_WORDS_APIS}${source}`; try { const res = await fetch(url); if (!res.ok) throw new Error(`HTTP ${res.status}`); const data = await res.json(); if (data.data && data.data.length) { return data.data.map(item => item.title); } } catch (e) { console.error(`热门词 ${source} 请求失败:`, e); current_source_index++; } } return DEFAULT_SEARCH_WORDS; } /** * 根据概率选择搜索词:60% Hitokoto / 30% 热门词 / 10% 默认词fallback。 * @returns {Promise} */ async function chooseSearchWords() { const p = Math.random(); try { if (p < 0.6) { return [await getHitokotoWord()]; } else if (p < 0.9) { return await getHotWords(); } else { return DEFAULT_SEARCH_WORDS; } } catch (e) { console.error("获取搜索词出错,使用默认词:", e); return DEFAULT_SEARCH_WORDS; } } /** * 对搜索词插入随机混淆字符,降低检测概率。 * @param {string} st 原始关键词 * @returns {string} */ function AutoStrTrans(st) { const yStr = st; const rStr = ""; // 可在此自定义要插入的混淆字符 let zStr = ""; let prePo = 0; for (let i = 0; i < yStr.length;) { const step = Math.floor(Math.random() * 5) + 1; // 随机步长 1~5 if (i > 0) { zStr += yStr.substr(prePo, i - prePo) + rStr; prePo = i; } i += step; } if (prePo < yStr.length) { zStr += yStr.substr(prePo); } return zStr; } /** * 生成指定长度的随机字符串,仅包含大写字母和数字。 * @param {number} length * @returns {string} */ function generateRandomString(length) { const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; let res = ""; for (let i = 0; i < length; i++) { res += chars.charAt(Math.floor(Math.random() * chars.length)); } return res; } /* ======================= 主流程 ======================= */ /** * 执行一次搜索:带随机延迟、随机 form/cvid 标记,以及分页切换与暂停。 */ function exec() { const randomDelay = Math.floor(Math.random() * 20000) + 10000; // 10~30 秒随机延迟 const randomString = generateRandomString(4); const randomCvid = generateRandomString(32); if (GM_getValue('Cnt') == null) { GM_setValue('Cnt', 0); } const cnt = GM_getValue('Cnt'); if (cnt >= max_rewards) return; // 任务完成 document.title = `[${cnt} / ${max_rewards}] ` + document.title; smoothScrollToBottom(); GM_setValue('Cnt', cnt + 1); setTimeout(() => { let nowtxt = search_words[cnt] || DEFAULT_SEARCH_WORDS[cnt % DEFAULT_SEARCH_WORDS.length]; nowtxt = AutoStrTrans(nowtxt); const baseUrl = cnt <= max_rewards / 2 ? "https://www.bing.com/search?q=" : "https://cn.bing.com/search?q="; const finalUrl = `${baseUrl}${encodeURIComponent(nowtxt)}&form=${randomString}&cvid=${randomCvid}`; if ((cnt + 1) % 5 === 0) { // 每 5 次暂停一次 setTimeout(() => { location.href = finalUrl; }, pause_time); } else { location.href = finalUrl; } }, randomDelay); } /** * 平滑滚动到底部,模拟人工滚动行为。 */ function smoothScrollToBottom() { document.documentElement.scrollIntoView({ behavior: 'smooth', block: 'end' }); } /* ======================= 菜单注册 ======================= */ GM_registerMenuCommand('开始 Bing Rewards 自动任务', () => { //if (!confirm("确定开始执行 Bing Rewards 自动搜索任务?")) return; GM_setValue('Cnt', 0); location.href = "https://www.bing.com/?br_msg=Please-Wait"; }, 'o'); GM_registerMenuCommand('停止 Bing Rewards 自动任务', () => { GM_setValue('Cnt', max_rewards + 1); alert("已停止 Bing Rewards 自动搜索任务。"); }, 'o'); /* ======================= 启动脚本 ======================= */ chooseSearchWords() .then(words => { search_words = words; exec(); }) .catch(err => { console.error(err); search_words = DEFAULT_SEARCH_WORDS; exec(); });