专技天下自动刷课脚本

自动播放并静音,自动下一节,后台播放不暂停

Dieses Skript sollte nicht direkt installiert werden. Es handelt sich hier um eine Bibliothek für andere Skripte, welche über folgenden Befehl in den Metadaten eines Skriptes eingebunden wird // @require https://update.greasyfork.org/scripts/588921/1887495/%E4%B8%93%E6%8A%80%E5%A4%A9%E4%B8%8B%E8%87%AA%E5%8A%A8%E5%88%B7%E8%AF%BE%E8%84%9A%E6%9C%AC.js

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey oder Violentmonkey installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey oder Violentmonkey installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey oder Userscripts installieren.

Um dieses Skript zu installieren, müssen Sie eine Erweiterung wie Tampermonkey installieren.

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

Um dieses Design zu installieren, müssen Sie eine Erweiterung wie Stylus installieren.

Um dieses Design zu installieren, müssen Sie eine Erweiterung wie Stylus installieren.

Um dieses Design zu installieren, müssen Sie eine Erweiterung wie Stylus installieren.

Um diesen Stil zu installieren, müssen Sie eine Erweiterung für den Benutzerstil Verwaltung installieren.

Um diesen Stil zu installieren, müssen Sie eine Erweiterung für den Benutzerstil Verwaltung installieren.

Um diesen Stil zu installieren, müssen Sie eine Erweiterung für den Benutzerstil Verwaltung installieren.

(Ich habe bereits einen Benutzerstil Verwaltung, ich möchte ihn installieren!)

