HackerWars.io UI++

Enables drag and drop functionality for list items

Versione datata 20/02/2025. Vedi la nuova versione l'ultima versione.

// ==UserScript==
// @name         HackerWars.io UI++
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  Enables drag and drop functionality for list items
// @author       Oryyx
// @match        https://hackerwars.io/*
// @license MIT

// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    //tabel filtr


       function initFilter() {
        let table = document.querySelector("table.table-software");
        if (!table) {
            console.warn("No software table found.");
            return;
        }

        // Prevent duplicate filters
        if (document.getElementById("software-filter")) return;

        // Create filter UI
        let filterContainer = document.createElement("div");
        filterContainer.style.marginBottom = "10px";

        let filterLabel = document.createElement("label");
        filterLabel.textContent = "Filter by Extension: ";
        filterLabel.style.fontWeight = "bold";
        filterLabel.style.marginRight = "5px";

        let filterSelect = document.createElement("select");
        filterSelect.id = "software-filter";

        let extensions = ["", ".crc", ".hash", ".fwl",'.hdr','.skr','.av','.exp','.vminer','.vspam','.vddos','.torrent','.dat','.txt'];
        extensions.forEach(ext => {
            let option = document.createElement("option");
            option.value = ext;
            option.textContent = ext === "" ? "Show All" : ext;
            filterSelect.appendChild(option);
        });

        filterContainer.appendChild(filterLabel);
        filterContainer.appendChild(filterSelect);

        // Insert filter above the table
        table.parentNode.insertBefore(filterContainer, table);

        // Filtering function
        function filterSoftware() {
            let selectedExt = filterSelect.value;
            let rows = document.querySelectorAll("table.table-software tbody tr");

            rows.forEach(row => {
                let softwareNameCell = row.querySelector("td:nth-child(2)"); // Second <td> contains software name
                if (!softwareNameCell) return;

                let softwareName = softwareNameCell.textContent.trim();
                row.style.display = (selectedExt === "" || softwareName.endsWith(selectedExt)) ? "" : "none";
            });
        }

        // Listen for dropdown changes
        filterSelect.addEventListener("change", filterSoftware);

        // Run filter in case page is already loaded
        filterSoftware();
    }

    // Use a MutationObserver to detect when the table appears (for dynamically loaded content)
    let observer = new MutationObserver(() => {
        if (document.querySelector("table.table-software")) {
            observer.disconnect(); // Stop observing once table is found
            initFilter();
        }
    });

    observer.observe(document.body, { childList: true, subtree: true });

    // Also try running it immediately (in case the table is already there)
    document.addEventListener("DOMContentLoaded", initFilter);



    //end table filtering


    // Task ordering


        // Adding custom styles
    const style = document.createElement('style');
    style.innerHTML = `
        .list {
            list-style: none;
            padding: 0;
        }

        .list li {
            display: flex;
            align-items: center;
            padding: 10px;
            background: #f4f4f4;
            margin: 5px 0;
            cursor: grab;
            border-radius: 5px;
            transition: background 0.2s ease-in-out;
        }

        .list li .drag-handle {
            cursor: grab;
            margin-right: 10px;
            font-size: 1.2em;
            opacity: 0.5;
        }

        .list li:hover .drag-handle {
            opacity: 1;
        }

        .list li.dragging {
            opacity: 0.7;
            background: #ddd;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
        }

        .list li:active {
            cursor: grabbing;
        }
    `;
    document.head.appendChild(style);

    // Make the list items draggable
    document.querySelectorAll('.list').forEach(list => {
        list.querySelectorAll('li').forEach(li => {
            // Add drag handle icon
            const dragHandle = document.createElement('span');
            dragHandle.classList.add('drag-handle');
            dragHandle.textContent = '⋮⋮'; // You can replace this with any icon, e.g., FontAwesome
            li.prepend(dragHandle);

            li.draggable = true;

            li.addEventListener('dragstart', (e) => {
                e.dataTransfer.setData('text/plain', ''); // Required for Firefox
                li.classList.add('dragging');
            });

            li.addEventListener('dragend', () => {
                li.classList.remove('dragging');
            });
        });

        list.addEventListener('dragover', (e) => {
            e.preventDefault();

            const dragging = document.querySelector('.dragging');
            if (!dragging) return; // Ensure dragging element exists

            const afterElement = getDragAfterElement(list, e.clientY);

            if (afterElement && afterElement.element) {
                list.insertBefore(dragging, afterElement.element);
            } else {
                list.appendChild(dragging);
            }
        });
    });

    function getDragAfterElement(container, y) {
        const draggableElements = [...container.querySelectorAll('li:not(.dragging)')];

        return draggableElements.reduce((closest, child) => {
            const box = child.getBoundingClientRect();
            const offset = y - box.top - box.height / 2;
            return (offset < 0 && offset > closest.offset) ? { offset, element: child } : closest;
        }, { offset: Number.NEGATIVE_INFINITY, element: null });
    }

    //end task ordering


    //Doublr click to view procb

        document.querySelectorAll('li').forEach(function(li) {
    li.addEventListener('dblclick', function() {
        // Find the element with the 'span5' class inside the clicked 'li'
        var span5 = li.querySelector('.span5');
        if (span5) {
            // Extract the 'data-process-id' from the child element
            var processElement = span5.querySelector('.process');
            var processId = processElement ? processElement.getAttribute('data-process-id') : null;
            window.location.href = '/processes?pid='+processId;
        }
    });
});


    //end


    // Inject a new button next to the "Edit log file" button
    function injectButton() {
        const existingButton = document.querySelector('input.btn.btn-inverse[value="Edit log file"]');
        if (!existingButton) return;

        const newButton = document.createElement('input');
        newButton.type = 'button';
        newButton.value = 'Wipe log';
        newButton.className = 'btn btn-inverse';
        newButton.style.marginLeft = '5px';

        newButton.addEventListener('click', () => {
            document.querySelector('.logarea').value = '';
            document.querySelector('[type="submit"]').click();
        });

        existingButton.parentNode.insertBefore(newButton, existingButton.nextSibling);
    }

    injectButton();






})();