// ==UserScript== // @name florr.io | Playtime counter // @namespace https://github.com/Samer-Kizi // @version 1.1.3 // @description Shows how no life you are // @author Furaken // @match https://florr.io/* // @grant unsafeWindow // @require https://cdn.jsdelivr.net/npm/chart.js@4.2.1/dist/chart.umd.min.js // @downloadURL none // ==/UserScript== var today = new Date().toString().substring(0,15) var leech = [{"date":today,"value":0,map:[0,0,0,0,0,0,0,0,0,0,0,0,0,0]}], cvs = document.querySelector('canvas') var newDoc = document.createElement('div') newDoc.style = ` right: 6px; bottom: -3px; color: white; text-shadow: rgb(0, 0, 0) 2px 0px 0px, rgb(0, 0, 0) 1.75517px 0.958851px 0px, rgb(0, 0, 0) 1.0806px 1.68294px 0px, rgb(0, 0, 0) 0.141474px 1.99499px 0px, rgb(0, 0, 0) -0.832294px 1.81859px 0px, rgb(0, 0, 0) -1.60229px 1.19694px 0px, rgb(0, 0, 0) -1.97998px 0.28224px 0px, rgb(0, 0, 0) -1.87291px -0.701566px 0px, rgb(0, 0, 0) -1.30729px -1.5136px 0px, rgb(0, 0, 0) -0.421592px -1.95506px 0px, rgb(0, 0, 0) 0.567324px -1.91785px 0px, rgb(0, 0, 0) 1.41734px -1.41108px 0px, rgb(0, 0, 0) 1.92034px -0.558831px 0px; position: absolute; z-index: 1; font-family: Ubuntu; line-height: 0px; text-align: right; pointer-events: none; ` document.querySelector('body').appendChild(newDoc) if (localStorage.getItem("florrTime") === null) localStorage.setItem('florrTime', JSON.stringify(leech)) if (JSON.parse(localStorage.getItem("florrTime"))[0].date != today) { let x = JSON.parse(localStorage.getItem('florrTime')) x.unshift({"date":today,"value":0,map:[0,0,0,0,0,0,0,0,0,0,0,0,0,0]}) localStorage.setItem('florrTime', JSON.stringify(x)); } if (JSON.parse(localStorage.getItem("florrTime"))[0].map == undefined) { let x = JSON.parse(localStorage.getItem('florrTime')) x[0].map = [0,0,0,0,0,0,0,0,0,0,0,0,0,0] localStorage.setItem('florrTime', JSON.stringify(x)); } var url const nativeWebSocket = unsafeWindow.WebSocket; unsafeWindow.WebSocket = function(...args){ const socket = new nativeWebSocket(...args); url = socket.url return socket; }; var start = Date.now() - Number(JSON.parse(localStorage.getItem("florrTime"))[0].value) * 1000, time, allTime = 0, allTimeA, stop = false, servers = [], indexV, start2, urlA = [], delta2 function Time(seconds) { var hoursLeft = Math.floor(seconds / 3600); var min = Math.floor((seconds - hoursLeft * 3600) / 60); var secondsLeft = seconds - hoursLeft * 3600 - min * 60; secondsLeft = Math.round(secondsLeft * 100) / 100; var answer = hoursLeft< 10 ? "0" + hoursLeft : hoursLeft; answer += ":" + (min < 10 ? "0" + min : min); answer += ":" + (secondsLeft< 10 ? "0" + secondsLeft : secondsLeft); return answer } for (let i = 0; i <= 13; i++) { fetch("https://api.n.m28.io/endpoint/florrio-map-" + i + "-green/findEach/").then((response) => response.json()).then((data) => { servers[i] = `${data.servers["vultr-miami"].id} ${data.servers["vultr-frankfurt"].id} ${data.servers["vultr-tokyo"].id}` }) } setInterval(function() { if (stop) { start = Date.now() stop = false } else { var delta = Date.now() - start, start2 = JSON.parse(localStorage.getItem('florrTime'))[0].value let x = JSON.parse(localStorage.getItem('florrTime')) x[0].value = Math.floor(delta / 1000) time = Time(Math.floor(Number(x[0].value))) x.forEach(k => {allTime += Number(k.value)}) allTimeA = Time(Math.floor(Number(allTime))) localStorage.setItem('florrTime', JSON.stringify(x)); newDoc.innerHTML = `

Since ${JSON.parse(localStorage.getItem('florrTime')).at(-1).date}: ${allTimeA}

${time}

