// ==UserScript== // @name Bing Rewards Lite (Win & Mac) // @version 1.5 // @description v1.5 双模版 - 可在“快速模式(~42分)”与“超稳健模式(~60分)”间切换。 // ✨ 功能: 自定义次数/高级拟人化/触屏拖拽/热词/双模式计时 // @match https://*.bing.com/* // @match https://*.bing.cn/* // @grant GM_getValue // @grant GM_setValue // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_setTimeout // @grant GM_clearTimeout // @grant GM_setInterval // @grant GM_clearInterval // @connect api.vvhan.com // @connect api-hot.imsyy.top // @license MIT // @namespace https://greasyfork.org/users/737649 // @downloadURL https://update.greasyfork.icu/scripts/534088/Bing%20Rewards%20Lite%20%28Win%20%20Mac%29.user.js // @updateURL https://update.greasyfork.icu/scripts/534088/Bing%20Rewards%20Lite%20%28Win%20%20Mac%29.meta.js // ==/UserScript== (function () { /* ===== 基本配置 ===== */ const ID = 'bru_panel'; const VER = '1.5'; // 版本号更新 const TYPE = { min: 35, max: 80 }; const FALL = ['今日新闻', '天气预报', '电影票房', '体育比分', '股票行情']; /* ===== 热榜接口(按优先级) ===== */ const HOT_APIS = [ 'https://api.vvhan.com/api/hotlist/all', // 聚合 'https://api.vvhan.com/api/hotlist/wbHot', // 微博 'https://api-hot.imsyy.top/baidu?num=50' // 百度 ]; /* ===== 兼容新版 Bing 选择器 ===== */ const SELECTORS = ['#sb_form_q','.b_searchbox','input[name="q"]','#searchboxinput','textarea[name="q"]']; /* ===== 通用工具 ===== */ const tSet =(typeof GM_setTimeout ==='function'?GM_setTimeout :setTimeout); const tClr =(typeof GM_clearTimeout==='function'?GM_clearTimeout:clearTimeout); const iSet =(typeof GM_setInterval ==='function'?GM_setInterval :setInterval); const iClr =(typeof GM_clearInterval==='function'?GM_clearInterval:clearInterval); const z2=n=> (n<10?'0':'')+n; /* ===== 状态记录 ===== */ const today = new Date().toISOString().slice(0,10); // 新增 ultra_stable_mode 状态 const def = {date:today, pc:0, ph:0, running:true, max_pc: 40, max_ph: 30, ultra_stable_mode: false}; // 使用新的存储键,确保数据纯净 let rec = { ...def, ...GM_getValue('bru_lite_v15_final', {}) }; if(rec.date !== today) { rec.date = today; rec.pc = 0; rec.ph = 0; } GM_setValue('bru_lite_v15_final', rec); const mobile = /mobile|android|iphone|ipad|touch/i.test(navigator.userAgent); const key = mobile ? 'ph' : 'pc'; let limit; function updateLimit() { limit = mobile ? rec.max_ph : rec.max_pc; } updateLimit(); /* ===== 热榜词 ===== */ let HOT = []; async function fetchHot(){ for(const url of HOT_APIS){ try{ const json=await new Promise((ok,err)=>{ GM_xmlhttpRequest({method:'GET',url,onload:({responseText})=>{try{ok(JSON.parse(responseText));}catch(e){err(e);}},onerror:err}); }); HOT=parseHot(json); if(HOT.length) return; }catch{} } HOT=FALL; } function parseHot(obj){ const words=[]; const seen=new Set(); const isWord=s=> typeof s==='string' && s.trim().length>0 && s.length<=40; const skipRe=/^(微博|知乎|百度|抖音|36氪|哔哩哔哩|IT资讯|虎嗅网|豆瓣|人人都是产品经理|热搜|热榜|API)/; function add(s){s=s.trim();if(isWord(s)&&!skipRe.test(s)&&!seen.has(s)){seen.add(s);words.push(s);}} function walk(v){ if(Array.isArray(v)){ v.forEach(walk); }else if(v&&typeof v==='object'){ if(v.title) add(v.title); if(v.keyword)add(v.keyword); if(v.name) add(v.name); if(v.word) add(v.word); for(const k of ['list','hotList','data','hot','children','items']){ if(v[k]) walk(v[k]); } } } const root=obj?.data??obj; walk(root); return words; } /* ===== 样式 ===== */ GM_addStyle(`#${ID}{position:fixed;top:10px;right:10px;z-index:99999;width:200px;padding:10px 10px 8px 10px;font:11px/1.45 system-ui,-apple-system,BlinkMacSystemFont,sans-serif;color:#222;background:rgba(255,255,255,.55);backdrop-filter:blur(12px)saturate(1.4);border-radius:10px;box-shadow:0 4px 12px rgba(0,0,0,.18);overflow:visible;}#${ID} button{all:unset;font-size:10px;background:#3b82f6;color:#fff;border-radius:5px;padding:3px 8px;margin-left:4px;cursor:pointer;text-align:center;}#${ID} input[type="number"]{width:40px;font-size:10px;border:1px solid #ccc;border-radius:4px;padding:2px 4px;margin:0 4px;}#${ID} input[type="checkbox"]{vertical-align:middle;margin-right:4px;}.bar{height:4px;background:#d0d0d0;border-radius:3px;overflow:hidden;margin-top:3px}.fill{height:100%;width:100%;background:linear-gradient(90deg,#00b7ff,#00ffb7,#d4ff00,#ff6600,#ff00aa,#00b7ff);background-size:400% 100%;transform-origin:left;transition:transform .6s ease;animation:flow 5s linear infinite}@keyframes flow{0%{background-position:0 0}100%{background-position:100% 0}}.err{display:none;color:#e63946;font-weight:600;margin-top:2px;font-size:10px}.decor{position:absolute;right:4px;top:60px;width:32px;height:32px;border-radius:50%;background:conic-gradient(#00b7ff,#00ffb7,#d4ff00,#ff6600,#ff00aa,#00b7ff);animation:spin 7s linear infinite,pulse 3.5s ease-in-out infinite alternate;pointer-events:none;opacity:.75;filter:blur(1px) drop-shadow(0 0 4px rgba(0,0,0,.12));}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{from{transform:scale(.9)}to{transform:scale(1.05)}}`); /* ===== 面板 ===== */ function buildPanel(){if(document.getElementById(ID))return;const box=document.createElement('div');box.id=ID;box.innerHTML=`
BR Lite
模式:${mobile?'手机':'桌面'}
状态:${rec.running?'运行中':'已暂停'}
下次:--s
计数:${rec[key]} / ${limit}
运行:00:00:00
热词获取失败!
v${VER}
`;document.body.append(box);const drag=document.getElementById('drag');let d=false,sx=0,sy=0,lx=0,ly=0; const isInteractive=e=>e.target.tagName==='BUTTON'||e.target.tagName==='INPUT'||e.target.tagName==='LABEL'; drag.onmousedown=e=>{if(e.button!==0||isInteractive(e))return;d=true;sx=e.clientX;sy=e.clientY;lx=box.offsetLeft;ly=box.offsetTop;document.onmousemove=ev=>{if(!d)return;box.style.left=lx+ev.clientX-sx+'px';box.style.top=ly+ev.clientY-sy+'px'};document.onmouseup=()=>{d=false;document.onmousemove=document.onmouseup=null}}; drag.ontouchstart=e=>{if(isInteractive(e))return;d=true;sx=e.touches[0].clientX;sy=e.touches[0].clientY;lx=box.offsetLeft;ly=box.offsetTop;document.ontouchmove=ev=>{if(!d)return;box.style.left=lx+ev.touches[0].clientX-sx+'px';box.style.top=ly+ev.touches[0].clientY-sy+'px'};document.ontouchend=()=>{d=false;document.ontouchmove=document.ontouchend=null}}; document.getElementById('run').onclick=toggle;document.getElementById('clr').onclick=()=>{rec.pc=rec.ph=0;GM_setValue('bru_lite_v15_final',rec);draw()};document.getElementById('save').onclick=()=>{const newPc=parseInt(document.getElementById('max_pc').value,10);const newPh=parseInt(document.getElementById('max_ph').value,10);if(!isNaN(newPc)&&newPc>0)rec.max_pc=newPc;if(!isNaN(newPh)&&newPh>0)rec.max_ph=newPh;GM_setValue('bru_lite_v15_final',rec);updateLimit();draw();const saveBtn=document.getElementById('save');saveBtn.textContent='已保存!';tSet(()=>saveBtn.textContent='保存',1500)};document.getElementById('mode_switch').onchange=function(){rec.ultra_stable_mode=this.checked;GM_setValue('bru_lite_v15_final',rec);};} /* ===== UI 渲染 ===== */ const start=Date.now(); function draw(t='--'){document.getElementById('sta').textContent=rec.running?'运行中':'已暂停';document.getElementById('ctd').textContent=rec.running?t:'--';document.getElementById('num').textContent=rec[key];document.getElementById('limit').textContent=limit;document.getElementById('fill').style.transform=`scaleX(${Math.min(rec[key]/limit,1)})`;const d=Date.now()-start;document.getElementById('time').textContent=`${z2(d/3600000|0)}:${z2(d%3600000/60000|0)}:${z2(d%60000/1000|0)}`}; /* ===== 小工具 (核心拟人化升级) ===== */ function waitMs(){ if (rec.ultra_stable_mode) { // “超稳健模式” (~60分钟完成) const r = Math.random(); if (r < 0.6) { return (90 + Math.random() * 30) * 1000; } // 90-120秒 else { return (120 + Math.random() * 30) * 1000; } // 120-150秒 } else { // “快速模式” (~42分钟完成) const r = Math.random(); if (r < 0.33) { return (35 + Math.random() * 20) * 1000; } // 35-55秒 else if (r < 0.66) { return (60 + Math.random() * 30) * 1000; } // 60-90秒 else { return (100 + Math.random() * 50) * 1000; } // 100-150秒 } } async function preSearchHesitation() { await new Promise(r => tSet(r, 600 + Math.random() * 1400)); } async function typeHuman(inp,str){ inp.focus(); inp.value=''; for(const c of str){ inp.value+=c; inp.dispatchEvent(new Event('input',{bubbles:true})); if (c === ' ') { await new Promise(r => tSet(r, 120 + Math.random() * 150)); } await new Promise(r=>tSet(r,TYPE.min+Math.random()*(TYPE.max-TYPE.min))) } } async function advancedSoftScroll() { const h = document.body.scrollHeight - innerHeight; if (h <= 0) return; const scroll = (y, t) => new Promise(r => tSet(() => { window.scrollTo({ top: y, behavior: 'smooth' }); r(); }, t)); await scroll(h * (0.2 + Math.random() * 0.2), 300 + Math.random() * 300); await scroll(h * (0.5 + Math.random() * 0.2), 500 + Math.random() * 400); if (Math.random() < 0.3) { await scroll(h * (0.4 + Math.random() * 0.1), 400 + Math.random() * 200); } await scroll(h, 800 + Math.random() * 500); } /* ===== 主循环 & 搜索动作 ===== */ let loopTimer=0,ctdTimer=0; async function doSearch(){ try{ await preSearchHesitation(); const kw=HOT[Math.random()*HOT.length|0]; if(!kw)return; let inp=null; for(const sel of SELECTORS){inp=document.querySelector(sel);if(inp)break} if(inp){ await typeHuman(inp,kw); ['keydown','keypress','keyup'].forEach(evt=>inp.dispatchEvent(new KeyboardEvent(evt,{key:'Enter',keyCode:13,which:13,bubbles:true,cancelable:true}))); const form=inp.closest('form'); if(form)form.submit(); tSet(()=>{if(location.pathname==='/'||location.pathname==='')location.href=`https://www.bing.com/search?q=${encodeURIComponent(kw)}`;},800); rec[key]++; GM_setValue('bru_lite_v15_final',rec); await advancedSoftScroll(); } else { rec[key]++; GM_setValue('bru_lite_v15_final',rec); location.href=`https://www.bing.com/search?q=${encodeURIComponent(kw)}`; } } catch(e){console.error('[BR]',e)} } function loop(){if(!rec.running)return;if(rec[key]>=limit){stop();return}const w=waitMs();let c=w/1000|0;draw(c);ctdTimer=iSet(()=>{if(!rec.running){iClr(ctdTimer);return}draw(--c)},1000);loopTimer=tSet(async()=>{iClr(ctdTimer);await doSearch();loop()},w)} function startLoop(){if(rec[key]>=limit)return;rec.running=true;GM_setValue('bru_lite_v15_final',rec);loop()} function stop(){rec.running=false;GM_setValue('bru_lite_v15_final',rec);tClr(loopTimer);iClr(ctdTimer);draw()} function toggle(){rec.running?stop():startLoop();document.getElementById('run').textContent=rec.running?'暂停':'启动'} /* ===== 页面加载 ===== */ (async()=>{buildPanel();await fetchHot();if(HOT===FALL)document.getElementById('err').style.display='block';draw();if(rec.running)startLoop()})(); })();