- // ==UserScript==
- // @name 东航易学助手
- // @namespace http://tampermonkey.net/
- // @version 2.2.2
- // @description 检测超时弹窗,稳定多开加速,并处理所有弹出按钮
- // @author 买不起泡面的Hanley
- // @match *://dhyx.ceair.com/*
- // @require http://code.jquery.com/jquery-1.9.1.min.js
- // @grant unsafeWindow
- // @grant GM_addStyle
- // @grant GM_getResourceText
- // @license MIT
- // ==/UserScript==
-
- var Status = 0; // 初始化状态标识
- var lastClickTime = Date.now(); // 最后一次点击的时间
- var refreshInterval; // 用于存储定时器ID
- var isDragging = false; // 用于标识是否正在拖动
- var dragStartX, dragStartY; // 记录拖动开始时的鼠标位置
-
- function getAutoNavigateEnabled() {
- return localStorage.getItem('autoNavigateEnabled') === 'true';
- }
-
- function setAutoNavigateEnabled(value) {
- localStorage.setItem('autoNavigateEnabled', value);
- manageAutoRefresh();
- }
-
- function manageAutoRefresh() {
- clearInterval(refreshInterval); // 清除之前的定时器
- if (Status == 0 && !getAutoNavigateEnabled()) {
- refreshInterval = setInterval(function() {
- window.top.location.reload(true);
- }, 300000); // 5分钟刷新一次
- }
- }
-
- function updateToggleButton(toggleButton) {
- const autoNavigateEnabled = getAutoNavigateEnabled();
- toggleButton.innerText = autoNavigateEnabled ? "自动导航:开" : "自动导航:关";
- toggleButton.style.background = autoNavigateEnabled ? 'rgba(255, 255, 0, 0.5)' : 'rgba(128, 128, 128, 0.5)';
- }
-
- function detectAndClickAlertButton() {
- // 查找弹窗的wrapper
- const alertWrapper = document.querySelector('.alert-shadow.new-alert-shadow');
- if (!alertWrapper) {
- return;
- }
-
- // 查找确定按钮
- const alertButton = document.getElementById('D253btn-ok');
- if (alertButton) {
- alertButton.click(); // 自动点击确定按钮
- }
- }
-
-
- function detectString() {
- function checkString(node) {
- if (node.nodeType === Node.TEXT_NODE) {
- if (node.nodeValue.includes('可继续学习')) {
- var confirmBtns3 = document.getElementsByClassName("btn");
- if (confirmBtns3 != null && confirmBtns3.length > 0) {
- confirmBtns3[0].click();
- lastClickTime = Date.now();
- }
- } else if (node.nodeValue.includes('恭喜')) {
- var cancelBtns = document.querySelectorAll('button[data-bb-handler="cancel"]');
- if (cancelBtns.length > 0) {
- cancelBtns[0].click();
- }
- if (getAutoNavigateEnabled()) {
- setTimeout(function() {
- window.top.location.reload(true);
- }, 5000);
- }
- } else if (node.nodeValue.includes('进度已保存')) {
- if (getAutoNavigateEnabled()) {
- // 5秒后刷新页面
- setTimeout(function() {
- window.top.location.reload(true);
- }, 5000);
- }
- } else if (node.nodeValue.includes('小测试')) {
- // 执行一次遍历
- }
- } else if (node.nodeType === Node.ELEMENT_NODE) {
- // 检查元素节点中的文本内容
- if (node.textContent.includes('进度已保存')) {
- if (getAutoNavigateEnabled()) {
- // 5秒后刷新页面
- setTimeout(function() {
- window.top.location.reload(true);
- }, 5000);
- }
- }
- // 遍历子节点
- for (let child of node.childNodes) {
- checkString(child);
- }
- }
- }
-
- const observer = new MutationObserver(function(mutations) {
- for (let mutation of mutations) {
- for (let addedNode of mutation.addedNodes) {
- checkString(addedNode);
- }
- }
- });
-
- observer.observe(document.body, {
- childList: true,
- subtree: true
- });
- }
-
- function updateFlagStatus() {
- const flag1 = document.getElementById('flag');
- if (Status == 1) {
- flag1.innerText = "检测到考试!代码停止运行!\nby:买不起泡面的Hanley";
- } else if (Status == 2) {
- flag1.innerText = "运行阅卷脚本\nby:买不起泡面的Hanley";
- } else {
- flag1.innerText = "脚本正在运行\nby:买不起泡面的Hanley";
- }
- }
-
- function makeElementDraggable(element) {
- let offsetX, offsetY;
-
- element.addEventListener('mousedown', function(event) {
- isDragging = false;
- dragStartX = event.clientX;
- dragStartY = event.clientY;
- offsetX = event.clientX - element.getBoundingClientRect().left;
- offsetY = event.clientY - element.getBoundingClientRect().top;
- element.style.cursor = 'move';
-
- function onMouseMove(event) {
- const deltaX = event.clientX - dragStartX;
- const deltaY = event.clientY - dragStartY;
- if (!isDragging && (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5)) {
- isDragging = true;
- }
- if (isDragging) {
- element.style.left = event.clientX - offsetX + 'px';
- element.style.top = event.clientY - offsetY + 'px';
- event.preventDefault(); // 防止选择文本
- }
- }
-
- function onMouseUp() {
- document.removeEventListener('mousemove', onMouseMove);
- document.removeEventListener('mouseup', onMouseUp);
- element.style.cursor = 'pointer';
- }
-
- document.addEventListener('mousemove', onMouseMove);
- document.addEventListener('mouseup', onMouseUp);
- });
- }
-
- if (window.self === window.top) { // 仅在顶层窗口显示悬浮窗
- setTimeout(function() {
- const flag = document.createElement("div");
- flag.id = 'flag';
- flag.style.cssText = 'left: 10px;bottom: 10px;background: rgba(26, 89, 183, 0.5);color:#ffffff;overflow: hidden;z-index: 9999;position: fixed;padding:3px;text-align:center;width: 175px;height: 45px;line-height: 20px;border-radius: 4px;cursor: pointer;';
- document.getElementById("content").appendChild(flag);
-
- updateFlagStatus();
-
- makeElementDraggable(flag);
-
- flag.addEventListener('click', function() {
- if (!isDragging && flag.innerText.includes("脚本正在运行")) {
- flag.style.background = 'rgba(255, 0, 0, 0.5)';
- flag.innerText = "正在尝试爆破\nby:买不起泡面的Hanley";
- markVideoAsCompleted();
- setTimeout(function() {
- flag.style.background = 'rgba(26, 89, 183, 0.5)';
- updateFlagStatus();
- }, 2000);
- loadKnockoutJs(proceedWithModifications);
- }
- });
-
- const toggleButton = document.createElement("div");
- toggleButton.id = 'toggleButton';
- toggleButton.style.cssText = 'right: 10px;bottom: 10px;color:#000000;overflow: hidden;z-index: 9999;position: fixed;padding:3px;text-align:center;width: 100px;height: 30px;line-height: 25px;border-radius: 4px;cursor: pointer;';
- document.body.appendChild(toggleButton);
-
- updateToggleButton(toggleButton); // 确保页面加载时立即更新按钮背景颜色
-
- makeElementDraggable(toggleButton);
-
- toggleButton.addEventListener('click', function() {
- if (!isDragging) {
- const newState = !getAutoNavigateEnabled();
- setAutoNavigateEnabled(newState);
- updateToggleButton(toggleButton);
- setTimeout(function() {
- window.top.location.reload(true);
- }, 1000);//一秒刷新
- }
- });
-
- // 初始化时检查并设置自动刷新
- manageAutoRefresh();
-
- }, 4000); // 4秒后显示状态牌
- }
-
- var AutoClick = setInterval(function() { Clicker() }, 1000); // 每秒运行一次
-
- function Clicker() {
- console.error = function() {};
-
- if (window.location.href.indexOf("exam") > -1) {
- if (window.location.href.indexOf("mark-paper") > -1) { // 检测到是在阅卷,停止运行但不跳弹窗
- clearInterval(AutoClick); // 阅卷了就不乱点了
- clearInterval(refreshInterval);
- Status = 2; // 阅卷了阅卷了
- } else {
- clearInterval(AutoClick); // 别是在考试,考试就直接摆烂
- clearInterval(refreshInterval);
- Status = 1; // 考试了还玩球,状态标异常
- alert('检测到考试!代码停止运行!');
- }
- }
- detectString(); // 叫外援
- checkLoginStatus();
- handleClicks();
- detectAndClickAlertButton();
-
- if (getAutoNavigateEnabled()) {
- clickNextButtonInIframe();
- autoNavigateNextChapter();
- }
-
- if (getAutoNavigateEnabled()) {
- const nextPage = document.querySelector(".navBtn.glyphicon.glyphicon-chevron-right");
- if (nextPage && !nextPage.disabled) {
- nextPage.click();
- lastClickTime = Date.now();
- }
- }
- }
-
- function handleClicks() {
- if (!getAutoNavigateEnabled()) return;
-
- const confirmBtns = document.querySelectorAll(".bootbox-close-button.close");
- if (confirmBtns.length > 0) {
- confirmBtns[0].click(); // 自动点击
- lastClickTime = Date.now();
- }
-
- const confirmBtns2 = document.querySelectorAll(".alertify-button.alertify-button-ok");
- if (confirmBtns2.length > 0) {
- confirmBtns2[0].click();
- lastClickTime = Date.now();
- }
- }
-
- // 自动导航到下一个章节
- function autoNavigateNextChapter() {
- if (!getAutoNavigateEnabled()) return;
-
- const currentChapter = findCurrentChapter();
- if (currentChapter && isChapterCompleted(currentChapter)) {
- clickNextChapter(currentChapter);
- }
- }
-
- // 查找当前正在学习的章节
- function findCurrentChapter() {
- return $(".chapter-list-box.focus");
- }
-
- // 判断章节是否完成
- function isChapterCompleted(chapter) {
- return !chapter.find('.item.pointer.item22').length;
- }
-
- function clickNextChapter(currentChapter) {
- if (!getAutoNavigateEnabled()) {
- return;
- }
- // 从当前章节开始,查找下一个未完成的章节
- let chapters = Array.from(document.querySelectorAll('.chapter-list-box'));
- let currentChapterIndex = chapters.indexOf(currentChapter[0]); // 获取当前章节的索引
-
- for (let i = currentChapterIndex + 1; i < chapters.length; i++) {
- let nextChapterToStudy = chapters[i];
- if (nextChapterToStudy.querySelector('.item.pointer.item22')) {
- let clickableElement = nextChapterToStudy.querySelector('.chapter-item');
- if (clickableElement) {
- clickableElement.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
- lastClickTime = Date.now();
- break;
- }
- }
- }
- }
-
- // 在 iframe 内部执行点击操作
- function clickNextButtonInIframe() {
- if (!getAutoNavigateEnabled()) return;
-
- const iframe = document.getElementById('scormIframe');
- if (iframe) {
- const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
- const nextPageButton = iframeDocument.querySelector('.navBtn.glyphicon.glyphicon-chevron-right.nextCompleted');
- if (nextPageButton) {
- nextPageButton.click();
- lastClickTime = Date.now();
- }
- const popupBtns = iframeDocument.querySelectorAll('.btn[data-bb-handler="ok"], .btn[data-bb-handler="next"], .btn[data-bb-handler="confirm"]');
- popupBtns.forEach(function(btn) {
- simulateClick(btn, iframe.contentWindow);
- if (getAutoNavigateEnabled()) {
- btn.click();
- lastClickTime = Date.now();
- }
- });
-
- const navigationLabel = iframeDocument.querySelector('.navigation-controls__label');
- if (navigationLabel && getAutoNavigateEnabled()) {
- const pageNumbers = navigationLabel.innerText.split('/');
- if (pageNumbers.length === 2 && pageNumbers[0].trim() === pageNumbers[1].trim()) {
- if (getAutoNavigateEnabled()) {
- setTimeout(function() {
- window.top.location.reload(true);
- }, 10000); // 等待 10 秒后强制导航到下一个章节
- }
- }
- }
-
- const buttons = iframeDocument.querySelectorAll('.uikit-primary-button.uikit-primary-button_size_medium.play-controls-container__play-pause-button');
- buttons.forEach(function(button) {
- const svg = button.querySelector('svg');
- if (svg) {
- const path = svg.querySelector('path');
- if (path && getAutoNavigateEnabled() && path.getAttribute('d') === 'M5 16.3087V3.54659L5 3.54659L16.8484 8.87836C17.2245 9.04759 17.2455 9.57369 16.8842 9.77243L5 16.3087Z') {
- simulateClick(button, iframe.contentWindow);
- }
- }
- });
-
- const popupBtns2 = iframeDocument.querySelectorAll('.message-box-buttons__window-button');
- popupBtns2.forEach(function(btn) {
- simulateClick(btn, iframe.contentWindow);
- });
- }
- }
-
- function simulateClick(element, win) {
- if (!getAutoNavigateEnabled()) return;
-
- const mouseDownEvent = new MouseEvent('mousedown', {
- bubbles: true,
- cancelable: true,
- view: win
- });
- const mouseUpEvent = new MouseEvent('mouseup', {
- bubbles: true,
- cancelable: true,
- view: win
- });
- const clickEvent = new MouseEvent('click', {
- bubbles: true,
- cancelable: true,
- view: win
- });
-
- element.dispatchEvent(mouseDownEvent);
- element.dispatchEvent(mouseUpEvent);
- element.dispatchEvent(clickEvent);
- }
-
- function loadKnockoutJs(callback) {
- var resources = performance.getEntriesByType('resource');
- var regex = /file-cloud\/01\/[0-9A-Za-z]+\/[0-9A-Za-z]+\/[0-9A-Za-z]+/;
- var knockoutJsUrl = '';
-
- for (var i = 0; i < resources.length; i++) {
- var resource = resources[i];
- if (resource.name.includes('scorm_api.jsp?')) {
- var match = resource.name.match(regex);
- if (match) {
- var dynamicPath = match[0];
- if (dynamicPath.includes('/player')) {
- dynamicPath = dynamicPath.replace('/player', '');
- }
- knockoutJsUrl = 'https://dhyx.ceair.com/' + dynamicPath + '/lib/knockout/knockout.min.js';
- break;
- }
- }
- }
-
- if (knockoutJsUrl) {
- var script = document.createElement('script');
- script.src = knockoutJsUrl;
- document.head.appendChild(script);
-
- script.onload = function() {
- callback();
- };
- } else {
- callback();
- }
- }
-
- function proceedWithModifications() {
- function findViewModel(root) {
- var queue = [{ obj: root, path: '' }];
- var visited = new Set();
-
- while (queue.length > 0) {
- var current = queue.shift();
- var obj = current.obj;
- var path = current.path;
-
- if (visited.has(obj)) {
- continue;
- }
- visited.add(obj);
-
- for (var prop in obj) {
- if (obj.hasOwnProperty(prop) && typeof obj[prop] === 'object' && obj[prop] !== null) {
- try {
- if (obj[prop].constructor && obj[prop].constructor.name === 'CBTPlayer') {
- return obj[prop];
- }
- } catch (e) {
- continue;
- }
- queue.push({ obj: obj[prop], path: path + prop + '.' });
- }
- }
- }
- return null;
- }
-
- var cbtPlayer = findViewModel(window);
-
- if (cbtPlayer) {
- var currentOrg = cbtPlayer.currentOrg();
- if (currentOrg && currentOrg.items) {
- currentOrg.items().forEach(function(item) {
- item.completed(true);
- item.visited(true);
- item.playbackFinished(true);
- if (item.type === 'topic' || item.type === 'mergedpages') {
- item.items().forEach(function(subItem) {
- subItem.completed(true);
- subItem.visited(true);
- subItem.playbackFinished(true);
- });
- }
- });
-
- currentOrg.items.valueHasMutated();
-
- if (typeof cbtPlayer.SavePlayer === 'function') {
- cbtPlayer.SavePlayer();
- }
- }
- }
- }
-
- //调用统一认证登录(不可用)
- function checkLoginStatus() {
- if (window.location.href.indexOf("oauth/#login") > -1) {
- setTimeout(function() {
- document.querySelector(".step-item.pointer:nth-child(3)").click();
- }, 5000);
- lastClickTime = Date.now();
- }
- }
-
- // 添加视频爆破功能
- function markVideoAsCompleted() {
- var videoElements = document.querySelectorAll('video[id$="player_html5_api"]');
- if (videoElements.length > 0) {
- var videoElement = videoElements[0];
- videojs(videoElement).ready(function() {
- var player = this;
- player.currentTime(player.duration());
- player.trigger('ended');
- });
- }
- }