HackerWars.io UI++

Enables drag and drop functionality for list items

Versión del día 22/02/2025. Echa un vistazo a la versión más reciente.

// ==UserScript==
// @name         HackerWars.io UI++
// @namespace    http://tampermonkey.net/
// @version      1.4.1
// @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

    //now for stuff
 setTimeout(function(){
        const rows = document.querySelectorAll("table tbody tr");
        rows.forEach(row => {
            const descriptionCell = row.cells[1]; // Get the second column
            if (descriptionCell) {
                const text = descriptionCell.innerText.trim(); // Get visible text only
                if (text.includes("This mission is hidden.")) {
                    row.style.display = "none"; // Hide the row
                }
            }
        });
    }, 500);


    //end



 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";

    // Define grouped extensions
    let extensionGroups = {
        "Show All": [""],
        "General": [".txt", ".dat", ".torrent"],
        "Security": [".crc", ".hash", ".fwl", ".hdr", ".skr"],
        "Virus/Malware": [".av", ".vspam", ".vddos", ".vminer"],
        "Hacking Tools": [".exp", ".vwarez", ".vcol"]
    };

    Object.entries(extensionGroups).forEach(([groupName, extensions]) => {
        let optgroup = document.createElement("optgroup");
        optgroup.label = groupName;

        extensions.forEach(ext => {
            let option = document.createElement("option");
            option.value = ext;
            option.textContent = ext === "" ? "Show All" : ext;
            optgroup.appendChild(option);
        });

        filterSelect.appendChild(optgroup);
    });

    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('input[type="submit"][value="Edit log file"]').click();
        });

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

    injectButton();






})();