Survev.IO-KrityHack

Xray, better zoom, smoke/obstacle opacity, player names for survev.io.

目前為 2024-12-29 提交的版本,檢視 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Survev.IO-KrityHack
// @namespace    https://github.com/Drino955/survev-krityhack
// @version      0.0.6
// @description  Xray, better zoom, smoke/obstacle opacity, player names for survev.io.
// @author       KrityTeam
// @match        *://survev.io/*
// @icon         https://www.google.com/s2/favicons?domain=survev.io
// @grant        none
// @run-at       document-end
// @webRequest   [{"selector":"*app-*.js","action":"cancel"}]
// @homepageURL  https://github.com/Drino955/survev-krityhack
// @supportURL   https://github.com/Drino955/survev-krityhack/issues
// ==/UserScript==


console.log('Script injecting...')

const script = document.createElement('script');
script.type = 'module';
script.src = '//cdn.jsdelivr.net/gh/drino955/survev-krityhack/survev/app.js';
script.onload = () => console.log('app.js loaded');
script.onerror = (err) => console.error('Error in app.js loading:', err);
document.head.append(script);

let espEnabled = false;
let aimbotEnabled = false;
let xrayEnabled = true;


const overlay = document.createElement('div');
overlay.className = 'krity-overlay';
document.querySelector('#ui-game').appendChild(overlay);

const styles = document.createElement('style');
styles.innerHTML = `
.krity-overlay{
    position: absolute;
    top: 100px;
    left: 0px;
    width: 100%;
    pointer-events: None;
    color: #fff;
    font-family: monospace;
}

.krity-control{
    text-align: center;
    margin-top: 3px;
    margin-bottom: 3px;
    font-size: 20px;
}
`;
document.head.append(styles);

window.addEventListener('keyup', function (event) {
    switch (String.fromCharCode(event.keyCode)) {
        case 'N': espEnabled = !espEnabled; break;
        case 'B': aimbotEnabled = !aimbotEnabled; break;
        case 'H': xrayEnabled = !xrayEnabled; break;
    }
    updateOverlay();
});

updateOverlay();



// remove ceilings
Object.defineProperty( Object.prototype, 'textureCacheIds', {
	set( value ) {
		this._textureCacheIds = value;

		if ( Array.isArray( value ) ) {
			const scope = this;

            value.push = new Proxy( value.push, {
                apply( target, thisArgs, args ) {
                    // console.log(args[0], scope, scope?.baseTexture?.cacheId);
                    // console.log(scope, args[0]);
                    if (args[0].includes('ceiling') || args[0].includes('map-snow-')) {
						Object.defineProperty( scope, 'valid', {
							set( value ) {
								this._valid = value;
							},
							get() {
								return xrayEnabled ? false : this._valid;
							}
						});
					}
					return Reflect.apply( ...arguments );

				}
			});

		}

	},
	get() {
		return this._textureCacheIds;
	}
});

Object.defineProperty(window, 'game', {
    get () {
        return this._game;
    },
    set(value) {
        this._game = value;
        
        if (!value) return;
        
        initGame();
        
    }
});


// Object.defineProperty( Object.prototype, 'obstaclePool', {
//     get () {
//         return this._obstaclePool;
//     },
//     set (value) {
//         this._obstaclePool = value;
//         console.log('set obstaclePool: ', this);

//         Object.defineProperty( this, 'pool', {
//             get () {
//                 return this._pool;
//             },
//             set (value) {
//                 this._pool = value;
//                 console.log('set pool: ', this);
                
//                 if (Array.isArray(value)) {
//                     const scope = this;
    
//                     value.push = new Proxy(value.push, {
//                         apply(target, thisArgs, args){
//                             console.log('poolik: ', scope, args[0]);
//                             args[0].sprite.alpha = 0.5;
//                             return Reflect.apply( ...arguments );
//                         }
//                     });
//                 }
//             }
//         });
//     }
// });


// setInterval(() => {
//     if (!window.game) return;

// 	window.game.map.obstaclePool.pool.forEach(obstacle => obstacle.sprite.alpha = 0.45);
// });



function initGame() {
    console.log('init game...........');

    const tasks = [
        {isApplied: false, condition: () => window.game?.activePlayer?.localData, action: betterScale},
        {isApplied: false, condition: () => window.game?.map?.obstaclePool?.pool != undefined, action: obstacleOpacity},
        // {isApplied: false, condition: () => window.game?.smokeBarn?.particles.length == 0, action: smokeOpacity},
        {isApplied: false, condition: () => Array.prototype.push === window.game?.smokeBarn?.particles.push, action: smokeOpacity},
        // {isApplied: false, condition: () => window.game?.playerBarn?.playerPool?.pool.length == 0, action: visibleNames},
        {isApplied: false, condition: () => Array.prototype.push === window.game?.playerBarn?.playerPool?.pool.push, action: visibleNames},
    ];

    (function checkLocalData(){
        if(!window.game.ws) return;

        console.log('Checking local data')

        console.log(
            window.game?.activePlayer?.localData, 
            window.game?.map?.obstaclePool?.pool,
            window.game?.smokeBarn?.particles,
            window.game?.playerBarn?.playerPool?.pool
        );

        tasks.forEach(task => console.log(task.action, task.isApplied))
        
        tasks.forEach(task => {
            if (task.isApplied || !task.condition()) return;
            task.action();
            task.isApplied = true;
        });
        
        if (tasks.some(task => !task.isApplied)) setTimeout(checkLocalData, 5);
        else console.log('All functions applied, stopping loop.');
    })();
}
mousedownClick();


