Greasy Fork

Ultra Mobs Alert

Show spawn timer, sharing another players. Work In Progress https://discord.gg/4nPjXjVf4t

当前为 2023-05-03 提交的版本,查看 最新版本

// ==UserScript==
// @name         Ultra Mobs Alert
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  Show spawn timer, sharing another players. Work In Progress https://discord.gg/4nPjXjVf4t
// @author       @jmatg1
// @license MIT
// @match        https://florr.io
// @icon         https://www.google.com/s2/favicons?sz=64&domain=florr.io
// @grant        none
// ==/UserScript==

class GUI {
    constructor() {
        this.bosses = [];
        this.menu = document.body.appendChild(document.createElement('div'));
        this.menu.style.padding = '15px';
        this.menu.style.background = '#ffffff3f';
        this.menu.style['border-radius'] = '10px';
        this.menu.style.display = 'block';
        this.menu.style.position = 'absolute';
        this.menu.style['pointer-events'] = 'none';
        this.menu.style.bottom = '5px';
        this.menu.style.right = '5px';

        this.table = this.menu.appendChild(document.createElement('table'));
        this.table.style['font-family'] = 'Ubuntu';
        this.table.style['border-collapse'] = 'collapse';
        this.table.style.width = `100%`;
        setInterval(() => {
            this.updateTable();
        }, 60 * 1000)
    }

    updateTable(bosses = this.bosses) {
        console.log(bosses);
        this.bosses = bosses;
        while (this.table.rows.length > 0) {
            this.table.deleteRow(0);
        }
        bosses.sort((a, b) => {
            return new Date(a.date).getTime() - new Date(b.date).getTime();
        });

        bosses = bosses.filter((x) => {
            const minutes = Math.floor((Date.now() - new Date(x.date).getTime()) / 1000 / 60);
            if (minutes > 240) {
               return false
            }
            return true;
        });
        bosses.forEach((x, i) => {
            const tr = this.table.insertRow();

            // Mob
            const td1 = tr.insertCell();
            if (i !== 0) {
                td1.style['padding-top'] = '5px';
            }
            if (i !== bosses.length - 1) {
                td1.style['padding-bottom'] = '5px';
            }
            td1.style['padding-right'] = '20px';

            td1.appendChild(document.createTextNode(x.name));

            // minutes ago
            const td2 = tr.insertCell();
            if (i !== 0) {
                td2.style['padding-top'] = '5px';
            }
            if (i !== bosses.length - 1) {
                td2.style['padding-bottom'] = '5px';
            }
            td2.style['pointer-events'] = 'auto';
            td2.style.cursor = 'pointer';
            td2.appendChild(document.createTextNode(this.toTimeSpanString(x.date)));
        });
    }

    toTimeSpanString(timestamp) {
        if (timestamp == null) {
            return 'N/A';
        }

        let minutes = Math.floor((Date.now() - new Date(timestamp).getTime()) / 1000 / 60);
        let h = Math.floor(minutes / 60);
        minutes = minutes % 60;
        return `${String(h).padStart(2, '0')}:${String(minutes).padStart(2, '0')}`;
    }
}
class ServerId {
    constructor() {
        this.servers = [];
    this.url;
    const nativeWebSocket = window.WebSocket;
    var totalServers = 17 - 1;
    var regionName, allServers = [];
    var _this = this;
    window.WebSocket = function (...args) {
        const socket = new nativeWebSocket(...args);
         _this.url = socket.url
        return socket;
    };

    for (let i = 0; i <= totalServers; i++) {
        fetch(`https://api.n.m28.io/endpoint/florrio-map-${i}-green/findEach/`).then((response) => response.json()).then((data) => {
            this.servers[i] = `${data.servers["vultr-miami"].id} ${data.servers["vultr-frankfurt"].id} ${data.servers["vultr-tokyo"].id}`
        });
    }
        }

    getId() {
        var wssUrl = this.url.slice(6, 9)
        var codeA = [];
        var regionName = '';
        this.servers.forEach(function callback(x, index) {
            if (x.includes(wssUrl)) {
                codeA = x.split(" ")
                if (wssUrl == codeA[0]) regionName = "NA"
                else if (wssUrl == codeA[1]) regionName = "EU"
                else if (wssUrl == codeA[2]) regionName = "AS"
            }
        });
        return regionName;
    }
}

(function () {
    'use strict';

    const gui = new GUI();
    const serv = new ServerId();

    let socket = new WebSocket("wss://cyber-glorious-ferry.glitch.me");

    socket.onopen = function(e) {
        console.log("[open] Соединение установлено");
        setInterval(() => {
            socket.send(JSON.stringify({message: "PING", serverName: 'EU'}));
        }, 60 * 1000)
    };

    socket.onmessage = function(event, isBinary) {
        const message = JSON.parse(event.data);
        if (message === "PONG") {
        return
        }
        gui.updateTable(message['EU']);

    };

    socket.onclose = function(event) {
        if (event.wasClean) {
            console.log(`[close] Соединение закрыто чисто, код=${event.code} причина=${event.reason}`);
        } else {
            console.log('[close] Соединение прервано');
        }
    };

    socket.onerror = function(error) {
        console.log(`[error]`);
    };

    var flag = false;
    function parseText(text, _this) {
        if(flag) {
            return
        }
        if(text && text.search(/((An Ultra)|(A Super)) (.*) has spawned!?( somewhere!?)?/i) !== -1) {
            socket.send(JSON.stringify({message: text, serverName: serv.getId()}));
            console.warn(JSON.stringify({message: text, serverName: serv.getId()}));
            flag = true;
            setTimeout(() => {
                flag = false;
            }, 10 * 60 * 1000)
        }
        //console.log(text, x, y, a)
    }

    function getCompatibleCanvas() {
        if (typeof (OffscreenCanvasRenderingContext2D) == 'undefined') { return [CanvasRenderingContext2D] }
        return [OffscreenCanvasRenderingContext2D, CanvasRenderingContext2D];
    }
    for (const { prototype } of getCompatibleCanvas()) {
        if (prototype.rewriteStrokeText == undefined) {
            if (false) { prototype.rewriteArc = prototype.arc }
            prototype.rewriteStrokeText = prototype.strokeText;
            prototype.rewriteFillText = prototype.fillText;
            prototype.rewriteMeasureText = prototype.measureText;
        }
        else { break }
    }
    for (const { prototype } of getCompatibleCanvas()) {

        //重写字符描边函数
        prototype.strokeText = function (text, x, y) {
            parseText(text, this);
            return this.rewriteStrokeText(text, x, y);
        }

        prototype.fillText = function (text, x, y) {
            parseText(text, this);
            return this.rewriteFillText((text), x, y);
        }
        prototype.measureText = function (text) {
            parseText(text, this);
            return this.rewriteMeasureText((text));
        }
    }
})();