您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
自动化学习脚本,修复自动启动标志检测问题
// ==UserScript== // @name 地理信息安全在线培训自动化学习(极简自动版) // @namespace http://tampermonkey.net/ // @version 6.6 // @description 自动化学习脚本,修复自动启动标志检测问题 // @author YourName // @match https://gistraining.webmap.cn/* // @grant GM_addStyle // @license MIT // @run-at document-idle // ==/UserScript== (function() { 'use strict'; console.log("[培训助手] 脚本开始执行"); // 极简样式 GM_addStyle(` #control-panel { position: fixed !important; bottom: 20px !important; right: 20px !important; width: 280px !important; background: linear-gradient(135deg, #4361ee, #3a0ca3) !important; border-radius: 16px !important; box-shadow: 0 8px 32px rgba(0,0,0,0.2) !important; color: white !important; font-family: 'Segoe UI', Arial, sans-serif !important; z-index: 999999 !important; padding: 20px !important; transition: all 0.3s ease !important; backdrop-filter: blur(10px) !important; border: 1px solid rgba(255,255,255,0.1) !important; } #control-panel.collapsed { height: 60px !important; overflow: hidden !important; } .panel-header { display: flex !important; justify-content: space-between !important; align-items: center !important; margin-bottom: 15px !important; padding-bottom: 10px !important; border-bottom: 1px solid rgba(255,255,255,0.1) !important; } .panel-title { display: flex !important; align-items: center !important; gap: 8px !important; font-weight: 600 !important; font-size: 18px !important; } .toggle-btn { background: rgba(255,255,255,0.1) !important; border: none !important; color: white !important; width: 30px !important; height: 30px !important; border-radius: 50% !important; cursor: pointer !important; font-weight: bold !important; transition: all 0.2s !important; } .toggle-btn:hover { background: rgba(255,255,255,0.2) !important; transform: scale(1.1) !important; } .control-group, .checkbox-group { margin: 10px 0 !important; display: flex !important; align-items: center !important; gap: 10px !important; } .control-label { font-size: 14px !important; min-width: 100px !important; color: #e0e0e0 !important; } .control-input { flex: 1 !important; padding: 8px !important; border-radius: 8px !important; border: 1px solid rgba(255,255,255,0.2) !important; background: rgba(255,255,255,0.1) !important; color: white !important; } .checkbox-input { width: 18px !important; height: 18px !important; } .btn-group { display: flex !important; gap: 10px !important; margin: 15px 0 !important; } .panel-btn { flex: 1 !important; padding: 10px !important; border: none !important; border-radius: 8px !important; font-weight: 600 !important; cursor: pointer !important; transition: all 0.2s !important; font-size: 14px !important; } .start-btn { background: linear-gradient(135deg, #4cc9f0, #4895ef) !important; color: white !important; } .start-btn.disabled { background: linear-gradient(135deg, #6c757d, #495057) !important; cursor: not-allowed !important; opacity: 0.7 !important; } .stop-btn { background: linear-gradient(135deg, #f72585, #b5179e) !important; color: white !important; } .panel-btn:hover:not(.disabled) { transform: translateY(-2px) !important; box-shadow: 0 4px 12px rgba(0,0,0,0.2) !important; } .action-btn { width: 100% !important; padding: 8px 12px !important; background: rgba(255,255,255,0.1) !important; border: 1px solid rgba(255,255,255,0.2) !important; border-radius: 6px !important; color: white !important; font-size: 13px !important; cursor: pointer !important; transition: all 0.2s !important; margin: 10px 0 !important; text-align: center !important; } .action-btn:hover { background: rgba(255,255,255,0.2) !important; } .scroll-progress { height: 6px !important; background: rgba(255,255,255,0.1) !important; border-radius: 3px !important; margin: 15px 0 !important; overflow: hidden !important; } .scroll-progress-bar { height: 100% !important; background: linear-gradient(90deg, #4cc9f0, #4895ef) !important; width: 0% !important; transition: width 0.3s ease !important; } .debug-info { font-family: monospace !important; font-size: 11px !important; max-height: 150px !important; overflow-y: auto !important; padding: 10px !important; background: rgba(0,0,0,0.2) !important; border-radius: 8px !important; white-space: pre-wrap !important; margin-top: 15px !important; } `); // 简化状态管理 const state = { isRunning: false, intervals: {}, lastActivity: Date.now(), activityStats: { scrolls: 0, clicks: 0, keystrokes: 0, mousemoves: 0 }, scrollDirection: 1, debugInfo: "", startTime: null, refreshTimer: null, config: { scrollInterval: 30000, microScrollInterval: 10000, clickInterval: 15000, moveInterval: 5000, activityInterval: 20000, studyTimeInterval: 30000, autoRefreshInterval: 30 * 60 * 1000, // 默认30分钟 minReadTime: 180000, debug: true } }; // 简化日志函数(仅控制台输出) function log(msg) { const time = new Date().toLocaleTimeString(); const message = `[${time}] ${msg}`; console.log(`[培训助手] ${message}`); if (state.config.debug) { state.debugInfo = message + "\n" + state.debugInfo.substring(0, 1000); updateDebugInfo(); } } // 更新调试信息 function updateDebugInfo() { const debugInfoEl = document.querySelector('.debug-info'); if (debugInfoEl) { debugInfoEl.textContent = state.debugInfo; } } // 简化活动记录 function recordActivity(type) { state.lastActivity = Date.now(); if (state.activityStats[type] !== undefined) { state.activityStats[type]++; } updateActivityStats(); } // 简化滚动容器获取 function getScrollContainer() { const selectors = [ '.box.itembox[style*="overflow-y: scroll"]', '.box.itembox[style*="overflow"]', 'div[style*="overflow-y: scroll"]', 'div[style*="overflow: auto"]', '.box.itembox:not(.collapsed)' ]; return selectors.map(sel => document.querySelector(sel)) .find(el => el && el.scrollHeight > el.clientHeight); } // 简化平滑滚动 function smoothScroll(element, target, duration = 2000) { if (!element) return; const start = element.scrollTop; const change = target - start; const startTime = performance.now(); function animate(currentTime) { const elapsed = currentTime - startTime; const progress = Math.min(elapsed / duration, 1); const easeProgress = 0.5 - 0.5 * Math.cos(progress * Math.PI); element.scrollTop = start + change * easeProgress; // 更新滚动进度条 const scrollBar = document.querySelector('.scroll-progress-bar'); if (scrollBar && element.scrollHeight > element.clientHeight) { const progress = (element.scrollTop / (element.scrollHeight - element.clientHeight)) * 100; scrollBar.style.width = `${progress}%`; } if (progress < 1) { requestAnimationFrame(animate); } else { recordActivity('scrolls'); } } requestAnimationFrame(animate); } // 简化滚动模拟 function simulateScroll() { if (!state.isRunning) return; const container = getScrollContainer(); if (!container) { log("未找到滚动容器"); return; } const maxScroll = container.scrollHeight - container.clientHeight; if (maxScroll <= 0) return; const current = container.scrollTop; let target; if (state.scrollDirection === 1) { // 向下 target = Math.min(current + 200, maxScroll); if (target >= maxScroll - 50) { target = maxScroll; setTimeout(() => { if (state.isRunning) { state.scrollDirection = -1; } }, 5000); } } else { // 向上 target = Math.max(current - 200, 0); if (target <= 50) { target = 0; setTimeout(() => { if (state.isRunning) { state.scrollDirection = 1; } }, 3000); } } smoothScroll(container, target); } // 简化点击模拟 function simulateClick() { if (!state.isRunning) return; try { const container = getScrollContainer() || document.body; const rect = container.getBoundingClientRect(); const x = rect.left + Math.random() * rect.width * 0.8; const y = rect.top + Math.random() * rect.height * 0.8; const element = document.elementFromPoint(x, y); if (element) { element.click(); recordActivity('clicks'); } } catch (e) { // 忽略错误 } } // 简化键盘模拟 function simulateKeyPress() { if (!state.isRunning) return; const keys = ['ArrowDown', 'ArrowUp', 'Space', 'PageDown', 'PageUp']; const key = keys[Math.floor(Math.random() * keys.length)]; try { document.dispatchEvent(new KeyboardEvent('keydown', { key })); recordActivity('keystrokes'); } catch (e) { // 忽略错误 } } // 简化鼠标移动 function simulateMouseMove() { if (!state.isRunning) return; try { const container = getScrollContainer() || document.body; const rect = container.getBoundingClientRect(); const x = rect.left + Math.random() * rect.width; const y = rect.top + Math.random() * rect.height; container.dispatchEvent(new MouseEvent('mousemove', { clientX: x, clientY: y })); recordActivity('mousemoves'); } catch (e) { // 忽略错误 } } // 自动刷新功能(支持自定义时间,刷新后自动启动) function setupAutoRefresh() { // 清除之前的定时器 if (state.refreshTimer) { clearTimeout(state.refreshTimer); state.refreshTimer = null; } // 如果自动刷新被禁用,直接返回 const autoRefreshCheckbox = document.getElementById('auto-refresh'); if (!autoRefreshCheckbox || !autoRefreshCheckbox.checked) { log("自动刷新已禁用"); return; } // 获取自定义刷新时间 const refreshTimeInput = document.getElementById('refresh-time'); let refreshInterval = state.config.autoRefreshInterval; if (refreshTimeInput) { const customMinutes = parseInt(refreshTimeInput.value) || 30; refreshInterval = customMinutes * 60 * 1000; state.config.autoRefreshInterval = refreshInterval; } // 设置新的自动刷新定时器 state.refreshTimer = setTimeout(() => { const refreshMinutes = refreshInterval / 60000; log(`准备自动刷新页面... (间隔: ${refreshMinutes}分钟)`); // 保存当前运行状态 const wasRunning = state.isRunning; // 停止脚本 if (state.isRunning) { stopScript(); } // 延迟刷新,确保状态保存 setTimeout(() => { // 如果之前是运行状态,设置自动启动标志 if (wasRunning) { localStorage.setItem('trainingAutoStart', 'true'); log("已设置自动启动标志,将在刷新后自动启动"); } window.location.reload(); }, 2000); }, refreshInterval); log(`设置自动刷新: ${refreshInterval/60000}分钟后`); } // 启动脚本 function startScript() { if (state.isRunning) { log("脚本已在运行"); return; } state.isRunning = true; state.startTime = Date.now(); state.scrollDirection = 1; // 清空活动统计 state.activityStats = { scrolls: 0, clicks: 0, keystrokes: 0, mousemoves: 0 }; // 启动各种模拟 state.intervals.scroll = setInterval(simulateScroll, state.config.scrollInterval); state.intervals.microScroll = setInterval(() => { const container = getScrollContainer(); if (container) { const offset = (Math.random() > 0.5 ? 1 : -1) * 20; const target = Math.max(0, Math.min(container.scrollTop + offset, container.scrollHeight - container.clientHeight)); smoothScroll(container, target, 500); } }, state.config.microScrollInterval); state.intervals.click = setInterval(simulateClick, state.config.clickInterval); state.intervals.move = setInterval(simulateMouseMove, state.config.moveInterval); // 启动自动刷新 setupAutoRefresh(); // 初始滚动 setTimeout(simulateScroll, 1000); log("脚本已启动"); updateUI(); } // 停止脚本 function stopScript() { state.isRunning = false; // 清除所有定时器 Object.keys(state.intervals).forEach(key => { clearInterval(state.intervals[key]); delete state.intervals[key]; }); // 清除自动刷新定时器 if (state.refreshTimer) { clearTimeout(state.refreshTimer); state.refreshTimer = null; } log("脚本已停止"); updateUI(); } // 更新活动统计显示 function updateActivityStats() { const statsEl = document.getElementById('activity-stats'); if (!statsEl) return; const elapsed = Date.now() - (state.startTime || Date.now()); const minutes = Math.floor(elapsed / 60000); const seconds = Math.floor((elapsed % 60000) / 1000); statsEl.innerHTML = ` <div>⏱️ 运行时间: ${minutes}分${seconds}秒</div> <div>↕️ 滚动次数: ${state.activityStats.scrolls}</div> <div>🖱️ 点击次数: ${state.activityStats.clicks}</div> <div>⌨️ 按键次数: ${state.activityStats.keystrokes}</div> <div>:pointer: 鼠标移动: ${state.activityStats.mousemoves}</div> `; } // 更新UI(主要是按钮状态) function updateUI() { const startBtn = document.getElementById('start-btn'); const stopBtn = document.getElementById('stop-btn'); if (startBtn && stopBtn) { if (state.isRunning) { startBtn.textContent = '✅ 已启动'; startBtn.classList.add('disabled'); startBtn.disabled = true; stopBtn.disabled = false; } else { startBtn.textContent = '▶️ 启动'; startBtn.classList.remove('disabled'); startBtn.disabled = false; stopBtn.disabled = false; } } // 更新活动统计 updateActivityStats(); } // 创建控制面板 function createControlPanel() { if (document.getElementById('control-panel')) return; const panel = document.createElement('div'); panel.id = 'control-panel'; panel.innerHTML = ` <div class="panel-header"> <div class="panel-title"> <span class="panel-icon">🎓</span> <span>培训助手 6.6</span> </div> <button class="toggle-btn" id="toggle-panel">−</button> </div> <div class="panel-content"> <div class="control-group"> <label class="control-label">自动刷新(分钟)</label> <input type="number" class="control-input" id="refresh-time" value="30" min="5" max="120"> </div> <div class="checkbox-group"> <input type="checkbox" class="checkbox-input" id="auto-refresh" checked> <label class="control-label" for="auto-refresh">启用自动刷新</label> </div> <div class="btn-group"> <button class="panel-btn start-btn" id="start-btn">▶️ 启动</button> <button class="panel-btn stop-btn" id="stop-btn">⏹️ 停止</button> </div> <div class="scroll-progress"> <div class="scroll-progress-bar"></div> </div> <div id="activity-stats">活跃度数据载入中...</div> <button class="action-btn" id="page-refresh">🔄 页面刷新并自启插件</button> <div class="debug-info"></div> </div> `; document.body.appendChild(panel); // 绑定事件 const startBtn = document.getElementById('start-btn'); const stopBtn = document.getElementById('stop-btn'); const refreshBtn = document.getElementById('page-refresh'); startBtn.addEventListener('click', function() { startScript(); // 设置自动启动标志 localStorage.setItem('trainingAutoStart', 'true'); log("已设置自动启动标志"); }); stopBtn.addEventListener('click', function() { stopScript(); // 只有在用户主动停止时才清除标志 localStorage.removeItem('trainingAutoStart'); log("已清除自动启动标志"); }); // 页面刷新并自启插件按钮 refreshBtn.addEventListener('click', () => { if (confirm("确定要刷新页面并自动重启插件吗?")) { log("准备刷新页面并自动重启插件..."); if (state.isRunning) { // 设置自动启动标志 localStorage.setItem('trainingAutoStart', 'true'); stopScript(); setTimeout(() => { window.location.reload(); }, 1000); } else { // 如果未运行,清除自动启动标志 localStorage.removeItem('trainingAutoStart'); window.location.reload(); } } }); document.getElementById('toggle-panel').addEventListener('click', function() { panel.classList.toggle('collapsed'); this.textContent = panel.classList.contains('collapsed') ? '+' : '−'; }); // 自动刷新时间更改时重新设置定时器 document.getElementById('refresh-time').addEventListener('change', function() { const minutes = parseInt(this.value) || 30; state.config.autoRefreshInterval = minutes * 60 * 1000; log(`自动刷新时间已更新为: ${minutes}分钟`); // 如果脚本正在运行,重新设置刷新定时器 if (state.isRunning) { setupAutoRefresh(); } }); // 自动刷新开关 document.getElementById('auto-refresh').addEventListener('change', function() { if (this.checked) { log('自动刷新已开启'); if (state.isRunning) { setupAutoRefresh(); } } else { if (state.refreshTimer) { clearTimeout(state.refreshTimer); state.refreshTimer = null; } log('自动刷新已关闭'); } }); updateUI(); log("控制面板创建完成"); } // 自动启动检查函数 function checkAutoStart() { // 检查localStorage中的自动启动标志 const autoStart = localStorage.getItem('trainingAutoStart'); if (autoStart === 'true') { log("检测到自动启动标志,准备启动脚本..."); // 不清除标志,保持它以便下次刷新也能自动启动 // 确保页面完全加载后再启动 const waitForPageLoad = () => { if (document.readyState === 'complete') { // 延迟启动,确保所有元素都已加载 setTimeout(() => { startScript(); }, 3000); } else { // 等待页面加载完成 window.addEventListener('load', () => { setTimeout(() => { startScript(); }, 3000); }, { once: true }); } }; waitForPageLoad(); } else { log("未检测到自动启动标志,等待用户手动启动"); } } // 页面加载完成后初始化 function init() { log("开始初始化..."); // 首先检查是否需要自动启动 checkAutoStart(); // 创建控制面板 const createPanelWhenReady = () => { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { createControlPanel(); log("DOMContentLoaded: 控制面板已创建"); }, { once: true }); } else { createControlPanel(); log("立即创建控制面板"); } }; createPanelWhenReady(); // 备用创建(如果3秒后仍未创建) setTimeout(() => { if (!document.getElementById('control-panel')) { createControlPanel(); log("备用创建: 控制面板已创建"); } }, 3000); log("初始化完成"); } // 启动初始化 init(); console.log("[培训助手] 脚本加载完成 - 修复自动启动版"); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址