MENDO.MK Enhancement

Adds dark mode, search in tasks and other stuff to MENDO.MK

目前為 2023-03-21 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         MENDO.MK Enhancement
// @version      23
// @namespace    mendo-mk-enhancement
// @description  Adds dark mode, search in tasks and other stuff to MENDO.MK
// @author       EntityPlantt
// @match        *://mendo.mk/*
// @noframes
// @icon         https://mendo.mk/img/favicon.ico
// @grant        none
// @license      CC-BY-ND
// ==/UserScript==

console.log("%cMENDO.MK Enhancement%c loaded", "color:magenta;text-decoration:underline", "");
var loadingSuccess = 0;
setTimeout(() => {
    if (loadingSuccess == 1) {
        console.log("Loading %csuccessful", "color:#4f4");
    }
	else if (loadingSuccess == 2) {
		console.log("Loading %cwith errors", "color:#ff0");
	}
    else {
        console.log("Loading %cunsuccessful", "color:red");
    }
}, 1000);
async function MendoMkEnhancement() {
	const VERSION = 23;
	try {
		function logFinish(taskName) {
			console.log("%cFinished task:%c " + taskName, "color:#0f0", "");
		}
		console.groupCollapsed("Start log");
		var style = document.createElement("style");
		style.innerHTML = `
${ // Dark mode
localStorage.getItem("mendo-mk-enhancement-theme") == "dark" ? `
html, img, svg, #cboxOverlay, .copy-io-btn span {
filter: invert(1) hue-rotate(180deg);
}
body, img, svg {
background: white;
}
::-webkit-scrollbar {
width: initial;
}
::-webkit-scrollbar-track {
background: #eee;
}
body::-webkit-scrollbar-track {
background: #111;
}
::-webkit-scrollbar-thumb {
background: #ddd;
}
body::-webkit-scrollbar-thumb {
background: #222;
}
td.solved, td.correct {
background: #bfb !important;
}
td.wrong {
background: #fbb !important;
}
` : ""}
#search {
font-family: consolas;
}
#search, #search-submit {
border: solid 2px black;
transition: box-shadow .5s;
}
#search-submit:hover {
cursor: pointer;
}
#search:focus {
background: #eee;
}
#search-submit:hover, #search:hover {
background: #ddd;
}
.copy-io-btn {
float: right;
background: #ddd;
padding: 5px;
cursor: pointer;
border-radius: 5px;
user-select: none;
}
.copy-io-btn:hover {
background: #e8e8e8;
}
#search:active, #search:focus, #search-submit:active, #search-submit:focus {
box-shadow: 0 0 2.5px 2.5px black;
}
@keyframes gta-cinematic-image {
0%, 50% {filter: blur(500px);}
10%, 40% {filter: blur(0px);}
}
td.share-solved {
background: #ac0 !important;
}
.update-available {
animation: update-available .5s infinite linear;
}
@keyframes update-available {
from, to {color: red}
50% {color: white}
}
`;
		document.head.appendChild(style);
		logFinish("inject style sheet");
		if (document.querySelector(".sitename h1 a")) {
			document.querySelector(".sitename h1").innerHTML += " <a href='https://greasyfork.org/en/scripts/450985-mendo-mk-enhancement' id=enhancement-logo><em><b>Enhanced</b></em></a>";
		}
		logFinish("complete site logo");
		var cfUpdt = await fetch("https://greasyfork.org/scripts/450985-mendo-mk-enhancement/code/MENDOMK%20Enhancement.user.js").then(x => x.text());
		if (parseInt(/@version *?(\d+)/.exec(cfUpdt)[1]) > VERSION) {
			alert(document.cookie.includes("mkjudge_language=en") ? "Script MENDO.MK Enhancement updated. Install new version to remove this message." : "Скриптот MENDO.MK Enhancement е ажуриран. Инсталирај ја новата верзија за да ја тргнеш оваа порака.");
			if (document.getElementById("enhancement-logo")) {
				document.getElementById("enhancement-logo").classList.add("update-available");
				document.querySelector("#enhancement-logo b").innerText = "Click & Update!";
			}
		}
		logFinish("check for updates");
		if (document.URL.includes("/Training.do") || document.URL.includes("/User_Competition.do")) {
			var search = document.createElement("form");
			search.className = "content-search";
			search.action = "#";
			search.innerHTML = `
        <input type=text id=search autocomplete=off>
        <input type=submit id=search-submit value=Search>
        `;
			search.onsubmit = e => {
				e.preventDefault();
				location.hash = "#" + escape(search.querySelector("#search").value);
				search.querySelector("#search").blur();
				hashChange();
			}
			function hashChange() {
				if (document.activeElement == search.querySelector("#search")) {
					return;
				}
				var kw = unescape(location.hash.substr(1));
				search.querySelector("#search").value = kw;
				kw = kw.toLowerCase();
				document.querySelectorAll("body > div.page-container > div.main > div.main-content > div:nth-child(4) > div > table > tbody > tr").forEach(elm => {
					if (!elm.querySelector("td:nth-child(2) > a")) {
						return;
					}
					if (elm.innerText.toLowerCase().includes(kw) || elm.querySelector("td:nth-child(2) > a").href.toLowerCase().includes(kw)) {
						elm.style.display = "";
					}
					else {
						elm.style.display = "none";
					}
				});
			}
			window.onhashcange = hashChange;
			setInterval(hashChange, 500);
			document.querySelector(".main-content").prepend(search);
			logFinish("add task search bar");
			document.querySelector("body > div.page-container > div.main > div.main-content > div:nth-child(3)").innerHTML += `<a href="./Training.do?cid=5">[ ${document.cookie.includes("mkjudge_language=en") ? "Other tasks" : "Други задачи"} ]</a>&nbsp;&nbsp;`;
			document.querySelector("body > div.page-container > div.main > div.main-content > div:last-child").innerHTML =
				document.querySelector("body > div.page-container > div.main > div.main-content > div:nth-child(3)").innerHTML;
			logFinish("add secret tasks");
		}
		if (document.querySelector("body > div.page-container > div.header > div.header-bottom > div")) {
			document.querySelector("body > div.page-container > div.header > div.header-bottom > div").innerHTML += `<ul><li><a style="
			background-image: url(https://evolveyoursuccess.com/wp-content/uploads/2019/12/lightbulb-icon-png-icon-transparent-light-bulb-png.png);
			background-size: 12.5px;
			" href='/algoritmi'>${document.cookie.includes("mkjudge_language=en") ? "II Algorithms" : "ИИ Алгоритми"}</a></li></ul>`;
			document.querySelector("body > div.page-container > div.header > div.header-bottom > div > ul:nth-child(1) > li > a").href = "/";
			document.querySelector("body > div.page-container > div.header > div.header-bottom > div > ul:nth-child(2) > li > a").href = "/Training.do";
			document.querySelector("body > div.page-container > div.header > div.header-bottom > div > ul:nth-child(2) > li > a").className = "";
			document.querySelectorAll("div.main-content > div:nth-child(3) > div > table > tbody > tr > td:nth-child(2) > a").forEach(e => {
				e.target = "_blank";
			});
			logFinish("make task links open in another window");
			if (document.URL.includes("/Training.do")) {
				var taskShare = document.createElement("div");
				taskShare.style.marginBottom = "10px";
				taskShare.innerHTML = `
<button id=solved-tasks-save>${document.cookie.includes("mkjudge_language=en") ? "Share solved tasks" : "Сподели решени задачи"}</button>
<button id=solved-tasks-load>${document.cookie.includes("mkjudge_language=en") ? "Load shared solved tasks from clipboard" : "Лоадирај споделени решени задачи од клипборд"}</button>`;
				taskShare.querySelector("#solved-tasks-save").onclick = () => {
					var array = [];
					document.querySelectorAll("body > div.page-container > div.main > div.main-content > div:nth-child(5) > div > table > tbody > tr > td:first-child").forEach(td => {
						if (td.className == "solved") array.push(td.innerText.substr(0, td.innerText.length - 1));
					});
					array.unshift("mendo-reseni-zadaci");
					navigator.clipboard.writeText(array.join(","));
				};
				taskShare.querySelector("#solved-tasks-load").onclick = async() => {
					var array = (await navigator.clipboard.readText()).split(",");
					if (array[0] != "mendo-reseni-zadaci") {
						alert(document.cookie.includes("mkjudge_language=en") ? "Invalid task solve share schema in clipboard!" : "Невалидна шема на споделени решени задачи во клипборд!");
						return;
					}
					array.shift();
					document.querySelectorAll("body > div.page-container > div.main > div.main-content > div:nth-child(5) > div > table > tbody > tr > td:first-child").forEach(td => {
						if (array.includes(td.innerText.substr(0, td.innerText.length - 1))) td.classList.add("share-solved"); else td.classList.remove("share-solved");
					});
				};
				document.querySelector(".main-content").prepend(taskShare);
				logFinish("add task share");
			}
		}
		logFinish("add ii algorithm button");
		if (document.querySelector("body > div.page-container > div.header > div.header-breadcrumbs > ul > li:last-child > a")) {
			window.name = document.querySelector("body > div.page-container > div.header > div.header-breadcrumbs > ul > li:last-child > a").innerText;
		}
		else if (document.querySelector(".pagetitle")) {
			window.name = document.querySelector(".pagetitle").innerText;
		}
		document.title = (document.querySelector("body > div.page-container > div.header > div.header-breadcrumbs > ul > li:last-child > a")
		?? document.querySelector(".pagetitle")
		?? document.querySelector(".pagename")
		?? {innerText: document.URL.substr(document.URL.indexOf("/", 8) + 1)}
		).innerText + " – МЕНДО";
		logFinish("document title set");
		if (document.URL.includes("/Task.do")) {
			document.querySelectorAll("body > div.page-container > div.main > div.main-content > div.column1-unit.taskContentView > table pre").forEach(pre => {
				var text = pre.innerText.substr(pre.innerText.indexOf("\n") + 1);
				var copyIoBtn = document.createElement("span");
				copyIoBtn.innerHTML = "<span>📃</span>";
				copyIoBtn.setAttribute("onclick", `navigator.clipboard.writeText(${JSON.stringify(text)})`);
				copyIoBtn.className = "copy-io-btn";
				pre.parentElement.appendChild(copyIoBtn);
			});
			logFinish("copy io buttons");
			var navArrows = document.createElement("div");
			navArrows.innerHTML = `
			<a href="${document.URL.substr(0, document.URL.lastIndexOf("=") + 1) + (parseInt(document.URL.substr(document.URL.lastIndexOf("=") + 1)) - 1)}">&lt;</a>
			<a href="${document.URL.substr(0, document.URL.lastIndexOf("=") + 1) + (parseInt(document.URL.substr(document.URL.lastIndexOf("=") + 1)) + 1)}" style="float:right">&gt;</a>
			`;
			navArrows.style.fontSize = "40px";
			navArrows.style.marginBottom = "20px";
			document.querySelector(".main-content").prepend(navArrows);
			logFinish("add nav buttons");
			document.querySelector(".pagetitle").style.textAlign = "center";
			logFinish("center title text");
		}
		(document.querySelector(".footer") ?? {}).innerHTML += `<p class="credits"><a href="https://greasyfork.org/en/scripts/450985-mendo-mk-enhancement">MENDO.MK Enhancement</a> <a href="javascript:toggleTheme()">🎨</a></p>`;
		window.toggleTheme = () => {
			localStorage.setItem("mendo-mk-enhancement-theme", localStorage.getItem("mendo-mk-enhancement-theme") == "dark" ? "light" : "dark");
			location.reload();
		};
		logFinish("dark mode button");
		loadingSuccess = 1;
		if (/^https?:\/\/mendo\.mk\/.+\.do/.test(document.URL) && Math.random() < .01) {
			document.querySelector(".sitelogo").style.backgroundImage = "url(https://i1.sndcdn.com/artworks-TWCDacMc5lCrZIPb-2W7mgg-t500x500.jpg)";
			document.querySelector(".sitelogo").style.backgroundSize = "contain";
			document.querySelector(".sitename h1 a").innerText = "𝐎 𝐁 𝐀 𝐌 𝐈 𝐔 𝐌";
			document.querySelector(".sitename h2 a").innerText = "𝐋𝐞𝐭 𝐎𝐛𝐚𝐦𝐢𝐮𝐦 𝐛𝐥𝐞𝐬𝐬 𝐲𝐨𝐮";
			(document.querySelector(".footer") || {}).innerHTML = "<p>𝐋𝐞𝐭 𝐎𝐛𝐚𝐦𝐢𝐮𝐦 𝐛𝐥𝐞𝐬𝐬 𝐲𝐨𝐮</p>";
			document.querySelectorAll("img").forEach(elm => {
				elm.src = "https://i1.sndcdn.com/artworks-TWCDacMc5lCrZIPb-2W7mgg-t500x500.jpg";
				elm.width = elm.height ||= 50;
			});
			document.querySelector("link[rel*=icon]").href = "https://i1.sndcdn.com/artworks-TWCDacMc5lCrZIPb-2W7mgg-t500x500.jpg";
			document.querySelector("link[rel*=icon]").removeAttribute("type");
			document.title = "𝐎 𝐁 𝐀 𝐌 𝐈 𝐔 𝐌";
			logFinish("obamium");
		}
		if (/^https?:\/\/mendo\.mk\/.*?User_Submission.do\?/.test(document.URL)) {
			function checkForCinematic() {
				var usubTBody = document.querySelector("body > div.page-container > div.main > div.main-content > div > div > table:nth-child(6) > tbody");
				if (!usubTBody) {
					requestAnimationFrame(checkForCinematic);
				}
				else if (usubTBody.querySelectorAll("tr td.correct:first-child").length + 1 >= usubTBody.querySelectorAll("tr").length) {
					taskSolveCinematic(true);
				}
				else {
					taskSolveCinematic(false);
				}
			}
			checkForCinematic();
			logFinish("task solve cinematic setup");
		}
	}
	catch (_) {
		console.error(_);
		loadingSuccess = 2;
	}
	console.groupEnd();
}
function taskSolveCinematic(solved) {
	var preCinematicScreen = document.createElement("div");
	preCinematicScreen.style = `
	top: 0px; left: 0px; position: fixed; width: 100vw; height: 100vh;
	background: white; font-size: 20px; cursor: pointer; z-index: 99999;
	`;
	preCinematicScreen.innerHTML = `
	<div style="color: black; position: fixed; top: 50vh; left: 50vw; transform: translate(-50%, -50%);">[ ${document.cookie.includes("mkjudge_language=en") ? "Reveal" : "Откриј"} ]</div>
	<div style="color: black; position: fixed; top: 10px; right: 10px;" id=skip-cinematic>${document.cookie.includes("mkjudge_language=en") ? "Skip if correct" : "Скокни ако точно"} &gt;&gt;</div>
	`;
	preCinematicScreen.onclick = () => {
	    preCinematicScreen.remove();
		if (window.event.target.id == "skip-cinematic" || !solved) return;
		var cinematics = [() => {
			var img = document.createElement("img");
			img.src = "https://i.ibb.co/b7WW8Q3/mission-passed.png";
			img.style = "animation: gta-cinematic-image 15s 1 linear; position: fixed; top: 0; left: 0; width: 100vw; background: transparent !important";
			var audio = document.createElement("audio");
			audio.src = "https://dl.sndup.net/fmjm/mission%20passed%20audio.mp3";
			audio.play();
			document.body.appendChild(img);
			setTimeout(() => img.remove(), 10000);
		}];
		cinematics[Math.floor(Math.random() * cinematics.length)]();
	};
	document.body.appendChild(preCinematicScreen);
}
window.MendoMkEnhancement = MendoMkEnhancement;
window.taskSolveCinematic = taskSolveCinematic;
MendoMkEnhancement();