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

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

目前為 2022-07-03 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 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, "+");
    }
}