course-helper/script/ds-listener.js
2025-05-08 20:05:49 +08:00

156 lines
5.6 KiB
JavaScript

// ==UserScript==
// @name BUCT cource deepseek listener
// @namespace http://tampermonkey.net/
// @version 2025-05-07
// @description try to take over the world!
// @author You
// @match https://chat.deepseek.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=deepseek.com
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// ==/UserScript==
(function () {
"use strict";
const CLASS_MAP = {
input: "_27c9245",
send: "_7436101",
chat: "dad65929",
latest: "d7dc56a8",
done: "_43c05b5"
};
const HOST = "https://local.bluemangoo.net:3443";
const question = {
question: "",
questionID: "",
answered: true
};
async function poll() {
// query latest question
let res;
try {
res = await fetch(`${HOST}/polling?env=deepseek`, {
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") {
if (question.answered) {
question.answered = false;
question.question = data.data.question;
question.questionID = data.data.questionID;
console.log("获取到新问题:", question.question);
ask(question.question);
}
}
} catch (e) {
console.error(e);
}
}
async function answer(questionID, answer) {
console.log("回答问题:", questionID, answer);
question.answered = true;
await fetch(`${HOST}/answer`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
questionID,
answer
})
});
}
function setNativeValue(element, value) {
const valueSetter = Object.getOwnPropertyDescriptor(element, "value").set;
const prototype = Object.getPrototypeOf(element);
const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, "value").set;
if (valueSetter && valueSetter !== prototypeValueSetter) {
prototypeValueSetter.call(element, value);
} else {
valueSetter.call(element, value);
}
}
function ask(question) {
const input = document.getElementsByClassName(CLASS_MAP.input)[0];
setNativeValue(input, question);
input.dispatchEvent(new Event("input", { bubbles: true }));
document.getElementsByClassName(CLASS_MAP.send)[0].click();
}
function init() {
const chat = document.getElementsByClassName(CLASS_MAP.chat)[0];
// 创建一个 MutationObserver 来监听子元素变化
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
// 检查新增的节点
mutation.addedNodes.forEach((node) => {
// 确保是元素节点
if (node.nodeType === Node.ELEMENT_NODE) {
const element = node;
// 检查新增的元素是否同时包含 "_4f9bf79" 和 "d7dc56a8" 类
if (
element.classList.contains("_4f9bf79") &&
element.classList.contains("d7dc56a8")
) {
console.log("目标元素已添加:", element);
// 对这个元素添加属性变化的监听器
const targetObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
// 检查是否添加了 "_43c05b5" 类
if (
mutation.type === "attributes" &&
mutation.attributeName === "class" &&
element.classList.contains("_43c05b5")
) {
const ans = element.innerText.toString();
console.log("内容:", ans);
// 可以在这里执行其他操作
targetObserver.disconnect();
answer(question.questionID, ans);
}
});
});
// 开始观察目标元素的属性变化
targetObserver.observe(element, {
attributes: true, // 监听属性变化
attributeFilter: ["class"] // 只监听 class 变化
});
}
}
});
});
});
// 开始观察父元素的子元素变化
observer.observe(chat, {
childList: true, // 监听子元素变化
subtree: true // 监听所有后代元素
});
console.log("正在监听父元素:", chat);
poll();
}
GM_registerMenuCommand("初始化作业桥", init);
})();