Skip to content

Releases: Fromsko/sLogin

Release 1.1.2

Choose a tag to compare

@github-actions github-actions released this 26 Jun 14:32
v1.1.3

fix: version

Release 1.1.2

Choose a tag to compare

@github-actions github-actions released this 01 Apr 11:55
500653b
v1.1.2

Update main.yml

Update

Choose a tag to compare

@Fromsko Fromsko released this 04 Nov 18:24
c4a0eb0
  • 增加鼠标右键操作
  • 修复登录失败数据清空失败,导致登录按钮失效

dev-1.0.0

Choose a tag to compare

@Fromsko Fromsko released this 16 Oct 17:54

更新内容

  • 优化逻辑
  • 引入 Pinia 管理状态

待实现

  • 云盘子页面
  • 设置页面的状态持久化
  • 云更新技术的支持
  • Github 仓库下载

登陆器

Choose a tag to compare

@Fromsko Fromsko released this 10 Oct 13:52

针对自动登录进行了一定的优化

仅包含登陆器

Choose a tag to compare

@Fromsko Fromsko released this 08 Oct 16:11

更新部分

  • 增加项目导航标注
  • 移除其余部分,仅保留登录部分

主版本-template

Choose a tag to compare

@Fromsko Fromsko released this 24 Sep 12:53

说明

张院每次登录网络都需要二次输入信息,非常麻烦而且手机号码也不一定记得住

最初版本使用 ScriptCat 制作
将 ScriptCat 版本迁移为 Go 语言 + vue3 实现,并制作成模板方便拓展。

ScriptCat 版本

// ==UserScript==
// @name         校园网直连
// @namespace    https://github.com/fromsko
// @version      0.1.1
// @description  用于张家界学院校园网直连的自动脚本
// @author       Fromsko
// @match        http://172.18.2.6/*
// @connect      172.18.2.6
// @connect      https://unpkg.com
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addValueChangeListener
// @grant        GM_info
// @grant        unsafeWindow
// @grant        GM_log
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_openInTab
// @grant        GM_notification
// @grant        GM_updateNotification
// @grant        GM_registerMenuCommand
// @run-at       doc-start
// ==/UserScript==
let loginStateInfo = GM_getValue('loginState', {})
let userInfo = {
    username: '10086',
    password: '111',
    client: '联通',
}

const defaultConfig = {
    setLoginParams (userInfo) {
        let random = function () {
            return Math.floor(Math.random() * 10000 + 500)
        }
        const params = new URLSearchParams()
        switch (userInfo.client) {
            case '移动':
                userInfo.client = '@cmcc'
                break
            case '联通':
                userInfo.client = '@unicom'
                break
            case '电信':
                userInfo.client = '@telecom'
            case '教职工':
                userInfo.client = ''
                break
        }
        params.append('callback', 'dr1003')
        params.append('DDDDD', userInfo.username + userInfo.client)
        params.append('upass', userInfo.password)
        params.append('0MKKey', '123456')
        params.append('R1', '0')
        params.append('R2', '')
        params.append('R3', '0')
        params.append('R6', '0')
        params.append('para', '00')
        params.append('v6ip', '')
        params.append('terminal_type', '1')
        params.append('lang', 'zh-cn')
        params.append('jsVersion', '4.2')
        params.append('v', random())
        params.append('lang', 'zh')
        return params.toString()
    },
    agent: 'Dalvik/2.1.0 (Linux; U; Android 11; M3121K1AB Build/SKQ1.211006.001) (device:M3121K1AB) Language/zh_CN',
    host: '172.18.2.6'
}

const useRequest = (config = defaultConfig) => {
    let { setLoginParams, host, agent } = config

    let request = (url, data = '', type = 'get') => {
        return new Promise((resolve, reject) => {
            var headers = {
                'User-Agent': agent,
            }
            GM_xmlhttpRequest({
                method: type,
                url: url,
                data: data,
                headers: headers,
                onload: function (xhr) {
                    try {
                        resolve(obj)
                    } catch (err) {
                        resolve(xhr.responseText)
                    }
                },
            })
        })
    }
    let parserResp = (response) => {
        const jsonString = response.match(/\((.*)\)/)[1]
        const jsonResponse = JSON.parse(jsonString)

        let result = { code: 400, msg: '登录失败', data: { v46ip: '', uid: '' } }
        if (jsonResponse.result === 1) {
            result.code = 200
            result.msg = '登录成功'
            result.data.v46ip = jsonResponse.v46ip
            result.data.uid = jsonResponse.uid
        } else {
            result.data.v46ip = jsonResponse.ss5
        }
        return result
    }
    return {
        parserResp,
        async login (userInfo) {
            return await request(`http://${host}/drcom/login?${setLoginParams(userInfo)}`)
        },
        async logout () {
            return await request(`http://${host}/drcom/logout?callback=dr1003&jsVersion=4.2&v=9074&lang=zh`)
        },
    }
}

// 日志封装
const useScriptLogger = (title, content, level = 'info') => {
    const scriptName = GM_info.script.name
    GM_log(scriptName, level, { script_log: { [title]: content } })
}

