// ==UserScript== // @name 更好用的NXU // @namespace http://tampermonkey.net/ // @version 0.0.5.1 // @description 让NXU更好用! // @author H // @license Apache Licence // @match https://webvpn.nxu.edu.cn/* // @match https://jwgl.nxu.edu.cn/* // @grant unsafeWindow // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_getResourceText // @grant GM_getResourceURL // @connect api-cn.faceplusplus.com // @connect webvpn.nxu.edu.cn/* // @require https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.5.1.min.js // @resource svg-logo https://cdn.bootcdn.net/ajax/libs/font-awesome/6.2.1/css/all.min.css // @noframes // @downloadURL none // ==/UserScript== //==需要调用的函数== //关闭窗口 function closeWindow() { try { window.opener = window; var win = window.open("", "_self"); win.close(); top.close(); } catch (error) { console.log("关闭窗口:失败\n错误信息:"+error); } } //随机数 function random(min, max){ return parseInt(Math.random()*(max-min+1)+min,10); } //等待执行 function justWait(min, max, log = true){ var waitmsg,waittime; if (max == 0) { waittime = min; waitmsg = "==等待了:"+(waittime / 1000)+" 秒=="; } else { waittime = random(min, max); waitmsg = "==随机等待了:"+(waittime / 1000)+" 秒=="; } return new Promise(function (resolve, reject) { setTimeout(function () { if (log) { console.log(waitmsg); } resolve(); }, waittime); }); } //toast输出 function createToast(id, mes, time = 5) { const notifications = document.querySelector('.notifications'); const toastDetails = { success:{ icon: 'fa-circle-check', text: 'Success: This is a success toast.' }, error:{ icon: 'fa-circle-xmark', text: 'Error: This is a error toast.' }, warning:{ icon: 'fa-circle-exclamation', text: 'Warning: This is a warning toast.' }, info:{ icon: 'fa-circle-info', text: 'Info: This is a info toast.' } }; if (document.querySelector("style.i"+time)){ document.querySelector("style.i"+time).innerHTML = ".toast.i"+time+"::before{animation-duration: "+time+"s;}"; } else { var style = document.createElement("style"); style.className = "i"+time; style.innerHTML = ".toast.i"+time+"::before{animation-duration: "+time+"s;}"; document.getElementsByTagName("head")[0].appendChild(style); } // console.log(id) const {icon, text} = toastDetails[id]; let txt; if (mes == "" || mes == null || typeof(mes) == "undefined"){ txt = text; } else { txt = mes; } const toast = document.createElement('li') // 创建li元素 toast.setAttribute("time", time); toast.setAttribute("style", "::before{animation-duration: "+time+"}") toast.className = `toast ${id} i${time}` // 为li元素新增样式 toast.innerHTML = `
${txt}
` notifications.appendChild(toast) // 添加元素到 notifications ul // 隐藏toast if (time != 0){ toast.timeoutId = setTimeout(()=> removeToast(toast), time * 1000); } } //toast移除 function removeToast(toast) { toast.classList.add('hide') if( toast.timeoutId) clearTimeout(toast.timeoutId) // 清楚setTimeout // 移除li元素 setTimeout(() => { toast.remove() },500) } //绑定 unsafeWindow.createToast = createToast; //==/需要调用的函数== //==常量== const css_content = `:root{--dark:#34495e;--light:#fff;--success:#0abf30;--error:#e24d4c;--warning:#e9bd0c;--info:#3498db}#plugin-settings-main{display:flex;flex-direction:column;justify-content:center}#plugin-settings-main>div{border:1px solid #e7e9eb;border-radius:4px;width:100%;display:flex;flex-direction:column;padding:1em 2em;margin-bottom:0.5em}#plugin-settings-main>div>div{width:100%;display:flex;align-items:center}#plugin-settings-main .hr{width:100%;background-color:#69c0ff;height:2px}#plugin-settings-main .hr-{width:100%;background-color:#e7e9eb;height:1px}#plugin-settings-main h2{font-size:18px}#plugin-settings-main p{margin:0;font-size:16px}#plugin-settings-main input{margin:0.5em 0.5em;padding:0.5em 0.5em;border-radius:4px;border:1px solid black;background-color:none}#plugin-settings-main input:-webkit-autofill,textarea:-webkit-autofill,select:-webkit-autofill{-webkit-box-shadow:0 0 0px 1000px transparent inset !important;background-color:transparent;background-image:none;transition:background-color 50000s ease-in-out 0s}#plugin-settings-main button{padding:0.3em 1em;border:2px solid #2881ff;background-color:#3a97fe;color:white;border-radius:5px;width:max-content}#plugin-settings-main button:disabled{border:2px solid #c5c7c8;background-color:#e7e9eb;color:black}#plugin-settings-main .button{justify-content:end}#plugin-settings-main .switch{display:flex}#plugin-settings-main .switch>p{flex-grow:1}#plugin-settings-main .note{font-size:14px;color:#8f8f8f;margin:0}#plugin-settings-main .warning{font-size:14px;color:red}#plugin-settings-main .flex-c{display:flex;flex-direction:column}#plugin-settings-main .flex{display:flex}#plugin-settings-main .flex-1{flex-grow:1}#plugin-settings-main div.switch{padding:0.5em 0}#plugin-settings-main .switch{--button-width:2.625em;--button-height:1.5em;--toggle-diameter:1.2em;--button-toggle-offset:calc((var(--button-height) - var(--toggle-diameter)) / 2);--toggle-shadow-offset:10px;--toggle-wider:2.4em;--color-grey:#cccccc;--color-green:#3a97fe}#plugin-settings-main .slider{display:inline-block;width:var(--button-width);height:var(--button-height);background-color:var(--color-grey);border-radius:calc(var(--button-height) / 2);position:relative;transition:0.3s all ease-in-out}#plugin-settings-main .slider::after{content:"";display:inline-block;width:var(--toggle-diameter);height:var(--toggle-diameter);background-color:#fff;border-radius:calc(var(--toggle-diameter) / 2);position:absolute;top:var(--button-toggle-offset);transform:translateX(var(--button-toggle-offset));box-shadow:var(--toggle-shadow-offset) 0 calc(var(--toggle-shadow-offset) * 4) rgba(0,0,0,0.1);transition:0.3s all ease-in-out}#plugin-settings-main .switch input[type="checkbox"]:checked+.slider{background-color:var(--color-green)}#plugin-settings-main .switch input[type="checkbox"]:checked+.slider::after{transform:translateX(calc(var(--button-width) - var(--toggle-diameter) - var(--button-toggle-offset)));box-shadow:calc(var(--toggle-shadow-offset) * -1) 0 calc(var(--toggle-shadow-offset) * 4) rgba(0,0,0,0.1)}#plugin-settings-main .switch input[type="checkbox"]{display:none}#plugin-settings-main .switch input[type="checkbox"]:active+.slider::after{width:var(--toggle-wider)}#plugin-settings-main .switch input[type="checkbox"]:checked:active+.slider::after{transform:translateX(calc(var(--button-width) - var(--toggle-wider) - var(--button-toggle-offset)))}.notifications:where(.toast,.column){display:flex;align-items:center}.notifications .column{display:flex;align-items:center}.notifications{position:fixed;top:30px;right:20px;z-index:9999}.notifications .toast{width:350px;list-style:none;display:flex;align-items:center;position:relative;overflow:hidden;border-radius:8px;border:1px solid rgb(220,218,215);padding:16px 17px;margin-bottom:10px;background-color:var(--light);justify-content:space-between;animation:show_toast 0.3s forwards}@keyframes show_toast{0%{transform:translateX(100%)}40%{transform:translateX(-5%)}80%{transform:translateX(0)}100%{transform:translateX(-10px)}}.toast .column i{font-size:1.75rem}.toast.hide{animation:hide_toast 0.3s forwards}@keyframes hide_toast{0%{transform:translateX(-10%)}40%{transform:translateX(0%)}80%{transform:translateX(-5%)}100%{transform:translateX(calc(100% + 20px))}}.toast .column span{font-size:1.07rem;margin-left:12px}.toast i:last-child{color:#aeb0d7;cursor:pointer}.toast i:last-child:hover{color:var(--dark)}.toast::after{content:attr(time time)''}.toast::before{content:'';position:absolute;left:0;bottom:0;width:100%;height:3px;animation:progress 5s linear forwards}@keyframes progress{100%{width:0}}.toast.success::before,.btn#success{background-color:var(--success)}.toast.error::before,.btn#error{background-color:var(--error)}.toast.warning::before,.btn#warning{background-color:var(--warning)}.toast.info::before,.btn#info{background-color:var(--info)}.toast.success .column i{color:var(--success)}.toast.error .column i{color:var(--error)}.toast.warning .column i{color:var(--warning)}.toast.info .column i{color:var(--info)}@media screen and (max-width:530px){.notifications{width:95%}.notifications .toast{width:100%;font-size:1rem;margin-left:20px}.buttons .btn{margin:0 1px;font-size:1.1rem;padding:8px 15px}}` const url = window.location.href; var type = document.querySelector("title").innerHTML; //==/常量== //==/开始== console.log("插件运行..."); //添加css样式 GM_addStyle(css_content); //插入toast列表 var link = document.createElement("link"); link.setAttribute("href", "https://cdn.bootcdn.net/ajax/libs/font-awesome/6.2.1/css/all.min.css"); link.setAttribute("rel", "stylesheet"); document.getElementsByTagName("head")[0].appendChild(link); var script = document.createElement("script"); script.innerHTML = ` function removeToast(toast) { toast.classList.add('hide') if( toast.timeoutId) clearTimeout(toast.timeoutId) // 清除setTimeout // 移除li元素 setTimeout(() => { toast.remove() },500) } `; document.getElementsByTagName("head")[0].appendChild(script); var ul = document.createElement("ul"); ul.className = "notifications"; document.getElementsByTagName("body")[0].appendChild(ul); //createToast("success", "测试消息", 0); //createToast("error", "测试消息测试消息", 0); //createToast("warning", "测试消息测试消息测试消息", 0); //createToast("info", "测试消息测试消息测试消息测试消息", 0); //自动关闭处理 if ((document.querySelector("body").innerHTML.indexOf("啊呀,服务器开小差了。3秒后自动返回上一页") != -1) || (document.querySelector("body").innerHTML.indexOf("出错啦!该网站无法访问!") != -1) || (url.indexOf("/login.action") != -1)){ if (GM_getValue("auto-close")) { closeWindow(); } else { return; } } else if (url.indexOf("/index.action?wrdrecordvisit") != -1) { if (type == "宁夏大学教务管理信息系统") { if (GM_getValue("jwgl-login") == undefined) { GM_setValue("jwgl-login", 0); } GM_setValue("jwgl-login", GM_getValue("jwgl-login") + 1); if (GM_getValue("jwgl-login") == 2) { createToast("warning", `111`, 0); GM_setValue("jwgl-login", 0); } else { closeWindow(); } } } //网页判断 if (url == "https://jwgl.nxu.edu.cn/index.action" || url == "https://jwgl.nxu.edu.cn/login.action" ) { console.log("检测到教务系统登录页面"); } else if (url.indexOf("https-443") != -1){ if (document.getElementsByTagName("h1")[0] && document.getElementsByTagName("h1")[0].innerHTML) { if (document.getElementsByTagName("h1")[0].innerHTML == 'An error occurred.') { console.log("检测到服务器错误页面"); if (GM_getValue("auto-close")) { closeWindow(); } else { return; } } } else if (type == "宁夏大学教务管理信息系统"){ console.log("检测到宁夏大学教务管理信息系统页面"); console.log("等待800ms"); if (document.getElementsByName("loginForm.name")[0]) { if (GM_getValue("auto-close")) { closeWindow(); } return; } //成功进入,监听课表页面 isIframeChange(); } } else if (url.indexOf("login") != -1){ console.log("疑似登录页面,确认中..."); if (!document.querySelector(".auth_tab")) { return; } console.log("登录页面"); if (GM_getValue("username") == undefined || GM_getValue("username") == "" || GM_getValue("username") == null || GM_getValue("password") == undefined || GM_getValue("password") == "" || GM_getValue("password") == null) { return; } //自动登录 if (GM_getValue("auto-login")) { console.log("自动登录..."); createToast("info", "自动登录...", 5); if (document.querySelector("#msg.auth_error")) { createToast("error", "输入的学号密码有误", 5); return; } document.querySelector("input#username").value = GM_getValue("username"); document.querySelector("input#password").value = GM_getValue("password"); document.querySelector("button.auth_login_btn").click(); } else { return; } } else if (url == "https://webvpn.nxu.edu.cn/" || url == "https://webvpn.nxu.edu.cn"){ console.log("资源访问控制系统首页"); resourceIndex(); } async function resourceIndex() { //等待标签加载完毕 while(true) { if (document.querySelector("div.el-scrollbar__view") && document.querySelector("div.el-scrollbar__view").innerHTML) { break; } await justWait(100, 0); } var div_title = document.querySelector("div.el-scrollbar__view"); var div_setting_title = document.createElement("div"); div_setting_title.innerHTML = "插件设置"; div_setting_title.classList.add("anchor__item"); div_setting_title.id = "plugin-settings"; div_title.appendChild(div_setting_title); var div_settings = document.createElement("div"); div_settings.innerHTML = `

插件设置

账号设置

学号:

密码:

注:用于系统自动登录,可留空。请确保学号密码输入正确!

功能设置

自动登录

自动关闭错误网站

(包括404、服务器错误等)

`; div_settings.id = "plugin-settings-content"; document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__view").appendChild(div_settings); var script = document.createElement("script"); script.innerHTML = ` function titleChange(dom) { //console.log("更改视图...") if (dom.id == "plugin-settings") { //document.querySelector(".anchor__item.is-active").classList.remove("is-active"); //dom.classList.add("is-active"); //var scrollableDiv = document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__view"); //var contentDiv = document.querySelector("div#plugin-settings-content"); //document.querySelector("div#plugin-settings-content").scrollIntoView({ behavior: 'auto', inline: 'center' }); let div = document.querySelector("div#plugin-settings-content"); let div_parent = document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__wrap"); document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__wrap").scrollBy(0, div.getBoundingClientRect().top - div_parent.getBoundingClientRect().top) } else { //dom.classList.add("is-active"); //document.querySelector("div.anchor__item#plugin-settings").classList.remove("is-active"); } } ` document.querySelector("head").appendChild(script); var div_option = document.querySelectorAll("div.anchor__item"); for (let i = 0; i < div_option.length; i++) { div_option[i].setAttribute("onclick", "titleChange(this)"); } document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__wrap").onscroll = () => { let div = document.querySelector("div#plugin-settings-content"); let div_parent = document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__wrap"); if (div.getBoundingClientRect().top <= div_parent.getBoundingClientRect().top) { document.querySelector("div.anchor__item#plugin-settings").classList.add("is-active"); } else { document.querySelector("div.anchor__item#plugin-settings").classList.remove("is-active"); } } var button = document.querySelector("#reflash-user-info"); var input_username = document.querySelector("input#username"); var input_password = document.querySelector("input#password"); if (GM_getValue("username") == undefined || GM_getValue("username") == "" || GM_getValue("username") == null || GM_getValue("password") == undefined || GM_getValue("password") == "" || GM_getValue("password") == null) { input_username.value = ""; input_password.value = ""; } else { input_username.value = GM_getValue("username"); input_password.value = GM_getValue("password"); } reflashUserInfoCheck() try { // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本 button.addEventListener("click", function(){ reflashUserInfo(); }, false); input_username.addEventListener("input", function(){ reflashUserInfoCheck(); }, false); input_password.addEventListener("input", function(){ reflashUserInfoCheck(); }, false); } catch (error) { try { // IE8.0及其以下版本 button.attachEvent("onclick", function(){ reflashUserInfo(); }, false); input_username.addEventListener("oninput", function(){ reflashUserInfoCheck(); }, false); input_password.addEventListener("oninput", function(){ reflashUserInfoCheck(); }, false); } catch (error) { // 早期浏览器 alert("错误: 按钮绑定事件失败\n很抱歉,该脚本并不适合您的浏览器\n请尝试安装最新版Edge、Chrome、FireFox、Opera、Safari或其他浏览器后获得支持"); return; } } var input_switch_total = document.querySelectorAll("label.switch"); for (let i = 0; i < input_switch_total.length; i++) { var input_switch = input_switch_total[i].querySelector("input"); input_switch.checked = GM_getValue(input_switch.id); try { // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本 input_switch.addEventListener("input", function(){ switchHandle(this); }, false); } catch (error) { try { // IE8.0及其以下版本 input_switch.addEventListener("oninput", function(input_switch){ switchHandle(this); }, false); } catch (error) { // 早期浏览器 alert("错误: 按钮绑定事件失败\n很抱歉,该脚本并不适合您的浏览器\n请尝试安装最新版Edge、Chrome、FireFox、Opera、Safari或其他浏览器后获得支持"); return; } } } } function reflashUserInfo() { var warning = document.querySelectorAll("p.warning"); for (let i = 0; i < warning.length; i++) { warning[i].style.display = "none"; } var username = document.querySelector("input#username").value; var password = document.querySelector("input#password").value; //console.log(username); var pass = true; if (username == null || username == "") { document.querySelector("p.warning#username-empty").style.display = "block"; pass = false; } else if (!/^1\d{9}\d$/.test(username)) { console.log(username); document.querySelector("p.warning#username-error").style.display = "block"; pass = false; } if (password == null || password == "") { document.querySelector("p.warning#password-empty").style.display = "block"; } if (pass) { //console.log("pass"); GM_setValue("username", username); GM_setValue("password", password); createToast("success", "账号设置成功!", 2); document.querySelector("#reflash-user-info").disabled = true; } } function reflashUserInfoCheck() { var username = document.querySelector("input#username").value; var password = document.querySelector("input#password").value; if (GM_getValue("username") == undefined || GM_getValue("username") == "" || GM_getValue("username") == null || GM_getValue("password") == undefined || GM_getValue("password") == "" || GM_getValue("password") == null) { return; } //console.log(username) //console.log(password) if (username == GM_getValue("username") && password == GM_getValue("password")) { document.querySelector("#reflash-user-info").disabled = true; } else { document.querySelector("#reflash-user-info").disabled = false; } } function switchHandle(input) { GM_setValue(input.id, input.checked); var message = input.parentNode.parentNode.querySelector("p").innerHTML; if (input.checked) { message += "    开"; } else { message += "    关"; } createToast("info", message, 2); } function isIframeChange() { var elemIfram = document.querySelector("iframe#main"); if (window.MutationObserver || window.webkitMutationObserver) { // chrome var callback = function(mutations) { mutations.forEach(function() { iframeChange(); }); }; var observer if (window.MutationObserver) { observer = new MutationObserver(callback); } else { observer = new webkitMutationObserver(callback); } observer.observe(elemIfram, { subtree: true, attributes: true, attributeOldValue: true }); } else if (elemIfram.addEventListener) { // Firefox, Opera and Safari elemIfram.addEventListener("DOMAttrModified", function(){iframeChange();}, false); } else if (elemIfram.attachEvent) { // Internet Explorer elemIfram.attachEvent("onpropertychange", function(){iframeChange();}); } } function iframeChange() { console.log("111"); } async function needLogin() { GM_xmlhttpRequest({ method: "GET", url: "https://webvpn.nxu.edu.cn/", onload: function(response) { console.log(response); } }); await justWait(1000 * 60 * 10, 0); } document.onvisibilitychange = ()=>{console.log(document.visibilityState)}