Neon's Hitbox mod

A Mod menu for hitbox.io. press shift+a to open the menu or click the white square on the corner.

当前为 2024-10-18 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Neon's Hitbox mod
// @namespace    http://tampermonkey.net/
// @version      1.0.4-Reworkv1
// @description  A Mod menu for hitbox.io. press shift+a to open the menu or click the white square on the corner.
// @author       iNeonz
// @match        https://heav.io/game.html
// @match        https://hitbox.io/game.html
// @match        https://heav.io/game2.html
// @match        https://hitbox.io/game2.html
// @match        https://hitbox.io/game-beta.html
// @icon         https://www.google.com/s2/favicons?sz=64&domain=heav.io
// @grant        none
// @run-at       document-idle
// ==/UserScript==

let modmenu = document.createElement('div');
document.body.appendChild(modmenu);

const feth = window.fetch;

function objy(params) {
    let t = {};
    for (let i of params.split('&')) {
        t[i.split('=')[0]] = i.split('=')[1];
    }
    return t;
}

let lastReplay;

window.fetch = async (url,method) => {
    let response = await feth(url,method);
    if (url.endsWith("replay_submit_spice.php")){
        let stream = response.clone();
        let r = objy(method.body);
        console.log(r);
        lastReplay = r;
    }
    return response;
}


let style = document.createElement('style');
style.innerHTML = `
  .styled-check {
  border-radius: 7px;
  vertical-align: middle;
  border: 1px solid black;
  appearance: none;
  -webkit-appearance: none;
  outline: none;
  background-color: #3b4353;
  cursor: pointer;
}

.styled-check:checked {
  appearance: none;
  background-color: #537aff;
}

.styled-button:hover {
background-color: #23262d !important;
cursor: pointer;
}

.styled-text {
border: none;
outline: none;
background-color: #595b65;
color: white;
border-radius: 7px;
}
  `;
document.head.appendChild(style);
let botEnabled = false;
let quickplayEnabled = false;
let settings = {};

let echoList = [];

function addElementToList(list,element,elements) {
    let divider = document.createElement('div');
    let content = list.querySelector('.content');
    content.appendChild(divider);
    divider.outerHTML = ` <div class="createWindow option divider lol" style="background-color: #17171c; width: calc(100% - 40px); font-size: 15px; height: 20px; margin: 5px; border-radius: 7px;">
    ${element}
    <div class="removeElement" style="cursor: pointer; top: 3px; display: inline-block; position: relative; left: 20px; width: 15px; height: 15px; border-radius: 7px; background-color: red;"></div>
    </div>`
    divider = document.querySelector('.lol');
    divider.classList.remove('lol');
    return divider;
}

function addList(tab,title,list,change) {
    let listTop = document.createElement('div');
    tab.appendChild(listTop);
    listTop.outerHTML = ` <div class="createWindow option list lol" style="width: calc(100% - 10px); font-size: 25px; min-height: 30px; height: calc(fit-content + 20px); margin: 15px; border-radius: 7px;">
    ${title}
    <input placeholder="add element" type="text" class="createWindow option styled-text" style="position: relative; top: 10px; width: calc(100% - 20px); height: 20px;"></input>
    <div class="content" style="overflow-y: scroll; max-height: 200px; position: relative; top: 10px; background-color: #292d31; width: calc(100% - 10px); font-size: 20px; height: fit-content; margin: 5px; border-radius: 7px;"></div>
    </div>`
    listTop = document.querySelector('.lol');
    listTop.classList.remove('lol');
    let input = listTop.querySelector('.styled-text');
    input.onkeydown = (e) => {
        if (e.which == 13) {
            if (!list.includes(input.value)) {
                let value = input.value;
                list.push(value);
                let element = addElementToList(listTop,value,list);
                input.value = '';
                change(list);
                element.children[0].onclick = () => {
                    list.splice(list.indexOf(value),1);
                    change(list);
                    element.remove();
                }
                setTimeout(() => {
                    document.activeElement.blur();
                },1);
            }
        }
    }
    for (let i of list) {
        let element = addElementToList(listTop,i,list);
        input.value = '';
        element.children[0].onclick = () => {
            list.splice(list.indexOf(i),1);
            change(list);
            element.remove();
        }
    }
    return listTop;
}

