'use strict'; // ==UserScript== // @name 虎牙Plus // @namespace http://tampermonkey.net/ // @icon https://www.google.com/s2/favicons?domain=huya.com // @version 0.2.9 // @description 虎牙自动领取任务经验、开宝箱,复制直播流链接,简化页面,去广告 // @author Francis // @match *://*.huya.com/* // @grant GM_setClipboard // @downloadURL none // ==/UserScript== let $; function addUi(){ let style = document.createElement('style'); style.appendChild(document.createTextNode(` span.copy-stream-link:after { display: none; position: absolute; content: ""; right: -20px; top: 6px; width: 18px; height: 18px; overflow: hidden; background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA4RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0YjMyYjVhNy1jMThjLTg2NDItYjRlMy04NzdmMjFiZjkzZTciIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEJCNDhFNEIxMDZBMTFFN0IzQUNGNTM3RTZBMjEyRTQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEJCNDhFNEExMDZBMTFFN0IzQUNGNTM3RTZBMjEyRTQiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKFdpbmRvd3MpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MmFlNTQ3NDgtZjlmZS04NjQwLTg0ZTgtMmY4ZTcwYjc2YTkyIiBzdFJlZjpkb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6NWE5YjI1YjQtZmE1ZC0xMWU2LWI1MmYtYWM2NWYxZGRlZjQ2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+KzIZ1wAAAz9JREFUeNqslm1IU1EYx5/dzSW+pWVZppimzV7pzZWVIhGFZiIEgmFlREGmH4qEJOhFqEVf+tCXviiCZC/4Icga0ocwIyURcmnO2ZIyM9+auqnb1NnzXM5sm7u719wffrC7c+7zP+fc55zzyDQN+0BEMiQNOYYcQBKRCNZmQr4iH5A6pBGZ8xVM4aONQwqRMmbiTVEMGkgpM9cgVYhDKKg3xSPNSIUPM29KZO80sxiSDDOQj0gK/L9SWIx0McMjSD0SCUsXxXiDHBUyVCG1iBL8JyWLqfI0lCPVSCj4WWtDN4ekxp6uZh7zWXpmid9sYfpzSkhbfwHU6/JBJuNSekZbCn+bOysUbJ+V+dNsTYgKspNvQmRQPMw4bKDt0gCaXcOmSgXLpER/GMnwC+2NLYD09eeBkylganoMajuuQt94u3PLpJNhlj/MgpUrISf5FsSF7+GfLfZheKIrhpHJ767dsshwv1gwGm3YstUwav3ltT0ufDea3eZNSeO2ATQrAdNUr2fXVDJM8j3yFZC76Q6sCk6AZ58vQ7/5i1u7OuYkZMQX4aD4JASzbRBq2i7h4Pq8hdvIuRzECxQdugUKd1ZB7PIdEKgIg/ztD/nfzizMSS6HQwkl82a2GQs8b78iZEaKEDy8t0ZlQmZSGci5gH+7WB4EedseQH33fdgVfYIfkFPTDismSCkMTRhB7LYwsRPfTQOWLrDOmPkldVUAFwjZqhseveegTl8OvWOfxNLBREva7a1laOIb1OiK+GwTU0PPI+gafislmQ1k2CTUSilNCUBZJ6SOwXpo6q2WunuayPCVrx5/pn6gaRGMWfth4bIbQGu4K3bJu+o1Gb5jN7WgaP89bruI++rn/H+UkS86r+PRZZdqRh6NHBvePbHetKz0TWnGJK1B4zYACSIPh/zw2Rh60LEjLtrXG/bZSdBjclhsQ6AbeLkYs1akmCbnvA9nkVN0BIq9OWEfgZa+p4sxo5gFzMPtxtcjeTQRP95UdhZTL1TTaJFcKTOVOLNcFtNn1aZlt3/rEsxaWQyt1LqUlkCNnEOMizAysnfUrssotfKmyrmSVdEHkePs7tzgUeobWalPafteqOJ26q8AAwB8rQG0tt5ioQAAAABJRU5ErkJggg==); background-size: 18px 18px; } span.copy-stream-link.copy-success:after { display: block; } .huya-plus-btn{ display: block; padding:0 10px; color:#b08444; background:#FFD29E; border-radius:15px; margin-left: 30px; user-select: none; transition:all .5s; } .huya-plus-btn:hover{ color:#FFF; background:#ffa801; } #huya-ab,.player-banner-gift,#player-marquee-wrap,.room-gg-chat,.room-mod-ggTop{ display:none !important; } `)); document.head.appendChild(style); let copyStreamLinkNode = document.createElement('div'); copyStreamLinkNode.style = "cursor: pointer;display:inline-flex;vertical-align:top;"; const openWithPlayerBtn = isMacOS() ? `使用IINA打开`: `使用PotPlayer打开`; copyStreamLinkNode.innerHTML = `复制直播流${openWithPlayerBtn}`; document.querySelector('.host-title').appendChild(copyStreamLinkNode); document.querySelector('.copy-stream-link').onclick = e=>{ GM_setClipboard(getStreamUrl()); showCopySuccessIcon(); }; $(".open-with-iina").click(()=>{ openStreamWithIINA(getStreamUrl()); }); $(".open-with-potplayer").click(()=>{ openStreamWithPotPlayer(getStreamUrl()); }); } function getStreamUrl(){ let config = unsafeWindow.hyPlayerConfig; try{ let info = config.stream.data[0].gameStreamInfoList[0] return `${info.sHlsUrl}/${info.sStreamName}.${info.sHlsUrlSuffix}?${info.sHlsAntiCode}`; }catch(e){ alert("获取直播流链接失败,房间未开播或刷新页面后重试") throw e; } } function isMacOS(){ var UserAgent = navigator.userAgent.toLowerCase(); return /mac os/.test(UserAgent); } function showCopySuccessIcon(){ $('span.copy-stream-link').addClass('copy-success'); setTimeout(()=>{$('span.copy-stream-link').removeClass('copy-success');},1000) } function autoReceiveBoxReward(){ let rewardBtns = $(".player-box-list .player-box-stat3").filter((i,it)=>$(it).css("visibility") === 'visible'); if(rewardBtns.size() > 0){ let btn = $(rewardBtns[0]); btn.click(); let waitComplete = ()=>{ if(btn.css("visibility") === 'hidden'){ $("#player-box").hide(); console.log("开启宝箱"); autoReceiveBoxReward(); } else { setTimeout(waitComplete,1000); } }; setTimeout(waitComplete,1000); } } function autoReceiveTaskXP(){ let taskBtns = $(".tasks .status .status-get"); if(taskBtns.size() > 0){ $.each(taskBtns,(_,btn)=>{ $(btn).click(); }); console.log(`自动领取经验,本次完成${taskBtns.length}个任务`) } } function cleanPage(){ $(".room-gg-chat").remove(); $(".room-footer").remove(); } function completeChatTask(){ const taskInfo = $(".tasks .tit").filter((i,it)=>$(it).text() === '在1场直播中发送弹幕'); const taskDone = taskInfo.siblings(".status").find(".status-ing").size() === 0; if(!taskDone){ chat('[送花]') } } function chat(msg){ $("#pub_msg_input").val(msg).keyup(); $("#msg_send_bt").click(); } function pageLoaded(){ $ = unsafeWindow.$ if($){ if($(".tasks .status").size() == 0){ $(".nav-user-title").mouseenter() } return $(".box-icon-word").size() > 0 && $(".tasks .status").size() > 0 } return false; } function openStreamWithPotPlayer(streamUrl){ openStreamWithPlayer("PotPlayer://", streamUrl); } function openStreamWithIINA(streamUrl){ openStreamWithPlayer("iina://weblink?url=", streamUrl) } function openStreamWithPlayer(playerUrlSchema, streamUrl){ window.open(`${playerUrlSchema}${streamUrl}`, "_self") } async function waitLoad(){ return new Promise(function(resolve,reject){ let w = ()=>{ if(pageLoaded()){ resolve(); } else { setTimeout(w,1000); } } w(); }); } let timer; (async function() { let intervalInMills = 10 * 60 * 1000 + 100; let task = ()=>{ autoReceiveBoxReward(); autoReceiveTaskXP(); }; await waitLoad(); cleanPage(); completeChatTask(); addUi(); task(); if(timer) clearInterval(timer); timer = setInterval(task,intervalInMills); })();