Greasy Fork

Greasy Fork is available in English.

Shell Shockers | All in One

This script gathers most of my mods into 1 place

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Shell Shockers | All in One
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_listValues
// @grant        GM_info
// @grant        GM_setClipboard
// @grant        GM_openInTab
//
// @grant        GM.setValue
// @grant        GM.getValue
// @grant        GM.deleteValue
// @grant        GM.listValues
// @grant        GM.info
// @grant        GM.setClipboard
// @grant        GM.openInTab

// @grant        none
// @run-at       document-start
// @require      https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js
// @require     https://cdn.jsdelivr.net/npm/[email protected]/dist/tweakpane.min.js
// @require      https://cdn.jsdelivr.net/npm/@tweakpane/[email protected]/dist/tweakpane-plugin-essentials.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js
//
// @license MIT
// @namespace http://greasyfork.icu/users/1361048

// @version     3.7
// @author      wish?
// @description This script gathers most of my mods into 1 place

// @match        *://*.shellshock.io/*
// @match        *://*.shell.onlypuppy7.online/*
// @match        *://*.algebra.best/*
// @match        *://*.algebra.vip/*
// @match        *://*.biologyclass.club/*
// @match        *://*.deadlyegg.com/*
// @match        *://*.deathegg.world/*
// @match        *://*.eggboy.club/*
// @match        *://*.eggboy.xyz/*
// @match        *://*.eggcombat.com/*
// @match        *://*.egg.dance/*
// @match        *://*.eggfacts.fun/*
// @match        *://*.egghead.institute/*
// @match        *://*.eggisthenewblack.com/*
// @match        *://*.eggsarecool.com/*
// @match        *://*.geometry.best/*
// @match        *://*.geometry.monster/*
// @match        *://*.geometry.pw/*
// @match        *://*.geometry.report/*
// @match        *://*.hardboiled.life/*
// @match        *://*.hardshell.life/*
// @match        *://*.humanorganising.org/*
// @match        *://*.mathactivity.xyz/*
// @match        *://*.mathactivity.club/*
// @match        *://*.mathdrills.info/*
// @match        *://*.mathdrills.life/*
// @match        *://*.mathfun.rocks/*
// @match        *://*.mathgames.world/*
// @match        *://*.math.international/*
// @match        *://*.mathlete.fun/*
// @match        *://*.mathlete.pro/*
// @match        *://*.overeasy.club/*
// @match        *://*.risenegg.com/*
// @match        *://*.scrambled.tech/*
// @match        *://*.scrambled.today/*
// @match        *://*.scrambled.us/*
// @match        *://*.scrambled.world/*
// @match        *://*.shellshockers.club/*
// @match        *://*.shellshockers.life/*
// @match        *://*.shellshockers.site/*
// @match        *://*.shellshockers.us/*
// @match        *://*.shellshockers.world/*
// @match        *://*.shellshockers.xyz/*
// @match        *://*.shellsocks.com/*
// @match        *://*.softboiled.club/*
// @match        *://*.urbanegger.com/*
// @match        *://*.violentegg.club/*
// @match        *://*.violentegg.fun/*
// @match        *://*.yolk.best/*
// @match        *://*.yolk.life/*
// @match        *://*.yolk.rocks/*
// @match        *://*.yolk.tech/*
// @match        *://*.yolk.quest/*
// @match        *://*.yolk.today/*
// @match        *://*.zygote.cafe/*
// @match        *://*.shellshockers.best/*
// @match        *://*.eggboy.me/*
// @match        *://*.shellshock.guru/*
// ==/UserScript==
(function () {
	let noPointerPause;
	const clientKeysURL = `https://raw.githubusercontent.com/StateFarmNetwork/client-keys/refs/heads/main/statefarm_`;
	let ss;
	let F = [];
	let H = {};
	let playerArr = [];
	let functionNames = [];
	let keyRetrieved = false;

	const tp = {
		mainCH: {
			color: "#fff",
			length: 0.8,
			width: 0.3,
			opacity: 0.7,
			border: "#000000",
			rotate: 0,
		},
		middleDot: {
			opacity: 1,
			color: "#000",
			border: "#000",
			size: 0.2,
			round: false,
			shape: "Dot",
			length: 0.2,
			width: 0.2,
		},
		FPS: {
			hide: false,
			min: 20,
			max: 200,
			random: false,
		},
		ping: {
			min: 20,
			max: 200,
			random: false,
		},
		sounds: {
			crackshot: "default",
			"egg-k": "default",
			scrambler: "default",
			"free-ranger": "default",
			rpegg: "default",
			whipper: "default",
			"tri-hard": "default",
			pistol: "default",
		},
		meleeSounds: {
			melee: "default",
		},
		extra: {
			disableScopeLines: false,
		},
		paneSettings: {
			width: 300,
			tabout: "`",
			hidePanel: "h",
			refreshSounds: "g",
		},
	};

	const startUp = function () {
		console.log("startup");
		injectScript();
		console.log("after startup");
	};

	let originalReplace = String.prototype.replace;
	let originalReplaceAll = String.prototype.replaceAll;

	String.prototype.originalReplace = function () {
		return originalReplace.apply(this, arguments);
	};
	String.prototype.originalReplaceAll = function () {
		return originalReplaceAll.apply(this, arguments);
	};

	const log = function (...args) {
		let condition;
		try {
			condition = false;
		} catch (error) {
			condition = GM_getValue(storageKey + "DisableLogs");
		}
		if (!condition) {
			console.log(...args);
		}
	};

	const fetchTextContent = function (url) {
		try {
			var xhr = new XMLHttpRequest();
			xhr.open("GET", url, false);
			xhr.send();
			if (xhr.status === 200) {
				return xhr.responseText;
			} else {
				console.error("Error fetching " + url);
				return null;
			}
		} catch (err) {
			return null;
		}
	};
	const findKeyWithProperty = function (obj, propertyToFind) {
		for (const key in obj) {
			if (obj[key] === null || obj[key] === undefined) {
				continue;
			}
			if (
				!!obj[key] &&
				(typeof obj[key] == "object" || typeof obj[key] == "function") &&
				obj[key].hasOwnProperty(propertyToFind)
			) {
				return key;
			}
		}
		// Property not found
		return null;
	};
	const getScrambled = () =>
		Array.from({ length: 10 }, () =>
			String.fromCharCode(97 + Math.floor(Math.random() * 26)),
		).join("");
	const createAnonFunction = function (name, func) {
		const funcName = getScrambled();
		window[funcName] = func;
		window[funcName] = function () {
			try {
				return func.apply(this, arguments);
			} catch (error) {
				log("Error in anonymous function:", error);
			}
		};

		F[name] = window[funcName];
		functionNames[name] = funcName;
	};

	function loadExistingSettings(name, target, callback) {
		const stuff = localStorage.getItem(name);

		if (stuff) {
			const parsed = JSON.parse(stuff);

			Object.assign(target, parsed);
			if (typeof callback === "function") callback();
		}
	}

	function updateSounds() {
		const players = window.players;
		if (!players) return;
		const H = window.H;

		const WEAPON_SOUND_MAP = {
			gun_m24: "crackshot",
			gun_eggk47: "egg-k",
			gun_dozenGauge: "scrambler",
			gun_csg1: "free-ranger",
			gun_rpegg: "rpegg",
			gun_smg: "whipper",
			gun_aug: "tri-hard",
			gun_cluck9mm: "pistol",
		};

		for (const player of players) {
			if (!player?.hasOwnProperty("ws")) continue;
			H.actor = findKeyWithProperty(player, H.mesh);

			for (const wp of player.weapons) {
				let weaponObj = wp[H.actor];
				let myWeaponName = wp[H.actor][H.extra.weapon];

				weaponObj.defaultSound ??= weaponObj.fireSound;

				const soundKey = WEAPON_SOUND_MAP[myWeaponName];
				if (soundKey) {
					const sound = tp.sounds[soundKey];
					weaponObj.fireSound =
						sound === "fire" ? weaponObj.defaultSound : `${myWeaponName}_${sound}`;
				}
			}

			player.meleeWeapon[H.actor].defaultSound ??= player.meleeWeapon[H.actor].swingSounds;

			// MELEE (MELEE default sound: [melee_whisk_a])
			// check if the sound saved in tp is the default sound
			// player.meleeWeapon[H.actor].swingSounds =
			// 	tp.meleeSounds["melee"][0] === "melee_whisk_a"
			// 		? player.meleeWeapon[H.actor].defaultSound
			// 		: tp.meleeSounds["melee"];

			if (Array.isArray(tp.meleeSounds["melee"])) {
				// its an array, meaning its not the default sound
				player.meleeWeapon[H.actor].swingSounds = [tp.meleeSounds["melee"][Math.floor(Math.random() * tp.meleeSounds["melee"].length)]]
				// Only the default option is a string, the rest are all in an array
				player.meleeWeapon[H.actor].swingSounds = player.meleeWeapon[H.actor].defaultSound;
			}
		}
	}

	const injectScript = function () {
		createAnonFunction("adBlocker", function (input) {
			try {
				if (input == 10 && false) {
					return 1;
				} else if (true) {
					if (typeof input == "boolean") {
						return true;
					} else if (input == 10) {
						return 5;
					} else if (input == "adsBlocked") {
						return false;
					}
				}
				return input;
			} catch (error) {
				return true;
			}
		});

		createAnonFunction("FakePing", function (original) {
			if (tp.ping.random) {
				const randomPing =
					Math.floor(Math.random() * (tp.ping.max - tp.ping.min + 1)) + tp.ping.min;
				return randomPing;
			} else {
				return Date.now() - original;
			}
		});
		createAnonFunction("FakeFps", function (original) {
			if (tp.FPS.hide) return "";
			if (tp.FPS.random) {
				const randomPing =
					Math.floor(Math.random() * (tp.FPS.max - tp.FPS.min + 1)) + tp.FPS.min;
				return randomPing;
			} else {
				return original;
			}
		});

		createAnonFunction("disableScopeLines", function () {
			return tp.extra.disableScopeLines ? "0" : "536870912";
		});

		let _apc = HTMLElement.prototype.appendChild;
		let shellshock_og = null;

		HTMLElement.prototype.appendChild = function (node) {
			if (
				node.tagName === "SCRIPT" &&
				node.innerHTML &&
				node.innerHTML.startsWith("(()=>{")
			) {
				shellshock_og = node.innerHTML;
				node.innerHTML = applyScript(node.innerHTML);
			}
			return _apc.call(this, node);
		};

		const proto = window.HTMLScriptElement.prototype;
		const existing = Object.getOwnPropertyDescriptor(proto, "textContent");

		const original =
			existing || Object.getOwnPropertyDescriptor(window.Node.prototype, "textContent");

		Object.defineProperty(proto, "textContent", {
			get: function () {
				// if (this === window.document.currentScript) {
				//     prompt("[Hook] document.currentScript.textContent accessed");
				//     debugger; // <-- triggers breakpoint
				// };
				let textContent = original.get.call(this);
				if (textContent && textContent.startsWith("(()=>{")) {
					return shellshock_og;
				} else {
					return textContent;
				}
			},
			set: original.set,
			configurable: true,
			enumerable: true,
		});

		const applyScript = function (js) {
			let match;
			let clientKeys;
			console.log(js);

			let originalJS = fetchTextContent("/js/shellshock.js");

			const getVardata = function () {
				return fetchTextContent(clientKeysURL + "latest.json?v=" + Date.now());
			};

			// console.log(hash);
			let onlineClientKeys = getVardata();

			try {
				clientKeys = JSON.parse(onlineClientKeys);
			} catch (e) {
				console.error(e);
			}

			let H = clientKeys.vars;
			let C = clientKeys.commCodes?.codes;

			const patterns = {
				scope: /,this\.(..)\.position\.z=2/,
				ping: /(case [A-Za-z$_]+\.[A-Za-z$_]+\:[A-Za-z$_]+\=)Date\.now\(\)-([A-Za-z$_]+),/,
				fps: /(document\.getElementById\("FPS"\)\.innerText=)(.*?)}/,
				spec: /received"\),(.*?)=.*?\.unPackInt8U\(\)/,
				weapon: /this\.([a-zA-Z0-9_$]+)\=\"gun\_/,
			};

			const scopeVar = patterns.scope.exec(js)[1];
			const fpsVar = patterns.fps.exec(js);
			const specVar = patterns.spec.exec(js);
			H.extra = {
				scope: scopeVar,
				fps: fpsVar,
				spec: specVar,
				ping: patterns.ping.exec(js),
				weapon: patterns.weapon.exec(js)[1],
			};
			window.H = H;

			let injectionString = "";

			try {
				//SERVERSYNC
				match = new RegExp(`function serverSync\\(\\)\\{(.*?)\\)\\}`).exec(js);
				log("SERVERSYNC:", match);
				H.SERVERSYNC = match
					? match[1].replace(/[a-zA-Z$_\.\[\]]+shots/, 0) + ")"
					: "function(){log('no serversync womp womp')}";
				//PAUSE
				match = new RegExp(
					`,setTimeout\\(\\(\\(\\)=>\\{([=A-z0-9\\(\\),\\{ \\.;!\\|\\?:\\}]+send\\([a-zA-Z$_]+\\))`,
				).exec(js);
				log("PAUSE:", match);
				H.PAUSE = match
					? `function(){${match[1]}}`
					: "function(){log('no pause womp womp')}";

				const variableNameRegex = /^[a-zA-Z0-9_$\[\]"\\\.,]*$/;
				console.log(H);
				for (let name in H) {
					let deobf = H[name];
					if (name == "SERVERSYNC" || name == "PAUSE" || variableNameRegex.test(deobf)) {
						//serversync should only be defined just before...
						injectionString = `${injectionString}${name}:  (() => { let variable = "value_undefined"; try { eval("variable = ${deobf};"); } catch (error) { return "value_undefined"; }; return variable; })(),`;
					} else {
					}
				}
				console.log(injectionString);

				log(
					"%cSTATEFARM INJECTION STAGE 1: GATHER VARS",
					"color: yellow; font-weight: bold; font-size: 1.2em; text-decoration: underline;",
				);

				const modifyJS = function (find, replace) {
					let oldJS = js;
					try {
						js = js.originalReplaceAll(find, replace);
					} catch (err) {
						console.log(
							"%cReplacement failed! Likely a required var was not found. Attempted to replace " +
								find +
								" with: " +
								replace,
							"color: red; font-weight: bold; font-size: 0.6em; text-decoration: italic;",
						);
					}
					if (oldJS !== js) {
						console.log(
							"%cReplacement successful! Injected code: replaced: " +
								find +
								" with: " +
								replace,
							"color: green; font-weight: bold; font-size: 0.6em; text-decoration: italic;",
						);
					} else {
						console.log(
							"%cReplacement failed! Attempted to replace " +
								find +
								" with: " +
								replace,
							"color: red; font-weight: bold; font-size: 0.6em; text-decoration: italic;",
						);
					}
				};

				const f = function (varName) {
					return varName.replace("$", "\\$");
				};
				const FUNCTIONPARAM = new RegExp(
					"function " + f(H._connectFail) + "\\(([a-zA-Z$_]+)\\)",
				).exec(js)[1];
				const v = `[a-zA-Z_$][a-zA-Z0-9_$]*`;
				const regex = (strings, ...values) =>
					new RegExp(
						strings.raw.reduce((acc, str, i) => acc + str + (values[i] ?? ""), ""),
						"g",
					);

				// ad-blocker
				modifyJS(
					"adsBlocked=" + FUNCTIONPARAM,
					"adsBlocked=" + functionNames.adBlocker + '("adsBlocked")',
				);
				modifyJS('"user-has-adblock"', functionNames.adBlocker + '("user-has-adblock")');
				modifyJS("layed=!1", "layed=window." + functionNames.adBlocker + "(!1)");
				modifyJS("showAdBlockerVideo", "hideAdBlockerVideo"); //hello eggs bullshit
				match = js.match(/return ([A-Za-z0-9_$]+)\.productBlockAds\}/);
				H.USERDATA = match[1];
				modifyJS(
					H.USERDATA + ".playerAccount.isUpgraded()",
					functionNames.adBlocker + "(" + f(H.USERDATA) + ".playerAccount.isUpgraded())",
				);

				// chat filter
				match = js.match(/this\.lastControlTeam=255\,.*?function ([A-z]+)\((.)\)/);
				H.isBadWord = match[1];
				H._insideFilterFunction = match[2];
				modifyJS(
					`!${f(H.isBadWord)}(${f(H._insideFilterFunction)})`,
					`((!${f(H.isBadWord)}(${f(H._insideFilterFunction)}))||true)`,
				);
				let [_, elm, str] = js.match(/\)\),([a-zA-Z$_]+)\.innerHTML=([a-zA-Z$_]+),/);
				modifyJS(
					_,
					_ +
						`${f(
							H.isBadWord,
						)}(${str})&&true&&!arguments[3]&&(${elm}.style.color="red"),`,
				);

				// remove mouse down console logs
				const r = /,?console\.log\(\`Mouse button .*?\`\),?/gm;
				const matches = js.match(r);

				if (matches) {
					for (const m of matches) {
						modifyJS(m, "");
					}
				}

				// FPS & PING
				modifyJS(
					H.extra.ping[0],
					`${H.extra.ping[1]}window.${functionNames.FakePing}(${H.extra.ping[2]}),`,
				);
				modifyJS(
					H.extra.fps[0],
					`${H.extra.fps[1]}window.${functionNames.FakeFps}(${H.extra.fps[2]})}`,
				);

				//SCOPE LINES
				modifyJS(
					`this.${H.extra.scope}.applyFog=!1,this.${H.extra.scope}.layerMask=536870912,`,
					`this.${H.extra.scope}.applyFog=!1,this.${H.extra.scope}.layerMask=window.${functionNames.disableScopeLines}(),`,
				);

				// GET PLAYERS
				match = js.match(/(([a-zA-Z_$][a-zA-Z0-9_$])\[this\.playerIdx\])/);
				modifyJS(`${match[2]}=[]`, `${match[2]}=[],window.players=${match[2]}`);

				log(H, "last");
				return js;
			} catch (e) {
				console.log(e);
			}
		};
	};
	// injectScript();
	startUp();

	function waitForElement(selector) {
		return new Promise((resolve) => {
			const intervalId = setInterval(() => {
				const element = document.getElementById(selector);
				console.log("looking for", selector);
				if (element) {
					console.dir(`found: ${element}`);
					clearInterval(intervalId);
					resolve(element);
				}
			}, 100);
		});
	}

	const changeMainCH = (obj) => {
		const previousStyle = document.getElementById("custom-mainCH");
		const containerCH = document.getElementById("crosshairContainer");
		containerCH.style.transform = `rotate(${obj.rotate}deg)`;

		if (previousStyle) {
			previousStyle.remove();
		}
		// Create a new stylesheet
		const style = document.createElement("style");
		style.id = "custom-mainCH";
		style.innerHTML = `
			.crosshair {
				position: absolute;
				transform-origin: 50% top;
				top: 50%;
				border: solid 0.05em ${obj.border};
				height: ${obj.length}em;
				opacity: ${obj.opacity};
				transform: rotate(${obj.angle || 0}deg);
			}
			.crosshair.normal {
				left: calc(50% - ${obj.width / 2}em);
				background: ${obj.color};
				width: ${obj.width}em;
			}
			.crosshair.powerful {
				left: calc(50% - ${obj.width / 2}em);
				background: red;
				width: ${obj.width}em;
			}
			.shotReticle.fill.normal {
				border-color: ${obj.color};
				border-left: solid transparent;
				border-right: solid transparent;
				border-width: 0.18em;
				padding: 0.18em;
			}
		`;

		document.body.appendChild(style);
	};

	const changeMiddleDot = (obj) => {
		const previousStyle = document.getElementById("custom-middleDot");
		if (previousStyle) previousStyle.remove();

		const dot = document.getElementById("reticleDot");

		dot.innerHTML = "";

		const style = document.createElement("style");
		style.id = "custom-middleDot";

		if (obj.shape === "plus") {
			style.innerHTML = `
				#reticleDot {
					position: absolute;
					top: 50%;
					left: 50%;
					transform: translate(-50%, -50%);
					width: 0;
					height: 0;
					background: none !important;
					border: none !important;
					opacity: ${obj.opacity};
				}
				#reticleDot .bar {
					position: absolute;
					background-color: ${obj.color};
					border: solid 0.05em ${obj.border}
				}
				#reticleDot .bar.horizontal {
					top: 50%;
					left: 50%;
					width: ${obj.width}px;
					height: ${obj.length}px;
					transform: translate(-50%, -50%) rotate(90deg);
				}
				#reticleDot .bar.vertical {
					left: 50%;
					top: 50%;
					width: ${obj.width}px;
					height: ${obj.length}px;
					transform: translate(-50%, -50%);
				}
			`;
			dot.innerHTML = `
				<div class="bar horizontal"></div>
				<div class="bar vertical"></div>
			`;
		} else {
			style.innerHTML = `
				#reticleDot {
					display: block;
					position: absolute;
					transform: translate(-50%, -50%);
					top: 50%;
					left: 50%;
					background-color: ${obj.color};
					border: solid 0.05em ${obj.border};
					width: ${obj.size}em;
					height: ${obj.size}em;
					opacity: ${obj.opacity};
					${obj.round ? "border-radius: 100%;" : ""}
				}
			`;
		}

		document.body.appendChild(style);
	};

	const makeDraggable = function (element, notMenu) {
		if (element) {
			let offsetX, offsetY;
			element.addEventListener("mousedown", function (e) {
				const dragElement = function (e) {
					const x = ((e.clientX - offsetX) / window.innerWidth) * 100;
					const y = ((e.clientY - offsetY) / window.innerHeight) * 100;
					const maxX = 100 - (element.offsetWidth / window.innerWidth) * 100;
					const maxY = 100 - (element.offsetHeight / window.innerHeight) * 100;
					element.style.left = `${Math.max(0, Math.min(x, maxX))}%`;
					element.style.top = `${Math.max(0, Math.min(y, maxY))}%`;
				};
				if (notMenu || e.target.classList.contains("tp-rotv_t")) {
					offsetX = e.clientX - element.getBoundingClientRect().left;
					offsetY = e.clientY - element.getBoundingClientRect().top;
					document.addEventListener("mousemove", dragElement);
					document.addEventListener("mouseup", function () {
						document.removeEventListener("mousemove", dragElement);
					});
					e.preventDefault(); // Prevent text selection during drag
				}
			});
		}
	};

	const playSound = (name) => {
		try {
			window.BAWK.play(name);
		} catch (e) {}
	};

	waitForElement("crosshairContainer").then((e) => {
		const Tweakpane = window.Tweakpane;
		const pane = new Tweakpane.Pane({
			title: "WISH",
			expanded: true,
		});
		const paneEl = document.querySelector("div.tp-dfwv");
		paneEl.style.zIndex = 1000;
		paneEl.style.width = `300px`;

		function createFolders(NFolder) {
			let test = pane.addFolder({
				title: NFolder,
				expanded: false,
			});
			return test;
		}

		function createInput(folder, obj, property, options, callback) {
			const x = folder.addInput(obj, property, options).on("change", callback);
			return x;
		}

		function addInputWithValidation(folder, obj, property, label) {
			const df = structuredClone(obj[property]);
			folder.addInput(obj, property, { label: label }).on("change", (value) => {
				if (value.value.length > 1) {
					value.value = df;
					obj[property] = df;
					console.log(obj[property]);
					value.target.controller_.binding.value.rawValue_ = df;
					window.alert("Please enter a single key");
				} else {
					const store = value.value.replace(/"/g, "");
					localStorage.setItem(`tp-${property}`, store);
				}
			});
		}

		makeDraggable(document.querySelector(".tp-dfwv"));

		const folderMainCH = createFolders("Crosshair");
		const folderMiddleDot = createFolders("Middle Dot");
		const folderFPSSettings = createFolders("FPS Settings");
		const folderPingSettings = createFolders("Ping Settings");
		const folderSoundsSettings = createFolders("Sounds Settings");
		const folderExtraSettings = createFolders("Extra Settings");
		const folderPaneSettings = createFolders("Panel Settings");

		loadExistingSettings("tp-mainCH", tp.mainCH, () => changeMainCH(tp.mainCH));
		loadExistingSettings("tp-middleDot", tp.middleDot, () => changeMiddleDot(tp.middleDot));
		loadExistingSettings("tp-paneSettings", tp.paneSettings, () => {
			const paneEl = document.querySelector("div.tp-dfwv");
			paneEl.style.width = `${tp.paneSettings.width}px`;
		});
		loadExistingSettings("tp-FPS", tp.FPS);
		loadExistingSettings("tp-ping", tp.ping);
		loadExistingSettings("tp-sounds", tp.sounds);
		loadExistingSettings("tp-extra", tp.extra);

		createInput(folderMainCH, tp.mainCH, "color", { label: "Color" }, () => {});
		createInput(folderMainCH, tp.mainCH, "border", { label: "Border Color" }, () => {});
		createInput(
			folderMainCH,
			tp.mainCH,
			"length",
			{ label: "Length", min: 0, max: 10, step: 0.1 },
			() => {},
		);
		createInput(
			folderMainCH,
			tp.mainCH,
			"width",
			{ label: "Width", min: 0.1, max: 10, step: 0.1 },
			() => {},
		);
		createInput(
			folderMainCH,
			tp.mainCH,
			"opacity",
			{ label: "Opacity", min: 0, max: 1, step: 0.01 },
			() => {},
		);
		createInput(
			folderMainCH,
			tp.mainCH,
			"rotate",
			{ label: "Rotate", min: 0, max: 360, step: 1.0 },
			() => {},
		);

		folderMainCH.on("change", (data) => {
			localStorage.setItem("tp-mainCH", JSON.stringify(tp.mainCH));
			changeMainCH(tp.mainCH);
		});

		const resetCHBtn = folderMainCH.addButton({
			title: "Reset",
			label: "Crosshair",
		});

		resetCHBtn.on("click", () => {
			const cur = {
				mainCH: {
					color: "#fff",
					length: 0.8,
					width: 0.3,
					opacity: 0.7,
					border: "#000000",
					rotate: 0,
				},
				middleDot: {
					opacity: 1,
					color: "#ffffff",
					border: "#000",
					size: 0.3,
					round: false,
					shape: "Dot",
					length: 0.2,
					width: 0.2,
				},
			};
			changeMainCH(cur.mainCH);
			changeMiddleDot(cur.middleDot);
		});

		createInput(folderMiddleDot, tp.middleDot, "color", { label: "Color" }, () => {});
		createInput(folderMiddleDot, tp.middleDot, "border", { label: "Border Color" }, () => {});
		const mdSize = createInput(
			folderMiddleDot,
			tp.middleDot,
			"size",
			{ label: "Size", min: 0, max: 5, step: 0.1 },
			() => {},
		);
		const mdRound = createInput(
			folderMiddleDot,
			tp.middleDot,
			"round",
			{ label: "Round" },
			() => {},
		);
		createInput(
			folderMiddleDot,
			tp.middleDot,
			"opacity",
			{ label: "Opacity", min: 0, max: 1, step: 0.01 },
			() => {},
		);
		createInput(
			folderMiddleDot,
			tp.middleDot,
			"shape",
			{
				view: "list",
				label: "Shape",
				options: [
					{ text: "Dot", value: "dot" },
					{ text: "Plus", value: "plus" },
				],
			},
			() => {},
		);
		const mdLength = createInput(
			folderMiddleDot,
			tp.middleDot,
			"length",
			{ label: "Length", min: 0, max: 100, step: 1 },
			() => {},
		);
		const mdWidth = createInput(
			folderMiddleDot,
			tp.middleDot,
			"width",
			{ label: "Width", min: 0, max: 5, step: 0.1 },
			() => {},
		);

		// to disable it when the script is first launched
		if (tp.middleDot.shape === "dot") {
			mdLength.disabled = true;
			mdWidth.disabled = true;
		} else {
			mdSize.disabled = true;
			mdRound.disabled = true;
		}

		folderMiddleDot.on("change", (data) => {
			localStorage.setItem("tp-middleDot", JSON.stringify(tp.middleDot));
			changeMiddleDot(tp.middleDot);
			// console.log(tp.middleDot);
			if (tp.middleDot.shape === "dot") {
				mdLength.disabled = true;
				mdWidth.disabled = true;
				mdSize.disabled = false;
				mdRound.disabled = false;
			} else {
				mdLength.disabled = false;
				mdWidth.disabled = false;
				mdSize.disabled = true;
				mdRound.disabled = true;
			}
		});

		createInput(folderFPSSettings, tp.FPS, "hide", { label: "Hide FPS" }, () => {});
		createInput(folderFPSSettings, tp.FPS, "random", { label: "Randomise FPS" }, () => {});
		createInput(
			folderFPSSettings,
			tp.FPS,
			"min",
			{ label: "Min FPS", view: "slider", min: 1, max: 999, step: 1 },
			() => {},
		);
		createInput(
			folderFPSSettings,
			tp.FPS,
			"max",
			{ label: "Max FPS", view: "slider", min: 1, max: 999, step: 1 },
			() => {},
		);

		folderFPSSettings.on("change", (data) => {
			localStorage.setItem("tp-FPS", JSON.stringify(tp.FPS));
		});

		createInput(
			folderPingSettings,
			tp.ping,
			"min",
			{ label: "Min Ping", view: "slider", min: 1, max: 999, step: 1 },
			() => {},
		);
		createInput(
			folderPingSettings,
			tp.ping,
			"max",
			{ label: "Max Ping", view: "slider", min: 1, max: 999, step: 1 },
			() => {},
		);
		createInput(folderPingSettings, tp.ping, "random", { label: "Randomise Ping" }, () => {});

		folderPingSettings.on("change", (data) => {
			localStorage.setItem("tp-ping", JSON.stringify(tp.ping));
		});

		createInput(
			folderSoundsSettings,
			tp.sounds,
			"crackshot",
			{
				label: "Crackshot",
				options: {
					Default: "fire",
					"8bit": "fire_m24_8bit",
					BadEgg: "Badegg_fire",
					Chess: "Chess_fire",
					Cyborg: "Cyborg_fire",
					Frostfall: "Frostfall_fire",
					Fusion: "Fusion_fire",
					Infernal: "Infernal_fire",
					Irish: "Irish_fire",
					Polaroid: "Polaroid_fire",
					Quack: "Quackshot_fire",
					Retro: "Retro_fire",
					Scavenger: "Scavenger_fire",
					Techno: "Techno_fire",
					Valkyrie: "Valkyrie_fire",
				},
			},
			(data) => {
				playSound(`gun_m24_${data.value}`);
			},
		);

		createInput(
			folderSoundsSettings,
			tp.sounds,
			"egg-k",
			{
				label: "Egg-K",
				options: {
					Default: "fire",
					Alien: "Alien_fire",
					Chocolate: "Chocolate_fire",
					Fusion: "Fusion_fire",
					Infernal: "Infernal_fire",
					"Infernal-2": "Infernal2_fire",
					Retro: "Retro_fire",
					Steambot: "Steambot_fire",
					Techno: "Techno_fire",
					Valkyrie: "Valkyrie_fire",
				},
			},
			(data) => {
				playSound(`gun_eggk47_${data.value}`);
			},
		);

		createInput(
			folderSoundsSettings,
			tp.sounds,
			"scrambler",
			{
				label: "Scrambler",
				options: {
					Default: "fire",
					Basketball: "Basketball_fire",
					Clouds: "Clouds_fire",
					Cutesy: "Cutesy_fire",
					Fantasy: "Fantasy_fire",
					Fusion: "Fusion_fire",
					Infernal: "Infernal_fire",
					Irish: "Irish_fire",
					Octopus: "Octopus_fire",
					Retro: "Retro_fire",
					Steambot: "Steambot_fire",
					Techno: "Techno_fire",
					Valkyrie: "Valkyrie_fire",
				},
			},
			(data) => {
				playSound(`gun_dozenGauge_${data.value}`);
			},
		);

		createInput(
			folderSoundsSettings,
			tp.sounds,
			"free-ranger",
			{
				label: "Free-Ranger",
				options: {
					Default: "fire",
					Fusion: "Fusion_fire",
					Infernal: "Infernal_fire",
					Retro: "Retro_fire",
					RubberChicken: "RubberChicken_fire",
					Shellpreme: "Shellpreme_fire",
					"Space-Egg": "spaceEgg_fire",
					Steambot: "Steambot_fire",
					Techno: "Techno_fire",
					Valkyrie: "Valkyrie_fire",
				},
			},
			(data) => {
				playSound(`gun_csg1_${data.value}`);
			},
		);

		createInput(
			folderSoundsSettings,
			tp.sounds,
			"rpegg",
			{
				label: "Rpegg",
				options: {
					Default: "fire",
					BFG: "BFG_fire",
					Bouzouki: "Bouzouki_fire",
					Christmas: "Christmas_fire",
					Fusion: "Fusion_fire",
					Infernal: "Infernal_fire",
					Retro: "Retro_fire",
					Skeleton: "Skeleton_fire",
					Techno: "Techno_fire",
					Valkyrie: "Valkyrie_fire",
				},
			},
			(data) => {
				playSound(`gun_rpegg_${data.value}`);
			},
		);

		createInput(
			folderSoundsSettings,
			tp.sounds,
			"whipper",
			{
				label: "Whipper",
				options: {
					Default: "fire",
					Fusion: "Fusion_fire",
					Infernal: "Infernal_fire",
					Pumpkin: "Pumpkin_fire",
					Retro: "Retro_fire",
					"Special-Turkey": "SpecialTurkey_fire",
					Techno: "Techno_fire",
					Valkyrie: "Valkyrie_fire",
				},
			},
			(data) => {
				playSound(`gun_smg_${data.value}`);
			},
		);

		createInput(
			folderSoundsSettings,
			tp.sounds,
			"tri-hard",
			{
				label: "Tri-Hard",
				options: {
					Default: "fire",
					Cupid: "Cupid_fire",
					Fusion: "Fusion_fire",
					Infernal: "Infernal_fire",
					Pumpkinpie: "Pumpkinpie_fire",
					Retro: "Retro_fire",
					Techno: "Techno_fire",
					Valkyrie: "Valkyrie_fire",
				},
			},
			(data) => {
				playSound(`gun_aug_${data.value}`);
			},
		);

		createInput(
			folderSoundsSettings,
			tp.meleeSounds,
			"melee",
			{
				label: "Melee",
				options: {
					Default: "melee_whisk_a",
					Carver: ["melee_carver"],
					"BOxing Glove": ["melee_boxingGlove_a", "melee_boxingGlove_b"],
					Cup: ["melee_cup_a", "melee_cup_b"],
					Eggpan: ["melee_eggpan"],
					Elf: ["melee_elf_a", "melee_elf_b"],
					Fish: ["melee_gfish_a", "melee_gfish_b"],
					Harrison: ["melee_harrison"],
					Infernal: ["melee_infernal"],
					Keytar: ["melee_keytar"],
					Mayan: ["melee_mayan"],
					Nutcracker: ["melee_nutcracker"],
					Pickleball: ["melee_pickleball"],
					Plunger: ["melee_plunger"],
					"Proper-Fish (idk)": ["melee_properfish_a", "melee_properfish_b"],
					"Red Saber": ["melee_redSaber"],
					Retro: ["melee_retro"],
					Rock: ["melee_rock"],
					Steambot: ["melee_steambot"],
					Techno: ["melee_techno"],
					Valkyrie: ["melee_valkyrie"],
					Zombie: ["melee_zombie"],
				},
			},
			(data) => {
				// console.log(data.value)
				playSound(`${Array.isArray(data.value) ? data.value[Math.floor(Math.random() * data.value.length)] : data.value}`);
			},
		);

		createInput(
			folderSoundsSettings,
			tp.sounds,
			"pistol",
			{
				label: "Pistol",
				options: {
					Default: "fire",
					Camera: "Camera_fire",
					Clouds: "Clouds_fire",
					"Cubic-Castle": "CubicCastles_fire",
					Fusion: "Fusion_fire",
					Infernal: "Infernal_fire",
					Megaphone: "Megaphone_fire",
					Retro: "Retro_fire",
					"Space-Egg": "spaceEgg_fire",
					Steambot: "Steambot_fire",
					Techno: "Techno_fire",
					Valkyrie: "Valkyrie_fire",
				},
			},
			(data) => {
				playSound(`gun_cluck9mm_${data.value}`);
			},
		);

		folderSoundsSettings.on("change", (value) => {
			localStorage.setItem("tp-sounds", JSON.stringify(tp.sounds));
			updateSounds();
		});

		createInput(
			folderExtraSettings,
			tp.extra,
			"disableScopeLines",
			{ label: "Hide Scope Lines" },
			() => {},
		);

		folderExtraSettings.on("change", (data) => {
			localStorage.setItem("tp-extra", JSON.stringify(tp.extra));
		});

		addInputWithValidation(folderPaneSettings, tp.paneSettings, "hidePanel", "Hide Panel");
		addInputWithValidation(folderPaneSettings, tp.paneSettings, "tabout", "Tabout");
		addInputWithValidation(
			folderPaneSettings,
			tp.paneSettings,
			"refreshSounds",
			"Refresh Sounds",
		);
		createInput(
			folderPaneSettings,
			tp.paneSettings,
			"width",
			{ label: "Panel Width", min: 300, max: 1000, step: 1 },
			() => {},
		);
		folderPaneSettings.on("change", (data) => {
			setTimeout(() => {
				const paneEl = document.querySelector("div.tp-dfwv");
				paneEl.style.width = `${tp.paneSettings.width}px`;
				localStorage.setItem("tp-paneSettings", JSON.stringify(tp.paneSettings));
			}, 1000);
		});

		// ADD OTHER STYLES
		const style = document.createElement("style");
		style.innerHTML = `
			#chickenBadge {
				display: none !important;
			}
		`;
		document.body.appendChild(style);
	});

	let oldPointerLock;
	let disable = () => {
		if (document.onpointerlockchange == null) return;
		oldPointerLock = document.onpointerlockchange;
		document.onpointerlockchange = null;
		document.exitPointerLock();
	};

	let enable = () => {
		if (document.onpointerlockchange) return;
		canvas.requestPointerLock();
		document.onpointerlockchange = oldPointerLock;
	};

	let handle = (event) => {
		let isPaused = vueApp?.game?.isPaused;
		let chatOpened = document.activeElement.id == "chatIn";
		if (chatOpened || isPaused) return; // hopefully this also helps prevent people from spamming it
		let inGame = extern?.inGame; // uncertain if this is needed?
		if (!inGame) return;
		document.onpointerlockchange == null ? enable() : disable(); // toggle :blobshrug:
	};
	document.addEventListener("keydown", (event) => {
		let chatOpened = document.activeElement.id == "chatIn";
		if (chatOpened) return;

		if (event.key === tp.paneSettings.hidePanel) {
			const element = document.querySelector(".tp-dfwv");
			element.style.display = element.style.display === "none" ? "block" : "none";
		} else if (event.key === tp.paneSettings.tabout) {
			handle(event);
		} else if (event.key === tp.paneSettings.refreshSounds) {
			updateSounds();
		}
	});
})();