Greasy Fork is available in English.

Voxiom.IO ESP & X-Ray

Let's you see players and items behind walls in voxiom.io. Also shows names of the items that are far far away.

2023-12-30 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name         Voxiom.IO ESP & X-Ray
// @namespace    http://tampermonkey.net/
// @version      0.5
// @description  Let's you see players and items behind walls in voxiom.io. Also shows names of the items that are far far away.
// @author       Zertalious (Zert)
// @match        *://voxiom.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=voxiom.io
// @grant        none
// @run-at       document-end
// @antifeature  ads
// @require      https://unpkg.com/three@latest/build/three.min.js
// ==/UserScript==

const THREE = window.THREE;

Object.defineProperty( window, 'THREE', {
	get() {

		return undefined;

	}
} );

Object.defineProperty( Object.prototype, 'Entity 1', {
	get() {

		console.log( this );

	}
} );

let showPlayers = true;
let showItems = true;
let showItemNames = false;
let showBlocks = false;

const geometry = new THREE.EdgesGeometry( new THREE.BoxGeometry( 1, 1, 1 ).translate( 0, 0.5, 0 ) );

const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 1000 );

const renderer = new THREE.WebGLRenderer( {
	alpha: true, 
	antialias: true
} );

renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.domElement.id = 'overlayCanvas';
document.body.appendChild( renderer.domElement );

window.addEventListener( 'resize', () => {

	renderer.setSize( window.innerWidth, window.innerHeight );

} )

function MyMaterial( color ) {

	return new THREE.RawShaderMaterial( {
		vertexShader: `

		attribute vec3 position;

		uniform mat4 projectionMatrix;
		uniform mat4 modelViewMatrix;

		void main() {

			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
			gl_Position.z = 1.0;

		}

		`,
		fragmentShader: `

		precision mediump float;

		uniform vec3 color;

		void main() {

			gl_FragColor = vec4( color, 1.0 );

		}

		`,
		uniforms: {
			color: { value: new THREE.Color( color ) }
		}
	} );

}

WeakMap.prototype.set = new Proxy( WeakMap.prototype.set, {
	apply( target, thisArgs, [ object ] ) {

		if ( object && typeof object === 'object' ) {

			if ( object.hasOwnProperty( 'background' ) ) checkScene( object );

			if ( typeof object.aspect === 'number' ) {

				object.projectionMatrix = new Proxy( object.projectionMatrix, {
					get() {

						setTransform( camera, object );
						camera.near = object.near;
						camera.far = object.far;
						camera.aspect = object.aspect;
						camera.updateProjectionMatrix();
						return Reflect.get( ...arguments );

					}
				} );

			}

		}

		return Reflect.apply( ...arguments );

	}
} );

function setTransform( targetObject, sourceObject ) {

	const matrix = new THREE.Matrix4().fromArray( sourceObject.matrixWorld.toArray() );
	matrix.decompose( targetObject.position, targetObject.quaternion, targetObject.scale );

}

let worldScene;
let childrenKey;

function checkScene( scene ) {

	for ( const key in scene ) {

		const children = scene[ key ];

		if ( Array.isArray( children ) && children.length === 9 ) {

			for ( const child of children ) {

				if ( typeof child !== 'object' || ! child.hasOwnProperty( 'uuid' ) ) return;

			}

			worldScene = scene;
			childrenKey = key;
			return;

		}

	}

}

function isBlock( entity ) {

	try {

		const mesh = entity[ childrenKey ][ 0 ];
		return mesh.geometry.index.count === 36;

	} catch {

		return false;

	}

}

function isPlayer( entity ) {

	try {

		return entity[ childrenKey ].length > 2 || ! entity[ childrenKey ][ 1 ].geometry;

	} catch {

		return false;

	}

}

