// ==UserScript==
// @name 绵阳公需课(免费版)|如需自动下一集、自动换课程、秒过、考试答题等高级功能见收费版本:http://doc.zhanyc.cn/pages/mygxk/
// @version 1.0-free
// @description 当前是免费版本,只包含了视频页面自动播放、解除播放暂停限制功能。如需自动下一集、自动换课程、秒过、考试答题、全自动无人值守高级功能可升级付费版本|接各类脚本开发、代挂工作,微信:zhanyc_cn 备用微信:zhanfengkuo 个人网站:http://doc.zhanyc.cn
// @author zfk
// @include *://*.mianyang.cn/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addStyle
// @grant GM_deleteValue
// @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/mygxk/";
let FREEJS = {
pageData: {
video: {
index: null,
},
userNameIndex: null,
},
async init() {
console.log("%c FREEJS init", "background:rgb(0,0,0);color:#fff");
this.addStyle();
this.createFloatPanel();
this.runByUrl(location.href);
},
async runByUrl(url) {
if (url.includes("/pc/index.jhtml")) {
this.page_pcIndex();
} else if (/.*\/jxjy\/pc\/zxxx_.*\/index.jhtml.*/.test(url)) {
this.page_video();
} else if (/.*\/jxjy\/pc\/ksjg_.*\/index.jhtml.*/.test(url)) {
this.page_ksjg();
} else if (url.includes("/index.jhtml?keyword=")) {
this.page_search();
}
},
createFloatPanel() {
if (document.getElementById("FREEJS_floatPanel")) return;
let panel = document.createElement("div");
panel.id = "FREEJS_floatPanel";
panel.innerHTML = `
`;
document.body.appendChild(panel);
// 关闭按钮事件
document.getElementById("FREEJS_closePanelBtn").onclick = function () {
let p = document.getElementById("FREEJS_floatPanel");
if (p) p.style.display = "none";
};
// 可拖动
this.makeDraggable(panel);
},
makeDraggable(el) {
let isDown = false, offsetX, offsetY;
let header = el.querySelector(".freejs-panel-header");
header.style.cursor = "move";
header.onmousedown = function (e) {
isDown = true;
offsetX = e.clientX - el.getBoundingClientRect().left;
offsetY = e.clientY - el.getBoundingClientRect().top;
document.onmousemove = function (e) {
if (!isDown) return;
el.style.left = (e.clientX - offsetX) + "px";
el.style.top = (e.clientY - offsetY) + "px";
el.style.right = "auto";
};
document.onmouseup = function () {
isDown = false;
document.onmousemove = null;
document.onmouseup = null;
};
};
},
updatePanelStatus(text) {
let el = document.getElementById("FREEJS_panelStatus");
if (el) el.textContent = text;
},
showPanelProgress(show) {
let el = document.getElementById("FREEJS_panelProgress");
if (el) el.style.display = show ? "block" : "none";
},
updatePanelProgress(current, total) {
this.showPanelProgress(true);
let fill = document.getElementById("FREEJS_progressFill");
let text = document.getElementById("FREEJS_progressText");
if (fill && text) {
let pct = total > 0 ? Math.min(100, (current / total) * 100) : 0;
fill.style.width = pct + "%";
text.textContent = current.toFixed(0) + "/" + total.toFixed(0) + " (" + pct.toFixed(1) + "%)";
}
// 更新标题
document.title = "进度:" + current.toFixed(0) + "/" + total.toFixed(0);
},
updatePanelVideoStatus(text, isPlaying) {
let el = document.getElementById("FREEJS_panelVideoStatus");
if (el) {
el.innerHTML = text;
el.className = "freejs-panel-video-status" + (isPlaying ? " playing" : " paused");
}
},
async page_pcIndex() {
console.log("%c FREEJS page_pcIndex", "background:rgb(255,0,0);color:#fff");
this.updatePanelStatus("已在首页,等待操作...");
await this.waitOf(function () { return $("#keywords:visible").length > 0; });
await this.waitOf(function () { return $(".login:visible,.user_center:visible").length > 0; });
if ($(".user_center:visible").length > 0) {
// 已登录 - 直接检索课程
this.updatePanelStatus("已登录,正在检索课程...");
$("#keywords:visible").val("20");
await this.waitTimeout(300);
$('[onclick="queryCousre()"]').click();
return;
}
// 未登录 - 提示登录
this.updatePanelStatus("请先登录账号后再使用");
},
async page_video() {
console.log("%c FREEJS page_video", "background:rgb(255,0,0);color:#fff");
if (this.pageData.video.index != null) {
return;
}
let self = this;
let timeout = 2;
self.updatePanelStatus("🎬 视频页面已加载");
self.showPanelProgress(true);
self.pageData.video.index = setInterval(async function () {
try {
// 处理"是否继续播放视频"弹窗
if ($("#jAlertParent:visible").length > 0) {
if (FREEJS.getElByText($("span.text"), "是否继续播放视频?") != null) {
$("#jAlertButton2").click();
return;
}
// 其他弹窗
let btn = $("#jAlertButton2:visible");
if (btn.length > 0) btn.click();
return;
}
// 处理"点击按钮,继续学习课程"弹窗
let $tips = FREEJS.getElByText(
".layui-layer-content p",
"您好,本平台要求实时在线学习,点击按钮,继续学习课程。"
);
if ($tips != null) {
$tips.parents(".layui-layer").find(".layui-layer-btn0")[0].click();
}
// 没有视频元素
if (!FREEJS.getVideo()) {
FREEJS.updatePanelStatus("⏳ 等待视频加载...");
return;
}
let video = FREEJS.getVideo();
video.volume = 0;
let cur = FREEJS.getCurTime();
let total = FREEJS.getTotalTime();
FREEJS.updatePanelProgress(cur, total);
// 检测是否播放完毕
let isFinish = FREEJS.isPlayFinish();
if (isFinish) {
FREEJS.updatePanelVideoStatus("✅ 当前视频已播放完成", true);
FREEJS.updatePanelStatus("✅ 视频已播完,如需自动下一集请升级付费版本");
return;
}
// 检测是否在播放
let isPlay = await FREEJS.videoIsPlay();
if (!isPlay) {
FREEJS.play();
FREEJS.updatePanelVideoStatus("▶ 正在播放中...", true);
FREEJS.updatePanelStatus("▶ 视频自动播放中");
} else {
FREEJS.updatePanelVideoStatus("▶ 正在播放中...", true);
FREEJS.updatePanelStatus("▶ 视频播放中");
}
} catch (e) {
console.error("FREEJS video interval error", e);
}
}, timeout * 1000);
},
async page_ksjg() {
console.log("%c FREEJS page_ksjg", "background:rgb(255,0,0);color:#fff");
this.updatePanelStatus("📄 考试结果页面");
// 引流: 自动切换账号功能改为引流文案
this.alertMsg(
"检测到考试结果页面。
自动切换账号功能仅在付费版本中提供。
" +
"如需全自动无人值守(自动下一集、自动换课、自动切换账号、秒过、考试答题等),请安装付费版本。
" +
'👉 点此查看付费版本说明',
0
);
},
async page_search() {
console.log("%c FREEJS page_search", "background:rgb(255,0,0);color:#fff");
this.updatePanelStatus("🔍 检索课程中...");
await this.waitOf(function () { return $(".resultListCon").length > 0; });
await this.waitTimeout(1000);
let $el = $(".resultListCon").eq(0);
let btnTxt = $el.find(".rightmsg:first").text().trim();
if (btnTxt == "选课") {
this.updatePanelStatus("检测到可选课程,正在选课...");
$el.find(".rightmsg>a")[0].click();
await this.waitTimeout(500);
let confirmBtn = FREEJS.getElByText($("div#jAlertButton2"), "确认选课");
if (confirmBtn) confirmBtn.click();
setTimeout(function () { location.reload(); }, 3000);
} else if (btnTxt == "继续学习" || btnTxt == "开始学习") {
if ($el.find(".rightlabel").text() == "考试合格") {
// 引流: 自动切换账号改为引流文案
this.updatePanelStatus("考试合格!自动切换账号功能需付费版本");
this.alertMsg(
"检测到该学员已考试合格。
自动切换账号功能仅在付费版本中提供。
" +
"如需全自动无人值守(自动下一集、自动换课、自动切换账号、秒过、考试答题等),请安装付费版本。
" +
'👉 点此查看付费版本说明',
0
);
return;
}
this.updatePanelStatus("正在进入课程学习...");
$el.find(".rightmsg>a")[0].click();
}
},
// 视频工具方法
play() {
let video = this.getVideo();
if (video) {
video.volume = 0;
setTimeout(function () { video.play(); }, 200);
}
},
getVideo() {
return $("video")[0];
},
isPlayFinish() {
try {
return this.getTotalTime() > 0 && this.getCurTime() + 5 >= this.getTotalTime();
} catch (e) {
return false;
}
},
getCurTime() {
try {
return this.getVideo() ? this.getVideo().currentTime : 0;
} catch (e) {
return 0;
}
},
getTotalTime() {
try {
return this.getVideo() ? this.getVideo().duration : 0;
} catch (e) {
return 0;
}
},
async videoIsPlay() {
return new Promise(function (resolve) {
try {
let video = $("video")[0];
if (!video) return resolve(false);
let curTime = video.currentTime;
setTimeout(function () {
let time1 = video.currentTime;
if (time1 > curTime) {
setTimeout(function () {
let time2 = video.currentTime;
resolve(time2 > time1);
}, 100);
} else {
resolve(false);
}
}, 100);
} catch (e) {
resolve(false);
}
});
},
waitTimeout(timeout) {
return new Promise(function (resolve) {
setTimeout(function () { resolve(); }, timeout);
});
},
waitOf(fun, interval, timeout) {
if (!interval) interval = 1000;
if (!timeout) timeout = -1;
return new Promise(function (resolve, reject) {
if (fun()) return resolve();
let _timeOut = timeout * 1000;
let index = setInterval(function () {
if (timeout != -1) {
_timeOut -= interval;
if (_timeOut < 0) {
clearInterval(index);
return reject();
}
}
if (fun()) {
clearInterval(index);
return resolve();
}
}, interval);
});
},
getElByText(query, text, mode) {
if (!mode) mode = "eq";
let $el = null;
$(query).each(function (i, el) {
if (mode == "eq" && $(el).text().trim() == text) {
$el = $(el);
return false;
} else if (mode == "startsWith" && $(el).text().trim().startsWith(text)) {
$el = $(el);
return false;
}
});
return $el;
},
addStyle() {
GM_addStyle(`
#FREEJS_floatPanel {
position: fixed;
top: 10px;
left: 10px;
z-index: 999999;
background: rgba(30, 30, 30, 0.92);
color: #fff;
padding: 0;
border-radius: 8px;
max-width: 320px;
min-width: 250px;
box-shadow: 0 4px 20px rgba(0,0,0,0.5);
font-size: 13px;
line-height: 1.5;
font-family: "Microsoft YaHei", sans-serif;
border: 1px solid #555;
}
#FREEJS_floatPanel .freejs-panel-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 12px;
background: linear-gradient(135deg, #e74c3c, #c0392b);
border-radius: 7px 7px 0 0;
user-select: none;
}
#FREEJS_floatPanel .freejs-panel-title {
font-weight: bold;
font-size: 14px;
color: #fff;
}
#FREEJS_floatPanel .freejs-panel-close {
cursor: pointer;
color: rgba(255,255,255,0.7);
font-size: 16px;
padding: 0 4px;
}
#FREEJS_floatPanel .freejs-panel-close:hover {
color: #fff;
}
#FREEJS_floatPanel .freejs-panel-body {
padding: 10px 12px;
}
#FREEJS_floatPanel .freejs-panel-status {
font-size: 13px;
color: #FFD700;
margin-bottom: 6px;
}
#FREEJS_floatPanel .freejs-panel-progress {
margin: 6px 0;
}
#FREEJS_floatPanel .freejs-progress-bar {
height: 8px;
background: #444;
border-radius: 4px;
overflow: hidden;
}
#FREEJS_floatPanel .freejs-progress-fill {
height: 100%;
width: 0%;
background: linear-gradient(90deg, #2ecc71, #27ae60);
border-radius: 4px;
transition: width 0.5s;
}
#FREEJS_floatPanel .freejs-progress-text {
font-size: 12px;
color: #aaa;
margin-top: 3px;
text-align: right;
}
#FREEJS_floatPanel .freejs-panel-video-status {
margin-top: 6px;
font-size: 13px;
}
#FREEJS_floatPanel .freejs-panel-video-status.playing {
color: #2ecc71;
}
#FREEJS_floatPanel .freejs-panel-video-status.paused {
color: #e74c3c;
}
#FREEJS_floatPanel .freejs-panel-footer {
padding: 8px 12px;
border-top: 1px solid #444;
font-size: 12px;
}
#FREEJS_floatPanel .freejs-footer-tips {
color: #FFD700;
margin-bottom: 6px;
}
#FREEJS_floatPanel .freejs-footer-link {
display: inline-block;
color: #00BFFF;
text-decoration: none;
margin-bottom: 4px;
}
#FREEJS_floatPanel .freejs-footer-link:hover {
text-decoration: underline;
}
#FREEJS_floatPanel .freejs-footer-contact {
color: #999;
font-size: 11px;
}
/* 简易弹窗样式 */
.freejs-modal-overlay {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.5);
z-index: 9999999;
display: flex;
justify-content: center;
align-items: center;
}
.freejs-modal-box {
background: #fff;
color: #333;
border-radius: 8px;
max-width: 420px;
width: 90%;
box-shadow: 0 8px 30px rgba(0,0,0,0.3);
overflow: hidden;
animation: freejsFadeIn 0.2s ease;
}
@keyframes freejsFadeIn {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
.freejs-modal-header {
background: #c0392b;
color: #fff;
padding: 10px 16px;
font-weight: bold;
font-size: 15px;
}
.freejs-modal-body {
padding: 16px;
font-size: 14px;
line-height: 1.6;
}
.freejs-modal-footer {
padding: 10px 16px;
text-align: right;
border-top: 1px solid #eee;
}
.freejs-modal-btn {
background: #e74c3c;
color: #fff;
border: none;
padding: 6px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.freejs-modal-btn:hover {
opacity: 0.9;
}
`);
},
// 简易弹窗(替代layer)
alertMsg(html, timeout) {
if (!timeout) timeout = 0;
var overlay = document.createElement("div");
overlay.className = "freejs-modal-overlay";
overlay.innerHTML =
'' +
'' +
'
' + html + '
' +
'' +
'
';
document.body.appendChild(overlay);
document.getElementById("FREEJS_alertBtn").onclick = function () {
document.body.removeChild(overlay);
};
if (timeout > 0) {
setTimeout(function () {
if (overlay.parentNode) document.body.removeChild(overlay);
}, timeout);
}
},
tipsMsg(msg) {
this.updatePanelStatus(msg);
},
// GM Data 工具
getGMData(item, def) {
return GM_getValue(item, def);
},
setGMData(item, val) {
return GM_setValue(item, val);
},
delGMData(item) {
return GM_deleteValue(item);
},
};
// 延迟初始化:3秒后检查是否付费版本已运行
setTimeout(function () {
if (typeof (zfk) == "undefined") {
console.log("%c FREEJS init start", "background:rgb(0,0,0);color:#fff");
FREEJS.init();
} else {
console.log("付费版本已运行,跳过免费版本初始化");
}
}, 3000);
})();