B站全局倒计时

全站同步倒计时,支持所有子域名,归零关闭所有B站页面

当前为 2025-03-08 提交的版本,查看 最新版本

// ==UserScript==
// @name         B站全局倒计时
// @namespace    https://gf.qytechs.cn/zh-CN/scripts/457839
// @version      4.0
// @description  全站同步倒计时,支持所有子域名,归零关闭所有B站页面
// @author       OYYS
// @match        https://*.bilibili.com/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_openInTab
// @grant        GM_notification
// @connect      bilibili.com
// @run-at       document-start
// @license      MIT
// @icon         https://www.google.com/s2/favicons?domain=bilibili.com
// ==/UserScript==

(function() {
    'use strict';

    // 存储初始化
    const initStorage = () => {
        if (!GM_getValue('globalEndTime')) {
            GM_setValue('globalEndTime', Date.now() + 7200000); // 2小时
            GM_setValue('timerStatus', 'running');
        }
    }

    // 创建倒计时UI
    const createTimerUI = () => {
        const timer = document.createElement('div');
        timer.id = 'bili-global-timer';
        timer.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: rgba(0,0,0,0.8);
            color: #00ff00;
            padding: 15px 25px;
            border-radius: 15px;
            font-family: 'Segoe UI', sans-serif;
            font-size: 1.5em;
            box-shadow: 0 0 15px rgba(0,255,0,0.3);
            z-index: 2147483647;
            transition: all 0.3s;
        `;
        document.body.appendChild(timer);
    }

    // 跨域同步控制器
    const syncController = () => {
        const checkStatus = () => {
            const status = GM_getValue('timerStatus');
            const endTime = GM_getValue('globalEndTime');

            if (status === 'expired' || Date.now() > endTime) {
                GM_setValue('timerStatus', 'expired');
                return true;
            }
            return false;
        }

        const closeAllTabs = () => {
            try {
                window.close();
                // 通过递归关闭所有同源页面
                if (window.opener) {
                    window.opener.postMessage('forceCloseBiliTabs', '*');
                }
            } catch(e) {
                GM_notification('请手动关闭B站标签页', '操作提醒');
            }
        }

        // 消息监听
        window.addEventListener('message', (e) => {
            if (e.data === 'forceCloseBiliTabs') {
                closeAllTabs();
            }
        });

        // 状态轮询
        setInterval(() => {
            if (checkStatus()) {
                document.getElementById('bili-global-timer').style.display = 'none';
                closeAllTabs();
                GM_setValue('timerStatus', 'expired');
            }
        }, 1000);
    }

    // 动态更新显示
    const updateDisplay = () => {
        const timerElement = document.getElementById('bili-global-timer');
        const formatTime = (ms) => {
            const hours = Math.floor(ms / 3600000);
            const minutes = Math.floor((ms % 3600000) / 60000);
            const seconds = Math.floor((ms % 60000) / 1000);
            return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
        }

        const update = () => {
            const endTime = GM_getValue('globalEndTime');
            const remaining = endTime - Date.now();

            timerElement.innerHTML = `⏳ 剩余时间:${formatTime(remaining)}`;

            // 样式变化
            if (remaining < 300000) { // 最后5分钟
                timerElement.style.color = '#ff0000';
                timerElement.style.animation = 'alertBlink 1s infinite';
            }
        }

        setInterval(update, 1000);
        update();
    }

    // 注入动画样式
    GM_addStyle(`
        @keyframes alertBlink {
            0% { opacity: 1; }
            50% { opacity: 0.3; }
            100% { opacity: 1; }
        }
        #bili-global-timer:hover {
            transform: scale(1.05);
            cursor: pointer;
        }
    `);

    // 初始化执行
    initStorage();
    createTimerUI();
    updateDisplay();
    syncController();

    // 右键菜单
    GM_registerMenuCommand('重置倒计时', () => {
        GM_setValue('globalEndTime', Date.now() + 7200000);
        GM_setValue('timerStatus', 'running');
        location.reload();
    });

    GM_registerMenuCommand('增加30分钟', () => {
        const currentEnd = GM_getValue('globalEndTime');
        GM_setValue('globalEndTime', currentEnd + 1800000);
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址