// ==UserScript== // @name TETRIO-RPC // @version 1.0 // @author PATXS // @description Discord RPC for TETR.IO, in the browser // // @grant GM_notification // // @updateURL https://raw.githubusercontent.com/PATXS/TETRIO-browser-rpc/main/TETRIO-RPC.js // @downloadURL https://raw.githubusercontent.com/PATXS/TETRIO-browser-rpc/main/TETRIO-RPC.js // @include https://tetr.io/* // @exclude https://tetr.io/res/* // ==/UserScript== var startTs = 0; var prev_menu = ""; var closed = false; var idling_started = false; var idleStart = 0; var Socket; (function() { "use strict"; var detail = ""; var currMenu = ""; var gamestate = ""; var checkMenu = setInterval(() => { if(!document.body.classList.contains("ingame")){ prev_menu = currMenu; updateTimestamp(); } currMenu = document.querySelector("#menus").getAttribute("data-menu-type"); if(currMenu != "none"){ detail = "In Menus"; if(currMenu == "tetra" || currMenu == "tetra_records" || currMenu == "tetra_players" || currMenu == "tetra_me"){ detail = "Tetra Channel"; } if(document.querySelector("#header_text").innerText == "RESULTS"){ gamestate = "Results Screen"; } if(currMenu == "lobby"){ gamestate = "In Lobby"; if(document.querySelector("#roomview").className.includes("sysroom")){ detail = "QUICK PLAY"; } else{ detail = "CUSTOM ROOM"; } } if(currMenu == "victory"){ gamestate = "Game Ending"; } } if((currMenu == "none" || currMenu == "lobby") && document.body.classList.contains("ingame")){ if(detail == "TETRA LEAGUE"){ if(document.querySelector("#mm_status_header").innerText == "MATCH FOUND"){ gamestate = "In Game"; } } else if(prev_menu == "40l"){ detail = "40 LINES"; gamestate = null; } else if(prev_menu == "blitz"){ detail = "BLITZ"; gamestate = null; } else if(prev_menu == "zen"){ detail = "ZEN"; gamestate = null; } else if(prev_menu == "custom"){ detail = "CUSTOM GAME"; gamestate = null; } else if(prev_menu == "lobby"){ gamestate = "In Game"; } } if(!document.querySelector("#replay").className.includes("hidden")){ detail = document.querySelector("#data_replay > span:nth-child(2)").innerText; gamestate = "Watching Replay"; } if(!document.querySelector("#spectate").className.includes("hidden")){ gamestate = "Spectating"; } if((detail == "QUICK PLAY" || detail == "CUSTOM ROOM") && document.querySelector("#mm_status_header").innerText == "ZEN WHILE WAITING" && !(document.querySelector("#mm_status.room") == null)){ gamestate = "In Lobby (ZEN)" } if(document.querySelector("#mm_status_header").innerText == "FINDING MATCH" && document.querySelector("#mm_status").className.includes("shown")){ detail = "TETRA LEAGUE"; gamestate = "In Queue"; } }, 1000); Socket = new WebSocket("ws://127.0.0.1:6680"); var Execution = setInterval(() => { if(!closed){ Socket.send(JSON.stringify(establishRPC( Date.now(), detail, gamestate, (document.querySelector("body").className.includes("anon")), document.querySelector("#me_username").innerText, document.querySelector("#me_level").innerText, ((document.querySelector("#me_leaguerank").src).replace("https://tetr.io/res/league-ranks/", "")).replace(".png", "").toUpperCase() )));} else{ if(!document.body.classList.contains("nofocus")){ idling_started = false; idleStart = 0; closed = false; Socket = new WebSocket("ws://127.0.0.1:6680"); } } }, 3000); Socket.onerror = function (Error) { console.error ("# [TETRIO-RPC] Error: " + Error); }; Socket.onclose = function (Error) { console.error ("# [TETRIO-RPC] Error: " + Error); if (Error.code != "1000") { console.log("It seems the DPS is not running on port 6680."); } }; Socket.onopen = function () { console.log("TETRIO-RPC connected"); }; var unnecessary_credit = setTimeout(() => { document.getElementById("version_line").innerText += "\nTETRIO-RPC v1.0 by PATXS" }, 10000); })(); function establishRPC(timestamp, detail, gamestate, anon, username, lvl, rank) { var time; var sik; var lit; if(anon){ lit = "Playing anonymously" } else{ lit = username + " - Lv. " +lvl +" - " +rank } if(detail == "40 LINES"){ sik = "mode_40l"; } if(detail == "BLITZ"){ sik = "mode_blitz"; } if(detail == "ZEN"){ sik = "mode_zen"; } if(detail == "CUSTOM GAME"){ sik = "mode_custom"; } if(detail == "CUSTOM ROOM"){ sik = "mode_custom"; } if(detail == "QUICK PLAY"){ sik = "mode_quickplay"; } if(detail == "TETRA LEAGUE"){ sik = "mode_league"; } if(detail == "In Menus" || detail == "Tetra Channel"){ gamestate = null; time = null; } else{ time = startTs; } if(gamestate == "In Lobby" || gamestate == "In Queue" || gamestate == "Results Screen" || gamestate == "Game Ending"){ time = null; } if(!document.querySelector("#preload").className.includes("hidden")){ lit = "Logging in..."; detail = "Logging in..."; time = null; } if(document.body.classList.contains("nofocus")){ idling(); detail = "Idle"; gamestate = null; time = null; } else{ idling_started = false; } return { cid: "688741895307788290", rpc: { state: gamestate, details: detail, //partySize: 1, //partyMax: 1, largeImageKey: "logo", largeImageText: lit, smallImageKey: sik, smallImageText: detail, startTimestamp: time } }; }; function updateTimestamp(){ startTs = Date.now(); } function idling(){ //after a 5 minute idle time, kill the RPC until the user comes back if(!idling_started){ idling_started = true; idleStart = Date.now(); } else{ if(idleStart+300000 <= Date.now()){ Socket.close(); closed = true; } } }