ZcxJames's hornex wave script

Fetch and display JSON data from zcxjames.top/data.json on the right side of the screen with grid lines, text color change based on time value, lighter font weight, and toggle visibility with Tab key

目前为 2024-08-14 提交的版本。查看 最新版本

// ==UserScript==
// @name         ZcxJames's hornex wave script
// @namespace    tampermonkey.net/
// @version      2.4
// @description  Fetch and display JSON data from zcxjames.top/data.json on the right side of the screen with grid lines, text color change based on time value, lighter font weight, and toggle visibility with Tab key
// @author       ZcxJames
// @match        https://hornex.pro/*
// @grant        GM_xmlhttpRequest
// @connect      zcxjames.top
// @connect      103.193.151.90
// @license      GPL
// ==/UserScript==

(function() {
    'use strict';

    const scriptVersion = '2.4';
    const regions = ['as1', 'as2', 'eu1', 'eu2', 'us1', 'us2'];
    const servers = {
        'eu1': 'rgb(166, 56, 237)', 'eu2': 'rgb(81, 121, 251)',
        'as1': 'rgb(237, 61, 234)', 'us1': 'rgb(219, 130, 41)',
        'us2': 'rgb(237, 236, 61)', 'as2': 'rgb(61, 179, 203)'
    };
    const zones = {
        'Ultra': 'rgb(255, 43, 117)', 'Super': 'rgb(43, 255, 163)',
        'Hyper': 'rgb(92, 116, 176)', 'Waveroom': 'rgb(126, 239, 109)'
    };

    let tableVisible = true;
    let previousServer = '', previousZone = '', currentServer = '', currentZone = '', progress = '';

    function createTable(jsonData) {
        const existingTable = document.getElementById('jsonDataTable');
        if (existingTable) existingTable.remove();

        const table = document.createElement('table');
        table.id = 'jsonDataTable';
        table.style.cssText = `
            position: fixed; top: 50%; right: 0; transform: translateY(-50%);
            border: 1px solid black; background-color: transparent;
            z-index: 1000; width: 200px; border-collapse: collapse; font-weight: lighter;
        `;

        table.innerHTML = `
            <thead>
                <tr><th style="border: 1px solid black;">&nbsp;</th>
                    <th style="border: 1px solid black;">Super</th>
                    <th style="border: 1px solid black;">Hyper</th>
                </tr>
            </thead>
            <tbody>
                ${regions.map(region => `
                    <tr>
                        <td style="border: 1px solid black;">${region}</td>
                        ${['Super', 'Hyper'].map(type => {
                            const key = `${region}_${type}`;
                            const data = jsonData[key] || {};
                            const timeValue = data.time;
                            const progress = data.progress || 'N/A';
                            return `<td style="border: 1px solid black; color: ${timeValue ? 'orange' : 'black'};">${progress}</td>`;
                        }).join('')}
                    </tr>`).join('')}
            </tbody>`;

        document.body.appendChild(table);
        table.style.display = tableVisible ? 'table' : 'none';
    }

    function fetchAndUpdateTable() {
        GM_xmlhttpRequest({
            method: 'GET',
            url: 'https://zcxjames.top/data.json',
            onload: response => createTable(JSON.parse(response.responseText))
        });
    }

    function toggleTableVisibility(event) {
        if (event.key === 'Tab') {
            event.preventDefault();
            tableVisible = !tableVisible;
            const table = document.getElementById('jsonDataTable');
            if (table) table.style.display = tableVisible ? 'table' : 'none';
        }
    }

    function updateIndicator() {
        const activeButton = document.querySelector('div.btn.active');
        const zoneName = document.querySelector('div.zone-name');
        const waveSpan = document.querySelector('body > div.hud > div.zone > div.progress > span[stroke]');

        currentServer = activeButton ? Object.keys(servers).find(server => activeButton.style.backgroundColor === servers[server]) : '';
        currentZone = zoneName ? Object.keys(zones).find(zone => zoneName.getAttribute('stroke') === zones[zone]) : '';
        if (document.querySelector('div.zone-name[stroke="Waveroom"]')) currentZone = 'Waveroom';

        const waveMatch = waveSpan ? waveSpan.getAttribute('stroke').match(/Wave (\d+)/i) : null;
        progress = waveMatch ? `Wave ${waveMatch[1]}` : '0%';

        document.querySelectorAll('div.bar').forEach(bar => {
            const match = bar.style.transform.match(/translate\(calc\(-(\d+(\.\d+)?)% \+ \d+(\.\d+)?em\), 0px\)/);
            if (match && parseFloat(match[1]) < parseFloat(progress)) {
                progress = `${(100 - parseFloat(match[1])).toFixed(4)}%`;
            }
        });

        document.getElementById('indicator').textContent = `${currentServer || 'Server not detected'} - ${currentZone || 'Zone not detected'} - Progress: ${progress}`;
    }

    function sendPost() {
        if (document.hidden) return;
        if (currentServer !== previousServer || currentZone !== previousZone) {
            previousServer = currentServer;
            previousZone = currentZone;
            return;
        }

        GM_xmlhttpRequest({
            method: "POST",
            url: "http://103.193.151.90:5000",
            data: JSON.stringify({ server: currentServer, zone: currentZone, progress }),
            headers: { "Content-Type": "application/json" }
        });
    }

    function setupIndicator() {
        const indicator = document.createElement('div');
        indicator.id = 'indicator';
        indicator.style.cssText = 'position: fixed; bottom: 20px; right: 0; background-color: transparent; padding: 10px; z-index: 10000;';
        document.body.appendChild(indicator);
    }

    function checkVersion() {
        GM_xmlhttpRequest({
            method: 'GET',
            url: 'https://zcxjames.top/version.json',
            onload: response => {
                const remoteVersion = JSON.parse(response.responseText).version;
                if (remoteVersion !== scriptVersion) displayVersionWarning();
            }
        });
    }

function displayVersionWarning() {
    const warningDiv = document.createElement('div');
    warningDiv.id = 'versionWarning';
    warningDiv.style.cssText = `
        position: fixed; bottom: 0; right: 0;
        background-color: red; color: white; padding: 10px;
        z-index: 10000; font-weight: bold; white-space: pre-wrap;
    `;
    warningDiv.innerHTML = `
        The script has a new version. Please update your script.
        \n\n Visit the release page:
        <a href="https://github.com/ZcxJames/hornex-wave-script/releases" target="_blank" style="color: white; text-decoration: underline;">
            https://github.com/ZcxJames/hornex-wave-script/releases
        </a>
    `;
    document.body.appendChild(warningDiv);
}

    document.addEventListener('keydown', toggleTableVisibility);
    setInterval(fetchAndUpdateTable, 1000);
    setInterval(sendPost, 1000);
    setupIndicator();
    checkVersion();

    const observer = new MutationObserver(updateIndicator);
    const hudZone = document.querySelector('body > div.hud > div.zone');
    if (hudZone) {
        observer.observe(hudZone.querySelector('div.zone-name'), { attributes: true, subtree: true, attributeFilter: ['style', 'class'] });
        observer.observe(hudZone.querySelector('div.progress > div'), { attributes: true, subtree: true, attributeFilter: ['style', 'class'] });
        observer.observe(hudZone.querySelector('div.progress > span'), { attributes: true, subtree: true, attributeFilter: ['style', 'class'] });
    }
    observer.observe(document.querySelector('body > div.menu'), { attributes: true, subtree: true, attributeFilter: ['style', 'class'] });

    requestAnimationFrame(function animate() {
        updateIndicator();
        requestAnimationFrame(animate);
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址