course-helper/script/buct-cource-copy.js
2025-05-08 20:13:58 +08:00

149 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ==UserScript==
// @name BUCT cource helper
// @namespace http://tampermonkey.net/
// @version 2025-03-12
// @description 北化在线助手
// @author Bluemangoo
// @match https://course.buct.edu.cn/meol/jpk/course/layout/newpage/index.jsp?*
// @icon https://www.google.com/s2/favicons?sz=64&domain=buct.edu.cn
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// ==/UserScript==
(function () {
"use strict";
const HOST = "https://local.bluemangoo.net:3443";
let question = {
id: ""
};
async function poll() {
let res;
try {
res = await fetch(`${HOST}/polling?env=course`, {
method: "GET",
headers: {
"Content-Type": "application/json"
}
});
} catch {
await new Promise((resolve) => setTimeout(resolve, 1000));
return poll();
}
poll();
try {
const data = await res.json();
if (data.status !== "nothing") {
const { questionID, answer } = data.data;
console.log("回答", questionID, "\n", answer);
answerQuestion(questionID, answer);
}
} catch (e) {
console.error(e);
}
}
function getAnswerElement() {
const doc = document
.getElementById("mainFrame")
.contentDocument.getElementById("questionshow").contentDocument;
return doc.getElementsByClassName("extable")[0];
}
function getContent() {
const doc = document
.getElementById("mainFrame")
.contentDocument.getElementById("questionshow").contentDocument;
const question = doc
.getElementsByTagName("iframe")[0]
.contentDocument.getElementById("body").innerText;
const answer = doc.getElementsByClassName("extable")[0].innerText.replaceAll("\t", "- ");
return question + answer;
}
function copyToClipboard() {
navigator.clipboard.writeText(getContent());
}
function answerQuestion(id, answer) {
if (id !== question.id) {
return;
}
aiButton.value = ""
const answers = answer.split("\n");
const children = getAnswerElement().children[0].children;
for (const child of children) {
if (child.classList[0] !== "optionContent") {
continue;
}
if (answers.includes(child.innerText.replaceAll("\t", ""))) {
child.children[0].children[0].click();
}
}
}
async function ask() {
const q = getContent();
const req = await fetch(`${HOST}/question`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
question: q
})
});
const data = await req.json();
if (data.data.questionId) {
question.id = data.data.questionId;
}
aiButton.value = "Zzz";
}
const flag = {
copyButton: false,
aiButton: false
};
let aiButton;
function createButton(addAiButton = false) {
const base = document.getElementById("mainFrame");
const win = base.contentWindow;
const doc = base.contentDocument;
win.getContent = getContent;
win.getAnswerElement = getAnswerElement;
win.answerQuestion = answerQuestion;
win.copyToClipboard = copyToClipboard;
if (!flag.copyButton) {
const button = doc.createElement("input");
button.value = "复制";
button.style = "margin-left: 10px;";
button.type = "button";
button.onclick = copyToClipboard;
doc.getElementsByClassName("navigation")[0].childNodes[1].appendChild(button);
flag.copyButton = true;
}
if (addAiButton && !flag.aiButton) {
const button = doc.createElement("input");
aiButton = button;
button.value = "";
button.style = "margin-left: 10px;";
button.type = "button";
button.onclick = ask;
doc.getElementsByClassName("navigation")[0].childNodes[1].appendChild(button);
flag.aiButton = true;
}
}
function initAiBridge() {
createButton(true);
poll();
}
GM_registerMenuCommand("添加复制按钮", createButton);
GM_registerMenuCommand("初始化ai桥", initAiBridge);
})();