【微赞直播】801微赞直播间观看刷新器

自动刷新微赞直播热度,支持本地存储,可设置倍数、目标热度和停止时间

// ==UserScript==
// @name         【微赞直播】801微赞直播间观看刷新器
// @namespace    http://tampermonkey.net/
// @version      1.2.1
// @description  自动刷新微赞直播热度,支持本地存储,可设置倍数、目标热度和停止时间
// @author       明灯花月夜
// @match        https://zb.jingyi.tv/live/page*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 本地存储键名
    const STORAGE_KEY = 'wz-refresher-data';

    // 添加自定义样式
    GM_addStyle(`
        #wz-refresher-container {
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 9999;
            background: rgba(255, 255, 255, 0.98);
            border-radius: 15px;
            box-shadow: 0 5px 30px rgba(0, 0, 0, 0.25);
            padding: 22px;
            width: 360px;
            font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
            border: 1px solid #e2e8f0;
            transition: all 0.3s ease;
            backdrop-filter: blur(6px);
        }

        #wz-refresher-container:hover {
            box-shadow: 0 8px 35px rgba(0, 0, 0, 0.3);
        }

        .wz-refresher-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 18px;
            padding-bottom: 18px;
            border-bottom: 1px solid #f0f5ff;
        }

        .wz-refresher-title {
            font-size: 22px;
            font-weight: 800;
            color: #2c3e50;
            display: flex;
            align-items: center;
            text-shadow: 0 2px 4px rgba(0,0,0,0.05);
            background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
        }

        .wz-refresher-title i {
            margin-right: 12px;
            font-size: 24px;
        }

        .wz-refresher-close {
            background: none;
            border: none;
            font-size: 22px;
            cursor: pointer;
            color: #a0aec0;
            transition: all 0.2s;
            width: 34px;
            height: 34px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .wz-refresher-close:hover {
            background: #f8fafc;
            color: #e53e3e;
            transform: rotate(90deg);
        }

        .wz-input-group {
            margin-bottom: 18px;
        }

        .wz-input-label {
            display: block;
            margin-bottom: 8px;
            font-weight: 700;
            color: #4a5568;
            font-size: 15px;
            display: flex;
            align-items: center;
        }

        .wz-input-label i {
            margin-right: 10px;
            color: #718096;
            font-size: 18px;
            min-width: 24px;
        }

        .wz-input {
            width: 100%;
            padding: 12px 16px;
            border: 1px solid #e2e8f0;
            border-radius: 12px;
            font-size: 16px;
            transition: all 0.3s;
            background: #f8fafc;
            color: #2d3748;
            box-sizing: border-box;
        }

        .wz-input:focus {
            outline: none;
            border-color: #4299e1;
            background: #fff;
            box-shadow: 0 0 0 4px rgba(66, 153, 225, 0.2);
        }

        .wz-button {
            width: 100%;
            padding: 14px;
            border: none;
            border-radius: 12px;
            font-size: 17px;
            font-weight: 700;
            cursor: pointer;
            transition: all 0.25s ease;
            margin-top: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            box-shadow: 0 4px 6px rgba(0,0,0,0.05);
        }

        .wz-button i {
            margin-right: 10px;
            font-size: 20px;
        }

        .wz-button-primary {
            background: linear-gradient(135deg, #4f46e5, #7c3aed);
            color: white;
        }

        .wz-button-primary:hover {
            background: linear-gradient(135deg, #4338ca, #6d28d9);
            transform: translateY(-3px);
            box-shadow: 0 6px 12px rgba(79, 70, 229, 0.3);
        }

        .wz-button-primary:active {
            transform: translateY(0);
        }

        .wz-button-stop {
            background: linear-gradient(135deg, #e53e3e, #c53030);
            color: white;
        }

        .wz-button-stop:hover {
            background: linear-gradient(135deg, #c53030, #9b2c2c);
            transform: translateY(-3px);
            box-shadow: 0 6px 12px rgba(229, 62, 62, 0.3);
        }

        .wz-button-stop:active {
            transform: translateY(0);
        }

        .wz-stats-container {
            background: linear-gradient(135deg, #f8fafc, #edf2f7);
            border-radius: 12px;
            padding: 18px;
            margin-top: 20px;
            border: 1px solid #e2e8f0;
        }

        .wz-stats-title {
            font-size: 16px;
            font-weight: 800;
            color: #4a5568;
            margin-bottom: 14px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .wz-stats-title i {
            margin-right: 10px;
            color: #4f46e5;
            font-size: 18px;
        }

        .wz-stats-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 14px;
        }

        .wz-stat {
            background: white;
            border-radius: 10px;
            padding: 12px;
            text-align: center;
            box-shadow: 0 4px 8px rgba(0,0,0,0.03);
            border: 1px solid #e2e8f0;
            transition: transform 0.3s ease;
        }

        .wz-stat:hover {
            transform: translateY(-3px);
            box-shadow: 0 6px 12px rgba(0,0,0,0.08);
        }

        .wz-stat-value {
            font-size: 22px;
            font-weight: 900;
            color: #2d3748;
            margin-bottom: 5px;
            text-shadow: 0 2px 3px rgba(0,0,0,0.05);
        }

        .wz-stat-label {
            font-size: 14px;
            color: #718096;
            font-weight: 600;
        }

        .wz-status {
            margin-top: 20px;
            padding: 16px;
            border-radius: 12px;
            font-size: 15px;
            text-align: center;
            font-weight: 600;
            display: none;
            border: 1px solid;
        }

        .wz-status.running {
            display: block;
            background: rgba(56, 161, 105, 0.1);
            color: #38a169;
            border-color: rgba(56, 161, 105, 0.3);
        }

        .wz-status.stopped {
            display: block;
            background: rgba(229, 62, 62, 0.1);
            color: #e53e3e;
            border-color: rgba(229, 62, 62, 0.3);
        }

        .wz-logo {
            display: flex;
            justify-content: center;
            margin-top: 20px;
            opacity: 0.8;
        }

        .wz-logo-text {
            font-size: 14px;
            color: #718096;
            font-weight: 600;
        }

        .wz-pulse {
            display: inline-block;
            width: 12px;
            height: 12px;
            background: #38a169;
            border-radius: 50%;
            margin-left: 10px;
            animation: pulse 1.5s infinite;
        }

        @keyframes pulse {
            0% { transform: scale(0.9); opacity: 0.7; }
            50% { transform: scale(1.1); opacity: 1; }
            100% { transform: scale(0.9); opacity: 0.7; }
        }

        .wz-save-indicator {
            position: absolute;
            top: 8px;
            right: 8px;
            font-size: 13px;
            color: #38a169;
            opacity: 0;
            transition: opacity 0.3s;
            font-weight: 600;
            background: rgba(56, 161, 105, 0.15);
            padding: 3px 8px;
            border-radius: 20px;
        }

        .wz-save-indicator.show {
            opacity: 1;
        }

        .wz-refresh-icon {
            position: absolute;
            top: 10px;
            left: 10px;
            font-size: 24px;
            color: #4f46e5;
            animation: spin 1.5s linear infinite;
            display: none;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
    `);

    // 保存数据到本地存储
    function saveData(data) {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
        showSaveIndicator();
    }

    // 显示保存指示器
    function showSaveIndicator() {
        const indicator = document.getElementById('wz-save-indicator');
        if (indicator) {
            indicator.classList.add('show');
            setTimeout(() => indicator.classList.remove('show'), 1000);
        }
    }

    // 从本地存储加载数据
    function loadData() {
        const data = localStorage.getItem(STORAGE_KEY);
        return data ? JSON.parse(data) : null;
    }

    // 主函数
    function initRefresher() {
        // 创建UI容器
        const container = document.createElement('div');
        container.id = 'wz-refresher-container';
        container.innerHTML = `
            <div class="wz-refresh-icon">🔄</div>
            <div class="wz-refresher-header">
                <div class="wz-refresher-title">
                    <i>🔥</i> 801微赞网页刷新器
                </div>
                <button class="wz-refresher-close">×</button>
            </div>

            <div class="wz-input-group">
                <label class="wz-input-label">
                    <i>⚡</i> 当前倍数
                </label>
                <input type="number" id="wz-multiplier" class="wz-input" min="1" value="1" placeholder="每次刷新增加的热度倍数">
            </div>

            <div class="wz-input-group">
                <label class="wz-input-label">
                    <i>🎯</i> 目标热度
                </label>
                <input type="number" id="wz-target-heat" class="wz-input" placeholder="达到此热度后停止">
            </div>

            <div class="wz-input-group">
                <label class="wz-input-label">
                    <i>⏱️</i> 停止时间
                </label>
                <input type="datetime-local" id="wz-stop-time" class="wz-input">
            </div>

            <button id="wz-start-btn" class="wz-button wz-button-primary">
                <i>▶️</i> 开始刷新
            </button>
            <button id="wz-stop-btn" class="wz-button wz-button-stop">
                <i>⏹️</i> 停止刷新
            </button>

            <div class="wz-stats-container">
                <div class="wz-stats-title">
                    <i>📊</i> 统计信息
                </div>
                <div class="wz-stats-grid">
                    <div class="wz-stat">
                        <div class="wz-stat-value" id="wz-current-heat">0</div>
                        <div class="wz-stat-label">当前热度</div>
                    </div>
                    <div class="wz-stat">
                        <div class="wz-stat-value" id="wz-refresh-count">0</div>
                        <div class="wz-stat-label">刷新次数</div>
                    </div>
                    <div class="wz-stat">
                        <div class="wz-stat-value" id="wz-time-left">--:--</div>
                        <div class="wz-stat-label">剩余时间</div>
                    </div>
                    <div class="wz-stat">
                        <div class="wz-stat-value" id="wz-next-refresh">0s</div>
                        <div class="wz-stat-label">下次刷新</div>
                    </div>
                </div>
            </div>

            <div id="wz-status" class="wz-status">准备就绪</div>

            <div class="wz-logo">
                <div class="wz-logo-text">微赞网页刷新器 v4.0 | 数据已本地保存</div>
            </div>

            <div id="wz-save-indicator" class="wz-save-indicator">✓ 已保存</div>
        `;

        document.body.appendChild(container);

        // 获取DOM元素
        const currentHeatEl = document.getElementById('wz-current-heat');
        const refreshCountEl = document.getElementById('wz-refresh-count');
        const timeLeftEl = document.getElementById('wz-time-left');
        const nextRefreshEl = document.getElementById('wz-next-refresh');
        const startBtn = document.getElementById('wz-start-btn');
        const stopBtn = document.getElementById('wz-stop-btn');
        const closeBtn = container.querySelector('.wz-refresher-close');
        const statusEl = document.getElementById('wz-status');
        const multiplierInput = document.getElementById('wz-multiplier');
        const targetHeatInput = document.getElementById('wz-target-heat');
        const stopTimeInput = document.getElementById('wz-stop-time');
        const refreshIcon = container.querySelector('.wz-refresh-icon');

        // 状态变量
        let refreshInterval = null;
        let refreshCount = 0;
        let startTime = null;
        let stopTime = null;
        let targetHeat = null;
        let multiplier = 1;
        let isRunning = false;
        let nextRefreshTime = null;

        // 从本地存储加载数据
        function loadSavedData() {
            const savedData = loadData();
            if (savedData) {
                multiplierInput.value = savedData.multiplier || 1;
                targetHeatInput.value = savedData.targetHeat || '';
                stopTimeInput.value = savedData.stopTime || '';
                refreshCount = savedData.refreshCount || 0;
                startTime = savedData.startTime || null;
                stopTime = savedData.stopTime ? new Date(savedData.stopTime).getTime() : null;
                isRunning = savedData.isRunning || false;
                nextRefreshTime = savedData.nextRefreshTime || null;

                refreshCountEl.textContent = refreshCount;

                if (isRunning) {
                    // 如果之前是运行状态,重新开始
                    startRefreshing(true);
                }
            }
        }

        // 保存当前状态
        function saveCurrentState() {
            const data = {
                multiplier: multiplier,
                targetHeat: targetHeat,
                stopTime: stopTimeInput.value,
                refreshCount: refreshCount,
                startTime: startTime,
                isRunning: isRunning,
                nextRefreshTime: nextRefreshTime
            };
            saveData(data);
        }

        // 更新当前热度 - 修复版本
        function updateCurrentHeat() {
            try {
                // 修复选择器问题
                const heatElement = document.querySelector('.live-info__item:has(.iconguankan2) p');

                if (!heatElement) {
                    // 备用选择器
                    const items = document.querySelectorAll('.live-info__item');
                    for (const item of items) {
                        const icon = item.querySelector('.iconguankan2');
                        if (icon) {
                            const p = item.querySelector('p');
                            if (p) {
                                const heat = parseInt(p.textContent.trim()) || 0;
                                currentHeatEl.textContent = heat;
                                return heat;
                            }
                        }
                    }
                } else {
                    const heat = parseInt(heatElement.textContent.trim()) || 0;
                    currentHeatEl.textContent = heat;
                    return heat;
                }
            } catch (e) {
                console.error('获取热度失败:', e);
            }
            return 0;
        }

        // 实际刷新页面
        function performPageRefresh() {
            // 显示刷新动画
            refreshIcon.style.display = 'block';

            // 保存当前状态
            saveCurrentState();

            // 模拟刷新延迟
            setTimeout(() => {
                // 实际刷新页面
                location.reload();
            }, 500);
        }

        // 开始刷新
        function startRefreshing(fromLoad = false) {
            if (isRunning && !fromLoad) return;

            // 获取输入值
            multiplier = parseInt(multiplierInput.value) || 1;
            targetHeat = parseInt(targetHeatInput.value) || null;
            stopTime = stopTimeInput.value ? new Date(stopTimeInput.value).getTime() : null;

            // 验证输入
            if (!targetHeat && !stopTime && !fromLoad) {
                showStatus('请设置目标热度或停止时间', 'stopped');
                return;
            }

            // 重置状态
            if (!fromLoad) {
                refreshCount = 0;
                startTime = Date.now();
            }
            isRunning = true;

            // 更新UI
            startBtn.disabled = true;
            statusEl.className = 'wz-status running';
            statusEl.innerHTML = '刷新中... <span class="wz-pulse"></span>';

            // 清除之前的定时器
            if (refreshInterval) {
                clearInterval(refreshInterval);
            }

            // 开始刷新循环
            refreshInterval = setInterval(() => {
                // 保存下一次刷新时间
                nextRefreshTime = Date.now() + 3000;

                // 更新刷新次数
                refreshCount++;
                refreshCountEl.textContent = refreshCount;

                // 更新下次刷新时间
                updateNextRefreshTime();

                // 检查停止条件
                const currentHeat = updateCurrentHeat();
                const currentTime = Date.now();

                // 保存当前状态
                saveCurrentState();

                // 检查目标热度
                if (targetHeat && currentHeat >= targetHeat) {
                    stopRefreshing(`已达到目标热度: ${targetHeat}`);
                    return;
                }

                // 检查停止时间
                if (stopTime && currentTime >= stopTime) {
                    stopRefreshing(`已到达停止时间`);
                    return;
                }

                // 计算剩余时间
                if (stopTime) {
                    const remaining = Math.floor((stopTime - currentTime) / 1000);
                    const minutes = Math.floor(remaining / 60);
                    const seconds = remaining % 60;
                    timeLeftEl.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
                }

                // 执行实际页面刷新
                performPageRefresh();

            }, 3000); // 每3秒刷新一次

            // 初始更新
            updateCurrentHeat();
            updateNextRefreshTime();

            // 保存状态
            saveCurrentState();
        }

        // 更新下次刷新时间
        function updateNextRefreshTime() {
            if (refreshInterval && nextRefreshTime) {
                const next = Math.floor((nextRefreshTime - Date.now()) / 1000);
                if (next > 0) {
                    nextRefreshEl.textContent = `${next}s`;
                } else {
                    nextRefreshEl.textContent = '0s';
                }
            } else {
                nextRefreshEl.textContent = '0s';
            }
        }

        // 停止刷新
        function stopRefreshing(message = '已停止刷新') {
            if (!isRunning) return;

            if (refreshInterval) {
                clearInterval(refreshInterval);
                refreshInterval = null;
            }
            isRunning = false;

            // 更新UI
            startBtn.disabled = false;
            statusEl.className = 'wz-status stopped';
            statusEl.textContent = message;

            // 重置计时器显示
            nextRefreshEl.textContent = '0s';

            // 保存状态
            saveCurrentState();
        }

        // 显示状态
        function showStatus(message, type = '') {
            statusEl.className = `wz-status ${type}`;
            statusEl.textContent = message;
            setTimeout(() => {
                if (!isRunning) {
                    statusEl.className = 'wz-status';
                    statusEl.textContent = '';
                }
            }, 3000);
        }

        // 事件监听
        startBtn.addEventListener('click', () => startRefreshing(false));
        stopBtn.addEventListener('click', () => stopRefreshing('已手动停止'));
        closeBtn.addEventListener('click', () => {
            container.style.display = 'none';
        });

        // 输入变化时保存数据
        multiplierInput.addEventListener('input', saveCurrentState);
        targetHeatInput.addEventListener('input', saveCurrentState);
        stopTimeInput.addEventListener('input', saveCurrentState);

        // 初始化当前热度
        updateCurrentHeat();

        // 设置默认停止时间(1小时后)
        const now = new Date();
        now.setHours(now.getHours() + 1);
        stopTimeInput.value = now.toISOString().slice(0, 16);

        // 从本地存储加载数据
        loadSavedData();

        // 每秒更新下次刷新时间
        setInterval(() => {
            if (isRunning) {
                updateNextRefreshTime();
            }
        }, 500);
    }

    // 页面加载完成后初始化
    if (document.readyState === 'complete') {
        initRefresher();
    } else {
        window.addEventListener('load', initRefresher);
    }
})();