// ==UserScript== // @name 锦江享学堂全自动学习(视频/图片通用+防挂机) // @namespace https://i-learning.jinjianghotels.com.cn/o2o/ // @version 1.2 // @description 自动播放视频/翻页图片,自动点击“下一个”,集成防挂机检测 // @author Assistant // @match https://i-learning.jinjianghotels.com.cn/o2o/* // @grant none // @license MIT // @icon https://www.google.com/s2/favicons?sz=64&domain=jinjianghotels.com.cn // ==/UserScript== (function() { 'use strict'; console.log('%c[锦江刷课] 全能版脚本已启动(修复图片版)...', 'color: #00adb5; font-size: 16px; font-weight: bold;'); /******************************* 防挂机检测模块 *******************************/ // 1. 阻止视频被强制暂停 const originalPause = HTMLVideoElement.prototype.pause; HTMLVideoElement.prototype.pause = function() { console.warn('[防检测] 拦截到 pause 调用'); return false; }; // 2. 拦截切屏事件监听 const blockedEvents = ['visibilitychange', 'blur', 'focus', 'focusin', 'focusout', 'pagehide', 'pageshow']; const blockEvent = (e) => { e.stopImmediatePropagation(); e.preventDefault(); }; blockedEvents.forEach(event => { window.addEventListener(event, blockEvent, true); document.addEventListener(event, blockEvent, true); }); // 覆盖可见性 API Object.defineProperty(document, 'hidden', { get: () => false }); Object.defineProperty(document, 'visibilityState', { get: () => 'visible' }); document.hasFocus = () => true; // 模拟鼠标移动 setInterval(() => { const event = new MouseEvent('mousemove', { view: window, bubbles: true, cancelable: true, clientX: Math.random() * window.innerWidth, clientY: Math.random() * window.innerHeight }); document.dispatchEvent(event); }, 30000); /******************************* 通用“下一个”点击函数 *******************************/ function clickNext() { // 可根据实际按钮文字增减 const nextKeywords = ['下一个', '下一课', '下一节', '完成学习', '确定', '继续']; const allButtons = document.querySelectorAll('button, a, span, div'); for (let btn of allButtons) { const text = btn.innerText.trim(); if (nextKeywords.some(kw => text === kw || text.includes(kw))) { console.log(`[刷课] 点击“${text}”按钮`); btn.click(); return true; } } return false; } /******************************* 视频处理逻辑 *******************************/ function findVideo() { let video = document.querySelector('video'); if (video && video.readyState > 0) return video; const container = document.querySelector('.video-js, .prism-player, .plyr, .jwplayer'); if (container) { video = container.querySelector('video'); if (video) return video; } return null; } function setupVideo() { const video = findVideo(); if (!video) { console.log('[刷课] 未找到视频,按图片模式处理'); return false; } video.muted = false; video.play().catch(e => console.warn('[刷课] 自动播放被阻止')); if (video.playbackRate) { video.playbackRate = 1.5; console.log('[刷课] 视频倍速 1.5x'); } return true; } /******************************* 主循环:同时监控视频和图片 *******************************/ let lastProgress = 0; setInterval(() => { // 1. 先尝试点击“下一个”(适用于图片课程,也适用于视频课程结束后的跳转) clickNext(); // 2. 处理视频进度(如果有视频) const video = findVideo(); if (video && video.duration) { const percent = (video.currentTime / video.duration * 100).toFixed(2); if (Math.abs(percent - lastProgress) > 1) { console.log(`[刷课] 视频进度 ${percent}%`); lastProgress = percent; } if (percent > 98 && !video.paused) { console.log('[刷课] 视频播放完成,再次尝试下一个'); clickNext(); lastProgress = 0; setTimeout(setupVideo, 3000); } } else { // 无视频时,主循环中的 clickNext() 已处理 console.log('[刷课] 当前无视频,持续监控“下一个”按钮'); } }, 5000); /******************************* 额外:定时点击“下一个”(兜底) *******************************/ setInterval(() => { clickNext(); }, 10000); /******************************* 启动脚本 *******************************/ setTimeout(() => { setupVideo(); }, 3000); console.log('[锦江刷课] 脚本运行中,视频/图片均可自动下一个'); })();