Neon's Heav mod

A Mod for heav.io. type -help for help.

目前為 2023-09-25 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Neon's Heav mod
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  A Mod for heav.io. type -help for help.
// @author       iNeonz
// @match        https://heav.io/game.html
// @icon         https://www.google.com/s2/favicons?sz=64&domain=heav.io
// @grant        none
// @run-at       document-idle
// ==/UserScript==

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

let users = [];
let pollActive = false;
let pollTimer = 0;
let rektbot = false;
let pollOptions = [];
let pollVotes = {};
let modeConfig = {};
let modes = [
    {
    name:"Normal"
    },
    {
    name:"Tag",
    tick: function(dt){
        if (!modeConfig.isTAG){
            modeConfig = {
             isTAG: true,
             timer: 10,
             player: 0
            }
        }
        for (let p of users){

        }
    },
    death: function(plr){

    }
    }
]
let currentMode = 0;

let abc = 'abcdefghijklmnopqrstuvwxyz';

const cmds = {
    "help":"The command list you see right now.",
    "qp":"Toggles qp",
    "poll [A,B,C,...]":"Creates a poll which lasts 30 seconds.",
    "stopPoll":"Ends the current active poll.",
    "rektbot":"toggles rekbot"
}

const admin = [
 'iNeonz'
]

function display(text,isPlayer){
    if (WSS){
        WSS.onmessage({data:`42[29,${myid},"NHM > ${text}"]`})
    }
}

function send(txt){
    if (WSS){
        WSS.send(`42[1,[28,"${txt}"]]`)
    }
}

function ask(question){
    let response = fetch('https://monke-bot.damcorruption.repl.co/chatbot/'+encodeURIComponent(question.replaceAll('monke','')))
    return response.then(r => r.json());
}

function runCMD(command){
    if (command == '+help'){
        display(`HELP COMMAND ----------|`)
        for (let i in cmds){
            display(`+${i} | ${cmds[i]}`)
        }
        return ' '
    }
    if (command == '+qp'){
        if (myid == hostId){
        quickplay = !quickplay;
        display(`qp is now ${quickplay}`);
        qpdelay = 1;
        }else{
        display(`You are not the host! `)
        }
        return ' '
    }
        if (command == '+rektbot'){
        rektbot = !rektbot;
        display(`rektbot is now ${rektbot}`);
        return ' '
    }
    if (command.startsWith('+poll')){
       let options = command.split('+poll ')[1].split(',');
        pollOptions = options;
        let ptxt = '';
        for (let i in options){
         let p = options[i];
         let letter = abc[i%abc.length];
         ptxt += `${letter}) ${p.substring(0,8)}${" ".repeat(5-p.substring(0,4).length)}`
        }
        display(`A NEW POLL HAS STARTED, AND WILL END IN 30 SECONDS`);
        pollActive = true;
        pollTimer = 30;
        return `Type the letter to vote: ${ptxt}`
    }
    if (command == '+stopPoll'){
     if (pollActive){
         pollTimer = .01;
         return 'Ending the poll.';
     }else{
         display("There is no polls active.");
     }
     return '';
    }
}

