Greasy Fork

Greasy Fork is available in English.

直播吧助手

直播吧使用助手,包括标题栏比分、新闻模块排序调整等

当前为 2023-03-19 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name            直播吧助手
// @namespace       http://tampermonkey.net/
// @version         2.75
// @description     直播吧使用助手,包括标题栏比分、新闻模块排序调整等
// @author          purezhi
// @icon            https://tu.duoduocdn.com/logo/logo_o3x_02.png
// @match           https://*.zhibo8.cc/*
// @require         https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @require         https://cdn.jsdelivr.net/npm/[email protected]/notyf.min.js
// @resource        CSS_notyf https://cdn.jsdelivr.net/npm/[email protected]/notyf.min.css
// @grant           GM_getResourceText
// @grant           GM_addStyle
// ==/UserScript==

var notyf = null;

var page = '';
var $cntr = null;
var modSltr = '';
var headSltr = '';
var ttlSltr = '';
var localKey = '';

(function() {
    'use strict';

    const notyfCss = GM_getResourceText("CSS_notyf");
    GM_addStyle(notyfCss);

    GM_addStyle(`
        .notyf__message { font-size: 14px; }
        .zb8-hlp-bar { position: absolute; right: 5px; top: 5px; }
        .zb8-hlp-bar .bbtn { height: 26px; line-height: 22px; padding: 0 10px; border-radius: 13px; user-select: none; display: inline-flex; align-items: center; justify-content: center; outline: none; cursor: pointer; background-image: linear-gradient(to top, #D8D9DB 0%, #fff 80%, #FDFDFD 100%); border: 1px solid #8F9092; box-shadow: 0 4px 3px 1px #FCFCFC, 0 6px 8px #D6D7D9, 0 -4px 4px #CECFD1, 0 -6px 4px #FEFEFE, inset 0 0 3px 0 #CECFD1; transition: all 0.2s ease; font-size: 13px; color: #606060; text-shadow: 0 1px #fff; }
        .zb8-hlp-bar .bbtn::-moz-focus-inner { border: 0; }
        .zb8-hlp-bar .bbtn:hover:not([disabled]) { box-shadow: 0 3px 2px 1px #FCFCFC, 0 5px 7px #D6D7D9, 0 -3px 3px #CECFD1, 0 -5px 3px #FEFEFE, inset 0 0 2px 2px #CECFD1; }
        .zb8-hlp-bar .bbtn:focus:not(:active) { animation: active 0.9s alternate infinite; outline: none; }
        .zb8-hlp-bar .bbtn:active:not([disabled]) { box-shadow: 0 3px 2px 1px #FCFCFC, 0 5px 7px #D6D7D9, 0 -3px 3px #CECFD1, 0 -5px 3px #FEFEFE, inset 0 0 4px 2px #999, inset 0 0 15px #aaa; }
        .zb8-hlp-bar .bbtn > * { transition: transform 0.2s ease; }
        .zb8-hlp-bar .bbtn:hover:not([disabled]) > * { transform: scale(0.975); }
        .zb8-hlp-bar .bbtn:active:not([disabled]) > * { transform: scale(0.95); }
        .zb8-hlp-tool { position: absolute; top: -26px; left: 0; right: 0; text-align: right; padding: 0; background: rgba(255,255,255,0.7); backdrop-filter: blur(12px); opacity: 0.15; }
        .zb8-hlp-tool a.opt { cursor: pointer; font-size: 14px !important; margin-left: 5px; }
        #middle .video { margin-bottom: 25px; }
        #middle .www_page .video:nth-child(1), #middle .www_page .video:nth-child(2) { margin-top: 30px; }
        #middle .zb8-hlp-tool a.opt { font-size: 14px !important; }
    `);

    notyf = new Notyf({ position: {x: 'center', y:'top'}, dismissible:true, duration: 2500 });

    initSorting();
    initScoreTitle();
})();

