diff --git a/Update.json b/Update.json
index 96f64b2d..043b5b37 100644
--- a/Update.json
+++ b/Update.json
@@ -3124,6 +3124,96 @@
}
],
"Notes": "#860 ..."
+ },
+ "2.4.5": {
+ "UpdateDate": 1759487413226,
+ "Prerelease": true,
+ "UpdateContents": [
+ {
+ "PR": 869,
+ "Description": "Update CSS selector (again...)"
+ }
+ ],
+ "Notes": "为什么这个破东西老是换位置"
+ },
+ "2.4.6": {
+ "UpdateDate": 1759548958578,
+ "Prerelease": true,
+ "UpdateContents": [
+ {
+ "PR": 871,
+ "Description": "Add tooltip for ProblemSwitcher"
+ }
+ ],
+ "Notes": "现在, 你只需要将鼠标悬浮在比赛题目切换器上方, 即可查看题目名称"
+ },
+ "2.4.7": {
+ "UpdateDate": 1759549826774,
+ "Prerelease": true,
+ "UpdateContents": [
+ {
+ "PR": 872,
+ "Description": "修复获取数据"
+ }
+ ],
+ "Notes": "funny"
+ },
+ "2.5.0": {
+ "UpdateDate": 1759568103629,
+ "Prerelease": false,
+ "UpdateContents": [
+ {
+ "PR": 861,
+ "Description": "Update CSS selector"
+ },
+ {
+ "PR": 863,
+ "Description": "修复“NaN年前“"
+ },
+ {
+ "PR": 865,
+ "Description": "删除获取数据功能"
+ },
+ {
+ "PR": 866,
+ "Description": "比赛题目页面里左侧栏加入题目序号列表"
+ },
+ {
+ "PR": 869,
+ "Description": "Update CSS selector (again...)"
+ },
+ {
+ "PR": 871,
+ "Description": "Add tooltip for ProblemSwitcher"
+ },
+ {
+ "PR": 872,
+ "Description": "修复获取数据"
+ }
+ ],
+ "Notes": "XMOJ-Script 2.5.0 新增了比赛题目切换器,方便您在题目之间快速切换。此功能默认启用,您也可以在设置中禁用它。本版本还修复了一个导致时间显示为“NaN年前”的错误, 更新了一些 CSS selector,以适应 XMOJ 网站的最新变化."
+ },
+ "2.5.1": {
+ "UpdateDate": 1759830659949,
+ "Prerelease": true,
+ "UpdateContents": [
+ {
+ "PR": 876,
+ "Description": "refactor: simplify SubmitLink selection by querying all anchors and finding by text"
+ }
+ ],
+ "Notes": "No release notes were provided for this release."
+ },
+ "2.5.2": {
+ "UpdateDate": 1759845614758,
+ "Prerelease": true,
+ "UpdateContents": [
+ {
+ "PR": 877,
+ "Description": "fix: problem PID 可能为 null"
+ }
+ ],
+ "Notes": "No release notes were provided for this release."
}
}
}
\ No newline at end of file
diff --git a/XMOJ.user.js b/XMOJ.user.js
index 69dfca7f..389809d0 100644
--- a/XMOJ.user.js
+++ b/XMOJ.user.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name XMOJ
-// @version 2.4.4
+// @version 2.5.2
// @description XMOJ增强脚本
// @author @XMOJ-Script-dev, @langningchen and the community
// @namespace https://github/langningchen
@@ -1469,7 +1469,7 @@ async function main() {
"Name": "恢复讨论与短消息功能"
}, {
"ID": "MoreSTD", "Type": "F", "Name": "查看到更多标程"
- }, {
+ }, {"ID": "ApplyData", "Type": "A", "Name": "获取数据功能"}, {
"ID": "AutoCheat", "Type": "A", "Name": "自动提交当年代码"
}, {"ID": "Rating", "Type": "A", "Name": "添加用户评分和用户名颜色"}, {
"ID": "AutoRefresh", "Type": "A", "Name": "比赛列表、比赛排名界面自动刷新"
@@ -1645,7 +1645,28 @@ async function main() {
} else if (location.pathname == "/problem.php") {
await RenderMathJax();
if (SearchParams.get("cid") != null && UtilityEnabled("ProblemSwitcher")) {
- document.getElementsByTagName("h2")[0].innerHTML += " (" + localStorage.getItem("UserScript-Contest-" + SearchParams.get("cid") + "-Problem-" + SearchParams.get("pid") + "-PID") + ")";
+ let pid = localStorage.getItem("UserScript-Contest-" + SearchParams.get("cid") + "-Problem-" + SearchParams.get("pid") + "-PID");
+ if (!pid) {
+ const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid"));
+ const res = await contestReq.text();
+ if (contestReq.status === 200 && res.indexOf("比赛尚未开始或私有,不能查看题目。") === -1) {
+ const parser = new DOMParser();
+ const dom = parser.parseFromString(res, "text/html");
+ const rows = (dom.querySelector("#problemset > tbody")).rows;
+ for (let i = 0; i < rows.length; i++) {
+ let problemIdText = rows[i].children[1].innerText; // Get the text content
+ let match = problemIdText.match(/\d+/); // Extract the number
+ if (match) {
+ let extractedPid = match[0];
+ localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-Problem-" + i + "-PID", extractedPid);
+ }
+ }
+ pid = localStorage.getItem("UserScript-Contest-" + SearchParams.get("cid") + "-Problem-" + SearchParams.get("pid") + "-PID");
+ }
+ }
+ if (pid) {
+ document.getElementsByTagName("h2")[0].innerHTML += " (" + pid + ")";
+ }
let ContestProblemList = localStorage.getItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemList");
if (ContestProblemList == null) {
const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + SearchParams.get("cid"));
@@ -1695,7 +1716,7 @@ async function main() {
if (problemList[i].url === location.href) {
activeClass = "active";
}
- problemSwitcher.innerHTML += `${buttonText}`;
+ problemSwitcher.innerHTML += `${buttonText}`;
}
document.body.appendChild(problemSwitcher);
}
@@ -1710,22 +1731,8 @@ async function main() {
document.querySelector("body > div > div.mt-3 > center").lastElementChild.style.marginLeft = "10px";
}
//修复提交按钮
- let SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(12)');
- if (SubmitLink == null) { //a special type of problem
- SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(10)');
- }
- if (SubmitLink == null) {
- SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(11)');
- }
- if (SubmitLink == null) {
- SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(13)');
- }
- if (SubmitLink == null) {
- SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(9)');
- }
- if (SubmitLink == null) { //为什么这个破东西老是换位置
- SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(7)');
- }
+ const links = document.querySelectorAll('.mt-3 > center:nth-child(1) > a');
+ const SubmitLink = Array.from(links).find(a => a.textContent.trim() === '提交');
let SubmitButton = document.createElement('button');
SubmitButton.id = 'SubmitButton';
SubmitButton.className = 'btn btn-outline-secondary';
@@ -1741,8 +1748,7 @@ async function main() {
// Remove the button's outer []
let str = document.querySelector('.mt-3 > center:nth-child(1)').innerHTML;
let target = SubmitButton.outerHTML;
- let result = str.replace(new RegExp(`(.?)${target}(.?)`, 'g'), target);
- document.querySelector('.mt-3 > center:nth-child(1)').innerHTML = result;
+ document.querySelector('.mt-3 > center:nth-child(1)').innerHTML = str.replace(new RegExp(`(.?)${target}(.?)`, 'g'), target);
document.querySelector('html body.placeholder-glow div.container div.mt-3 center button#SubmitButton.btn.btn-outline-secondary').onclick = function () {
window.location.href = SubmitLink.href;
console.log(SubmitLink.href);
@@ -3474,6 +3480,121 @@ async function main() {
if (document.getElementById("apply_data")) {
let ApplyDiv = document.getElementById("apply_data").parentElement;
console.log("启动!!!");
+ if (UtilityEnabled("ApplyData")) {
+ let GetDataButton = document.createElement("button");
+ GetDataButton.className = "ms-2 btn btn-outline-secondary";
+ GetDataButton.innerText = "获取数据";
+ console.log("按钮创建成功");
+ ApplyDiv.appendChild(GetDataButton);
+ GetDataButton.addEventListener("click", async () => {
+ GetDataButton.disabled = true;
+ GetDataButton.innerText = "正在获取数据...";
+ let PID = localStorage.getItem("UserScript-Solution-" + SearchParams.get("sid") + "-Problem");
+ if (PID == null) {
+ GetDataButton.innerText = "失败! 无法获取PID";
+ GetDataButton.disabled = false;
+ await new Promise((resolve) => {
+ setTimeout(resolve, 800);
+ });
+ GetDataButton.innerText = "获取数据";
+ return;
+ }
+ let Code = "";
+ if (localStorage.getItem(`UserScript-Problem-${PID}-IOFilename`) !== null) {
+ Code = `#define IOFile "${localStorage.getItem(`UserScript-Problem-${PID}-IOFilename`)}"\n`;
+ }
+ Code += `//XMOJ-Script 获取数据代码
+ #include
+using namespace std;
+string Base64Encode(string Input)
+{
+ const string Base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ string Output;
+ for (int i = 0; i < Input.length(); i += 3)
+ {
+ Output.push_back(i + 0 > Input.length() ? '=' : Base64Chars[(Input[i + 0] & 0xfc) >> 2]);
+ Output.push_back(i + 1 > Input.length() ? '=' : Base64Chars[((Input[i + 0] & 0x03) << 4) + ((Input[i + 1] & 0xf0) >> 4)]);
+ Output.push_back(i + 2 > Input.length() ? '=' : Base64Chars[((Input[i + 1] & 0x0f) << 2) + ((Input[i + 2] & 0xc0) >> 6)]);
+ Output.push_back(i + 3 > Input.length() ? '=' : Base64Chars[Input[i + 2] & 0x3f]);
+ }
+ return Output;
+}
+int main()
+{
+#ifdef IOFile
+ freopen(IOFile ".in", "r", stdin);
+ freopen(IOFile ".out", "w", stdout);
+#endif
+ string Input;
+ while (1)
+ {
+ char Data = getchar();
+ if (Data == EOF)
+ break;
+ Input.push_back(Data);
+ }
+ throw logic_error("[" + Base64Encode(Input.c_str()) + "]");
+ return 0;
+}`;
+
+ await fetch("https://www.xmoj.tech/submit.php", {
+ "headers": {
+ "content-type": "application/x-www-form-urlencoded"
+ },
+ "referrer": "https://www.xmoj.tech/submitpage.php?id=" + PID,
+ "method": "POST",
+ "body": "id=" + PID + "&" + "language=1&" + "source=" + encodeURIComponent(Code) + "&" + "enable_O2=on"
+ });
+
+ let SID = await fetch("https://www.xmoj.tech/status.php").then((Response) => {
+ return Response.text();
+ }).then((Response) => {
+ let ParsedDocument = new DOMParser().parseFromString(Response, "text/html");
+ return ParsedDocument.querySelector("#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)").innerText;
+ });
+
+ await new Promise((Resolve) => {
+ let Interval = setInterval(async () => {
+ await fetch("status-ajax.php?solution_id=" + SID).then((Response) => {
+ return Response.text();
+ }).then((Response) => {
+ if (Response.split(",")[0] >= 4) {
+ clearInterval(Interval);
+ Resolve();
+ }
+ });
+ }, 500);
+ });
+
+ await fetch(`https://www.xmoj.tech/reinfo.php?sid=${SID}`).then((Response) => {
+ return Response.text();
+ }).then((Response) => {
+ let ParsedDocument = new DOMParser().parseFromString(Response, "text/html");
+ let ErrorData = ParsedDocument.getElementById("errtxt").innerText;
+ let MatchResult = ErrorData.match(/\what\(\): \[([A-Za-z0-9+\/=]+)\]/g);
+ if (MatchResult === null) {
+ GetDataButton.innerText = "获取数据失败";
+ GetDataButton.disabled = false;
+ return;
+ }
+ for (let i = 0; i < MatchResult.length; i++) {
+ let Data = CryptoJS.enc.Base64.parse(MatchResult[i].substring(10, MatchResult[i].length - 1)).toString(CryptoJS.enc.Utf8);
+ ApplyDiv.appendChild(document.createElement("hr"));
+ ApplyDiv.appendChild(document.createTextNode("数据" + (i + 1) + ":"));
+ let CodeElement = document.createElement("div");
+ ApplyDiv.appendChild(CodeElement);
+ CodeMirror(CodeElement, {
+ value: Data,
+ theme: (UtilityEnabled("DarkMode") ? "darcula" : "default"),
+ lineNumbers: true,
+ readOnly: true
+ }).setSize("100%", "auto");
+ }
+ GetDataButton.innerText = "获取数据成功";
+ GetDataButton.disabled = false;
+ });
+ });
+ }
document.getElementById("apply_data").addEventListener("click", () => {
let ApplyElements = document.getElementsByClassName("data");
for (let i = 0; i < ApplyElements.length; i++) {
diff --git a/package.json b/package.json
index 169470fd..b70e2ba3 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "xmoj-script",
- "version": "2.4.4",
+ "version": "2.5.2",
"description": "an improvement script for xmoj.tech",
"main": "AddonScript.js",
"scripts": {