Greasy Fork

Greasy Fork is available in English.

虎牙Plus

虎牙自动领取任务经验、开宝箱,复制直播流链接,简化页面,去广告, 夜间模式,自动进入剧场模式

当前为 2020-05-16 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

'use strict';
// ==UserScript==
// @name         虎牙Plus
// @namespace    http://tampermonkey.net/
// @icon         https://www.google.com/s2/favicons?domain=huya.com
// @version      1.0.7
// @description  虎牙自动领取任务经验、开宝箱,复制直播流链接,简化页面,去广告, 夜间模式,自动进入剧场模式
// @author       Francis
// @match        *://*.huya.com/*
// @grant        GM_setClipboard
// @license      MIT
// ==/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,
#hy-nav-download,
.hy-nav-kaibo,
.hy-nav-item:nth-child(2),
#J_roomGameBuy,
.jump-to-phone,
#week-star-btn,
.g-gift,
#J_bigStreamerStage
{
    display:none !important;
}

*{
    transition: background .5s;
}

.night-mode .duya-header-wrap,
.night-mode #main_col,
.night-mode .room-hd-l,
.night-mode .player-gift-wrap,
.night-mode .chat-room__ft,
.night-mode .jspPane,
.night-mode #J_profileNotice>div,
.night-mode .week-rank__btn,
.night-mode .J_msg,
.night-mode .chat-room__list,
.night-mode .msg-nobleEnter,
.night-mode .msg-nobleEnter>div,
.night-mode .msg-nobleSpeak,
.night-mode .player-face-arrow,
.night-mode #player-gift-tip,
.night-mode .jspVerticalBar,
.night-mode .illegal-report,
.night-mode .subscribe-hd.sub-on,
.night-mode .huya-plus-btn,
.night-mode #player-gift-tip bottom,
.night-mode #player-gift-tip btn,
.night-mode .fansBadge-box,
.night-mode .nav-expand-list,
.night-mode .tt-user-card,
.night-mode .share-entrance,
.night-mode .search-suggest,
.night-mode .u-links,
.night-mode .entrance-expand,
.night-mode .gameBuy-bd,
.night-mode .guide-to-app,
.night-mode .chat-room__wrap,
.night-mode #J_profileNotice,
.night-mode .msg-onTVLottery,
.night-mode .room-core,
.night-mode .msg-noble
{
    background-color: rgb(47, 48, 53) !important;
}

.night-mode #J_box_msgOfKing,
.night-mode .msg-of-king
{
    background: rgb(47, 48, 53) !important;
}

.night-mode .subscribe-hd.sub-on,
.night-mode .huya-plus-btn,
.night-mode .nav-expand-game dd a
{
    background-color: #464646 !important;
}

.night-mode .subscribe-hd.sub-on,
.night-mode .huya-plus-btn,
.night-mode .match-item
{
    color: #8e8a8a !important;
}

.night-mode .hy-nav-link,
.night-mode .hy-nav-title,
.night-mode .nav-user-title,
.night-mode #J_roomTitle,
.night-mode .msg,
.night-mode .subscribe-hd.sub-on,
.night-mode .huya-plus-btn,
.night-mode .cont-item,
.night-mode .week-rank__btn,
.night-mode .week-rank-name,
.night-mode .msg-nobleEnter,
.night-mode .peo-name,
.night-mode .search-item,
.night-mode .history-bd .new-clickstat,
.night-mode .from,
.night-mode .to,
.night-mode .nav-expand-game dd a,
.night-mode .hy-header-match-preview-name,
.night-mode #pub_msg_input,
.night-mode #search-bar-input:focus,
.night-mode .msg-noble,
.night-mode #J_box_msgOfKing,
.night-mode #J_hyUserCard .u-assets
{
    color: #E7E7E7 !important;
}

.night-mode .room-sidebar,
.night-mode .duya-header-wrap,
.night-mode .week-rank__unit,
.night-mode .chat-room__input,
.night-mode .chatNotice,
.night-mode #J_profileNotice,
.night-mode .plaer-face-icon-bg,
.night-mode .chat-room__ft__chat,
.night-mode #tipsOrchat
{
    border-color: #3e3e3e !important;
}

