Display hospital timer on the attack page
// ==UserScript==
// @name torn-attack-hospital-timer
// @namespace typhon.torn.attack-hospital
// @version 1.4.3
// @description Display hospital timer on the attack page
// @author rantMore [3265877]
// @license GNU GPLv3
// @run-at document-end
// @license MIT
// @grant GM_log
// @match https://www.torn.com/loader.php?sid=attack*
// ==/UserScript==
const apiKey = "YOUR_API_HERE";
const preFire = 750; // Milliseconds desired for automatic reload
const disableAutomaticReload = false; // Set to true to disable the automatic reload
function generateInformation(outTime, hospital_timestamp) {
// Show green under 1 minute
const seconds = Math.floor((outTime - Date.now()) / 1000);
return `
<div> </div>
<div>Coming out at ${outTime.toLocaleTimeString('en-US')}</div>
<div>In <span class="bold ${seconds <= 60 ? 'title___fOh2J' : 'title___fOh2J'}" style="${seconds < 60 ? 'color: #98FB98' : ''}">${getTimeLeft(hospital_timestamp)}</span></div>` +
(!disableAutomaticReload ? `<div>Reloading ${(preFire/1000).toFixed(1)}s before the end</div>`: '');
}
function getTimeLeft(hospital_timestamp) {
let outTime = new Date(0);
outTime.setUTCSeconds(hospital_timestamp);
const seconds = Math.floor((outTime - Date.now()) / 1000);
if (seconds >= 60) {
const secondsFormated = Math.floor(seconds % 60).toString().padStart(2, '0');
return seconds < 3600 ? `${Math.floor(seconds/60)}:${secondsFormated}` : `${Math.floor(seconds / 3600)}h${Math.floor((seconds % 3600) / 60).toString().padStart(2, '0')}`;
} else {
return `${seconds}s`;
}
}
(function hospital_time() {
'use strict';
const initialTitle = document.title;
const userid = location.href.replace(/.*?user2ID=(\d+)/i, "$1");
fetch(`https://api.torn.com/user/${userid}?selections=profile&key=${apiKey}&comment=attack_stats`).then( async response => {
let user = (await response.json())||{};
if (user.status.state.toLowerCase() === 'hospital') {
let alertWrapper = document.createElement("div")
alertWrapper.setAttribute("class", "userName___loAWK bold");
let outTime = new Date(0); // The 0 there is the key, which sets the date to the epoch
outTime.setUTCSeconds(user.states.hospital_timestamp);
// Don't do anything if we are right on the ending of the hospital timer
let msToWait = outTime - Date.now();
if (msToWait > preFire) {
// Prepare div content
alertWrapper.innerHTML = generateInformation(outTime, user.states.hospital_timestamp);
document.title = `${getTimeLeft(user.states.hospital_timestamp)} | ${user.name}`;
// Sometimes the element is not yet present, let's wait for it
let outerBox = document.querySelector('.dialogButtons___nX4Bz');
let timerPtr;
let tempBox;
let tempDiv;
new Promise( (resolve, reject) => {
if (!outerBox) {
// Lets grab the top div to add the time info insde. If it fails, then too bad for the tentative
tempBox = document.querySelector('.colored___sN72G');
if (tempBox) {
tempDiv = tempBox.appendChild(alertWrapper);
}
let waitPtr = setInterval( () => {
document.title = `${getTimeLeft(user.states.hospital_timestamp)} | ${user.name}`;
outerBox = document.querySelector('.dialogButtons___nX4Bz');
if (outerBox) {
resolve(true)
clearInterval(waitPtr);
}
}, 250)
} else {
resolve(true)
}
}).then( () => {
// Good to go!
if (tempDiv) {
// lets get rid of this extra div
tempDiv.remove()
}
outerBox.appendChild(alertWrapper);
// Redraw content every second
timerPtr = setInterval( () => {
alertWrapper.innerHTML = generateInformation(outTime, user.states.hospital_timestamp);
document.title = `${getTimeLeft(user.states.hospital_timestamp)} | ${user.name}`;
}, 1000)
})
// Set a new timer to trigger when we are done waiting
setTimeout( () => {
// Stop everything, we are done.
document.title = initialTitle;
clearInterval(timerPtr);
// Make sure not to reload if unwanted
if (disableAutomaticReload === false) {
location.reload();
}
}, msToWait - preFire);
}
}
});
})();