// ==UserScript== // @name 华为人才在线课程助手 (Huawei Talent Helper) - Log+Safe // @namespace http://tampermonkey.net/ // @version 0.7 // @description 【日志增强版】支持 Alt+Shift+L 导出运行日志,默认 1.0x 安全倍速及随机延迟跳转。 // @author Antigravity // @match *://e.huawei.com/cn/talent/* // @match *://talent.shixizhi.huawei.com/* // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; /** * v0.7 日志增强版更新日志: * 1. 日志本地保存:按 Alt + Shift + L 可将当前运行日志下载为 txt 文件。 * 2. 依然保持 v0.6 的“极稳模式”:1.0x 倍速 + 随机延迟,防止系统报错。 */ const CONFIG = { autoNext: true, playbackSpeed: 1.0, minDelay: 5000, maxDelay: 15000 }; // 日志系统 const logger = { buffer: [], log: function(msg, type = "INFO") { const time = new Date().toLocaleTimeString(); const logMsg = `[${time}] [${type}] ${msg}`; this.buffer.push(logMsg); // 同时也输出到控制台 if (type === "SUCCESS") { console.log(`%c${logMsg}`, "color: #28a745; font-weight: bold;"); } else if (type === "WARN") { console.warn(logMsg); } else { console.log(logMsg); } // 保持缓冲区在合理范围 if (this.buffer.length > 1000) this.buffer.shift(); }, download: function() { if (this.buffer.length === 0) { alert("当前没有可导出的日志。"); return; } const blob = new Blob([this.buffer.join("\n")], { type: "text/plain" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `huawei_logs_${new Date().getTime()}.txt`; a.click(); URL.revokeObjectURL(url); this.log("日志已成功导出并触发下载。", "SUCCESS"); } }; logger.log("华为助手 v0.7 已启动。按 Alt + Shift + L 可下载日志。"); // 快捷键监听 window.addEventListener('keydown', (e) => { if (e.altKey && e.shiftKey && e.code === 'KeyL') { e.preventDefault(); logger.download(); } }); function safeRun() { const videos = document.querySelectorAll('video'); if (videos.length === 0) { // 仅在控制台静默显示巡检,不存入 buffer 减少干扰 // console.debug("[HuaweiSafe] 正在巡检:未发现视频元素..."); } videos.forEach((video, index) => { const status = video.paused ? "已暂停" : "播放中"; const progress = ((video.currentTime / video.duration) * 100).toFixed(1); // 周期性记录进度 if (Math.floor(video.currentTime) % 30 === 0) { logger.log(`视频[${index}] 状态: ${status}, 进度: ${progress}%, 倍速: ${video.playbackRate}x`); } // 确保播放速度正常 if (video.playbackRate !== CONFIG.playbackSpeed) { logger.log(`修正倍速: ${video.playbackRate}x -> ${CONFIG.playbackSpeed}x`, "WARN"); video.playbackRate = CONFIG.playbackSpeed; } // 自动播放 if (video.paused && !video.ended && video.readyState >= 2) { logger.log("检测到暂停,尝试恢复播放..."); video.play().catch(() => {}); } // 自动连播 (带随机延迟) if (video.ended && CONFIG.autoNext && !video.dataset.safeJumped) { video.dataset.safeJumped = "true"; const delay = Math.floor(Math.random() * (CONFIG.maxDelay - CONFIG.minDelay) + CONFIG.minDelay); logger.log(`视频播放完毕!将在 ${Math.round(delay/1000)} 秒后触发自动跳转...`, "SUCCESS"); setTimeout(doJump, delay); } }); setTimeout(safeRun, 5000 + Math.random() * 2000); } function doJump() { const selectors = [ '.course-next-item', '.kltCourse-btn-next', '.vjs-next-button', 'div.next-chapter-btn' ]; let clicked = false; for (const selector of selectors) { const btn = document.querySelector(selector); if (btn && btn.offsetParent !== null) { btn.click(); clicked = true; break; } } if (!clicked) { const elements = document.querySelectorAll('span, button, div'); for (const el of elements) { if ((el.innerText.includes('下一讲') || el.innerText.includes('下一节')) && el.offsetParent !== null) { el.click(); clicked = true; break; } } } if (clicked) { logger.log("已点击跳转按钮。", "SUCCESS"); } else { logger.log("未找到跳转按钮,请手动操作。", "WARN"); } } // 5秒后启动主逻辑 setTimeout(safeRun, 5000); })();