function animate() {

	if ( ! worldScene ) return;

	const scene = new THREE.Scene();

	const entities = worldScene[ childrenKey ][ 5 ][ childrenKey ];

	for ( let i = 0; i < entities.length; i ++ ) {

		const entity = entities[ i ];
		if ( entity[ childrenKey ].length === 0 ) continue;

		if ( ! entity.myContainer ) {

			entity.myContainer = new THREE.Object3D();

		}

		if ( ! entity.myBox ) {

			const box = new THREE.LineSegments( geometry );
			// const name = entity[ childrenKey ][ 0 ].name;
			const name = entity.name;

			if ( isPlayer( entity ) ) {

				entity.isPlayer = true;
				box.material = MyMaterial( 'red' );
				box.scale.set( 0.5, 1.25, 0.5 );

			} else {
				
				// entity.isBlock = name === 'BlockModel';
				entity.isBlock = isBlock( entity ); 
				box.material = MyMaterial( entity.isBlock ? 'green' : 'gold' );
				box.scale.setScalar( 0.25, 0.1, 0.25 );

				if ( entity.isBlock === false ) {

					const fontSize = 40;
					const strokeSize = 8;
					const font = 'bolder ' + fontSize + 'px Arial';

					const canvas = document.createElement( 'canvas' );
					const ctx = canvas.getContext( '2d' );

					ctx.font = font;
					canvas.width = ctx.measureText( name ).width + strokeSize * 2;
					canvas.height = fontSize + strokeSize * 2;

					ctx.font = font;
					ctx.fillStyle = 'white';
					ctx.textBaseline = 'top';
					ctx.textAlign = 'left';
					ctx.lineWidth = strokeSize;

					ctx.strokeText( name, strokeSize, strokeSize );
					ctx.fillText( name, strokeSize, strokeSize );

					const sprite = new THREE.Sprite( new THREE.SpriteMaterial( {
						map: new THREE.CanvasTexture( canvas ), 
						sizeAttenuation: false,
						fog: false, 
						depthTest: false, 
						depthWrite: false
					} ) );

					sprite.scale.y = 0.035;
					sprite.scale.x = sprite.scale.y * canvas.width / canvas.height;
					sprite.position.y = sprite.scale.y + 0.1;

					entity.mySprite = sprite;
					entity.myContainer.add( entity.mySprite );

				}

			}
			
			entity.myBox = box;
			entity.myContainer.add( entity.myBox );

		}

		if ( entity.isPlayer ) {

			entity.myBox.visible = showPlayers;

		} else if ( entity.isBlock ) {

			entity.myBox.visible = showBlocks;

		} else {

			entity.myBox.visible = showItems;
			entity.mySprite.visible = showItemNames;

		}

		setTransform( entity.myContainer, entity );
		scene.add( entity.myContainer );

	}

	renderer.render( scene, camera );
	
}

window.requestAnimationFrame = new Proxy( window.requestAnimationFrame, {
	apply( target, thisArgs, args ) {

		args[ 0 ] = new Proxy( args[ 0 ], {
			apply() {

				if ( typeof shouldShowAd === 'boolean' && shouldShowAd === false ) {

					animate();

				}

				return Reflect.apply( ...arguments );

			}
		} );

		return Reflect.apply( ...arguments );

	}
} );

const value = parseInt( new URLSearchParams( window.location.search ).get( 'showAd' ), 16 );

const shouldShowAd = isNaN( value ) || Date.now() - value < 0 || Date.now() - value > 10 * 60 * 1000;

const el = document.createElement( 'div' );

