// ==UserScript==
// @name 安徽专业技术人员继续教育在线|安徽公需课
// @namespace free
// @version 1.0
// @description 当前是免费版本,只包含了视频页面自动播放、解除播放暂停限制、自动关闭弹窗功能。永久授权、免费更新!如需自动下一集、自动换课程、[秒过]、[考试答题]、全自动无人值守高级功能可升级付费版本|接各类脚本开发、代挂工作,微信:zhanyc_cn 个人网站:http://doc.zhanyc.cn
// @include *://*zjzx.ah.cn*
// @include *://*.zjzx.ah.cn/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addStyle
// @grant GM_deleteValue
// @grant GM_xmlhttpRequest
// @grant GM_setClipboard
// @grant GM_registerMenuCommand
// @grant GM_getResourceURL
// @grant GM_addValueChangeListener
// @grant GM_removeValueChangeListener
// @grant GM_getResourceText
// @grant window.close
// @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/ahzjjyzx/";
let _app = {
_pd: {
_mgIdx: null,
_crZ: 19991018,
_wt: 0,
_vi: {
index: null,
},
},
// ========== 工具方法 ==========
_slp(timeout) {
return new Promise((resolve) => {
setTimeout(() => resolve(), timeout);
});
},
_wf(fun, interval = 1000, timeout = 60) {
console.log("%c _wf", "background:rgb(0,0,0);color:#fff", fun);
return new Promise((resolve, reject) => {
let _timeOut = timeout * 1000;
try {
if (fun()) {
return resolve();
}
} catch (e) {
console.error(e);
}
let index = setInterval(() => {
try {
if (timeout != -1) {
_timeOut -= interval;
if (_timeOut < 0) {
clearInterval(index);
return reject();
}
}
if (fun()) {
clearInterval(index);
return resolve();
}
} catch (e) {
console.error(e);
}
}, interval);
});
},
_gd(item, def) {
return GM_getValue(item, def);
},
_sv(item, val) {
return GM_setValue(item, val);
},
_dv(item) {
return GM_deleteValue(item);
},
_ts() {
return new Date().getTime();
},
_get(query, text, mode = "eq", visible = true) {
let $el = null;
text = text.trim()
$(query).each((i, el) => {
if (visible && !$(el).is(":visible")) {
return true;
}
if (mode == "eq" && $(el).text().trim() == text) {
$el = $(el);
return false;
} else if (
mode == "startsWith" &&
$(el).text().trim().startsWith(text)
) {
$el = $(el);
return false;
} else if (mode == "endsWith" && $(el).text().trim().endsWith(text)) {
$el = $(el);
return false;
}
});
return $el;
},
_gelt(query, text, mode = "eq", visible = true) {
let arr = [];
$(query).each((i, el) => {
if (visible && !$(query).is(":visible")) {
return true;
}
if (mode == "eq" && $(el).text().trim() == text) {
arr.push($(el));
} else if (
mode == "startsWith" &&
$(el).text().trim().startsWith(text)
) {
arr.push($(el));
} else if (mode == "endsWith" && $(el).text().trim().endsWith(text)) {
arr.push($(el));
}
});
return arr;
},
_gv() {
return $("video")[0];
},
_ct() {
let res = 0;
try {
res = _app._gv().currentTime;
} catch (e) {
console.error(e);
}
return res;
},
_td() {
let res = 0;
try {
res = _app._gv().duration;
} catch (e) {
console.error(e);
}
return res;
},
_done() {
try {
return (
_app._td() > 0 && _app._ct() + 5 >= _app._td()
);
} catch (e) {
return false;
}
},
_playing() {
return new Promise((resolve) => {
try {
let curTime = $("video")[0].currentTime;
setTimeout(() => {
let time1 = $("video")[0].currentTime;
let res = time1 > curTime;
if (res) {
setTimeout(() => {
let time2 = $("video")[0].currentTime;
let res2 = time2 > time1;
resolve(res2);
}, 100);
} else {
return resolve(false);
}
}, 100);
} catch (e) {
resolve(false);
}
});
},
// ========== 样式与面板 ==========
_sty() {
GM_addStyle(`
._xb{background-color:#0fbcf9;color:#fff;padding:4px 12px;border:none;box-sizing:content-box;font-size:14px;height:20px;border-radius:4px;cursor:pointer;display:inline-block;border:1px solid transparent;white-space:nowrap;user-select:none;text-align:center;vertical-align:middle}._xb:hover{opacity:.8}._xb.success{background-color:#38b03f}._xb.warning{background-color:#f1a325}._xb.info{background-color:#03b8cf}._xb.danger{background-color:#ea644a}
`);
},
_ifp() {
if ($("#_fp").length > 0) return;
let panelHtml = `
脚本运行中(免费版)
×
初始化中...
🔥 付费脚本:一次购买 · 永久使用 · 永久更新
✔ 当前免费功能:
• 解除视频暂停限制
• 视频自动播放
• 自动关闭弹窗
★ 付费版专属功能:
• 自动下一集 / 自动换课程
• [秒过] 快速完成学习
• [考试答题] 自动答题
• 全自动无人值守
接各类脚本开发、代挂工作
微信:zhanyc_cn
`;
$("body").append(panelHtml);
$("#_fp_c").click(function () {
$("#_fp").hide();
});
// 拖拽
let _drag = false, _sx, _sy, _sl, _st2;
$("#_fp_h").on("mousedown", function (e) {
if ($(e.target).is("#_fp_c")) return;
_drag = true;
_sx = e.clientX;
_sy = e.clientY;
let $panel = $("#_fp");
_sl = $panel.position().left;
_st2 = $panel.position().top;
e.preventDefault();
});
$(document).on("mousemove", function (e) {
if (!_drag) return;
let dx = e.clientX - _sx;
let dy = e.clientY - _sy;
$("#_fp").css({
left: _sl + dx + "px",
top: _st2 + dy + "px"
});
});
$(document).on("mouseup", function () {
_drag = false;
});
},
_ut(text) {
$("#_fp_s").text(text);
},
// ========== 页面路由 ==========
_route(url) {
clearInterval(_app._pd._vi.index)
_app._pd._vi.index = null
url = url.toLocaleLowerCase()
if (top == window) {
_app._pt()
}
if (url.includes("courseplay".toLocaleLowerCase())) {
_app._pv();
} else if (url.includes("/personcenter".toLocaleLowerCase())) {
_app._pl();
}
},
_pt() {
_app._wf(a => _app._get($(".el-common_show_roll_pc b"), "关闭") != null).then(a => {
setTimeout(() => {
$(".el-common_show_roll_pc b").click()
}, 3000);
})
},
async _pl() {
console.log("%c _pl", "background:rgb(0,0,0);color:#fff");
_app._ut("当前为课程列表页面,请手动点击课程进入学习,脚本将自动播放视频")
},
// ========== 视频播放核心 ==========
async _pv() {
console.log("%c _pv", "background:rgb(0,0,0);color:#fff");
let _itv = 2;
let _lt = null;
let _ctBak = 60;
let _ctCnt = _ctBak;
if (_app._pd._vi.index != null) {
return;
}
setTimeout(async () => {
let time = _app._ct()
await _app._slp(5000)
if (_app._ct() == time) {
_app._ut("貌似卡住了,3秒后刷新页面")
await _app._slp(3000)
location.reload()
}
}, 60 * 1000);
_app._ut("视频自动播放中...")
_app._pd._vi.index = setInterval(async () => {
try {
if (_app._pd._wt > 0) {
_app._pd._wt -= _itv;
return;
}
if ($(".xgplayer-error-text:visible").text().includes('请刷新试试')) {
_app._ut("检测到错误提示,准备刷新页面")
await _app._slp(3000)
location.reload()
return
}
if (!_app._gv()) {
console.log("%c _app no video", "background:rgb(0,0,0);color:#fff");
return;
}
let curTime = _app._ct();
if (curTime == _lt) {
_lt = _app._ct();
_ctCnt -= _itv;
if (_ctCnt <= 0) {
_ctCnt = _ctBak;
_app._ut("貌似卡死了,请手动返回列表页面")
_app._pd._wt = 10;
return;
}
} else {
_lt = curTime;
_ctCnt = _ctBak;
}
_app._gv().volume = 0;
let title = `进度:${_app._ct().toFixed(0)}/${_app._td().toFixed(0)}`;
$("title").text(title);
_app._ut(`视频自动播放中 | ${title}`)
console.log("%c video run", "background:rgb(255,0,0);color:#fff");
let isFinish = await _app._done();
if (isFinish) {
_app._pd._wt = 15;
_app._ut("视频即将结束")
clearInterval(_app._pd._vi.index)
_app._pd._vi.index = null
return;
}
let isPlay = await _app._playing();
if (!isPlay) {
if (!isFinish) {
_app._doPlay();
}
}
} catch (e) {
console.error("视频页面定时器出错", e);
}
}, _itv * 1000);
},
_doPlay() {
_app._gv().volume = 0;
setTimeout(() => {
_app._gv().play();
}, 200);
},
// ========== 请求拦截 ==========
_hk() {
try {
ah.proxy(
{
onRequest: (config, handler) => {
handler.next(config);
},
onError: (err, handler) => {
console.log(err.type);
handler.next(err);
},
onResponse: (response, handler) => {
try {
let url = response.config.url;
if (url.includes("/stdCustLearnRecord/learnSave/v1.lyai")) {
let body = JSON.parse(response.response);
_app._ut("当前进度:" + body.data.completionRate + "%")
if (body.data.completionRate >= 100) {
_app._ut("视频播放完成!请手动返回列表页面选择下一课程")
}
response.response = JSON.stringify(body)
}
} finally {
handler.next(response);
}
},
},
unsafeWindow.window
);
} catch (e) {
console.error(e)
}
},
// ========== 启动入口 ==========
_boot() {
console.log("%c _app boot", "background:rgb(0,0,0);color:#fff");
_app._sty();
_app._hk();
_app._route(location.href);
},
};
// ========== 引流悬浮面板初始化 ==========
_app._ifp();
setTimeout(() => {
if (typeof (zfk) == 'undefined') {
_app._boot();
} else {
console.log('skip init');
}
}, 3000);
if (!unsafeWindow._app) unsafeWindow._app = _app;
})();