// ==UserScript==
// @name         zgzjzj-autoplay
// @namespace    https://tampermonkey.net/
// @version      2.0
// @description  auto play zgzjzj courses, works when minimized
// @author       Antigravity
// @match        https://www.zgzjzj.com/learncenter/play*
// @match        https://*.zgzjzj.com/learncenter/play*
// @grant        none
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    // ============================================================
    // PART 1: Override Page Visibility API
    // This MUST run at document-start, before the site's own scripts
    // ============================================================

    // 1a. Override document.hidden to always return false
    Object.defineProperty(document, 'hidden', {
        get: function () { return false; },
        configurable: true
    });

    // 1b. Override document.visibilityState to always return 'visible'
    Object.defineProperty(document, 'visibilityState', {
        get: function () { return 'visible'; },
        configurable: true
    });

    // 1c. Override document.webkitVisibilityState (for older WebKit browsers)
    Object.defineProperty(document, 'webkitVisibilityState', {
        get: function () { return 'visible'; },
        configurable: true
    });

    // 1d. Block visibilitychange events so the site never knows you left
    document.addEventListener('visibilitychange', function (e) {
        e.stopImmediatePropagation();
    }, true);
    document.addEventListener('webkitvisibilitychange', function (e) {
        e.stopImmediatePropagation();
    }, true);

    // 1e. Block blur/focus events on window (some sites use these too)
    window.addEventListener('blur', function (e) {
        e.stopImmediatePropagation();
    }, true);
    window.addEventListener('focus', function (e) {
        e.stopImmediatePropagation();
    }, true);

    // 1f. Override document.hasFocus to always return true
    document.hasFocus = function () { return true; };

    console.log('[zgzjzj-helper] Visibility API override applied');

    // ============================================================
    // PART 2: Web Worker based timer (immune to browser throttling)
    // ============================================================

    function createWorkerTimer(callback, interval) {
        var blob = new Blob([
            'var iv = setInterval(function(){ postMessage("tick"); }, ' + interval + ');'
        ], { type: 'application/javascript' });
        var url = URL.createObjectURL(blob);
        var worker = new Worker(url);
        worker.onmessage = function () {
            callback();
        };
        return worker;
    }

    // ============================================================
    // PART 3: Main automation logic (runs after page loads)
    // ============================================================

    window.addEventListener('load', function () {
        console.log('[zgzjzj-helper] script loaded, starting automation');

        var CONFIG = {
            playbackRate: 1.0,
            checkInterval: 2000,
            autoMute: true
        };

        // --- UI Panel ---
        function createUI() {
            if (document.getElementById('zgzjzj-helper-panel')) return;
            var panel = document.createElement('div');
            panel.id = 'zgzjzj-helper-panel';
            panel.style.cssText = 'position:fixed;top:80px;right:20px;z-index:999999;background:rgba(15,23,42,0.92);color:#fff;padding:14px 18px;border-radius:10px;font-size:13px;box-shadow:0 8px 24px rgba(0,0,0,0.3);font-family:sans-serif;min-width:210px;border:1px solid rgba(255,255,255,0.1);backdrop-filter:blur(8px);';
            panel.innerHTML = '<div style="font-weight:bold;margin-bottom:8px;color:#38bdf8;">&#9889; \u8BFE\u7A0B\u81EA\u52A8\u64AD\u653E\u4E2D v2.0</div><div id="zgzjzj-status" style="margin-bottom:6px;color:#e2e8f0;">\u72B6\u6001: \u521D\u59CB\u5316...</div><div id="zgzjzj-progress" style="color:#94a3b8;font-size:12px;">\u6B63\u5728\u76D1\u542C\u89C6\u9891\u7EC4\u4EF6</div><div id="zgzjzj-vis" style="color:#4ade80;font-size:11px;margin-top:6px;">&#x2705; \u53EF\u89C1\u6027\u9501\u5B9A\u5DF2\u542F\u7528\uFF08\u6700\u5C0F\u5316\u4E0D\u4F1A\u6682\u505C\uFF09</div>';
            document.body.appendChild(panel);
        }

        function updateStatus(s, d) {
            var a = document.getElementById('zgzjzj-status');
            var b = document.getElementById('zgzjzj-progress');
            if (a) a.innerText = '\u72B6\u6001: ' + s;
            if (b && d) b.innerText = d;
        }

        // --- Popup handler ---
        function handlePopups() {
            var btns = document.querySelectorAll('.el-dialog__wrapper .el-button--primary, .el-message-box__btns .el-button--primary, .el-message-box__btns button');
            for (var i = 0; i < btns.length; i++) {
                if (btns[i] && btns[i].offsetParent !== null) {
                    console.log('[\u4E13\u6280\u5929\u4E0B\u52A9\u624B] \u70B9\u51FB\u5F39\u7A97\u6309\u94AE');
                    btns[i].click();
                }
            }
            var allBtns = document.querySelectorAll('button, .el-button, a, div[role="button"]');
            var keywords = ['\u7EE7\u7EED\u5B66\u4E60', '\u786E\u5B9A', '\u786E\u8BA4', '\u6211\u77E5\u9053\u4E86', '\u7EE7\u7EED\u64AD\u653E', '\u5F00\u59CB\u64AD\u653E'];
            for (var j = 0; j < allBtns.length; j++) {
                var txt = (allBtns[j].innerText || '').trim();
                if (allBtns[j].offsetParent !== null) {
                    for (var k = 0; k < keywords.length; k++) {
                        if (txt === keywords[k]) {
                            console.log('[\u4E13\u6280\u5929\u4E0B\u52A9\u624B] \u70B9\u51FB: ' + txt);
                            allBtns[j].click();
                            break;
                        }
                    }
                }
            }
        }

        // --- Next section ---
        function playNextSection() {
            console.log('[\u4E13\u6280\u5929\u4E0B\u52A9\u624B] \u6B63\u5728\u5BFB\u627E\u4E0B\u4E00\u8282...');
            updateStatus('\u5BFB\u627E\u4E0B\u4E00\u8282...', '\u68C0\u7D22\u8BFE\u7A0B\u76EE\u5F55\u4E2D');

            var nextKeywords = ['\u4E0B\u4E00\u8282', '\u4E0B\u4E00\u8BFE', '\u4E0B\u4E00\u7AE0'];
            var allEl = document.querySelectorAll('button, a, span, div');
            for (var i = 0; i < allEl.length; i++) {
                var t = (allEl[i].innerText || '').trim();
                for (var n = 0; n < nextKeywords.length; n++) {
                    if (t === nextKeywords[n] && allEl[i].offsetParent !== null) {
                        console.log('[\u4E13\u6280\u5929\u4E0B\u52A9\u624B] \u627E\u5230\u4E0B\u4E00\u8282\u6309\u94AE');
                        allEl[i].click();
                        return true;
                    }
                }
            }

            var items = document.querySelectorAll('.el-tree-node__content, li.el-menu-item, .course-item, .video-item, .catalog-item');
            var visible = [];
            for (var m = 0; m < items.length; m++) {
                if (items[m].innerText && items[m].innerText.trim().length > 0 && items[m].offsetParent !== null) {
                    visible.push(items[m]);
                }
            }

            if (visible.length > 0) {
                var currentIndex = -1;
                for (var p = 0; p < visible.length; p++) {
                    if (visible[p].classList.contains('active') || visible[p].classList.contains('is-active') || visible[p].classList.contains('current') || visible[p].querySelector('.active, .is-active')) {
                        currentIndex = p;
                        break;
                    }
                }
                if (currentIndex !== -1 && currentIndex + 1 < visible.length) {
                    console.log('[\u4E13\u6280\u5929\u4E0B\u52A9\u624B] \u70B9\u51FB\u7B2C ' + (currentIndex + 1) + ' \u4E2A\u5C0F\u8282');
                    visible[currentIndex + 1].click();
                    return true;
                }
            }

            updateStatus('\u672A\u68C0\u6D4B\u5230\u4E0B\u4E00\u8282', '\u8BF7\u624B\u52A8\u70B9\u51FB\u4E0B\u4E00\u8BFE');
            return false;
        }

        // --- Prevent video pause from external calls ---
        var videoPatchApplied = false;
        function patchVideoPause() {
            var video = document.querySelector('video');
            if (video && !videoPatchApplied) {
                var originalPause = video.pause.bind(video);
                video.pause = function () {
                    // Check if this pause call comes from visibility change
                    // Only allow pause if user explicitly clicks pause button
                    if (document.hidden === false && !video._userPaused) {
                        console.log('[zgzjzj-helper] blocked programmatic pause');
                        return;
                    }
                    return originalPause();
                };
                videoPatchApplied = true;
                console.log('[zgzjzj-helper] video.pause() patched');
            }
        }

        // --- Main loop ---
        var nextSectionTriggered = false;

        function mainLoop() {
            createUI();
            handlePopups();
            patchVideoPause();

            var video = document.querySelector('video');
            if (!video) {
                updateStatus('\u7B49\u5F85\u89C6\u9891\u52A0\u8F7D...', '\u672A\u627E\u5230\u64AD\u653E\u5668');
                nextSectionTriggered = false;
                return;
            }

            if (CONFIG.autoMute && !video.muted) {
                video.muted = true;
            }

            if (video.playbackRate !== CONFIG.playbackRate) {
                try { video.playbackRate = CONFIG.playbackRate; } catch (e) {}
            }

            if (video.ended) {
                if (!nextSectionTriggered) {
                    nextSectionTriggered = true;
                    updateStatus('\u672C\u8282\u5B8C\u6210', '\u6B63\u5728\u8DF3\u8F6C\u4E0B\u4E00\u8282...');
                    setTimeout(function () {
                        playNextSection();
                        // Reset flag after some time to allow re-trigger on new video
                        setTimeout(function () { nextSectionTriggered = false; }, 5000);
                    }, 1500);
                }
            } else if (video.paused) {
                nextSectionTriggered = false;
                updateStatus('\u5DF2\u6682\u505C', '\u6B63\u5728\u6062\u590D\u64AD\u653E...');
                video._userPaused = false;
                var p = video.play();
                if (p !== undefined) {
                    p.catch(function () {
                        video.muted = true;
                        video.play();
                    });
                }
            } else {
                nextSectionTriggered = false;
                var cur = Math.floor(video.currentTime);
                var tot = Math.floor(video.duration || 0);
                var pct = tot > 0 ? Math.floor((cur / tot) * 100) : 0;
                updateStatus('\u64AD\u653E\u4E2D \u25B6', '\u8FDB\u5EA6: ' + pct + '% (' + cur + '\u79D2 / ' + tot + '\u79D2)');
            }
        }

        // Use Web Worker timer so it keeps running when tab is in background
        try {
            createWorkerTimer(mainLoop, CONFIG.checkInterval);
            console.log('[zgzjzj-helper] Web Worker timer started');
        } catch (e) {
            // Fallback to setInterval if Worker fails
            console.log('[zgzjzj-helper] Worker failed, using setInterval fallback');
            setInterval(mainLoop, CONFIG.checkInterval);
        }

    }); // end window.load

})();