el.innerHTML = `<style>

.dialog {
	position: absolute;
	left: 50%;
	top: 50%;
	padding: 20px;
	background: rgba(50, 0, 0, 0.8);
	border: 6px solid rgba(0, 0, 0, 0.2);
	color: #fff;
	transform: translate(-50%, -50%);
	box-shadow: 0 0 0 10000px rgba(0, 0, 0, 0.3);
	text-align: center;
	z-index: 999999;
}

.dialog * {
	color: #fff;
}

.close {
	position: absolute;
	right: 5px;
	top: 5px;
	width: 20px;
	height: 20px;
	opacity: 0.5;
	cursor: pointer;
}

.close:before, .close:after {
	content: ' ';
	position: absolute;
	left: 50%;
	top: 50%;
	width: 100%;
	height: 20%;
	transform: translate(-50%, -50%) rotate(-45deg);
	background: #fff;
}

.close:after {
	transform: translate(-50%, -50%) rotate(45deg);
}

.close:hover {
	opacity: 1;
}

.dialog .btn {
	cursor: pointer;
	padding: 0.5em;
	background: hsla(0, 67%, 44%, 0.7);
	border: 3px solid rgba(0, 0, 0, 0.2);
}

.dialog .btn:active {
	transform: scale(0.8);
}

.msg {
	position: absolute;
	left: 10px;
	bottom: 10px;
	background: rgba(50, 0, 0, 0.8);
	color: #fff;
	padding: 15px;
	animation: msg 0.5s forwards, msg 0.5s reverse forwards 3s;
	z-index: 999999;
	pointer-events: none;
}

.msg, .dialog {
	font-family: cursive;
}

@keyframes msg {
	from {
		transform: translate(-120%, 0);
	}

	to {
		transform: none;
	}
}

#overlayCanvas {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

</style>
<div class="dialog">${shouldShowAd ? `<big>Loading ad...</big>` : `<div class="close" onclick="this.parentNode.style.display='none';"></div>
	<big>Voxiom.IO ESP & X-Ray</big>
	<br>
	<br>
	Keys:
	<br>
	[V] to show/hide players
	<br>
	[I] to show/hide items
	<br>
	[N] to show/hide item names
	<br>
	[L] to show/hide blocks
	<br>
	[H] to show/hide help
	<br>
	<br>
	By Zertalious
	<br>
	<br>
	<div style="display: grid; grid-gap: 8px; grid-template-columns: 1fr 1fr;">
		<div class="btn" onclick="window.open('https://discord.gg/K24Zxy88VM', '_blank')">Discord</div>
		<div class="btn" onclick="window.open('https://www.instagram.com/zertalious/', '_blank')">Instagram</div>
		<div class="btn" onclick="window.open('https://twitter.com/Zertalious', '_blank')">Twitter</div>
		<div class="btn" onclick="window.open('https://greasyfork.org/en/users/662330-zertalious', '_blank')">More scripts</div>
	</div>
	` }
</div>
<div class="msg" style="display: none;"></div>`;

const msgEl = el.querySelector( '.msg' );
const dialogEl = el.querySelector( '.dialog' );

while ( el.children.length > 0 ) {

	document.body.appendChild( el.children[ 0 ] );

}

if ( shouldShowAd ) {

	const url = new URL( window.location.href );

	url.searchParams.set( 'showAd', Date.now().toString( 16 ) );
	url.searchParams.set( 'scriptVersion', GM.info.script.version );

	window.location.href = 'https://zertalious.xyz?ref=' + new TextEncoder().encode( url.href ).toString();

}

window.addEventListener( 'keyup', function ( event ) {

	switch ( event.code ) {

		case 'KeyV':
			showPlayers = ! showPlayers;
			showMsg( 'Show Players', showPlayers );
			break;

		case 'KeyI':
			showItems = ! showItems;
			showMsg( 'Show Items', showItems );
			break;

		case 'KeyN':
			showItemNames = ! showItemNames;
			showMsg( 'Item Names', showItemNames );
			break;

		case 'KeyL':
			showBlocks = ! showBlocks;
			showMsg( 'Show Blocks', showBlocks );
			break;

		case 'KeyH':
			dialogEl.style.display = dialogEl.style.display === '' ? 'none' : '';
			break;

	}

} );

function showMsg( name, bool ) {

	msgEl.innerText = name + ': ' + ( bool ? 'ON' : 'OFF' );
 
	msgEl.style.display = 'none';
	
	void msgEl.offsetWidth;

	msgEl.style.display = '';

}