您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
懒人冲虫,自动检测点踩开车刹车
// ==UserScript== // @name coco-pa // @icon https://www.hololive.tv/favicon.ico // @version 0.15 // @description 懒人冲虫,自动检测点踩开车刹车 // @author coco-pa // @match *://www.youtube.com/* // @match *://schedule.hololive.tv/* // @match *://www.google.com/sorry/* // @grant GM_setValue // @grant GM_getValue // @grant GM_openInTab // @grant window.close // @grant unsafeWindow // @run-at document-start // @grant GM_xmlhttpRequest // @grant unsafeWindow // @namespace https://greasyfork.org/zh-CN/users/700210-coco-pa // ==/UserScript== const config = { channel: "UCS9uQI-jC3DE0L4IpXyvr6w", autoOpenDLC: true, // 自动打开独轮车 DLCConfig: { slowMode: { minCycleSec: "90", maxCycleSec: "100" }, fastMode: { minCycleSec: "5", maxCycleSec: "10" } } } let comfirmDom = { box: null, text: null, ok: null, cancel: null } const log = function(text){ const date = new Date() console.log(`[全自动冲蝗][${date.getHours()<10?'0'+date.getHours():date.getHours()}:${date.getMinutes()<10?'0'+date.getMinutes():date.getMinutes()}:${date.getSeconds()<10?'0'+date.getSeconds():date.getSeconds()}]${text}`) } function cocopacomfirm(text,ok,cancel){ if(!comfirmDom.box){ comfirmDom.box = document.createElement("div") comfirmDom.box.style="z-index: 9999;position:fixed;width: 400px;height: 200px;left: 50%;top: 50%;transform: translate(-50%, -50%);box-shadow: 0px 0px 10px #000;background-color: #fff;" document.body.append(comfirmDom.box) comfirmDom.text = document.createElement("div") comfirmDom.text.style="height: 150px;text-align: center;" comfirmDom.text.innerHTML = "" comfirmDom.box.append(comfirmDom.text) comfirmDom.ok = document.createElement("div") comfirmDom.ok.style="cursor: pointer;line-height:50px;height: 50px;width:200px;text-align: center;float:left;" comfirmDom.ok.innerHTML = "确认" comfirmDom.box.append(comfirmDom.ok) comfirmDom.cancel = document.createElement("div") comfirmDom.cancel.style="cursor: pointer;line-height:50px;height: 50px;width:200px;text-align: center;float:left;" comfirmDom.cancel.innerHTML = "取消" comfirmDom.box.append(comfirmDom.cancel) } comfirmDom.text.innerHTML = `[全自动冲蝗]${text}` comfirmDom.ok.onclick=function(){ comfirmDom.box.style.display = "none" ok() } comfirmDom.cancel.onclick=function(){ comfirmDom.box.style.display = "none" cancel() } } let exitTimer function exit(text){ try{ clearTimeout(exitTimer) }catch(e){} exitTimer = setTimeout(()=>{ window.close() unsafeWindow.close() },1*60*1000) cocopacomfirm(`${text}<br />点击确认立即退出,点击取消取消退出,不点击1分钟后退出`,()=>{ window.close() unsafeWindow.close() },()=>{ clearTimeout(exitTimer) }) } function inWatchPage(){ const refs = { name: null, button: null } let isDLCError = false function isLive(){ document.querySelector(".ytp-live-badge") && document.querySelector(".ytp-live-badge").click() return !!(document.querySelector(".ytp-live") && document.querySelector(".ytp-live-badge") && document.querySelector(".ytp-live-badge").disabled) } function isWaitLive(){ return document.querySelector(".ytp-live") !== null && document.querySelector(".ytp-live").style.display === "none" } function hasDLC(){ try{ return !!unsafeWindow.dulunche.refs }catch(e){ return false } } function checkBan(){ return new Promise((res)=>{ try{ // YouTube聊天观察哨提供api // https://greasyfork.org/scripts/414521 window.top.document.querySelector("#chatframe").contentWindow.checkSuperChat().then((status)=>{ if(status.error !== null){ if(!(refs.button.classList.value.indexOf("style-default-active")>-1)){ refs.button.click() } log(`当前账号可能已被封禁: ${status.error}`) exit(`当前账号可能已被封禁,视频已踩,1分钟后关闭: ${status.error}`) res(true) }else{ res(false) } }) }catch(e){ res(false) } }) } function waitDLC(){ if(hasDLC() && isLive()){ if(isDLCError){ exit("独轮车开启失败,视频已踩,1分钟后关闭") return } log("独轮车输出,等待直播结束") let timeout = 0 const timer = setInterval(()=>{ if(!isLive()){ if(document.querySelector(".videowall-endscreen").style.display === "none"){ document.querySelector(".ytp-live-badge").click() setTimeout(()=>{ if(!isLive()){ timeout += 1; if(timeout > 2){ if(!(refs.button.classList.value.indexOf("style-default-active")>-1)){ refs.button.click() } clearInterval(timer) exit("直播已结束,视频已踩,1分钟后关闭") } } },500) }else{ if(!(refs.button.classList.value.indexOf("style-default-active")>-1)){ refs.button.click() } clearInterval(timer) exit("直播已结束,视频已踩,1分钟后关闭") } }else{ timeout = 0 } // 开启会员专享模式情况或其他不可评论的情况 // if(document.querySelector("#chatframe").contentDocument.querySelector("yt-live-chat-restricted-participation-renderer")){ // if(!(refs.button.classList.value.indexOf("style-default-active")>-1)){ // refs.button.click() // } // exit("不可评论,视频已踩,1分钟后关闭") // } },60000) checkBan().then((isBan)=>{ if(!isBan){ const checkBanTimer = setInterval(()=>{ checkBan().then((isBan)=>{ if(isBan){ clearInterval(checkBanTimer) } }) },5*60*1000)// 5分钟检测一次ban情况 } }) }else{ exit("未检测到独轮车或直播已结束,视频已踩,1分钟后关闭") } } function setDefinition(){ setTimeout(()=>{ // 调整画质 log(`调整画质`) document.querySelector(".ytp-settings-button").click() setTimeout(()=>{ const bts = document.querySelectorAll(".ytp-settings-menu .ytp-menuitem") bts[bts.length-1].click() setTimeout(()=>{ const bts = document.querySelectorAll(".ytp-quality-menu .ytp-menuitem") bts[bts.length-2].click() },1000) },1000) },60000) } const waitDown = function(){ log("开始计时观看10分钟") setTimeout(()=>{ if(refs.button.classList.value.indexOf("style-default-active")>-1){ log("已踩") }else{ refs.button.click() } waitDLC() },60*1000*10) } const tryOpenDLC = function(){ if(hasDLC()){ try{ document.querySelector(".dlc-suspension").click() // 更新远程弹幕库 const bts = document.querySelectorAll(".dlc-cmd>div")[1].querySelectorAll("button") bts[bts.length-1].click() }catch(e){ isDLCError = true } setTimeout(()=>{ try{ let flag = false if(/慢速/.test(document.querySelector(".ytd-live-chat-frame").contentDocument.querySelector("#input-container label").innerText)){ flag = unsafeWindow.dulunche.config.minCycleSec !== String(config.DLCConfig.slowMode.minCycleSec) || unsafeWindow.dulunche.config.maxCycleSec !== String(config.DLCConfig.slowMode.maxCycleSec) unsafeWindow.dulunche.config.minCycleSec = String(config.DLCConfig.slowMode.minCycleSec) unsafeWindow.dulunche.config.maxCycleSec = String(config.DLCConfig.slowMode.maxCycleSec) }else{ flag = unsafeWindow.dulunche.config.minCycleSec !== String(config.DLCConfig.fastMode.minCycleSec) || unsafeWindow.dulunche.config.maxCycleSec !== String(config.DLCConfig.fastMode.maxCycleSec) unsafeWindow.dulunche.config.minCycleSec = String(config.DLCConfig.fastMode.minCycleSec) unsafeWindow.dulunche.config.maxCycleSec = String(config.DLCConfig.fastMode.maxCycleSec) } if(flag){ setTimeout(()=>{ if(document.querySelector(".dlc-titlebar>button").innerHTML === "出动"){ document.querySelector(".dlc-titlebar>button").click() }else{ document.querySelector(".dlc-titlebar>button").click() setTimeout(()=>{ document.querySelector(".dlc-titlebar>button").click() },500) } },1000) }else{ if(document.querySelector(".dlc-titlebar>button").innerHTML === "出动"){ document.querySelector(".dlc-titlebar>button").click() } } }catch(e){ log("开启独轮车失败") console.error(e) isDLCError = true } },5000) } } const start = function(){ try{ if(refs.name.getAttribute("href") !== `/channel/${config.channel}`){ log("非蝗直播间: " + refs.name.getAttribute("href")) return } if(isLive() && config.autoOpenDLC){ tryOpenDLC() } if(document.querySelector("#related") && document.querySelector("#related").querySelector("paper-toggle-button") && document.querySelector("#related").querySelector("paper-toggle-button").getAttribute("aria-pressed") == "true"){ log("关闭自动播放") document.querySelector("#related").querySelector("paper-toggle-button").click() } if(document.querySelector(".ytp-autonav-toggle-button") && document.querySelector(".ytp-autonav-toggle-button").getAttribute("aria-checked") == "true"){ log("关闭自动播放") document.querySelector(".ytp-autonav-toggle-button").click() } if(refs.button.classList.value.indexOf("style-default-active")>-1){ log("此视频已踩过") waitDLC() setDefinition() }else{ if(isWaitLive()){ log("直播尚未开始,等待开始后计时观看") const waitLiveTimer = setInterval(()=>{ if(isLive()){ waitDown() setDefinition() clearInterval(waitLiveTimer) } },60000) }else{ // 正在直播和直播结束都会观看10钟后踩 waitDown() setDefinition() } } }catch(e){ console.log(e) } } const findRefsTimer = setInterval(() => { try { refs.name = document.querySelector("#channel-name .yt-simple-endpoint.style-scope.yt-formatted-string") refs.button = document.querySelectorAll("#top-level-buttons ytd-toggle-button-renderer")[1] if(refs.name.getAttribute("href")){ clearInterval(findRefsTimer) log("元素定位成功") start() } } catch (e) { } }, 1000); } async function inSchedulePage(){ setTimeout(()=>{ window.location.reload() },60000) window.addEventListener("load",async function(){ let fireList = [] try{ fireList = JSON.parse(GM_getValue("coco-pa-live")) if(!Array.isArray(fireList)){ fireList = [] } }catch(e){ fireList = [] } const thumbnails = document.querySelectorAll(".thumbnail") let nowFlag = false for(let i=0;i<thumbnails.length;i++){ const thumbnail = thumbnails[i] const name = thumbnail.querySelector(".name").innerHTML const watchURL = thumbnail.getAttribute("href") if(/red/.test(thumbnail.style.border)){ nowFlag = true } if(/桐生ココ/.test(name) && /red/.test(thumbnail.style.border)){ if(fireList.includes(watchURL)){ log(`[JPT: ${thumbnail.querySelector('.datetime').innerText}]该直播已处理过`) }else{ fireList.push(watchURL) GM_setValue("coco-pa-live",JSON.stringify(fireList)) GM_openInTab(watchURL,{ active: true }) return } } if(/桐生ココ/.test(name) && nowFlag && !/red/.test(thumbnail.style.border)){ log("即将开始的直播[JPT]: " + thumbnail.querySelector('.datetime').innerText) } } log("holo日程表未发现虫皇正在直播且未冲的的直播间") try{ const response = await new Promise((res,rej)=>{ const curl = GM_xmlhttpRequest({ method: "GET", url: `https://dsjzxgqd48j6m.cloudfront.net/coco-gachi.json`, onload: (response)=>{ try{ res(JSON.parse(response.response)) }catch(e){ rej(e) } } }) }) if(response.currentLives.length > 0){ const watchURL = response.currentLives[0].link if(!fireList.includes(watchURL)){ fireList.push(watchURL) GM_setValue("coco-pa-live",JSON.stringify(fireList)) GM_openInTab(watchURL,{ active: true }) return }else{ log(`正在直播但已处理: ${response.currentLives[0].title}`) } }else{ log("API未发现虫皇正在直播且未冲的的直播间") for(let upcomingLive of response.upcomingLives){ log("即将开始的直播: " + upcomingLive.title) } } }catch(e){ log("直播信息API访问失败") console.log(e) } }) } async function inBotCheck(){ Notification.requestPermission(function (status) { if (Notification.permission !== status) { Notification.permission = status; } if(location.href === "https://www.google.com/sorry/index?coco-pa"){ if (status === "granted") { new Notification("授权已完成"); } else { alert("授权已完成:未获得通知授权"); } window.close() }else{ if (status === "granted") { new Notification("请完成人机验证"); } else { alert("请完成人机验证"); } } }); } (function() { 'use strict'; if(window.self !== window.top){ return } if(/www\.youtube\.com/.test(location.href)){ if(/www\.youtube\.com\/watch\?v=/.test(location.href)){ inWatchPage() } let href = location.href setInterval(()=>{ if(href !== location.href && /www\.youtube\.com\/watch\?v=/.test(location.href)){ location.reload() } href = location.href },1000) } if(/schedule\.hololive\.tv/.test(location.href)){ if(!GM_getValue("coco-pa-checkbot")){ alert("当前为首次打开脚本,请先进行人机验证页的通知授权,使遇到人机验证时及时收到通知") GM_openInTab("https://www.google.com/sorry/index?coco-pa",{ active: true }) GM_setValue("coco-pa-checkbot","true") } log("当前为直播表页") inSchedulePage() } if(/www\.google\.com\/sorry/.test(location.href)){ log("人机验证") inBotCheck() } })();