// ==UserScript== // @name 🥇山东大学执业药师网络继续教育|如需自动下一集、自动换课程等高级功能见收费版本:http://doc.zhanyc.cn/pages/sddxzyys/ // @namespace free // @version 1.0 // @description 当前是免费版本,只包含了解除视频暂停限制功能。如需自动下一集、自动换课程等高级功能可升级付费版本|接各类脚本开发、代挂任务,微信:zhanyc_cn 个人网站:http://doc.zhanyc.cn // @include *://*sdlpa.org.cn* // @include *://*.sdlpa.org.cn/* // @grant GM_addStyle // @grant GM_registerMenuCommand // @run-at document-end // @require http://libs.baidu.com/jquery/2.0.0/jquery.min.js // ==/UserScript== (function () { let $jq = $; unsafeWindow.$jq = $; let docUrl = "http://doc.zhanyc.cn/pages/sddxzyys/"; let isDev = true; let yxk = { pageData: { waitOfTimers: [], videoTimer: null, waitCount: 0, }, async init() { console.log("%c yxk init", "background:rgb(0,0,0);color:#fff"); yxk.showFloatingBox(); yxk.regMenuCmd(); yxk.routeByUrl(location.href); let prevUrl = location.href; setInterval(function () { if (prevUrl != location.href) { prevUrl = location.href; yxk.routeByUrl(location.href); } }, 500); }, regMenuCmd() { if (unsafeWindow.top !== unsafeWindow) return; GM_registerMenuCommand("使用说明", function () { window.open(docUrl); }); GM_registerMenuCommand("联系作者", function () { window.open("http://doc.zhanyc.cn/contact-me/"); }); }, async routeByUrl(url) { clearInterval(yxk.pageData.videoTimer); yxk.pageData.videoTimer = null; url = url.toLowerCase(); if (url.includes("/learn?")) { yxk.startVideoHandler(); } }, async startVideoHandler() { console.log("%c startVideoHandler", "background:rgb(0,0,0);color:#fff"); await yxkWaitOf(function () { return $("video").length > 0; }); await yxkWaitTimeout(1000); if (yxk.pageData.videoTimer != null) return; let interval = 2; let prevTime = null; let stuckLimit = 60; let stuckCount = stuckLimit; // 显示视频状态区域 $(".yxk-float-video-status").show(); yxk.pageData.videoTimer = setInterval(async function () { try { if (yxk.pageData.waitCount > 0) { yxk.pageData.waitCount -= interval; return; } // 处理"您已离开播放界面"弹窗 - 解除暂停限制核心 let $leaveTip = yxkFindElByText($(".el-message-box__message"), "您已离开播放界面,已暂停播放和计时。", 'like'); if ($leaveTip != null) { $leaveTip.parents('.el-message-box:first').find('button.el-button--primary').click(); return; } // 处理"请点击签到按钮"弹窗 let $signTip = yxkFindElByText($(".el-message-box__message"), "请点击[签到]按钮继续学习。", 'like'); if ($signTip != null) { $signTip.parents('.el-message-box:first').find('button.el-button--primary').click(); return; } let video = yxkGetVideo(); if (!video) return; let curTime = video.currentTime; if (curTime == prevTime) { stuckCount -= interval; if (stuckCount <= 0) { stuckCount = stuckLimit; location.reload(); return; } } else { prevTime = curTime; stuckCount = stuckLimit; } video.volume = 0; // 更新悬浮面板播放进度 yxk.refreshProgress(curTime, video.duration); let titleText = "进度:" + curTime.toFixed(0) + "/" + video.duration.toFixed(0); $("title").text(titleText); let playing = await yxkCheckPlaying(); if (!playing) { yxkAutoPlay(); } } catch (e) { console.error("视频页面定时器出错", e); } }, interval * 1000); }, refreshProgress(curTime, totalTime) { $(".yxk-progress-text").text(yxkFormatTime(curTime) + " / " + yxkFormatTime(totalTime)); let pct = totalTime > 0 ? (curTime / totalTime * 100).toFixed(1) : 0; $(".yxk-progress-bar-inner").css("width", pct + "%"); $(".yxk-progress-percent").text(pct + "%"); $(".yxk-play-status").html("▶ 视频播放中").css("color", "#00ff83"); }, showFloatingBox() { GM_addStyle(` @keyframes yxkFadeIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}} @keyframes yxkPulse{0%{opacity:1}50%{opacity:0.4}100%{opacity:1}} #yxkFloatBox{position:fixed;left:10px;top:10px;z-index:2147483647;background:linear-gradient(145deg,rgba(30,30,60,0.95),rgba(20,20,50,0.95));border:1px solid rgba(255,255,255,0.15);border-radius:10px;box-shadow:0 8px 32px rgba(0,0,0,0.5);padding:0;min-width:260px;max-width:320px;font-size:14px;color:#fff;font-family:sans-serif;animation:yxkFadeIn 0.3s ease;} #yxkFloatBox .yxk-float-header{background:linear-gradient(135deg,#6c5ce7,#a29bfe);padding:8px 12px;border-radius:10px 10px 0 0;display:flex;justify-content:space-between;align-items:center;} #yxkFloatBox .yxk-float-running{font-weight:bold;font-size:14px;animation:yxkPulse 2s infinite;} #yxkFloatBox .yxk-float-close{background:rgba(255,255,255,0.15);border:none;cursor:pointer;font-size:16px;color:#fff;width:22px;height:22px;line-height:22px;text-align:center;border-radius:50%;padding:0;transition:all 0.2s;} #yxkFloatBox .yxk-float-close:hover{background:rgba(255,80,80,0.7);} #yxkFloatBox .yxk-float-body{padding:10px 12px;} #yxkFloatBox .yxk-float-video-status{margin-bottom:8px;} #yxkFloatBox .yxk-play-status{font-size:16px;font-weight:bold;color:#00ff83;animation:yxkPulse 2s infinite;} #yxkFloatBox .yxk-progress-wrap{margin-top:6px;} #yxkFloatBox .yxk-progress-bar{background:rgba(255,255,255,0.15);border-radius:6px;height:10px;overflow:hidden;} #yxkFloatBox .yxk-progress-bar-inner{background:linear-gradient(90deg,#00ff83,#00d4ff);height:100%;border-radius:6px;transition:width 0.5s;width:0%;} #yxkFloatBox .yxk-progress-info{display:flex;justify-content:space-between;margin-top:4px;font-size:12px;color:rgba(255,255,255,0.8);} #yxkFloatBox .yxk-progress-percent{color:#ffd700;font-weight:bold;} #yxkFloatBox .yxk-float-divider{border-top:1px solid rgba(255,255,255,0.1);margin:8px 0;} #yxkFloatBox .yxk-float-ad{font-size:12px;line-height:1.6;} #yxkFloatBox .yxk-ad-title{color:#ffd700;font-weight:bold;font-size:13px;margin-bottom:4px;text-align:center;} #yxkFloatBox .yxk-ad-desc{color:rgba(255,255,255,0.8);margin-bottom:4px;} #yxkFloatBox .yxk-ad-link{display:inline-block;margin:4px 0;padding:4px 12px;background:linear-gradient(135deg,#ffd700,#ffaa00);color:#333;border-radius:4px;text-decoration:none;font-weight:bold;font-size:12px;} #yxkFloatBox .yxk-ad-link:hover{opacity:0.9;} #yxkFloatBox .yxk-ad-service{color:rgba(255,255,255,0.7);margin-top:4px;} #yxkFloatBox .yxk-ad-contact{color:#00ff83;font-weight:bold;} #yxkFloatBox .yxk-float-free-label{display:inline-block;background:rgba(0,255,131,0.2);border:1px solid #00ff83;border-radius:4px;padding:1px 6px;font-size:11px;color:#00ff83;margin-bottom:6px;} `); let html = `
● 免费版运行中
当前功能:解除视频暂停限制
付费版本 · 一次付费永久使用 · 免费维护
如需使用全功能版本,请通过地址安装付费版本购买授权后可使用
点击查看付费版本
接各类脚本开发、代挂、网站小程序开发工作
微信:zhanyc_cn
`; $("body").append(html); $("#yxkFloatClose").on("click", function () { $("#yxkFloatBox").remove(); }); }, }; // ========== 工具函数 ========== function yxkWaitTimeout(ms) { return new Promise(function (resolve) { setTimeout(resolve, ms); }); } function yxkWaitOf(fn, ms, maxWait) { ms = ms || 1000; maxWait = maxWait || 60; return new Promise(function (resolve, reject) { let remaining = maxWait * 1000; try { if (fn()) return resolve(); } catch (e) {} let tid = setInterval(function () { remaining -= ms; if (remaining < 0) { clearInterval(tid); return reject(); } try { if (fn()) { clearInterval(tid); return resolve(); } } catch (e) {} }, ms); yxk.pageData.waitOfTimers.push(tid); }); } function yxkGetVideo() { try { return $("video")[0]; } catch (e) { return null; } } function yxkAutoPlay() { let v = yxkGetVideo(); if (v) { v.volume = 0; setTimeout(function () { v.play(); }, 200); } } function yxkCheckPlaying() { return new Promise(function (resolve) { try { let t0 = yxkGetVideo().currentTime; setTimeout(function () { let t1 = yxkGetVideo().currentTime; if (t1 > t0) { setTimeout(function () { let t2 = yxkGetVideo().currentTime; resolve(t2 > t1); }, 100); } else { resolve(false); } }, 100); } catch (e) { resolve(false); } }); } function yxkFindElByText($els, text, mode) { mode = mode || "eq"; text = text.trim(); let $result = null; $els.each(function (i, el) { if (!$(el).is(":visible")) return true; let t = $(el).text().trim(); if (mode == "eq" && t == text) { $result = $(el); return false; } if (mode == "like" && t.includes(text)) { $result = $(el); return false; } return true; }); return $result; } function yxkFormatTime(sec) { sec = Math.floor(Math.abs(sec)); let h = Math.floor(sec / 3600); let m = Math.floor((sec % 3600) / 60); let s = sec % 60; return (h < 10 ? "0" + h : h) + ":" + (m < 10 ? "0" + m : m) + ":" + (s < 10 ? "0" + s : s); } // 3秒后检查是否已有付费版运行,如果没有则初始化免费版 setTimeout(function () { debugger if (typeof(zfk)=='undefined') { yxk.init(); } else { console.log('skip init'); } }, 3000); })();