The Ultimate Ratio Script (time, score/min, projected times)

Uses time from your computer to calculate your ratio and expected time to get milestones based on that

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         The Ultimate Ratio Script (time, score/min, projected times)
// @namespace    http://tampermonkey.net/
// @version      1.8.3
// @description  Uses time from your computer to calculate your ratio and expected time to get milestones based on that
// @author       MrCheese#4666
// @match        https://diep.io/
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Add HTML elements
    const textContainer = document.createElement("div");
    const gui = document.createElement("div");
    document.body.appendChild(textContainer);
    document.body.appendChild(gui);

    // Enabled/disabled lines
    var dispLine1 = false;
    var dispLine2 = true;
    var dispLine3 = true;
    var dispLine4 = false;
    var dispLine5 = true;
    var dispLine6 = true;

    // Set variables
    var time = '00:00:00';
    var rawTime = 0;
    var rawRatio = 0;
    var showText = true;
    var _100k = false;
    var _500k = false;
    var _1m = false;
    var _1_5m = false;
    var _2m = false;
    var _100kTime = '100k 00:00:00';
    var _500kTime = '500k 00:00:00';
    var _1mTime = '1.0m 00:00:00';
    var _1_5mTime = '1.5m 00:00:00';
    var _2mTime = '2.0m 00:00:00';
    var ratio = '0/min';

    updateText();

    gui.outerHTML = `
<div class='parent' id='menu' style='user-select:none; position:fixed; bottom:43%; right:0.75%; text-align:center; width:7.5vw; font-family:Ubuntu; color:#FFFFFF; font-style:normal; font-size:0.9vw; text-shadow:black 0.18vh 0, black -0.18vh 0, black 0 -0.18vh, black 0 0.18vh, black 0.18vh 0.18vh, black -0.18vh 0.18vh, black 0.18vh -0.18vh, black -0.18vh -0.18vh, black 0.09vh 0.18vh, black -0.09vh 0.18vh, black 0.09vh -0.18vh, black -0.09vh -0.18vh, black 0.18vh 0.09vh, black -0.18vh 0.09vh, black 0.18vh -0.09vh, black -0.18vh -0.09vh'>
    <div class='child' style='line-height:2vh; opacity:75%'>
        [Z] toggle menu
        [X] toggle text
        <hr>
    </div>
    <button class='child' type='button' id='button1' value='off' style='width:7.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:#E69F6C; color:#FFFFFF; font-style:normal; font-size:0.9vw; text-shadow:black 0.18vh 0, black -0.18vh 0, black 0 -0.18vh, black 0 0.18vh, black 0.18vh 0.18vh, black -0.18vh 0.18vh, black 0.18vh -0.18vh, black -0.18vh -0.18vh, black 0.09vh 0.18vh, black -0.09vh 0.18vh, black 0.09vh -0.18vh, black -0.09vh -0.18vh, black 0.18vh 0.09vh, black -0.18vh 0.09vh, black 0.18vh -0.09vh, black -0.18vh -0.09vh'></button>
    <button class='child' type='button' id='button2' value='on' style='width:7.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:#FF73FF; color:#FFFFFF; font-style:normal; font-size:0.9vw; text-shadow:black 0.18vh 0, black -0.18vh 0, black 0 -0.18vh, black 0 0.18vh, black 0.18vh 0.18vh, black -0.18vh 0.18vh, black 0.18vh -0.18vh, black -0.18vh -0.18vh, black 0.09vh 0.18vh, black -0.09vh 0.18vh, black 0.09vh -0.18vh, black -0.09vh -0.18vh, black 0.18vh 0.09vh, black -0.18vh 0.09vh, black 0.18vh -0.09vh, black -0.18vh -0.09vh'></button>
    <button class='child' type='button' id='button3' value='on' style='width:7.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:#C980FF; color:#FFFFFF; font-style:normal; font-size:0.9vw; text-shadow:black 0.18vh 0, black -0.18vh 0, black 0 -0.18vh, black 0 0.18vh, black 0.18vh 0.18vh, black -0.18vh 0.18vh, black 0.18vh -0.18vh, black -0.18vh -0.18vh, black 0.09vh 0.18vh, black -0.09vh 0.18vh, black 0.09vh -0.18vh, black -0.09vh -0.18vh, black 0.18vh 0.09vh, black -0.18vh 0.09vh, black 0.18vh -0.09vh, black -0.18vh -0.09vh'></button>
    <button class='child' type='button' id='button4' value='off' style='width:7.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:#71B4FF; color:#FFFFFF; font-style:normal; font-size:0.9vw; text-shadow:black 0.18vh 0, black -0.18vh 0, black 0 -0.18vh, black 0 0.18vh, black 0.18vh 0.18vh, black -0.18vh 0.18vh, black 0.18vh -0.18vh, black -0.18vh -0.18vh, black 0.09vh 0.18vh, black -0.09vh 0.18vh, black 0.09vh -0.18vh, black -0.09vh -0.18vh, black 0.18vh 0.09vh, black -0.18vh 0.09vh, black 0.18vh -0.09vh, black -0.18vh -0.09vh'></button>
    <button class='child' type='button' id='button5' value='on' style='width:7.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:#FFED3F; color:#FFFFFF; font-style:normal; font-size:0.9vw; text-shadow:black 0.18vh 0, black -0.18vh 0, black 0 -0.18vh, black 0 0.18vh, black 0.18vh 0.18vh, black -0.18vh 0.18vh, black 0.18vh -0.18vh, black -0.18vh -0.18vh, black 0.09vh 0.18vh, black -0.09vh 0.18vh, black 0.09vh -0.18vh, black -0.09vh -0.18vh, black 0.18vh 0.09vh, black -0.18vh 0.09vh, black 0.18vh -0.09vh, black -0.18vh -0.09vh'></button>
    <button class='child' type='button' id='button6' value='on' style='width:7.5vw; height:3vh; font-family:Ubuntu; opacity:75%; background:#FF7979; color:#FFFFFF; font-style:normal; font-size:0.9vw; text-shadow:black 0.18vh 0, black -0.18vh 0, black 0 -0.18vh, black 0 0.18vh, black 0.18vh 0.18vh, black -0.18vh 0.18vh, black 0.18vh -0.18vh, black -0.18vh -0.18vh, black 0.09vh 0.18vh, black -0.09vh 0.18vh, black 0.09vh -0.18vh, black -0.09vh -0.18vh, black 0.18vh 0.09vh, black -0.18vh 0.09vh, black 0.18vh -0.09vh, black -0.18vh -0.09vh'></button>
</div>
`;
    if (localStorage.getItem('menu') == 'hide') {
        menu.style.display = "block";
    } else {
        localStorage.setItem('menu', 'hide');
    }

    addButtonListener('button1');
    addButtonListener('button2');
    addButtonListener('button3');
    addButtonListener('button4');
    addButtonListener('button5');
    addButtonListener('button6');

    updateGui();

    function addButtonListener(id) {
        document.getElementById(id).addEventListener("click", function() {buttonAction(id)});
        document.getElementById(id).addEventListener("mouseenter", function() {lightenColor(id)});
        document.getElementById(id).addEventListener("mouseleave", function() {resetColor(id)});
    }

    function lightenColor(id) {
        document.getElementById(id).style.opacity = '100%'
    }

    function resetColor(id) {
        document.getElementById(id).style.opacity = '75%'
    }

    // Removes "diep.io" text above the minimap to preserve space (by ABC)
    const crx = CanvasRenderingContext2D.prototype;
    crx.fillText = new Proxy(crx.fillText, {
        apply: function(f, _this, args) {
            const text = args[0];
            if (args[0] === "diep.io") {
                args[0] = "";
            }
            f.apply(_this, args);
        }
    });
    crx.strokeText = new Proxy(crx.strokeText, {
        apply: function(f, _this, args) {
            const text = args[0];
            if (args[0] === "diep.io") {
                args[0] = "";
            }
            f.apply(_this, args);
        }
    });

    // Button action
    function buttonAction(id) {
        let button = document.getElementById(id);
        if (button.value == "on") button.value = "off"
        else button.value = "on"

        if (id == 'button1') {
            if (dispLine1 == true) dispLine1 = false
            else dispLine1 = true
        }
        if (id == 'button2') {
            if (dispLine2 == true) dispLine2 = false
            else dispLine2 = true
        }
        if (id == 'button3') {
            if (dispLine3 == true) dispLine3 = false
            else dispLine3 = true
        }
        if (id == 'button4') {
            if (dispLine4 == true) dispLine4 = false
            else dispLine4 = true
        }
        if (id == 'button5') {
            if (dispLine5 == true) dispLine5 = false
            else dispLine5 = true
        }
        if (id == 'button6') {
            if (dispLine6 == true) dispLine6 = false
            else dispLine6 = true
        }

        updateText();
        updateGui();
    }

    // Update GUI
    function updateGui() {
        let button1Text = '100k: ' + document.getElementById('button1').value;
        let button2Text = '500k: ' + document.getElementById('button2').value;
        let button3Text = '1.0m: ' + document.getElementById('button3').value;
        let button4Text = '1.5m: ' + document.getElementById('button4').value;
        let button5Text = '2.0m: ' + document.getElementById('button5').value;
        let button6Text = 'Ratio: ' + document.getElementById('button6').value;

        document.getElementById('button1').innerHTML = button1Text;
        document.getElementById('button2').innerHTML = button2Text;
        document.getElementById('button3').innerHTML = button3Text;
        document.getElementById('button4').innerHTML = button4Text;
        document.getElementById('button5').innerHTML = button5Text;
        document.getElementById('button6').innerHTML = button6Text;
    }

    // Reset times at the start of each round
    function resetTimes() {
        _100kTime = '100k 00:00:00';
        _500kTime = '500k 00:00:00';
        _1mTime = '1.0m 00:00:00';
        _1_5mTime = '1.5m 00:00:00';
        _2mTime = '2.0m 00:00:00';
        ratio = '0/min';
    }

    // Press X to toggle text and Z to toggle menu
    document.body.onkeydown = function(e) {
        if (e.keyCode === 88) {
            if (showText == false) {
                textContainer.style.opacity = '100%';
                showText = true;
            } else {
                textContainer.style.opacity = '0%';
                showText = false;
            }
        }

        if (e.keyCode === 90) {
            var menu = document.getElementById('menu');
            if (menu.style.display === "none") {
                menu.style.display = "block";
            } else {
                menu.style.display = "none";
            }
        }
    }

    // Get current score (by ABC)
    let _rScore = "0";
    CanvasRenderingContext2D.prototype.fillText = new Proxy(CanvasRenderingContext2D.prototype.fillText, {
        apply(fillRect, ctx, [text, x, y, ...blah]) {

            if (text.startsWith('Score: ')) _rScore = text

            fillRect.call(ctx, text, x, y, ...blah);
        }
    });

    const getScore = () => {
        if (!input.should_prevent_unload()) return -1;
        return parseFloat(_rScore.slice(7).replace(/,/g, ''));
    }

    // Parse time for projected score times
    function timeParse(score) {
        let _time = (score / rawRatio) * 60;
        let hours = 0;
        let minutes = 0;
        let seconds = 0;

        if (_time >= 3600) {
            hours = Math.round(_time / 3600 - 0.5);
            _time -= hours * 3600;
            if (hours < 10) hours = '0' + hours;
        } else hours = '00';

        if (_time >= 60) {
            minutes = Math.round(_time / 60 - 0.5);
            _time -= minutes * 60;
            if (minutes < 10) minutes = '0' + minutes;
        } else minutes = '00';

        if (_time !== 0) {
            seconds = Math.round(_time);
            if (seconds < 10) seconds = '0' + seconds;
        } else seconds = '00';

        let parsedTime = hours + ':' + minutes + ':' + seconds;
        return parsedTime;
    }

    // Update text
    function updateText() {
        let line1 = _100kTime;
        let line2 = _500kTime;
        let line3 = _1mTime;
        let line4 = _1_5mTime;
        let line5 = _2mTime;
        let line6 = ratio;
        if (dispLine1 == false) line1 = ''
        if (dispLine2 == false) line2 = ''
        if (dispLine3 == false) line3 = ''
        if (dispLine4 == false) line4 = ''
        if (dispLine5 == false) line5 = ''
        if (dispLine6 == false) line6 = ''

        textContainer.innerHTML = `
<div class="parent" style='pointer-events:none; user-select:none; position:fixed; text-align:right; bottom:24%; right:1.3%; font-family:Ubuntu; color:#FFFFFF; font-style:normal; font-size:1.85vh; opacity:65%; text-shadow:black 0.18vh 0vh,black -0.18vh 0vh,black 0vh -0.18vh,black 0vh 0.18vh,black 0.18vh 0.18vh, black -0.18vh 0.18vh, black 0.18vh -0.18vh, black -0.18vh -0.18vh, black 0.09vh 0.18vh, black -0.09vh 0.18vh, black 0.09vh -0.18vh, black -0.09vh -0.18vh, black 0.18vh 0.09vh, black -0.18vh 0.09vh, black 0.18vh -0.09vh, black -0.18vh -0.09vh'>
<div class="child" style='font-size:3.1vh; text-shadow:black 0.2vh 0vh, black -0.2vh 0vh, black 0vh -0.2vh, black 0vh 0.2vh, black 0.2vh 0.2vh, black -0.2vh 0.2vh, black 0.2vh -0.2vh, black -0.2vh -0.2vh, black 0.1vh 0.2vh, black -0.1vh 0.2vh, black 0.1vh -0.2vh, black -0.1vh -0.2vh, black 0.2vh 0.1vh, black -0.2vh 0.1vh, black 0.2vh -0.1vh, black -0.2vh -0.1vh'>${time}</div>
<div class="child">${line1}</div>
<div class="child">${line2}</div>
<div class="child">${line3}</div>
<div class="child">${line4}</div>
<div class="child">${line5}</div>
<div class="child">${line6}</div>
</div>
`;
    }

    // Main code (runs once a second)
    setInterval(() => {

        // Get time and display on main timer
        if (input.should_prevent_unload()) {
            let [hours, minutes, seconds] = time.split(':');
            if (parseInt(seconds) + 1 !== 60) {
                let addZero = (parseInt(seconds) + 1).toString().length == 1 ? '0' : '';
                seconds = `${addZero}${parseInt(seconds) + 1}`;
                rawTime += 1;
            } else {
                if (parseInt(minutes) + 1 !== 60) {
                    let addZero = (parseInt(minutes) + 1).toString().length == 1 ? '0' : '';
                    seconds = '00';
                    minutes = `${addZero}${parseInt(minutes) + 1}`;
                } else {
                    let addZero = (parseInt(hours) + 1).toString().length == 1 ? '0' : '';
                    seconds = '00';
                    minutes = '00';
                    hours = `${addZero}${parseInt(hours) + 1}`;
                }
            }

            time = `${hours}:${minutes}:${seconds}`;
        } else if (!input.should_prevent_unload()) {
            time = '00:00:00';
            rawTime = 0;
        }

        // Check if score is 0
        if (getScore() !== -1) {
            if (getScore() == 0) resetTimes()
            else {

                // Calculate and display ratio
                if (rawTime != 0) ratio = getScore() / (rawTime / 60);
                    else ratio = 0;
                    rawRatio = ratio;

                if (ratio >= 1000000) {
                    ratio /= 1000000;
                    ratio = ratio.toFixed(2);
                    ratio = ratio + 'm';
                } else if (ratio >= 1000) {
                    ratio /= 1000;
                    ratio = ratio.toFixed(2);
                    ratio = ratio + 'k';
                } else ratio = Math.round(ratio);
                ratio = ratio + '/min'

                // Display projected score times
                if (getScore() < 100000) {
                    _100kTime = '100k ' + timeParse(100000);
                } else if (_100k == false) {
                    _100kTime = '100k ' + time;
                    _100k = true;
                }

                if (getScore() < 500000) {
                    _500kTime = '500k ' + timeParse(500000);
                } else if (_500k == false) {
                    _500kTime = '500k ' + time;
                    _500k = true;
                }

                if (getScore() < 1000000) {
                    _1mTime = '1.0m ' + timeParse(1000000);
                } else if (_1m == false) {
                    _1mTime = '1.0m ' + time;
                    _1m = true;
                }

                if (getScore() < 1500000) {
                    _1_5mTime = '1.5m ' + timeParse(1500000);
                } else if (_1_5m == false) {
                    _1_5mTime = '1.5m ' + time;
                    _1_5m = true;
                }

                if (getScore() < 2000000) {
                    _2mTime = '2.0m ' + timeParse(2000000);
                } else if (_2m == false) {
                    _2mTime = '2.0m ' + time;
                    _2m = true;
                }
            }
        }

        // Update text
        updateText();
    }, 1000);
})();