Dead Frontier Tooltip DPS Injector

Injects DPS into #infoBox on hover for exact weapon name matches, on specific pages, caching data in localStorage for 24 hours.

2025-05-06 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

// ==UserScript==
// @name         Dead Frontier Tooltip DPS Injector
// @author       ils94
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Injects DPS into #infoBox on hover for exact weapon name matches, on specific pages, caching data in localStorage for 24 hours.
// @match        https://fairview.deadfrontier.com/onlinezombiemmo/index.php?page=35
// @match        https://fairview.deadfrontier.com/onlinezombiemmo/index.php?page=50
// @match        https://fairview.deadfrontier.com/onlinezombiemmo/index.php?page=24
// @match        https://fairview.deadfrontier.com/onlinezombiemmo/index.php?page=59
// @match        https://fairview.deadfrontier.com/onlinezombiemmo/index.php?page=84
// @match        https://fairview.deadfrontier.com/onlinezombiemmo/index.php?page=25
// @license      MIT
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    let dpsData = {};

    // Load DPS data, either from localStorage or by fetching
    function loadDPS() {
        const cacheKey = 'deadFrontierDPSData';
        const timestampKey = 'deadFrontierDPSTimestamp';
        const cacheDuration = 24 * 60 * 60 * 1000; // 24 hours in milliseconds

        // Check localStorage for cached data and timestamp
        const cachedData = localStorage.getItem(cacheKey);
        const cachedTimestamp = localStorage.getItem(timestampKey);

        if (cachedData && cachedTimestamp) {
            const timeElapsed = Date.now() - parseInt(cachedTimestamp, 10);
            if (timeElapsed < cacheDuration) {
                // Use cached data if less than 24 hours old
                dpsData = JSON.parse(cachedData);
                console.log('[DPS] Loaded', Object.keys(dpsData).length, 'entries from localStorage');
                startWatcher();
                return;
            }
        }

        // Fetch new data if no cache or cache is stale
        fetch('https://fairview.deadfrontier.com/onlinezombiemmo/dfdata/damagepersec.php')
            .then(r => r.text())
            .then(text => {
                const regex = /(.+?)\s*:\s*<b>([\d.]+)<\/b>\s*\(<b>([\d.]+)<\/b>\)<br \/>/g;
                let m;
                while ((m = regex.exec(text)) !== null) {
                    const name = m[1].trim();
                    dpsData[name.toLowerCase()] = {
                        name,
                        base: m[2],
                        mod: m[3]
                    };
                }
                // Save to localStorage
                localStorage.setItem(cacheKey, JSON.stringify(dpsData));
                localStorage.setItem(timestampKey, Date.now().toString());
                console.log('[DPS] Loaded', Object.keys(dpsData).length, 'entries from server and saved to localStorage');
                startWatcher();
            })
            .catch(err => {
                console.error('[DPS] Failed to load DPS list:', err);
                // Fallback to cached data if available, even if stale
                if (cachedData) {
                    dpsData = JSON.parse(cachedData);
                    console.log('[DPS] Loaded', Object.keys(dpsData).length, 'entries from localStorage (fallback)');
                    startWatcher();
                }
            });
    }

    // 2) Every 1000ms, check for a visible tooltip and inject DPS for exact matches
    function startWatcher() {
        setInterval(() => {
            const box = document.getElementById('infoBox');
            if (!box || box.style.visibility === 'hidden') return;

            const nameEl = box.querySelector('.itemName');
            if (!nameEl) return;

            const weapon = nameEl.textContent.trim();
            const key = weapon.toLowerCase();

            // Check for exact match only
            const entry = dpsData[key];
            if (!entry) {
                // Remove any existing DPS if no exact match
                const old = box.querySelector('.dpsInjected');
                if (old) old.remove();
                console.log(`[DPS] ✗ ${weapon} (no exact match)`);
                return;
            }

            // Remove old DPS
            const old = box.querySelector('.dpsInjected');
            if (old) old.remove();

            // Inject new DPS
            const line = document.createElement('div');
            line.className = 'itemData dpsInjected';
            line.style.color = '#00FF00';
            line.textContent = `DPS: ${entry.base} (Theorical: ${entry.mod})`;
            box.appendChild(line);

            console.log(`[DPS] ✔ ${weapon}`);
        }, 1000);
    }

    loadDPS();
})();