// ==UserScript== // @name 华医网全自动 // @namespace http://tampermonkey.net/ // @version 1.2.6 // @description 仅用于华医网,自动播放、自动考试、无人巡航 // @author otis // @license AGPL License // @match *://*.91huayi.com/course_ware/course_ware_polyv.aspx?* // @match *://*.91huayi.com/course_ware/course_ware_cc.aspx?* // @match *://*.91huayi.com/pages/exam.aspx?* // @match *://*.91huayi.com/pages/exam_result.aspx?* // @match *://*.91huayi.com/* // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js // @grant none // @downloadURL https://update.greasyfork.icu/scripts/558495/%E5%8D%8E%E5%8C%BB%E7%BD%91%E5%85%A8%E8%87%AA%E5%8A%A8.user.js // @updateURL https://update.greasyfork.icu/scripts/558495/%E5%8D%8E%E5%8C%BB%E7%BD%91%E5%85%A8%E8%87%AA%E5%8A%A8.meta.js // ==/UserScript== (function () { 'use strict'; $(document).ready(main); function main() { const submitTime = 6100; const reTryTime = 2100; const randomX = 5000; const autoSkip = false; const keyTest = 'HY_Test'; const keyResult = 'HY_Result'; const keyThisTitle = 'HY_ThisTitle'; const keyTestAnswer = 'HY_TestAnswer'; const keyRightAnswer = 'HY_RightAnswer'; const keyAllAnswer = 'HY_AllAnswer'; const btstyleB = 'font-size: 12px;font-weight: 300;text-decoration: none;text-align: center;line-height: 20px;height: 20px;padding: 0 5px;display: inline-block;appearance: none;cursor: pointer;border: none;box-sizing: border-box;transition-property: all;transition-duration: .3s;background-color: #4cb0f9;border-color: #4cb0f9;border-radius: 4px;margin: 5px;color: #FFF;'; const urlInfos = window.location.href.split('/'); const urlTip = urlInfos[urlInfos.length - 1].split('?')[0]; const controller = createController(); let clock = null; let timerCheck = null; if (urlTip == 'course_ware_polyv.aspx') { controller.watchVideo(1); } else if (urlTip == 'course_ware_cc.aspx') { controller.watchVideo(2); } else if (urlTip == 'exam.aspx') { controller.handleExam(); } else if (urlTip == 'course.aspx' || urlTip == 'cme.aspx') { controller.showCourseList(); } else if (urlTip == 'exam_result.aspx') { controller.handleExamResult(); } function createController() { return { showCourseList: function () { addAnswerCopyBtn(); deleteAllAnswers(); }, watchVideo: function (e) { cleanKeyStorage(); disablePlayerQuestion(); disableInteraction(); autoClosePopups(); addInfoPanel(); updateLayout(); function initVideoWatch() { localStorage.setItem( keyThisTitle, JSON.stringify(window.document.title) ); if (autoSkip == true) { setTimeout(function () { skipVideo(); }, submitTime + Math.ceil(Math.random() * randomX)); } let videoEndCheckTimer = null; let maxTimeReached = 0; let videoCompleted = false; let nearEndTriggered = false; clock = setInterval(checkExamStatus, 3000); function checkVideoEnd() { try { let currentState = $('i#top_play') .parent() .nextAll() .eq(2) .text(); if (currentState === '已完成') { return; } let videoElement = $('video')[0]; if (!videoElement) { if (videoEndCheckTimer) { clearInterval(videoEndCheckTimer); } return; } let duration = videoElement.duration; let currentTime = videoElement.currentTime; if (duration > 0 && currentTime > 0) { if (currentTime > maxTimeReached) { maxTimeReached = currentTime; } let remaining = duration - currentTime; if (remaining < 3 && !nearEndTriggered) { nearEndTriggered = true; videoElement.loop = false; } if (nearEndTriggered && currentTime < maxTimeReached - 5) { videoCompleted = true; } let isEnded = videoElement.ended || (nearEndTriggered && remaining < 0.3) || Math.abs(currentTime - duration) < 0.3; if ((isEnded || videoCompleted) && !videoCompleted) { videoCompleted = true; } if (videoCompleted) { if (videoEndCheckTimer) { clearInterval(videoEndCheckTimer); } if (timerCheck) { clearTimeout(timerCheck); } timerCheck = setTimeout(function () { window.location.reload(); }, 10000); } } } catch (e) {} } videoEndCheckTimer = setInterval(checkVideoEnd, 1000); switch (e) { case 1: window.s2j_onPlayerInitOver(); { player?.j2s_setVolume(0); $('video').prop('defaultMuted', true); setTimeout(function () { try { player.j2s_resumeVideo(); checkExamStatus(); } catch (e) {} }, 2000); } break; case 2: window.on_CCH5player_ready(); { cc_js_Player?.setVolume(0); $('video').prop('defaultMuted', true); setTimeout(function () { try { cc_js_Player.play(); checkExamStatus(); } catch (e) {} }, 2000); } break; default: break; } } $(window).on('load', initVideoWatch); }, handleExam: function () { let questions = JSON.parse(localStorage.getItem(keyTest)) || {}; let qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {}; if (JSON.stringify(qRightAnswer) == '{}') { qRightAnswer = loadRightAnswers(); } let qTestAnswer = {}; let index = 0; while (true) { let question = $('table.tablestyle').eq(index); if (question.length === 0) break; else { let q = question .find('.q_name') .text() .substring(2) .replace(/\s*/g, ''); if (qRightAnswer.hasOwnProperty(q)) { let rightSelection = findAnswer( 'tbody', index, qRightAnswer[q] ); rightSelection.click(); } else { if (questions.hasOwnProperty(q)) { questions[q] = getNextChoice(questions[q]); } else { questions[q] = 'A'; } let answer = getChoiceCode(questions[q]); let element = $('tbody').eq(index).find('label').eq(answer); if (element.length === 0) { questions[q] = 'A'; answer = getChoiceCode('A'); element = $('tbody').eq(index).find('label').eq(answer); } try { let answerText = element.text().substring(3); qTestAnswer[q] = answerText; } catch (e) {} element[0].click(); } index = index + 1; } } localStorage.setItem(keyTest, JSON.stringify(questions)); localStorage.setItem(keyTestAnswer, JSON.stringify(qTestAnswer)); setTimeout(function () { $('#btn_submit')[0]?.click(); }, submitTime + Math.ceil(Math.random() * randomX)); function findAnswer(qaKey, index, rightAnswerText) { let answersList = $(qaKey).eq(index); let arr = answersList.find('label'); for (let i = 0; i < arr.length; i++) { if (arr.eq(i).text().substring(3) == rightAnswerText) { return arr[i]; } } } function getChoiceCode(an) { let charin = an || 'A'; return charin.charCodeAt(0) - 'A'.charCodeAt(0); } function getNextChoice(an) { let code = an.charCodeAt(0) + 1; return String.fromCharCode(code); } }, handleExamResult: function () { let res = $('.tips_text').text() || ''; let dds = $('.state_cour_lis'); localStorage.removeItem(keyResult); if ( ['考试通过', '完成项目学习', '已学习完'].filter( (i) => res.indexOf(i) !== -1 ).length > 0 ) { saveRightAnswers(); saveAllAnswers(); cleanKeyStorage(); const buttons = $('.state_lis_btn'); let firstLearn = null; buttons.each(function (i) { if ($(this).val() === '立即学习') { firstLearn = $(this); return false; } }); buttons.each(function (i) { const btn = $(this); if ( btn.val() === '立即学习' || btn.val() === '待考试' || btn.val() === '立即考试' ) { setTimeout(() => { btn[0]?.click(); }, 2000); setTimeout(() => { if (window.location.href.indexOf('exam_result.aspx') !== -1) { if (firstLearn) { firstLearn[0]?.click(); } } }, 10000); return false; } }); let _arr = []; buttons.each(function () { _arr.push($(this).val()); }); if (_arr.every((btn) => btn === '已完成')) { setTimeout(() => { location.reload(); }, 60000); } } else { let qWrong = {}; dds.each(function (i) { if (!$(this).find('img').attr('src')?.includes('bar_img')) { qWrong[$(this).find('p').attr('title').replace(/\s*/g, '')] = i; } }); if (qWrong != {}) { localStorage.setItem(keyResult, JSON.stringify(qWrong)); saveRightAnswers(); setTimeout(function () { $("input[type='button'][value='重新考试']")[0]?.click(); }, (reTryTime + Math.ceil(Math.random() * randomX)) * 1); } } }, }; } function saveAllAnswers() { let qAllAnswer = JSON.parse(localStorage.getItem(keyAllAnswer)) || {}; let qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {}; let qTitle = JSON.parse(localStorage.getItem(keyThisTitle)) || '没有记录到章节名称'; let qOldAnswer = qAllAnswer[qTitle] || {}; for (let q in qRightAnswer) { qOldAnswer[q] = qRightAnswer[q]; } qAllAnswer[qTitle] = qOldAnswer; if (qAllAnswer != null) { localStorage.setItem(keyAllAnswer, JSON.stringify(qAllAnswer)); } } function loadRightAnswers() { let qAllAnswer = JSON.parse(localStorage.getItem(keyAllAnswer)) || {}; let qTitle = JSON.parse(localStorage.getItem(keyThisTitle)) || '没有记录到章节名称'; if (qTitle == '没有记录到章节名称') { return {}; } let qOldAnswer = qAllAnswer[qTitle] || {}; return qOldAnswer; } function saveRightAnswers() { let qRightAnswer = JSON.parse(localStorage.getItem(keyRightAnswer)) || {}; let qTestAnswer = JSON.parse(localStorage.getItem(keyTestAnswer)) || {}; let qWrongs = JSON.parse(localStorage.getItem(keyResult)) || {}; for (let q in qTestAnswer) { if (!qWrongs.hasOwnProperty(q)) { qRightAnswer[q] = qTestAnswer[q]; } } localStorage.removeItem(keyTestAnswer); if (qRightAnswer != null) { localStorage.setItem(keyRightAnswer, JSON.stringify(qRightAnswer)); } } function addAnswerCopyBtn() { let alink = $('').html('显示已记录答案').attr('style', btstyleB); alink.on('click', function (event) { let qAllAnswer = JSON.parse(localStorage.getItem(keyAllAnswer)) || {}; let Aout = JSON.stringify(qAllAnswer, null, '\t'); if ($('#AnwserOut').length) { $('#AnwserOut').html(Aout); } else { let textout = $('