// ==UserScript==
// @name 知到智慧树全自动刷问答平时分助手
// @version 1.0.5(务必更新此版本)
// @namespace http://fenda.github.io/
// @description 全自动刷智慧树问答,自动提交,自动刷新,自动跳转,自动关闭,自动通知
// @author fenda
// @match https://qah5.zhihuishu.com/qa.html
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_notification
// @grant GM_registerMenuCommand
// @license MIT
// ==/UserScript==
(function () {
'use strict';
const defaultAPIKey = "sk-zt3dcYmk8D4FECtgDa7427F7E71444B589D6FbD6CcC44b30";
const defaultAPIUrl = "https://api.gpt.ge/v1/chat/completions";
const defaultModel = "glm-4-flash";
const intervalTime = GM_getValue("intervalTime", 2000);
const initialCountdownTime = GM_getValue("countdownTime", 20);
let requestLock = false;
let noAnswerButtonCount = 0;
let countdownInterval;
const inputEvent = new Event("input", { bubbles: true, cancelable: true });
function debounce(fn, delay) {
let timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(() => fn.apply(this, arguments), delay);
};
}
function initMutationObserver() {
const debouncedUpdate = debounce(() => {
console.log("DOM 变化检测到,更新问题列表...");
addQuestionStatus();
checkHomeRegex();
}, 500);
const observer = new MutationObserver(debouncedUpdate);
const config = { attributes: true, childList: true, subtree: true };
observer.observe(document.body, config);
console.log("MutationObserver 已启动,正在监听 DOM 变化...");
}
function createQuestionManagementModal() {
const modal = document.createElement('div');
modal.className = 'question-management-modal';
modal.style = `
position: fixed;
top: 50px;
left: 5%;
width: 90%;
height: 80%;
background: linear-gradient(145deg, #ffffff, #e6e6e6);
box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.1);
border-radius: 15px;
z-index: 1000;
padding: 20px;
overflow: auto;
`;
const questionsData = GM_getValue("questionsData", {});
const lastViewedCourseIndex = GM_getValue("lastViewedCourseIndex", 0);
const coursetabs = document.createElement('div');
coursetabs.style = `
display: flex;
justify-content: center;
margin-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
`;
const contentArea = document.createElement('div');
Object.keys(questionsData).forEach((courseName, index) => {
const courseTab = document.createElement('div');
courseTab.textContent = courseName;
courseTab.style = `
padding: 10px 15px;
cursor: pointer;
background: ${index === lastViewedCourseIndex ? 'linear-gradient(145deg, #4c88d6, #3b5998)' : 'transparent'};
color: ${index === lastViewedCourseIndex ? 'white' : 'black'};
border-radius: 5px 5px 0 0;
margin-right: 5px;
`;
const courseTable = document.createElement('div');
courseTable.style = `
display: ${index === lastViewedCourseIndex ? 'block' : 'none'};
width: 100%;
`;
const table = document.createElement('table');
table.style = `
width: 100%;
border-collapse: collapse;
`;
table.innerHTML = `
<thead>
<tr style="background: linear-gradient(145deg, #4c88d6, #3b5998); color: white;">
<th style="padding: 10px; text-align: left;">题目
<input type="text" placeholder="搜索..." class="filter-input" style="margin-left: 5px; padding: 3px; border-radius: 5px; border: 1px solid #ccc; color: black;">
</th>
<th style="padding: 10px; text-align: center;">状态</th>
<th style="padding: 10px; text-align: center;">操作</th>
</tr>
</thead>
<tbody>
${Object.entries(questionsData[courseName]).map(([question, status]) => `
<tr data-question="${question}">
<td style="padding: 10px; border-bottom: 1px solid #e0e0e0; white-space: normal; word-break: break-word;">${question}</td>
<td style="padding: 10px; border-bottom: 1px solid #e0e0e0; text-align: center; color: ${status === '已回答' ? 'green' : 'red'}; white-space: nowrap;">
${status}
</td>
<td style="padding: 10px; border-bottom: 1px solid #e0e0e0; text-align: center; white-space: nowrap;">
<button class="set-answered" data-course="${courseName}" data-question="${question}" style="
margin-right: 5px;
padding: 5px 10px;
background: green;
color: white;
border: none;
border-radius: 5px;
">设为已答</button>
<button class="set-unanswered" data-course="${courseName}" data-question="${question}" style="
padding: 5px 10px;
background: red;
color: white;
border: none;
border-radius: 5px;
">设为未答</button>
</td>
</tr>
`).join('')}
</tbody>
`;
table.querySelector('.filter-input').addEventListener('input', function() {
const filterValue = this.value.toLowerCase();
table.querySelectorAll('tbody tr').forEach(row => {
row.style.display = row.getAttribute('data-question').toLowerCase().includes(filterValue) ? '' : 'none';
});
});
table.addEventListener('click', function(event) {
const target = event.target;
const courseName = target.dataset.course;
const question = target.dataset.question;
const questionsData = GM_getValue("questionsData", {});
if (target.classList.contains('set-answered')) {
questionsData[courseName][question] = '已回答';
GM_setValue("questionsData", questionsData);
refreshQuestionManagementModal();
}
if (target.classList.contains('set-unanswered')) {
questionsData[courseName][question] = '未回答';
GM_setValue("questionsData", questionsData);
refreshQuestionManagementModal();
}
});
courseTable.appendChild(table);
courseTab.addEventListener('click', () => {
Array.from(coursetabs.children).forEach((tab, idx) => {
tab.style.background = 'transparent';
tab.style.color = 'black';
contentArea.children[idx].style.display = 'none';
});
courseTab.style.background = 'linear-gradient(145deg, #4c88d6, #3b5998)';
courseTab.style.color = 'white';
courseTable.style.display = 'block';
GM_setValue("lastViewedCourseIndex", index);
});
courseTab.setAttribute('data-course', courseName);
coursetabs.appendChild(courseTab);
contentArea.appendChild(courseTable);
});
const closeButton = document.createElement('button');
closeButton.textContent = '关闭';
closeButton.style = `
position: absolute;
top: 10px;
right: 10px;
padding: 5px 10px;
background: red;
color: white;
border: none;
border-radius: 5px;
`;
closeButton.addEventListener('click', () => modal.remove());
modal.appendChild(coursetabs);
modal.appendChild(contentArea);
modal.appendChild(closeButton);
document.body.appendChild(modal);
}
function refreshQuestionManagementModal() {
const scrollTop = document.querySelector('.question-management-modal').scrollTop;
const existingModal = document.querySelector('.question-management-modal');
if (existingModal) {
existingModal.remove();
}
createQuestionManagementModal();
document.querySelector('.question-management-modal').scrollTop = scrollTop;
}
function displayCountdown(countdown) {
let participatoryDiv = document.querySelector('.MyParticipatory-div');
let countdownElement = document.querySelector('.new-neumorphic-card');
const linkClicked = GM_getValue("linkClicked", false);
if (participatoryDiv) {
if (!countdownElement) {
countdownElement = document.createElement('div');
countdownElement.className = 'new-neumorphic-card';
countdownElement.style = `
padding: 15px;
border-radius: 15px;
background: linear-gradient(145deg, #ffffff, #e6e6e6);
box-shadow: 6px 6px 12px #aaaaaa,
-6px -6px 12px #ffffff;
display: inline-block;
max-width: 300px;
`;
participatoryDiv.parentElement.appendChild(countdownElement);
countdownElement.innerHTML = `
<div class="Participatorytitle-div" style="white-space: normal; overflow-wrap: break-word; display: flex; flex-direction: column;">
<div style="margin-bottom: 10px; font-weight: bold;">倒计时
<i class="el-tooltip item" tabindex="0"
style="margin-left: 4px; cursor: pointer; position: relative;" id="infoIcon">
ℹ️
</i>
<span style="margin-left: 10px; white-space: nowrap;">${countdown} 秒</span>
</div>
${!linkClicked ? `<a href="#" id="purchaseLink" target="_blank" style="margin-top: 10px; text-decoration: none; color: #0066cc;">注册购买API(非作者运营勿找,点击后刷新不再显示)</a>` : ''}
<div style="display: flex; flex-direction: column; align-items: start; margin-top: 10px;">
<label style="margin-bottom: 15px; display: flex; align-items: center; white-space: nowrap;">API_KEY:
<input type="text" id="apiKeyInput" style="
margin-left: 10px;
width: 100%;
padding: 10px;
border-radius: 10px;
border: none;
outline: none;
background: linear-gradient(145deg, #e6e6e6, #ffffff);
box-shadow: inset 3px 3px 6px #cccccc,
inset -3px -3px 6px #ffffff;
">
</label>
<label style="margin-bottom: 15px; display: flex; align-items: center; white-space: nowrap;">API_URL:
<input type="text" id="apiUrlInput" style="
margin-left: 10px;
width: 100%;
padding: 10px;
border-radius: 10px;
border: none;
outline: none;
background: linear-gradient(145deg, #e6e6e6, #ffffff);
box-shadow: inset 3px 3px 6px #cccccc,
inset -3px -3px 6px #ffffff;
">
</label>
<label style="margin-bottom: 15px; display: flex; align-items: center; white-space: nowrap;">倒计时范围:
<input type="number" id="countdownMinInput" style="
margin-left: 10px;
padding: 10px;
border-radius: 10px;
border: none;
outline: none;
width: 48%;
background: linear-gradient(145deg, #e6e6e6, #ffffff);
box-shadow: inset 3px 3px 6px #cccccc,
inset -3px -3px 6px #ffffff;"
placeholder="最小值">
<input type="number" id="countdownMaxInput" style="
margin-left: 10px;
padding: 10px;
border-radius: 10px;
border: none;
outline: none;
width: 48%;
background: linear-gradient(145deg, #e6e6e6, #ffffff);
box-shadow: inset 3px 3px 6px #cccccc,
inset -3px -3px 6px #ffffff;"
placeholder="最大值">
</label>
<label style="display: flex; align-items: center; white-space: nowrap;">模型:
<input type="text" id="modelInput" style="
margin-left: 10px;
width: 100%;
padding: 10px;
border-radius: 10px;
border: none;
outline: none;
background: linear-gradient(145deg, #e6e6e6, #ffffff);
box-shadow: inset 3px 3px 6px #cccccc,
inset -3px -3px 6px #ffffff;
">
</label>
</div>
<div style="margin-top: 15px; text-align: right;">
<button id="saveButton" style="
padding: 10px 20px;
border: none;
border-radius: 10px;
background: linear-gradient(145deg, #4c88d6, #3b5998);
box-shadow: 3px 3px 6px #2f4686, -3px -3px 6px #507bcf;
color: white;
font-weight: bold;
cursor: pointer;
">保存</button>
</div>
<div style="margin-top: 20px; text-align: center; font-size: 12px; color: #666;">
<span>当前版本:1.0.5(最新:</span><span id="latestVersion">加载中...</span><span>)</span>
</div>
</div>
`;
const manageButton = document.createElement('button');
manageButton.textContent = '管理答题列表';
manageButton.style = `
margin-right: 10px;
padding: 10px 20px;
border: none;
border-radius: 10px;
background: linear-gradient(145deg, #4c88d6, #3b5998);
box-shadow: 3px 3px 6px #2f4686, -3px -3px 6px #507bcf;
color: white;
font-weight: bold;
cursor: pointer;
`;
manageButton.addEventListener('click', createQuestionManagementModal);
const saveButtonContainer = countdownElement.querySelector('div[style*="text-align: right"]');
saveButtonContainer.insertBefore(manageButton, saveButtonContainer.firstChild);
document.getElementById("apiKeyInput").value = GM_getValue("API_KEY", defaultAPIKey);
document.getElementById("apiUrlInput").value = GM_getValue("API_URL", defaultAPIUrl);
document.getElementById("countdownMinInput").value = GM_getValue("countdownMin", 20);
document.getElementById("countdownMaxInput").value = GM_getValue("countdownMax", 30);
document.getElementById("modelInput").value = GM_getValue("aimodel", defaultModel);
document.getElementById("saveButton").addEventListener('click', function() {
GM_setValue("API_KEY", document.getElementById("apiKeyInput").value);
GM_setValue("API_URL", document.getElementById("apiUrlInput").value);
GM_setValue("countdownMin", parseInt(document.getElementById("countdownMinInput").value));
GM_setValue("countdownMax", parseInt(document.getElementById("countdownMaxInput").value));
GM_setValue("aimodel", document.getElementById("modelInput").value);
alert('设置已保存');
});
checkForLatestVersion();
if (!linkClicked) {
document.getElementById("purchaseLink").addEventListener('click', function(event) {
event.preventDefault();
GM_setValue("linkClicked", true);
window.open("https://api.v3.cm/register?aff=25L7", "_blank");
});
}
const infoIcon = document.getElementById("infoIcon");
infoIcon.addEventListener("mouseenter", function() {
const tooltip = document.createElement('div');
tooltip.id = 'tooltip';
tooltip.style = `
position: absolute;
top: 25px;
left: 0;
background: #333;
color: #fff;
padding: 8px;
border-radius: 5px;
font-size: 12px;
white-space: pre-wrap;
width: 200px;
height: auto;
z-index: 1000;
box-sizing: border-box;
overflow: hidden;
`;
tooltip.innerText = `1.由于答题太快会导致被禁言,故倒计时不要太低。\n2.作者提供的API仅供测试,没有多少量,请勿大量使用。请在试用脚本有效后立刻点击链接购买API。\n3.此API用完作者不会去补充,请为后面想使用的人考虑!\n4.被屏蔽的问题会显示下划线,未回答问题显示红色,回答过显示黑色。\n5.重要信息;考虑到一些原因,只自动回答页面中的问题,也就是说回答完本页问题后,需要手动加载下一页,或者你可以直接提前加载下一页(一页50题目)。`;
infoIcon.appendChild(tooltip);
});
infoIcon.addEventListener("mouseleave", function() {
const tooltip = document.getElementById('tooltip');
if (tooltip) tooltip.remove();
});
} else {
countdownElement.querySelector('.Participatorytitle-div div span').innerText = `${countdown} 秒`;
}
}
}
function checkForLatestVersion() {
const lastChecked = GM_getValue("lastVersionCheck", 0);
const currentTime = new Date().getTime();
const oneHourMillis = 60 * 60 * 1000;
let retryAttempts = 0;
const maxRetries = 5;
const retryDelay = 1000;
function requestVersion() {
GM_xmlhttpRequest({
method: "GET",
url: "https://update.greasyfork.org/scripts/519662/知到智慧树全自动刷问答平时分助手.meta.js",
onload: function(response) {
const match = response.responseText.match(/@version\s+([\d.]+)/);
if (match) {
const latestVersion = match[1];
GM_setValue("lastVersionCheck", currentTime);
GM_setValue("lastCheckedVersion", latestVersion);
document.getElementById("latestVersion").innerText = latestVersion;
} else {
if (retryAttempts < maxRetries) {
retryAttempts++;
setTimeout(requestVersion, retryDelay);
} else {
document.getElementById("latestVersion").innerText = "获取失败";
}
}
}
});
}
if (currentTime - lastChecked > oneHourMillis) {
requestVersion();
} else {
const lastCheckedVersion = GM_getValue("lastCheckedVersion", "未检测");
document.getElementById("latestVersion").innerText = lastCheckedVersion;
}
}
function startCountdown(restartCount = null) {
if (countdownInterval) {
clearInterval(countdownInterval);
}
const minTime = GM_getValue("countdownMin", 20);
const maxTime = GM_getValue("countdownMax", 30);
let countdown = restartCount !== null
? restartCount
: Math.floor(Math.random() * ((maxTime + 1) - minTime)) + minTime;
GM_setValue("countdownTime", countdown);
displayCountdown(countdown);
countdownInterval = setInterval(() => {
countdown--;
displayCountdown(countdown);
if (countdown <= 0) {
clearInterval(countdownInterval);
countdownInterval = null;
console.log(`${GM_getValue("countdownTime", initialCountdownTime)}秒已过,点击动作触发。`);
scrollToUnansweredQuestions();
startCountdown();
}
}, 1000);
}
function checkHomeRegex() {
const homePattern = /^https:\/\/qah5\.zhihuishu\.com\/qa\.html#\/web\/home/;
const currentURL = window.location.href;
if (homePattern.test(currentURL)) {
console.log("正在获取问题列表...");
const items = document.querySelectorAll(".question-item .question-content span");
const courseNameElement = document.querySelector(".course-name");
if (courseNameElement && items.length) {
const courseName = courseNameElement.innerText.trim();
let questionsData = GM_getValue("questionsData", {});
if (!questionsData[courseName]) {
questionsData[courseName] = {};
}
items.forEach(item => {
const questionTitle = item.getAttribute("title").trim();
if (!questionsData[courseName][questionTitle]) {
questionsData[courseName][questionTitle] = "未回答";
}
});
GM_setValue("questionsData", questionsData);
console.log("问题列表已更新:", questionsData);
}
}
}
function markQuestionAsAnswered(questionText) {
const courseNameElement = document.querySelector(".course-name");
if (courseNameElement) {
const courseName = courseNameElement.innerText.trim();
let questionsData = GM_getValue("questionsData", {});
if (questionsData[courseName] && questionsData[courseName][questionText] === "未回答") {
questionsData[courseName][questionText] = "已回答";
GM_setValue("questionsData", questionsData);
console.log(`问题“${questionText}”状态已更新为“已回答”。`);
}
}
}
function waitForAnswerButton() {
console.log("正在检测‘我来回答’按钮...");
const answerButton = document.querySelector("div.my-answer-btn.ZHIHUISHU_QZMD.tool-show span");
if (answerButton && answerButton.textContent.trim() === "我来回答") {
console.log("找到‘我来回答’按钮,点击...");
answerButton.click();
noAnswerButtonCount = 0;
setTimeout(() => {
const inputElement = document.querySelector("textarea");
if (inputElement) {
console.log("文本框已出现,准备回答问题...");
startChecking();
} else {
console.log("文本框未出现,继续检测‘我来回答’按钮...");
waitForAnswerButton();
}
}, intervalTime);
} else {
checkHomeRegex();
console.log("未找到‘我来回答’按钮或按钮状态不符合条件,稍后重试...");
noAnswerButtonCount++;
const currentURL = window.location.href;
const pattern = /^https:\/\/qah5\.zhihuishu\.com\/qa\.html#\/web\/questionDetail\/\d+/;
if (noAnswerButtonCount >= 3) {
if (pattern.test(currentURL)) {
const questionElement = document.querySelector(".question-content span");
const questionText = questionElement ? questionElement.innerText.trim() : '';
if (questionText) {
markQuestionAsAnswered(questionText);
}
console.log("当前页面符合特定模式,关闭网页...");
window.close();
} else {
console.log("当前页面不符合关闭条件,继续检测...");
noAnswerButtonCount = 0;
}
} else {
setTimeout(waitForAnswerButton, intervalTime);
}
}
}
function addQuestionStatus() {
const questionItems = document.querySelectorAll('.question-item');
questionItems.forEach(item => {
const spanElement = item.querySelector('.question-content span');
const questionText = spanElement ? spanElement.title.trim() : '';
if (questionText) {
const courseNameElement = document.querySelector(".course-name");
if (courseNameElement) {
const courseName = courseNameElement.innerText.trim();
let status = "未获取";
const questionsData = GM_getValue("questionsData", {});
if (questionsData[courseName] && questionsData[courseName][questionText]) {
status = questionsData[courseName][questionText];
}
const invalidPatterns = [
/什么是.+/, /.+是什么/, /.+是什么意思/, /.+的含义/, /指什么/,
/是不是/, /对不对/, /好不好/, /好吗/, /近吗/, /远吗/, /对吗/,
/可以吗/, /可以.+吗/, /是否可以/, /有没有/, /能不能/, /应该.+吗/,
/是否应该/, /必须.+吗/, /是否必须/, /需要.+吗/, /是否需要/, /一定.+吗/,
/是否一定/, /属于.+吗/, /是否属于/, /是否合理/, /是否相同/, /是否不同/,
/有意义吗/, /意义大吗/, /喜欢.+吗/, /如何翻译.+/
];
const isInvalidQuestion = invalidPatterns.some(pattern => pattern.test(questionText));
if (isInvalidQuestion) {
spanElement.style.textDecoration = 'line-through';
status = "已回答";
questionsData[courseName] = questionsData[courseName] || {};
questionsData[courseName][questionText] = status;
GM_setValue("questionsData", questionsData);
} else if (status === "未回答") {
spanElement.style.color = 'red';
} else if (status === "已回答") {
spanElement.style.color = 'green';
}
}
}
});
}
function scrollToUnansweredQuestions() {
console.log("滚动到未回答的问题");
const questionItems = document.querySelectorAll('.question-item');
const unansweredQuestions = Array.from(questionItems).filter(item => {
const spanElement = item.querySelector('.question-content span');
const questionText = spanElement ? spanElement.title.trim() : '';
const courseNameElement = document.querySelector(".course-name");
const courseName = courseNameElement ? courseNameElement.innerText.trim() : '';
const status = GM_getValue("questionsData", {})[courseName]?.[questionText];
return status === "未回答";
});
if (unansweredQuestions.length > 0) {
const firstUnansweredQuestionSpan = unansweredQuestions[0].querySelector('.question-content span');
if (firstUnansweredQuestionSpan) {
firstUnansweredQuestionSpan.click();
console.log(`已点击第一个未回答的问题: ${firstUnansweredQuestionSpan.title}`);
} else {
console.log("未找到未回答问题的链接元素");
}
} else {
console.log("目前无未回答问题.");
}
}
function startChecking() {
setInterval(() => {
console.log("检查问题和输入框是否存在...");
const questionElement = document.querySelector(".question-content span");
if (!questionElement) {
console.log("未找到问题元素。");
return;
}
const questionText = questionElement.innerText.trim();
if (!questionText) {
console.log("问题内容为空。");
return;
}
const inputElement = document.querySelector("textarea");
if (!inputElement) {
console.log("未找到输入框元素。");
return;
}
addQuestionStatus();
const answerButton = document.querySelector("div.my-answer-btn.ZHIHUISHU_QZMD.tool-show span");
const modalExists = document.querySelector(".yidun_modal");
if (modalExists) {
console.log("检测到二维码,需要手动验证。10秒后关闭窗口。");
GM_notification("检测到二维码,请手动验证。10秒后关闭窗口。", "安全验证");
setTimeout(() => {
window.close();
}, 10000);
return;
}
if (!answerButton || answerButton.textContent.trim() !== "我来回答") {
const currentURL = window.location.href;
const pattern = /^https:\/\/qah5\.zhihuishu\.com\/qa\.html#\/web\/questionDetail/;
if (pattern.test(currentURL)) {
console.log("未找到'我来回答'按钮且当前页面符合特定模式,关闭当前窗口。");
markQuestionAsAnswered(questionText);
window.close();
} else {
console.log("未找到'我来回答'按钮且当前页面不符合特定模式,停止回答逻辑。");
}
return;
}
if (inputElement.value.trim() !== "") {
console.log("输入框中已有数据,检查是否需要点击立即发布...");
startPublishChecking();
return;
}
console.log("找到问题并准备回答:", questionText);
if (!requestLock) {
requestLock = true;
answerQuestion(questionText, inputElement);
} else {
console.log("请求进行中,跳过此次回答逻辑。");
}
}, intervalTime);
}
function startPublishChecking() {
console.log("检查是否需要点击立即发布按钮...");
const publishButton = document.querySelector('.dialog-bottom .up-btn.ZHIHUISHU_QZMD.set-btn');
const inputElement = document.querySelector('textarea');
if (
inputElement &&
inputElement.value.trim() !== "" &&
publishButton &&
publishButton.textContent.trim() === "立即发布"
) {
console.log("找到立即发布按钮,自动点击...");
publishButton.click();
}
}
function answerQuestion(questionText, inputElement) {
GM_xmlhttpRequest({
method: "POST",
url: GM_getValue("API_URL", defaultAPIUrl),
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${GM_getValue("API_KEY", defaultAPIKey)}`
},
data: JSON.stringify({
model: GM_getValue("aimodel", defaultModel),
messages: [
{
role: "user",
content: `智慧树问题回答,你比如我提问:音乐剧与民歌在曲风、表现形式和情感表达上有何不同?如何在声乐演唱中体现这些差异?你只需要给出简介30字以内或者左右的回答即可。只需要输出回答,不需要其他,也不需要markdown格式,回答中严禁出现下面三个词连在一起:“学习通”。且回答至少超过10个字。问题如下:${questionText}`
}
],
max_tokens: 1688,
temperature: 0.5,
stream: false
}),
onload: function (response) {
requestLock = false;
console.log("请求成功:",response.responseText);
if (response.status === 200) {
const jsonResponse = JSON.parse(response.responseText);
const answer = jsonResponse.choices[0].message.content.trim();
console.log("获取到的回答:", answer);
inputElement.value = answer;
inputElement.dispatchEvent(inputEvent);
} else {
console.error("API 请求失败,状态码:", response.status);
}
},
onerror: function () {
requestLock = false;
console.error("API 请求出错。");
}
});
}
window.onload = () => {
console.log("启动智慧树自动回答器...");
waitForAnswerButton();
initMutationObserver();
startCountdown();
};
})();