Ratio Script snowy

real time score prediction. you need to join https://discord.gg/GMtN8ttCdS for updates because i will not be updating it here, just posting occasionally.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

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

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         Ratio Script snowy
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  real time score prediction. you need to join https://discord.gg/GMtN8ttCdS for updates because i will not be updating it here, just posting occasionally.
// @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" }
]
// put the correct new pointers
const scorePointer = 114060
const scoreOffset = 6

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


const scoreMarks = [ // update these for different score projections
    { score: 250000, reached: false, time: 0, default: "00:00:00", format: "250k" },
    { 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()
    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
    }
}, 1000)


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