🌱【免费版】云南省干部在线学习学院|如需自动下一集、自动换课程、验证码识别等高级功能见收费版本:https://doc.zhanyc.cn/pages/yngb/

当前是免费版本,只包含了视频页面自动播放、解除播放暂停限制功能。如需自动下一集、自动换课程、验证码识别、全自动无人值守高级功能可升级付费版本,一杯咖啡钱,保你无忧学习,且永久使用|接各类脚本开发、代挂工作,微信:zhanyc_cn 备用微信:zhanfengkuo 个人网站:http://doc.zhanyc.cn

  1. // ==UserScript==
  2. // @name 🌱【免费版】云南省干部在线学习学院|如需自动下一集、自动换课程、验证码识别等高级功能见收费版本:https://doc.zhanyc.cn/pages/yngb/
  3. // @namespace http://jb.zhanyc.cn/
  4. // @icon https://js.zhanyc.cn/img/js-logo.svg
  5. // @version 1.1
  6. // @description 当前是免费版本,只包含了视频页面自动播放、解除播放暂停限制功能。如需自动下一集、自动换课程、验证码识别、全自动无人值守高级功能可升级付费版本,一杯咖啡钱,保你无忧学习,且永久使用|接各类脚本开发、代挂工作,微信:zhanyc_cn 备用微信:zhanfengkuo 个人网站:http://doc.zhanyc.cn
  7. // @author zfk
  8. // @include *://*.ynsgbzx.cn/*
  9. // @grant GM_getValue
  10. // @grant GM_setValue
  11. // @grant GM_addStyle
  12. // @grant GM_deleteValue
  13. // @grant GM_setClipboard
  14. // @grant GM_registerMenuCommand
  15. // @grant GM_getResourceURL
  16. // @grant GM_addValueChangeListener
  17. // @grant GM_removeValueChangeListener
  18. // @grant GM_getResourceText
  19. // @grant window.close
  20. // @run-at document-body
  21. // @require http://libs.baidu.com/jquery/2.0.0/jquery.min.js
  22. // @require https://update.greasyfork.org/scripts/502187/1419386/base_lib.js
  23. // @require https://greasyfork.org/scripts/434540-layerjs-gm-with-css/code/layerjs-gm-with-css.js?version=1065982
  24. // @antifeature
  25. // @license GPL
  26. // ==/UserScript==
  27. (function () {
  28. // @run-at document-start
  29. let $jq = $;
  30. unsafeWindow.$jq = $;
  31. unsafeWindow.layer = layer;
  32. let baseConfig = {}
  33.  
  34. let freeTips = " 当前是免费版本,只包含了视频页面自动播放、解除播放暂停限制功能。如需自动下一集、自动换课程、验证码识别、全自动无人值守等高级功能,可点击下方按钮查看付费版本"
  35. let docUrl = "https://doc.zhanyc.cn/pages/yngb/";
  36. let plugMain = Object.assign(baseConfig, {
  37. config: {
  38. maxComment: 100,
  39. },
  40. pageData: {
  41. userNameIndex: null,
  42. closeTipsIndex: null,
  43. confirmRunIndex: null,
  44. confirmRunZIndex: 19991018,
  45. waitTime: 0,
  46. index: {
  47. list: null,
  48. },
  49. video: {
  50. index: null,
  51. },
  52. },
  53. async init() {
  54. console.log("%c pg init", "background:rgb(0,0,0);color:#fff");
  55. var lockResolver;
  56. if (navigator && navigator.locks && navigator.locks.request) {
  57. const promise = new Promise((res) => {
  58. lockResolver = res;
  59. });
  60.  
  61. navigator.locks.request("unique_lock_name", { mode: "shared" }, () => {
  62. return promise;
  63. });
  64. }
  65. plugMain.addStyle();
  66. unsafeWindow.alert = function (msg) {
  67. layer.alert(msg);
  68. };
  69. let run = true;
  70. if (run) plugMain.firstRun();
  71. },
  72. async runByUrl(url) {
  73. if (url.includes("/userpage.aspx")) {
  74. plugMain.showPaidContent(`免费版本不包含自动换课、无人值守功能,如需使用请安装收费版本`);
  75. } else if (url.includes("play/play.aspx")) {
  76. plugMain.showPaidContent(`免费版本不包含验证码识别功能,如需使用请安装收费版本`);
  77. } else if (url.includes("play/Right1.aspx")) {
  78. plugMain.page_video();
  79. }
  80.  
  81. },
  82.  
  83. async page_video() {
  84.  
  85. console.log("%c page_video", "background:rgb(0,0,0);color:#fff");
  86. let timeout = 2;
  87. plugMain.pageData.video.index = setInterval(async () => {
  88. try {
  89. if (plugMain.pageData.waitTime > 0) {
  90. plugMain.pageData.waitTime -= timeout;
  91. return;
  92. }
  93. // if (!location.href.includes("/video?")) {
  94. // return;
  95. // }
  96. let title = `进度:${plugMain.getCurTime().toFixed(0)}/${plugMain
  97. .getTotalTime()
  98. .toFixed(0)}`;
  99. $("title").text(title);
  100. console.log("%c video run", "background:rgb(255,0,0);color:#fff");
  101.  
  102. let isFinish = await plugMain.isPlayFinish();
  103. if (isFinish) {
  104. layer.msg("视频即将结束,等待下一步操作", { time: 10 * 1000 });
  105. plugMain.pageData.waitTime = 15;
  106. plugMain.nextVideo();
  107. return;
  108. }
  109. let isPlay = await plugMain.videoIsPlay();
  110. if (!isPlay) {
  111. if (!isFinish) {
  112. plugMain.play();
  113. }
  114. }
  115. } catch (e) {
  116. console.error("视频页面定时器出错", e);
  117. }
  118. }, timeout * 1000);
  119. },
  120. nextVideo() {
  121. layer.msg("视频即将结束,等待下一步操作", { time: 10 * 1000 });
  122.  
  123. setTimeout(() => {
  124.  
  125. plugMain.showPaidContent(`自动下一集启动失败,免费版本不包含自动换课、无人值守功能,如需使用请安装收费版本`);
  126. }, 10 * 1000);
  127. },
  128. page_top() {
  129. GM_addValueChangeListener('openLjts', function (name, old_value, new_value, remote) {
  130. plugMain.openLjTips()
  131. })
  132. },
  133. firstRun() {
  134. if (top === window && plugMain.getGMData("showDoc", true)) {
  135. layer.confirm(
  136. freeTips,
  137. { icon: 3, title: "首次使用?", btn: ["查看付费版本", "继续使用免费版本"] },
  138. function (index) {
  139. plugMain.openDoc();
  140. layer.close(index);
  141. plugMain.setGMData("showDoc", false);
  142. plugMain.begin("");
  143. },
  144. function () {
  145. plugMain.setGMData("showDoc", false);
  146. plugMain.begin("");
  147. }
  148. );
  149. } else {
  150. }
  151. plugMain.begin("");
  152. },
  153. async begin(key) {
  154. if (window === top) {
  155. plugMain.registerMenuCommand();
  156. }
  157. // let lastUrl =location.href;
  158.  
  159. // setInterval(async () => {
  160. // if (lastUrl != location.href) {
  161. // lastUrl = location.href;
  162. // plugMain.runByUrl(location.href);
  163. // }
  164. // }, 500);
  165. plugMain.runByUrl(location.href);
  166. },
  167.  
  168. async showPaidContent(msg = "此页面为付费内容,免费脚本不包含", withPostfix = true) {
  169. if (withPostfix) {
  170. msg += "<span style='font-weight:bold;'>*重要:一个学员付费一次,永久使用,永久更新!</span>"
  171. }
  172. if (!plugMain.pageData.paidIndexArr) {
  173. plugMain.pageData.paidIndexArr = []
  174. }
  175. if (plugMain.pageData.paidIndexArr.length > 0) {
  176. for (let i = 0; i < plugMain.pageData.paidIndexArr.length; i++) {
  177. const index = plugMain.pageData.paidIndexArr[i];
  178. layer.close(index)
  179. }
  180. }
  181. let index = layer.open(
  182. {
  183. type: "1",
  184. content: `<div style="padding:14px;">${msg}</div>`,
  185. title: "免费版本提示",
  186. offset: "rb",
  187. area: ["500px"],
  188. btn: ["查看收费版本", "关闭"],
  189. shade: 0,
  190. yes: function (index) { plugMain.openDoc() }
  191. })
  192. plugMain.pageData.paidIndexArr.push(index)
  193. },
  194. localSaveQa(qaArr) {
  195. let list = plugMain.getGMData("qaList", []);
  196. qaArr.forEach((item) => {
  197. let old = list.find((a) => a.key == item.key);
  198. item.value = item.value.replace(/#split#/g, "|");
  199. if (!old) {
  200. list.push(item);
  201. } else {
  202. old.value = item.value;
  203. }
  204. });
  205. plugMain.setGMData("qaList", list);
  206. },
  207. play() {
  208. plugMain.getVideo().volume = 0;
  209. setTimeout(() => {
  210. plugMain.getVideo().play();
  211. }, 200);
  212. // });
  213. },
  214. setVideoVolume() {
  215. try {
  216. if (plugMain.getVideo().volume != 0) {
  217. plugMain.getVideo().volume = 0;
  218. }
  219. } catch (e) {
  220. console.error(e);
  221. }
  222. },
  223. isPlayFinish() {
  224. try {
  225. return (
  226. plugMain.getTotalTime() > 0 && plugMain.getCurTime() + 5 >= plugMain.getTotalTime()
  227. );
  228. } catch (e) {
  229. return false;
  230. }
  231. },
  232. getVideo() {
  233. return $("video")[0];
  234. },
  235. getCurTime() {
  236. let res = 0;
  237. try {
  238. res = $("video")[0].currentTime;
  239. } catch (e) {
  240. console.error(e);
  241. }
  242. return res;
  243. },
  244. getTotalTime() {
  245. let res = 0;
  246. try {
  247. res = $("video")[0].duration;
  248. } catch (e) {
  249. console.error(e);
  250. }
  251. return res;
  252. },
  253. // 题库方法
  254. formatAnswerOption(option) {
  255. // 检查输入是否是单个字母且在 A-Z 范围内
  256. if (/^[a-zA-Z]$/.test(option)) {
  257. option = option.toUpperCase();
  258. return option.charCodeAt(0) - 'A'.charCodeAt(0);
  259. } else {
  260. let arr = [
  261. ["正确", "错误"],
  262. ["对", "错"],
  263. ];
  264. let opt = option.toUpperCase();
  265. let res = -1;
  266. arr.forEach((subArr) => {
  267. if (subArr.includes(opt)) {
  268. res = subArr.indexOf(opt);
  269. return false;
  270. }
  271. });
  272. return res;
  273. }
  274. },
  275.  
  276. // 题库方法
  277. formatAnswerOptionNo(index) {
  278. return ["A", "B", "C", "D", "E", "F", "G", "H"][index]
  279. },
  280. isMatchQAText(txt1, txt2) {
  281. return (
  282. txt1 == txt2 ||
  283. plugMain.simpleHtml(txt1) == plugMain.simpleHtml(txt2) ||
  284. plugMain.simpleText(txt1) == plugMain.simpleText(txt2)
  285. );
  286. },
  287. simpleHtml(html) {
  288. html = html.replace(/&nbsp;|<br\/>|<br>|\n|\r/gi, "");
  289. html = html.trim();
  290. if (!html) return html;
  291. if (html.startsWith("<") && html.endsWith(">")) {
  292. return $(html).text().trim();
  293. }
  294. return html.trim();
  295. },
  296. simpleText(text) {
  297. return text
  298. .replace(/[^\u4e00-\u9fa5a-zA-Z0-9#split#√×]/g, "")
  299. .replace(/[的]/g, "");
  300. },
  301. async videoIsPlay() {
  302. return new Promise((resolve) => {
  303. try {
  304. let curTime = $("video")[0].currentTime;
  305. setTimeout(() => {
  306. let time1 = $("video")[0].currentTime;
  307. let res = time1 > curTime;
  308. if (res) {
  309. setTimeout(() => {
  310. let time2 = $("video")[0].currentTime;
  311. let res2 = time2 > time1;
  312. resolve(res2);
  313. }, 100);
  314. } else {
  315. return resolve(false);
  316. }
  317. }, 100);
  318. } catch (e) {
  319. resolve(false);
  320. }
  321. });
  322. },
  323. beginMan() {
  324. console.log("%c beginMan", "background:rgb(0,0,0);color:#fff");
  325. },
  326. stop() {
  327. location.href = location.href;
  328. },
  329.  
  330. openDoc() {
  331. if (docUrl) {
  332. window.open(docUrl);
  333. } else {
  334. window.open("http://doc.zhanyc.cn/pages/auth/");
  335. }
  336. },
  337. isDZKFMode() {
  338. let res = typeof (loadFun) == 'function' && loadFun.toString().includes('var data = res.response;')
  339. if (!res)
  340. res = typeof isDZKF == "boolean" && !!isDZKF;
  341. return res
  342. },
  343. registerMenuCommand() {
  344. GM_registerMenuCommand("当前是免费版", plugMain.openDoc);
  345. GM_registerMenuCommand("点此安装付费版本", plugMain.openDoc);
  346. GM_registerMenuCommand("联系脚本客服", plugMain.linkAuthor);
  347. },
  348. linkAuthor() {
  349. window.open("http://doc.zhanyc.cn/contact-me/");
  350. },
  351. setClip(txt) {
  352. GM_setClipboard(txt, "text");
  353. layer.msg("复制成功");
  354. },
  355. addStyle() {
  356. GM_addStyle(`
  357. .zfk-btn{background-color:#0fbcf9;color:white;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}.zfk-btn:hover{opacity:.8}.zfk-btn.success{background-color:#38b03f}.zfk-btn.warning{background-color:#f1a325}.zfk-btn.info{background-color:#03b8cf}.zfk-btn.danger{background-color:#ea644a}.zfk-form-tips{font-size:1.2em;color:red}.tips{color:red}.zfk-form textarea,.zfk-form input[type=text],.zfk-form input[type=number],.zfk-form input[type=password]{border:1px solid #888;border-radius:4px;padding:5px;box-sizing:border-box}.zfk-form textarea{width:100%}.zfk-form-item{margin-bottom:10px}.zfk-form-item>label:first-child{width:7em;text-align:right;display:inline-block;padding-right:5px;margin-right:0}.zfk-form-item label{margin-right:4px}.zfk-form-item.block>label:first-child{text-align:left;display:block;width:100%;font-weight:bold}.text-l{text-align:left !important}.text-c{text-align:center !important}.text-r{text-align:right !important}.p-0{padding:0px !important}.p-5{padding:5px !important}.p-10{padding:10px !important}.p-15{padding:15px !important}.p-20{padding:20px !important}.p-t-0{padding-top:0px !important}.p-t-5{padding-top:5px !important}.p-t-10{padding-top:10px !important}.p-t-15{padding-top:15px !important}.p-t-20{padding-top:20px !important}.p-b-0{padding-bottom:0px !important}.p-b-5{padding-bottom:5px !important}.p-b-10{padding-bottom:10px !important}.p-b-15{padding-bottom:15px !important}.p-b-20{padding-bottom:20px !important}.p-l-0{padding-left:0px !important}.p-l-5{padding-left:5px !important}.p-l-10{padding-left:10px !important}.p-l-15{padding-left:15px !important}.p-l-20{padding-left:20px !important}.p-r-0{padding-right:0px !important}.p-r-5{padding-right:5px !important}.p-r-10{padding-right:10px !important}.p-r-15{padding-right:15px !important}.p-r-20{padding-right:20px !important}.p-0{padding:0px !important}.p-5{padding:5px !important}.p-10{padding:10px !important}.p-15{padding:15px !important}.p-20{padding:20px !important}.m-t-0{margin-top:0px !important}.m-t-5{margin-top:5px !important}.m-t-10{margin-top:10px !important}.m-t-15{margin-top:15px !important}.m-t-20{margin-top:20px !important}.m-b-0{margin-bottom:0px !important}.m-b-5{margin-bottom:5px !important}.m-b-10{margin-bottom:10px !important}.m-b-15{margin-bottom:15px !important}.m-b-20{margin-bottom:20px !important}.m-l-0{margin-left:0px !important}.m-l-5{margin-left:5px !important}.m-l-10{margin-left:10px !important}.m-l-15{margin-left:15px !important}.m-l-20{margin-left:20px !important}.m-r-0{margin-right:0px !important}.m-r-5{margin-right:5px !important}.m-r-10{margin-right:10px !important}.m-r-15{margin-right:15px !important}.m-r-20{margin-right:20px !important}.bold{font-weight:bold !important}.tips-box{padding:10px;border:1px solid red;background-color:#fff0f0;color:red}.bold{font-weight:bold}.font-l{font-size:1.2em}.font-xl{font-size:40px}.font-l{font-size:25px}.color-default{color:#ea644a !important}.color-success{color:#38b03f !important}.color-warning{color:#f1a325 !important}.color-danger{color:#ea644a !important}.bg-default{background-color:#ea644a !important}.bg-success{background-color:#38b03f !important}.bg-warning{background-color:#f1a325 !important}.bg-danger{background-color:#ea644a !important}.zfk-table{border-collapse:collapse}.zfk-table thead{background-color:#1abc9c}.zfk-table td,.zfk-table th{text-align:center;padding:6px;border:1px solid #888}.zfk-table tr:nth-child(2n){background-color:#f2f2f2}.zfk-table tr:hover{background-color:#fff799}.zfk-container *{font-size:17px}
  358. `);
  359. }, // plugMain.setGMData("closeLJTS", plugMain.now());
  360. openLjTips(tipsAndClose = true, checkUrlBeforeClose = false) {
  361. let index = layer.open({
  362. type: 1,
  363. title: "请确认",
  364. offset: "100px",
  365. content: `
  366. <div style="padding:10px">
  367. <p>已经为你打开下一门课程,如果没有打开窗口,请检查浏览器地址栏右侧是否有拦截提示,请选择【永久允许】或者在浏览器设置中设置本网站【弹出式窗口和重定向】设置为允许</p>
  368. <p style="color:red;">如下图所示:</p>
  369. <img src="https://js.zhanyc.cn/img/ljts.jpg"/>
  370. </div>
  371. `,
  372. });
  373. if (!plugMain.pageData.ljtsIndexArr) {
  374. plugMain.pageData.ljtsIndexArr = []
  375. }
  376. plugMain.pageData.ljtsIndexArr.push(index)
  377. let url = checkUrlBeforeClose ? location.href : "";
  378. if (plugMain.pageData.closeTipsIndex != null) return;
  379. plugMain.pageData.closeTipsIndex = GM_addValueChangeListener(
  380. "closeLJTS",
  381. function (name, old_value, new_value, remote) {
  382. plugMain.pageData.ljtsIndexArr.forEach(item => {
  383. layer.close(item);
  384. })
  385. plugMain.pageData.ljtsIndexArr = []
  386. tipsAndClose && plugMain.tipsAndClose && plugMain.tipsAndClose(url);
  387. }
  388. );
  389. },
  390. tipsAndClose(checkUrl, timeout = 5000) {
  391. let mark = plugMain.now()
  392. plugMain.pageData.tipsAndCloseMark = mark
  393. plugMain.confirmRun("准备关闭当前页面,如果不想关闭请点击下面【取消执行】按钮", timeout).then((a) => {
  394. if (plugMain.pageData.tipsAndCloseMark != mark) {
  395. isDev && console.log("页面标识变更,取消关闭窗口");
  396. return
  397. }
  398. if (!checkUrl || location.href == checkUrl) window.close();
  399. });
  400. },
  401. closeWaitConfrimWin() {
  402. plugMain.setGMData("closeLJTS", plugMain.now());
  403. },
  404. removeArrEmpty(arr) {
  405. let res = [];
  406. arr.forEach((item) => {
  407. if (!!item && item.trim() != "") {
  408. res.push(item);
  409. }
  410. });
  411. return res;
  412. },
  413. confirmRun(msg = "脚本:3秒后执行下一步操作", time = 3000) {
  414. return new Promise((resolve, reject) => {
  415. let isRun = true;
  416. // clearTimeout(plugMain.pageData.confirmRunIndex);
  417. let confirmRunIndex =
  418. layer.open({
  419. type: '1',
  420. title: '脚本:是否继续执行?',
  421. closeBtn: 0,
  422. zIndex: plugMain.pageData.confirmRunZIndex++,
  423. btn: '取消执行',
  424. offset: "100px",
  425. content: `<div style="padding:20px;">${msg}</div>`,
  426. yes: function (index) {
  427. isRun = false;
  428. reject();
  429. layer.close(confirmRunIndex);
  430. }
  431. });
  432.  
  433. // layer.alert(
  434. // msg,
  435. // { icon: 3, title: "是否继续?", btn: ["取消执行"], offset: "100px" },
  436. // function (index) {
  437. // isRun = false;
  438. // reject();
  439. // layer.close(plugMain.pageData.confirmRunIndex);
  440. // }
  441. // );
  442. setTimeout(() => {
  443. layer.close(confirmRunIndex);
  444. resolve(true);
  445. }, time);
  446. });
  447. },
  448. waitTimeout(timeout) {
  449. return new Promise((resolve, reject) => {
  450. setTimeout(() => {
  451. resolve();
  452. }, timeout);
  453. });
  454. },
  455. waitOf(fun, interval = 1000, timeout = 30) {
  456. console.log("%c waitOf", "background:rgb(0,0,0);color:#fff", fun);
  457. return new Promise((resolve, reject) => {
  458. let _timeOut = timeout * 1000;
  459. try {
  460. if (fun()) {
  461. return resolve();
  462. }
  463. } catch (e) {
  464. console.error(e);
  465. }
  466. let index = setInterval(() => {
  467. try {
  468. if (timeout != -1) {
  469. _timeOut -= interval;
  470. if (_timeOut < 0) {
  471. clearInterval(index);
  472. return reject();
  473. }
  474. }
  475. if (fun()) {
  476. clearInterval(index);
  477. return resolve();
  478. }
  479. } catch (e) {
  480. console.error(e);
  481. }
  482. }, interval);
  483. });
  484. },
  485. getUrlParam(url, name) {
  486. if (arguments.length == 1) {
  487. name = url;
  488. url = window.location;
  489. }
  490. var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
  491. var r = url.search.substr(1).match(reg);
  492. if (r != null) return unescape(r[2]);
  493. return "";
  494. },
  495. objectToQueryString(obj) {
  496. var queryParams = [];
  497. for (var key in obj) {
  498. if (obj.hasOwnProperty(key)) {
  499. var value = obj[key];
  500. // 如果值为数组,则将其转换为多个参数
  501. if (Array.isArray(value)) {
  502. for (var i = 0; i < value.length; i++) {
  503. queryParams.push(
  504. encodeURIComponent(key) + "=" + encodeURIComponent(value[i])
  505. );
  506. }
  507. } else {
  508. queryParams.push(
  509. encodeURIComponent(key) + "=" + encodeURIComponent(value)
  510. );
  511. }
  512. }
  513. }
  514. return queryParams.join("&");
  515. },
  516. parseQueryString(url = window.location.href) {
  517. //url参数转对象
  518. url = !url ? window.location.href : url;
  519. if (url.indexOf("?") === -1) {
  520. return {};
  521. }
  522. let search =
  523. url[0] === "?"
  524. ? url.substr(1)
  525. : url.substring(url.lastIndexOf("?") + 1);
  526. if (search === "") {
  527. return {};
  528. }
  529. search = search.split("&");
  530. let query = {};
  531. for (let i = 0; i < search.length; i++) {
  532. let pair = search[i].split("=");
  533. query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || "");
  534. }
  535. return query;
  536. },
  537. getAttrName(el, key) {
  538. if (el.jquery) el = el.get(0);
  539. let propName = Object.keys(el).find((a) => a.startsWith(key));
  540. return propName;
  541. },
  542. getAttrNameList(el, key) {
  543. if (el.jquery) el = el.get(0);
  544. let propName = Object.keys(el).filter((a) => a.startsWith(key));
  545. return propName;
  546. },
  547. alertMsg(msg, timeout = 0) {
  548. layer.open(
  549. {
  550. type: "1",
  551. content: `<div style="padding:14px;">${msg}</div>`,
  552. title: "脚本提示" + (timeout == 0 ? '' : `(${(timeout / 1000).toFixed(2)}秒后自动关闭})`),
  553. offset: "100px",
  554. time: timeout,
  555. btn: "关闭"
  556. })
  557. },
  558. tipsMsg(msg, timeout = 3000) {
  559. layer.msg(msg, { offset: "100px", time: timeout });
  560. },
  561. confirmMsg(msg = "请确认", option = {}) {
  562. let defConfig = {
  563. title: "脚本提示", btn: ["确定", "关闭"],
  564. offset: "100px",
  565. area: ["500px"],
  566. shade: 0.3,
  567. fun1(index) { layer.close(index) },
  568. fun2() { },
  569. fun3() { }
  570. }
  571. Object.assign(defConfig, option)
  572. layer.open(
  573. {
  574. type: "1",
  575. content: `<div style="padding:14px;">${msg}</div>`,
  576. title: option.title,
  577. offset: defConfig.offset,
  578. area: defConfig.area,
  579. btn: defConfig.btn,
  580. shade: defConfig.shade,
  581. yes: defConfig.fun1,
  582. btn2: defConfig.fun2,
  583. btn3: defConfig.fun3
  584. })
  585. },
  586. matchUrl(urlKeyword, mode = "like", url = location.href) {
  587. let res = false;
  588. switch (mode) {
  589. case "eq":
  590. res = urlKeyword == url;
  591. break;
  592. case "like":
  593. res = url.indexOf(urlKeyword) != -1;
  594. break;
  595. case "left":
  596. res = url.startsWith(urlKeyword);
  597. break;
  598. case "right":
  599. res = url.endsWith(urlKeyword);
  600. break;
  601. }
  602. return res;
  603. },
  604. getPromiseWithAbort(p) {
  605. let obj = {};
  606. let p1 = new Promise(function (resolve, reject) {
  607. obj.abort = reject;
  608. });
  609. obj.promise = Promise.race([p, p1]);
  610. return obj;
  611. },
  612. page_yhwelcome() {
  613. console.log("%c page_yhwelcome", "background:rgb(255,0,0);color:#fff");
  614. var token = sessionStorage.getItem("token");
  615. this.setGMData("token", token);
  616. this.setGMData("login", { login: true, time: plugMain.now() });
  617. },
  618. createWorker(f) {
  619. var blob = new Blob(["(" + f + ")()"]);
  620. var url = window.URL.createObjectURL(blob);
  621. var worker = new Worker(url);
  622. return worker;
  623. },
  624. createIntervalWorker(callback, time) {
  625. var pollingWorker = plugMain.createWorker(`async function (e) {
  626. setInterval(async function () {
  627. this.postMessage(null)
  628. }, ${time})
  629. }`);
  630. pollingWorker.onmessage = callback;
  631. return pollingWorker;
  632. },
  633. createTimeoutWorker(callback, time) {
  634. var pollingWorker = plugMain.createWorker(`async function (e) {
  635. setTimeout(async function () {
  636. this.postMessage(null)
  637. }, ${time})
  638. }`);
  639. pollingWorker.onmessage = function () {
  640. callback();
  641. plugMain.stopWorker(pollingWorker);
  642. };
  643. return pollingWorker;
  644. },
  645. stopWorker(vm) {
  646. try {
  647. vm && vm.terminate();
  648. } catch (err) {
  649. console.log(err);
  650. }
  651. },
  652. getGMData(item, def) {
  653. return GM_getValue(item, def);
  654. },
  655. setGMData(item, val) {
  656. return GM_setValue(item, val);
  657. },
  658. delGMData(item, val) {
  659. return GM_deleteValue(item);
  660. },
  661. generateRandomString(length) {
  662. const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  663. let randomString = "";
  664.  
  665. for (let i = 0; i < length; i++) {
  666. const randomIndex = Math.floor(Math.random() * charset.length);
  667. randomString += charset.charAt(randomIndex);
  668. }
  669.  
  670. return randomString;
  671. },
  672. timeSecondsFormat(seconds) {
  673. // 确保秒数为非负整数
  674. seconds = Math.floor(Math.abs(seconds));
  675.  
  676. // 计算小时、分钟和秒
  677. var hours = Math.floor(seconds / 3600);
  678. var minutes = Math.floor((seconds % 3600) / 60);
  679. var secs = seconds % 60;
  680.  
  681. // 如果小时、分钟或秒小于10,则在其前面添加一个0
  682. hours = (hours < 10) ? "0" + hours : hours;
  683. minutes = (minutes < 10) ? "0" + minutes : minutes;
  684. secs = (secs < 10) ? "0" + secs : secs;
  685.  
  686. // 返回格式化的时间字符串
  687. return hours + ":" + minutes + ":" + secs;
  688. },
  689. // 时间转换成秒
  690. timeStringToSeconds(timeString) {
  691. if (!timeString.includes("时")) {
  692. timeString = '0时' + timeString
  693. }
  694. timeString = timeString
  695. .replace("小时", ":")
  696. .replace("时", ":")
  697. .replace("分钟", ":")
  698. .replace("分", ":")
  699. .replace("秒", "");
  700. if (timeString.endsWith(":")) {
  701. timeString = timeString.substring(0, timeString.length - 1);
  702. }
  703. const parts = timeString.split(":");
  704. if (parts.length !== 3) {
  705. if (parts.length == 2) {
  706. parts.push(0);
  707. } else {
  708. throw new Error("Invalid time string format. Expected 'hh:mm:ss'.");
  709. }
  710. }
  711.  
  712. const hours = parseInt(parts[0]);
  713. const minutes = parseInt(parts[1]);
  714. const seconds = parseInt(parts[2]);
  715.  
  716. if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) {
  717. throw new Error("Invalid time string format. Expected numeric values.");
  718. }
  719.  
  720. return hours * 3600 + minutes * 60 + seconds;
  721. },
  722. getLocalData(item, def) {
  723. var val = localStorage.getItem(item);
  724. if (val == null) return def;
  725.  
  726. return JSON.parse(val).val;
  727. },
  728. setLocalData(item, val) {
  729. return localStorage.setItem(item, JSON.stringify({ val: val }));
  730. },
  731. setFormVal(selector, formVal) {
  732. $.each(formVal, function (key, val) {
  733. let $el = $(selector).find(`[name="${key}"]`);
  734. // console.log($el);
  735. // console.log(key, $el.eq(0).attr("type"));
  736. if ($el.length == 0) return true;
  737. else if ($el.length == 1) {
  738. let type = $el.eq(0).attr("type");
  739. switch (type) {
  740. case "radio":
  741. case "checkbox":
  742. if ($el.val() == val) $el.prop("checked", true);
  743. break;
  744. default:
  745. $el.val(val);
  746. break;
  747. }
  748. } else {
  749. $el.each((i, el) => {
  750. // console.log($(el), $(el).val());
  751. if (val.includes($(el).val())) {
  752. $(el).prop("checked", true);
  753. }
  754. });
  755. }
  756. });
  757. },
  758. getFormVal(selector) {
  759. let formVal = {};
  760. var arr = $(selector).serializeArray();
  761. let tempArr = [];
  762. $.each(arr, function () {
  763. console.log(this);
  764. if (!tempArr.includes(this.name)) {
  765. tempArr.push(this.name);
  766. formVal[this.name] = this.value;
  767. } else {
  768. let oldVal = formVal[this.name];
  769. if (Array.isArray(oldVal)) {
  770. formVal[this.name].push(this.value);
  771. } else {
  772. formVal[this.name] = [formVal[this.name], this.value];
  773. }
  774. }
  775. });
  776. return formVal;
  777. },
  778. now() {
  779. return new Date().getTime();
  780. },
  781. getElByText(query, text, mode = "eq", visible = true) {
  782. let $el = null;
  783. $(query).each((i, el) => {
  784. if (visible && !$(el).is(":visible")) {
  785. return true;
  786. }
  787. if (mode == "eq" && $(el).text().trim() == text) {
  788. $el = $(el);
  789. return false;
  790. } else if (
  791. mode == "startsWith" &&
  792. $(el).text().trim().startsWith(text)
  793. ) {
  794. $el = $(el);
  795. return false;
  796. } else if (mode == "endsWith" && $(el).text().trim().endsWith(text)) {
  797. $el = $(el);
  798. return false;
  799. } else if (mode == "like" && $(el).text().trim().includes(text)) {
  800. $el = $(el);
  801. return false;
  802. }
  803. });
  804. return $el;
  805. },
  806. getElListByText(query, text, mode = "eq", visible = true) {
  807. let arr = [];
  808. $(query).each((i, el) => {
  809. if (visible && !$(query).is(":visible")) {
  810. return true;
  811. }
  812. if (mode == "eq" && $(el).text().trim() == text) {
  813. arr.push($(el));
  814. } else if (
  815. mode == "startsWith" &&
  816. $(el).text().trim().startsWith(text)
  817. ) {
  818. arr.push($(el));
  819. } else if (mode == "endsWith" && $(el).text().trim().endsWith(text)) {
  820. arr.push($(el));
  821. }
  822. });
  823. return arr;
  824. },
  825. random(min, max) {
  826. // 生成随机数范围
  827. if (arguments.length === 2) {
  828. return Math.floor(min + Math.random() * (max + 1 - min));
  829. } else {
  830. return null;
  831. }
  832. },
  833. downloadTxt(filename, text) {
  834. var element = document.createElement("a");
  835. element.setAttribute(
  836. "href",
  837. "data:text/plain;charset=utf-8," + encodeURIComponent(text)
  838. );
  839. element.setAttribute("download", filename);
  840.  
  841. element.style.display = "none";
  842. document.body.appendChild(element);
  843.  
  844. element.click();
  845.  
  846. document.body.removeChild(element);
  847. },
  848. dateFormat(date = new Date(), fmt = "yyyy-MM-dd HH:mm") {
  849. let ret;
  850. if (typeof date === "number") date = new Date(date);
  851. const opt = {
  852. "y+": date.getFullYear().toString(), // 年
  853. "M+": (date.getMonth() + 1).toString(), // 月
  854. "d+": date.getDate().toString(), // 日
  855. "H+": date.getHours().toString(), // 时
  856. "m+": date.getMinutes().toString(), // 分
  857. "s+": date.getSeconds().toString(), // 秒
  858. // 有其他格式化字符需求可以继续添加,必须转化成字符串
  859. };
  860. for (let k in opt) {
  861. ret = new RegExp("(" + k + ")").exec(fmt);
  862. if (ret) {
  863. fmt = fmt.replace(
  864. ret[1],
  865. ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, "0")
  866. );
  867. }
  868. }
  869. return fmt;
  870. },
  871. });
  872. plugMain.tipsMsg("脚本加载中")
  873. setTimeout(() => {
  874. if (!unsafeWindow.zfk) {
  875. plugMain.init();
  876. } else {
  877. console.log('skip init');
  878. }
  879. }, 3000);
  880. if (!unsafeWindow.plugMain) unsafeWindow.plugMain = plugMain;
  881. })();