您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
一键修改分数,一键获取答案。更多功能正在添加~
// ==UserScript== // @name 西柚英语辅助脚本 // @namespace [email protected] // @version 0.0.6 // @author Ravi // @description 一键修改分数,一键获取答案。更多功能正在添加~ // @license AGPL-3.0-only // @match https://student.xiyouyingyu.com/* // @require https://registry.npmmirror.com/vue/3.3.4/files/dist/vue.global.prod.js // @require data:application/javascript,%3Bwindow.Vue%3DVue%3B // @require https://registry.npmmirror.com/element-plus/2.4.4/files/dist/index.full.min.js // @resource element-plus/dist/index.css https://registry.npmmirror.com/element-plus/2.4.4/files/dist/index.css // @grant GM_addStyle // @grant GM_getResourceText // @grant unsafeWindow // @run-at document-start // ==/UserScript== (function (vue, ElementPlus) { 'use strict'; const d=new Set;const e = async e=>{d.has(e)||(d.add(e),(t=>{typeof GM_addStyle=="function"?GM_addStyle(t):document.head.appendChild(document.createElement("style")).append(t);})(e));}; e(" .side-blank[data-v-b5cc696d]{display:flex;flex-direction:column;margin-top:10px}.div-style[data-v-b5cc696d]{white-space:pre-line;overflow:auto;height:300px;color:#000}.side-blank[data-v-79925db6]{display:flex;flex-direction:column;margin-top:10px}.tip-text[data-v-79925db6]{padding-bottom:15px}.side-blank[data-v-96104ecd]{display:flex;flex-direction:column;margin-top:10px}.div-style[data-v-96104ecd]{white-space:pre-line;overflow:auto;height:300px;color:#000}.setting_blank[data-v-bd57d942]{display:flex;flex-direction:column;margin-top:10px} "); function processResponse(res, mode) { let answer = ""; if (mode === 1) { for (let i of res) { console.log(i); if (i["name"] !== "模仿朗读" || i["name"] !== "单词或句子朗读") { for (let question of i["smallList"]) { for (let process of question["processList"]) { if (process["name"] === "录音作答") { let question_text = JSON.parse(process["content"])["showTxt"]; let question_answer = String(process["oralTypeModel"]["answerTxt"]); question_answer = question_answer.replaceAll("<blockquote>", ""); question_answer = question_answer.replaceAll("</blockquote>", ""); answer += ` ${question_text} ${question_answer} `; } if (process["name"] === "选项勾选") { let data = JSON.parse(process["content"])["textModelList"]; for (let a of data) { if (a["showType"] === "3" || a["showType"] === "4") { for (let b of JSON.parse(a["showTxt"])) { let question_text = b["text"]; let question_answer = b["answer"]; answer += ` ${question_text} ${question_answer} `; } } if (a["showType"] === "5") { for (let b of JSON.parse(a["showTxt"])) { let question_text = b["text"]; let question_answer = b["answers"][0]; answer += ` ${question_text} ${question_answer} `; } } } } } } } } } if (mode === 2) { for (let i of res["titleList"]) { if (["单项选择", "重点词汇听写"].includes(i["questionsTypeName"])) { for (let question of i["writtenList"]) { let question_text = question["libList"][0]["titleType"]["text"]; let question_answer = question["libList"][0]["titleType"]["answer"]; answer += ` ${question_text} ${question_answer} `; } } } } return answer; } const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; const _sfc_main$3 = { data() { return { modifyDialogVisible: false, answerDialogVisible: false, score: 60, min: 0.7, max: 0.8 }; }, computed: { answer() { return localStorage.getItem(window.location.hash.split("&")[0].split("id=")[1]); } }, mounted() { if (localStorage.getItem("auto_modify_limit") !== null) { const data = JSON.parse(localStorage.getItem("auto_modify_limit")); this.score = data.score; this.min = data.min; this.max = data.max; } if (localStorage.getItem("modify_switch") == null) { localStorage.setItem("modify_switch", "false"); } if (localStorage.getItem("modify_switch") === "true") { document.getElementById("btn2").innerText = "禁用"; } else { document.getElementById("btn2").innerText = "启用"; } }, methods: { switch_mute: function() { const dom = document.querySelector("#app > div > div.paper-detail-container > div.content > div > div > div.substance > div > video"); dom.muted = dom.muted === false; if (document.getElementById("btn1").innerText === "开启") { document.getElementById("btn1").innerText = "关闭"; } else { document.getElementById("btn1").innerText = "开启"; } }, switch_modify: function() { if (document.getElementById("btn2").innerText === "启用") { document.getElementById("btn2").innerText = "禁用"; this.modifyDialogVisible = true; localStorage.setItem("modify_switch", "true"); } else { document.getElementById("btn2").innerText = "启用"; localStorage.setItem("modify_switch", "false"); ElementPlus.ElNotification({ title: "Success", duration: 2e3, message: "分数修改已禁用", type: "success" }); } }, setting: function() { const data = { score: this.score, min: this.min, max: this.max }; localStorage.setItem("auto_modify_limit", JSON.stringify(data)); this.modifyDialogVisible = false; ElementPlus.ElNotification({ title: "Success", duration: 2e3, message: "设置保存成功", type: "success" }); } } }; const _hoisted_1$3 = { class: "side-blank" }; const _hoisted_2$2 = { style: { "text-align": "center", "padding-top": "10px" } }; const _hoisted_3 = { class: "div-style" }; function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) { const _component_el_button = vue.resolveComponent("el-button"); const _component_el_input_number = vue.resolveComponent("el-input-number"); const _component_el_col = vue.resolveComponent("el-col"); const _component_el_row = vue.resolveComponent("el-row"); const _component_el_dialog = vue.resolveComponent("el-dialog"); return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, [ vue.createVNode(_component_el_button, { onClick: _cache[0] || (_cache[0] = ($event) => $data.answerDialogVisible = true) }, { default: vue.withCtx(() => [..._cache[9] || (_cache[9] = [ vue.createTextVNode(" 参考答案 ", -1) ])]), _: 1 }), _cache[17] || (_cache[17] = vue.createElementVNode("span", { style: { "text-align": "center" } }, "模仿朗读声音", -1)), vue.createVNode(_component_el_button, { id: "btn1", style: { "margin-left": "0", "margin-top": "5px" }, onClick: _cache[1] || (_cache[1] = ($event) => $options.switch_mute()) }, { default: vue.withCtx(() => [..._cache[10] || (_cache[10] = [ vue.createTextVNode(" 开启 ", -1) ])]), _: 1 }), _cache[18] || (_cache[18] = vue.createElementVNode("span", { style: { "text-align": "center" } }, "自动修改分数", -1)), vue.createVNode(_component_el_button, { id: "btn2", style: { "margin-left": "0", "margin-top": "5px" }, onClick: _cache[2] || (_cache[2] = ($event) => $options.switch_modify()) }, { default: vue.withCtx(() => [..._cache[11] || (_cache[11] = [ vue.createTextVNode(" 启用 ", -1) ])]), _: 1 }), vue.createVNode(_component_el_dialog, { modelValue: $data.modifyDialogVisible, "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => $data.modifyDialogVisible = $event), title: "设置", width: "40%", draggable: "", "align-center": "" }, { default: vue.withCtx(() => [ _cache[16] || (_cache[16] = vue.createElementVNode("div", { style: { "padding-bottom": "10px", "text-align": "center" } }, " 自动修改分数阈值 ", -1)), vue.createVNode(_component_el_row, null, { default: vue.withCtx(() => [ vue.createVNode(_component_el_col, { span: 8, style: { "text-align": "center" } }, { default: vue.withCtx(() => [ _cache[12] || (_cache[12] = vue.createElementVNode("div", null, " 启用修改阈值 ", -1)), vue.createVNode(_component_el_input_number, { modelValue: $data.score, "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $data.score = $event), precision: 2, step: 0.01, max: 100, "controls-position": "right" }, null, 8, ["modelValue"]) ]), _: 1 }), vue.createVNode(_component_el_col, { span: 8, style: { "text-align": "center" } }, { default: vue.withCtx(() => [ _cache[13] || (_cache[13] = vue.createElementVNode("div", null, "最低分数百分比", -1)), vue.createVNode(_component_el_input_number, { modelValue: $data.max, "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => $data.max = $event), precision: 1, step: 0.1, max: 1, "controls-position": "right" }, null, 8, ["modelValue"]) ]), _: 1 }), vue.createVNode(_component_el_col, { span: 8, style: { "text-align": "center" } }, { default: vue.withCtx(() => [ _cache[14] || (_cache[14] = vue.createElementVNode("div", null, " 最高分数百分比 ", -1)), vue.createVNode(_component_el_input_number, { modelValue: $data.min, "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => $data.min = $event), precision: 1, step: 0.1, max: 1, "controls-position": "right" }, null, 8, ["modelValue"]) ]), _: 1 }) ]), _: 1 }), vue.createElementVNode("div", _hoisted_2$2, [ vue.createVNode(_component_el_button, { onClick: _cache[6] || (_cache[6] = ($event) => $options.setting()) }, { default: vue.withCtx(() => [..._cache[15] || (_cache[15] = [ vue.createTextVNode(" 设定 ", -1) ])]), _: 1 }) ]) ]), _: 1 }, 8, ["modelValue"]), vue.createVNode(_component_el_dialog, { modelValue: $data.answerDialogVisible, "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => $data.answerDialogVisible = $event), title: "参考答案", width: "40%", draggable: "", "align-center": "" }, { default: vue.withCtx(() => [ vue.createElementVNode("div", _hoisted_3, vue.toDisplayString($options.answer), 1) ]), _: 1 }, 8, ["modelValue"]) ]); } const paper = _export_sfc(_sfc_main$3, [["render", _sfc_render$3], ["__scopeId", "data-v-b5cc696d"]]); function show_answer_for_paper() { if (localStorage.getItem(window.location.hash.split("&")[0].split("id=")[1]) === null) { alert("未找到答案,请重新进入当前页面"); } else { setTimeout(() => { vue.createApp(paper).use(ElementPlus).mount( (() => { const app = document.createElement("div"); document.querySelector("#app > div > div.slider").appendChild(app); return app; })() ); }, 1e3); } } const _sfc_main$2 = { data() { return { modifyDialogVisible: false, score: 60, min: 0.7, max: 0.8 }; }, mounted() { if (localStorage.getItem("auto_modify_limit") !== null) { const data = JSON.parse(localStorage.getItem("auto_modify_limit")); this.score = data.score; this.min = data.min; this.max = data.max; } if (localStorage.getItem("modify_switch") == null) { localStorage.setItem("modify_switch", "false"); } if (localStorage.getItem("modify_switch") === "true") { document.getElementById("btn2").innerText = "禁用"; } else { document.getElementById("btn2").innerText = "启用"; } }, methods: { switch_modify: function() { if (document.getElementById("btn2").innerText === "启用") { document.getElementById("btn2").innerText = "禁用"; this.modifyDialogVisible = true; localStorage.setItem("modify_switch", "true"); } else { document.getElementById("btn2").innerText = "启用"; localStorage.setItem("modify_switch", "false"); ElementPlus.ElNotification({ title: "Success", duration: 2e3, message: "分数修改已禁用", type: "success" }); } }, setting: function() { const data = { score: this.score, min: this.min, max: this.max }; localStorage.setItem("auto_modify_limit", JSON.stringify(data)); this.modifyDialogVisible = false; ElementPlus.ElNotification({ title: "Success", duration: 2e3, message: "设置保存成功", type: "success" }); } } }; const _hoisted_1$2 = { class: "side-blank" }; const _hoisted_2$1 = { style: { "text-align": "center", "padding-top": "10px" } }; function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) { const _component_el_button = vue.resolveComponent("el-button"); const _component_el_input_number = vue.resolveComponent("el-input-number"); const _component_el_col = vue.resolveComponent("el-col"); const _component_el_row = vue.resolveComponent("el-row"); const _component_el_dialog = vue.resolveComponent("el-dialog"); return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [ _cache[12] || (_cache[12] = vue.createElementVNode("span", { style: { "text-align": "center", "color": "black" } }, "自动修改分数", -1)), vue.createVNode(_component_el_button, { id: "btn2", style: { "margin-left": "0", "margin-top": "20px" }, onClick: _cache[0] || (_cache[0] = ($event) => $options.switch_modify()) }, { default: vue.withCtx(() => [..._cache[6] || (_cache[6] = [ vue.createTextVNode(" 启用 ", -1) ])]), _: 1 }), vue.createVNode(_component_el_dialog, { modelValue: $data.modifyDialogVisible, "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => $data.modifyDialogVisible = $event), title: "设置", width: "40%", draggable: "", "align-center": "" }, { default: vue.withCtx(() => [ _cache[11] || (_cache[11] = vue.createElementVNode("div", { style: { "padding-bottom": "25px", "text-align": "center" } }, " 自动修改分数阈值 ", -1)), vue.createVNode(_component_el_row, null, { default: vue.withCtx(() => [ vue.createVNode(_component_el_col, { span: 8, style: { "text-align": "center" } }, { default: vue.withCtx(() => [ _cache[7] || (_cache[7] = vue.createElementVNode("div", { class: "tip-text" }, " 启用修改阈值 ", -1)), vue.createVNode(_component_el_input_number, { modelValue: $data.score, "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.score = $event), precision: 2, step: 0.01, max: 100, "controls-position": "right" }, null, 8, ["modelValue"]) ]), _: 1 }), vue.createVNode(_component_el_col, { span: 8, style: { "text-align": "center" } }, { default: vue.withCtx(() => [ _cache[8] || (_cache[8] = vue.createElementVNode("div", { class: "tip-text" }, " 最低分数百分比 ", -1)), vue.createVNode(_component_el_input_number, { modelValue: $data.max, "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $data.max = $event), precision: 1, step: 0.1, max: 1, "controls-position": "right" }, null, 8, ["modelValue"]) ]), _: 1 }), vue.createVNode(_component_el_col, { span: 8, style: { "text-align": "center" } }, { default: vue.withCtx(() => [ _cache[9] || (_cache[9] = vue.createElementVNode("div", { class: "tip-text" }, " 最高分数百分比 ", -1)), vue.createVNode(_component_el_input_number, { modelValue: $data.min, "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $data.min = $event), precision: 1, step: 0.1, max: 1, "controls-position": "right" }, null, 8, ["modelValue"]) ]), _: 1 }) ]), _: 1 }), vue.createElementVNode("div", _hoisted_2$1, [ vue.createVNode(_component_el_button, { onClick: _cache[4] || (_cache[4] = ($event) => $options.setting()) }, { default: vue.withCtx(() => [..._cache[10] || (_cache[10] = [ vue.createTextVNode(" 设定 ", -1) ])]), _: 1 }) ]) ]), _: 1 }, 8, ["modelValue"]) ]); } const accent = _export_sfc(_sfc_main$2, [["render", _sfc_render$2], ["__scopeId", "data-v-79925db6"]]); function show_setting_for_accent() { setTimeout(() => { vue.createApp(accent).use(ElementPlus).mount( (() => { const app = document.createElement("div"); document.querySelector("#app > div > div.container > div.slider > ul").appendChild(app); return app; })() ); }, 1e3); } const _sfc_main$1 = { data() { return { answerDialogVisible: false }; }, computed: { answer() { return localStorage.getItem(window.location.hash.split("&")[0].split("id=")[1]); } } }; const _hoisted_1$1 = { class: "side-blank" }; const _hoisted_2 = { class: "div-style" }; function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) { const _component_el_button = vue.resolveComponent("el-button"); const _component_el_dialog = vue.resolveComponent("el-dialog"); return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [ vue.createVNode(_component_el_button, { onClick: _cache[0] || (_cache[0] = ($event) => $data.answerDialogVisible = true) }, { default: vue.withCtx(() => [..._cache[2] || (_cache[2] = [ vue.createTextVNode(" 参考答案 ", -1) ])]), _: 1 }), vue.createVNode(_component_el_dialog, { modelValue: $data.answerDialogVisible, "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.answerDialogVisible = $event), title: "参考答案", width: "40%", draggable: "", "align-center": "" }, { default: vue.withCtx(() => [ vue.createElementVNode("div", _hoisted_2, vue.toDisplayString($options.answer), 1) ]), _: 1 }, 8, ["modelValue"]) ]); } const written = _export_sfc(_sfc_main$1, [["render", _sfc_render$1], ["__scopeId", "data-v-96104ecd"]]); function show_answer_for_written() { if (localStorage.getItem(window.location.hash.split("&")[0].split("id=")[1]) === null) { alert("未找到答案,请重新进入当前页面"); } else { setTimeout(() => { vue.createApp(written).use(ElementPlus).mount( (() => { const app = document.createElement("div"); document.querySelector("#app > div > div.card > div.main").appendChild(app); return app; })() ); }, 1e3); } } const _sfc_main = { data() { return { score: 70 }; }, mounted() { if (localStorage.getItem("next_one_limit") !== null) { this.score = localStorage.getItem("next_one_limit"); } }, methods: { setting: function() { localStorage.setItem("next_one_limit", this.score); } } }; const _hoisted_1 = { class: "setting_blank" }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_el_input_number = vue.resolveComponent("el-input-number"); const _component_el_button = vue.resolveComponent("el-button"); return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ _cache[3] || (_cache[3] = vue.createElementVNode("span", { style: { "padding-bottom": "5px" } }, "设定自动下一个分数阈值", -1)), vue.createVNode(_component_el_input_number, { modelValue: $data.score, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.score = $event), precision: 2, step: 0.01, max: 100, "controls-position": "right" }, null, 8, ["modelValue"]), vue.createVNode(_component_el_button, { style: { "margin-top": "5px" }, onClick: _cache[1] || (_cache[1] = ($event) => $options.setting()) }, { default: vue.withCtx(() => [..._cache[2] || (_cache[2] = [ vue.createTextVNode(" 设定 ", -1) ])]), _: 1 }) ]); } const word = _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-bd57d942"]]); function show_answer_for_chooseTranslate(dict) { try { for (let index = 0; index < dict.data.length; index++) { const answer = dict["data"][index]["titleType"]["optionsTypeList"]; for (let i = 0; i < 4; i++) { if (answer[i]["answer"] === true) { console.log(answer[i]["text"]); } } } } catch (e) { try { const answers = deepsearch(dict, "textBookParaphrase"); for (let i = 0; i < answers.length; i++) { if (answers[i] !== null) { console.log(answers[i]); } } } catch (e2) { ElementPlus.ElNotification({ title: "Error", message: "答案解析失败,右键->检查->控制台 查看错误详情", type: "error" }); console.log(e2); console.log("脚本出现错误,请粘贴 downloadHAR() 到下方并回车"); console.log("将下载的 HAR 文件提交至 https://github.com/ravizhan/xiyou_crack/issues"); } } ElementPlus.ElNotification({ title: "Success", message: "答案解析成功,右键->检查->控制台 即可查看", type: "success" }); } function show_setting_for_word() { if (localStorage.getItem("next_one_limit") === "undefined") { localStorage.setItem("next_one_limit", "70.00"); } setTimeout(() => { vue.createApp(word).use(ElementPlus).mount( (() => { const app = document.createElement("div"); app.setAttribute("style", "text-align: center"); document.querySelector("#app > div > div.left-menu").appendChild(app); return app; })() ); }, 1e3); let old_score = null; setInterval(() => { const num = document.querySelector("#app > div > div.read-container > div.ant-spin-nested-loading > div > div > div.top > div:nth-child(1)").innerHTML.split("/")[0]; const score = document.querySelector("#app > div > div.read-container > div.ant-spin-nested-loading > div > div > div.ul > div:nth-child(" + num + ") > div.user > div > div.score"); if (score) { if (parseFloat(score.innerHTML) === old_score) { console.log("stop"); } else { if (parseFloat(score.innerHTML) >= localStorage.getItem("next_one_limit")) { old_score = parseFloat(score.innerHTML); console.log("next"); document.querySelector("#app > div > div.read-container > div.ant-spin-nested-loading > div > div > div.tool > div.right > div:nth-child(2)").click(); } } } }, 1e3); } function deepsearch(obj, column) { const results = []; function traverse(item) { if (item === null || typeof item !== "object") { return; } if (column in item) { results.push(item[column]); } for (const key in item) { if (item.hasOwnProperty(key)) { traverse(item[key]); } } } traverse(obj); return results; } class HARRecorder { constructor() { this.entries = []; this.startTime = ( new Date()).toISOString(); this.isRecording = false; } startRecording() { this.isRecording = true; this.entries = []; this.startTime = ( new Date()).toISOString(); console.log("HAR recording started"); } stopRecording() { this.isRecording = false; console.log("HAR recording stopped"); } recordRequest(method, url, requestHeaders, requestBody, status, responseHeaders, responseBody) { if (!this.isRecording) return; const startTime = ( new Date()).toISOString(); const entry = { startedDateTime: startTime, time: 100, request: { method, url, httpVersion: "HTTP/1.1", headers: this.formatHeaders(requestHeaders || {}), queryString: this.parseQueryString(url), headersSize: -1, bodySize: requestBody ? requestBody.length : 0 }, response: { status, statusText: "OK", httpVersion: "HTTP/1.1", headers: this.formatHeaders(responseHeaders || {}), content: { size: responseBody ? responseBody.length : 0, mimeType: "application/json", text: responseBody || "" }, headersSize: -1, bodySize: responseBody ? responseBody.length : 0 }, cache: {}, timings: { blocked: -1, dns: -1, connect: -1, send: 0, wait: 100, receive: 0, ssl: -1 }, pageref: "page_1" }; if (requestBody) { entry.request.postData = { mimeType: "application/x-www-form-urlencoded", text: requestBody }; } this.entries.push(entry); } formatHeaders(headers) { if (Array.isArray(headers)) return headers; return Object.keys(headers).map((name) => ({ name, value: headers[name] })); } parseQueryString(url) { try { const urlObj = new URL(url); const params = []; urlObj.searchParams.forEach((value, name) => { params.push({ name, value }); }); return params; } catch (e) { return []; } } generateHAR() { return JSON.stringify({ log: { version: "1.2", creator: { name: "Xiyou Crack HAR Recorder", version: "1.0" }, pages: [{ startedDateTime: this.startTime, id: "page_1", title: "Xiyou English App Requests", pageTimings: { onContentLoad: -1, onLoad: -1 } }], entries: this.entries } }, null, 2); } downloadHAR() { this.stopRecording(); const harData = this.generateHAR(); const blob = new Blob([harData], { type: "application/json" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `xiyou-requests-${( new Date()).toISOString().replace(/[:.]/g, "-")}.har`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); console.log("HAR file downloaded and recording stopped"); } getRecordedEntries() { return this.entries; } } const harRecorder = new HARRecorder(); harRecorder.startRecording(); console.log("HAR recording started automatically. Use downloadHAR() in console to stop and download."); window.downloadHAR = function() { harRecorder.downloadHAR(); }; var _GM_addStyle = (() => typeof GM_addStyle != "undefined" ? GM_addStyle : void 0)(); var _GM_getResourceText = (() => typeof GM_getResourceText != "undefined" ? GM_getResourceText : void 0)(); var _unsafeWindow = (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)(); const cssLoader = (e) => _GM_addStyle(_GM_getResourceText(e)); cssLoader("element-plus/dist/index.css"); const hash = window.location.hash; let old = history.pushState; history.pushState = function(...arg) { if (arg[2].includes("paperDetail")) { show_answer_for_paper(); } if (arg[2].includes("readingLoudly")) { show_setting_for_word(); } if (arg[2].includes("accentDetail")) { show_setting_for_accent(); } if (arg[2].includes("writtenDetail")) { show_answer_for_written(); } return old.call(this, ...arg); }; if (hash.includes("readingLoudly")) { show_setting_for_word(); } if (hash.includes("paperDetail")) { show_answer_for_paper(); } if (hash.includes("accentDetail")) { show_setting_for_accent(); } if (hash.includes("writtenDetail")) { show_answer_for_written(); } const originOpen = XMLHttpRequest.prototype.open; const oldSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.open = function(method, url) { this._url = url; this._method = method; this._requestHeaders = {}; const originalSetRequestHeader = this.setRequestHeader; this.setRequestHeader = function(name, value) { this._requestHeaders[name] = value; return originalSetRequestHeader.call(this, name, value); }; originOpen.apply(this, arguments); }; XMLHttpRequest.prototype.send = function(data) { const self = this; this.addEventListener("readystatechange", function() { if (this.readyState === 4) { harRecorder.recordRequest( self._method, self._url, self._requestHeaders, data, this.status, self.parseResponseHeaders(self.getAllResponseHeaders()), this.responseText ); if (self._method.toLowerCase() === "post") { try { if (self._url === "https://app.xiyouyingyu.com/paper/getPaperGroupById") { localStorage.setItem(data.split("groupId=")[1], processResponse(JSON.parse(this.responseText)["data"], 1)); } if (self._url === "https://app.xiyouyingyu.com/write/selectByPrimaryKey") { localStorage.setItem(data.split("examId=")[1], processResponse(JSON.parse(this.responseText)["data"], 2)); } if (self._url === "https://app.xiyouyingyu.com/word/findListByIds" || self._url === "https://app.xiyouyingyu.com/word/getWordPush") { show_answer_for_chooseTranslate(JSON.parse(this.responseText)); } if (self._url === "https://app.xiyouyingyu.com/entrance/moduleListNew") { const response = JSON.parse(this.responseText); if (Array.isArray(response["data"]["common"])) { for (let i = 0; i < response["data"]["common"].length; i++) { if (response["data"]["common"][i]["isLock"] === 1) { response["data"]["common"][i]["isLock"] = 0; } } } if (Array.isArray(response["data"]["special"])) { for (let i = 0; i < response["data"]["special"].length; i++) { if (response["data"]["special"][i]["isLock"] === 1) { response["data"]["special"][i]["isLock"] = 0; } } } Object.defineProperty(this, "responseText", { get: function() { return JSON.stringify(response); } }); } if (self._url === "https://app.xiyouyingyu.com/entrance/getModulesByPid") { const response = JSON.parse(this.responseText); for (let i = 0; i < response["moduleList"].length; i++) { if (response["moduleList"][i]["isLock"] === 1) { response["moduleList"][i]["isLock"] = 0; } } Object.defineProperty(this, "responseText", { get: function() { return JSON.stringify(response); } }); } if (self._url === "https://app.xiyouyingyu.com/paperAnswerCount/userPracticeInfo") { const response = JSON.parse(this.responseText); if (response["data"]["expire"] === "1") { response["data"]["expire"] = "0"; response["data"]["expireAt"] = "2099-12-31 23:59:59"; } Object.defineProperty(this, "responseText", { get: function() { return JSON.stringify(response); } }); } } catch (e) { ElementPlus.ElNotification({ title: "Error", message: "答案解析失败,右键->检查->控制台 查看错误详情", type: "error" }); console.log(e); console.log("脚本出现错误,请粘贴 downloadHAR() 到下方并回车"); console.log("将下载的 HAR 文件提交至 https://github.com/ravizhan/xiyou_crack/issues"); } } } }); oldSend.apply(this, arguments); }; XMLHttpRequest.prototype.parseResponseHeaders = function(headerStr) { const headers = {}; if (!headerStr) return headers; const headerPairs = headerStr.split("\r\n"); for (let i = 0; i < headerPairs.length; i++) { const headerPair = headerPairs[i]; const index = headerPair.indexOf(": "); if (index > 0) { const key = headerPair.substring(0, index); headers[key] = headerPair.substring(index + 2); } } return headers; }; const originSocket = _unsafeWindow.WebSocket; _unsafeWindow.WebSocket = function(...args) { let callback = void 0; const ws = new originSocket(...args); ws.onmessage = function(evt) { const proxyEvent = new Proxy(evt, { get: function(target, prop) { let data = target[prop]; if (prop === "data") { data = JSON.parse(data); if (JSON.stringify(data).includes("tokenId") && localStorage.getItem("modify_switch") === "true") { let auto_modify_limit = JSON.parse(localStorage.getItem("auto_modify_limit")); const old2 = data["result"]["overall"]; const min = data["result"]["rank"] * auto_modify_limit["min"]; const max = data["result"]["rank"] * auto_modify_limit["max"]; if (old2 > auto_modify_limit["score"]) { return JSON.stringify(data); } data["result"]["overall"] = (Math.random() * (max - min) + min).toPrecision(2); console.log("分数修改成功\n修改前: " + old2.toString() + "\n修改后: " + data["result"]["overall"].toString()); ElementPlus.ElNotification({ title: "Success", duration: 3e3, message: "分数修改成功\n修改前: " + old2.toString() + "\n修改后: " + data["result"]["overall"].toString(), type: "success" }); return JSON.stringify(data); } return JSON.stringify(data); } return JSON.stringify(data); } }); callback && callback(proxyEvent); }; Object.defineProperty(ws, "onmessage", { get: () => { return callback; }, set: (setCall) => { callback = setCall; } }); return ws; }; window.harRecorder = harRecorder; })(Vue, ElementPlus);