window.addEventListener('keydown', (e) => {
    if (document.activeElement.tagName == "INPUT" && e.which != 13) {
        console.log('ha');
        e.stopImmediatePropagation()
        return;
    }
    if (e.which == 65 && e.shiftKey) {
        modmenu.style.display = modmenu.style.display == 'none'? 'block' : 'none';
        window.selectTab(lastTabSelected);
    }
},true)

function addDivider(tab,title) {
    let divider = document.createElement('div');
    tab.appendChild(divider);
    divider.outerHTML = ` <div class="createWindow option divider" style="text-align: center; width: calc(100% - 10px); font-size: 30px; height: 30px; margin: 5px; border-radius: 7px;">${title}</div>`
}

function addDetail(tab,title) {
    let divider = document.createElement('div');
    tab.appendChild(divider);
    divider.outerHTML = ` <div class="createWindow option detail" style="width: calc(100% - 10px); font-size: 13px; height: 13px; margin: 5px; border-radius: 7px;">${title}</div>`
}


function addButton(tab,title) {
    let btn = document.createElement('div');
    tab.appendChild(btn);
    btn.outerHTML = ` <div class="createWindow option styled-button lol" style="background-color: #3d424d; width: calc(100% - 30px); font-size: 20px; height: 30px; margin-left: 20px; margin-top: 5px; border-radius: 7px;">${title}</div>`
    btn = document.querySelector('.lol');
    btn.classList.remove('lol');
    return btn;
}

function addCheckButton(tab,title,checked) {
    let check = document.createElement('div');
    tab.appendChild(check);
    check.outerHTML = ` <div class="createWindow option check lol" style="background-color: #25262a; width: calc(100% - 10px); font-size: 25px; height: 30px; margin: 5px; border-radius: 7px;">${title}</div>`
    check = document.querySelector('.lol');
    check.classList.remove('lol');
    let input = document.createElement('input');
    check.appendChild(input);
    input.outerHTML = ` <input type="checkbox" style="accent-color: #454755; top: -5px; position: relative; width: 20px;height: 20px;" class="styled-check tab input lol"></input>`
    input = document.querySelector('.lol');
    input.classList.remove('lol');
    input.checked = checked;
    return input;
}

let highestMapId = 0;
let bwLIST = JSON.parse(localStorage.getItem('bannedwords') || '[]');
let bLIST = JSON.parse(localStorage.getItem('staffList') || '[]');
let kickAFK = false;
let levels = localStorage.getItem('levels') || false;
let pingcolor = localStorage.getItem('pingcolor') || false;
let minmode = localStorage.getItem('minmode') || false;
let playerBox = localStorage.getItem('playerBox') || false;
let trailDisabled = localStorage.getItem('trailDisabled') || false;
let kickLaggy = false;

fetch("https://hitbox.io/scripts/map_get_newest_spice.php", {
    "headers": {
        "accept": "*/*",
        "content-type": "application/x-www-form-urlencoded",
        "priority": "u=1, i",
    },
    "body": "startingfrom=0",
    "method": "POST",
})
    .then(r => r.json())
    .then(r => {
    highestMapId = r.maps[0].id-602;
});

let lastTabSelected = 'Hosting & Utils';

