Performance HUD - Valhalla

Interactive cyber HUD: FPS, CPS/KPS, ping, latency, human check, keyboard heatmap, session stats, graphs

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name         Performance HUD - Valhalla
// @namespace    http://tampermonkey.net/
// @version      4.0
// @description  Interactive cyber HUD: FPS, CPS/KPS, ping, latency, human check, keyboard heatmap, session stats, graphs
// @match        *://*/*
// @grant        none
// @run-at       document-end
// @license      All rights reserved. Copyright © 2026 Valhalla_Vikings
// You may not copy, distribute, or modify this script without permission.
// ==/UserScript==

(function () {
    'use strict';

    // =========================
    // STATE
    // =========================
    let fps = 0, frames = [], fpsHistory = [];
    let clickTimes = [], cps = 0, cpsHistory = [];
    let keyTimes = [], kps = 0;
    let clickIntervals = [];
    let totalClicks = 0, peakCPS = 0;

    let latency = 0;
    let clickLatency = 0;

    const MAX_FPS = 240;

    const keyHeat = {};

    // =========================
    // FPS TRACKER
    // =========================
    function frameLoop(now) {
        frames.push(now);
        if (frames.length > 30) frames.shift();

        if (frames.length > 1) {
            const duration = frames.at(-1) - frames[0];
            fps = Math.round((frames.length - 1) * 1000 / duration);
        }

        fpsHistory.push(fps);
        if (fpsHistory.length > 60) fpsHistory.shift();

        requestAnimationFrame(frameLoop);
    }
    requestAnimationFrame(frameLoop);

    // =========================
    // INPUT TRACKING
    // =========================
    document.addEventListener("pointerdown", () => {
        const now = performance.now();

        clickTimes.push(now);
        clickTimes = clickTimes.filter(t => now - t < 1000);
        cps = clickTimes.length;

        cpsHistory.push(cps);
        if (cpsHistory.length > 60) cpsHistory.shift();

        totalClicks++;
        if (cps > peakCPS) peakCPS = cps;

        if (clickTimes.length > 1) {
            const interval = clickTimes.at(-1) - clickTimes.at(-2);
            clickIntervals.push(interval);
            if (clickIntervals.length > 50) clickIntervals.shift();
        }

        requestAnimationFrame(() => {
            clickLatency = Math.round(performance.now() - now);
        });

        keyHeat['Mouse'] = 1.0;
    });

    document.addEventListener("keydown", (e) => {
        const now = performance.now();
        keyTimes.push(now);
        keyTimes = keyTimes.filter(t => now - t < 1000);
        kps = keyTimes.length;

        keyHeat[e.key.toUpperCase()] = 1.0;
    });

    document.addEventListener("keyup", (e) => { keyHeat[e.key.toUpperCase()] = 0; });

    // =========================
    // LATENCY
    // =========================
    async function measureLatency() {
        const start = performance.now();
        try {
            await fetch(location.origin, { method: "HEAD", cache: "no-store" });
            latency = Math.round(performance.now() - start);
        } catch { latency = -1; }
    }
    setInterval(measureLatency, 5000);

    // =========================
    // ANALYSIS
    // =========================
    function getHumanScore() {
        if (clickIntervals.length < 5) return "N/A";
        const avg = clickIntervals.reduce((a,b)=>a+b)/clickIntervals.length;
        const variance = clickIntervals.reduce((a,b)=>a+(b-avg)**2,0)/clickIntervals.length;
        const stdDev = Math.sqrt(variance);

        const hasOutliers = clickIntervals.some(i => Math.abs(i - avg) > avg * 0.5);

        if (stdDev < 5 && !hasOutliers) return "BOT";
        if (stdDev < 15) return "SUSPICIOUS";
        return "HUMAN";
    }

    function getAvgCPS() {
        if (!cpsHistory.length) return 0;
        return Math.round(cpsHistory.reduce((a,b)=>a+b)/cpsHistory.length);
    }

    function colorHuman(score) {
        return score==="HUMAN"?"#00ff9c":score==="SUSPICIOUS"?"#ffd166":"#ff4d6d";
    }

    function colorPing(p) {
        return p<80?"#00ff9c":p<150?"#ffd166":"#ff4d6d";
    }

    // =========================
    // UI
    // =========================
    function createUI() {
        if (document.getElementById("cyberHUD")) return;

        const ui = document.createElement("div");
        ui.id = "cyberHUD";

        const saved = JSON.parse(localStorage.getItem("cyberHUD")||"{}");
        ui.style.left = saved.x || "20px";
        ui.style.top = saved.y || "20px";

        ui.innerHTML = `
            <div id="hdr">⚡ CYBER HUD ▼</div>
            <div id="content">
                <div class="row"><span>FPS</span><span id="fps"></span></div>
                <canvas id="fpsGraph" width="240" height="20"></canvas>

                <div class="row"><span>CPS</span><span id="cps"></span></div>
                <canvas id="cpsGraph" width="240" height="20"></canvas>

                <div class="row"><span>KPS</span><span id="kps"></span></div>
                <div class="row"><span>Latency</span><span id="lat"></span></div>
                <div class="row"><span>Human</span><span id="human"></span></div>

                <hr>
                <div class="row"><span>Peak CPS</span><span id="peak"></span></div>
                <div class="row"><span>Avg CPS</span><span id="avg"></span></div>
                <div class="row"><span>Total Clicks</span><span id="total"></span></div>

                <div id="heatmap"></div>
            </div>
        `;

        document.body.appendChild(ui);

        const style = document.createElement("style");
        style.textContent = `
            #cyberHUD{position:fixed;width:240px;font-family:monospace;background:linear-gradient(135deg,#021a1a,#031f2e);border:1px solid #00ffc8;border-radius:12px;color:#d9fff8;box-shadow:0 0 20px #00ffc855,inset 0 0 10px #00ffc822;z-index:999999;}
            #hdr{padding:8px;text-align:center;font-weight:bold;background:linear-gradient(90deg,#00ff9c,#00cfff);color:#002;cursor:grab;}
            #content{padding:10px;font-size:12px;}
            .row{display:flex;justify-content:space-between;margin:4px 0;}
            canvas{margin-bottom:4px;}
            #heatmap{display:flex;gap:2px;margin-top:4px;flex-wrap:wrap;}
            .keyBlock{width:20px;height:20px;background:#004d40;border-radius:3px;text-align:center;font-size:10px;color:#d9fff8;line-height:20px;transition:background 0.2s;}
        `;
        document.head.appendChild(style);

        const header = ui.querySelector("#hdr");
        const content = ui.querySelector("#content");

        let collapsed = saved.collapsed ?? true;
        content.style.display = collapsed?"none":"block";

        header.onclick = () => {
            collapsed = !collapsed;
            content.style.display = collapsed ? "none" : "block";
            header.textContent = collapsed ? "⚡ CYBER HUD ▼" : "⚡ CYBER HUD ▲";
            localStorage.setItem("cyberHUD",JSON.stringify({x:ui.style.left,y:ui.style.top,collapsed}));
        };

        let dragging = false, ox = 0, oy = 0;
        header.addEventListener("mousedown", e => { dragging = true; ox = e.clientX - ui.offsetLeft; oy = e.clientY - ui.offsetTop; });
        document.addEventListener("mousemove", e => {
            if(!dragging) return;
            ui.style.left = (e.clientX - ox) + "px";
            ui.style.top = (e.clientY - oy) + "px";
            localStorage.setItem("cyberHUD",JSON.stringify({x:ui.style.left,y:ui.style.top,collapsed}));
        });
        document.addEventListener("mouseup", ()=> dragging=false);

        // Cache elements for updates
        const fpsEl = ui.querySelector("#fps");
        const cpsEl = ui.querySelector("#cps");
        const kpsEl = ui.querySelector("#kps");
        const latEl = ui.querySelector("#lat");
        const humanEl = ui.querySelector("#human");
        const peakEl = ui.querySelector("#peak");
        const avgEl = ui.querySelector("#avg");
        const totalEl = ui.querySelector("#total");
        const fpsCanvas = ui.querySelector("#fpsGraph");
        const cpsCanvas = ui.querySelector("#cpsGraph");
        const fpsCtx = fpsCanvas.getContext("2d");
        const cpsCtx = cpsCanvas.getContext("2d");

        // Heatmap keys
        const keysToShow = ["W","A","S","D","Mouse"];
        keysToShow.forEach(k => {
            if(!keyHeat[k]) keyHeat[k]=0;
            const div = document.createElement("div");
            div.id = "key_"+k;
            div.className="keyBlock";
            div.textContent=k;
            ui.querySelector("#heatmap").appendChild(div);
        });

        setInterval(()=>{
            fpsEl.textContent = fps;
            cpsEl.textContent = cps;
            kpsEl.textContent = kps;
            latEl.textContent = latency;
            humanEl.textContent = getHumanScore();
            peakEl.textContent = peakCPS;
            avgEl.textContent = getAvgCPS();
            totalEl.textContent = totalClicks;

            // FPS Graph
            fpsCtx.clearRect(0,0,fpsCanvas.width,fpsCanvas.height);
            fpsCtx.beginPath();
            fpsHistory.forEach((v,i)=>{
                const x = i*(fpsCanvas.width/fpsHistory.length);
                const y = fpsCanvas.height - (v/MAX_FPS)*fpsCanvas.height;
                i===0?fpsCtx.moveTo(x,y):fpsCtx.lineTo(x,y);
            });
            fpsCtx.strokeStyle="#00ffc8";
            fpsCtx.stroke();

            // CPS Graph
            cpsCtx.clearRect(0,0,cpsCanvas.width,cpsCanvas.height);
            cpsCtx.beginPath();
            cpsHistory.forEach((v,i)=>{
                const x = i*(cpsCanvas.width/cpsHistory.length);
                const y = cpsCanvas.height - Math.min(v/30,1)*cpsCanvas.height;
                i===0?cpsCtx.moveTo(x,y):cpsCtx.lineTo(x,y);
            });
            cpsCtx.strokeStyle="#ffd166";
            cpsCtx.stroke();

            // Heatmap
            keysToShow.forEach(k=>{
                if(keyHeat[k]>0) keyHeat[k]-=0.05;
                const div=document.getElementById("key_"+k);
                div.style.background=`rgba(0, 200, 255, ${0.3+keyHeat[k]*0.7})`;
            });
        }, 200);
    }

    const wait = setInterval(()=>{if(document.body){clearInterval(wait);createUI();}},100);

})();