// ==UserScript== // @name Torn - Arrival Time Predictor // @namespace http://tampermonkey.net/ // @version 1.0 // @description Calculates and displays the exact local time you will land while traveling // @author You // @match https://www.torn.com/page.php?sid=travel // @grant GM_addStyle // ==/UserScript== (function() { 'use strict'; // Setup CSS rule for the pulsing text. GM_addStyle(` @keyframes colorPulse { 0% { color: #ff3333; } /* Start Red */ 50% { color: #ffffff; } /* Midpoint Orange */ 100% { color: #ff3333; } /* End Red */ } .pulse-text { animation: colorPulse 1s infinite ease-in-out; } `); //const flight_image = document.querySelector("#travel-root > div.viewport___cdEK9 > div.airspaceScene___euCKY.outboundFlight___rIvIA"); //flight_image.remove(); // 1. Wait for Torn's travel container to load const checkFlight = setInterval(() => { // Torn uses countdown timers inside specific structural classes depending on the layout type const timerElement = document.querySelector("#travel-root > div.viewport___cdEK9 > div.flightProgressSection___OEJoR > div.progressText___BEQ0k > span > span:nth-child(2) > time"); if (timerElement) { clearInterval(checkFlight); initClockExtension(timerElement); } }, 500); function initClockExtension(timerElement) { // Create a custom UI box to display our text safely without breaking Torn's CSS const travelRoot = document.querySelector("#travel-root"); // Remove travel fact travelRoot.querySelector('[class^="factWrapper"]').remove(); // Remove flight scene travelRoot.querySelector('[class^="airspaceScene"]').remove(); const ogTimer = document.querySelector("#travel-root > div.viewport___cdEK9 > div.flightProgressSection___OEJoR > div.progressText___BEQ0k > div > span"); if (ogTimer) { ogTimer.style.cssText = 'font-weight: bold; font-size: 1.5rem;'; ogTimer.innerText = 'Calculating landing time...'; } else { const timeDisplay = document.createElement('div'); timeDisplay.style.cssText = 'padding: 10px; margin-top: 10px; color: #fff; text-align: center; border-radius: 5px; font-weight: bold; border: 1px solid #444; transition: color 0.5s ease;'; timerElement.parentNode.insertBefore(timeDisplay, timerElement.nextSibling); } //const info = document.querySelector("#travel-root > div.viewport___cdEK9.stage0 > div.factWrapper___LvERA > div"); //info.remove(); // Insert our box right below Torn's native countdown timer // // Update the landing time prediction every single second setInterval(() => { const timeString = timerElement.innerText; // Grabs 'HH:MM:SS' from the page if (!timeString) return; const timeParts = timeString.split(':'); if (timeParts.length === 3) { const hours = parseInt(timeParts[0], 10); const minutes = parseInt(timeParts[1], 10); const seconds = parseInt(timeParts[2], 10); // Convert countdown duration entirely to total milliseconds const msRemaining = ((hours * 60 * 60) + (minutes * 60) + seconds) * 1000; // Blink the text if time left is < 2 minutes. if (msRemaining <= 120000) { //ogTimer.style.cssText += ' color: #aa0000;' // Add the blinking class to the text. ogTimer.classList.add('pulse-text'); } // Add the flight duration to the current system date/time const landingTime = new Date(Date.now() + msRemaining); // Remove OG timer //ogTimer.remove(); // Format the output neatly (e.g., "16:24:05") ogTimer.innerText = `Estimated Landing: ${landingTime.toLocaleTimeString()}`; } }, 1000); } })();