const modMenuTabs = {
    "Hosting & Utils": function (tab) {
        if (myid != hostId) {
            tab.style.opacity = .3;
            tab.style.pointerEvents = 'none';
            addDivider(tab,"You need to be host to use this tab.");
        }
        addDetail(tab,"Press shift+a to open the menu");
        addDivider(tab,"Teams");
        addButton(tab,'Move all Blue').onclick = () => {
            for (let i of users) {
                WSS.send(`42[1,[47,{"i":${i.id},"t":3}]]`)
            }
        };
        addButton(tab,'Move all Red').onclick = () => {
            for (let i of users) {
                WSS.send(`42[1,[47,{"i":${i.id},"t":2}]]`)
            }
        };
        addButton(tab,'Shuffle teams').onclick = () => {
            let teams = [2,3].sort(() => .5 - Math.random());
            let score = [0,0,0,0,0];
            for (let i of [...users].sort(() => .5 - Math.random())) {
                let team = -1;
                let lowest = 1/0;
                for (let x of teams) {
                    if (score[x] < lowest) {
                        lowest = score[x];
                        team = x;
                    }
                }
                score[team] += 1;
                WSS.send(`42[1,[47,{"i":${i.id},"t":${team}}]]`)
            }
        };
        addButton(tab,'Move all Spec').onclick = () => {
            for (let i of users) {
                WSS.send(`42[1,[47,{"i":${i.id},"t":0}]]`)
            }
        };
        addButton(tab,'Move all FFA').onclick = () => {
            for (let i of users) {
                WSS.send(`42[1,[47,{"i":${i.id},"t":1}]]`)
            }
        };
        addDivider(tab,"Auto hosting");
        let qpb = addCheckButton(tab,"Quickplay enabled? | ",quickplayEnabled);
        addDetail(tab,"Idle hosting. automatically starts a new map after round end.");
        qpb.onchange = () => {
            quickplayEnabled = qpb.checked;
        };
        let rngMap = addButton(tab,'Random Map');
        addDetail(tab,"Chooses a random map (includes private maps)");
        rngMap.onclick = () => {
            modmenu.style.display = 'none';
            WSS.send(`42[1,[42,${Math.floor(Math.random()*highestMapId)+602}]]`);
        }

        let kkp = addCheckButton(tab,"Auto kick Laggy? (700+ ms) | ",kickLaggy);
        kkp.onchange = () => {
            kickLaggy = kkp.checked;
        };
        let kka = addCheckButton(tab,"Auto kick AFK? (afk for 2 minutes) | ",kickAFK);
        kka.onchange = () => {
            kickAFK = kka.checked;
        };
        addList(tab,"Banned words",bwLIST,(e) => {
            bwLIST = e;
            localStorage.setItem('bannedwords',JSON.stringify(bwLIST));
        });
        addList(tab,"Staff list",bLIST,(e) => {
            for (let i in e) {
                e[i] = e[i].toLowerCase();
            }
            bLIST = e;
            localStorage.setItem('staffList',JSON.stringify(bLIST));
        });
        addDetail(tab,"List of players that are unbannable");
        addDetail(tab,"And allowed to run exclusive bot commands");
        addDetail(tab,"Useful if you don't want certain players affected by anti-afk or anti-ping");
        addDivider(tab,"Settings");
        addButton(tab,'Download Settings').onclick = () => {
            let element = document.createElement('a');
            element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(JSON.stringify(settings)));
            element.setAttribute('download', 'game_settings.json');

            element.style.display = 'none';
            document.body.appendChild(element);

            element.click();

            document.body.removeChild(element);
        };
        addDetail(tab,"Download current game settings as a file to import later");
        addButton(tab,'Import Settings').onclick = () => {
            let input = document.createElement('input');
            input.setAttribute('accept','.json');
            input.type = 'file';
            input.click();
            input.onchange = (e) => {
                let a = e.target.files[0];
                const reader = new FileReader();
                reader.onload = () => {
                    WSS.send('42'+JSON.stringify([1,[62,JSON.parse(reader.result)]]));
                    WSS.onmessage({data:'42'+JSON.stringify([63,JSON.parse(reader.result)])})
                    modmenu.style.display = 'none';
                }
                reader.readAsText(a);
            }
        }
    },
    "Fun & Misc": function (tab,tabName) {
        addDivider(tab,"Bot");
        let bbn = addCheckButton(tab,"Bot enabled? | ",botEnabled);
        bbn.onchange = () => {
            botEnabled = bbn.checked;
        };
        addDivider(tab,"Chat");
        addList(tab,"Copy players",echoList,(e) => {
            echoList = e;
        });
        addButton(tab,'Clear List').onclick = () => {
            echoList = [];
            window.selectTab(tabName);
        };
        addDetail(tab,"Echo list | Copy any message a player included in the list sends.");
    },
    "Visual": function (tab,tabName) {
        addDivider(tab,"Players");
        let bbn = addCheckButton(tab,"Show player levels ingame",levels);
        bbn.onchange = () => {
            levels = bbn.checked;
            localStorage.setItem('levels',levels);
        };
        addDetail(tab,'Shows levels and indicators next to player names.');
        let bbt = addCheckButton(tab,"Laggy Colors",pingcolor);
        bbt.onchange = () => {
            pingcolor = bbt.checked;
            localStorage.setItem('pingcolor',pingcolor);
        };
        addDetail(tab,'Colors player names based on how laggy they are.');
        let ming = addCheckButton(tab,"Mini display",minmode);
        addDetail(tab,'Shorter player names, Display their ID on the side');
        ming.onchange = () => {
            minmode = ming.checked;
            localStorage.setItem('minmode',minmode);
        };
        let tt = addCheckButton(tab,"Trail disabled",trailDisabled);
        tt.onchange = () => {
            trailDisabled = tt.checked;
            localStorage.setItem('trailDisabled',trailDisabled);
        };
        addDetail(tab,'Disables trails behind players.');
        let pb = addCheckButton(tab,"Jump Box",playerBox);
        pb.onchange = () => {
            playerBox = pb.checked;
            localStorage.setItem('playerBox',playerBox);
        };
        addDetail(tab,'Shows funni box for parkour alignment');
        addDivider(tab,"World");
    },
    "Replays": function (tab,tabName) {
        addButton(tab,"Download last replay").onclick = () => {
            let element = document.createElement('a');
            element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(JSON.stringify(lastReplay)));
            element.setAttribute('download', 'replay-'+Date.now()+'.json');

            element.style.display = 'none';
            document.body.appendChild(element);

            element.click();

            document.body.removeChild(element);
        }
    }
}