function globalCmds(plrID,txt){
    if (txt.toLowerCase().includes("monke")){
        ask(txt)
            .then(r => {
            send('Monke > '+r.response);
        })
    }
    if (txt.length == 1){
     let ntxt = txt.toLowerCase();
     if (abc.includes(ntxt)){
      let option = pollOptions[abc.indexOf(ntxt)];
      let pl = findUser(plrID);
      if (option && pl){
      pollVotes[name] = abc.indexOf(ntxt);
      }
     }
    }
    if (txt.startsWith("!info")){
        send("Hi, i created a funni script with damian's chatbot.");
    }
    if (txt.startsWith("!help")){
     send("!roll 1-20|!gay");
    }
    if (txt.startsWith("!roll")){
        try {
        let num = parseInt(txt.split(' ')[1])
        send(`1d${Math.floor(Math.random()*num)}`)
        }catch(e){}
     }
    if (txt == '!track'){
              let alivey = 0;
         let p1;
         let p2;
            for (let i in alive){
                if (p1 && !p2){
                    p2 = i;
                }else if (!p1){
                 p1 = i;
                }
                alivey++;
            }
        console.log(alivey,p1,p2);
            if (alivey== 2 && p1 && p2){
                let pl1 = findUser(p1);
                let pl2 = findUser(p2);
                let arrows = {
                    "1 0":'➡️',
                    "1 1":'↘️',
                    "0 1":'⬇️',
                    "-1 1":'↙️',
                    "-1 0":'⬅️',
                    "-1 -1":'↖️',
                    "0 -1":'⬆️',
                    "1 -1":'↗️'
                }
                let p1c = gCoordinates(pl1.x,pl1.y);
                let p2c = gCoordinates(pl2.x,pl2.y);
                let dir = Math.atan2(p2c[1]-p1c[1],p2c[0]-p1c[0]);
                let c = [Math.cos(dir),Math.sin(dir)];
                let p3 = [c[0] > 0.4? 1 : (c[0] < -0.4? -1 : 0),c[1] > 0.4? 1 : (c[1] < -0.4? -1 : 0)];
                let t = p3[0]+' '+p3[1];
                console.log('p1',p1c,'p2',p2c,'dir',dir,'c',c,'p3',p3);
                let arr = arrows[t];
                let dist = Math.floor(Math.sqrt(((p1c[0]-p2c[0])**2)+((p1c[1]-p2c[1])**2)));
                send(`${pl2.name} is ${dist}ft away from ${pl1.name} (${arr})`);
            }else{
             send(`There must be 2 players alive, right now there is ${alivey}.`);
            }
    }
    if (txt.startsWith("!gay")){
     let pl = findUser(plrID);
     if (pl){
      let perc = Math.floor(Math.random()*10000)/100
      /*let txts = [
          'Sigma',
          'Hetéro',
          'Mei viado',
          'Beta',
          'Viado',
          'Boiola Mega'
          ]*/
      let txts = [
          'Sigma',
          'Straight',
          'Kinda gay',
          'Beta',
          'Gay',
          'Very Pretty Much A Gay'
          ]
      let part = Math.floor((Math.floor(perc)/100)*txts.length);
      //send(`${pl.name}, você é ${perc}% gay... Eu diria que você é... ${txts[part]}`);
       send(`${pl.name}, You are ${perc}% gay... I'd say you are... ${txts[part]}`);
     }
    }
}

const alive = {};

// Your code here...

const render = window.PIXI.Graphics.prototype.finishPoly
window.PIXI.Graphics.prototype.finishPoly = function(...args){
    render.call(this,...args)
    if (this.parent) {
        for (let i of this.parent.children) {
            if (i._text) {
                alive[i._text] = {obj: this.parent,frames: 5, txt: i};
                if (admin.includes(i._text)){
                    i.tint = 0xff11ff
                }
                break;
            }
        }
    }
}
/*for (let i in window.PIXI.Graphics.prototype) {
        let v = window.PIXI.Graphics.prototype[i];
        if (typeof(v) == 'function') {
            console.log(i," injected");
            let prot = window.PIXI.Graphics.prototype[i]
            window.PIXI.Graphics.prototype[i] = function(...args){
                let c = prot.call(this,...args);
                if (this.parent && this.parent.children) {
                 for (let p of this.parent.children) {
                     if (p._text) {
                      console.log(i,p._text);
                     }
                 }
                }
               if (this.children) {
                 for (let p of this.children) {
                     if (p._text) {
                      console.log(i,p._text);
                     }
                 }
                }
                return c
            }
        }
    }*/
let frames = 0;
let lc = Date.now();

function gCoordinates(x,y){
    let bg = document.getElementById('backgroundImage')
    if (bg){
     let w = bg.clientWidth;
     let h = bg.clientHeight;
     let scale = w/730;
     return [x/scale,y/scale];
    }
    return [0,0];
}

