苏大双创教育平台刷课插件

目前能够稳定运行 - 注意:需在扩展开发者模式下使用

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         苏大双创教育平台刷课插件
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  目前能够稳定运行 - 注意:需在扩展开发者模式下使用
// @author       Shimamura
// @match        https://suda.wnssedu.com/*
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    const config = {
        // 播放设置
        playbackRate: 1.0,
        autoSkip: true,
        autoContinue: true,

        // 检测设置
        detectionInterval: 2000,
        skipDelay: 1200,

        // 时长模拟设置
        simulateNormalProgress: true,
        progressReportInterval: 40000,
        minWatchPercentage: 0.95,

        // 新增功能设置
        permanentMute: true,
        autoResume: true,

        // 新增:时长伪造配置
        enableTimeForgery: true,
        minForgedProgress: 0.95,
        maxStayTimeMultiplier: 1.2,
        simulateHumanBehavior: true,
        randomizeIntervals: true,
        forgeNetworkRequests: true,

        log: false
    };

    // 新增:时长伪造系统类
    class TimeForgerySystem {
        constructor() {
            this.forgedWatchTime = 0; // 伪造的观看时长
            this.realWatchTime = 0;   // 实际观看时长
            this.videoStartTime = 0;  // 视频开始时间
            this.playbackRate = 1.0;  // 当前播放速率
            this.video = null;
        }

        // 核心伪造算法
        simulateNormalProgress() {
            if (!this.video) return;

            const currentRealTime = (Date.now() - this.videoStartTime) / 1000; // 实际秒数
            const videoDuration = this.video.duration;

            // 计算伪造的观看时长(模拟1倍速观看)
            this.forgedWatchTime = Math.min(
                currentRealTime * this.playbackRate, // 关键:实际时间 × 倍速
                videoDuration
            );

            // 确保伪造时长不会超过视频总时长
            if (this.forgedWatchTime >= videoDuration) {
                this.forgedWatchTime = videoDuration;
            }
        }

        // 伪造页面停留时间相关指标
        forgePageStayMetrics() {
            // 1. 伪造鼠标活动(保持页面"活跃"状态)
            this.forgeMouseActivity();

            // 2. 伪造焦点状态(页面始终在前台)
            this.forgeFocusState();

            // 3. 伪造网络活动(模拟正常用户请求)
            this.forgeNetworkActivity();

            // 4. 伪造视频事件(模拟正常播放行为)
            this.forgeVideoEvents();
        }

        forgeMouseActivity() {
            // 随机但合理的鼠标移动
            const moveMouse = () => {
                const x = 100 + Math.random() * (window.innerWidth - 200);
                const y = 100 + Math.random() * (window.innerHeight - 200);

                document.dispatchEvent(new MouseEvent('mousemove', {
                    bubbles: true,
                    cancelable: true,
                    clientX: x,
                    clientY: y,
                    movementX: (Math.random() - 0.5) * 10,
                    movementY: (Math.random() - 0.5) * 10
                }));
            };

            // 每30-120秒随机移动一次鼠标
            setTimeout(moveMouse, 30000 + Math.random() * 90000);
        }

        forgeFocusState() {
            // 确保页面始终显示为"活跃"状态
            try {
                Object.defineProperty(document, 'hidden', {
                    get: () => false,
                    configurable: true
                });

                Object.defineProperty(document, 'visibilityState', {
                    get: () => 'visible',
                    configurable: true
                });
            } catch (e) {
                // 忽略定义错误
            }

            // 定期触发focus事件
            setInterval(() => {
                window.dispatchEvent(new Event('focus'));
                document.dispatchEvent(new Event('visibilitychange'));
            }, 60000);
        }

        forgeNetworkActivity() {
            if (!config.forgeNetworkRequests) return;

            // 模拟正常的API心跳请求
            setInterval(() => {
                this.sendHeartbeat();
                this.sendProgressUpdate();
            }, 45000 + Math.random() * 15000); // 45-60秒随机间隔
        }

        forgeVideoEvents() {
            if (!this.video) return;

            // 模拟正常的视频事件序列
            const events = ['loadstart', 'loadeddata', 'canplay', 'playing', 'timeupdate', 'progress'];

            events.forEach(event => {
                setTimeout(() => {
                    try {
                        this.video.dispatchEvent(new Event(event));
                    } catch (e) {}
                }, Math.random() * 5000);
            });

            // 定期触发timeupdate(视频进度更新)
            setInterval(() => {
                if (this.video && !this.video.paused) {
                    try {
                        this.video.dispatchEvent(new Event('timeupdate'));
                    } catch (e) {}
                }
            }, 1000);
        }

        // 伪造的上报请求
        sendProgressUpdate() {
            if (!this.video) return;

            const progressData = {
                videoId: this.getVideoId(),
                currentTime: this.video.currentTime,
                duration: this.video.duration,
                watchTime: this.forgedWatchTime * 1000, // 转换为毫秒
                progress: (this.video.currentTime / this.video.duration) * 100,
                timestamp: Date.now(),
                userAgent: navigator.userAgent,
                pageFocus: true,
                videoState: 'playing'
            };

            this.sendForgedRequest('/api/progress/update', progressData);
            this.sendForgedRequest('/api/heartbeat', progressData);
        }

        sendHeartbeat() {
            const heartbeatData = {
                timestamp: Date.now(),
                pageActive: true,
                videoPlaying: true,
                focusState: 'visible',
                stayDuration: this.forgedWatchTime * 1000
            };

            this.sendForgedRequest('/api/heartbeat', heartbeatData);
        }

        getVideoId() {
            // 尝试从URL、页面元素或全局变量中获取视频ID
            try {
                const urlParams = new URLSearchParams(window.location.search);
                return urlParams.get('videoId') ||
                       document.querySelector('[data-video-id]')?.dataset.videoId ||
                       'defaultVideoId';
            } catch (e) {
                return 'defaultVideoId';
            }
        }

        sendForgedRequest(endpoint, data) {
            if (!config.forgeNetworkRequests) return;

            // 使用多种方式发送伪造请求
            const methods = [
                () => this.forgeFetchRequest(endpoint, data),
                () => this.forgeXHRRequest(endpoint, data),
                () => this.forgeBeaconRequest(endpoint, data)
            ];

            methods.forEach(method => {
                try {
                    method();
                } catch (e) {
                    // 静默失败
                }
            });
        }

        forgeFetchRequest(endpoint, data) {
            try {
                fetch(endpoint, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-Requested-With': 'XMLHttpRequest'
                    },
                    body: JSON.stringify(data)
                }).catch(() => {});
            } catch (e) {}
        }

        forgeXHRRequest(endpoint, data) {
            try {
                const xhr = new XMLHttpRequest();
                xhr.open('POST', endpoint, true);
                xhr.setRequestHeader('Content-Type', 'application/json');
                xhr.send(JSON.stringify(data));
            } catch (e) {}
        }

        forgeBeaconRequest(endpoint, data) {
            try {
                const blob = new Blob([JSON.stringify(data)], {type: 'application/json'});
                navigator.sendBeacon(endpoint, blob);
            } catch (e) {}
        }

        // 强制上报最终进度
        forceFinalProgressReport() {
            if (!this.video) return;

            // 模拟100%进度上报
            const finalData = {
                videoId: this.getVideoId(),
                currentTime: this.video.duration,
                duration: this.video.duration,
                progress: 100,
                timestamp: Date.now(),
                status: 'completed',
                watchTime: this.forgedWatchTime * 1000
            };

            this.sendForgedRequest('/api/progress/update', finalData);
            this.sendForgedRequest('/api/progress/complete', finalData);
        }
    }

    class UltimateCourseHelper {
        constructor() {
            this.video = null;
            this.skipAttempts = 0;
            this.isProcessing = false;
            this.currentStatus = '初始化';
            this.videoPlayState = 'unknown';
            this.detectionCycles = 0;
            this.lastProgressReport = 0;
            this.realWatchTime = 0;
            this.reportWatchTime = 0;
            this.videoStartTime = Date.now();
            this.lastStatusUpdate = 0;
            this.successfulSkips = 0;

            // 自动恢复播放相关
            this.autoResumeAttempts = 0;
            this.maxResumeAttempts = 2;
            this.resumeCheckInterval = null;
            this.lastResumeAttempt = 0;
            this.resumeCooldown = 8000;

            // 静音相关
            this.muteCheckInterval = null;
            this.isMuteApplied = false;
            this.lastMuteCheck = 0;
            this.muteCheckCooldown = 5000;

            // 连播相关
            this.continueAttempts = 0;
            this.maxContinueAttempts = 3;
            this.nextSectionCheckInterval = null;

            // 新增:视频监控相关
            this.videoCheckInterval = null;
            this.lastVideoCheck = 0;
            this.videoCheckCooldown = 3000;

            // 新增:时长伪造系统
            this.timeForger = new TimeForgerySystem();

            this.init();
        }

        init() {
            console.log('苏大双创教育平台刷课插件启动(视频切换修复版+时长伪造)');
            this.injectStyles();
            this.createControlPanel();
            this.startVideoMonitoring();
            this.startIndependentDetection();
            this.startProgressSimulation();
            this.setupGlobalObservers();
            this.startStatusMonitoring();

            // 新增:启动时长伪造系统
            if (config.enableTimeForgery) {
                this.startTimeForgery();
            }

            setTimeout(() => {
                this.startAutoResumeMonitoring();
                this.startMuteMonitoring();
                this.startNextSectionDetection();
            }, 8000);
        }

        // 新增:启动时长伪造
        startTimeForgery() {
            // 核心:每5秒更新伪造时长
            this.forgeryInterval = setInterval(() => {
                this.timeForger.simulateNormalProgress();
                if (config.simulateHumanBehavior) {
                    this.timeForger.forgePageStayMetrics();
                }
            }, 5000);

            this.log('时长伪造系统已启动');
        }

        // 修改:增强视频设置 - 关联伪造系统
        setupVideo() {
            if (!this.video) return;

            try {
                // 移除旧的事件监听器(如果存在)
                this.removeVideoEventListeners();

                // 设置播放速率
                this.video.playbackRate = config.playbackRate;
                this.log(`设置播放速率: ${config.playbackRate}`);

                // 应用静音
                this.applyMuteSettings();
                this.log('应用静音设置');

                // 绑定事件监听器
                this.bindVideoEventListeners();

                // 确保播放
                this.ensurePlayback();

                // 关联伪造系统
                this.timeForger.video = this.video;
                this.timeForger.videoStartTime = Date.now();
                this.timeForger.playbackRate = config.playbackRate;

                this.log('视频设置完成');

            } catch (error) {
                this.log(`视频设置失败: ${error.message}`);
            }
        }

        // 修改:视频结束处理 - 确保100%进度
        handleVideoEnd() {
            this.log('视频播放结束');

            // 关键:强制上报最终进度
            if (config.enableTimeForgery) {
                this.timeForger.forceFinalProgressReport();
                this.log('强制上报最终进度');
            }

            if (config.autoContinue) {
                this.log('自动连播已启用');
                setTimeout(() => {
                    this.handleContinuePlay();
                }, 8000); // 延长等待时间,确保完成状态被处理
            }
        }

        // 修改:进度模拟 - 整合时长伪造
        simulateProgressReport() {
            if (!this.video || this.video.paused) return;

            this.log('模拟进度上报');
            try {
                // 原有的鼠标事件模拟
                document.dispatchEvent(new MouseEvent('mousemove', {
                    bubbles: true,
                    cancelable: true,
                    clientX: 100,
                    clientY: 100
                }));

                // 新增:时长伪造系统的进度上报
                if (config.enableTimeForgery) {
                    this.timeForger.sendProgressUpdate();
                }
            } catch (e) {
                // 忽略错误
            }
        }

        // 以下是你原有代码的其他部分,保持不变...
        // [保留所有原有方法,包括:injectStyles, createControlPanel, startStatusMonitoring,
        // checkSystemStatus, setStatusNormal, setStatusError, toggleDetection, ensurePlayback,
        // startAutoResumeMonitoring, checkAutoResume, shouldAutoResume, attemptAutoResume,
        // startIndependentDetection, runDetectionCycle, detectAndHandleQuestions, findSkipButtons,
        // handleSkipButtons, forceSkip, updateTimeTracking, startProgressSimulation,
        // startNextSectionDetection, checkNextSection, findNextSectionButtons, handleNextSectionButtons,
        // handleContinuePlay, navigateByChapterList, clickContinueButton, clickNextSection,
        // forceContinuePlay, setupGlobalObservers, resetState, simpleClick, isVisible, delay, log]

        // 原有代码保持不变...
        injectStyles() {
            GM_addStyle(`
                .uch-panel {
                    position: fixed;
                    top: 10px;
                    right: 10px;
                    background: rgba(0,0,0,0.95);
                    color: white;
                    padding: 12px;
                    border-radius: 8px;
                    z-index: 10000;
                    font-size: 12px;
                    font-family: Arial;
                    width: 200px;
                    height: 140px;
                    border: 2px solid #ff6b00;
                    box-shadow: 0 0 15px rgba(255,107,0,0.5);
                    display: flex;
                    flex-direction: column;
                    justify-content: space-around;
                    align-items: center;
                }
                .uch-btn {
                    background: #ff4444;
                    color: white;
                    border: none;
                    padding: 6px 12px;
                    border-radius: 4px;
                    cursor: pointer;
                    margin: 3px;
                    font-size: 11px;
                    width: 90%;
                    min-width: 120px !important;
                    max-width: 120px !important;
                    height: 28px !important;
                    box-sizing: border-box !important;
                    flex-shrink: 0 !important;
                }
                .uch-btn:hover {
                    opacity: 0.9;
                }
                .uch-btn-skip {
                    background: #ff4444;
                }
                .uch-btn-continue {
                    background: #44aa44;
                }
                .uch-btn-toggle {
                    background: #4444ff;
                }
                .uch-status-display {
                    width: 100%;
                    padding: 4px;
                    margin: 4px 0;
                    border-radius: 4px;
                    text-align: center;
                    font-size: 11px;
                    font-weight: bold;
                    background: #333;
                    border: 1px solid #555;
                }
                .status-normal {
                    color: #4CAF50;
                    border-color: #4CAF50;
                }
                .status-error {
                    color: #f44336;
                    border-color: #f44336;
                }
            `);
        }

        createControlPanel() {
            this.panel = document.createElement('div');
            this.panel.className = 'uch-panel';
            this.panel.innerHTML = `
                <div style="font-weight: bold; margin-bottom: 5px; color: #ff6b00; text-align: center;">🎯 苏大刷课插件 v1.1</div>
                <div id="uch-status-display" class="uch-status-display status-normal">运行中</div>
                <button class="uch-btn uch-btn-skip" id="uch-manual-skip">立即跳过</button>
                <button class="uch-btn uch-btn-continue" id="uch-force-continue">强制连播</button>
                <button class="uch-btn uch-btn-toggle" id="uch-toggle-skip">暂停检测</button>
            `;
            document.body.appendChild(this.panel);

            document.getElementById('uch-manual-skip').addEventListener('click', () => {
                this.forceSkip();
            });

            document.getElementById('uch-force-continue').addEventListener('click', () => {
                this.forceContinuePlay();
            });

            document.getElementById('uch-toggle-skip').addEventListener('click', () => {
                this.toggleDetection();
            });
        }

        startStatusMonitoring() {
            setInterval(() => {
                this.checkSystemStatus();
            }, 10000);
        }

        checkSystemStatus() {
            const statusElement = document.getElementById('uch-status-display');
            if (!statusElement) return;

            try {
                if (this.video && this.video.error) {
                    this.setStatusError('视频异常');
                    return;
                }

                // 检查视频设置状态
                if (this.video) {
                    if (this.video.playbackRate !== config.playbackRate) {
                        this.setStatusError('倍速异常');
                        return;
                    }
                    if (config.permanentMute && (!this.video.muted || this.video.volume > 0)) {
                        this.setStatusError('静音异常');
                        return;
                    }
                }

                this.setStatusNormal('运行中');

            } catch (error) {
                this.setStatusError('系统异常');
            }
        }

        setStatusNormal(message) {
            const statusElement = document.getElementById('uch-status-display');
            if (statusElement) {
                statusElement.textContent = message;
                statusElement.className = 'uch-status-display status-normal';
            }
        }

        setStatusError(message) {
            const statusElement = document.getElementById('uch-status-display');
            if (statusElement) {
                statusElement.textContent = message;
                statusElement.className = 'uch-status-display status-error';
            }
        }

        toggleDetection() {
            config.autoSkip = !config.autoSkip;
            const button = document.getElementById('uch-toggle-skip');
            if (config.autoSkip) {
                button.textContent = '暂停检测';
                button.className = 'uch-btn uch-btn-toggle';
                this.log('自动检测已启用');
                this.setStatusNormal('检测中');
            } else {
                button.textContent = '恢复检测';
                button.className = 'uch-btn uch-btn-skip';
                this.log('自动检测已暂停');
                this.setStatusNormal('检测暂停');
            }
        }

        ensurePlayback() {
            if (this.video && this.video.paused) {
                this.log('尝试开始播放视频...');

                const playVideo = () => {
                    if (this.video && this.video.paused) {
                        this.video.play().then(() => {
                            this.log('视频开始播放成功');
                        }).catch(e => {
                            if (e.name === 'NotAllowedError') {
                                console.log('[苏大刷课插件] 请点击页面开始播放');
                            }
                        });
                    }
                };

                setTimeout(playVideo, 1000);
                setTimeout(playVideo, 5000);
                setTimeout(playVideo, 10000);
            }
        }

        startAutoResumeMonitoring() {
            if (!config.autoResume) return;

            this.resumeCheckInterval = setInterval(() => {
                this.checkAutoResume();
            }, 15000);

            this.log('自动恢复播放监控已启动');
        }

        checkAutoResume() {
            if (!config.autoResume || !this.video) return;

            const now = Date.now();
            if (now - this.lastResumeAttempt < this.resumeCooldown) {
                return;
            }

            if (this.video.ended) return;

            if (this.video.paused && this.shouldAutoResume()) {
                this.log('检测到视频暂停,尝试自动恢复播放');
                this.attemptAutoResume();
            }
        }

        shouldAutoResume() {
            if (!this.video) return false;
            if (this.video.currentTime === 0) return false;
            if (this.video.duration && this.video.currentTime / this.video.duration > 0.98) {
                return false;
            }
            return true;
        }

        attemptAutoResume() {
            if (!this.video || this.autoResumeAttempts >= this.maxResumeAttempts) return;

            this.autoResumeAttempts++;
            this.lastResumeAttempt = Date.now();

            this.video.play().then(() => {
                this.log(`自动恢复播放成功`);
                this.autoResumeAttempts = 0;
                this.setStatusNormal('运行中');
            }).catch(error => {
                this.log(`自动恢复播放失败: ${error.message}`);
            });
        }

        startIndependentDetection() {
            setInterval(() => {
                if (!this.isProcessing) {
                    this.runDetectionCycle();
                }
            }, config.detectionInterval);

            this.log(`独立检测系统启动,间隔: ${config.detectionInterval}ms`);
        }

        runDetectionCycle() {
            if (!config.autoSkip || this.isProcessing) return;
            this.detectAndHandleQuestions();
        }

        detectAndHandleQuestions() {
            const skipButtons = this.findSkipButtons();
            if (skipButtons.length > 0) {
                this.log(`发现跳过按钮: ${skipButtons.length}个`);
                this.handleSkipButtons(skipButtons);
                return true;
            }
            return false;
        }

        findSkipButtons() {
            const buttons = [];
            const possibleButtons = document.querySelectorAll('button');

            for (let i = 0; i < possibleButtons.length; i++) {
                const btn = possibleButtons[i];
                if (!this.isVisible(btn)) continue;

                const text = (btn.textContent || '').trim().toLowerCase();
                if (text.includes('跳过') || text === 'skip') {
                    buttons.push(btn);
                    if (buttons.length >= 5) break;
                }
            }

            return buttons;
        }

        async handleSkipButtons(buttons) {
            if (this.isProcessing) return;

            this.isProcessing = true;
            this.skipAttempts++;

            try {
                await this.delay(config.skipDelay);

                let clicked = false;
                for (let button of buttons) {
                    if (this.isVisible(button)) {
                        if (await this.simpleClick(button)) {
                            clicked = true;
                            this.successfulSkips++;
                            this.log(`成功跳过题目`);
                            break;
                        }
                    }
                }

                if (!clicked) {
                    this.log('跳过按钮点击失败');
                }

            } catch (error) {
                this.log('跳过处理出错');
            } finally {
                this.isProcessing = false;
            }
        }

        async forceSkip() {
            this.log('手动触发跳过');
            this.setStatusNormal('跳过中...');
            const buttons = this.findSkipButtons();
            if (buttons.length > 0) {
                await this.handleSkipButtons(buttons);
            } else {
                this.log('未找到跳过按钮');
            }
            this.setStatusNormal('运行中');
        }

        updateTimeTracking() {
            if (!this.video) return;

            if (this.videoPlayState === 'playing') {
                this.realWatchTime = (Date.now() - this.videoStartTime) / 1000;
            }

            if (config.simulateNormalProgress) {
                this.reportWatchTime = this.realWatchTime;
            }
        }

        startProgressSimulation() {
            if (config.simulateNormalProgress) {
                setInterval(() => {
                    this.simulateProgressReport();
                }, config.progressReportInterval);

                this.log(`进度模拟启动`);
            }
        }

        startNextSectionDetection() {
            if (!config.autoContinue) return;

            this.nextSectionCheckInterval = setInterval(() => {
                this.checkNextSection();
            }, 10000);

            this.log('下一节检测已启动');
        }

        checkNextSection() {
            if (!config.autoContinue || this.isProcessing) return;

            if (this.video && this.video.ended) {
                this.log('检测到视频结束,开始连播流程');
                this.handleContinuePlay();
                return;
            }

            const nextButtons = this.findNextSectionButtons();
            if (nextButtons.length > 0) {
                this.log(`发现下一节按钮: ${nextButtons.length}个`);
                this.handleNextSectionButtons(nextButtons);
            }
        }

        findNextSectionButtons() {
            const buttons = [];
            const possibleButtons = document.querySelectorAll('button, a, .btn, [class*="button"]');

            for (let i = 0; i < possibleButtons.length; i++) {
                const btn = possibleButtons[i];
                if (!this.isVisible(btn)) continue;

                const text = (btn.textContent || btn.innerText || '').trim().toLowerCase();
                if (text.includes('下一节') || text.includes('下一课') || text.includes('下一章') ||
                    text.includes('下一视频') || text.includes('继续学习') || text.includes('next')) {
                    buttons.push(btn);
                    if (buttons.length >= 3) break;
                }
            }

            return buttons;
        }

        async handleNextSectionButtons(buttons) {
            if (this.isProcessing) return;

            this.isProcessing = true;
            this.setStatusNormal('跳转中...');

            try {
                await this.delay(2000);

                let clicked = false;
                for (let button of buttons) {
                    if (this.isVisible(button)) {
                        if (await this.simpleClick(button)) {
                            clicked = true;
                            this.log(`成功点击下一节按钮`);
                            break;
                        }
                    }
                }

                if (clicked) {
                    this.setStatusNormal('跳转成功');
                    setTimeout(() => {
                        this.resetState();
                        // 不需要手动调用 findVideo(),因为视频监控会自动处理
                    }, 5000);
                } else {
                    this.log('下一节按钮点击失败');
                    this.setStatusNormal('跳转失败');
                }

            } catch (error) {
                this.log('下一节处理出错');
                this.setStatusNormal('跳转异常');
            } finally {
                this.isProcessing = false;
            }
        }

        async handleContinuePlay() {
            if (this.continueAttempts >= this.maxContinueAttempts) {
                this.log('连播尝试次数过多,停止尝试');
                this.setStatusNormal('连播停止');
                return;
            }

            this.continueAttempts++;
            this.log(`开始连播尝试 ${this.continueAttempts}/${this.maxContinueAttempts}`);
            this.setStatusNormal('连播中...');

            try {
                let success = false;

                // 方法1: 直接查找并点击下一节按钮
                const nextButtons = this.findNextSectionButtons();
                if (nextButtons.length > 0) {
                    this.log('直接发现下一节按钮');
                    for (let button of nextButtons) {
                        if (await this.simpleClick(button)) {
                            success = true;
                            break;
                        }
                    }
                }

                // 方法2: 如果没有找到下一节按钮,尝试继续播放+下一节流程
                if (!success) {
                    this.log('尝试继续播放流程');
                    const continueSuccess = await this.clickContinueButton();
                    if (continueSuccess) {
                        await this.delay(3000);
                        const nextSuccess = await this.clickNextSection();
                        if (nextSuccess) {
                            success = true;
                        }
                    }
                }

                // 方法3: 尝试章节列表跳转
                if (!success) {
                    this.log('尝试章节列表跳转');
                    success = await this.navigateByChapterList();
                }

                if (success) {
                    this.log('连播成功');
                    this.setStatusNormal('连播成功');
                    this.continueAttempts = 0;

                    setTimeout(() => {
                        this.resetState();
                    }, 8000);
                } else {
                    this.log(`连播失败,已尝试 ${this.continueAttempts} 次`);
                    this.setStatusNormal('连播失败');

                    setTimeout(() => {
                        if (this.continueAttempts < this.maxContinueAttempts) {
                            this.handleContinuePlay();
                        }
                    }, 10000);
                }

            } catch (error) {
                this.log('连播处理出错');
                this.setStatusNormal('连播异常');
            }
        }

        async navigateByChapterList() {
            try {
                const currentActive = document.querySelector('.chapter_list li.active, .ant-menu-item-selected, .el-menu-item.is-active');
                if (currentActive) {
                    const nextItem = currentActive.nextElementSibling;
                    if (nextItem) {
                        const link = nextItem.querySelector('a');
                        if (link && this.isVisible(link)) {
                            this.log('通过章节列表跳转到下一节');
                            return await this.simpleClick(link);
                        }
                    } else {
                        this.log('已经是最后一章');
                        return false;
                    }
                }

                const chapterLinks = document.querySelectorAll('.chapter_list a, .ant-menu-item a, .el-menu-item a');
                for (let i = 0; i < chapterLinks.length; i++) {
                    const link = chapterLinks[i];
                    if (link.classList.contains('active') || link.parentElement.classList.contains('active')) {
                        const nextLink = chapterLinks[i + 1];
                        if (nextLink && this.isVisible(nextLink)) {
                            this.log('通过章节链接跳转到下一节');
                            return await this.simpleClick(nextLink);
                        }
                        break;
                    }
                }

                return false;
            } catch (error) {
                this.log('章节列表跳转失败');
                return false;
            }
        }

        async clickContinueButton() {
            const continueTexts = ['继续播放', '重新播放', '继续', '重播'];
            const buttons = document.querySelectorAll('button');

            for (let i = 0; i < buttons.length; i++) {
                const button = buttons[i];
                if (!this.isVisible(button)) continue;

                const text = (button.textContent || '').trim();
                if (continueTexts.some(t => text.includes(t))) {
                    this.log(`找到继续播放按钮: ${text}`);
                    if (await this.simpleClick(button)) {
                        return true;
                    }
                }
            }

            return false;
        }

        async clickNextSection() {
            const nextTexts = ['下一节', '下一章', '下一个', '继续学习', '下一课', '下一视频', 'next section', 'next lesson'];
            const buttons = document.querySelectorAll('button, a, .btn, [class*="button"]');

            for (let i = 0; i < buttons.length; i++) {
                const button = buttons[i];
                if (!this.isVisible(button)) continue;

                const text = (button.textContent || button.innerText || '').trim().toLowerCase();
                if (nextTexts.some(t => text.includes(t.toLowerCase()))) {
                    this.log(`找到下一节按钮: ${text}`);
                    if (await this.simpleClick(button)) {
                        return true;
                    }
                }
            }

            const specificSelectors = [
                '#btn3', '.next-btn', '.next-section', '.next_btn_section',
                '[onclick*="next"]', '[onclick*="Next"]'
            ];

            for (let selector of specificSelectors) {
                try {
                    const button = document.querySelector(selector);
                    if (button && this.isVisible(button)) {
                        this.log(`通过选择器找到下一节按钮: ${selector}`);
                        if (await this.simpleClick(button)) {
                            return true;
                        }
                    }
                } catch (e) {
                    // 忽略选择器错误
                }
            }

            return false;
        }

        async forceContinuePlay() {
            this.log('手动触发连播');
            this.setStatusNormal('连播中...');
            await this.handleContinuePlay();
            this.setStatusNormal('运行中');
        }

        setupGlobalObservers() {
            const observer = new MutationObserver((mutations) => {
                const hasNewNodes = mutations.some(mutation =>
                    mutation.addedNodes && mutation.addedNodes.length > 0
                );

                if (hasNewNodes) {
                    clearTimeout(this.observerTimeout);
                    this.observerTimeout = setTimeout(() => {
                        if (config.autoSkip && !this.isProcessing) {
                            this.detectAndHandleQuestions();
                        }
                    }, 2000);
                }
            });

            observer.observe(document.body, {
                childList: true,
                subtree: false
            });
        }

        resetState() {
            this.realWatchTime = 0;
            this.reportWatchTime = 0;
            this.videoStartTime = Date.now();
            this.autoResumeAttempts = 0;
            this.continueAttempts = 0;

            // 重置伪造系统
            if (this.timeForger) {
                this.timeForger.videoStartTime = Date.now();
                this.timeForger.forgedWatchTime = 0;
                this.timeForger.realWatchTime = 0;
            }
        }

        async simpleClick(element) {
            return new Promise((resolve) => {
                try {
                    element.click();
                    resolve(true);
                } catch (error) {
                    resolve(false);
                }
            });
        }

        isVisible(element) {
            if (!element) return false;
            const rect = element.getBoundingClientRect();
            return !!(rect.width && rect.height &&
                     rect.top < window.innerHeight &&
                     rect.bottom > 0);
        }

        delay(ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        }

        log(message) {
            if (config.log) {
                console.log(`[苏大刷课插件] ${message}`);
            }
        }

        // 新增:持续视频监控 - 解决视频切换问题
        startVideoMonitoring() {
            this.videoCheckInterval = setInterval(() => {
                this.checkAndSetupVideo();
            }, this.videoCheckCooldown);

            this.log('视频监控已启动');
        }

        // 新增:检查和设置视频
        checkAndSetupVideo() {
            const now = Date.now();
            if (now - this.lastVideoCheck < this.videoCheckCooldown) {
                return;
            }

            this.lastVideoCheck = now;

            // 查找视频元素
            const video = document.querySelector('video');

            // 如果没有找到视频,尝试重新查找
            if (!video) {
                if (this.video) {
                    this.log('视频元素丢失,等待重新加载');
                    this.video = null;
                }
                return;
            }

            // 如果找到新视频或视频发生变化
            if (!this.video || this.video !== video) {
                this.log('发现新视频元素,重新设置');
                this.video = video;
                this.setupVideo();
            } else {
                // 确保现有视频的设置仍然有效
                this.ensureVideoSettings();
            }
        }

        // 新增:移除视频事件监听器
        removeVideoEventListeners() {
            if (!this.video) return;

            // 这里可以移除之前绑定的事件监听器
            // 由于我们使用匿名函数,实际上不需要特别移除
            // 但如果有命名函数,应该在这里移除
        }

        // 新增:绑定视频事件监听器
        bindVideoEventListeners() {
            if (!this.video) return;

            const handlePlay = () => {
                this.videoPlayState = 'playing';
                this.videoStartTime = Date.now();
                this.log('视频开始播放');
            };

            const handlePause = () => {
                this.videoPlayState = 'paused';
                this.log('视频暂停');
                if (config.autoResume) {
                    setTimeout(() => {
                        if (this.video && this.video.paused) {
                            this.checkAutoResume();
                        }
                    }, 5000);
                }
            };

            const handleEnded = () => {
                this.log('视频播放结束');
                this.handleVideoEnd();
            };

            // 绑定事件
            this.video.addEventListener('play', handlePlay);
            this.video.addEventListener('pause', handlePause);
            this.video.addEventListener('ended', handleEnded);

            this.log('视频事件监听器已绑定');
        }

        // 新增:确保视频设置
        ensureVideoSettings() {
            if (!this.video) return;

            // 确保播放速率
            if (this.video.playbackRate !== config.playbackRate) {
                this.video.playbackRate = config.playbackRate;
                this.log(`修复播放速率: ${config.playbackRate}`);
            }

            // 确保静音
            if (config.permanentMute && (!this.video.muted || this.video.volume > 0)) {
                this.applyMuteSettings();
                this.log('修复静音设置');
            }
        }

        // 修改:应用静音设置
        applyMuteSettings() {
            if (!this.video || !config.permanentMute) return;

            this.video.muted = true;
            this.video.volume = 0;
            this.isMuteApplied = true;
        }

        // 修改:静音监控
        startMuteMonitoring() {
            if (!config.permanentMute) return;

            this.muteCheckInterval = setInterval(() => {
                this.checkAndApplyMute();
            }, 10000);

            this.log('静音监控已启动');
        }

        // 修改:检查并应用静音
        checkAndApplyMute() {
            if (!config.permanentMute || !this.video) return;

            const now = Date.now();
            if (now - this.lastMuteCheck < this.muteCheckCooldown) {
                return;
            }

            this.lastMuteCheck = now;

            if (!this.video.muted || this.video.volume > 0) {
                this.applyMuteSettings();
                this.log('静音状态已修复');
            }
        }
    }

    // 启动系统
    let system;
    const initSystem = () => {
        system = new UltimateCourseHelper();
    };

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            setTimeout(initSystem, 3000);
        });
    } else {
        setTimeout(initSystem, 3000);
    }

    // 全局控制接口
    window.uch = {
        skip: () => {
            if (system) system.forceSkip();
        },
        continue: () => {
            if (system) system.forceContinuePlay();
        },
        setSpeed: (speed) => {
            config.playbackRate = speed;
            if (system && system.video) {
                system.video.playbackRate = speed;
                system.log(`手动设置播放速率: ${speed}`);
            }
            // 更新伪造系统的播放速率
            if (system && system.timeForger) {
                system.timeForger.playbackRate = speed;
            }
        },
        // 新增:手动应用静音
        applyMute: () => {
            if (system && system.video) {
                system.applyMuteSettings();
                system.log('手动应用静音');
            }
        },
        // 新增:时长伪造控制
        setForgedTime: (minutes) => {
            if (system && system.timeForger) {
                system.timeForger.forgedWatchTime = minutes * 60;
                system.log(`手动设置伪造时长: ${minutes}分钟`);
            }
        },
        getTimeStats: () => {
            if (system && system.timeForger) {
                return {
                    realTime: system.timeForger.realWatchTime,
                    forgedTime: system.timeForger.forgedWatchTime,
                    playbackRate: system.timeForger.playbackRate
                };
            }
        },
        // 新增:强制上报进度
        forceProgressReport: () => {
            if (system && system.timeForger) {
                system.timeForger.sendProgressUpdate();
                system.log('手动强制上报进度');
            }
        }
    };

    console.log('🎯 苏大双创教育平台刷课插件已加载(视频切换修复版+时长伪造)');
    console.log('使用 window.uch.setSpeed(1.5) 调整播放速度');
    console.log('使用 window.uch.applyMute() 手动应用静音');
    console.log('使用 window.uch.getTimeStats() 查看时间统计');
    console.log('使用 window.uch.forceProgressReport() 强制上报进度');
})();