// ==UserScript== // @name 华北水利水电大学校园网自动登录 // @namespace http://tampermonkey.net/ // @version 0.0.1 // @description 首次使用弹窗配置账号密码,之后自动登录校园网并提示成功。 // @author 安和壹 // @match http://10.1.1.10/* // @match http://10.1.1.10/ // @match http://10.1.1.10:801/eportal/portal/login* // @grant none // @run-at document-end // ==/UserScript== (function() { 'use strict'; const STORAGE_KEY = 'ncwu_network_auto_login_v3'; const OVERLAY_ID = 'ncwu-overlay'; const GEAR_ID = 'ncwu-gear'; const CARRIER_OPTIONS = [ { name: '校园网', suffix: '' }, { name: '中国移动', suffix: '@cmcc' }, { name: '中国联通', suffix: '@lt' }, { name: '中国电信', suffix: '@dx' } ]; /* ================= 配置存取 ================= */ function loadConfig() { try { const raw = localStorage.getItem(STORAGE_KEY); if (raw) return JSON.parse(raw); } catch (e) {} return null; } function saveConfig(cfg) { localStorage.setItem(STORAGE_KEY, JSON.stringify(cfg)); } /* ================= 工具函数 ================= */ function parseJsonp(text) { const m = text.match(/dr1003\(([\s\S]*)\)\s*$/); if (!m) return null; try { return JSON.parse(m[1]); } catch (e) { return null; } } function isSuccess(data) { if (!data) return false; return data.result === '1' || data.result === 1 || (data.msg && (data.msg.includes('成功') || data.msg.includes('认证成功'))); } function notifyAndClose(msg) { alert(msg); try { window.close(); } catch(e) {} setTimeout(() => { document.body && (document.body.innerHTML = `
${msg}
您可以手动关闭此页面
`); document.title = '登录成功'; }, 100); } /* ================= 样式 ================= */ function injectStyles() { if (document.getElementById('ncwu-style')) return; const css = ` #ncwu-overlay { all: initial; position: fixed; inset: 0; z-index: 2147483647; background: rgba(0,0,0,0.55); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; } #ncwu-modal { all: initial; width: 380px; background: #fff; border-radius: 16px; padding: 32px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); display: flex; flex-direction: column; gap: 18px; animation: ncwu-pop 0.3s ease-out; } @keyframes ncwu-pop { from { opacity: 0; transform: scale(0.9) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } } #ncwu-modal h2 { all: initial; font-size: 22px; font-weight: 700; color: #1a1a1a; text-align: center; } #ncwu-modal .ncwu-sub { all: initial; font-size: 13px; color: #888; text-align: center; margin-top: -10px; } .ncwu-group { all: initial; display: flex; flex-direction: column; gap: 6px; } .ncwu-group label { all: initial; font-size: 13px; font-weight: 600; color: #444; } .ncwu-group input, .ncwu-group select { all: initial; height: 42px; padding: 0 14px; border: 1px solid #d0d0d0; border-radius: 8px; font-size: 14px; color: #333; background: #fafafa; transition: border-color .2s, box-shadow .2s; width: 100%; box-sizing: border-box; } .ncwu-group input:focus, .ncwu-group select:focus { outline: none; border-color: #c41e24; box-shadow: 0 0 0 3px rgba(196,30,36,0.08); background: #fff; } #ncwu-save { all: initial; margin-top: 6px; height: 44px; border-radius: 8px; background: linear-gradient(135deg, #c41e24, #a01820); color: #fff; font-size: 15px; font-weight: 600; cursor: pointer; text-align: center; line-height: 44px; transition: transform .15s, filter .15s; user-select: none; } #ncwu-save:hover { filter: brightness(1.1); } #ncwu-save:active { transform: scale(0.98); } #ncwu-tips { all: initial; font-size: 12px; color: #999; text-align: center; margin-top: -6px; } #ncwu-error { all: initial; font-size: 12px; color: #c41e24; text-align: center; min-height: 16px; } #ncwu-gear { all: initial; position: fixed; right: 16px; bottom: 16px; z-index: 2147483646; width: 40px; height: 40px; border-radius: 50%; background: #fff; box-shadow: 0 2px 8px rgba(0,0,0,0.15); cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 20px; opacity: 0.4; transition: opacity .2s; } #ncwu-gear:hover { opacity: 1; } `; const style = document.createElement('style'); style.id = 'ncwu-style'; style.textContent = css; (document.head || document.documentElement).appendChild(style); } /* ================= 弹窗逻辑(挂载到 documentElement 防清空) ================= */ function showConfigDialog(onSave) { injectStyles(); // 如果已存在则不再创建 if (document.getElementById(OVERLAY_ID)) return; const overlay = document.createElement('div'); overlay.id = OVERLAY_ID; const existing = loadConfig(); const current = existing || { username: '', password: '', carrierSuffix: '@cmcc' }; overlay.innerHTML = `

