您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show spawn timer, sharing another players. Work In Progress https://discord.gg/4nPjXjVf4t Dont use your real discrod you can banned
当前为
// ==UserScript== // @name Ultra Mobs Alert // @namespace http://tampermonkey.net/ // @version 9 // @description Show spawn timer, sharing another players. Work In Progress https://discord.gg/4nPjXjVf4t Dont use your real discrod you can banned // @author @jmatg1 // @license MIT // @match https://florr.io // @icon https://www.google.com/s2/favicons?sz=64&domain=florr.io // @grant none // @require https://openuserjs.org/src/libs/sizzle/GM_config.js // ==/UserScript== const VERSION = "9"; alert('Detected. Wait update') return; GM_config.init( { 'id': 'MyConfig', // The id used for this instance of GM_config 'fields': // Fields object { 'filterNames': // This is the id of the field { 'label': 'Filter Names, Example: Rock, Bush', // Appears next to field 'type': 'text', 'default': '' // Default value if user doesn't change it }, 'spawnSound': // This is the id of the field { 'label': 'Spawn Sound', // Appears next to field 'type': 'checkbox', 'default': true // Default value if user doesn't change it }, 'spawnSoundUrl': // This is the id of the field { 'label': 'spawnSoundUrl', // Appears next to field 'type': 'text', 'default': "https://zvukogram.com/index.php?r=site/download&id=47315" // Default value if user doesn't change it }, 'Button': { 'label': 'Test Sound', // Appears on the button 'type': 'button', // Makes this setting a button input 'size': 100, // Control the size of the button (default is 25) 'click': function() { // Function to call when button is clicked playSound(); } } } }); try { let xhr = new XMLHttpRequest(); xhr.open('GET', "https://greasyfork.org/ru/scripts/465457.json"); xhr.send(); xhr.onload = function() { let obj = JSON.parse(xhr.response) if (obj.version !== VERSION){ let t = "New Version!!!" + " (" + VERSION + " -> " + obj.version + ") https://greasyfork.org/ru/scripts/465457-ultra-mobs-alert" window.alert(t) } }; } catch (e){} function playSound() { try{ new Audio(GM_config.get('spawnSoundUrl')).play() } catch(er) { alert(er) } } function createInput(array, id) { var selectList = document.createElement("select"); selectList.style.pointerEvents = "auto"; selectList.id = id; for (var i = 0; i < array.length; i++) { var option = document.createElement("option"); option.value = array[i]; option.text = array[i]; selectList.appendChild(option); } return selectList; } class GUI { constructor(serv) { this.data = {}; this.bosses = []; this.filterName = []; const div = document.createElement('div'); div.appendChild(createInput(["All", "NA", "EU", "AS"], "serverIdSelect")); const fl = document.createElement('span') fl.appendChild(document.createTextNode('Settings')); fl.onclick = () => {GM_config.open()} fl.style['pointer-events'] = 'auto'; div.appendChild(fl); this.menu = document.body.appendChild(document.createElement('div')); this.menu.appendChild(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.changeServer(document.getElementById('serverIdSelect').value); }, 10 * 1000) } updateTable(bosses = this.bosses) { this.bosses = bosses; const filtered = GM_config.get('filterNames') === '' ? [] : GM_config.get('filterNames').split(',').map(el => el.trim()); 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 > 25) { return false } return true; }); bosses.forEach((x, i) => { if(filtered.length && !filtered.find(el => x.name.search(el) !== -1)) { return } 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.style['color'] = x?.l ? 'green' : 'black'; td1.style['pointer-events'] = 'none'; 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'] = 'none'; 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); minutes = minutes <= 0 ? 0 : minutes; return `${minutes}m ago`; } changeServer(id = 'All') { let data = [] if (id === 'All') { for(let key of Object.keys(this.data)) { this.data[key].forEach(el => { data.push({ ...el, name: el.name + ' [' + key + ']', }); }) } } else { data = this.data[id]; } this.updateTable(data); } } class ServerId { constructor() { this.servers = []; this.url; this.regionName; const nativeWebSocket = window.WebSocket; var totalServers = 17 - 1; var allServers = []; var _this = this; window.WebSocket = function (...args) { const socket = new nativeWebSocket(...args); if (socket.url.search('cyber-glorious') === -1){ _this.url = socket.url; } return socket; }; const urls = []; for (let i = 0; i <= totalServers; i++) { urls.push(`https://api.n.m28.io/endpoint/florrio-map-${i}-green/findEach/`); } Promise.all(urls.map(url => fetch(url).then(resp => resp.text()) )).then(texts => { if (texts.length === 17) { texts.forEach(el => { const data = JSON.parse(el) this.servers.push(`${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 = []; this.servers.forEach((x, index) => { if (x.includes(wssUrl)) { codeA = x.split(" ") if (wssUrl == codeA[0]) this.regionName = "NA" else if (wssUrl == codeA[1]) this.regionName = "EU" else if (wssUrl == codeA[2]) this.regionName = "AS" } }); return this.regionName; } } class WebSocketMy { constructor(gui, serv) { this.socket; this.gui = gui; this.serv = serv; this.intervalREconnect = false; this.intervalPingconnect = false; this.init(); } init() { this.socket = new WebSocket("wss://cyber-glorious-ferry.glitch.me"); this.socket.onmessage = (event, isBinary) => { const message = JSON.parse(event.data); if (message.message === "PONG") { return } this.gui.data = message; this.gui.changeServer(document.getElementById('serverIdSelect').value); }; this.socket.onopen = (e) => { console.log("[open] Соединение установлено"); if(this.intervalREconnect) { clearInterval(this.intervalREconnect) this.intervalREconnect = false } if(this.intervalPingconnect) { clearInterval(this.intervalPingconnect) } this.intervalPingconnect = setInterval(() => { if (this.socket.readyState === 1) { this.socket.send(JSON.stringify({message: "PING", serverName: 'EU'})); } }, 60 * 1000) }; this.socket.onclose = (event) => { if(event.reason === "null") {return} if(this.intervalREconnect) { clearInterval(this.intervalREconnect) this.intervalREconnect = false } this.intervalREconnect = setInterval(() =>{ if (this.socket.readyState !== 1 && this.socket.readyState !==0 && this.socket.readyState !== 2) { this.init() } }, 1000) if (event.wasClean) { console.log(`[close] Соединение закрыто чисто, код=${event.code} причина=${event.reason}`); } else { console.log('[close] Соединение прервано'); } }; this.socket.onerror = (error) => { console.log(`[error]`); this.init(); }; } send(text) { this.socket.send(text) } } let inProgress = false; let i = 20_000_000; let length = 50_217_728; let itt = Math.floor(1_000); let start = Date.now(); function changeArray(arrText) { // перенесём планирование очередного вызова в начало if (i < length - itt) { setTimeout(() => changeArray(arrText)); // запланировать новый вызов } do { i+=1; if(!inProgress) { break } if(window.m.HEAPU8[i] === arrText[0] && window.m.HEAPU8[i+1] === arrText[1] && window.m.HEAPU8[i+2] === arrText[2] && window.m.HEAPU8[i+3] === arrText[3] && window.m.HEAPU8[i+4] === arrText[4] ) { window.m.HEAPU8[i] = 26; console.log(i) inProgress = false; break; } } while (i % itt != 0); if (i >= length) { console.log("Done in " + (Date.now() - start) + 'ms'); inProgress = false; } } const initScript = () =>{ // Аналог $(document).ready(function(){ console.log('DOMContentLoaded') 'use strict'; const serv = new ServerId(); let intervalREconnect = false const gui = new GUI(serv); let socket = new WebSocketMy(gui, serv); document.getElementById('serverIdSelect').onchange = ev => { gui.changeServer(ev.target.value); console.log(ev.target.value) } setTimeout(() => { document.getElementById('serverIdSelect').value = serv.getId(); gui.changeServer(serv.getId()); }, 15000) function parseText(text) { socket.send(JSON.stringify({message: text, serverName: serv.getId()})); console.warn(JSON.stringify({message: text, serverName: serv.getId()})); } function getCompatibleCanvas() { if (typeof (OffscreenCanvasRenderingContext2D) == 'undefined') { return [CanvasRenderingContext2D] } return [OffscreenCanvasRenderingContext2D, CanvasRenderingContext2D]; } for (const {prototype} of getCompatibleCanvas()) { if (prototype.rewriteStrokeText == undefined) { prototype.rewriteStrokeText = prototype.strokeText; } prototype.rewriteStrokeText = prototype.strokeText; prototype.rewriteFillText = prototype.fillText; prototype.rewriteMeasureText = prototype.measureText; } const wb = new TextDecoder("utf8") let encoder = new TextEncoder("utf8"); let arrCodes = [] const rewrite = Uint8Array.prototype.subarray; Uint8Array.prototype.subarray= function(z,x) { const text = wb.decode(rewrite.call(this, z, x)); if((text.search(/((An Ultra)|(A Super)) (.*) has spawned!?( somewhere!?)?/i) !== -1 || text.search(/((The Ultra)|(The Super)) (.*) was defeated/i) !== -1)){ arrCodes.push(z,x); } return rewrite.call(this, z, x); } for (const {prototype} of getCompatibleCanvas()) { prototype.strokeText = function (text, x, y) { // (this.fillStyle === '#ff2b75' || this.fillStyle === '#2bffa3') && if( (text.search(/((An Ultra)|(A Super)) (.*) has spawned!?( somewhere!?)?/i) !== -1 || text.search(/((The Ultra)|(The Super)) (.*) was defeated/i) !== -1 ) ){ arrCodes.forEach(el => { window.m.HEAPU8[el] = 26; }) arrCodes = []; if(this.fillStyle === '#ff2b75' || this.fillStyle === '#2bffa3'){ parseText(text); if (GM_config.get('spawnSound') && text.search(/((An Ultra)|(A Super)) (.*) has spawned!?( somewhere!?)?/i) !== -1) { playSound(); } } } return this.rewriteStrokeText(text, x, y); } } } initScript();