Waypoints [Sploop.io]

Easily traverse the world of Sploop.io with Waypoints!

// ==UserScript==
// @name         Waypoints [Sploop.io]
// @name:zh      航点 [Sploop.io]
// @name:tr      Yolu Göstergeleri [Sploop.io]
// @name:ru      Точки маршрута [Sploop.io]
// @name:vi      Điểm chỉ đường [Sploop.io]
// @name:ar      علامات الطريق [Sploop.io]
// @description  Easily traverse the world of Sploop.io with Waypoints!
// @description:zh 轻松通过航点在Sploop.io世界中穿行!
// @description:tr  Kolayca Sploop.io dünyasında yol göstergeleri ile gezin!
// @description:ru  Легко путешествуйте по миру Sploop.io с помощью точек маршрута!
// @description:vi  Dễ dàng di chuyển trong thế giới Sploop.io với các điểm chỉ đường!
// @description:ar  اجتاز عالم Sploop.io بسهولة باستخدام علامات الطريق!
// @version      2.0.0
// @author       Hori + viper
// @match        https://sploop.io/
// @icon         https://i.ibb.co/ym4LXJF7/Waypoints-3-removebg-preview.png
// @grant        none
// @run-at       document-start
// @license      MIT
// @namespace https://gf.qytechs.cn/users/1441649
// ==/UserScript==

/**
 *  Authors: horizion, viper
 *
 *  Menu Keybind : ESCAPE
 *
 *  (!) - You are able to modify the script in any way, as long as it abides by the in-game rules.
 *  (!) - Contact Horizion if the script does not work.
 *
 *  Discord: horizon2025.#0000 | <@880415818142347297>
 *
 *  Official Sploop.io Discord Server: https://discord.com/invite/CYadgpyv78
 */

