// ==UserScript== // @name B站直播间简化 // @namespace https://live.bilibili.com/暂无主页 // @home https://github.com/Gamyou/bilibili-live-random-send // @version 1.0.0 // @description 定时发送;凌晨打卡;设置随机弹幕;弹幕分组管理;各直播间弹幕互不干扰;无人值守参与、关闭天选时刻;直播间防休眠;隐藏模块简化直播间等 // @author Gamyou // @match *://live.bilibili.com/* // @icon https://www.bilibili.com/favicon.ico // @license Apache License, Version 2.0 // @run-at document-idle // @grant GM_info // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_notification // @grant GM_openInTab // @grant GM_xmlhttpRequest // @connect jsdelivr.net // @connect greasyfork.org // @connect scriptcat.org // @note 24-09-10 2.5.0 处理缓存长时间不失效导致加载不了新版本的问题 // ==/UserScript== window.onload = (function () { const local = { "id": "RandomSendHelper", "text": "打卡", "default": "danmu", "config": "config" }, infoUrl = 'https://scriptcat.org/lib/2801/latest/RandomSendBaseInfo.js', frameUrl = 'https://scriptcat.org/zh-CN/script-show-page/9999999', isNull = str => { if (!str || str == "") { return true; } let regu = "^[ ]+$"; let re = new RegExp(regu); return re.test(str); }, delValue = key => GM_deleteValue(key), getValue = (key, defaultVaue) => { return GM_getValue(key, defaultVaue); }, setValue = (key, obj) => { if (isNull(key)) { console.warn('key为空,保存失败'); return; } if (obj) { GM_setValue(key, obj); } }, notice = (msg) => { if (isNull(msg)) { GM_notification(msg); } else { console.warn('消息对象为空,无效通知'); } }, compareVersion = (v1, v2) => { if (isNull(v1)) return -1; if (isNull(v2)) return 1; const a1 = v1.split('.').map(x => x * 1), a2 = v2.split('.').map(x => x * 1), len = Math.max(a1.length, a2.length); for (let i = 0; i < len; i++) { if ((a1[i] || 0) > (a2[i] || 0)) return 1; if ((a1[i] || 0) < (a2[i] || 0)) return -1; } return 0; }, getVersion = txt => { let m = txt.match(/@version\s+\d+\.\d+\.\d+/i); if (!m || 1 > m.length || !m[0]) { return 0; } let n = m[0].match(/\d+\.\d+\.\d+/); if (!n || 1 > n.length || !n[0]) { return 0; } return n[0]; }, getInfo = count => { count = count || 0; if (1 < count) { create(); } if (8 > count) { const d = { "url": infoUrl, "method": "GET", "nocache": true, "timeout": 15e3, "responseType": "json", "ontimeout": t => { console.log(`===> 获取信息超时【${JSON.stringify(t)}】`); getInfo(++count); }, "onerror": e => { console.log(`===> 获取信息出错【${JSON.stringify(e)}】`); getInfo(++count); }, "onload": r => { if (!r || !r.response) { console.log(`===> 获取信息为空,进行重试`); getInfo(++count); return; } let info = {...r.response, ...local}; info.url = (info.url || "").replace("@latest/", `@${info.version || "latest"}/`); if (0 < compareVersion(info.frame, GM_info?.script?.version)) { alert(`定时发随机弹幕版本过低,请及时升级`); GM_openInTab(frameUrl, {active: true}); return; } updateScript(info); } }; GM_xmlhttpRequest(d); } }, updateScript = (info, count) => { count = count || 0; let c = getValue((info.config || local.config), {}); if (!isNull(c.moduleVersion) && 0 == compareVersion(c.moduleVersion, info.version)) { create(info, c.script); return; } if (1 < count) { create(info, c.script); } if (!isNull(info.url) && 6 > count) { const d = { "url": info.url, "method": "GET", "nocache": true, "timeout": 20e3, "ontimeout": t => { console.log(`===> 获取脚本超时【${JSON.stringify(t)}】`); updateScript(info, ++count); }, "onerror": e => { console.log(`===> 获取脚本出错【${JSON.stringify(e)}】`); updateScript(info, ++count); }, "onload": r => { if (!r || !r.responseText) { console.log(`===> 获取脚本为空,进行重试`); updateScript(info, ++count); return; } create(info, r.responseText); c.script = r.responseText; c.moduleVersion = info.version; c.lastUpdate = new Date().toLocaleString(); setValue(info.config, c); checkVersion(); } }; GM_xmlhttpRequest(d); } }, create = (info, txt) => { if (!info) info = local; let script = document.getElementById(info.id); if (!script) { if (isNull(txt)) { let config = getValue((info.config), null); if (!config || !config.script) { return; } txt = config.script; } script = document.createElement('script'); script.id = info.id; script.type = 'text/javascript'; script.text = txt; document.head.appendChild(script); init(info); } }, init = info => { setGmNotice(notice); setGmGetValue(getValue); setGmSetValue(setValue); setGmDelValue(delValue); setBaseInfo(info); runStart(); }; getInfo(); })();