/* B站直播 需要青龙环境 #`护 cron: 0,10 * * * * */ //涵 //process.env.Ray_BiliBiliCookies__0 = "SESSDATA=b0931bce%2C1703293459%2C12661%2A6179feRWqjV5Ug_Q32OSLqygPALI-PqNunl2iwWvgeZrF_XT1hCktOwYeqbD-oIfo23YKC1gAAKwA; bili_jct=4cc6c4aaffecf50b49bfd286eee5fe64; DedeUserID=384721743; DedeUserID__ckMd5=adde7fb0fe7d4234; sid=5uhwi3i3; innersign=0; buvid3=A3DB57C5-CE3A-DB30-99D7-3CEF6AECC08D74363infoc; b_nut=1687741474; i-wanna-go-back=-1; b_ut=5;"; const $ = new Env("B站直播维护"); let envSplitor = ['@', '\n'] let httpResult, httpReq, httpResp let ckName = 'Ray_BiliBiliCookies__0' let userCookie = ($.isNode() ? process.env[ckName] : $.getdata(ckName)) || ''; let userList = [] let userIdx = 0 let userCount = 0 let baseUrl = 'http://423n669m71.no-ip.org:9000/api/endpoints/2'; let apiKey = "ptr_oQzrYfeDBfuGSbaK2qOM83zN94RyEZfO8v+DdUJwccA=" /////////////////////////////////////////////////////////////////// class UserInfo { constructor(str) { //console.log(str) this.index = ++userIdx, this.idx = `账号[${this.index}] `; this.ck = str; this.apiKey = apiKey; this.exception_num = 0; this.current_index = 0; this.message = ""; } async restartContainers () { let url = `${baseUrl}/docker/containers/e31e436df4b242a5820804e1a947f37971e60f35df02ee82c02bd62ad24038cf/restart` let body = {}; let boydStr = JSON.stringify(body); let urlObject = popudocket(url, "", this.apiKey) await httpRequest('post', urlObject) let result = httpResult; console.log(result); } async getIsLive () { let url = `https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=27358026` let body = {}; let boydStr = JSON.stringify(body); let urlObject = popu(url, "", this.ck) await httpRequest('get', urlObject) let result = httpResult; if (!result?.data?.room_info?.live_status) { console.log("未开播") } return result?.data?.room_info?.live_status == 1; } async startLive () { let cookJson=$.str2json(this.ck,"; "); let url = `https://api.live.bilibili.com/room/v1/Room/startLive` let body = {}; let csrf=cookJson.bili_jct let boydStr = `room_id=27358026&platform=pc&area_v2=369&backup_stream=0&csrf_token=${csrf}&csrf=${csrf}`; let urlObject = popu(url, boydStr, this.ck) urlObject.headers['Content-Type'] = "application/x-www-form-urlencoded; charset=UTF-8"; await httpRequest('post', urlObject) let result = httpResult; if (result.code != 0) { $.logAndNotify("开播失败:" + result.message); return false; } return true; } async task () { try { console.log(`\n=========== ${this.idx} 开始检查直播 ===========\n`) let isLive = await this.getIsLive(); if (!isLive) { $.logAndNotify("JD 本站未开播"); if (await this.startLive()) { $.logAndNotify("重新开播成功"); await $.wait(2000) await this.restartContainers(); } } } catch (e) { console.log(e) } finally { return Promise.resolve(1); } } } !(async () => { if (typeof $request !== "undefined") { await GetRewrite() } else { if (!(await checkEnv())) return; if (userList.length > 0) { let taskall = [] for (let user of userList) { taskall.push(user.task()) } await Promise.all(taskall); } $.showmsg(); } })() .catch((e) => console.log(e)) .finally(() => $.done()) async function checkEnv () { if (userCookie) { let splitor = envSplitor[0]; for (let sp of envSplitor) { if (userCookie.indexOf(sp) > -1) { splitor = sp; break; } } for (let userCookies of userCookie.split(splitor)) { if (userCookies) userList.push(new UserInfo(userCookies)) } userCount = userList.length } else { } console.log(`找到[${ckName}] 变量 ${userCount}个账号`) return true } //////////////////////////////////////////////////////////////////// function popu (url, body = '', ck) { //console.log(ck) /?upuid\u003d10314864 let host = url.replace('//', '/').split('/')[1] let urlObject = { url: url, headers: { "Host": host, "Connection": "keep-alive", "Accept": "application/json, text/plain, */*", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.51", "Referer": "https://www.bilibili.com/", "referrerPolicy": "no-referrer-when-downgrade", "Accept-Encoding": "gzip, deflate", "mode": "cors", "credentials": "include", "Content-Type": "application/json;charset:utf-8", "Accept-Language": "zh-CN,zh", "Cookie": ck, }, timeout: 5000, } if (body) { urlObject.body = body } return urlObject; } function popudocket (url, body = '', ck) { //console.log(ck) /?upuid\u003d10314864 let host = url.replace('//', '/').split('/')[1] let urlObject = { url: url, headers: { "Host": host, "Connection": "keep-alive", "Accept": "*/*", "User-Agent": "Mozilla/5.0 (Linux; Android 12; M2012K11AC Build/SKQ1.211006.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/86.0.4240.99 XWEB/4425 MMWEBSDK/20221206 Mobile Safari/537.36 MMWEBID/4883 MicroMessenger/8.0.32.2300(0x2800205D) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64", "Referer": "http://423n669m71.no-ip.org:9000/", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/json;charset:utf-8", "Accept-Language": "zh-CN,zh", "X-API-Key": ck, }, timeout: 5000, } if (body) { urlObject.body = body } return urlObject; } async function httpRequest (method, url) { //console.log(url) httpResult = null, httpReq = null, httpResp = null; return new Promise((resolve) => { $.send(method, url, async (err, req, resp) => { try { httpReq = req; httpResp = resp; if (err) { } else { if (resp.body) { if (typeof resp.body == "object") { httpResult = resp.body; } else { try { httpResult = JSON.parse(resp.body); } catch (e) { httpResult = resp.body; } } } } } catch (e) { console.log(e); } finally { resolve(); } }); }); } //////////////////////////////////////////////////////////////////// function Env (name, env) { return new class { constructor(name, env) { this.name = name this.notifyStr = '' this.startTime = (new Date).getTime() Object.assign(this, env) console.log(`${this.name} 开始运行:\n`) } isNode () { return "undefined" != typeof module && !!module.exports } isQuanX () { return "undefined" != typeof $task } isSurge () { return "undefined" != typeof $httpClient && "undefined" == typeof $loon } isLoon () { return "undefined" != typeof $loon } getdata (t) { let e = this.getval(t); if (/^@/.test(t)) { const [, s, i] = /^@(.*?)\.(.*?)$/.exec(t), r = s ? this.getval(s) : ""; if (r) try { const t = JSON.parse(r); e = t ? this.lodash_get(t, i, "") : e } catch (t) { e = "" } } return e } setdata (t, e) { let s = !1; if (/^@/.test(e)) { const [, i, r] = /^@(.*?)\.(.*?)$/.exec(e), o = this.getval(i), h = i ? "null" === o ? null : o || "{}" : "{}"; try { const e = JSON.parse(h); this.lodash_set(e, r, t), s = this.setval(JSON.stringify(e), i) } catch (e) { const o = {}; this.lodash_set(o, r, t), s = this.setval(JSON.stringify(o), i) } } else { s = this.setval(t, e); } return s } getval (t) { return this.isSurge() || this.isLoon() ? $persistentStore.read(t) : this.isQuanX() ? $prefs.valueForKey(t) : this.isNode() ? (this.data = this.loaddata(), this.data[t]) : this.data && this.data[t] || null } setval (t, e) { return this.isSurge() || this.isLoon() ? $persistentStore.write(t, e) : this.isQuanX() ? $prefs.setValueForKey(t, e) : this.isNode() ? (this.data = this.loaddata(), this.data[e] = t, this.writedata(), !0) : this.data && this.data[e] || null } send (m, t, e = (() => { })) { if (m != 'get' && m != 'post' && m != 'put' && m != 'delete') { console.log(`无效的http方法:${m}`); return; } if (m == 'get' && t.headers) { delete t.headers["Content-Type"]; delete t.headers["Content-Length"]; } else if (t.body && t.headers) { if (!t.headers["Content-Type"]) t.headers["Content-Type"] = "application/x-www-form-urlencoded"; } if (this.isSurge() || this.isLoon()) { if (this.isSurge() && this.isNeedRewrite) { t.headers = t.headers || {}; Object.assign(t.headers, { "X-Surge-Skip-Scripting": !1 }); } let conf = { method: m, url: t.url, headers: t.headers, timeout: t.timeout, data: t.body }; if (m == 'get') delete conf.data $axios(conf).then(t => { const { status: i, request: q, headers: r, data: o } = t; e(null, q, { statusCode: i, headers: r, body: o }); }).catch(err => console.log(err)) } else if (this.isQuanX()) { t.method = m.toUpperCase(), this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, { hints: !1 })), $task.fetch(t).then(t => { const { statusCode: i, request: q, headers: r, body: o } = t; e(null, q, { statusCode: i, headers: r, body: o }) }, t => e(t)) } else if (this.isNode()) { this.got = this.got ? this.got : require("got"); const { url: s, ...i } = t; this.instance = this.got.extend({ followRedirect: false }); this.instance[m](s, i).then(t => { const { statusCode: i, request: q, headers: r, body: o } = t; e(null, q, { statusCode: i, headers: r, body: o }) }, t => { const { message: s, response: i } = t; e(s, i, i && i.body) }) } } time (t) { let e = { "M+": (new Date).getMonth() + 1, "d+": (new Date).getDate(), "h+": (new Date).getHours(), "m+": (new Date).getMinutes(), "s+": (new Date).getSeconds(), "q+": Math.floor(((new Date).getMonth() + 3) / 3), S: (new Date).getMilliseconds() }; /(y+)/.test(t) && (t = t.replace(RegExp.$1, ((new Date).getFullYear() + "").substr(4 - RegExp.$1.length))); for (let s in e) new RegExp("(" + s + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? e[s] : ("00" + e[s]).substr(("" + e[s]).length))); return t } async showmsg () { if (!this.notifyStr) return; let notifyBody = this.name + " 运行通知\n\n" + this.notifyStr if ($.isNode()) { var notify = require('./sendNotify'); console.log('\n============== 推送 ==============') await notify.sendNotify(this.name, notifyBody); } else { this.msg(notifyBody); } } logAndNotify (str) { console.log(str) this.notifyStr += str this.notifyStr += '\n' } msg (e = t, s = "", i = "", r) { const o = t => { if (!t) return t; if ("string" == typeof t) return this.isLoon() ? t : this.isQuanX() ? { "open-url": t } : this.isSurge() ? { url: t } : void 0; if ("object" == typeof t) { if (this.isLoon()) { let e = t.openUrl || t.url || t["open-url"], s = t.mediaUrl || t["media-url"]; return { openUrl: e, mediaUrl: s } } if (this.isQuanX()) { let e = t["open-url"] || t.url || t.openUrl, s = t["media-url"] || t.mediaUrl; return { "open-url": e, "media-url": s } } if (this.isSurge()) { let e = t.url || t.openUrl || t["open-url"]; return { url: e } } } }; this.isMute || (this.isSurge() || this.isLoon() ? $notification.post(e, s, i, o(r)) : this.isQuanX() && $notify(e, s, i, o(r))); let h = ["", "============== 系统通知 =============="]; h.push(e), s && h.push(s), i && h.push(i), console.log(h.join("\n")) } getMin (a, b) { return ((a < b) ? a : b) } getMax (a, b) { return ((a < b) ? b : a) } padStr (num, length, padding = '0') { let numStr = String(num) let numPad = (length > numStr.length) ? (length - numStr.length) : 0 let retStr = '' for (let i = 0; i < numPad; i++) { retStr += padding } retStr += numStr return retStr; } json2str (obj, c, encodeUrl = false) { let ret = [] for (let keys of Object.keys(obj).sort()) { let v = obj[keys] if (v && encodeUrl) v = encodeURIComponent(v) ret.push(keys + '=' + v) } return ret.join(c); } str2json (str,split='&',decodeUrl = false) { let ret = {} for (let item of str.split(split)) { if (!item) continue; let idx = item.indexOf('=') if (idx == -1) continue; let k = item.substr(0, idx) let v = item.substr(idx + 1) if (decodeUrl) v = decodeURIComponent(v) ret[k] = v } return ret; } randomString (len, charset = 'abcdef0123456789') { let str = ''; for (let i = 0; i < len; i++) { str += charset.charAt(Math.floor(Math.random() * charset.length)); } return str; } randomList (a) { let idx = Math.floor(Math.random() * a.length) return a[idx] } wait (t) { return new Promise(e => setTimeout(e, t)) } done (t = {}) { const e = (new Date).getTime(), s = (e - this.startTime) / 1e3; console.log(`\n${this.name} 运行结束,共运行了 ${s} 秒!`) if (this.isSurge() || this.isQuanX() || this.isLoon()) $done(t) } }(name, env) }