Memory based AFK & move to tank

set Afk spot with Q, toggle afk with R, toggle move2Tank with T, switch Follow mode: Body/Mouse with G

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         Memory based AFK & move to tank
// @namespace    http://tampermonkey.net/
// @version      0.0.3
// @description  set Afk spot with Q, toggle afk with R, toggle move2Tank with T, switch Follow mode: Body/Mouse with G
// @author       r!PsAw
// @match        https://diep.io/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=diep.io
// @grant        unsafeWindow
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-start
// @license      MIT
// ==/UserScript==

//define win
const win = typeof unsafeWindow !== "undefined" ? unsafeWindow : window;

//keys bypass
(function() {
    win.frozenHasFocus = {
        hasFocus: () => true
    };
    document.hasFocus = () => true;
})();

//memory hook
if(!win.exists){
    win.exists = false;
    win.Object.defineProperty(win.Object.prototype, "HEAPF32", {
        get: function() {
            return undefined;
        },
        set: function(newHeapF32) {
            if (!newHeapF32 || !this.HEAPU32) return;
            delete win.Object.prototype.HEAPF32;
            window.Module = this;
            window.Module.HEAPF32 = newHeapF32;
            win.Module = window.Module;
            win.exists = true;
        },
        configurable: true,
        enumerable: true
    });
}

//keys definition
const diep_keys = [
  "KeyA", "KeyB", "KeyC", "KeyD", "KeyE", "KeyF", "KeyG", "KeyH", "KeyI", "KeyJ", "KeyK", "KeyL", "KeyM", "KeyN", "KeyO", "KeyP", "KeyQ", "KeyR", "KeyS", "KeyT", "KeyU", "KeyV", "KeyW", "KeyX", "KeyY", "KeyZ",
  "ArrowUp", "ArrowLeft", "ArrowDown", "ArrowRight", "Tab", "Enter", "NumpadEnter", "ShiftLeft", "ShiftRight", "Space", "Numpad0", "Numpad1", "Numpad2", "Numpad3", "Numpad4", "Numpad5", "Numpad6", "Numpad7", "Numpad8", "Numpad9",
  "Digit0", "Digit1", "Digit2", "Digit3", "Digit4", "Digit5", "Digit6", "Digit7", "Digit8", "Digit9", "F2", "End", "Home", "Semicolon", "Comma", "NumpadComma", "Period", "Backslash"
].reduce((n, e, c) => {
    n[e] = c + 1;
    return n;
}, {});

function key_down(Key){
    input.onKeyDown(diep_keys[Key]);
    //console.log('pressing', Key);
}

function key_up(Key){
    input.onKeyUp(diep_keys[Key]);
    //console.log('unpressing', Key);
}

//generate TAB ID
function generate_ID(length) {
    let final_result = "";
    let chars =
        "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+-=/.,".split(
            ""
        );
    for (let i = 0; i < length; i++) {
        final_result += chars[Math.floor(Math.random() * chars.length)];
    }
    return GM_getValue(final_result) ? generate_ID(length) : final_result;
}

//find index
const basevalue = 4.593316236210318e-41; //0x800b
const offsets = {x: 65, y: 69};
let baseindex;


function find_index() {
    //console.log('called find_index');
    if(baseindex && baseindex != -1){
        //console.log('FOUND baseindex: ', baseindex);
        return
    }
    if(win.exists){
        //console.log('win exists');
        baseindex = Module.HEAPF32.indexOf(basevalue);
    }
    setTimeout(find_index, 100);
}
find_index();

//movement control
function unpress_all(){
    key_up("KeyW");
    key_up("KeyA");
    key_up("KeyS");
    key_up("KeyD");
}

class MovementControl{
    constructor(){
        this.afk = false;
        this.move2tank = false;
        this.moving = false;
        this.pressed_keys = [0, 0, 0, 0];
        this.afk_goal = {x: 0, y: 0};
        this.tank_goal = {x: 0, y:0};
    }
    toggle_afk(){
        unpress_all();
        this.afk = !this.afk;
        this.move2tank = false;
    }
    toggle_move2tank(){
        unpress_all();
        this.move2tank = !this.move2tank;
        this.afk = false;
    }
}
const mc = new MovementControl();

//store info about your tab
class Tab{
    constructor(){
        this.id = generate_ID(20);
        this.master = false;
        this.follow = "Body"; //Body or Mouse
        this.last_pos = {x:0, y:0};
        this.current_pos = {x:0, y:0};
        this.predicted_pos = {x:0, y:0};
        this.mouse_pos = {x:0, y:0};
    }
    change_follow(){
        if(this.follow === "Body"){
            this.follow = "Mouse";
        }else if(this.follow === "Mouse"){
            this.follow = "Body";
        }
    }
    update(){
        if(baseindex && baseindex != -1){
            this.last_pos.x = this.current_pos.x;
            this.last_pos.y = this.current_pos.y;
            this.current_pos.x = Module.HEAPF32[baseindex+offsets.x];
            this.current_pos.y = Module.HEAPF32[baseindex+offsets.y];
            this.mouse_pos.x = Module.HEAPF32[18022];
            this.mouse_pos.y = Module.HEAPF32[18024];
        }
    }
    predict(){
        this.predicted_pos.x = this.current_pos.x+((this.current_pos.x-this.last_pos.x)*100);
        this.predicted_pos.y = this.current_pos.y+((this.current_pos.y-this.last_pos.y)*100);
    }
    save(){
        GM_setValue(this.id + ' Body', this.predicted_pos);
        GM_setValue(this.id + ' Mouse', this.mouse_pos);
    }
}