// 浏览器控制台颜色日志
const useWebColorLogger = () => {
    const isProduction = false

    const isEmpty = (value) => {
        return value == null || value === undefined || value === ''
    }
    const prettyPrint = (title, text, color) => {
        if (isProduction) return
        console.log(
            `%c ${title} %c ${text} %c`,
            `background:${color};border:1px solid ${color}; padding: 1px; border-radius: 2px 0 0 2px; color: #fff;`,
            `border:1px solid ${color}; padding: 1px; border-radius: 0 2px 2px 0; color: ${color};`,
            'background:transparent'
        )
    }
    const info = (textOrTitle, content = '') => {
        const title = isEmpty(content) ? 'Info' : textOrTitle
        const text = isEmpty(content) ? textOrTitle : content
        prettyPrint(title, text, '#909399')
    }
    const error = (textOrTitle, content = '') => {
        const title = isEmpty(content) ? 'Error' : textOrTitle
        const text = isEmpty(content) ? textOrTitle : content
        prettyPrint(title, text, '#F56C6C')
    }
    const warning = (textOrTitle, content = '') => {
        const title = isEmpty(content) ? 'Warning' : textOrTitle
        const text = isEmpty(content) ? textOrTitle : content
        prettyPrint(title, text, '#E6A23C')
    }
    const success = (textOrTitle, content = '') => {
        const title = isEmpty(content) ? 'Success ' : textOrTitle
        const text = isEmpty(content) ? textOrTitle : content
        prettyPrint(title, text, '#67C23A')
    }
    const table = () => {
        const data = [
            { id: 1, name: 'Alice', age: 25 },
            { id: 2, name: 'Bob', age: 30 },
            { id: 3, name: 'Charlie', age: 35 }
        ]
        console.log(
            '%c id%c name%c age',
            'color: white; background-color: black; padding: 2px 10px;',
            'color: white; background-color: black; padding: 2px 10px;',
            'color: white; background-color: black; padding: 2px 10px;'
        )

        data.forEach((row) => {
            console.log(
                `%c ${row.id} %c ${row.name} %c ${row.age} `,
                'color: black; background-color: lightgray; padding: 2px 10px;',
                'color: black; background-color: lightgray; padding: 2px 10px;',
                'color: black; background-color: lightgray; padding: 2px 10px;'
            )
        })
    }
    const picture = (url, scale = 1) => {
        if (isProduction) return
        const img = new Image()
        img.crossOrigin = 'anonymous'
        img.onload = () => {
            const c = document.createElement('canvas')
            const ctx = c.getContext('2d')
            if (ctx) {
                c.width = img.width
                c.height = img.height
                ctx.fillStyle = 'red'
                ctx.fillRect(0, 0, c.width, c.height)
                ctx.drawImage(img, 0, 0)
                const dataUri = c.toDataURL('image/png')

                console.log(
                    `%c sup?`,
                    `font-size: 1px;
                    padding: ${Math.floor((img.height * scale) / 2)}px ${Math.floor((img.width * scale) / 2)}px;
                    background-image: url(${dataUri});
                    background-repeat: no-repeat;
                    background-size: ${img.width * scale}px ${img.height * scale}px;
                    color: transparent;
                    `
                )
            }
        }
        img.src = url
    }

    return {
        info,
        error,
        warning,
        success,
        picture,
        table
    }
}

const SelectPage = () => {
    let logger = useWebColorLogger()
    let { login, logout, parserResp } = useRequest()
    let handleEvent = (view, callback = () => { }) => {
        let removeHtmlStyle = () => {
            let htmlElement = document.documentElement
            htmlElement.removeAttribute('style')
            document.body.style.margin = '0'
            document.body.style.display = 'flex'
            document.body.style.alignItems = 'center'
            document.body.style.justifyContent = 'center'
            document.body.style.backgroundColor = 'skyblue'
        }
        let timer = setTimeout(function () {
            document.body.innerHTML = view
            callback()
            removeHtmlStyle()
            clearTimeout(timer)
        }, 500)
    }

    switch (document.title) {
        case '注销页':
            handleEvent(
                `
                <div class="login-container" style="display: flex; align-items: center; justify-content: center; height: 100vh; width: 250px; min-height: 100vh; backdrop-filter: blur(10px);">
                    <div class="login-box" style="display: flex; flex-direction: column; background-color: rgba(255, 255, 255, 0.8); padding: 20px; border-radius: 10px; align-items: center;">
                        <div style="text-align: center; margin-bottom: 20px; font-size: 20px;">登录成功</div>
                        <div style="text-align: center; margin-bottom: 10px;">账户: ${loginStateInfo.data.uid}</div>
                        <div style="text-align: center; margin-bottom: 10px; margin-top: 5px;">IP地址: ${loginStateInfo.data.v46ip}</div>
                        <button type="button" id="loginBtn" style="padding: 10px 20px; border-radius: 5px; border: none; outline: none; background-color: #3498db; color: #fff; cursor: pointer;">注销</button>
                    </div>
                </div>
                `,
                () => {
                    const loginBtn = document.getElementById('loginBtn')
                    loginBtn.oncl...
Read more