function botCommands(user,cmd) {
    if (!botEnabled) return;
}

let modMenuButton = document.createElement('div');
document.body.appendChild(modMenuButton);
modMenuButton.outerHTML = `<div class="modmenubutton" style="position: absolute; right: 15px; top: 50px; width: 30px; height: 30px; border-radius: 10px; background-color: #ffffff;"></div>`

    modmenu.outerHTML = `<div style="opacity: .95; display: none; z-index: 9999999; right: 90px; top: 90px; position: absolute; width: calc(100% - 170px); height: calc(100% - 180px); background-color: #25262a; border-radius: 7px;" class="createWindow modMenu">
       <div class="createWindow modMenuTabs" style="background-color: #131616; position: absolute; top: 20px; left: 20px; width: 200px; height: calc(100% - 40px); border-radius: 7px;"></div>
       <div class="createWindow openTab" style="overflow-x: hidden; background-color: #131616; overflow-y: scroll; position: absolute; top: 20; left: 240px; width: calc(100% - 280px); height: calc(100% - 40px); border-radius: 7px;"></div>
</div>`
    modmenu = document.querySelector('.modMenu');

modMenuButton = document.querySelector(".modmenubutton");
modMenuButton.onclick = () => {
    modmenu.style.display = modmenu.style.display == 'none'? 'block' : 'none';
    window.selectTab(lastTabSelected);
}

const tabs = document.querySelector('.createWindow .modMenuTabs');
const openTab = document.querySelector('.createWindow .openTab');

window.selectTab = (tab) => {
    lastTabSelected = tab;
    openTab.style.opacity = '1';
    openTab.style.pointerEvents = 'all';
    openTab.replaceChildren();
    modMenuTabs[tab](openTab,tab);
}

