'use strict';
// ==UserScript==
// @name 虎牙Plus
// @namespace http://tampermonkey.net/
// @icon https://www.google.com/s2/favicons?domain=huya.com
// @version 0.2.4
// @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: block;
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:#FFF;
background:#ffa801;
border-radius:10px;
margin-right: 30px;
user-select: none;
}
`));
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;
let info = config.stream.data[0].gameStreamInfoList[0]
return `${info.sHlsUrl}/${info.sStreamName}.${info.sHlsUrlSuffix}?${info.sHlsAntiCode}`;
}
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") === 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);
})();