Ratio Script

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

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

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

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

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

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

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.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

// ==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);