.night-mode .week-rank__btn.active,
.night-mode #pub_msg_input,
.night-mode #J_weekRankList li:hover,
.night-mode #J_fansRankList li:hover,
.night-mode .seat-item:hover,
.night-mode #search-bar-input,
.night-mode .search-item:hover,
.night-mode .video-link:hover,
.night-mode .history-bd .new-clickstat:hover,
.night-mode .video-item:hover,
.night-mode .match-item:hover,
.night-mode .hy-header-match-preview li:hover
{
    background-color: #565656 !important;
}

.night-mode-btn-wrapper{
    float: left;
    position: relative;
    margin-left:15px;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.night-mode-switch-btn{
    width: 50px;
    border: 1px solid #e4e4e4;
    height: 26px;
    border-radius: 13px;
    background-color:#ff8a00;
}

.night-mode-switch-dot{
    width: 24px;
    height: 24px;
    border-radius: 12px;
    background: #FFF;
    line-height: 24px;
    border:1px solid #b1b1b1;
    text-align: center;
    color: #6b6b6b;
    transition: all .5s;
    cursor: pointer;
    user-select:none;
}

.night-mode .night-mode-switch-btn{
    background-color:#8c8c8c;
}

.night-mode .night-mode-switch-dot{
    transform: translateX(24px);
}
`));

    document.head.appendChild(style);

    let copyStreamLinkNode = document.createElement('div');
    copyStreamLinkNode.style = "cursor: pointer;display:inline-flex;vertical-align:top;";
    const openWithPlayerBtn = isMacOS() ? `<span class="huya-plus-btn open-with-iina" style="position: relative;">使用IINA打开</span>`: `<span class="huya-plus-btn open-with-potplayer" style="position: relative;">使用PotPlayer打开</span>`;
    copyStreamLinkNode.innerHTML = `<span class="huya-plus-btn copy-stream-link" style="position: relative;">复制直播流</span>${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();
    });
}

function nightMode(){
    $("#J_global_user_tips").before(`
<div class="night-mode-btn-wrapper">
    <div class="night-mode-switch-btn">
        <div class="night-mode-switch-dot">日</div>
    </div>
</div>
`)

    let switchDay = ()=>{
        $(".night-mode-switch-dot").text("日");
        document.body.classList.remove('night-mode');
        localStorage.setItem("night-mode",false);
    }

    let switchNight = ()=>{
        $(".night-mode-switch-dot").text("夜");
        document.body.classList.add('night-mode');
        localStorage.setItem("night-mode",true);
    }

    $(".night-mode-switch-btn").click(()=>{
        if(document.body.classList.contains("night-mode")){
            switchDay();
        } else {
            switchNight();
        }
    })

    if(localStorage.getItem("night-mode") === 'true'){
        switchNight();
    }
}

// 自动领取礼物掉落的宝箱
let receiveTimer;
function autoReceiveTreasure(){
    if($("#J_treasureChestContainer .btn").size() === 0){
        return;
    }
    let receive = ()=>{
        if($("#J_treasureChestContainer .btn.usable").size() > 0){
            $("#J_treasureChestContainer .btn.usable").click()
            clearInterval(receiveTimer);
            receiveTimer = undefined;
        } else {
            chat('[送花]')
        }
    }
    if(!receiveTimer){
       receiveTimer = setInterval(receive,1000);
    }
}

let timer,treasureTimer;
(async function() {
    let intervalInMills = 10 * 60 * 1000 + 100;
    let task = ()=>{
        autoReceiveBoxReward();
        autoReceiveTaskXP();
    };
    await waitLoad();

    cleanPage();
    nightMode();
    $(".player-fullpage-btn").click();
    completeChatTask();
    addUi();
    task();
    if(timer) clearInterval(timer);
    timer = setInterval(task,intervalInMills);
    if(treasureTimer) clearInterval(treasureTimer)
    treasureTimer = setInterval(autoReceiveTreasure, 30000)
})();