Ratio Script

join my discord server for updates to the script: https://discord.gg/862cXbhXmh

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         Ratio Script
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  join my discord server for updates to the script: https://discord.gg/862cXbhXmh
// @author       Snowfall (_snowyfall_ on Discord)
// @match        https://*diep.io/*
// @grant        unsafeWindow
// @run-at       document-start
// ==/UserScript==

const win = typeof unsafeWindow !== "undefined" ? unsafeWindow : window;
const W = WebAssembly;

const expose = e => {
    try {
        const m = e.memory || Object.values(e).find(x => x instanceof W.Memory);
        if (!m) return;

        const b = m.buffer;

        win.Module = {
            memory: m,
            HEAP8:   new Int8Array(b),
            HEAPU8:  new Uint8Array(b),
            HEAP16:  new Int16Array(b),
            HEAPU16: new Uint16Array(b),
            HEAP32:  new Int32Array(b),
            HEAPU32: new Uint32Array(b),
            HEAPF32: new Float32Array(b),
            HEAPF64: new Float64Array(b),
            ready: true
        };

        win.dispatchEvent(new Event("wasm-ready"));
    } catch (e) {
        console.error(e);
    }
};

const wrap = f => async (...a) => {
    const r = await f(...a);
    const i = r.instance || r;
    expose(i.exports || {});
    return r;
};

W.instantiate = wrap(W.instantiate.bind(W));
if (W.instantiateStreaming) {
    W.instantiateStreaming = wrap(W.instantiateStreaming.bind(W));
}

let visible = true;
document.addEventListener('keydown', (e) => {
    if (e.key.toLowerCase() === 'q') {
        visible = !visible;
        timeEl.style.display = visible ? 'block' : 'none';
    }
});

const screenStates = [
    { name: "home", selector: "#home-screen" },
    { name: "ingame", selector: "#in-game-screen" },
    { name: "deathscreen", selector: "#game-over-screen" }
]

const scorePtr = 146096
const scoreOffset = 100

const current_score = (scorePointer) => {
    let pointer = Module.HEAP32[scorePointer] >> 2
    let scorePtr = (Module.HEAP32[pointer] >> 2) + scoreOffset
    return Module.HEAPF32[scorePtr]
}


const scoreMarks = [ // update these for different score projections
    { score: 20000, reached: false, time: 0, default: "00:00:00", format: "20k" },
    { score: 500000, reached: false, time: 0, default: "00:00:00", format: "500k" },
    { score: 1000000, reached: false, time: 0, default: "00:00:00", format: "1.0m" },
    { score: 2000000, reached: false, time: 0, default: "00:00:00", format: "2.0m" },
]

const projectedTime = (score, time, projectedScore) => { // seconds
    let currentRate = score / time
    currentRate = projectedScore / currentRate
    return currentRate
}

const convert = (score) => { // score to string func
    if (score >= 1000000) {
        return (score / 1000000).toFixed(6) + "m";
    } else if (score >= 1000) {
        return (score / 1000).toFixed(3) + "k";
    } else {
        return score.toString();
    }
};

const ratio = (score, time) => {
    return (score / (time / 60)).toFixed(2)
}

const format = (time) => {
    return new Date(time * 1000).toISOString().substr(11, 8);
};

let start = null
let alive = false
let elapsed

setInterval(() => {
    const current = Math.floor(Date.now() / 1000)
    const score = current_score(scorePtr)
    let currentState = null;

    screenStates.forEach((state) => {
        let x = document.querySelector(state.selector)
        x = Array.from(x.classList)
        if (x.includes("active")) {
            currentState = state.name
        }
    })

    if (currentState == "ingame" && alive == false) {
        start = Math.floor(Date.now() / 1000)

        scoreMarks.forEach((mark) => {
            mark.reached = false
        })

        alive = true
    }

    elapsed = current - start

    if (currentState == "ingame" && alive == true) {
        if (score > 0) {
            scoreMarks.forEach((mark) => {
                if (mark.reached === false) {
                    if (score >= mark.score) {
                        mark.reached = true
                        mark.time = format(elapsed)
                    } else {
                        const projected = projectedTime(score, elapsed, mark.score)
                        mark.time = format(projected)
                    }
                }
            })

            timeEl.textContent = `${format(elapsed)}\n`
            scoreMarks.forEach((mark) => {
                timeEl.textContent += `${mark.format}: ${mark.time}\n`
            })
            timeEl.textContent += `${convert(ratio(score, elapsed))}/min\n`
        } else {
            timeEl.textContent = `${format(elapsed)}\n`
            scoreMarks.forEach((mark) => {
                timeEl.textContent += `${mark.format}: ${mark.default}\n`
            })
            timeEl.textContent += `${convert(ratio(score, elapsed))}/min`
        }
    } else if (currentState == "home" || currentState == "deathscreen") {
        alive = false
    }

    console.log(scoreMarks)
}, 1000)

const timeEl = document.createElement('div');
Object.assign(timeEl.style, {
    position: 'fixed',
    right: '10px',
    top: '60%',
    transform: 'translateY(-50%)',
    color: '#ffffff',
    fontSize: '18px',
    fontFamily: 'Arial, sans-serif',
    pointerEvents: 'none',
    zIndex: '999999',
    whiteSpace: 'pre-line',
    textAlign: 'right',
});
document.body.appendChild(timeEl);