function mousedownClick(){
    let timeoutId;

    function updateMouseButtons() {
        if (!window.game?.input?.mouseButtonsOld) return;
        Object.keys(window.game.input.mouseButtonsOld).forEach(key => delete (window.game.input.mouseButtonsOld[key]));
        timeoutId = setTimeout(updateMouseButtons, 5);
    }

    window.addEventListener('mousedown', function (event) {
        if (event.button === 0) { // 0 is the code for the left mouse button
            updateMouseButtons();
        }
    });

    window.addEventListener('mouseup', function (event) {
        if (event.button === 0) { // 0 is the code for the left mouse button
            clearTimeout(timeoutId);
        }
    });
}

function betterScale(){
    Object.defineProperty(window.game.camera, 'zoom', {
        get() {
            return Math.max(window.game.camera.targetZoom - 0.45, 0.35);
        },
        set(value) {
        }
    });

    let oldScope = window.game.activePlayer.localData.scope;
    Object.defineProperty(window.game.camera, 'targetZoom', {
        get(){
            return this._targetZoom;
        },
        set(value) {
            const newScope = window.game.activePlayer.localData.scope;
            const inventory = window.game.activePlayer.localData.inventory;

            const scopes = ['1xscope', '2xscope', '4xscope', '8xscope', '15xscope']

            // console.log(value, oldScope, newScope, newScope == oldScope, (inventory['2xscope'] || inventory['4xscope'] || inventory['8xscope'] || inventory['15xscope']));
            if ( (newScope == oldScope) && (inventory['2xscope'] || inventory['4xscope'] || inventory['8xscope'] || inventory['15xscope']) && value >= this._targetZoom
                // || scopes.indexOf(newScope) > scopes.indexOf(oldScope) && value >= this._targetZoom
            ) return;

            oldScope = window.game.activePlayer.localData.scope;

            this._targetZoom = value;
        }
    });
}

function smokeOpacity(){
    console.log('smokeopacity')
    
    const particles = window.game.smokeBarn.particles;
    console.log('smokeopacity', particles, window.game.smokeBarn.particles)
    particles.push = new Proxy( particles.push, {
        apply( target, thisArgs, args ) {
            console.log('smokeopacity', args[0]);
            const particle = args[0];

            Object.defineProperty(particle.sprite, 'alpha', {
                get() {
                    return 0.12;
                },
                set(value) {
                }
            });

            return Reflect.apply( ...arguments );

        }
    });

    particles.forEach(particle => {
        Object.defineProperty(particle.sprite, 'alpha', {
            get() {
                return 0.12;
            },
            set(value) {
            }
        });
    });
}

function obstacleOpacity(){
    setInterval(() => {
        window.game.map.obstaclePool.pool.forEach(obstacle => {
            if (!['bush', 'tree', 'table', 'stairs'].some(substring => obstacle.type.includes(substring))) return;
            obstacle.sprite.alpha = 0.45
        });
    });
}

function visibleNames(){
    const pool = window.game.playerBarn.playerPool.pool;

    console.log('visibleNames', pool)

    pool.push = new Proxy( pool.push, {
        apply( target, thisArgs, args ) {
            console.log('visibleNames', args[0]);
            const player = args[0];

            player.nameText.tint = 0xff0000;
            Object.defineProperty(player.nameText, 'visible', {
                get(){
                    return true;
                },
                set(value){
                }
            });

            return Reflect.apply( ...arguments );
        }
    });

    pool.forEach(player => {
        player.nameText.tint = 0xff0000;
        Object.defineProperty(player.nameText, 'visible', {
            get(){
                return true;
            },
            set(value){
            }
        });
    });
}

function esp(){
    
    const pixi = window.game.pixi;
    
    const me = window.game.activePlayer;
    const players = window.game.playerBarn.playerPool.pool;
    
    players.push = new Proxy( players.push, {
        apply( target, thisArgs, args ) {
            const player = args[0];

            if(!player.active || player.netData.dead) return;

            const playerX = +player.pos.x;
            const playerY = +player.pos.y;
            const distanceToPlayer = Math.hypot(meX - playerX, meY - playerY);
            console.log(`${player.nameText._text}, distance: ${distanceToPlayer}`);

            graphics.lineStyle(2, 0xFF0000, 1);
            graphics.moveTo(meX, meY);
            graphics.lineTo(playerX, playerY);

            return Reflect.apply( ...arguments );
        }
    });

    const meX = me.pos.x;
    const meY = me.pos.y;

    const graphics = new pixi.Graphics();
    pixi.stage.addChild(graphics);

    players.forEach(player => {
        if(!player.active || player.netData.dead) return;

        const playerX = +player.pos.x;
        const playerY = +player.pos.y;
        const distanceToPlayer = Math.hypot(meX - playerX, meY - playerY);
        console.log(`${player.nameText._text}, distance: ${distanceToPlayer}`);

        graphics.lineStyle(2, 0xFF0000, 1);
        graphics.moveTo(meX, meY);
        graphics.lineTo(playerX, playerY);
    });
}


function updateOverlay() {
    overlay.innerHTML = '';

    const controls = [
        // [ '[B] Aimbot', aimbotEnabled ],
        // [ '[N] ESP', espEnabled ],
        [ '[H] X-Ray', xrayEnabled ]
    ];

    controls.forEach((control, index) => {
        // console.log('control', control);
        let [text, isEnabled] = control;
        text = `${text} ${isEnabled ? 'ON' : 'OFF'}`;

        const line = document.createElement('p');
        line.className = 'krity-control';
        line.style.opacity = isEnabled ? 1 : 0.5;
        line.textContent = text;
        overlay.appendChild(line);
    });
}

console.log('Script injected')