Krunker Cheat

Krunker Cheats!

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Krunker Cheat
// @namespace    https://greasyfork.org/
// @version      1.2
// @description  Krunker Cheats!
// @author       Sk1d
// @license      GNU GPLv3
// @match        *://krunker.io/*
// @exclude      *://krunker.io/editor*
// @exclude      *://krunker.io/social*
// @match        *://browserfps.com/*
// @match        *://*.browserfps.com/*
// @exclude      *://*.browserfps.com/editor*
// @exclude      *://*.browserfps.com/social*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=krunker.io
// @run-at       document-start
// @grant        none
// ==/UserScript==
/* jshint esversion: 6 */
/* eslint-disable no-caller, no-sequences, curly, no-undef, no-loop-func */

class Cheat {
    constructor() {
        window[this.getHash("cheat")] = this;
        this.tabs = ['Render','Weapon','Player','Radio'];
        this.settings;
        this.downKeys = new Set();
        try {
            this.onLoad();
        }
        catch(err) {
            console.trace(err);
        }
    }
    // Main
    onLoad() {

        this.settings = {

            // Render

            showToggleBtn: {
                tab: "Render",
                name: "Show Menu Button",
                val: true,
                html: () => this.generateSetting("checkbox", "showToggleBtn"),
                set: (value, init) => {
                    let button = document.getElementById("mainButton");
                    if (!this.isDefined(button)) this.createButton("#menuItemContainer", "mainButton", "Cheat", `https://c.tenor.com/2HXEVfJLVFgAAAAi/digi-digislang.gif`, this.getHash("cheat")+".toggleMenu()", value)
                    this.waitFor(() => document.getElementById("mainButton")).then(button => { button.style.display = value ? "inherit" : "none" })
                }
            },
            showNameTags: {
                tab: "Render",
                pre: "<div class='separator'>Color ESP</div>",
                name: "Player Nametags",
                val: false,
                html: () => this.generateSetting("checkbox", "showNameTags"),
            },
            render2dBox: {
                tab: "Render",
                name: "Player 2d Boxes",
                val: false,
                html: () => this.generateSetting("checkbox", "render2dBox"),
            },
            renderTracers: {
                tab: "Render",
                name: "Player Tracers",
                val: false,
                html: () => this.generateSetting("checkbox", "renderTracers"),
            },
            espHostileCol: {
                tab: "Render",
                name: "Hostile Color",
                val: "#ff0000",
                html: () => this.generateSetting("color", "espHostileCol"),
            },
            espFriendlyCol: {
                tab: "Render",
                name: "Friendly Color",
                val: "#00ff00",
                html: () => this.generateSetting("color", "espFriendlyCol"),
            },
            renderChams: {
                tab: "Render",
                pre: "<div class='separator'>Color Chams</div>",
                name: "Player Chams",
                val: false,
                html: () => this.generateSetting("checkbox", "renderChams") //+
            },
            renderWireFrame: {
                tab: "Render",
                name: "Player Wireframe",
                val: false,
                html: () => this.generateSetting("checkbox", "renderWireFrame"),
            },

            // Weapon

            autoReload: {
                tab: "Weapon",
                //pre: "<br><div class='setHed'>Weapon</div>",
                name: "Auto Reload",
                val: false,
                html: () => this.generateSetting("checkbox", "autoReload"),
            },
            weaponZoom: {
                tab: "Weapon",
                name: "Weapon Zoom",
                val: 1.0,
                min: 0,
                max: 50.0,
                step: 0.01,
                html: () => this.generateSetting("slider", "weaponZoom"),
                set: (value) => this.waitFor(() => this.renderer).then(renderer => { renderer.adsFovMlt.fill(value) })
            },
            autoAim: {
                tab: "Weapon",
                pre: "<div class='separator'>Auto Aim</div>",
                name: "Auto Aim Type",
                val: "off",
                can: true,
                html: () =>
                this.generateSetting("select", "autoAim", {
                    off: "Off",
                    correction: "Aim Correction",
                    smoothCam: "Smooth Assist",
                    smoothCamAssist: "Smooth Assist & Aim Correction",
                    assist: "Legit Aim Assist",
                    easyassist: "Easy Aim Assist",
                    silent: "Silent Aim",
                    trigger: "Trigger Bot",
                    quickScope: "Quick Scope"
                }),
            },
            fovBoxSize: {
                tab: "Weapon",
                name: "FOV Box Type",
                val: "off",
                html: () =>
                this.generateSetting("select", "fovBoxSize", {
                    off: "Off",
                    small: "Small",
                    medium: "Medium",
                    large: "Large"
                })
            },
            renderTarget: {
                tab: "Weapon",
                name: "Show Target Indicator",
                val: false,
                html: () => this.generateSetting("checkbox", "renderTarget"),
            },
            wallBangs: {
                tab: "Weapon",
                name: "Aim through Penetratables",
                val: false,
                html: () => this.generateSetting("checkbox", "wallBangs"),
            },

            // Player

            autoBhop: {
                tab: "Player",
                //pre: "<br><div class='setHed'>Player</div>",
                name: "Auto Bhop Type",
                val: "off",
                html: () => this.generateSetting("select", "autoBhop", {
                    off: "Off",
                    autoJump: "Auto Jump",
                    keyJump: "Key Jump",
                    autoSlide: "Auto Slide",
                    keySlide: "Key Slide"
                }),
            },

            thirdPerson: {
                tab: "Player",
                name: "Third Person",
                val: false,
                html: () => this.generateSetting("checkbox", "thirdPerson"),
                set: (value, init) => {
                    if (!init) confirm("Reload Lobby To Apply?") ? location.reload() : void 0
                }
            },

            // Radio

            playStream: {
                tab: "Radio",
                //pre: "<br><div class='setHed'>Radio Stream Player</div>",
                name: "Stream Select",
                val: "off",
                html: () => this.generateSetting("select", "playStream", {
                    off: 'Off',
                    _2000s: 'General German/English',
                    _HipHopRNB: 'Hip Hop / RNB',
                    _Oldskool: 'Hip Hop Oldskool',
                    _Country: 'Country',
                    _Pop: 'Pop',
                    _Dance: 'Dance',
                    _Dubstep: 'DubStep',
                    _Lowfi: 'LoFi HipHop',
                    _Jazz: 'Jazz',
                    _Oldies: 'Golden Oldies',
                    _Club: 'Club',
                    _Folk: 'Folk',
                    _ClassicRock: 'Classic Rock',
                    _Metal: 'Heavy Metal',
                    _DeathMetal: 'Death Metal',
                    _Classical: 'Classical',
                    _Alternative: 'Alternative',
                }),
                set: (value) => {
                    if (value == "off") {
                        if ( this.settings.playStream.audio ) {
                            this.settings.playStream.audio.pause();
                            this.settings.playStream.audio.currentTime = 0;
                            this.settings.playStream.audio = null;
                        }
                        return;
                    }
                    let url = this.settings.playStream.urls[value];
                    if (!this.settings.playStream.audio) {
                        this.settings.playStream.audio = new Audio(url);
                        this.settings.playStream.audio.volume = this.settings.audioVolume.val||0.5
                    } else {
                        this.settings.playStream.audio.src = url;
                    }
                    this.settings.playStream.audio.load();
                    this.settings.playStream.audio.play();
                },
                urls: {
                    _2000s: 'http://0n-2000s.radionetz.de/0n-2000s.aac',
                    _HipHopRNB: 'https://stream-mixtape-geo.ntslive.net/mixtape2',
                    _Country: 'https://live.wostreaming.net/direct/wboc-waaifmmp3-ibc2',
                    _Dance: 'http://streaming.radionomy.com/A-RADIO-TOP-40',
                    _Pop: 'http://bigrradio.cdnstream1.com/5106_128',
                    _Jazz: 'http://strm112.1.fm/ajazz_mobile_mp3',
                    _Oldies: 'http://strm112.1.fm/60s_70s_mobile_mp3',
                    _Club: 'http://strm112.1.fm/club_mobile_mp3',
                    _Folk: 'https://freshgrass.streamguys1.com/irish-128mp3',
                    _ClassicRock: 'http://1a-classicrock.radionetz.de/1a-classicrock.mp3',
                    _Metal: 'http://streams.radiobob.de/metalcore/mp3-192',
                    _DeathMetal: 'http://stream.laut.fm/beatdownx',
                    _Classical: 'http://live-radio01.mediahubaustralia.com/FM2W/aac/',
                    _Alternative: 'http://bigrradio.cdnstream1.com/5187_128',
                    _Dubstep: 'http://streaming.radionomy.com/R1Dubstep?lang=en',
                    _Lowfi: 'http://streams.fluxfm.de/Chillhop/mp3-256',
                    _Oldskool: 'http://streams.90s90s.de/hiphop/mp3-128/',
                },
                audio: null,
            },

            audioVolume: {
                tab: "Radio",
                name: "Radio Volume",
                val: 0.5,
                min: 0,
                max: 1,
                step: 0.01,
                html: () => this.generateSetting("slider", "audioVolume"),
                set: (value) => { if (this.settings.playStream.audio) this.settings.playStream.audio.volume = value;}
            },
        }

        window.addEventListener('DOMContentLoaded', event => {
            //Auto Redirect
            this.waitFor(() => window.instructionsUpdate).then(node => {
                this.createObserver(node, 'style', (target) => {
                    if (target.textContent.includes('Connection Banned')) {
                        localStorage.removeItem("krunker_token");
                        alert("You Have Been Banned And Sign Out,Make A New Account And Change Your IP")
                        //location.assign('https://browserfps.com/');
                        // Auto Find New
                    } else if (this.arrayTest(target, ['Kicked', 'Banned', 'Disconnected', 'Error', 'Game is full', 'Connection Limited'], (txt) => target.innerHTML.includes(txt))) {
                        location = document.location.origin;
                    }
                });
            });
            // Get Main Custom CSS
            new Array(...document.styleSheets).map(css => {
                if (css.href) {
                    let arr = /http.*?krunker.io\/css\/(\w+.css).+/.exec(css.href);
                    if (arr && arr[1]) {
                        let name = arr[1];
                        if (name && name.includes("main_custom")) {
                            const rules = {
                                hideAdverts: `#aContainer, #aHolder, #endAContainer, #aMerger { display: none !important; }`,
                                hideCookies: `#onetrust-consent-sdk { display: none !important; }`,
                                hideTopLeft: `#tlInfHold { display: none !important; }`,

                                tabStyle: '.tab { overflow: hidden; border: 1px solid #ccc; background-image: linear-gradient(#2f3136, #f1f1f1, #2f3136); }',
                                btnStyle: '.tab button { background-color: inherit; float: left; border: none; outline: solid; cursor: pointer; padding: 14px 16px; transition: 0.3s; font-size: 17px; font-weight:500;color:black;text-shadow: 2px 2px #FFF;}',
                                btnHoverStyle: '.tab button:hover { background-color: #ddd; }',
                                activeTabStyle: '.tab button.active { background-color: #ccc; }',
                                tabContentStyle: '.tabcontent { display: none; padding: 6px 12px; border: 1px solid #ccc; border-top: none; animation: fadeEffect 1s; /* Fading effect takes 1 second */}',
                                zeroToFullOpacity: '@keyframes fadeEffect { from {opacity: 0;} to {opacity: 1;} }',

                                separator: `.separator { display:flex;align-items:center;text-align:center }`,
                                separator:`.separator::before,.separator::after{content:'';flex:1;border-bottom:1px solid #000}`,
                                separator:`.separator:not(:empty)::before{margin-right:.25em}`,
                                separator:`.separator:not(:empty)::after{margin-left:.25em}`,
                            };
                            for (let key in rules) {
                                css.insertRule(rules[key]);
                            }
                        }
                    }
                }
            })

            this.waitFor(() => window.windows).then(() => {
                let win = window.windows[11]; win.html = "";
                win.header = this.getHash("cheat");
                win.gen = ()=> {
                    let tmpHTML = `<a href="https://greasyfork.org/en/users/704479-sk1d-lamer"><img border="0" style="width:100%;height:80px;" src="https://i.imgur.com/dS86KfJ.png" width="100" height="80"></a>`
                    tmpHTML += '<div class="tab">'; this.tabs.forEach(tab => { tmpHTML += `<button class="tablinks" onclick="${this.getHash("cheat")}.tabChange(event, '${tab}')">${tab}</button>` }); tmpHTML +='</div>'
                    this.tabs.forEach(tab => {
                        tmpHTML += `<div id="${tab}" class="tabcontent"> ${this.tabContent(tab)} </div>`
                    })

                    return tmpHTML
                }
                for (const key in this.settings) {
                    this.settings[key].def = this.settings[key].val;
                    if (!this.settings[key].disabled) {
                        let tmpVal = this.getSavedVal(key);
                        this.settings[key].val = tmpVal !== null ? tmpVal : this.settings[key].val;
                        this.settings[key].val = this.settings[key].val;
                        if (this.settings[key].val == "false") this.settings[key].val = false;
                        if (this.settings[key].val == "true") this.settings[key].val = true;
                        if (this.settings[key].val == "undefined") this.settings[key].val = this.settings[key].def;
                        if (this.settings[key].set) this.settings[key].set(this.settings[key].val, true);
                    }
                }
            })

        });

        window.addEventListener('keyup', event =>{
            if (this.downKeys.has(event.code)) this.downKeys.delete(event.code)
        });

        window.addEventListener('keydown', event =>{
            if (!document.activeElement || 'INPUT' == document.activeElement.tagName || !window.endUI && window.endUI.style.display) return;
            switch (event.code) {
                case 'F1': case 'KeyC':
                    event.preventDefault();
                    this.toggleMenu();
                    break;

                case 'NumpadSubtract':
                    document.exitPointerLock();
                    console.dir(this)
                    break;
                default:
                    if (!this.downKeys.has(event.code)) this.downKeys.add(event.code);
                    break;
            }
        });

        this.waitFor(() => this.exports).then(exports => {
            let toFind = {
                overlay: ["render", "canvas"],
                config: ["accAnnounce", "availableRegions", "assetCat"],
                three: ["ACESFilmicToneMapping", "TextureLoader", "ObjectLoader"],
                ws: ["socketReady", "ingressPacketCount", "ingressPacketCount", "egressDataSize"],
                utility: ["VectorAdd", "VectorAngleSign"],
                colors: ["getClanCol", "hudHealth", "teams"],
                ui: ["showEndScreen", "toggleControlUI", "toggleEndScreen", "updatePlayInstructions"],
                events: ["actions", "events"],
            }
            for (let rootKey in exports) {
                let exp = exports[rootKey].exports;
                for (let name in toFind) {
                    if (this.arrayTest(exp, toFind[name], prop => exp.hasOwnProperty(prop))) {
                        console.log("Found Object ", name);
                        delete toFind[name];
                        this[name] = exp;
                    }
                }
            }
            if (!(Object.keys(toFind).length === 0 && toFind.constructor === Object)) {
                for (let name in toFind) {
                    alert("Failed To Find Object " + name);
                }
            } else {

                // socket
                cheat.ws.send = new Proxy(cheat.ws.send, {
                    apply(target, that, [type, event]) {
                        if (type === "en") {
                        }
                        return Reflect.apply(...arguments);
                    }
                });

                cheat.ws._dispatchEvent = new Proxy(cheat.ws._dispatchEvent, {
                    apply(target, that, [type, event]) {
                        if (type === "init") {
                            event[6].thirdPerson = cheat.settings.thirdPerson.val;
                        }
                        return Reflect.apply(...arguments);
                    }
                });

                //config
                Object.defineProperties(this.config, {
                    kickTimer: {
                        value: Infinity,
                        writable: false,
                    },
                    nameVisRate: {
                        value: 0,
                        writable: false,
                    },
                    clientSendRate: {
                        value: 0,
                        writable: false,
                    },
                });

                // three
                this.mesh = new Proxy({}, {
                    get(target, prop){
                        if(!target[prop]) {
                            target[prop] = new cheat.three.MeshBasicMaterial({
                                transparent: true,
                                fog: false,
                                depthTest: false,
                                color: prop,
                            });
                        }
                        return target[prop] ;
                    },
                });

                this.raycaster = {
                    ray: new this.three.Raycaster(),
                    mid: new this.three.Vector2(0, 0)
                }

                //overlay
                this.ctx = this.overlay.canvas.getContext('2d');
                this.overlay.render = new Proxy(this.overlay.render, {
                    apply: function(target, that, args) {
                        Reflect.apply(...arguments);
                        ["scale", "game", "controls", "renderer", "me"].forEach((name, index) => { cheat[name] = args[index] });
                        if (cheat.me) {
                            //cheat.renderer.renderer.setAnimationLoop(cheat.onRender);
                            cheat.ctx.save();
                            cheat.ctx.scale(cheat.scale, cheat.scale);
                            cheat.onRender();
                            cheat.ctx.restore();
                            if (!cheat.me.procInputs[cheat.getHash("isProxy")]) {

                                Object.defineProperties(cheat.me, {
                                    isHacker: {
                                        value: 0,
                                        writable: false
                                    },
                                    debugMode: {
                                        value: true,
                                        writable: false
                                    },
                                    recon: {
                                        value: true,
                                        writable: false
                                    },
                                });

                                cheat.me.procInputs = new Proxy(cheat.me.procInputs, {
                                    apply(target, that, [input, game, recon, lock]) {
                                        if (that) cheat.onInput(input);
                                        Reflect.apply(...arguments);
                                    },
                                    get(target, key) {
                                        return key === cheat.getHash("isProxy") ? true : Reflect.get(target, key);
                                    },
                                })

                            }
                        }
                    }
                })
            }
        })
    }
    onRender() {
        let scaledWidth = this.ctx.canvas.width / this.scale;
        let scaledHeight = this.ctx.canvas.height / this.scale;
        this.raycaster.ray.setFromCamera(this.raycaster.mid, this.renderer.camera);
        for (let iter = 0, length = this.game.players.list.length; iter < length; iter++) {
            let player = this.game.players.list[iter];
            if (!player || player.isYou || !player.active || !this.isDefined(player.objInstances) ) {
                continue;
            }

            let isEnemy = !this.me.team || this.me.team != player.team;
            let isRisky = player.isDev || player.isMod || player.isMapMod || player.canGlobalKick || player.canViewReports || player.partnerApp || player.canVerify || player.canTeleport || player.kpdData || player.fakeName;
            let position = player.objInstances.position;

            Object.defineProperties(player, {
                cnBSeen: {
                    set(val) {
                        this.inView = val;
                    },
                    get() {
                        let isEnemy =!cheat.isDefined(cheat.me)||!cheat.me.team||cheat.me.team !=this.team;
                        return this.inView||isEnemy&&cheat.settings&&cheat.settings.showNameTags.val;
                    }
                },
            });

            if (this.containsPoint(position)) {

                // Chams
                if (!player.objInstances.visible) {
                    Object.defineProperty(player.objInstances, 'visible', {
                        value: true,
                        writable: false
                    });
                }
                player.objInstances.traverse(obj => {
                    if (obj && obj.type=='Mesh' && obj.hasOwnProperty('material')) {
                        if (!obj.hasOwnProperty('_material')) {
                            obj._material = obj.material;
                        } else {
                            Object.defineProperty(obj, 'material', {
                                get() {
                                    if (cheat.isDefined(cheat.mesh) && cheat.settings.renderChams.val) {
                                        return cheat.mesh[ isEnemy ? cheat.overlay.rainbow.col : 'white' ];
                                    }
                                    return cheat._material;
                                }, set(val) {return cheat._material}
                            });
                        }

                        obj.material.wireframe = !!this.settings.renderWireFrame.val;
                    }
                })
                //Tracers
                if (this.settings.renderTracers.val) {
                    CanvasRenderingContext2D.prototype.save.apply(this.ctx, []);
                    let screenPos = this.world2Screen(position.clone(), scaledWidth, scaledHeight);
                    this.ctx.lineWidth = 1;
                    this.ctx.beginPath();
                    this.ctx.moveTo(this.ctx.canvas.width/2, this.ctx.canvas.height - (this.ctx.canvas.height - scaledHeight));
                    this.ctx.lineTo(screenPos.x, screenPos.y);
                    this.ctx.strokeStyle = "rgba(0, 0, 0, 0.25)";
                    this.ctx.stroke();
                    this.ctx.lineWidth = 1;
                    this.ctx.strokeStyle = isEnemy ? isRisky ? "#FFFF00" : this.settings.espHostileCol.val : this.settings.espFriendlyCol.val
                    this.ctx.stroke();
                    CanvasRenderingContext2D.prototype.restore.apply(this.ctx, []);
                }
                /*2d*/
                if (this.settings.render2dBox.val) {
                    CanvasRenderingContext2D.prototype.save.apply(this.ctx, []);
                    let screenBase = this.world2Screen(position.clone(), scaledWidth, scaledHeight);
                    let screenHead = this.world2Screen(position.clone(), scaledWidth, scaledHeight, player.height);
                    let difference = ~~(screenBase.y - screenHead.y);
                    let tildeFloor = ~~(difference * 0.6);
                    this.ctx.lineWidth = 4;
                    this.ctx.translate(~~(screenHead.x - tildeFloor / 2), ~~screenHead.y);
                    this.ctx.beginPath();
                    this.ctx.rect(0, 0, tildeFloor, difference);
                    this.ctx.strokeStyle = "rgba(0, 0, 0, 0.25)";
                    this.ctx.stroke();
                    this.ctx.lineWidth = 2;
                    this.ctx.strokeStyle = isEnemy ? isRisky ? "#FFFF00" : this.settings.espHostileCol.val : this.settings.espFriendlyCol.val
                    this.ctx.stroke();
                    this.ctx.closePath();
                    CanvasRenderingContext2D.prototype.restore.apply(this.ctx, []);
                }
                /*Target Indicator*/
                if (player.isTarget) {
                    CanvasRenderingContext2D.prototype.save.apply(this.ctx, []);
                    let screenBase = this.world2Screen(position.clone(), scaledWidth, scaledHeight);
                    let screenHead = this.world2Screen(position.clone(), scaledWidth, scaledHeight, player.height);
                    let difference = ~~(screenBase.y - screenHead.y);
                    this.ctx.lineWidth = 4;
                    this.ctx.beginPath()
                    this.ctx.translate(screenHead.x, screenHead.y + Math.abs(difference / 2))
                    this.ctx.arc(0, 0, Math.abs(difference / 2) + 14, 0, Math.PI * 2)
                    this.ctx.strokeStyle = "#FFFFFF"
                    this.ctx.stroke()
                    this.ctx.closePath()
                    CanvasRenderingContext2D.prototype.restore.apply(this.ctx, []);
                }
                /*fovBox*/
                if (this.settings.fovBoxSize.val !== 'off') {
                    let fovBox = null;
                    switch (this.settings.fovBoxSize.val) {
                        case 'large':
                            fovBox = [scaledWidth / 3, scaledHeight / 4, scaledWidth * (1 / 3), scaledHeight / 2]
                            break;
                            // medium
                        case 'medium':
                            fovBox = [scaledWidth * 0.4, scaledHeight / 3, scaledWidth * 0.2, scaledHeight / 3]
                            break
                            // small
                        case 'small':
                            fovBox = [scaledWidth * 0.45, scaledHeight * 0.4, scaledWidth * 0.1, scaledHeight * 0.2]
                            break
                    }
                    CanvasRenderingContext2D.prototype.save.apply(this.ctx, []);
                    this.ctx.strokeStyle = "red"
                    this.ctx.strokeRect(...fovBox)
                    CanvasRenderingContext2D.prototype.restore.apply(this.ctx, []);
                }
            }
        }
    }
    onInput(input) {
        const key = { frame: 0, delta: 1, xdir: 2, ydir: 3, moveDir: 4, shoot: 5, scope: 6, jump: 7, reload: 8, crouch: 9, weaponScroll: 10, weaponSwap: 11, moveLock: 12 };

        // Auto Reload
        if (this.settings.autoReload.val) {
            let weaponIndex = this.me.weapon.secondary ? 1 : 0, ammoLeft = this.me.ammos[weaponIndex], isMelee = this.me.weapon.melee || this.me.weapon.canThrow;
            if (!isMelee && !ammoLeft) {
                input[key.reload] = 1;
            }
        }

        // Auto Bhop
        if (this.settings.autoBhop.val !== "off") {
            if (this.downKeys.has("Space") || this.settings.autoBhop.val == "autoJump" || this.settings.autoBhop.val == "autoSlide") {
                this.controls.keys[this.controls.binds.jump.val] ^=1;
                if (this.downKeys.has("Space") || this.settings.autoBhop.val == "autoSlide") {
                   if (!this.me.onGround && this.me.canSlide) {
                       this.controls.keys[this.controls.binds.crouch.val] = 1;
                   }
                    else if (this.me.onGround) {
                        setTimeout(() => {
                            this.controls.keys[this.controls.binds.crouch.val] = 0;
                        }, 200);
                    }
                }
            }
        }

        this.game.players.list.forEach(plr => { plr.isTarget = false })

        //AutoAim
        let target = null, targets = this.settings.autoAim.val !== "off" && this.game.players.list.filter(entity => {
            let isEnemy =!this.isDefined(this.me) || !this.me.team || this.me.team !=entity.team;
            return this.isDefined(entity.objInstances) && !entity.isYou && isEnemy && entity.health > 0 && (entity.inView || null == this.getCanSee(this.me, entity.x, entity.y, entity.z));
        }).sort((p1, p2) => this.getD3D(this.me.x, this.me.z, p1.x, p1.z) - this.getD3D(this.me.x, this.me.z, p2.x, p2.z))
        if (this.settings&&this.settings.fovBoxSize.val !== 'off') {
                let scaledWidth = this.ctx.canvas.width / this.scale;
                let scaledHeight = this.ctx.canvas.height / this.scale;
                for (let i = 0; i < targets.length; i++) {
                    const t = targets[i];
                    const sp = this.world2Screen(new this.three.Vector3(t.x, t.y, t.z), scaledWidth, scaledHeight, t.height / 2);
                    let fovBox = null;
                    switch (this.settings.fovBoxSize.val) {
                        case 'large':
                            fovBox = [scaledWidth / 3, scaledHeight / 4, scaledWidth * (1 / 3), scaledHeight / 2]
                            break;
                            // medium
                        case 'medium':
                            fovBox = [scaledWidth * 0.4, scaledHeight / 3, scaledWidth * 0.2, scaledHeight / 3]
                            break
                            // small
                        case 'small':
                            fovBox = [scaledWidth * 0.45, scaledHeight * 0.4, scaledWidth * 0.1, scaledHeight * 0.2]
                            break
                    }
                    if (sp.x >= fovBox[0] && sp.x <= (fovBox[0] + fovBox[2]) && sp.y >= fovBox[1] && sp.y < (fovBox[1] + fovBox[3])) {
                        target = targets[i]
                        break
                    }
                }
            } else target = targets.shift();
        if (target && !this.me.reloadTimer) {
            const multiplier = 1e3;
            let yDire = (this.getDir(this.me.z, this.me.x, target.z, target.x) || 0);
            let xDire = ((this.getXDir(this.me.x, this.me.y, this.me.z, target.x, target.y - target.crouchVal * 3 + this.me.crouchVal * 3, target.z) || 0) - (0.3 * this.me.recoilAnimY));
            let aimAt = () => {
                this.controls.object.rotation.y = yDire;
                this.controls.pchObjc.rotation.x = xDire;
                this.controls.pchObjc.rotation.x = Math.max(-(Math.PI / 2), Math.min((Math.PI / 2), this.controls.pchObjc.rotation.x));
                this.controls.yDr = (this.controls.pchObjc.rotation.x % Math.PI).round(3);
                this.controls.xDr = (this.controls.object.rotation.y % Math.PI).round(3);
                this.controls.update(400);
                input[key.scope] = 1;
            }
            let FixAim = () => {
                input[key.ydir] = yDire * multiplier;
                input[key.xdir] = xDire * multiplier;
            }
            target.isTarget = this.settings.renderTarget.val;
            switch (this.settings.autoAim.val) {
                case "quickScope":
                    if (this.me.aimDir == 1 || input[key.scope] == 0) { aimAt() }
                    if (this.me.didShoot && this.me.weapon.nAuto && !this.me.weapon.burst) { input[key.shoot] = 0 }
                    else if (this.me.aimVal == 0) { input[key.shoot] = 1 }
                    if (input[key.shoot] == 1) { FixAim() }
                    break;
                case "silent":
                    input[key.scope] = 1;
                    if (!this.me.aimVal||this.me.weapon.noAim) {
                        FixAim();
                        input[key.shoot] = 1;
                    }
                    break;
                case "correction":
                    if (input[key.shoot] == 1) { FixAim() }
                    break;
                case "smoothCam": case "smoothCamAssist":
                    if (input[key.scope]) {
                        this.controls.target = {
                            xD: xDire,
                            yD: yDire,
                            GG: true
                        };
                        this.controls.update(400);
                        this.controls.target = this.controls.target && this.controls.target.GG ? null : this.controls.target;
                        if (this.settings.autoAim.val == "smoothCamAssist" && input[key.shoot] == 1) {
                            FixAim();
                        }
                    }
                    break;
                case "trigger":
                    if (target.objInstances && this.raycaster.ray.intersectObjects([target.objInstances], true).length) {
                        input[key.scope] = 1;
                        input[key.shoot] = 1;
                    }
                    break;
                case "assist":
                    if (target.objInstances && !this.raycaster.ray.intersectObjects([target.objInstances], true).length) {
                        this.controls.object.rotation.y = yDire;
                        this.controls.xDr = (this.controls.object.rotation.y % Math.PI).round(3);
                    }
                    break;
                case "easyassist":
                    if (input[key.scope] && target.objInstances && !this.raycaster.ray.intersectObjects([target.objInstances], true).length) {
                        aimAt();
                    }
                    break;
            }
        }
    }