校园网自动登录配置

首次使用,请填写您的上网账号信息
保存并登录
信息仅保存在本地浏览器,不会上传至任何服务器
`; // 关键:挂载到 documentElement,避免 body 被 JS 清空时丢失 document.documentElement.appendChild(overlay); overlay.querySelector('#ncwu-save').addEventListener('click', () => { const username = overlay.querySelector('#ncwu-user').value.trim(); const password = overlay.querySelector('#ncwu-pass').value; const carrierSuffix = overlay.querySelector('#ncwu-carrier').value; const errEl = overlay.querySelector('#ncwu-error'); if (!username) { errEl.textContent = '请填写账号'; return; } if (!password) { errEl.textContent = '请填写密码'; return; } const cfg = { username, password, carrierSuffix }; saveConfig(cfg); overlay.remove(); onSave(cfg); }); } /* ================= 齿轮按钮 ================= */ function addGearButton() { if (document.getElementById(GEAR_ID)) return; const gear = document.createElement('div'); gear.id = GEAR_ID; gear.innerHTML = '⚙️'; gear.title = '修改校园网登录配置'; gear.addEventListener('click', () => { showConfigDialog((cfg) => startLogin(cfg)); }); document.documentElement.appendChild(gear); } /* ================= 登录核心 ================= */ function startLogin(cfg) { const userIp = window.v46ip || window.ss5 || ''; const userMac = window.ss1 || '000000000000'; const account = encodeURIComponent(`,0,${cfg.username}${cfg.carrierSuffix}`); const password = encodeURIComponent(cfg.password); const url = `http://10.1.1.10:801/eportal/portal/login?callback=dr1003&login_method=1&user_account=${account}&user_password=${password}&wlan_user_ip=${userIp}&wlan_user_ipv6=&wlan_user_mac=${userMac}&wlan_ac_ip=&wlan_ac_name=&jsVersion=4.2&terminal_type=1&lang=zh-cn&v=${Date.now()}&lang=zh`; console.log('[校园网登录] 准备登录... IP=' + userIp); fetch(url, { method: 'GET', credentials: 'include' }) .then(r => r.text()) .then(text => { console.log('[校园网登录] 返回:', text); const data = parseJsonp(text); if (isSuccess(data)) { notifyAndClose('成功登录校园网'); } else { alert('登录失败:' + (data?.msg || '未知错误,请检查账号密码或运营商')); } }) .catch(err => { console.warn('[校园网登录] fetch 失败,回退跳转:', err); window.location.replace(url); }); } /* ================= MutationObserver 守护弹窗 ================= */ function guardDialog(onSave) { const observer = new MutationObserver(() => { const cfg = loadConfig(); const overlay = document.getElementById(OVERLAY_ID); const hasForm = document.querySelector('input[name="DDDDD"]'); // 如果还没配置,且弹窗被干掉了,就重新创建 if ((!cfg || !cfg.username || !cfg.password) && !overlay && hasForm) { console.log('[校园网登录] 检测到弹窗被页面重绘清除,正在重建...'); showConfigDialog(onSave); } }); observer.observe(document.documentElement, { childList: true, subtree: true }); } /* ================= 入口 ================= */ // 场景1:已在登录回调页 if (location.href.includes('/eportal/portal/login')) { const text = document.body?.innerText || document.body?.textContent || ''; const data = parseJsonp(text); if (isSuccess(data)) { notifyAndClose('成功登录校园网'); } else if (data) { alert('登录失败:' + (data.msg || JSON.stringify(data))); } else { notifyAndClose('成功登录校园网'); } return; } // 场景2:在 10.1.1.10 主页 const cfg = loadConfig(); if (!cfg || !cfg.username || !cfg.password) { // 首次使用:立即显示弹窗,并启动守护防止被刷掉 showConfigDialog((newCfg) => startLogin(newCfg)); guardDialog((newCfg) => startLogin(newCfg)); } else { // 已有配置:直接登录 startLogin(cfg); addGearButton(); } })();