(function () {
	"use strict";
	const win = window;
	const log = console.log;
	const version = `2.0.0`;

	const ARROW_DISTANCE_FROM_PLAYER = 210;
	const COLORS = [
		"red",
		"orange",
		"yellow",
		"green",
		"dark_blue",
		"light_blue",
		"purple",
		"violet",
		"pink",
		"rose",
	];
	const MARKER_IMAGES = [
		"https://i.ibb.co/20h3vpRG/map-cross-red.png",
		"https://i.ibb.co/VWZCzbgK/map-cross-orange.png",
		"https://i.ibb.co/x8jT4J4x/map-cross-yellow.png",
		"https://i.ibb.co/dstqTPQP/map-cross-darkgreen.png",
		"https://i.ibb.co/dsSZtg0Q/map-cross-darkblue.png",
		"https://i.ibb.co/4RPBRMH7/map-cross-lightblue.png",
		"https://i.ibb.co/84KYxdNd/map-cross-purple.png",
		"https://i.ibb.co/8LJ4FbbW/map-cross-indigo.png",
		"https://i.ibb.co/bgNv5NB7/map-cross-pink.png",
		"https://i.ibb.co/5WMsX1f1/map-cross-main.png",
	];
	const ARROW_IMAGES = [
		"https://i.ibb.co/chgGndnF/arrow-red.png",
		"https://i.ibb.co/LdkChynd/arrow-orange.png",
		"https://i.ibb.co/v6x76XN6/arrow-yellow.png",
		"https://i.ibb.co/2YYvqNHj/arrow-darkgreen.png",
		"https://i.ibb.co/6RrD7MvR/arrow-darkblue.png",
		"https://i.ibb.co/9kqtG2k4/arrow-lightblue.png",
		"https://i.ibb.co/ZzjZhK0g/arrow-purple.png",
		"https://i.ibb.co/sdgDvP0Y/arrow-indigo.png",
		"https://i.ibb.co/yFFq6jBN/arrow-pink.png",
		"https://i.ibb.co/zT2rYdFT/arrow-main.png",
	];
	const MARKER_COLOR_IMAGES = {
		red: "https://i.ibb.co/ksRyM6FY/circle-red.png",
		orange: "https://i.ibb.co/4gNKXnp6/circle-orange.png",
		yellow: "https://i.ibb.co/60rHrBWP/circle-yellow.png",
		green: "https://i.ibb.co/kVGgcVKT/circle-green.png",
		dark_blue: "https://i.ibb.co/9mbLDCLq/circle-darkblue.png",
		light_blue: "https://i.ibb.co/LhNv7JXx/circle-lightblue.png",
		purple: "https://i.ibb.co/WvddsXyk/circle-purple.png",
		violet: "https://i.ibb.co/PZKjyN2g/circle-indigo.png",
		pink: "https://i.ibb.co/bf2LzgM/circle-pink.png",
		rose: "https://i.ibb.co/0pMvXrMS/circle-main.png",
	};

	let waypointID = 0;
	let waypoints = [];
	let cards = [];

	win.showWaypointArrows = 1;

	//** Styling DOM */

	const style = document.createElement("style");
	style.type = "text/css";
	style.textContent = `
        :root {
            --main: #de5978;
            --secondary: rgb(43, 37, 37, 1);
        }
        button:focus {
            border: none;
            outline: none;
        }
        input:focus {
            outline: none;
            border: none;
        }

        /* Making scroll bar more pro */

        ::-webkit-scrollbar {
            width: 7px;
        }

        ::-webkit-scrollbar-thumb {
            background-color: var(--main);
            border-top-right-radius: 10px;
            border-bottom-right-radius: 10px;
            border-top-left-radius: 0;
            border-bottom-left-radius: 0;
        }

        ::-webkit-scrollbar-track {
            background-color: var(--secondary);
            border-top-right-radius: 10px;
            border-bottom-right-radius: 10px;
            border-top-left-radius: 0;
            border-bottom-left-radius: 0;
        }

        /* Main menu styling */

        #wayMenu {
            display: none;
            position: fixed;
            top: 160px;
            left: 293px;
            z-index: 99999;
            padding: 20px;
            background: var(--secondary);
            border-radius: 10px;
            max-height: 60%;
            overflow-y: auto;
            width: 400px;
            border: 1.5px solid var(--main);
        }
        .wayHeader {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
        }
        .wayTitle {
            font-size: 20px;
            color: var(--main);
        }
        .version {
            font-size: 15px;
            color: rgba(100, 100, 100,1);
        }
        .wayArrowToggle {
            display: flex;
            align-items: center;
            gap: 5px;
            opacity: 0;
            transition: all 0.3s ease-in-out;
            pointer-events: none;
        }
        .wayArrowToggle i {
            color: var(--main);
            font-size: 18px;
        }

        .switch {
            position: relative;
            display: inline-block;
            width: 40px;
            height: 20px;
        }

        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }

        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgb(41, 41, 41);
            transition: 0.3s;
            border-radius: 20px;
            border: 1px solid rgb(112, 53, 74);
        }

        .slider:before {
            position: absolute;
            content: "";
            height: 14px;
            width: 14px;
            left: 3px;
            background-color: var(--main);
            bottom: 3px;
            transition: 0.3s;
            border-radius: 50%;
        }

        input:checked + .slider {
            background-color: rgba(187, 75, 101,0.6);
        }

        input:checked + .slider:before {
            transform: translateX(20px);
        }
        .wayCreateNewButton {
            margin-top: 25px;
            border: none;
            color: white;
            width: 250px;
            text-align: center;
            border-radius: 10px;
            padding: 7px;
            background: var(--main);
            font-size: 18px;
            cursor: pointer;
            font-weight: 990;
            height:35px;
            transition: transform 0.4s ease;
            border: 1px solid var(--secondary);
        }
        .wayCreateNewButton:hover {
            transform: translateY(-1px);
        }
        .wayCreateNewButton:disabled {
            background:rgb(187, 75, 101);
            color:rgba(156, 156, 156, 0.99);
            cursor: not-allowed;
            opacity: 0.85;
            transform: none;
        }
        .wayNotFound {
            text-align: center;
            display: block;
            font-size: 15px;
            color: white;
            margin-top: 20px;
        }
        .wayCreate {
        text-align: center;
        }

        /* popup styling */

        #wayPopMenu {
            display: block;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            padding: 25px;
            background: var(--secondary);
            border-radius: 10px;
            max-height: 50%;
            overflow-y: auto;
            text-align: center;
        }
        .popupHeader {
            position: absolute;
            top: 0;
            right: 8px;
            margin-bottom: 8px;
        }
        .closePopup {
            font-size: 24px;
            font-weight: bold;
            cursor: pointer;
            color: #fff;
        }
        .popupHeader:hover {
            transform: translateY(-1px);
        }
        #markerName {
            border-radius: 10px;
            height:35px;
            text-align: center;
            font-size: 16px;
            border: none;
            width: 200px;
        }
        #wayColors {
            padding: 7px;
            height:35px;
            width: 200px;
            border: none;
            border-radius: 10px;
            font-size: 16px;
            margin-bottom: 16px;
            background: #fff;
            color: #333;
            -webkit-appearance: none;
            -moz-appearance: none;
            appearance: none;
            text-align: center;
            font-weight: 800;
            cursor: pointer;
        }
        .wayCreateButton {
            border: none;
            color: white;
            width: 200px;
            text-align: center;
            border-radius: 10px;
            padding: 7px;
            background: var(--main);
            cursor: pointer;
            font-weight: 560;
            font-size: 16px;
            height:35px;
            transition: transform 0.4s ease;
        }
        .wayCreateButton:focus{
            border:none;
        }
        .wayCreateButton:hover {
            transform: translateY(-1px);
        }

        /* Card Styling */

        .card {
            display: flex;
            align-items: center;
            background:rgb(41, 41, 41);
            border-radius: 10px;
            padding: 10px;
            margin-top: 10px;
            color: white;
            border: 1px solid rgb(112, 53, 74);
        }

        .card img {
            width: 22px;
            height: 22px;
            margin-right: 10px;
            border-radius: 50%;
        }

        .card .card-name {
            flex: 4;
            font-size: 16px;
            margin-right: 10px;
            max-width: 145px;
        }

        .card .card-coords {
            flex: 3;
            font-size: 16px;
            margin-right: 10px;
            color: rgba(100, 100, 100,1);
        }

        .card .card-remove {
            background: #e43939;
            border: none;
            color: white;
            padding: 5px 10px;
            border-radius: 5px;
            cursor: pointer;
        }
        .card .card-remove:hover {
            transform: translateY(-1px);
        }
        #trash:hover {
            cursor: pointer;
        }
    `;
	document.head.appendChild(style);

	//** Main */

	document.addEventListener("DOMContentLoaded", () => {
		log(
			`%cWaypoints %cVersion ${version}\n%cCreators: %cviper + Hori`,
			"font-size: 90px; font-weight: 900; color: #de5978;",
			"font-size: 20px; color: gray;",
			"font-size: 20px; font-weight: 900; color:rgb(255, 255, 255); margin-top: 8px; margin-bottom: 10px;",
			"font-size: 20px; color:rgb(235, 187, 97); margin-top: 8px; margin-bottom: 10px;"
		);

		const wayMenu = document.createElement("div");
		wayMenu.id = "wayMenu";
		wayMenu.innerHTML = `
            <div class="wayHeader">
                <span class="wayTitle">Waypoints <span class="version">- v${version}</span></span>
                <div class="wayArrowToggle">
                    <i class="fa-solid fa-location-arrow"></i>
                    <label class="switch">
                        <input type="checkbox" id="waypointToggle" checked>
                        <span class="slider"></span>
                    </label>
                </div>
            </div>
            <div class="wayContent">
                <div id="wayNotFound" class="wayNotFound">
                    No Waypoints Found
                    <i class="fa-solid fa-magnifying-glass"></i>
                </div>
            </div>
            <div class="wayCreate">
                <button id="wayCreateNewButton" class="wayCreateNewButton" disabled>+</button>
            </div>
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css" integrity="sha512-SzlrxWUlpfuzQ+pcUCosxcglQRNAq/DZjVsC0lE40xsADsfeQoEypE+enwcOiGjk/bSuGGKHEyjSoQ1zVisanQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
        `;
		document.body.append(wayMenu);

		let isDragging = false,
			displayToggled = false,
			offsetX,
			offsetY;

		wayMenu.addEventListener("mousedown", function (event) {
			isDragging = true;
			offsetX = event.clientX - wayMenu.getBoundingClientRect().left;
			offsetY = event.clientY - wayMenu.getBoundingClientRect().top;
		});
		document.addEventListener("mousemove", function (event) {
			if (isDragging) {
				const newX = event.clientX - offsetX;
				const newY = event.clientY - offsetY;
				wayMenu.style.left = newX + "px";
				wayMenu.style.top = newY + "px";
			}
		});
		document.addEventListener("mouseup", () => {
			isDragging = false;
		});

		document
			.getElementById("wayCreateNewButton")
			.addEventListener("click", () => {
				if (!document.getElementById("wayPopMenu")) {
					createPopup();
				}
			});

		document.addEventListener("keydown", (event) => {
			if (event.key === "Escape" && !isChatWrapperVisible()) {
				wayMenu.style.display = displayToggled ? "none" : "block";
				displayToggled = !displayToggled;
			}
		});

		document
			.getElementById("waypointToggle")
			.addEventListener("change", function () {
				if (this.checked) {
					win.showWaypointArrows = 1;
				} else {
					win.showWaypointArrows = 0;
				}
			});

		const observer = new MutationObserver(() => {
			updateCreateButton();
		});
		const homepage = document.getElementById("homepage");
		if (homepage) {
			observer.observe(homepage, {
				attributes: true,
				attributeFilter: ["style"],
			});
		}
	});

	const addWaypoint = new Proxy(waypoints, {
		set(target, property, value, receiver) {
			const result = Reflect.set(target, property, value, receiver);
			if (!isNaN(property)) {
				createCard(value);
			}
			return result;
		},
	});

	function createPopup() {
		let wayPopMenu = document.createElement("div");
		wayPopMenu.id = "wayPopMenu";
		wayPopMenu.innerHTML = `
            <div class="popupHeader">
                <span id="closePopup" class="closePopup">x</span>
            </div>
            <div class="inputContainer">
                <input type="text" id="markerName"placeholder="New Waypoint" maxLength="13"><br><br>
            </div>
            <div class="wayColor">
                <select name="colors" id="wayColors">
                    <option value="0">Red</option>
                    <option value="1">Orange</option>
                    <option value="2">Yellow</option>
                    <option value="3">Green</option>
                    <option value="4">Dark Blue</option>
                    <option value="5">Light Blue</option>
                    <option value="6">Purple</option>
                    <option value="7">Violet</option>
                    <option value="8">Pink</option>
                    <option value="9">Rose</option>
                </select>
            </div>
            <div class="wayCreate">
                <button id="createButton" class="wayCreateButton">Create</button>
            </div>
        `;
		document.body.appendChild(wayPopMenu);

		document
			.getElementById("markerName")
			.addEventListener("keydown", function (event) {
				event.stopPropagation();
			});
		document.getElementById("closePopup").addEventListener("click", () => {
			wayPopMenu.remove();
		});
		document
			.getElementById("createButton")
			.addEventListener("click", getOption);
	}

	function createCard(waypoint) {
		cards.push({
			name: waypoint.name,
			id: waypoint.id,
		});

		const card = document.createElement("div");
		card.className = "card";
		card.innerHTML = `
            <img src="${MARKER_COLOR_IMAGES[waypoint.color]}" alt="color">
            <div class="card-name">${waypoint.name}</div>
            <div class="card-coords">[${Math.round(waypoint.x)},${Math.round(waypoint.y)}]</div>
            <button class="card-remove"><i class="fa-solid fa-trash" id="trash"></i></button>
        `;

		document.querySelector(".wayContent").appendChild(card);

		updateArrowToggleAlpha();

		const removeButton = card.querySelector(".card-remove");

		removeButton.addEventListener("click", function () {
			const waypointIndex = waypoints.findIndex(
				(way) => way.id === waypoint.id
			);
			if (waypointIndex > -1) {
				waypoints.splice(waypointIndex, 1);
			}
			const cardIndex = cards.findIndex(
				(card) => card.id === waypoint.id
			);
			if (cardIndex > -1) {
				cards.splice(cardIndex, 1);
			}
			card.remove();
			if (cards.length === 0) {
				document.getElementById("wayNotFound").style.display = "block";
			}
			updateArrowToggleAlpha();
		});
	}

	function createWaypoint(name, color) {
		const chosenMarker = MARKER_IMAGES[color];
		const chosenArrow = ARROW_IMAGES[color];

		const markerImg = createImage(chosenMarker);
		const arrowImg = createImage(chosenArrow);

		const newWaypoint = {
			name,
			id: waypointID++,
			arrow: arrowImg,
			marker: markerImg,
			x: win.coords.x,
			y: win.coords.y,
			color: COLORS[color],
		};

		addWaypoint.push(newWaypoint);
	}
	function getOption() {
		const markerName = document.getElementById("markerName").value;
		const wayColor = document.getElementById("wayColors");
		const color = wayColor.value;
		if (markerName !== "") {
			createWaypoint(markerName, color);
			document.getElementById("wayNotFound").style.display = "none";
			document.getElementById("wayPopMenu").remove();
		}
	}
	function updateCreateButton() {
		const button = document.getElementById("wayCreateNewButton");
		const homepage = document.getElementById("homepage");

		if (homepage && homepage.style.display === "flex") {
			button.disabled = true;
		} else {
			button.disabled = false;
		}
	}
	function updateArrowToggleAlpha() {
		const toggle = document.querySelector(".wayArrowToggle");
		if (toggle) {
			toggle.style.opacity = cards.length === 0 ? "0" : "1";
			toggle.style.pointerEvents = cards.length === 0 ? "none" : "auto";
		}
	}
	function createImage(URL) {
		const image = new Image();
		image.src = URL;
		return image;
	}
	function isChatWrapperVisible() {
		return (
			document.getElementById("chat-wrapper").style.display === "block"
		);
	}

	//** Draw Waypoints, Arrows, Names */

	class Drawing {
		arrows(context, arrow, angle, x, y) {
			context.save();
			context.globalAlpha = 0.52;
			context.translate(x, y);
			context.rotate(angle);
			context.drawImage(arrow, -25 / 2, -25 / 2, 25, 25);
			context.restore();
		}
		name(context, waypoint) {
			const x = waypoint.x;
			const y = waypoint.y - 42;

			context.font = "24px Baloo Paaji";
			context.textAlign = "center";
			context.lineWidth = 8;
			context.strokeStyle = "#414141";
			context.lineJoin = "round";
			context.strokeText(waypoint.name, x, y);
			context.fillStyle = "white";
			context.fillText(waypoint.name, x, y);
		}
		waypoint(context, waypoint) {
			context.drawImage(
				waypoint.marker,
				waypoint.x - 70 / 2,
				waypoint.y - 70 / 2,
				70,
				70
			);
		}
	}
	const Draw = new Drawing();

	win.draw = (context) => {
		waypoints.forEach((waypoint) => {
			const distance = Math.hypot(
				waypoint.x - win.coords.x,
				waypoint.y - win.coords.y
			);

			if (distance < 1200) {
				Draw.waypoint(context, waypoint);
				Draw.name(context, waypoint);
			}
			if (win.showWaypointArrows && distance > 450) {
				const angle = Math.atan2(
					waypoint.y - win.coords.y,
					waypoint.x - win.coords.x
				);
				let radius = ARROW_DISTANCE_FROM_PLAYER;

				const x = win.coords.x + Math.cos(angle) * radius;
				const y = win.coords.y + Math.sin(angle) * radius;

				Draw.arrows(context, waypoint.arrow, angle, x, y);
			}
		});
	};

	//** Hooking onto the game */

	const TYPEOF = (value) =>
		Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
	const NumberSystem = [
		{
			radix: 2,
			prefix: "0b0*",
		},
		{
			radix: 8,
			prefix: "0+",
		},
		{
			radix: 10,
			prefix: "",
		},
		{
			radix: 16,
			prefix: "0x0*",
		},
	];
	class Regex {
		constructor(code, unicode, namespace) {
			if (!namespace)
				namespace =
					"new_script_" + Math.random().toString(36).substr(2, 8);
			this.code = code;
			this.COPY_CODE = code;
			this.unicode = unicode || false;
			this.hooks = {};
			this.namespace = namespace;
			this.totalHooks = 0;
		}

		static parseValue(value) {
			try {
				return Function(`return (${value})`)();
			} catch (err) {
				return null;
			}
		}

		isRegexp(value) {
			return TYPEOF(value) === "regexp";
		}

		generateNumberSystem(int) {
			const template = NumberSystem.map(
				({ prefix, radix }) => prefix + int.toString(radix)
			);
			return `(?:${template.join("|")})`;
		}

		parseVariables(regex) {
			regex = regex.replace(/\{VAR\}/g, "(?:let|var|const)");
			regex = regex.replace(/\{QUOTE\}/g, "['\"`]");
			regex = regex.replace(/ARGS\{(\d+)\}/g, (...args) => {
				let count = Number(args[1]),
					arr = [];
				while (count--) arr.push("\\w+");
				return arr.join("\\s*,\\s*");
			});
			regex = regex.replace(/NUMBER\{(\d+)\}/g, (...args) => {
				const int = Number(args[1]);
				return this.generateNumberSystem(int);
			});
			return regex;
		}

		_hookName(name) {
			return `${this.namespace}:${name}`;
		}

		format(name, inputRegex, flags) {
			this.totalHooks++;
			let regex = "";
			if (Array.isArray(inputRegex)) {
				regex = inputRegex
					.map((exp) => (this.isRegexp(exp) ? exp.source : exp))
					.join("\\s*");
			} else if (this.isRegexp(inputRegex)) {
				regex = inputRegex.source;
			}
			regex = this.parseVariables(regex);
			if (this.unicode) {
				regex = regex.replace(/\\w/g, "(?:[^\\x00-\\x7F-]|\\$|\\w)");
			}
			const expression = new RegExp(
				regex.replace(/\{INSERT\}/, ""),
				flags
			);
			return regex.includes("{INSERT}")
				? new RegExp(regex, flags)
				: expression;
		}

		template(type, name, regex, substr) {
			const hookName = this._hookName(name);
			const expression = new RegExp(
				`(${this.format(hookName, regex).source})`
			);
			const match = this.code.match(expression) || [];
			this.code = this.code.replace(
				expression,
				type === 0 ? "$1" + substr : substr + "$1"
			);
			this.hooks[hookName] = { expression, match };
			return match;
		}

		logHooks() {
			log(
				"%cApplied Hooks:",
				"font-weight: bold; font-size: 24px; color:rgb(255, 255, 255); margin-top: 20px;"
			);
			let index = 1;
			for (const hookName in this.hooks) {
				const hook = this.hooks[hookName];
				const matches = Array.isArray(hook.match)
					? hook.match
					: [hook.match];
				const status =
					matches && matches.length > 0
						? "successful"
						: "unsuccessful";
				const style =
					matches && matches.length > 0
						? "color:rgb(134, 204, 125); font-size: 14px;"
						: "color:rgb(221, 94, 113); font-size: 14px;";
				log(`%c${index}. ${hookName} | ${status}`, style);
				index++;
			}
			log(
				"%c-----------------",
				"font-weight: bold; color: gray; margin-bottom: 5px; margin-top: 20px;"
			);
		}

		match(name, regex, flags) {
			const hookName = this._hookName(name);
			const expression = this.format(hookName, regex, flags);
			const match = this.code.match(expression) || [];
			this.hooks[hookName] = { expression, match };
			return match;
		}

		replace(name, regex, substr, flags) {
			const hookName = this._hookName(name);
			const expression = this.format(hookName, regex, flags);
			const preMatch = this.code.match(expression) || [];
			this.code = this.code.replace(expression, substr);
			this.hooks[hookName] = {
				expression,
				match: preMatch,
				replaced: preMatch.length > 0,
			};
			return this.code.match(expression) || [];
		}

		append(name, regex, substr) {
			return this.template(0, name, regex, substr);
		}

		prepend(name, regex, substr) {
			return this.template(1, name, regex, substr);
		}
	}

	const applyHooks = (code) => {
		const namespace = `waypoints_v${version}`;
		const Hook = new Regex(window.HOOKED_CODE || code, true, namespace);

		window.COPY_CODE = (Hook.COPY_CODE.match(
			/^(\(function \w+\(\w+\)\{.+)\(.+?\);$/
		) || [])[1];
		// log(Hook.COPY_CODE);

		if (!window.HOOKED_CODE)
			Hook.append(
				"EXTERNAL fix",
				/\(function (\w+)\(\w+\)\{/,
				"let $2 = eval(`(() => ${COPY_CODE})()`); delete window.COPY_CODE;"
			);
		Hook.replace("LOADER", /Loading Sploop.io/, `Loading...`);
		Hook.append(
			"COORDS",
			/,this\.\w{2}=0\},this\.\w{2}=\w+\((\w),(\w),\w\)\{/,
			`window.coords = { x: $2, y: $3 };`
		);
		Hook.prepend("DRAW",/\w=\w\[\w\(\)\.\w+\],\w=\w.{7,8};for\(let \w=\d;\w\W\w;\w\+\+\)!\(\w\[\w\]\.\w+&\w\(\)\.\w+\)&&\w+\(\w\[\w\],(\w),\w\);/,"/*55306335646D457A5457645A4D3070735756685362467044516D6C6C553046335A555657616D4649546C5A50626B70365756453950513D3D*/window.draw($2);");

		// log(Hook.code);
		window.HOOKED_CODE = Hook.code;

		Hook.logHooks();
		return Hook.code;
	};
	window.eval = new Proxy(window.eval, {
		apply(target, _this, args) {
			const code = args[0];
			if (code.length > 1e5) {
				args[0] = applyHooks(code);
				window.eval = target;
				target.apply(_this, args);
				return;
			}
			return target.apply(_this, args);
		},
	});
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址