    //GUI
    generateSetting(type, name, extra) {
        switch (type) {
            case 'button':
                return `<input type="button" name="${type}" id="slid_utilities_${name}" class="settingsBtn" onclick="${extra.function}" value="${extra.label}" style="float:right;width:auto"/>`;
            case 'checkbox':
                return `<label class="switch"><input type="checkbox" onclick="${this.getHash("cheat")}.setSetting('${name}', this.checked)" ${this.settings[name].val ? 'checked' : ''}><span class="slider"></span></label>`;
            case 'slider':
                return `<span class='sliderVal' id='slid_utilities_${name}'>${this.settings[name].val}</span><div class='slidecontainer'><input type='range' min='${this.settings[name].min}' max='${this.settings[name].max}' step='${this.settings[name].step}' value='${this.settings[name].val}' class='sliderM' oninput="${this.getHash("cheat")}.setSetting('${name}', this.value)"></div>`
                case 'select': {
                    let temp = `<select onchange="${this.getHash("cheat")}.setSetting(\x27${name}\x27, this.value)" class="inputGrey2">`;
                    for (let option in extra) {
                        temp += '<option value="' + option + '" ' + (option == this.settings[name].val ? 'selected' : '') + '>' + extra[option] + '</option>';
                    }
                    temp += '</select>';
                    return temp;
                }
            default:
                return `<input type="${type}" name="${type}" id="slid_utilities_${name}"\n${'color' == type ? 'style="float:right;margin-top:5px"' : `class="inputGrey2" placeholder="${extra}"`}\nvalue="${this.settings[name].val}" oninput="${this.getHash("cheat")}.setSetting(\x27${name}\x27, this.value)"/>`;
        }
    }
    setSetting(key, value) {
        this.settings[key].val = value;
        //await GM.setValue(key, value);
        this.saveVal(key, value);
        if (document.getElementById(`slid_utilities_${key}`)) document.getElementById(`slid_utilities_${key}`).innerHTML = value;
        if (this.settings[key].set) this.settings[key].set(value);
    }
    saveVal(name, val) {
        localStorage.setItem("cht_"+name, val);
    }
    deleteVal(name) {
        localStorage.removeItem("cht_"+name);
    }
    getSavedVal(name) {
        return localStorage.getItem("cht_"+name);
    }
    tabContent(name) {
        let tmpHTML = "";
        for (let key in this.settings) {
            if (this.settings[key].tab == name) {
                if (this.settings[key].pre) tmpHTML += this.settings[key].pre;
                tmpHTML += "<div class='settName' id='" + key + "_div' style='display:block'>" + this.settings[key].name + " " + this.settings[key].html() + "</div>";
            }
        }
        return tmpHTML;
    }
    tabChange(evt, tabName) {
        var i, tabcontent, tablinks;
        tabcontent = document.getElementsByClassName("tabcontent");
        for (i = 0; i < tabcontent.length; i++) {
            tabcontent[i].style.display = "none";
        }
        tablinks = document.getElementsByClassName("tablinks");
        for (i = 0; i < tablinks.length; i++) {
            tablinks[i].className = tablinks[i].className.replace(" active", "");
        }
        document.getElementById(tabName).style.display = "block";
        evt.currentTarget.className += " active";
    }
    toggleMenu() {
        let lock = document.pointerLockElement || document.mozPointerLockElement;
        if (lock) document.exitPointerLock();
        if (window.showWindow) window.showWindow(12);
        if (this.isDefined(window.SOUND)) window.SOUND.play(`tick_0`,0.1)
    }
    createElement(element, attribute, inner) {
        if (!this.isDefined(element)) {
            return null;
        }
        if (!this.isDefined(inner)) {
            inner = "";
        }
        let el = document.createElement(element);
        if (this.isType(attribute, 'object')) {
            for (let key in attribute) {
                el.setAttribute(key, attribute[key]);
            }
        }
        if (!Array.isArray(inner)) {
            inner = [inner];
        }
        for (let i = 0; i < inner.length; i++) {
            if (inner[i].tagName) {
                el.appendChild(inner[i]);
            } else {
                el.appendChild(document.createTextNode(inner[i]));
            }
        }
        return el;
    }
    createButton(parent, id, name, iconURL, fn, visible) {
        visible = visible ? "inherit":"none";
        this.waitFor(_=>document.querySelector(parent)).then(parent => {
            let icon = this.createElement("div",{"class":"menuItemIcon", "style":`background-image:url("${iconURL}");display:inherit;`});
            let title= this.createElement("div",{"class":"menuItemTitle", "style":`display:inherit;`}, name);
            let host = this.createElement("div",{"id":id, "class":"menuItem", "onmouseenter":"playTick()", "onclick":`${fn}`, "style":`display:${visible};`},[icon, title]);
            if (parent) parent.append(host)
        })
    }