window.requestAnimationFrame = new Proxy( window.requestAnimationFrame, {
    apply( target, thisArgs, args ) {
        let T = Date.now();
        let dt = (T-lc)/1000;
        lc = T;
        frames++
        if (frames % 60 == 0){

        }
        if (pollActive){
         if (pollTimer > 0){
          pollTimer -= dt;
          if (pollTimer <= 0){
           let votes = {};
           let mostVoted = 0;
           let mostVotes = 0;
           for (let i in pollVotes){
               let option = pollOptions[pollVotes[i]];
               if (!votes[option]){votes[option] = 0;}
               votes[option] += 1
               if (votes[option] > mostVotes){mostVotes = votes[option]; mostVoted = pollVotes[i];}
           }
           let choosen = pollOptions[mostVoted];
           if (choosen){
            send(`POLL ENDED: ${choosen} has won the Poll with ${mostVotes} votes! (Which is ${Math.floor((mostVotes/users.length)*10000)/100}% of this room)`);
           }
           pollVotes = [];
           pollOptions = [];
           pollActive = false;
          }
         }
        }
        //matrix.hue(frames%300);
        for (let i in alive) {
            let unalive = (!alive[i].obj || !alive[i].obj.transform || !alive[i].obj.parent || !alive[i].txt || !alive[i].txt.visible || alive[i].txt.parent != alive[i].obj || !alive[i].obj.visible || alive[i].obj.alpha <= 0);
            let p = findUser(i);
            if (p){
            if (unalive){
                alive[i].frames--
                if (alive[i].frames <= 0){
                    console.log(i,' has died');
                    if (document.getElementsByClassName('lobbyContainer')[0].style.display == 'none'){
                     let c = gCoordinates(p.x,p.y);
                     if (rektbot){
                     send("[NHM Rekt Bot] > "+i+" has died at X: "+Math.floor(c[0])+" Y: "+Math.floor(c[1]));
                     }
                    }
                    delete alive[i];
                }
            }else{
                p.x = alive[i].obj.x;
                p.y = alive[i].obj.y;
            }
            }else{
             delete alive[i];
            }
        }
        if (quickplay){
            if (document.getElementsByClassName('lobbyContainer')[0].style.display != 'none'){
                if (qpdelay > 0){
                    qpdelay -= dt;
                }
                if (qpdelay <= 0){
                    qpdelay = 5;
                    let maps = document.getElementsByClassName('mapsContainer')[0].getElementsByClassName('element');
                    let map = maps[Math.floor(Math.random()*maps.length)];
                    map.click();
                    setTimeout(() => {
                        document.getElementsByClassName("startButton")[0].click();
                    },100);
                }
            }
        }
        Reflect.apply(...arguments);
    }
})

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

window.sendPacket = function(packet) {
    if (WSS) {
        console.log("SENT > ",packet);
    }else{
        console.log("Could not send: No wss connected.");
    }
}
/*

   */

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

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;
            }
            if (WSS == this){
                if (args.startsWith('42[1,[')) {
                    try{
                        let packet = JSON.parse(args.slice(5,-1))
                        if (packet[0] == 28) {
                            let newMsg = runCMD(packet[1]);
                            if (newMsg) {
                                console.log(newMsg.length);
                                if (newMsg.length < 2) {args = ''; return;}
                                args = `42[1,[28,"${newMsg}"]]`
                        }
                        }
                    }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 = [];
                    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] == 7){
                            console.log("ID: ",packet[1][0])
                            myid = packet[1][0]
                            hostId = packet[1][1];
                            for (let i of packet[1][3]){
                             users.push({"name":i[0],"id":i[4],"lvl":i[6]});
                            }
                        }
                        if (packet[0] == 9){
                         hostId = packet[2];
                         let user = findUser(packet[1]);
                         if (user){
                          console.log(user.name,'left');
                          users.splice(user.index,1);
                         }
                        }
                        if (packet[0] == 45){
                           hostId = packet[1];
                            if (hostId != myid){
                             quickplay = false;
                            }
                        }
                        if (packet[0] == 29 && !packet[2].startsWith("Monke > ")){
                            globalCmds(packet[1],packet[2])
                        }
                        if (packet[0] == 8){
                            console.log("plr join")
                            users.push({"name":packet[1][0],"id":packet[1][4],"lvl":packet[1][6]});
                            setTimeout(() => {
                            WSS.send(`42[1,[28,"Hello! welcome, mr or ms ${packet[1][0]} that entered with lvl ${packet[1][6]}"]]`)
                            },100);
                        }
                    }
                }
                this.onmessage2(event);
            }
        }
    }
    return originalSend.call(this, args);
}

/* setInterval(() => {
        WSS.send('42[1,[13,["TEST"]]]')
    },1000) */