function initSorting() {
    if (/^https?:\/\/www\.zhibo8\.cc\/nba\/?$/.test(location.href)) {
        page = 'www_nba';
    }
    else if (/^https?:\/\/www\.zhibo8\.cc\/zuqiu\/?$/.test(location.href)) {
        page = 'www_zuqiu';
    }
    else if (/^https?:\/\/news\.zhibo8\.cc\/nba\/?$/.test(location.href)) {
        page = 'news_nba';
    }
    else if (/^https?:\/\/news\.zhibo8\.cc\/zuqiu\/?$/.test(location.href)) {
        page = 'news_zuqiu';
    }

    if (!page) return;

    $cntr = $('#middle .m_left');
    if (page === 'www_nba' || page === 'www_zuqiu') {
      $cntr.addClass('www_page');
    }
    modSltr = '.video.v_change';
    headSltr = '.v_top';
    ttlSltr = '.v_top>a:first-child';
    localKey = 'sorting_' + page;

    $('.menu .container').append( `
        <div class="zb8-hlp-bar">
            <button mod-order-save class="bbtn">保存排序</button>
            <button mod-order-reset class="bbtn">重置排序</button>
        </div>
    `);

    $(document).on('click', '[mod-order-save]', function (event) {
        saveSort();
    });

    $(document).on('click', '[mod-order-reset]', function (event) {
        if (localStorage.getItem(localKey) != null) {
            localStorage.removeItem(localKey);
        }
        location.reload();
    });

    $(document).on('click', '[mod-top]', function (event) {
        let $el = $(this);
        let $mod = $el.closest(modSltr);
        if ($mod.length <= 0 || $mod.prevAll(modSltr).length <= 0) return;
        $mod.insertBefore($mod.prevAll(modSltr).last());
    });

    $(document).on('click', '[mod-prev]', function (event) {
        let $el = $(this);
        let $mod = $el.closest(modSltr);
        if ($mod.length <= 0 || $mod.prev(modSltr).length <= 0) return;
        $mod.insertBefore($mod.prev(modSltr));
    });

    $(document).on('click', '[mod-next]', function (event) {
        let $el = $(this);
        let $mod = $el.closest(modSltr);
        if ($mod.length <= 0 || $mod.next(modSltr).length <= 0) return;
        $mod.insertAfter($mod.next(modSltr));
    });

    let sortings = loadSort();

    const modCount = $(modSltr).length;
    $(modSltr).each(function (idx, el) {
        let $head = $(el).find(headSltr);
        if (!$head) return;

        let $titleEl = $(el).find(ttlSltr);
        if (!$titleEl) return;

        const title = $titleEl.html();
        if (!title) return;

        let sort = modCount - idx;
        if (sortings && sortings[title] != null) {
            sort = sortings[title];
        }

        $(el).attr('mod-order', sort);

        $head.css('position', 'relative');
        $head.append(`
            <div mod-sort class="zb8-hlp-tool">
                <a class="opt" mod-top href="javascript:;">⬆️置顶</a>
                <a class="opt" mod-prev href="javascript:;">⬅️ 前移</a>
                <a class="opt" mod-next href="javascript:;">➡️️ 后移</a>
            </div>
        `);
    });

    doSort();

    $('[mod-sort]').on('mouseover', function (event) {
        $(this).css('opacity', '1');
    })
    $('[mod-sort]').on('mouseout', function (event) {
        $(this).css('opacity', '0.15');
    });
}

function initScoreTitle() {
    if (!/https?:\/\/(www\.)?zhibo8\.cc\/zhibo\/nba\/([^\.]+?)\.htm/.test(location.href)) return;

    var ttlIntrvl = setInterval(function() {
        showScoreTitle();
    }, 3000);
    showScoreTitle();
}

function doSort() {
    const modArr = []
    let max = 0;
    $(modSltr).each(function (idx, el) {
        let sort = $(el).attr('mod-order');
        if (!sort) return;

        sort = parseInt(sort)
        modArr[sort] = $(el);
        if (max < sort) max = parseInt(sort);
    });

    for (let i = 0; i <= max; i++) {
        if (!modArr[i]) continue;
        modArr[i].insertBefore(modSltr + ':first-child');
    }
}

function loadSort() {
    if (localStorage.getItem(localKey)) {
        return JSON.parse(localStorage.getItem(localKey));
    }
    return null;
}

function saveSort() {
    const sortings = {};
    const modCount = $(modSltr).length;
    $(modSltr).each(function (idx, el) {
        let $head = $(el).find(headSltr);
        if (!$head) return;

        let $titleEl = $(el).find(ttlSltr);
        if (!$titleEl) return;

        const title = $titleEl.html();
        if (!title) return;

        sortings[title] = modCount - idx;
    });

    localStorage.setItem(localKey, JSON.stringify(sortings));

    showSuccess('保存成功');
}

function showScoreTitle() {
    const vtm = document.querySelectorAll('.bf_table .visit_team_name a');
    if (vtm.length < 1) {
        console.warn("no visit team");
        return;
    }
    const vsc = document.querySelectorAll('.bf_top .bf_box.tmtop .time_score .visit_score');
    if (vtm.length < 1) {
        console.warn("no visit score");
        return;
    }
    const htm = document.querySelectorAll('.bf_table .home_team_name a');
    if (vtm.length < 1) {
        console.warn("no host team");
        return;
    }
    const hsc = document.querySelectorAll('.bf_top .bf_box.tmtop .time_score .host_score');
    if (vtm.length < 1) {
        console.warn("no host score");
        return;
    }

    document.title = `${vtm[0].innerText} ${vsc[0].innerText} ➲ ${htm[0].innerText} ${hsc[0].innerText}`;
}

function showError(msg) {
    showMsg(msg, 'error')
}

function showSuccess(msg) {
    showMsg(msg, 'success')
}

function showMsg(msg, typ) {
    if (notyf) notyf.open({
        type: typ ? typ : 'info',
        message: msg
    });
    else alert(msg);
}