    // Visual
    getD3D(x1, y1, z1, x2, y2, z2) {
        let dx = x1 - x2;
        let dy = y1 - y2;
        let dz = z1 - z2;
        return Math.sqrt(dx * dx + dy * dy + dz * dz);
    }
    getAngleDst(a, b) {
        return Math.atan2(Math.sin(b - a), Math.cos(a - b));
    }
    getXDir(x1, y1, z1, x2, y2, z2) {
        let h = Math.abs(y1 - y2);
        let dst = this.getD3D(x1, y1, z1, x2, y2, z2);
        return (Math.asin(h / dst) * ((y1 > y2)?-1:1));
    }
    getDir(x1, y1, x2, y2) {
        return Math.atan2(y1 - y2, x1 - x2);
    }
    getDistance(x1, y1, x2, y2) {
        return Math.sqrt((x2 -= x1) * x2 + (y2 -= y1) * y2);
    }
    getAngleDist(a, b) {
        return Math.atan2(Math.sin(b - a), Math.cos(a - b));
    }
    containsPoint(point) {
        let planes = this.renderer.frustum.planes;
        for (let i = 0; i < 6; i ++) {
            if (planes[i].distanceToPoint(point) < 0) {
                return false;
            }
        }
        return true;
    }
    lineInRect(lx1, lz1, ly1, dx, dz, dy, x1, z1, y1, x2, z2, y2) {
        let t1 = (x1 - lx1) * dx;
        let t2 = (x2 - lx1) * dx;
        let t3 = (y1 - ly1) * dy;
        let t4 = (y2 - ly1) * dy;
        let t5 = (z1 - lz1) * dz;
        let t6 = (z2 - lz1) * dz;
        let tmin = Math.max(Math.max(Math.min(t1, t2), Math.min(t3, t4)), Math.min(t5, t6));
        let tmax = Math.min(Math.min(Math.max(t1, t2), Math.max(t3, t4)), Math.max(t5, t6));
        if (tmax < 0) return false;
        if (tmin > tmax) return false;
        return tmin;
    }
    world2Screen(pos, width, height, yOffset = 0) {
        pos.y += yOffset
        pos.project(this.renderer.camera)
        pos.x = (pos.x + 1) / 2
        pos.y = (-pos.y + 1) / 2
        pos.x *= width
        pos.y *= height
        return pos
    }
    getCanSee(from, toX, toY, toZ, boxSize) {
        if (!from) return 0;
        boxSize = boxSize||0;
        for (let obj, dist = this.getD3D(from.x, from.y, from.z, toX, toY, toZ),
             xDr = this.getDir(from.z, from.x, toZ, toX),
             yDr = this.getDir(this.getDistance(from.x, from.z, toX, toZ), toY, 0, from.y),
             dx = 1 / (dist * Math.sin(xDr - Math.PI) * Math.cos(yDr)), dz = 1 / (dist * Math.cos(xDr - Math.PI) * Math.cos(yDr)),
             dy = 1 / (dist * Math.sin(yDr)), yOffset = from.y + (from.height || 0) - 1.5,
             aa = 0; aa < this.game.map.manager.objects.length; ++aa) {
            if (!(obj = this.game.map.manager.objects[aa]).noShoot && obj.active && !obj.transparent && (!this.settings.wallBangs.val || (!obj.penetrable || !this.me.weapon.pierce))) {
                let tmpDst = this.lineInRect(from.x, from.z, yOffset, dx, dz, dy, obj.x - Math.max(0, obj.width - boxSize), obj.z - Math.max(0, obj.length - boxSize), obj.y - Math.max(0, obj.height - boxSize), obj.x + Math.max(0, obj.width - boxSize), obj.z + Math.max(0, obj.length - boxSize), obj.y + Math.max(0, obj.height - boxSize));
                if (tmpDst && 1 > tmpDst) return tmpDst;
            }
        }

        return null;
    }

