BZOJ Helper

BZOJ助手

当前为 2019-02-17 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name BZOJ Helper
  3. // @namespace bzoj
  4. // @version 1.5.3
  5. // @description BZOJ助手
  6. // @author ranwen
  7. // @match https://lydsy.com/*
  8. // @match https://www.lydsy.com/*
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. String.prototype.trim = function () {
  14. return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  15. }
  16. function savedata(name, val) {
  17. localStorage.setItem(name, JSON.stringify(val));
  18. }
  19. function readdata(name) {
  20. return JSON.parse(localStorage.getItem(name))
  21. }
  22. function getradioval(name) {
  23. for (i of document.getElementsByName(name)) {
  24. if (i.checked) {
  25. return i.value;
  26. }
  27. }
  28. }
  29. var poly_star = "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" style=\"width: 20px;height: 20px;\">\
  30. <polygon points=\"19.510565162951536,6.9098300562505255 12.351141009169893,6.76393202250021 10,0 7.648858990830108,6.76393202250021 0.48943483704846535,6.9098300562505255 6.195773934819385,11.236067977499792 4.122147477075267,18.090169943749473 10,14 15.87785252292473,18.090169943749476 13.804226065180615,11.23606797749979\" style=\"fill:#FFFF00;\"></polygon>\
  31. </svg>";
  32. var logined = 0
  33. var username = "";
  34. var mydb = Array();
  35. var markedp = Array();
  36. var fixurl = location.href;
  37. var havenotice = 0;
  38. if(document.getElementsByTagName("center")[1].innerText.indexOf("Notice")!=-1) havenotice=1;
  39. if (fixurl.indexOf("www.lydsy.com") != -1) {
  40. fixurl = fixurl.replace("www.lydsy.com", "lydsy.com");
  41. location.href = fixurl;
  42. }
  43. function getmyusername() {
  44. for (i of document.getElementsByTagName("table")[0].childNodes[1].childNodes[0].childNodes)
  45. if (typeof (i.innerText) != "undefined" && i.innerText.indexOf("ModifyUser") != -1) {
  46. username = i.innerText.substr(12);
  47. username = username.trim();
  48. return;
  49. }
  50. logined = -1;
  51. }
  52. //页面判断
  53. function isprob() {
  54. if (fixurl.indexOf("https://lydsy.com/JudgeOnline/problem.php?id=") == -1) {
  55. return -1;
  56. }
  57. return fixurl.substr(45);
  58. }
  59. function isstatus() {
  60. if (fixurl.indexOf("https://lydsy.com/JudgeOnline/status.php") == -1) {
  61. return -1;
  62. }
  63. return 0;
  64. }
  65. function islist() {
  66. if (fixurl.indexOf("https://lydsy.com/JudgeOnline/problemset.php") == -1) {
  67. return -1;
  68. }
  69. return 0;
  70. }
  71. function isconfig() {
  72. if (fixurl.indexOf("https://lydsy.com/JudgeOnline/modifypage.php") == -1) {
  73. return -1;
  74. }
  75. return 0;
  76. }
  77. function isdiscusspage() {
  78. if (fixurl.indexOf("https://lydsy.com/JudgeOnline/wttl/thread.php") == -1) {
  79. return -1;
  80. }
  81. return 0;
  82. }
  83. function isuserinfo() {
  84. if (fixurl.indexOf("https://lydsy.com/JudgeOnline/userinfo.php?user=") == -1) {
  85. return -1;
  86. }
  87. return 0;
  88.  
  89. }
  90. //更新db
  91. function updateprobinfobypage(pid) {
  92. sb = {};
  93. for (i of document.getElementsByTagName("h2")[0].childNodes)
  94. if (i.nodeName == "#text") {
  95. sb["title"] = i.data.substr(6)
  96. break
  97. }
  98. sb["submit"] = document.getElementsByTagName("center")[1+havenotice].getElementsByClassName("green")[2].nextSibling.data;
  99. sb["submit"] = sb["submit"].slice(0, -2);
  100. sb["solved"] = document.getElementsByTagName("center")[1+havenotice].getElementsByClassName("green")[3].nextSibling.data;
  101. sb["source"] = document.getElementsByTagName("h2")[7].nextElementSibling.childNodes[0].innerText;
  102. savedata("problem_" + pid, sb)
  103. }
  104. function updateprobinfobylist() {
  105. for (i of document.getElementById("problemset").getElementsByTagName("tbody")[0].childNodes) {
  106. sb = {}
  107. prob = i.childNodes[1].innerText.trim();
  108. sb["title"] = i.childNodes[2].innerText.trim();
  109. sb["source"] = i.childNodes[3].innerText.trim();
  110. sb["solved"] = i.childNodes[4].innerText.trim();
  111. sb["submit"] = i.childNodes[5].innerText.trim();
  112. if (i.childNodes[0].innerText.trim() == "Y") {
  113. if (mydb.indexOf(prob) == -1)
  114. mydb.push(prob)
  115. }
  116. savedata("problem_" + prob, sb)
  117. }
  118. savedata("userlist_" + username, mydb)
  119. }
  120. function updateuserdb(def = document, nm = fixurl.substr(48)) {
  121. var list = def.getElementsByTagName("script")[2].innerHTML.match(/p\([1-9][0-9]{3}\)/g);
  122. var rl = Array();
  123. for (var i of list) {
  124. rl.push(i.substr(2, 4))
  125. }
  126. savedata("userlist_" + nm, rl)
  127. }
  128. function getmydb() {
  129. ret = readdata("userlist_" + username);
  130. if (ret == null) {
  131. xhr = new XMLHttpRequest();
  132. xhr.open('GET', 'https://lydsy.com/JudgeOnline/userinfo.php?user=' + username, false);
  133. xhr.send(null);
  134. parser = new DOMParser();
  135. gg = parser.parseFromString(xhr.responseText, "text/html")
  136. updateuserdb(gg, username)
  137. ret = readdata("userlist_" + username)
  138. }
  139. return ret
  140. }
  141. function setdefaultconfig() {
  142. def = { "unmarkalert": "0", "autoext": "1", "statusny": "1" };
  143. for (i in def) {
  144. if (typeof (config[i]) == "undefined")
  145. config[i] = def[i];
  146. }
  147. savedata("config", config);
  148. }
  149. getmyusername()
  150. if (logined == -1) {
  151. return;
  152. }
  153. markedp = readdata("marked");
  154. if (markedp == null) {
  155. savedata("marked", Array());
  156. markedp = Array();
  157. }
  158. config = readdata("config");
  159. if (config == null) {
  160. savedata("config", {});
  161. config = {};
  162. }
  163. setdefaultconfig();
  164. //page
  165. if (isuserinfo() != -1) {
  166. updateuserdb();
  167. document.getElementsByTagName("table")[1].getElementsByTagName("tr")[0].getElementsByTagName("td")[2].innerHTML+=" <a href=\"javascript:;\" id=\"diffme\">Diff with me</a>"
  168. document.getElementById("diffme").onclick = function () {
  169. nm=fixurl.substr(48)
  170. txt=""
  171. usdb=readdata("userlist_"+nm)
  172. for(i=1000;i<=9999;i++)
  173. {
  174. hs1=(mydb.indexOf(""+i)!=-1)
  175. hs2=(usdb.indexOf(""+i)!=-1)
  176. if(hs1 && hs2)
  177. txt+="<a href=\"problem.php?id="+i+"\">"+i+"</a>\n"
  178. if(hs1 && (!hs2))
  179. txt+="<a href=\"problem.php?id="+i+"\" style=\"color:#00FF00\">"+i+"</a>\n"
  180. if((!hs1) && hs2)
  181. txt+="<a href=\"problem.php?id="+i+"\" style=\"color:#FF0000\">"+i+"</a>\n"
  182. }
  183. document.getElementsByTagName("table")[1].getElementsByTagName("tr")[1].getElementsByTagName("td")[2].innerHTML=txt
  184. }
  185. }
  186.  
  187. mydb = getmydb();
  188. if (islist() != -1) {
  189. updateprobinfobylist();
  190. for (i of document.getElementById("problemset").getElementsByTagName("tbody")[0].childNodes) {
  191. prob = i.childNodes[1].innerText.trim();
  192. if (markedp.indexOf(prob) != -1) i.childNodes[2].innerHTML = i.childNodes[2].innerHTML + poly_star;
  193. }
  194. document.getElementById("problemset").getElementsByTagName("thead")[0].childNodes[1].childNodes[0].childNodes[0].innerHTML = document.getElementById("problemset").getElementsByTagName("thead")[0].childNodes[1].childNodes[0].childNodes[0].innerHTML +
  195. " <a href=\"javascript:;\" id=\"showmarkedlist\">Marked Problem</a>";
  196. document.getElementById("showmarkedlist").onclick = function () {
  197. document.getElementById("problemset").getElementsByTagName("thead")[0].childNodes[1].childNodes[0].childNodes[0].innerHTML+=" <a href=\"javascript:;\" id=\"unmarkac\">Unmark AC Problem</a>";
  198. txt = ""
  199. for (i = 0; i < markedp.length; i++) {
  200. o = markedp[i]
  201. info = readdata("problem_" + o);
  202. nr = ""
  203. nr += "<tr class=\"" + ((i & 1) == 0 ? "evenrow" : "oddrow") + "\">";
  204. nr += "<td>";
  205. if (mydb.indexOf(o) != -1) nr += "<span class=\"yes\">Y</span>";
  206. nr += "</td>";
  207. nr += "<td align=\"center\">";
  208. nr += o;
  209. nr += "</td>";
  210. nr += "<td align=\"left\">";
  211. nr += "<a href=\"problem.php?id=" + o + "\">" + info['title'] + "</a>" + poly_star;
  212. nr += "</td>"
  213. nr += "<td align=\"center\">";
  214. nr += info['source']
  215. nr += "</td>";
  216. nr += "<td align=\"center\">";
  217. nr += "<a href=\"status.php?problem_id=" + o + "&amp;jresult=4\">" + info['solved'] + "</a>";
  218. nr += "</td>";
  219. nr += "<td align=\"center\">";
  220. nr += "<a href=\"status.php?problem_id=" + o + "\">" + info['submit'] + "</a>";
  221. nr += "</td>";
  222. nr += "</tr>";
  223. txt += nr;
  224. }
  225. document.getElementById("problemset").getElementsByTagName("tbody")[0].innerHTML = txt;
  226.  
  227. //show unmarkac
  228. document.getElementById("unmarkac").onclick = function () {
  229. if(!window.confirm("确定取消标记所有AC题目?")) return
  230. markedp=readdata("marked")
  231. for (i = 0; i < markedp.length; i++) {
  232. o = markedp[i]
  233. if(mydb.indexOf(o) != -1)
  234. {
  235. markedp.splice(markedp.indexOf(o), 1)
  236. i--
  237. }
  238. }
  239. savedata("marked", markedp)
  240. //rerender
  241. txt = ""
  242. for (i = 0; i < markedp.length; i++) {
  243. o = markedp[i]
  244. info = readdata("problem_" + o);
  245. nr = ""
  246. nr += "<tr class=\"" + ((i & 1) == 0 ? "evenrow" : "oddrow") + "\">";
  247. nr += "<td>";
  248. if (mydb.indexOf(o) != -1) nr += "<span class=\"yes\">Y</span>";
  249. nr += "</td>";
  250. nr += "<td align=\"center\">";
  251. nr += o;
  252. nr += "</td>";
  253. nr += "<td align=\"left\">";
  254. nr += "<a href=\"problem.php?id=" + o + "\">" + info['title'] + "</a>" + poly_star;
  255. nr += "</td>"
  256. nr += "<td align=\"center\">";
  257. nr += info['source']
  258. nr += "</td>";
  259. nr += "<td align=\"center\">";
  260. nr += "<a href=\"status.php?problem_id=" + o + "&amp;jresult=4\">" + info['solved'] + "</a>";
  261. nr += "</td>";
  262. nr += "<td align=\"center\">";
  263. nr += "<a href=\"status.php?problem_id=" + o + "\">" + info['submit'] + "</a>";
  264. nr += "</td>";
  265. nr += "</tr>";
  266. txt += nr;
  267. }
  268. document.getElementById("problemset").getElementsByTagName("tbody")[0].innerHTML = txt;
  269. }
  270. }
  271. }
  272.  
  273. var prob = isprob();
  274. if (prob != -1) {
  275. updateprobinfobypage(prob)
  276. if (mydb.indexOf(prob) != -1) {
  277. var rdt = document.getElementsByTagName("center")[1+havenotice].getElementsByTagName("h2")[0].innerHTML;
  278. var tdb = "<span style=\"color:#00FF00\">Y</span>" + rdt;
  279. document.getElementsByTagName("center")[1+havenotice].getElementsByTagName("h2")[0].innerHTML = tdb;
  280. }
  281. var ttt = document.getElementsByTagName("center")[1+havenotice].innerHTML;
  282. var fff = ttt + "[<a href=\"https://lydsy.com/JudgeOnline/status.php?problem_id=" + prob + "&user_id=" + username + "\">My Status</a>]";
  283. document.getElementsByTagName("center")[1+havenotice].innerHTML = fff;
  284. var rdt = document.getElementsByTagName("center")[1+havenotice].getElementsByTagName("h2")[0].innerHTML;
  285. col = "#cccccc"
  286. if (markedp.indexOf(prob) != -1) col = "#FFFF00";
  287. var tdb = rdt +
  288. "<a href=\"javascript:;\" id=\"chmr\"><svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" style=\"width: 20px;height: 20px;\">\
  289. <polygon points=\"19.510565162951536,6.9098300562505255 12.351141009169893,6.76393202250021 10,0 7.648858990830108,6.76393202250021 0.48943483704846535,6.9098300562505255 6.195773934819385,11.236067977499792 4.122147477075267,18.090169943749473 10,14 15.87785252292473,18.090169943749476 13.804226065180615,11.23606797749979\" style=\"fill:"+ col + ";\"></polygon>\
  290. </svg></a>";
  291. document.getElementsByTagName("center")[1+havenotice].getElementsByTagName("h2")[0].innerHTML = tdb;
  292.  
  293. document.getElementById("chmr").onclick = function () {
  294. markedp = readdata("marked");
  295. if (markedp.indexOf(prob) != -1) {
  296. if (config["unmarkalert"] == "1" && !window.confirm("确定鸽掉它?")) return; //取消标记提示
  297. markedp.splice(markedp.indexOf(prob), 1)
  298. document.getElementsByTagName("center")[1+havenotice].getElementsByTagName("h2")[0].getElementsByTagName("a")[0].childNodes[0].childNodes[1].style.fill = "#cccccc"
  299. }
  300. else {
  301. markedp.push(prob)
  302. document.getElementsByTagName("center")[1+havenotice].getElementsByTagName("h2")[0].getElementsByTagName("a")[0].childNodes[0].childNodes[1].style.fill = "#FFFF00"
  303. }
  304. markedp.sort()
  305. savedata("marked", markedp)
  306. }
  307. }
  308.  
  309. if (isstatus() != -1) {
  310. for (var i of document.getElementsByTagName("center")[0].getElementsByTagName("table")[2].getElementsByTagName("tbody")[0].childNodes) {
  311. if (i.className != "evenrow" && i.className != "oddrow") continue;
  312. prob = i.childNodes[2].childNodes[0].innerText.trim();
  313. user = i.childNodes[1].childNodes[0].innerText.trim();
  314. stat = i.childNodes[3].childNodes[0].innerText.trim();
  315. if (stat == "Accepted" && readdata("userlist_" + user) != null) {
  316. udb = readdata("userlist_" + user)
  317. if (udb.indexOf(prob) == -1)
  318. udb.push(prob)
  319. savedata("userlist_" + user, udb)
  320. if (user == username)
  321. mydb.push(prob)
  322. }
  323. mkd = ""
  324. if (markedp.indexOf(prob) != -1)
  325. mkd = poly_star;
  326. if (mydb.indexOf(prob) != -1) {
  327. fky = "<span style=\"color:#00FF00\">Y</span>";
  328. }
  329. else {
  330. fky = "<span style=\"color:#FF0000\">N</span>";
  331. }
  332.  
  333. if (config['statusny'] == "0") fky = ""
  334. i.childNodes[2].childNodes[0].innerHTML = fky + i.childNodes[2].childNodes[0].innerHTML + mkd;
  335. }
  336. }
  337.  
  338. if (isconfig() != -1) {
  339. var usco =
  340. {
  341. "unmarkalert":
  342. {
  343. "name": "取消标记时弹窗确认",
  344. "0": "关闭",
  345. "1": "开启"
  346. },
  347. "autoext":
  348. {
  349. "name": "自动续命",
  350. "0": "关闭",
  351. "1": "开启"
  352. },
  353. "statusny":
  354. {
  355. "name": "Status页面显示是否AC",
  356. "0": "关闭",
  357. "1": "开启"
  358. }
  359. };
  360. tmpid = 0
  361. txt = "<h3>BZOJ Helper设置</h3>"
  362. document.getElementsByTagName("center")[1+havenotice].innerHTML += txt;
  363. for (i in usco) {
  364. txt = "<p>"
  365. txt += usco[i]["name"] + ":"
  366. chid = -1
  367. for (j in usco[i]) {
  368. if (j == "name") continue;
  369. txt += "<label for=\"tmprad" + tmpid + "\"><input id=\"tmprad" + tmpid + "\" type=\"radio\" value=\"" + j + "\" name=\"" + i + "\">" + usco[i][j] + "</label>"
  370. if (j == config[i])
  371. chid = tmpid
  372. tmpid++
  373. }
  374. txt += "</p>"
  375. document.getElementsByTagName("center")[1+havenotice].innerHTML += txt;
  376. document.getElementById("tmprad" + chid).setAttribute("checked", true)
  377. }
  378. document.getElementsByTagName("center")[1+havenotice].innerHTML += "<p><input id=\"helpersumbit\" type=\"button\" value=\"保存\"/></p>"
  379. document.getElementsByTagName("center")[1+havenotice].innerHTML += "<span style=\"color:#FF0000\" id=\"savesucci\" hidden=\"true\">保存成功</span>"
  380. document.getElementById("helpersumbit").onclick = function () {
  381. for (i in usco)
  382. config[i] = getradioval(i)
  383. savedata("config", config);
  384. document.getElementById("savesucci").removeAttribute("hidden")
  385. }
  386. }
  387.  
  388. if (isdiscusspage() != -1) {
  389. document.getElementsByTagName("center")[1+havenotice].childNodes[1].childNodes[1].innerHTML += document.getElementsByTagName("center")[1+havenotice].childNodes[1].childNodes[5].innerHTML;
  390. }
  391.  
  392. //自动续命
  393. document.getElementsByTagName("center")[0].childNodes[1].innerHTML += "<div class=\"tmp\" style=\"height:0px;width:0px;\"><img id=\"autofre\" src=\"data:image/png;base64,\" style=\"width:0px;height:0px;\"/></div>";
  394. if (config["autoext"] == "1") setInterval(function () { document.getElementById("autofre").src = "https://lydsy.com/JudgeOnline/" }, 600000);
  395. })();