const you = new Tab();

//handle focus
window.addEventListener("focus", () => {
    if (typeof you !== "undefined" && you) {
        you.master = true;
        unpress_all();
        GM_setValue("Master", you.id);
    }
});

window.addEventListener("blur", () => {
    if (typeof you !== "undefined" && you) {
        you.master = false;
    }
});

//handle movement
function move(goal){
    const your_coords = you.current_pos;
    if (!goal.x || !goal.y) return;
    const deltaX = goal.x - your_coords.x;
    const deltaY = goal.y - your_coords.y;

    const angle = Math.atan2(deltaY, deltaX);
    const angleDeg = (Math.atan2(deltaY, deltaX) * 180 / Math.PI + 360) % 360;
    const quadrant = Math.floor((angleDeg + 22.5) / 45) % 8;
    const directionKeys = [
        [0,0,0,1],
        [0,0,1,1],
        [0,0,1,0],
        [0,1,1,0],
        [0,1,0,0],
        [1,1,0,0],
        [1,0,0,0],
        [1,0,0,1]
    ];
    //console.log(quadrant);
    mc.pressed_keys = directionKeys[quadrant];
    //console.log(mc.pressed_keys, quadrant);
    mc.pressed_keys[0] ? key_down("KeyW") : key_up("KeyW");
    mc.pressed_keys[1] ? key_down("KeyA") : key_up("KeyA");
    mc.pressed_keys[2] ? key_down("KeyS") : key_up("KeyS");
    mc.pressed_keys[3] ? key_down("KeyD") : key_up("KeyD");
}

function handle_movement(){
    if(mc.afk){ //AFK logic
        move(mc.afk_goal);
    }else if(mc.move2tank && !you.master){ //move to tank logic
        move(mc.tank_goal);
    }
}

setInterval(handle_movement, 100);

//handle toggling
function set_goal(){
    mc.afk_goal.x = you.current_pos.x;
    mc.afk_goal.y = you.current_pos.y;
}

function handle_world_pos(){
    window.requestAnimationFrame(handle_world_pos);
    you.update();
    you.predict();
    you.save();
    if(!you.master){
        let master = GM_getValue("Master");
        if(!master) return;
        let raw_pos;
        if(you.follow === "Body"){
            raw_pos = GM_getValue(master + ' Body');
            //console.log(raw_pos);
        }else if(you.follow === "Mouse"){
            raw_pos = GM_getValue(master + ' Mouse');
            //console.log(raw_pos);
        }
        //console.log(raw_pos);
        //if(!raw_pos) return;
        //let parsed_pos = JSON.parse(raw_pos);
        //console.log(raw_pos);
        if(!raw_pos || !raw_pos.x || !raw_pos.y) return;
        mc.tank_goal.x = raw_pos.x;
        mc.tank_goal.y = raw_pos.y;
    }
}
window.requestAnimationFrame(handle_world_pos);

document.onkeydown = function(e) {
    if(!input?.doesHaveTank()) return;
    //console.log(e.key);
    if(e.key === "q" || e.key === "Q"){
        input.inGameNotification(`New position selected at x: ${Math.floor(you.current_pos.x)} y: ${Math.floor(you.current_pos.y)}`, 9999);
        set_goal();
    }else if(e.key === "r" || e.key === "R"){
        mc.toggle_afk();
        let message = mc.afk? "ON" : "OFF";
        input.inGameNotification(`AFK: ${message}`, 999);
    }else if(e.key === "t" || e.key === "T"){
        mc.toggle_move2tank();
        let message = mc.move2tank? "ON" : "OFF";
        input.inGameNotification(`move to Tank: ${message}`, 5000);
    }else if(e.key === "g" || e.key === "G"){
        you.change_follow();
        input.inGameNotification(`Now following: ${you.follow}`, 20000);
    }
};

function debug(){
    console.log(`
    you.master: ${you.master}
    you.id: ${you.id}
    your pos x: ${you.current_pos.x}
    your pos y: ${you.current_pos.y}
    baseindex: ${baseindex}
    real master: ${GM_getValue("Master")}
    move2Tank goal x: ${GM_getValue(GM_getValue("Master")+" Body").x}
    move2Tank goal y: ${GM_getValue(GM_getValue("Master")+" Body").y}
    `);
}
//setInterval(debug, 5000);