🥇优学院答题小助手(2022/07/03更新)|仅支持作业、考试界面,视频章节小测待开发。

优学院答题小助手,用于考试和作业界面辅助答题(非自动答题)。

当前为 2022-07-03 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         🥇优学院答题小助手(2022/07/03更新)|仅支持作业、考试界面,视频章节小测待开发。
// @namespace    http://tampermonkey.net/
// @version      1.1.1
// @description  优学院答题小助手,用于考试和作业界面辅助答题(非自动答题)。
// @author       Miss.
// @match        https://utest.ulearning.cn/*
// @match        https://*ulearning.cn/*/homework.do*
// @grant        unsafeWindow
// @grant        GM_setClipboard
// @grant        GM_xmlhttpRequest
// @run-at       document-start
// @connect      http://fm90.cn/*
// ==/UserScript==

"use strict";
const set = {
    get_answer: "http://fm90.cn/fuck/cha.php",
    upload_data: "http://fm90.cn/fuck/upload.php",
    heartbeat: "http://fm90.cn/fuck/server.php",
    Dealagging: false,
    left: 0,
    top: 0,
    uid: -1, //后期加入
    token: null, //后期加入
    timestamp: -1,
};
const Util = {
    post_form: function (url, data, onload, onerror) {
        Util.post(url, data, onload, onerror, { "Content-Type": "application/x-www-form-urlencoded" });
    },
    post: function (url, data, onload, onerror, headers) {
        let data_form = new Deal();
        for (let value in data) {
            data_form.append(value, data[value]);
        }
        GM_xmlhttpRequest({
            method: "POST",
            url: url,
            headers: headers,
            data: data_form.text,
            onload: onload,
            onerror: onerror,
        });
    },
    get: function (url, data, onload, onerror) {
        let data_form = new Deal();
        for (let value in data) {
            data_form.append(value, data[value]);
        }
        GM_xmlhttpRequest({
            method: "GET",
            url: url + "?" + data_form.text,
            onload: onload,
            onerror: onerror,
        });
    },
    upload_api: function (data, send) {
        if (set.token == -1) {
            setTimeout(Util.upload_api, 1000, data, true);
            if (send === true) {
                return;
            }
        }
        Util.post_form(set.upload_data, {
            token: "" + set.token,
            data: JSON.stringify(data),
        });
    },
    upload_paper: function (paper, pid, eid) {
        Util.upload_api({ op: 4,eid: eid, pid: pid, paper: paper });
    },
    upload_answer: function (answer, pid, eid) {
        Util.upload_api({ op: 5,eid: eid, pid: pid, answer: answer });
    },
    upload_title: function (title, quetype, quetxt) {
        Util.upload_api({ op: 6, type: quetype, title: title ,cont: quetxt });
    },
    get_answer: function (question, td) {
        Util.get(set.get_answer, { question: question }, function (xhr) {
            if (xhr.status == 200) {
                try {
                    let data = JSON.parse(xhr.responseText);
                    if (data.code == 1) {
                        td.innerText = data.data[0].answer;
                        td.addEventListener("click", function () {
                            GM_setClipboard(data.answer);
                        });
                        return;
                    }
                    else if (data.code == 0) {
                        td.innerText = "无答案(已回传服务器)";
                        return 0;
                    }
                }
                catch (e) { }
            }
            td.innerText = "服务器错误";
        }, function () {
            td.innerText = "服务器错误";
        });
    },
};
Re_Write();
Set_Heart();
Init();
function Re_Write() {
    const open = unsafeWindow.XMLHttpRequest.prototype.open;
    unsafeWindow.XMLHttpRequest.prototype.open = function () {
        let url = arguments[1];
        if (url) {
            if (url.match(/getPaperForStudent/) && url.match(/examId=(\d+)/) && url.match(/paperId=(\d+)/)) {
                let examID = url.match(/examId=(\d+)/)[1];
                let paperID = url.match(/paperId=(\d+)/)[1];
                this.addEventListener('load', () => {
                    let data = JSON.parse(this.responseText);
                    Util.upload_paper(data, paperID, examID);
                });
            }
            else if (url.match(/getCorrectAnswer/) && url.match(/examId=(\d+)/) && url.match(/paperId=(\d+)/)) {
                let examID = url.match(/examId=(\d+)/)[1];
                let paperID = url.match(/paperId=(\d+)/)[1];
                this.addEventListener('load', () => {
                    let data = JSON.parse(this.responseText);
                    Util.upload_answer(data, paperID, examID);
                });
            }
        }
        return open.apply(this, arguments);
    };
}
function Init() {
    if (!document.body) {
        setTimeout(Init, 100);
        return;
    }
    let style = document.createElement("style");
    style.innerHTML = `
    #answer_key {
        min-height: 22px;
        max-height: 250px;
        overflow: auto;
    }
    .td_center {
        text-align: center;
    }
    .td_left {
        text-align: left;
    }
    .td_right {
        text-align: right;
    }
    .td_width {
        width: 125px;
    }`;
    let div = document.createElement("div");
    pageurl = window.location.href.split("?")[0];
    if(pageurl=="https://utest.ulearning.cn/"){
        div.setAttribute("style", "background-color: #4fc8db; position: fixed; top: 54px; right: 300px; width: 270px; opacity: 0.75; border-style: dotted; border-width: 3px;");
    }
    else{
        div.setAttribute("style", "background-color: #4fc8db; position: fixed; top: 54px; left: 50px; width: 270px; opacity: 0.75; border-style: dotted; border-width: 3px;");
    }

    div.innerHTML = `
    <h3 style="text-align: center;">Ulearning 查题</h3>
    <table>
        <tbody>
            <tr>
                <td class="td_width td_center">
                    <button id="get_answer" style="background-color: #84f584; border-radius: 10px;">查询答案</button>
                </td>
                <td class="td_width td_center">
                    <button id="hide_show" style="background-color: #84f584; border-radius: 10px;">显示/隐藏答案</button>
                </td>
            </tr>
            <tr>
                <td class="td_width td_right">
                    服务器状态:
                </td>
                <td id="server_status" class="td_width td_left" style="font-color: blue;">
                    获取中..
                </td>
            </tr>
        </tbody>
    </table>
    <div id="answer_key" style="display: block;">
        <table border="1" id="answer_table">
            <tbody>
                <tr>
                    <th class="td_width td_center">题目</th>
                    <th class="td_width td_center">答案</th>
                </tr>
            </tbody>
        </table>
    </div>
    `;
    document.body.appendChild(style);
    document.body.appendChild(div);
    Bind();
    div.addEventListener("mousedown", function (e) {
        set.Dealagging = true;
        let mer = div.getBoundingClientRect();
        set.left = e.clientX - mer.left;
        set.top = e.clientY - mer.top;
    });
    div.addEventListener("mouseup", function () {
        set.Dealagging = false;
    });
    div.addEventListener("mousemove", function (e) {
        if (set.Dealagging) {
            let x = e.clientX - set.left;
            let y = e.clientY - set.top;
            div.style.left = x + "px";
            div.style.top = y + "px";
        }
    });
}
function Bind() {
    let get_answer = document.querySelector("#get_answer");
    get_answer && (function () {
        get_answer.addEventListener("click", Get_Answer, false);
    })();
    let hide_show = document.querySelector("#hide_show");
    hide_show && (function () {
        hide_show.addEventListener("click", function () {
            let answer_key = document.querySelector("#answer_key");
            answer_key && (function () {
                answer_key.getAttribute("style") === "display: block;" && (function () {
                    answer_key.setAttribute("style", "display: none;");
                    return true;
                })() || (function () {
                    answer_key.setAttribute("style", "display: block;");
                })();
            })();
        }, false);
    })();
}
function Set_Heart() {
        setInterval(Heart, 20000);
}
function Heart() {
    let server_status = document.querySelector("#server_status");
    if (server_status) {
        set.timestamp = new Date().getTime();
        Util.get(set.heartbeat, { token: "" + set.token, timestamp: "" + set.timestamp }, function (xhr) {
            try {
                let xhr_json = JSON.parse(xhr.responseText);
                if (xhr_json.code == 1) {
                    server_status.innerText = "正常";
                    return;
                }
            }
            catch (e) { }
            server_status.innerText = "异常";
        }, function () {
            server_status.innerText = "异常";
        });
    }
}
function Clear_Table() {
    let answer_table = document.querySelector("#answer_table");
    answer_table && (function () {
        while (answer_table.rows.length > 1) {
            answer_table.deleteRow(1);
        }
    })();
}
function Get_Answer() {
    Clear_Table();
    let question_area = document.querySelectorAll(".question-area");
    question_area && (function(){
        question_area.forEach(function (item) {
            item.childNodes.forEach(function (div) {
                if (div.className.indexOf("next-part") != -1) {
                    return;
                }
                switch (div.className) {
                    case "question-item":
                        way1(div);
                        break;
                    default:
                        way2(div);
                }
            });
        });
    })();
    let question_wrap = document.querySelectorAll("#questionWrap");
    question_area && (function(){
        question_wrap.forEach(function (item) {
            item.childNodes.forEach(function (div){
                switch (div.className) {
                    case "multiple-choices":
                        case "judge":
                        case "fill":
                        case "match":
                        case "sort":
                            way3(div);
                            break;
                        case "blankFill":
                        case "cloze":
                        default:
                            way2(div);
                }
            });
        });
    })();
}
function way3(div) {
    let index = div.querySelector(".position-rltv").firstChild.innerText;
    let title = div.querySelector(".position-rltv").lastChild;
    let title_text = title && title.innerText || "";
    let answer_table = document.querySelector("#answer_table");
    answer_table && (function () {
        let tr = answer_table.insertRow();
        let t = tr.insertCell();
        t.innerText = "【" + index.split(".")[0] + "】" + title_text;
        t.addEventListener("click", function () {
            GM_setClipboard(this.innerText);
        }, false);
        t = tr.insertCell();
        Util.get_answer(title_text, t);
    })();
}
function way2(div) {
//   英语答题类      待提供测试账号开发
//   英语答题类      待提供测试账号开发
//   英语答题类      待提供测试账号开发
}
function way1(div) {
    let qid = div.firstChild.__vue__.question.questionid;
    if (!qid) {
        return;
    }
    let index = div.firstChild.__vue__.question.index;
    let title = div.firstChild.__vue__.question.title;
    let quetype = div.firstChild.__vue__.question.type;
    let quetxt = "";
    let cho = div.firstChild.__vue__.question.choices;
    if(quetype==1||quetype==2){
        cho.forEach(function(item){quetxt+=item.text+"||";})
        quetxt = re_text(quetxt);
    }
    let answer_table = document.querySelector("#answer_table");
    answer_table && (function () {
        let tr = answer_table.insertRow();
        let t = tr.insertCell();
        t.innerText = "【" + index + "】" + title;
        t.addEventListener("click", function () {
            GM_setClipboard(this.innerText);
        }, false);
        t = tr.insertCell();
        let getcode = Util.get_answer(title, t);
        if(getcode==0){
            Util.upload_title(title, quetype, quetxt);
        }
    })();
}

function re_text(text) {
    text = text.replace(/<\/?.+?\/?>/g,'');
    text = text.replace(/\t/g, "");
    text = text.replace(/\n/g, "");
    text = text.replace(/\r/g, "");
    text = text.replace(/&.*?;/g, "");
    return $.trim(text.substr(0,text.length-2));
}

function sleep(d){
  for(var t = Date.now();Date.now() - t <= d;);
}

class Deal {
    constructor() {
        this.text = "";
        this.data = [];
    }
    append(k, v) {
        this.data.push(encodeURIComponent(k) + "=" + encodeURIComponent(v));
        this.text = this.data.join("&").replace(/%20/g, "+");
    }
}