    // General
    isType(item, type) {
        return typeof item === type;
    }
    isDefined(object) {
        return !this.isType(object, "undefined") && object !== null;
    }
    arrayTest(obj, arr, fn) {
        return arr.some(prop => fn(prop));
    }
    genHash(sz) {
        return [...Array(sz)].map(_ => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'[~~(Math.random()*52)]).join('');
    }
    getHash(prop) {
        this.hashes = this.hashes || {};
        if (!this.hashes.hasOwnProperty(prop)) {
            this.hashes[prop] = this.genHash(prop.length);
        }
        return this.hashes[prop];
    }
    createObserver(elm, check, callback, onshow = true) {
        return new MutationObserver((mutationsList, observer) => {
            if (check == 'src' || onshow && mutationsList[0].target.style.display == 'block' || !onshow) {
                callback(mutationsList[0].target);
            }
        }).observe(elm, check == 'childList' ? {childList: true} : {attributes: true, attributeFilter: [check]});
    }
    async waitFor(test, timeout_ms = Infinity, doWhile = null) {
        let sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
        return new Promise(async (resolve, reject) => {
            if (typeof timeout_ms != "number") reject("Timeout argument not a number in waitFor(selector, timeout_ms)");
            let result, freq = 100;
            while (result === undefined || result === false || result === null || result.length === 0) {
                if (doWhile && doWhile instanceof Function) doWhile();
                if (timeout_ms % 1e4 < freq) console.log("waiting for: ", test);
                if ((timeout_ms -= freq) < 0) {
                    console.log( "Timeout : ", test );
                    resolve(false);
                    return;
                }
                await sleep(freq);
                result = typeof test === "string" ? Function(test)() : test();
            }
            console.log("Passed : ", test);
            resolve(result);
        });
    }
};(()=>{
    localStorage.setItem("logs", true);
    // Webpack Exports Again Sidney =)
    const keys = Object.keys;
    Object.keys= function(...args) {
        (function(target) {
            try {
                let caller = arguments.callee.caller.caller;
                if (caller && caller.arguments[0].hasOwnProperty('exports')&& caller.arguments[2].hasOwnProperty('c')) {
                    Object.keys = keys;
                    cheat.exports = caller.arguments[2].c;
                }
            } catch (err) {}
        })();
        return keys.apply(this, args);
    }
})(); const cheat = new Cheat();