for (let i in modMenuTabs) {
    let tabButton = document.createElement('div');
    tabs.appendChild(tabButton);
    tabButton.outerHTML = `<div onclick="javascript:window.selectTab('${i}');" class="createWindow tab" style="cursor: pointer; background-color: #25262a; width: calc(100% - 10px); font-size: 25px; height: 30px; margin: 5px; border-radius: 7px;">${i}</div>`
    }

const codeNames = {};
const codeNamesRegex = {
    "simulation": {
        reg: /\];\}.{0,2}\(.{0,3}\) {var .{0,3},.{0,3},.{0,3},.{0,3},.{0,3},.{0,3};(.*?)\{throw new Error\("Failed to simulate(.*?)\);\}(.*?)\.step\((.*?)\);(.*?).{0,2}\(\);(.*?)\}.{0,2}\(\)/ig,
        verify: function(match)
        {
            //console.log(match);
            let world = match[0].match(/this\..{2,2}\.step\(/ig)[0];
            let sim = match[0].split(";}")[1].split("(")[0];
            //console.log(sim);
            let thisses = match[0].split("this.");
            //console.log(thisses);
            for (let i of thisses){
                if (i.match("=")){
                    i = i.split("=")[0];
                }else{
                    i = null;
                }
            }
            thisses.filter(a => a != null);
            //console.log(thisses);
            //console.log([sim,thisses[1].split(".")[0],thisses[1].split(".")[1].split("(")[0]]);
            return [sim,thisses[1].split(".")[0],thisses[1].split(".")[1].split("(")[0],world.split("this.")[1].split(".")[0]];
        }
    },
}


//funny
setInterval(() => {
    if (hostId == myid && kickAFK) {
        for (let i of users) {
            if (Date.now() > i.act+120000 && !bLIST.includes(i.name.toLowerCase())) {
                WSS.send(`42[1,[32,{"id":${i.id},"ban":0}]]`);
            }
        }
    }
},1000);

parent.document.getElementById("adboxverticalright").style.top = "-200%";
parent.document.getElementById("adboxverticalleft").style.top = "-200%";

const lerpNumber = function(a, b, weight) {
    return ((1 - weight) * a + weight * b);
};


let bot = false;
let myid = -1;
let quickplay = false;
let qpdelay = 0;
let hostId = -2;

let DN = [
    "gsFightersCollide",
    "recordMode",
    "o",
    "l",
    "u",
    "m",
    "g",
    "v",
    "k",
    "N",
    "S",
    "M",
    "C",
    "_",
    "T",
    "P",
    "B",
    "I",
    "F",
    "R",
    "O",
    "A",
    "D",
    "L",
    "U",
    "H",
    "J",
    "W",
    "G",
    "Y", // ss
    "V",
    "q",
    "K",
    "X",
    "Z",
    "$",
    "tt",
    "it",
    "st",
    "ht",
    "et",
    "nt",
    "ot",
    "rt",
    "at",
    "lt",
    "ut",
    "ct",
    "dt",
    "wt",
    "ft",
    "gt",
    "bt"
]

let stateMaker;
let mostScore = -1;

for (let a1 in window.multiplayerSession){
    let a = window.multiplayerSession[a1];
    if (typeof a == "object")
    {
        let score = 0;
        for (let x1 in a){
            let x = a[x1];
            if (typeof x == "object")
            {
                if (x.constructor.name == "Array"){

                }
                else
                {
                    let length = 0;
                    for (let y1 in x){
                        let y = x[y1];
                        length++
                        if (length > 2){
                            break;
                        }
                    }
                    if (length == 1){
                        for (let y1 in x){
                            let y = x[y1];
                            if (y.constructor.name == "Map"){
                                score++
                            }
                            break;
                        }
                    }else{
                        let isDN = true;
                        for (let i of DN){
                            if (!i in x){
                                isDN = false;
                                break;
                            }
                        }
                        if (isDN){
                            score+=5;
                        }
                    }
                }
            }
        }
        if (score > mostScore && score < 52){
            mostScore = score;
            stateMaker = a;
        }
    }
}

function buildArray(sample) {
    const sampleVar = String(sample.constructor).match(/this\.(.*?)=/ig);
    const sampleArray = [];
    for (let i of sampleVar) {
        if (i && i.match("=")) {
            sampleArray.push(i.split("this.")[1].split("=")[0]);
        }
    }
    return sampleArray;
}

const KRArray = buildArray(stateMaker);
console.log(KRArray,'krarray');
const HB = stateMaker[KRArray[24]];
const HBArray = buildArray(HB);
console.log(HBArray,'HB');

let plrArray;

HB.rre = HB.render;

// 10 - NameBG
// 11,12 - Stamina
// 14 - jump
// 13 - name
// 0 - trail
// 8 - cube

HB.render = (...args) => {
    const playerArray = HB[HBArray[0]];
    if (playerArray[8]) {
        for (let x in playerArray[8]) {
            let y = playerArray[8][x];
            if (y) {
                if (!plrArray) {
                    plrArray = buildArray(y);
                    console.log(plrArray,'plrArray');
                }
                let user = findUser(x);
                let display = y[plrArray[1]];
                if (display.children[17] && user) {
                    let name = display.children[13];
                    if (playerBox) {
                        let width = (display.children[8]._w || display.children[8].width)*1.2;
                        if (!display.children[8]._w) {
                            display.children[8]._w = width;
                        }
                        if (!user.b || user.b.parent != display.children[8]) {
                            if (user.b) {
                                user.b.destroy();
                                delete user.b;
                            }
                            var b = new PIXI.Graphics();
                            //b.beginFill(0xFFFF00);
                            b.lineStyle(.1, 0xFFFFFF);
                            b.drawRect(-.5, -.5, 1, 1);
                            b.drawRect(-1.7/2, -.05, 1.7, .1);
                            b.drawRect(-.05, -1.7/2, .1, 1.7);

                            display.children[8].addChild(b);
                            user.b = b;
                            user.b.alpha = .25;
                        }
                        user.b.width = width;
                        user.b.height = width;
                        let rot = (Math.round(user.b.angle/45)*45);
                        user.b.tint = rot % 90 != 0? 0xFF0000 : 0xffffff;
                        user.b.angle = -display.children[8].angle;
                    }else{
                        if (user.b) {
                            user.b.destroy();
                            delete user.b;
                        }
                    }
                    let playerName = user.mininame || user.name;
                    if (display.children[0]) {
                        display.children[0].visible = !trailDisabled;
                    }
                    if (minmode) {
                        if (!user.mininame || display.children[10].visible) {
                            playerName = `${user.id}-${user.name.toLowerCase().replaceAll(' ','').replaceAll('_','').slice(0,3)}`;
                            user.mininame = playerName;
                            display.children[10].visible = false;
                            display.children[14].alpha = .25;
                        }
                    }else if (user.mininame){
                        display.children[10].visible = true;
                        display.children[14].alpha = 1;
                        delete user.mininame;
                    }
                    if (name && levels) {
                        name.text = `${playerName}. ${user.lvl}${hostId == user.id? '👑' : ''}`;
                    }else{
                        name.text = playerName;
                    }
                    if (pingcolor && user.LagStrikes) {
                        if (user.LagStrikes > 3) {
                            name.tint = 0xff0000;
                        }else if (user.LagStrikes > 1) {
                            name.tint = 0xffff00;
                        }else{
                            name.tint = 0xffffff;
                        }
                    }
                }
            }
        }
    }
    return HB.rre(...args);
}

/*
    if (this.parent && this._text) {
        let user = findUser(this._text);
        if (!user && this._text.includes('. ')) {
            user = findUser(this._text.split('. ')[0]);
        }
        if (user) {
            if (levels) {
                if (!this._text.includes('. ')) {
                    this.text = user.name+'. '+user.lvl+(myid == user.id? '🔺' : '🔹');
                }
            }else{
                if (this._text.includes('. ')) {
                    this.text = user.name;
                }
            }
            if (pingcolor && user.LagStrikes) {
                if (user.LagStrikes > 3) {
                    this.tint = 0xff0000;
                }else if (user.LagStrikes > 1) {
                    this.tint = 0xffff00;
                }else{
                    this.tint = 0xffffff;
                }
            }
        }
    }
*/

let users = [];

window.requestAnimationFrame = new Proxy( window.requestAnimationFrame, {
    apply( target, thisArgs, args ) {
        Reflect.apply(...arguments);
    }
})

//Nm vm Sm

const originalSend = window.WebSocket.prototype.send;
const excludewss = [];
let WSS = 0;

function findUser(id){
    return users[id-0] || (() => {
        for (let t in users) {
            let o = users[t];
            if (o.name == id || o.id == id){
                return o;
            }
        }
    })();
}

window.WebSocket.prototype.send = function(args) {
    if(this.url.includes("/socket.io/?EIO=3&transport=websocket&sid=")){
        if(typeof(args) == "string" && !excludewss.includes(this)){
            if (!WSS){
                WSS = this;
                window.WS = this;
            }
            if (WSS == this){
                if (args.startsWith('42[1,[')) {
                    try{
                        let packet = JSON.parse(args.slice(5,-1))
                        if (packet[0] == 62) {
                            settings = packet[1];
                        }
                        if (quickplayEnabled) {
                            if (packet[0] == 68 && myid == hostId) {
                                WSS.send(`42[1,[42,${Math.floor(Math.random()*highestMapId)+602}]]`);
                                setTimeout(() => {document.querySelector("#appContainer > div.lobbyContainer > div.settingsBox > div.startButton.settingsButton").click();},500);
                            }
                        }
                    }catch(error){}
                }else if (args.startsWith('42[2,')) {
                    myid = 0;
                    hostId = 0;
                }
            }else{
                excludewss.push(this);
            }
            //console.log('SENT',args);
        }
        if (!this.injected){
            this.injected = true;
            const originalClose = this.onclose;
            this.onclose = (...args) => {
                if (WSS == this){
                    WSS = 0;
                    users = [];
                    hostId = -2;
                    quickplay = false;
                }
                originalClose.call(this,...args);
            }
            this.onmessage2 = this.onmessage;
            this.onmessage = function(event){
                if(!excludewss.includes(this) && typeof(event.data) == 'string'){
                    if (event.data.startsWith('42[')){
                        let packet = JSON.parse(event.data.slice(2,event.data.length));
                        if (packet[0] == 16) {
                            settings = packet[1][0];
                        }
                        if (packet[0] == 63) {
                            settings = packet[1];
                        }
                        if (packet[0] == 35) {
                            for (let i of packet[1]) {
                                let user = findUser(i.i);
                                if (!user.LagStrikes) {
                                    user.LagStrikes = 0;
                                }
                                if (i.p > 250) {
                                    user.LagStrikes += 1;
                                    if (i.p < 700 && user.LagStrikes > 2) {
                                        user.LagStrikes = 2;
                                    }
                                    if (hostId == myid && user.id != hostId && user.LagStrikes > 6 && !bLIST.includes(user.name.toLowerCase()) && kickLaggy) {
                                        WSS.send(`42[1,[32,{"id":${user.id},"ban":0}]]`);
                                    }
                                }else{
                                    if (user.LagStrikes > 0) {
                                        user.LagStrikes -= .5;
                                    }
                                }
                            }
                        }
                        if (packet[0] == 12) {
                            let user = findUser(packet[1][3]);
                            if (user) {
                                user.act = Date.now();
                            }
                        }
                        if (packet[0] == 7){
                            users = [];
                            myid = packet[1][0]
                            hostId = packet[1][1];
                            for (let i of packet[1][3]){
                                users[i[4]] = ({"act": Date.now(),"team": i[2],"color":(i[7][0] || i[7][1]),"name":i[0],"id":i[4],"lvl":i[6]});
                            }
                        }
                        if (packet[0] == 29) {
                            let user = findUser(packet[1]);
                            user.act = Date.now();
                            if (echoList.includes(user.name)) {
                                WSS.send('42'+JSON.stringify([1,[28,packet[2]]]));
                            }
                            if (hostId == myid) {
                                for (let i of bwLIST) {
                                    if (packet[2].toLowerCase().includes(i.toLowerCase())) {
                                        WSS.send(`42[1,[32,{"id":${user.id},"ban":0}]]`);
                                    }
                                }
                            }
                            botCommands(user,packet[2]);
                        }
                        if (packet[0] == 25){
                            let plr = findUser(packet[1]);
                            if (plr){
                                plr.team = packet[2];
                            }
                        }
                        if (packet[0] == 9){
                            hostId = packet[2];
                            let user = findUser(packet[1]);
                            if (user){
                                if (user.pet){
                                    user.pet.destroy();
                                    user.pet = null;
                                }
                                delete users[packet[1]];
                            }
                        }
                        if (packet[0] == 45){
                            hostId = packet[1];
                            if (hostId != myid){
                                quickplay = false;
                            }
                        }
                        if (packet[0] == 8){
                            users[packet[1][4]] = ({"act": Date.now(),"name":packet[1][0],"color":(packet[7]? (packet[7][1] || packet[7][0]):undefined),"team":packet[1][2],"id":packet[1][4],"lvl":packet[1][6]});
                        }
                    }
                }
                this.onmessage2(event);
            }
        }
    }
    return originalSend.call(this, args);
}

let chats = document.getElementsByClassName('content');
let inputs = document.getElementsByClassName('input');

let chatI = [];

for (let c of inputs){
    if (c.parentElement.classList.contains('inGameChat') || c.parentElement.classList.contains('chatBox')){
        chatI.push(c);
    }
}


window.hescape = (s) => {
    let lookup = {'$':'&#36;','%':'&#37;','.':'&#46;','+':'&#43;','-':'&#45;','&':"&amp;",'"': "&quot;",'\'': "&apos;",'<': "&lt;",'*':'&#42;','=':'&#61;','>': "&gt;",'#':'&#35;',':':'&#58;',';':'&#59;','`':'&#96;'};
    return s.replace( /[\*=%#\-+&"'<>]/g, c => lookup[c] );
}

function getRGBFromNUM(colorID,offset,max){
    const red = (colorID >> 16) & 0xFF;
    const green = (colorID >> 8) & 0xFF;
    const blue = colorID & 0xFF;

    // Construct the RGB color representation
    return `rgb(${Math.max(max || 0,red-(offset || 0))}, ${Math.max(max || 0,green-(offset || 0))}, ${Math.max(max || 0,blue-(offset || 0))})`;
}


function display(text,ingamecolor,lobbycolor,sanitize){
    if (WSS){
        let div = document.createElement('div');
        div.classList.add('statusContainer');
        let span = document.createElement('span');
        span.classList.add('status');
        span.style.color = lobbycolor || "#ffffff";
        if (sanitize != false){
            span.textContent = text;
        }else{
            span.innerHTML = text;
        }
        span.style.backgroundColor = 'rgba(37, 38, 42, 0.768627451)';
        div.style.borderRadius = '7px';
        div.appendChild(span);
        let clone = div.cloneNode(true);
        clone.children[0].style.color = ingamecolor || '#ffffff';
        setTimeout(() => {
            clone.remove();
        },11500);
        for (let i of chats){
            if (i.parentElement.classList.contains('chatBox')){
                i.appendChild(div);
                i.scrollTop = Number.MAX_SAFE_INTEGER;
            }else{
                i.appendChild(clone);
            }
        }
    }
}