物理实验选课油猴脚本

该脚本需要edge浏览器(或其他)支持油猴插件的浏览器

使用方法:

0.在油猴插件中添加新脚本

1.进入物理选课网站(先别登录)

2.点击拓展打开这个油猴脚本

3.刷新网站并登录(如果右上角显示"脚本加载完毕,当前版本为ready_for_use版"则表示脚本加载成功)

4.选择你想要选择的课程并点击选修

5.一直等待

6.等到消息框中返回"已经获取课程: ${labName}"时代表选修成功

脚本如下:

// ==UserScript==
// @name         百丽宫物理实验选课辅助脚本(ready_for_use1)
// @version      0.1.1
// @description  get_ready_for_use
// @author       Capsize_rm
// @match        http://10.133.22.200:7100/*
// @icon         http://10.133.22.200:7100/favicon.ico
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // 保存原始的 XMLHttpRequest 对象
    const originalXHR = window.XMLHttpRequest;

    // 创建悬浮消息容器
    const messageContainer = document.createElement('div');
    messageContainer.style.position = 'fixed';
    messageContainer.style.top = '20px';
    messageContainer.style.right = '20px';
    messageContainer.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
    messageContainer.style.color = '#ffffff';
    messageContainer.style.padding = '10px';
    messageContainer.style.borderRadius = '5px';
    messageContainer.style.zIndex = '9999';
    messageContainer.style.fontFamily = 'Arial, sans-serif';
    messageContainer.style.fontSize = '14px';
    messageContainer.style.maxHeight = '300px';
    messageContainer.style.overflowY = 'auto';
    messageContainer.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.5)';

    // 将容器添加到页面
    document.body.appendChild(messageContainer);

    // 消息队列
    const maxMessages = 20;
    let messageCount = 0;
    // 启动提示
    const newMessage = document.createElement('div');
    newMessage.textContent = `脚本加载完毕,当前版本为ready_for_use版`;
    newMessage.style.marginBottom = '5px';
    messageContainer.insertBefore(newMessage, messageContainer.firstChild);
    if (messageContainer.children.length > maxMessages) {
        messageContainer.removeChild(messageContainer.lastChild);
    }

    // 重写 XMLHttpRequest
    window.XMLHttpRequest = function () {
        const xhr = new originalXHR();

        // 用于存储定时器的 ID
        let retryIntervalId = null;

        // 重写 open 方法
        const originalOpen = xhr.open;
        xhr.open = function (method, url) {
            console.log(`拦截到请求: ${method} ${url}`);

            // 如果是 POST 请求并且 URL 匹配目标路径
            if (method.toUpperCase() === 'POST' && url.includes('/XPK/StuCourseElective/UseCoursesLab')) {
                // 重写 send 方法
                const originalSend = xhr.send;
                xhr.send = function (body) {
                    console.log('原始请求体:', body);

                    // 解析请求体(假设是 URL 编码格式)
                    const params = new URLSearchParams(body);

                    // 检查 ObjectIDs 是否包含 TeacherID
                    const objectIDs = params.get('ObjectIDs');
                    if (objectIDs && objectIDs.includes('TeacherID')) {
                        console.log('ObjectIDs 包含 TeacherID');

                        // 修改请求体(如果需要)
                        const modifiedBody = modifyRequestBody(body);
                        console.log('修改后的请求体:', modifiedBody);

                        // 调用原始的 send 方法
                        originalSend.call(xhr, modifiedBody);

                        // 解析 ObjectIDs 获取 LabName
                        const objectIDsJson = JSON.parse(decodeURIComponent(objectIDs));
                        const labName = objectIDsJson[0].LabName;

                        // 计数器
                        let i = 0;

                        // 重写 onreadystatechange 方法以检查响应
                        const originalOnReadyStateChange = xhr.onreadystatechange;
                        xhr.onreadystatechange = function () {
                            if (xhr.readyState === 4) { // 请求完成
                                console.log('请求完成,响应:', xhr.responseText);

                                // 检查响应中是否包含“成功”
                                if (xhr.responseText.includes('成功')) {
                                    console.log('响应包含“成功”,停止重发请求');
                                    clearInterval(retryIntervalId); // 清除定时器

                                    // 在悬浮消息中打印“已经获取课程”
                                    const newMessage = document.createElement('div');
                                    newMessage.textContent = `已经获取课程: ${labName}`;
                                    newMessage.style.marginBottom = '5px'; // 设置消息间距

                                    // 将新消息添加到容器顶部
                                    messageContainer.insertBefore(newMessage, messageContainer.firstChild);

                                    // 如果消息超过最大数量,移除最旧的消息
                                    if (messageContainer.children.length > maxMessages) {
                                        messageContainer.removeChild(messageContainer.lastChild);
                                    }
                                }
                            }

                            // 调用原始的 onreadystatechange 方法
                            if (originalOnReadyStateChange) {
                                originalOnReadyStateChange.apply(xhr, arguments);
                            }
                        };

                        // 每隔一秒重发一次数据包请求
                        retryIntervalId = setInterval(() => {
                            i++; // 每次重发时增加计数器
                            console.log('重发请求体:', modifiedBody);

                            // 重新调用 open 方法,确保请求状态为 OPENED
                            xhr.open('POST', url, true); // 重新打开请求
                            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

                            // 调用原始的 send 方法
                            originalSend.call(xhr, modifiedBody);

                            // 在悬浮消息中打印信息
                            const newMessage = document.createElement('div');
                            newMessage.textContent = `正在获取课程: ${labName}, 进度: ${i}`;
                            newMessage.style.marginBottom = '5px'; // 设置消息间距

                            // 将新消息添加到容器顶部
                            messageContainer.insertBefore(newMessage, messageContainer.firstChild);

                            // 如果消息超过最大数量,移除最旧的消息
                            if (messageContainer.children.length > maxMessages) {
                                messageContainer.removeChild(messageContainer.lastChild);
                            }
                        }, 800);
                    } else {
                        console.log('ObjectIDs 不包含 TeacherID,不处理此请求');
                        // 如果不满足条件,直接发送原始请求
                        originalSend.call(xhr, body);
                    }
                };
            }

            // 调用原始的 open 方法
            originalOpen.apply(xhr, arguments);
        };

        return xhr;
    };

    // 修改请求体的函数
    function modifyRequestBody(body) {
        // 解析请求体(假设是 URL 编码格式)
        const params = new URLSearchParams(body);
        // 返回修改后的请求体
        return params.toString();
    }

    console.log('油猴脚本已加载,开始拦截请求...');
})();

免责声明:

这段脚本运行目的仅仅为了方便同学们选课,具体原理就是不断重发数据包直到选上了课为止.

正常使用不会产生任何问题,但是请不要乱改参数.

所有后果均因为乱改参数导致,请不要怪到原版脚本头上.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值