// ==UserScript== // @name Crosshair Mod // @namespace http://tampermonkey.net/ // @version 1 // @description Custom crosshairs for Sploop.io // @author You // @match https://sploop.io/* // @grant none // @license MIT // @run-at document-end // @downloadURL none // ==/UserScript== (function () { 'use strict'; const style = document.createElement('style'); style.textContent = ` * { font-family: 'Segoe UI', sans-serif; } #hookx-ui { position: fixed; top: 50px; left: 50px; width: 300px; background: rgba(20, 20, 20, 0.95); border-radius: 10px; color: white; z-index: 100000; box-shadow: 0 0 12px rgba(0,0,0,0.6); padding: 15px; } .hookx-select, .hookx-color { margin-top: 10px; width: 100%; padding: 5px; background: #111; color: white; border: 1px solid #333; border-radius: 5px; } .crosshair { position: fixed; z-index: 99999; pointer-events: none; display: none; transform: translate(-50%, -50%); will-change: transform; } .crosshair.dot { width: 12px; height: 12px; border-radius: 50%; } .crosshair.cross { width: 20px; height: 20px; } .crosshair.cross::before, .crosshair.cross::after { content: ''; position: absolute; background-color: currentColor; } .crosshair.cross::before { top: 50%; left: 0; width: 100%; height: 2px; transform: translateY(-50%); } .crosshair.cross::after { top: 0; left: 50%; width: 2px; height: 100%; transform: translateX(-50%); } .crosshair.spike { width: 48px; height: 48px; background-image: url("https://sploop.io/img/entity/hard_spike.png"); background-size: cover; background-repeat: no-repeat; background-position: center; } .crosshair.square { width: 14px; height: 14px; border: 2px solid; } .crosshair.triangle { width: 0; height: 0; border-left: 10px solid transparent; border-right: 10px solid transparent; border-bottom: 18px solid currentColor; } .crosshair.xcross { width: 20px; height: 20px; } .crosshair.xcross::before, .crosshair.xcross::after { content: ''; position: absolute; width: 2px; height: 100%; background-color: currentColor; left: 50%; top: 0; transform-origin: center; } .crosshair.xcross::before { transform: rotate(45deg); } .crosshair.xcross::after { transform: rotate(-45deg); } body.hide-cursor * { cursor: none !important; } `; document.head.appendChild(style); const ui = document.createElement('div'); ui.id = 'hookx-ui'; ui.innerHTML = ` `; document.body.appendChild(ui); let crosshair = document.createElement('div'); crosshair.className = 'crosshair dot'; document.body.appendChild(crosshair); const toggle = document.getElementById('toggleCrosshair'); const styleSelect = document.getElementById('crosshairStyle'); const colorPicker = document.getElementById('crosshairColor'); function throttle(fn, wait) { let lastCall = 0; return function (...args) { const now = performance.now(); if (now - lastCall >= wait) { lastCall = now; fn(...args); } }; } function debounce(fn, wait) { let timeout; return function (...args) { clearTimeout(timeout); timeout = setTimeout(() => fn(...args), wait); }; } function setCrosshairStyle(styleName) { const newCrosshair = document.createElement('div'); newCrosshair.className = 'crosshair ' + styleName; document.body.replaceChild(newCrosshair, crosshair); crosshair = newCrosshair; updateColor(); if (toggle.checked) { crosshair.style.display = 'block'; } } toggle.addEventListener('change', () => { if (toggle.checked) { crosshair.style.display = 'block'; document.body.classList.add('hide-cursor'); document.addEventListener('mousemove', throttledMoveCrosshair); } else { crosshair.style.display = 'none'; document.body.classList.remove('hide-cursor'); document.removeEventListener('mousemove', throttledMoveCrosshair); } }); styleSelect.addEventListener('change', () => { setCrosshairStyle(styleSelect.value); }); const debouncedUpdateColor = debounce(updateColor, 100); colorPicker.addEventListener('input', debouncedUpdateColor); function updateColor() { const color = colorPicker.value; crosshair.style.backgroundColor = ''; crosshair.style.borderColor = ''; crosshair.style.color = color; if (crosshair.classList.contains('dot')) { crosshair.style.backgroundColor = color; } else if (crosshair.classList.contains('cross') || crosshair.classList.contains('xcross')) { crosshair.style.background = 'transparent'; } else if (crosshair.classList.contains('square')) { crosshair.style.borderColor = color; crosshair.style.background = 'transparent'; } } const throttledMoveCrosshair = throttle((e) => { crosshair.style.transform = `translate(${e.clientX}px, ${e.clientY}px) translate(-50%, -50%)`; }, 16); })();