// ==UserScript==
// @name bjjnts
// @namespace https://www.bjjnts.cn/mine/student/study
// @version 1.0
// @description 北京市职业技能提升行动管理平台自动播放,提示验证码
// @author Jassist
// @match https://*.bjjnts.cn/*
// @match https://*.bjjnts.cn/*
// @match https://*.zpimg.cn/*
// @match https://*.alicdn.com/*
// @grant unsafeWindow
// @grant GM_log
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_listValues
// @grant GM_openInTab
// @connect 100anquan.com
// @run-at document-end
// @require https://libs.baidu.com/jquery/1.8.3/jquery.min.js
// ==/UserScript==
class CaptchaWrite {
constructor() {
this.Tip = this.AddTip();
if (GM_listValues().indexOf("set") == -1) {
GM_setValue("set", {
"idCard": ""
});
var WhetherHelp = confirm("万能验证码填入\n初始化完毕!\n在将来的时间里将会在后台默默的为你\n自动识别页面是否存在验证码并填入。\n对于一些书写不规整的验证码页面请手动添加规则。\n查看添加方法请点击确定。");
if (WhetherHelp == true) {
GM_openInTab(this.getCaptchaServerUrl() + "help.html", 'active')
}
}
Set = GM_getValue("set");
// 设置自动识别初始值
if(Set["autoIdentification"] == undefined ){
Set["autoIdentification"]="true";
GM_setValue("set", Set);
}
// 设置开启提示初始值
if(Set["showHintCheck"] == undefined ){
Set["showHintCheck"]="true";
GM_setValue("set", Set);
}
// 设置开启提示音初始值
if(Set["warningTone"] == undefined ){
Set["warningTone"]="true";
GM_setValue("set", Set);
}
// 设置崩溃后自动拉黑网站初始值
if(Set["autoBlackList"] == undefined ){
Set["autoBlackList"]="false";
GM_setValue("set", Set);
}
}
//手动添加规则
PickUp() {
var that = this;
var AddRule = {};
var IdentifyResult = '';
that.Hint('请对验证码图片点击右键!')
$("img").each(function() {
$(this).on("contextmenu", function() {
var img = that.Aimed($(this));
console.log('PickUp_Img:' + img);
if($(img).length!=1){
that.Hint('验证码选择错误,该图片实际对应多个元素。')
return;
}
that.Hint('等待识别')
IdentifyResult = that.Identify(img,function ManualRule(img,IdentifyResult){
if (img && IdentifyResult) {
console.log('记录信息' + img + IdentifyResult);
AddRule['img'] = img;
$("img").each(function() {
$(this).off("click");
$(this).off("on");
$(this).off("load");
});
that.Hint('接下来请点击验证码输入框')
$("input").each(function() {
$(this).click(function() {
var input = that.Aimed($(this));
// console.log('PickUp_input' + input);
AddRule['input'] = input;
AddRule['path'] = window.location.href;
AddRule['title'] = document.title;
AddRule['host'] = window.location.host;
AddRule['idcard'] = that.IdCard();
that.Write(IdentifyResult,input);
that.Hint('完成')
//移除事件
$("input").each(function() {
$(this).off("click");
});
//添加信息
that.Query({
"method": "captchaHostAdd",
"data": AddRule
},function(data){writeResultIntervals[writeResultIntervals.length]={"img":img,"input":input}});
that.delCapFoowwLocalStorage(window.location.host);
});
});
}
});
});
});
}
//创建提示元素
AddTip() {
var TipHtml = $("<div id='like996_identification'></div>").text("Text.");
TipHtml.css({
"background-color": "rgba(211,211,211,0.86)",
"align-items": "center",
"justify-content": "center",
"position": "fixed",
"color": "black",
"top": "-5em",
"height": "2em",
"margin": "0em",
"padding": "0em",
"font-size": "1.2em",
"width": "100%",
"left": "0",
"right": "0",
"text-align": "center",
"z-index": "9999999999999",
"padding-top": "3px",
display: 'none'
});
$("body").prepend(TipHtml);
return TipHtml;
}
//展示提醒
Hint(Content, Duration) {
if(Set["showHintCheck"]!="true"){
return;
}
var that = this;
that.Tip.stop(true, false).animate({
top: '-5em'
}, 300, function() {
if(Set["warningTone"]=="true"){
Content += that.doWarningTone(Content)
}
Content += "<span style='color:red;float: right;margin-right: 20px;' onclick='document.getElementById(\"like996_identification\").remove()'>X</span>";
that.Tip.show();
that.Tip.html(Content);
});
that.Tip.animate({
top: '0em'
}, 500).animate({
top: '0em'
}, Duration ? Duration : 3000).animate({
top: '-5em'
}, 500, function() {
that.Tip.hide();
});
return;
}
// 播放音频朗读
doWarningTone(body){
if(body.indexOf(",")){
body=body.split(",")[0];
}
if(body.indexOf(",")){
body=body.split(",")[0];
}
if(body.indexOf("!")){
body=body.split("!")[0];
}
var zhText = encodeURI(body);
var text="<audio autoplay='autoplay'>"+
"<source src='//tts.baidu.com/text2audio?lan=zh&ie=UTF-8&spd=10&text="+ zhText +"' type='audio/mpeg'>"+
"<embed height='0' width='0' src='//tts.baidu.com/text2audio?lan=zh&ie=UTF-8&spd=10&text="+ zhText +"'>"+
"</audio>";
return text;
}
}
var crabCaptcha = new CaptchaWrite();
let playErr = 0;//播放错误次数
(function () {
'use strict';
//
let tooberUrl = "";
//有时间获取url有问题,循环监听地址变化再见触发
setInterval(function () {
if (unsafeWindow.window.location.href !== tooberUrl) {
//时时检测当前网页网址
tooberUrl = unsafeWindow.window.location.href;
if (tooberUrl.indexOf("https://www.bjjnts.cn/home") !== -1) {
MyPlayer._log("进入:首页");
MyWeb._init();
}
if(!MyPlayer._getPlayFlat()){
MyPlayer._log("暂停");
return ;
}
if (tooberUrl.indexOf("https://www.bjjnts.cn/mine/student/study") !== -1) {
MyPlayer._log("进入:课程列表");
MyWeb._searchLoginName(); //查找用户名
/**
* 逻辑关系:检测课程列表数量,并且根据当前学习索引进入进程学习
*/
MyPlayer._playStduy();
} else if (tooberUrl.indexOf("https://www.bjjnts.cn/study/video") !== -1 ||
tooberUrl.indexOf("https://www.bjjnts.cn/study?") !== -1
) {
MyPlayer._log("进入视频: stduyIndex:" + MyPlayer._getStudyIndex());
/**
* 逻辑关系:1 检查当前页未学完的视频
* 1 学完跳转到课程页
* 2 有未学完的点击播放进行学习
*/
setInterval(function () {
if (MyWeb._any()) {
//检测确定按钮/学习超时按钮提示
return;
}
let linksSize = MyWeb._searchLinksSize();
if (linksSize <= 0) {
MyPlayer._log("本课程已学完");
MyWeb._goHome();
} else {
if (MyWeb._checkStudyFinish()) {
//本页视频完成
MyWeb._joinLinks();
} else {
//本页没有播放完成则播放
let b1 = MyWeb._checkStopButton(false);
let b2 = MyWeb._checkPlayButton(true);
if(b1 == false && b2 == false){
//无播放,无停止按
MyWeb._repVedio();
}
}
}
//设置title
MyWeb._setLoginName();
//检查视频是不是出错,是则刷新
MyWeb._searchVedioErr();
}, 5000);
} else if (tooberUrl.indexOf("https://www.bjjnts.cn/study/exam") !== -1) {
MyPlayer._log("跳过单元测式");
MyWeb._goHome();
} else if (tooberUrl.indexOf("https://www.bjjnts.cn/study/courseware") !== -1) {
MyPlayer._log("跳过单元考试");
MyWeb._goHome();
}
} else {
tooberUrl = unsafeWindow.window.location.href;
}
MyPlayer._log(tooberUrl);
}, 2000);
})();
//播放控制
let MyPlayer = {
_init: function () {
unsafeWindow.MyPlayer = MyPlayer;
unsafeWindow.MyWeb = MyWeb;
},
_playStduy: function () {
//此方法需要在课程目录下调用
//开始学习一个课程
if (!MyPlayer._getPlayFlat()) {
MyPlayer._log("未开始或已暂停");
return;
}
let studysIndex = MyPlayer._getStudyIndex(); //取当前课程索引
let timeThread = setInterval(function () {
//因为列表是异步加载,所有定时检测
let studys = MyWeb._searchStudy();
if (studys.length > 0) {
//检测到了就清除定时器
clearInterval(timeThread);
if (studysIndex > studys.length) {
MyPlayer._log("MyPlayer._play:播放课程索引越界");
} else {
//进入课程
MyPlayer._log("进入课程:" + studys.length + " " + studysIndex);
if((studysIndex + 1) > studys.length){
MyPlayer._setStudyIndex(0);
}else{
MyPlayer._setStudyIndex(studysIndex + 1);
}
studys[studysIndex].click(); //点击进入
}
}
}, 2000);
},
_stopStduy: function () {
//暂停课程播放
MyPlayer._setPlayFlat(true);
MyPlayer._setStudyIndex(0);
},
_getPlayFlat: function () {
//获取播放状态
let result = GM_getValue("playFlat");
if (result === undefined) {
return true;
}
MyPlayer._log("getPlayFlat_playFlat:", result);
return result;
},
_setPlayFlat: function (isPlay) {
//设置播放状态
GM_setValue("playFlat", isPlay);
MyPlayer._log("GM_setValue_playFlat:", isPlay);
},
_setStudyIndex: function (value) {
//存储当前播放课程索引
if (value === undefined) {
GM_setValue("studyIndex", 0);
} else {
GM_setValue("studyIndex", value);
}
},
_getStudyIndex: function () {
//从存出获取当前播放课程索引
let val = GM_getValue("studyIndex");
if (val === undefined) {
MyPlayer._setStudyIndex(0);
return 0;
} else {
return val;
}
},
_log: function (msg) {
GM_log(msg);
}
};
//网页操作
let MyWeb = {
_init: function(){
unsafeWindow.MyWeb = MyWeb;
unsafeWindow.MyPlayer = MyPlayer;
let lab = $("[class^='ant-dropdown-trigger']");
if(lab.length > 0){
if(MyPlayer._getPlayFlat()){
lab.parent().after("<button id = 'btn-on' style='background: red;color: white' onclick='MyPlayer._setPlayFlat(false);alert(\"连播插件已停用\");MyWeb._goHome();' >停用连播插件</button>")
}else{
lab.parent().after("<button id = 'btn-on' style='background: green;color: white' onclick='MyPlayer._setPlayFlat(true);MyPlayer._setStudyIndex(0);alert(\"连播插件已开启\");MyWeb._goHome();' >开启连播插件</button>")
}
}
},
_repVedio: function(){
MyWeb._goHome();
},
_searchLoginName : function(){
//mobile___3wQCc
let lName = $("div[class^='mobile___']");
if(lName.length > 0 ){
GM_setValue("bjjnts_loginName", lName.eq(0).text());
}
},
_setLoginName : function(){
let loginName = GM_getValue("bjjnts_loginName");
if(loginName === null || loginName === undefined)
{
return;
}
let time = "";
//current-time
let span1 = $("span[class='current-time']");
let span2 = $("span[class='duration']");
if(span1.length > 0 && span2.length > 0){
time = span1.text()+":"+span2.text();
}
$("title").html("["+loginName+"]"+time);
},
_goHome: function () {
// 跳转到课程页
unsafeWindow.window.location.href = "https://www.bjjnts.cn/mine/student/study";
},
_addHomeBtn :function() {
//主页增加控制按钮
let trigger = $("a[class='ant-dropdown-trigger']");
if(trigger.length > 0){
trigger.parent().append(' 开启连播插件<input style="font-size:20px"; id="hk_sw" type="checkbox" value="连播插件" checked="checked" /> ');
}
},
_checkPlayButton: function (isPlay) {
//检查是否有播放按钮,有则表示未播放,点击会播放
//prism-big-play-btn loading-center
//prism-big-play-btn loading-center pause
//prism-play-btn
let playBtn = $("[class='prism-big-play-btn loading-center']");
if (playBtn.length > 0) {
//有则返回此按钮
MyPlayer._log("有播放按钮:" + playBtn.length);
if(isPlay){
playBtn[0].click();
MyPlayer._log("点击播放");
playErr++;
if(playErr>=5){
playErr = 0;
//大于次无法播放直接返回
MyWeb._repVedio();
}
}
return true;
} else {
MyPlayer._log("无播放按钮");
return false;
}
},
_checkStopButton: function (isStop) {
//检查是否有播放按钮,有则代表正在播放,点击会暂停
let stopBtn = $("[class='prism-play-btn playing']");
if (stopBtn.length >= 1) {
//有则返回此按钮
MyPlayer._log("有停止按钮");
if(isStop){
stopBtn[0].click();
}
return true;
} else {
MyPlayer._log("无停止按钮");
return false;
}
},
_searchStudy: function () {
//寻找课程列表
// https://www.bjjnts.cn/mine/student/study
let list = $("a[class^='lesson_list_item___']");
MyPlayer._log("课程数量:" + list.length);
return list;
},
_joinLinks(){
//进入未学视频学习
let list = $("a[href^='/study/video']");
MyPlayer._log("进入未学课程:" + list.length);
//搜索<span role="img" aria-label="check-circle" class="anticon anticon-check-circle study_success_svg___jPGAq">
for (let i = 0; i < list.length; i++) {
let aTag = list.eq(i); //jquery对象
if (aTag.find("span[role='img']").length <= 0) {
list[i].click(); //dom对象点击
break;
}
}
},
_searchVedioErr: function(){
//video_error_wrap
//视频解析失败了,请几分钟后再试。您可以尝试切换清晰度或先学习其他章节。
//[4400]由于服务器或网络原因不能加载资源,或者格式不支持
let lab = $("div[class='video_error_wrap']");
if(lab.length > 0){
MyPlayer._log( lab.eq(0).text());
unsafeWindow.window.location.reload();
}
},
_searchLinksSize: function () {
//搜索未学的链接列表
let index = 0;
//href="/study/video?course_id=529&unit_id=12076&class_id=12447"
let list = $("a[href^='/study/video']");
MyPlayer._log("搜索到视频个数:" + list.length);
//搜索<span role="img" aria-label="check-circle" class="anticon anticon-check-circle study_success_svg___jPGAq">
for (let i = 0; i < list.length; i++) {
let aTag = list.eq(i);
if (aTag.find("span[role='img']").length <= 0) {
index++
}
}
MyPlayer._log("未学习的视频个数:" + index);
return index;
},
_checkStudyFinish: function () {
//检查当前而是否已学完
//<img src="https://g.alicdn.com/de/prismplayer/2.9.3/skins/default/img/dragcursor.png">
let result = false;
/**
* 判断是否有此图片(播放条拖拽图片)有则已完成
*
*/
let playTag = $("#J_prismPlayer");
if (playTag.length > 0) {
//有播放视频DIV层,J_prismPlayer
let imgTag = playTag.find("img[src$='https://g.alicdn.com/de/prismplayer/2.9.3/skins/default/img/dragcursor.png']");
if (imgTag.length > 0) {
result = true;
}
}
if(!result){
if(MyWeb._searchNextBtn()){
//判断是否有下一集按钮
result = true;
}
}
if(!result){
if(MyWeb._searchRepBtn()){
//判断是否有重播按钮
result = true;
}
}
MyPlayer._log("本页播放是否完成:" + result);
return result;
},_searchNextBtn : function (){
//寻找下一集按钮
let btn = $("button[class^='next_button___']");
if(btn.length > 0){
return true;
}else{
return false;
}
},_searchRepBtn : function (){
//寻找重播按钮
let btn = $("button[class^='reset_button___']");
if(btn.length > 0){
return true;
}else{
return false;
}
},
_any: function any() {
//检测确认按钮/学习超过8小时按钮
//ant-btn ant-btn-primary
let time = $("button[class='ant-btn ant-btn-primary']");
if (time.length > 0) {
MyPlayer._log("检测到需要确认学习:" + time.length);
crabCaptcha.Hint('检测到需要确认学习!');
let spans = $("span");
let flag = false;
for (let i = 0; i < spans.length; i++) {
if (spans.eq(i).text() == "1天最多学习8小时,快去休息吧") {
MyPlayer._log("1天最多学习8小时,快去休息吧");
flag = true;
MyPlayer._stopStduy(); //停止
break;
}
}
if (!flag) {
//检测到需要确认学习
time[0].click();
}
return true;
} else {
return false;
}
}
};