` allTime = 0 delta2 = JSON.parse(localStorage.getItem('florrTime'))[0].value - start2 var xyz = JSON.parse(localStorage.getItem("florrTime")) xyz[0].map[indexV] += delta2 localStorage.setItem('florrTime', JSON.stringify(xyz)); urlA.unshift(url) if (urlA.length > 2) urlA.splice(2) if (urlA.at(-1) != urlA[0]) { start2 = JSON.parse(localStorage.getItem('florrTime'))[0].value servers.forEach(function callback(x, index) { if (x.includes(url.slice(6, 9))) indexV = index }); } } }, 1000) var chartCon = document.createElement('div') chartCon.style = ` width: 100%; height: 100%; position: absolute; z-index: 100; font-family: Ubuntu; top: 0; margin: 0; opacity: 0; pointer-events: none; transition: 0.4s ease-in-out; ` chartCon.innerHTML = ` ` document.querySelector('body').appendChild(chartCon) Chart.defaults.font.family = 'Ubuntu'; Chart.defaults.font.size = 16; var chart = new Chart(document.getElementById('chartCtx'), { type: 'line', data: { labels: null, datasets: null }, options: { responsive: true, maintainAspectRatio: false, plugins: { title: { text: 'Playtime (Month)', display: true } }, scales: { x: { title: { display: true, text: 'Date' } }, y: { title: { display: true, text: 'Hours' } } }, }, }); var chart2 = new Chart(document.getElementById('chartCtx2'), { type: 'doughnut', data: { labels: null, datasets: null }, options: { responsive: true, maintainAspectRatio: false, plugins: { title: { text: 'Playtime (Hours)', display: true } }, }, }); function updateData() { var data = [], labels = [], labels2 = [], mapData = [], allMap = [[],[],[],[],[],[],[],[],[],[],[],[],[],[]], localStr = JSON.parse(localStorage.getItem("florrTime")), len = 30, pieMapData = [0,0,0,0,0,0,0,0,0,0,0,0,0,0], colorRandomPie = [] function be(date) { return date.slice(8, 10) + "/" + (new Date(Date.parse(date.slice(4, 7) + " 1, 2012")).getMonth() + 1) + "/" + date.slice(-4) } for (let i = 0; i <= 13; i++) { labels2.push('MAP'+i) } if (localStr.length < 30) len = localStr.length for (let i = 0; i < len; i++) { data.unshift(localStr[i].value / 3600) labels.unshift(be(localStr[i].date)) mapData.unshift(localStr[i].map) } mapData.forEach(x => { for (let i = 0; i <= 13; i++) { if (x == undefined) x = [0,0,0,0,0,0,0,0,0,0,0,0,0,0] allMap[i].push(x[i] / 3600) pieMapData[i] += (x[i] / 3600) } }) var colorPalette = [ "#067A69", "#09BB9F", "#39F3BB", "#18A1CD", "#1D81A2", "#15607A", "#003f5c", "#2f4b7c", "#665191", "#a05195", "#d45087", "#f95d6a", "#ff7c43", "#ffa600" ] var chartObj = [{ label: 'All', data: data, fill: true, borderColor: 1, borderWidth: 4, tension: 0.3 }], color for (let i = 0; i <= 13; i++) { chartObj.push({ "label": "MAP" + i, "data": allMap[i], "fill": true, "backgroundColor": colorPalette[i] + "1A", "borderColor": colorPalette[i], "borderWidth": 2.5, "tension": 0.3 }) localStr[0].map[i] = localStr[0].map[i] / 3600 } chart.data.datasets = chartObj chart.data.labels = labels chart.update() chart2.data.labels = labels2 chart2.data.datasets = [ { label: 'Latest 30 Days', data: pieMapData, backgroundColor: colorPalette, hoverOffset: 10 }, { label: 'Today', data: localStr[0].map, backgroundColor: colorPalette, hoverOffset: 10 } ] chart2.update() } document.documentElement.addEventListener("keydown", function() { if (event.keyCode === 191 && event.ctrlKey && event.shiftKey) { if (confirm("Confirm reset all")) { stop = true; localStorage.setItem('florrTime', JSON.stringify(leech)) } } else if (event.keyCode === 186) newDoc.style.display = newDoc.style.display === 'none' ? '' : 'none' else if (event.keyCode === 220) { if (chartCon.style.opacity == '0') { chartCon.style.opacity = '1' chartCon.style.pointerEvents = 'all' updateData() } else { chartCon.style.opacity = '0' chartCon.style.pointerEvents = 'none' } } else if (event.keyCode === 221) { var x = document.getElementById('chartCtx') x.style.zIndex = x.style.zIndex === '1' ? '-1' : '1' } });