深圳大学大物实验预习题小助手增强版 (modified by WYK)

自动提供参考答案

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

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

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

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

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

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

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         深圳大学大物实验预习题小助手增强版 (modified by WYK)
// @namespace    https://github.com/AnotiaWang
// @version      0.56
// @description  自动提供参考答案
// @author       AnotiaWang
// @match        http://172.31.80.102:7101/Student/ReadyForExam/*
// @match        http://172.31.80.245:8101/Student/ReadyForExam/*
// @match        http://172.31.80.45:8101/Student/ReadyForExam/*
// @match        http://172.31.80.16:8101/Student/ReadyForExam/*
// @match        http://172.31.80.95:8101/Student/ReadyForExam/*
// @match        http://172.31.80.1:8101/Student/ReadyForExam/*
// @match        http://172.31.80.102:8101/Student/ReadyForExam/*
// @match        http://172.31.80.14:7101/Student/ReadyForExam/*
// @grant        none
// @require      https://unpkg.com/[email protected]/dist/ajaxhook.min.js
// @license      WTFPL
// ==/UserScript==

(function(e, a) { for(var i in a) e[i] = a[i]; }(window, /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__webpack_require__.i = function(value) { return value; };
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 3);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, "__esModule", {
    value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

exports.configEvent = configEvent;
exports.hook = hook;
exports.unHook = unHook;
/*
 * author: wendux
 * email: [email protected]
 * source code: https://github.com/wendux/Ajax-hook
 */

// Save original XMLHttpRequest as _rxhr
var realXhr = "_rxhr";

function configEvent(event, xhrProxy) {
    var e = {};
    for (var attr in event) {
        e[attr] = event[attr];
    } // xhrProxy instead
    e.target = e.currentTarget = xhrProxy;
    return e;
}

function hook(proxy) {
    // Avoid double hookAjax
    window[realXhr] = window[realXhr] || XMLHttpRequest;

    XMLHttpRequest = function XMLHttpRequest() {
        var xhr = new window[realXhr]();
        // We shouldn't hookAjax XMLHttpRequest.prototype because we can't
        // guarantee that all attributes are on the prototype。
        // Instead, hooking XMLHttpRequest instance can avoid this problem.
        for (var attr in xhr) {
            var type = "";
            try {
                type = _typeof(xhr[attr]); // May cause exception on some browser
            } catch (e) {}
            if (type === "function") {
                // hookAjax methods of xhr, such as `open`、`send` ...
                this[attr] = hookFunction(attr);
            } else {
                Object.defineProperty(this, attr, {
                    get: getterFactory(attr),
                    set: setterFactory(attr),
                    enumerable: true
                });
            }
        }
        var that = this;
        xhr.getProxy = function () {
            return that;
        };
        this.xhr = xhr;
    };

    // Generate getter for attributes of xhr
    function getterFactory(attr) {
        return function () {
            var v = this.hasOwnProperty(attr + "_") ? this[attr + "_"] : this.xhr[attr];
            var attrGetterHook = (proxy[attr] || {})["getter"];
            return attrGetterHook && attrGetterHook(v, this) || v;
        };
    }

    // Generate setter for attributes of xhr; by this we have an opportunity
    // to hookAjax event callbacks (eg: `onload`) of xhr;
    function setterFactory(attr) {
        return function (v) {
            var xhr = this.xhr;
            var that = this;
            var hook = proxy[attr];
            // hookAjax  event callbacks such as `onload`、`onreadystatechange`...
            if (attr.substring(0, 2) === 'on') {
                that[attr + "_"] = v;
                xhr[attr] = function (e) {
                    e = configEvent(e, that);
                    var ret = proxy[attr] && proxy[attr].call(that, xhr, e);
                    ret || v.call(that, e);
                };
            } else {
                //If the attribute isn't writable, generate proxy attribute
                var attrSetterHook = (hook || {})["setter"];
                v = attrSetterHook && attrSetterHook(v, that) || v;
                this[attr + "_"] = v;
                try {
                    // Not all attributes of xhr are writable(setter may undefined).
                    xhr[attr] = v;
                } catch (e) {}
            }
        };
    }

    // Hook methods of xhr.
    function hookFunction(fun) {
        return function () {
            var args = [].slice.call(arguments);
            if (proxy[fun]) {
                var ret = proxy[fun].call(this, args, this.xhr);
                // If the proxy return value exists, return it directly,
                // otherwise call the function of xhr.
                if (ret) return ret;
            }
            return this.xhr[fun].apply(this.xhr, args);
        };
    }

    // Return the real XMLHttpRequest
    return window[realXhr];
}

function unHook() {
    if (window[realXhr]) XMLHttpRequest = window[realXhr];
    window[realXhr] = undefined;
}

/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, "__esModule", {
    value: true
});
exports.proxy = proxy;
exports.unProxy = unProxy;

var _xhrHook = __webpack_require__(0);

var events = ['load', 'loadend', 'timeout', 'error', 'readystatechange', 'abort']; /*
                                                                                    * author: wendux
                                                                                    * email: [email protected]
                                                                                    * source code: https://github.com/wendux/Ajax-hook
                                                                                    */

var eventLoad = events[0],
    eventLoadEnd = events[1],
    eventTimeout = events[2],
    eventError = events[3],
    eventReadyStateChange = events[4],
    eventAbort = events[5];

var singleton,
    prototype = 'prototype';

function proxy(proxy) {
    if (singleton) throw "Proxy already exists";
    return singleton = new Proxy(proxy);
}

function unProxy() {
    singleton = null;
    (0, _xhrHook.unHook)();
}

function trim(str) {
    return str.replace(/^\s+|\s+$/g, '');
}

function getEventTarget(xhr) {
    return xhr.watcher || (xhr.watcher = document.createElement('a'));
}

function triggerListener(xhr, name) {
    var xhrProxy = xhr.getProxy();
    var callback = 'on' + name + '_';
    var event = (0, _xhrHook.configEvent)({ type: name }, xhrProxy);
    xhrProxy[callback] && xhrProxy[callback](event);
    var evt;
    if (typeof Event === 'function') {
        evt = new Event(name, { bubbles: false });
    } else {
        // https://stackoverflow.com/questions/27176983/dispatchevent-not-working-in-ie11
        evt = document.createEvent('Event');
        evt.initEvent(name, false, true);
    }
    getEventTarget(xhr).dispatchEvent(evt);
}

function Handler(xhr) {
    this.xhr = xhr;
    this.xhrProxy = xhr.getProxy();
}

Handler[prototype] = Object.create({
    resolve: function resolve(response) {
        var xhrProxy = this.xhrProxy;
        var xhr = this.xhr;
        xhrProxy.readyState = 4;
        xhr.resHeader = response.headers;
        xhrProxy.response = xhrProxy.responseText = response.response;
        xhrProxy.statusText = response.statusText;
        xhrProxy.status = response.status;
        triggerListener(xhr, eventReadyStateChange);
        triggerListener(xhr, eventLoad);
        triggerListener(xhr, eventLoadEnd);
    },
    reject: function reject(error) {
        this.xhrProxy.status = 0;
        triggerListener(this.xhr, error.type);
        triggerListener(this.xhr, eventLoadEnd);
    }
});

function makeHandler(next) {
    function sub(xhr) {
        Handler.call(this, xhr);
    }

    sub[prototype] = Object.create(Handler[prototype]);
    sub[prototype].next = next;
    return sub;
}

var RequestHandler = makeHandler(function (rq) {
    var xhr = this.xhr;
    rq = rq || xhr.config;
    xhr.withCredentials = rq.withCredentials;
    xhr.open(rq.method, rq.url, rq.async !== false, rq.user, rq.password);
    for (var key in rq.headers) {
        xhr.setRequestHeader(key, rq.headers[key]);
    }
    xhr.send(rq.body);
});

var ResponseHandler = makeHandler(function (response) {
    this.resolve(response);
});

var ErrorHandler = makeHandler(function (error) {
    this.reject(error);
});

function Proxy(proxy) {
    var onRequest = proxy.onRequest,
        onResponse = proxy.onResponse,
        onError = proxy.onError;

    function handleResponse(xhr, xhrProxy) {
        var handler = new ResponseHandler(xhr);
        if (!onResponse) return handler.resolve();
        var ret = {
            response: xhrProxy.response,
            status: xhrProxy.status,
            statusText: xhrProxy.statusText,
            config: xhr.config,
            headers: xhr.resHeader || xhr.getAllResponseHeaders().split('\r\n').reduce(function (ob, str) {
                if (str === "") return ob;
                var m = str.split(":");
                ob[m.shift()] = trim(m.join(':'));
                return ob;
            }, {})
        };
        onResponse(ret, handler);
    }

    function onerror(xhr, xhrProxy, e) {
        var handler = new ErrorHandler(xhr);
        var error = { config: xhr.config, error: e };
        if (onError) {
            onError(error, handler);
        } else {
            handler.next(error);
        }
    }

    function preventXhrProxyCallback() {
        return true;
    }

    function errorCallback(xhr, e) {
        onerror(xhr, this, e);
        return true;
    }

    function stateChangeCallback(xhr, xhrProxy) {
        if (xhr.readyState === 4 && xhr.status !== 0) {
            handleResponse(xhr, xhrProxy);
        } else if (xhr.readyState !== 4) {
            triggerListener(xhr, eventReadyStateChange);
        }
        return true;
    }

    return (0, _xhrHook.hook)({
        onload: preventXhrProxyCallback,
        onloadend: preventXhrProxyCallback,
        onerror: errorCallback,
        ontimeout: errorCallback,
        onabort: errorCallback,
        onreadystatechange: function onreadystatechange(xhr) {
            return stateChangeCallback(xhr, this);
        },
        open: function open(args, xhr) {
            var _this = this;
            var config = xhr.config = { headers: {} };
            config.method = args[0];
            config.url = args[1];
            config.async = args[2];
            config.user = args[3];
            config.password = args[4];
            config.xhr = xhr;
            var evName = 'on' + eventReadyStateChange;
            if (!xhr[evName]) {
                xhr[evName] = function () {
                    return stateChangeCallback(xhr, _this);
                };
            }

            var defaultErrorHandler = function defaultErrorHandler(e) {
                onerror(xhr, _this, (0, _xhrHook.configEvent)(e, _this));
            };
            [eventError, eventTimeout, eventAbort].forEach(function (e) {
                var event = 'on' + e;
                if (!xhr[event]) xhr[event] = defaultErrorHandler;
            });

            // 如果有请求拦截器,则在调用onRequest后再打开链接。因为onRequest最佳调用时机是在send前,
            // 所以我们在send拦截函数中再手动调用open,因此返回true阻止xhr.open调用。
            //
            // 如果没有请求拦截器,则不用阻断xhr.open调用
            if (onRequest) return true;
        },
        send: function send(args, xhr) {
            var config = xhr.config;
            config.withCredentials = xhr.withCredentials;
            config.body = args[0];
            if (onRequest) {
                // In 'onRequest', we may call XHR's event handler, such as `xhr.onload`.
                // However, XHR's event handler may not be set until xhr.send is called in
                // the user's code, so we use `setTimeout` to avoid this situation
                var req = function req() {
                    onRequest(config, new RequestHandler(xhr));
                };
                config.async === false ? req() : setTimeout(req);
                return true;
            }
        },
        setRequestHeader: function setRequestHeader(args, xhr) {
            // Collect request headers
            xhr.config.headers[args[0].toLowerCase()] = args[1];
            return true;
        },
        addEventListener: function addEventListener(args, xhr) {
            var _this = this;
            if (events.indexOf(args[0]) !== -1) {
                var handler = args[1];
                getEventTarget(xhr).addEventListener(args[0], function (e) {
                    var event = (0, _xhrHook.configEvent)(e, _this);
                    event.type = args[0];
                    event.isTrusted = true;
                    handler.call(_this, event);
                });
                return true;
            }
        },
        getAllResponseHeaders: function getAllResponseHeaders(_, xhr) {
            var headers = xhr.resHeader;
            if (headers) {
                var header = "";
                for (var key in headers) {
                    header += key + ': ' + headers[key] + '\r\n';
                }
                return header;
            }
        },
        getResponseHeader: function getResponseHeader(args, xhr) {
            var headers = xhr.resHeader;
            if (headers) {
                return headers[(args[0] || '').toLowerCase()];
            }
        }
    });
}

/***/ }),
/* 2 */,
/* 3 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ah = undefined;

var _xhrHook = __webpack_require__(0);

var _xhrProxy = __webpack_require__(1);

// ah(ajax hook)
/*
 * author: wendux
 * email: [email protected]
 * source code: https://github.com/wendux/Ajax-hook
 */

