// ==UserScript==
// @name 【FLY】智慧树知道网课辅助[稳妥版]
// @namespace wyn665817 & Shadow
// @version 2.5.3
// @description 【最新版】,章测试和考试支持自动答题,视频自动倍速播放、线路选择、默认静音等,解除各类功能限制,开放自定义参数 ,稳定性未知!!建议夜深人静时悄悄食用
// @author wyn665817 & Shadow
// @match *://*.zhihuishu.com/*
// @match *://*.zhihuishu.com/videoStudy*
// @match *://*.zhihuishu.com/portals_h5*
// @match *://*.zhihuishu.com/live*
// @match *://*.zhihuishu.com/examh5*
// @match *://*.zhihuishu.com/live/vod_room*
// @match *://*.zhihuishu.com/stuExamWeb*
// @connect up.026wk.xyz
// @connect aa.6hck.xyz
// @run-at document-start
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @grant GM_getResourceText
// @grant GM_setClipboard
// @grant GM_setValue
// @grant GM_getValue
// @resource css https://unpkg.com/bulma@0.9.4/css/bulma.min.css
// @resource css https://unpkg.com/bootstrap@3.3.7/dist/css/bootstrap.min.css
// @license MIT
// @antifeature ads
// ==/UserScript==
const qrCode = ``;
enableWebpackHook();
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const config = {
awaitTime: 5000,
stopTimer: false,
questionCount: 0,
finishCount: 0,
questionType: {
'判断题': 10,
'单选题': 20,
'多选题': 25,
'填空题': 30,
'问答题': 40,
},
apiKey: GM_getValue('apiKey', '') // 获取保存的 API Key
};
function answerQuestion(questionBody, questionIndex) {
const questionTitle = questionBody.querySelector('.subject_describe div,.smallStem_describe p').__Ivue__._data.shadowDom.textContent;
appendToTable(questionTitle, "", questionIndex);
const questionType = questionBody.querySelector(".subject_type").innerText.match(/【(.+)】|$/)[1];
let type = config.questionType[questionType];
type = type !== undefined ? type : -1;
GM_xmlhttpRequest({
method: "GET",
url: `https://up.026wk.xyz/tkapi4.php?question=${encodeURIComponent(questionTitle)}${config.apiKey ? `&key=${config.apiKey}` : ''}`,
onload: xhr => {
const res = JSON.parse(xhr.responseText);
const msg = res.msg;
let answerString = res.answer;
const displayMsg = res.msgs;
// Get the msgs parameter from the API response
updateMsg(displayMsg); // Update the floating window with the msgs content
if (msg === "暂无答案") {
answerString = "暂无答案";
changeAnswerInTable(answerString, questionIndex, true);
} else {
const isSelect = chooseAnswer(type, questionBody, answerString);
changeAnswerInTable(answerString, questionIndex, isSelect);
}
document.querySelectorAll('.switch-btn-box > button')[1].click();
},
onerror: err => console.log(err)
});
}
function chooseAnswer(questionType, questionBody, answerString) {
let isSelect = false;
const answers = answerString.split(/[\u0001,#,=,===,;,---]+/).map(a => a.trim()).filter(Boolean);
if (questionType === 10) { // 判断题
const firstOptionText = questionBody.querySelector(".node_detail");
const firstOption = questionBody.querySelector(".nodeLab");
const correctAnswer = /(^|,)(正确|是|对|√|T|ri|right|true)(,|$)/.test(firstOptionText.innerText);
const givenAnswer = /(^|,)(正确|是|对|√|T|ri|right|true)(,|$)/.test(answerString);
(correctAnswer === givenAnswer ? firstOption : questionBody.querySelectorAll(".nodeLab")[1]).click();
isSelect = true;
}
if (questionType === 20) { // 单选题
const regexPattern = new RegExp("^(" + answerString + ")$");
questionBody.querySelectorAll(".node_detail").forEach((option, i) => {
if (regexPattern.test(option.innerText)) {
questionBody.querySelectorAll(".nodeLab")[i].click();
isSelect = true;
}
});
}
if (questionType === 25) { // 多选题
questionBody.querySelectorAll(".node_detail").forEach((option, i) => {
if (answers.includes(option.innerText.trim())) {
questionBody.querySelectorAll(".nodeLab")[i].click();
isSelect = true;
}
});
}
if (questionType === 30) { // 填空题
const blanks = questionBody.querySelectorAll(".blankInput");
answers.forEach((answer, i) => {
if (answer) {
blanks[i].value = answer;
isSelect = true;
}
});
}
if (questionType === 40) { // 问答题
const answerArea = questionBody.querySelector("textarea");
if (answerArea) {
answerArea.value = answerString;
isSelect = true;
}
}
return isSelect;
}
function appendToTable(questionTitle, answerString, questionIndex) {
const table = document.querySelector("#record-table tbody");
table.innerHTML += `<tr><td>${questionIndex}</td><td>${questionTitle}</td><td id="answer${questionIndex}">正在搜索...</td></tr>`;
}
function changeAnswerInTable(answerString, questionIndex, isSelect) {
const answerCell = document.querySelector(`#answer${questionIndex}`);
answerCell.innerHTML = answerString;
if (answerString === "暂无答案") {
answerCell.insertAdjacentHTML('beforeend', `<p style="color:red">扫码关注公众号防止失联反馈交流群348740961</p>`);
}
if (!isSelect) {
answerCell.insertAdjacentHTML('beforeend', `<p style="color:red">未匹配答案,请根据搜索结果手动选择答案</p>`);
}
}
function enableWebpackHook() {
const originCall = Function.prototype.call;
Function.prototype.call = function (...args) {
const result = originCall.apply(this, args);
if (args[2]?.default?.version === '2.5.2') {
args[2]?.default?.mixin({
mounted: function () {
this.$el['__Ivue__'] = this;
}
});
}
return result;
}
}
function makeElementDraggable(el) {
el.style.position = 'absolute';
el.onmousedown = function (event) {
let shiftX = event.clientX - el.getBoundingClientRect().left;
let shiftY = event.clientY - el.getBoundingClientRect().top;
function moveAt(pageX, pageY) {
el.style.left = pageX - shiftX + 'px';
el.style.top = pageY - shiftY + 'px';
}
function onMouseMove(event) {
moveAt(event.pageX, event.pageY);
}
document.addEventListener('mousemove', onMouseMove);
el.onmouseup = function () {
document.removeEventListener('mousemove', onMouseMove);
el.onmouseup = null;
};
};
el.ondragstart = function () {
return false;
};
}
function updateMsg(msg) {
document.getElementById('display-msg').innerText = msg;
}
function saveApiKey() {
const apiKeyInput = document.getElementById('api-key-input');
const newApiKey = apiKeyInput.value.trim();
if (newApiKey) {
GM_setValue('apiKey', newApiKey);
config.apiKey = newApiKey; // Update the local config as well
}
}
function clearApiKey() {
GM_setValue('apiKey', '');
config.apiKey = ''; // Clear the local config as well
document.getElementById('api-key-input').value = ''; // Clear the input field
}
unsafeWindow.onload = (() => (async () => {
GM_addStyle(GM_getResourceText("css"));
const cssStyle = `
<div id="floating-window" class="modal is-active" style="display: block;width: 420px; height: 550px;">
<div class="modal-card" style="width: 100%; height: 100%;">
<header class="modal-card-head">
<p class="modal-card-title">智慧树小助手</p>
<button class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
<div class="field">
<label class="label">API Key</label>
<div class="control">
<input class="input" id="api-key-input" type="text" placeholder="请输入API Key" value="${config.apiKey}">
<button class="button is-primary" id="save-api-key-btn">保存</button>
<button class="button is-danger" id="clear-api-key-btn">清除</button>
</div>
</div>
<div id="qr-code" class="has-text-centered"></div>
<div class="content has-text-centered">扫码关注公众号防止失联</div>
<div id="display-msg" class="content"></div>
<div class="content">
<table class="table is-bordered is-striped is-narrow" id="record-table">
<thead>
<tr>
<th>#</th>
<th>题目</th>
<th>答案</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</section>
</div>
</div>`;
document.body.insertAdjacentHTML('beforeend', cssStyle);
makeElementDraggable(document.getElementById('floating-window'));
const img = new Image();
img.src = "http://up.026wk.xyz/12.png";
img.width = 200;
img.height = 200;
document.querySelector("#qr-code").appendChild(img);
// Save API Key button event listener
document.getElementById('save-api-key-btn').addEventListener('click', saveApiKey);
// Clear API Key button event listener
document.getElementById('clear-api-key-btn').addEventListener('click', clearApiKey);
await sleep(config.awaitTime);
const questionBodyAll = document.querySelectorAll(".examPaper_subject.mt20");
if (questionBodyAll.length === 0) return;
config.questionCount = questionBodyAll.length;
answerQuestion(questionBodyAll[0], 1);
let finishCount = 1;
const interval = setInterval(() => {
if (finishCount < questionBodyAll.length) {
answerQuestion(questionBodyAll[finishCount], finishCount + 1);
finishCount += 1;
} else {
clearInterval(interval);
}
}, 3000);
}))();