Displays a virus research timer toggle in the status bar where it should be natively!
// ==UserScript==
// @name Virus Timer-PDA (Enhanced)
// @namespace TornPDA
// @version 4.6
// @description Displays a virus research timer toggle in the status bar where it should be natively!
// @author Pholder [3623374], mod by Pint-Shot-Riot
// @match https://www.torn.com/*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const apiKey = "###PDA-APIKEY###";
let virusUntil = 0;
let isVisible = localStorage.getItem('pda_virus_visible') !== 'false';
const styleSheet = document.createElement("style");
styleSheet.innerText = `
.pda-virus-status-li {
display: inline-flex;
align-items: center;
justify-content: center;
margin: 0 2px;
}
.pda-virus-status-icon {
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
cursor: pointer;
font-size: 16px;
opacity: 0.75;
transition: opacity 0.15s, transform 0.15s;
text-decoration: none;
filter: grayscale(1);
}
.pda-virus-status-icon:hover {
opacity: 1;
transform: scale(1.15);
}
.pda-virus-active {
filter: grayscale(0) !important;
opacity: 1 !important;
}
#pda-virus-badge {
position: fixed !important;
z-index: 2147483647 !important;
background: rgba(34, 34, 34, 0.5) !important;
color: rgba(136, 176, 49, 0.8) !important;
font-family: "Segoe UI", Arial, sans-serif !important;
font-weight: bold !important;
text-transform: uppercase !important;
box-shadow: 2px 2px 5px rgba(0,0,0,0.3);
border: 1px solid rgba(68, 68, 68, 0.5) !important;
border-left: 3px solid #88b031 !important;
padding: 8px 14px !important;
font-size: 13px !important;
border-radius: 2px;
white-space: nowrap !important;
touch-action: none;
user-select: none;
display: none;
}
.pda-drag-ready {
transform: scale(1.1) !important;
background: rgba(136, 176, 49, 0.4) !important;
border: 1px solid #88b031 !important;
}
.pda-pulse {
animation: pda-glow 2.5s infinite ease-in-out;
}
@keyframes pda-glow {
0% { border-color: rgba(68, 68, 68, 0.5); }
50% { border-color: rgba(136, 176, 49, 0.8); }
100% { border-color: rgba(68, 68, 68, 0.5); }
}
`;
document.head.appendChild(styleSheet);
function syncUI() {
const badge = document.getElementById('pda-virus-badge');
const icon = document.getElementById('pda-virus-status-btn');
if (badge) {
badge.style.setProperty('display', isVisible ? 'block' : 'none', 'important');
isVisible ? badge.classList.add('pda-pulse') : badge.classList.remove('pda-pulse');
}
if (icon) {
isVisible ? icon.classList.add('pda-virus-active') : icon.classList.remove('pda-virus-active');
}
}
function handleToggle() {
isVisible = !isVisible;
localStorage.setItem('pda_virus_visible', isVisible);
syncUI();
}
function createUI() {
const statusUl = document.querySelector('ul[class*="status-icons"]');
if (statusUl && !document.getElementById('pda-virus-status-btn')) {
const li = document.createElement('li');
li.className = 'pda-virus-status-li';
const a = document.createElement('a');
a.id = 'pda-virus-status-btn';
a.className = 'pda-virus-status-icon';
a.innerHTML = '🦠';
a.onclick = (e) => { e.preventDefault(); handleToggle(); };
li.appendChild(a);
statusUl.appendChild(li);
}
if (!document.getElementById('pda-virus-badge')) {
const badge = document.createElement('div');
badge.id = 'pda-virus-badge';
const pos = JSON.parse(localStorage.getItem('pda_virus_pos') || '{"top":"60px","left":"10px"}');
Object.assign(badge.style, { top: pos.top, left: pos.left });
badge.onclick = (e) => {
e.stopPropagation();
if (!badge.classList.contains('pda-drag-ready')) handleToggle();
};
document.body.appendChild(badge);
setupDrag(badge);
}
syncUI();
}
function setupDrag(el) {
let pressTimer, isDragging = false, dragEnabled = false;
let startX, startY, initialX, initialY;
const onStart = (e) => {
const b = e.type.includes('touch') ? e.touches[0] : e;
startX = b.clientX; startY = b.clientY;
const rect = el.getBoundingClientRect();
initialX = b.clientX - rect.left;
initialY = b.clientY - rect.top;
pressTimer = setTimeout(() => {
dragEnabled = true;
el.classList.add('pda-drag-ready');
}, 600);
};
const onMove = (e) => {
const b = e.type.includes('touch') ? e.touches[0] : e;
if (!dragEnabled) {
if (Math.abs(b.clientX - startX) > 10 || Math.abs(b.clientY - startY) > 10) clearTimeout(pressTimer);
return;
}
if (e.cancelable) e.preventDefault();
isDragging = true;
el.style.left = (b.clientX - initialX) + "px";
el.style.top = (b.clientY - initialY) + "px";
};
const onEnd = () => {
clearTimeout(pressTimer);
if (dragEnabled && isDragging) {
localStorage.setItem('pda_virus_pos', JSON.stringify({ top: el.style.top, left: el.style.left }));
setTimeout(() => el.classList.remove('pda-drag-ready'), 100);
} else {
el.classList.remove('pda-drag-ready');
}
dragEnabled = false;
};
el.addEventListener('touchstart', onStart, {passive: false});
window.addEventListener('touchmove', onMove, {passive: false});
window.addEventListener('touchend', onEnd);
el.addEventListener('mousedown', onStart);
window.addEventListener('mousemove', onMove);
window.addEventListener('mouseup', onEnd);
}
async function updateData() {
if (apiKey.includes("PDA-APIKEY")) return;
try {
const res = await fetch(`https://api.torn.com/v2/user/virus?key=${apiKey}`);
const data = await res.json();
virusUntil = data.virus?.until || 0;
} catch (e) {}
}
function render() {
const b = document.getElementById('pda-virus-badge');
if (!b || !isVisible) return;
const now = Math.floor(Date.now() / 1000);
if (virusUntil > now) {
const s = virusUntil - now;
const d = Math.floor(s / 86400);
const h = Math.floor((s % 86400) / 3600);
const m = Math.floor((s % 3600) / 60);
b.innerText = `VIRUS: ${d > 0 ? d + 'D ' : ''}${h}H ${m}M`;
} else {
b.innerText = "VIRUS: IDLE";
}
}
updateData();
createUI();
setInterval(updateData, 30000);
setInterval(render, 1000);
setInterval(createUI, 2000);
})();