var ah = exports.ah = {
  proxy: _xhrProxy.proxy,
  unProxy: _xhrProxy.unProxy,
  hook: _xhrHook.hook,
  unHook: _xhrHook.unHook
};

/***/ })
/******/ ])));
ah.proxy({
    //请求发起前进入
    onRequest: (config, handler) => {
        handler.next(config);
    },
    //请求发生错误时进入,比如超时;注意,不包括http状态码错误,如404仍然会认为请求成功
    onError: (err, handler) => {
        console.log(err.type)
        handler.next(err)
    },
    //请求成功后进入
    onResponse: (response, handler) => {
        if (response.config.url == "/Student/ReadyForExam/GetPaperContent") {
            //各类正则匹配获取数据
            let finalArr = {}
            let obj = String(response.response).replace(/\\r\\n/g, "")
            let data = JSON.parse(obj).OtherDate
            let arrHtml = data.match(/<Question Type=(.*?)<\/Question>/g)

            for (const i in arrHtml) {
                try {
                    let qusArr = arrHtml[i].match(/<Describe>(.*?)<\/Describe>/)[0].match(/Text="(.*?)\"/g)
                    let quse = ""

                    let ans = arrHtml[i].match(/<StdAnswer>(.*?)<\/StdAnswer>/)[0].slice(11, -12)
                    for (const j in qusArr) {
                        quse += qusArr[j].replace(/ /g, "").slice(6, -1)
                    }
                    if (!finalArr[arrHtml[i].slice(16, 18)]) {
                        finalArr[arrHtml[i].slice(16, 18)] = []
                    }
                    finalArr[arrHtml[i].slice(16, 18)].push({
                        qusetion: quse,
                        answer: ans
                    })
                } catch {}
            }

            //需要延缓答案生成时间,保证答案被生成
            setTimeout(function () {
                for (const i in finalArr) {
                    //利用之前的finalArr搜索doc
                    let question = document.getElementById(i.toLowerCase())
                    for (let j = 0; j < question.childNodes.length; j = j + 2) {
                        let item = question.childNodes[j].childNodes[0]
                        let answerBox = question.childNodes[j].childNodes[1]
                        let lastSpan = item.getElementsByTagName("span")[item.getElementsByTagName("span").length - 1]
                        let aSpan = document.createElement("span")
                        let answer = finalArr[i][j / 2].answer

                        aSpan.style = "color: red;font-size: 16px;"
                        aSpan.innerHTML = answer
                        lastSpan.append(aSpan)

                        let inputBoxes
                        // 选择答案
                        switch (i) {
                                // 判断题
                            case 'TF':
                                inputBoxes = answerBox.getElementsByTagName('input')
                                inputBoxes[answer === '正确' ? 0 : 1].checked = true;
                                break
                                // 多选
                            case 'MS':
                                inputBoxes = answerBox.getElementsByTagName('input')
                                for (let k in inputBoxes) {
                                    if (answer.includes(inputBoxes[k].value)) {
                                        inputBoxes[k].checked = true
                                    }
                                }
                                break
                                // 单选
                            case 'SS':
                                inputBoxes = answerBox.getElementsByTagName('input')
                                for (let k of inputBoxes) {
                                    if (k.value === answer) {
                                        k.checked = true
                                        break
                                    }
                                }
                                break
                                // 填空
                            case 'BL':
                                inputBoxes = answerBox.getElementsByTagName('select')
                                const answers = answer.split(';')
                                for (let k in inputBoxes) {
                                    const selectValue = answers[k]
                                    for (const e in inputBoxes[k]) {
                                        const optionElement = inputBoxes[k][e]
                                        if (optionElement.value === selectValue) {
                                            optionElement.selected = true
                                            break
                                        }
                                    }
                                }
                                break
                            default:
                                break
                        }
                    }
                }
            }, 2000)
        }
        //拦截处理完数据发回给网页
        handler.next(response)
    }
})