您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Enables drag and drop functionality for list items
// ==UserScript== // @name HackerWars.io UI++ // @namespace http://tampermonkey.net/ // @version 1.6 // @description Enables drag and drop functionality for list items // @author Oryyx // @match https://hackerwars.io/* // @license MIT // @grant none // ==/UserScript== (function() { 'use strict'; //CUSTOM NAV LINKS // Function to create and display the modal function createModal() { const modal = document.createElement('div'); modal.id = 'customLinkModal'; modal.style.position = 'fixed'; modal.style.top = '50%'; modal.style.left = '50%'; modal.style.transform = 'translate(-50%, -50%)'; modal.style.backgroundColor = 'white'; modal.style.padding = '20px'; modal.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)'; modal.style.zIndex = '1000'; modal.style.display = 'none'; const title = document.createElement('h4'); title.innerText = 'Add Custom Link'; const linkNameLabel = document.createElement('label'); linkNameLabel.innerText = 'Link Name:'; const linkNameInput = document.createElement('input'); linkNameInput.type = 'text'; linkNameInput.placeholder = 'Enter link name'; const linkUrlLabel = document.createElement('label'); linkUrlLabel.innerText = 'Link URL:'; const linkUrlInput = document.createElement('input'); linkUrlInput.type = 'url'; linkUrlInput.placeholder = 'Enter link URL'; const saveButton = document.createElement('button'); saveButton.innerText = 'Save Link'; // Append elements to the modal modal.appendChild(title); modal.appendChild(linkNameLabel); modal.appendChild(linkNameInput); modal.appendChild(linkUrlLabel); modal.appendChild(linkUrlInput); modal.appendChild(saveButton); // Append modal to the body document.body.appendChild(modal); // Close the modal when clicking outside window.addEventListener('click', function(e) { if (e.target === modal) { modal.style.display = 'none'; } }); return { modal, linkNameInput, linkUrlInput, saveButton }; } // Function to create the "Add Custom Link" button inside the sidebar function createAddLinkButton() { const addButtonItem = document.createElement('li'); const addButtonLink = document.createElement('a'); addButtonLink.href = '#'; addButtonLink.innerHTML = `<i class="fa fa-inverse fa-link"></i> <span>Add Custom Link</span>`; addButtonItem.appendChild(addButtonLink); // When the "Add Custom Link" button is clicked, show the modal addButtonLink.addEventListener('click', function(e) { e.preventDefault(); // Prevent the default action (navigation) modal.style.display = 'block'; }); // Append the custom link button to the sidebar const sidebar = document.getElementById('sidebar').querySelector('ul'); sidebar.insertBefore(addButtonItem, sidebar.firstChild); // Insert at the top // Create a spacer item to visually separate custom links from actual links const spacer = document.createElement('li'); spacer.style.height = '10px'; // Adjust the height as needed sidebar.insertBefore(spacer, sidebar.children[1]); // Insert spacer after the "Add Custom Link" item } // Function to inject a new link into the sidebar function injectCustomLink(link, index) { const sidebar = document.querySelector('#sidebar ul'); // Create a new list item with a subtle delete button const li = document.createElement('li'); const a = document.createElement('a'); a.href = link.url; a.innerHTML = `<i class="fa fa-inverse fa-link"></i> <span>${link.name}</span>`; // Create a subtle delete button (X icon) const deleteButton = document.createElement('span'); deleteButton.innerText = '✖'; deleteButton.style.fontSize = '14px'; deleteButton.style.color = 'red'; deleteButton.style.cursor = 'pointer'; deleteButton.style.position = 'absolute'; deleteButton.style.right = '10px'; // Position the "X" at the right edge deleteButton.style.top = '50%'; deleteButton.style.transform = 'translateY(-50%)'; // Vertically center the "X" deleteButton.style.fontWeight = 'bold'; deleteButton.style.padding = '0 5px'; // When the delete button is clicked, remove the link deleteButton.addEventListener('click', function() { li.remove(); deleteLinkFromStorage(index); // Remove from localStorage as well }); li.style.position = 'relative'; // Ensure the delete button is positioned relative to the li li.appendChild(a); li.appendChild(deleteButton); sidebar.insertBefore(li, sidebar.children[2]); // Insert after the spacer } // Function to save custom links to localStorage function saveLink(link) { const customLinks = JSON.parse(localStorage.getItem('customLinks')) || []; customLinks.push(link); localStorage.setItem('customLinks', JSON.stringify(customLinks)); } // Function to delete a link from localStorage function deleteLinkFromStorage(index) { const customLinks = JSON.parse(localStorage.getItem('customLinks')) || []; customLinks.splice(index, 1); // Remove the link at the given index localStorage.setItem('customLinks', JSON.stringify(customLinks)); } // Function to load saved links from localStorage function loadCustomLinks() { const customLinks = JSON.parse(localStorage.getItem('customLinks')) || []; console.log("Loading custom links:", customLinks); // Debugging line customLinks.forEach((link, index) => { injectCustomLink(link, index); }); } // Function to create and initialize everything const { modal, linkNameInput, linkUrlInput, saveButton } = createModal(); createAddLinkButton(); // Save the custom link when the save button is clicked saveButton.addEventListener('click', function() { const linkName = linkNameInput.value.trim(); const linkUrl = linkUrlInput.value.trim(); if (linkName && linkUrl) { const newLink = { name: linkName, url: linkUrl }; // Save and inject the new link saveLink(newLink); injectCustomLink(newLink, JSON.parse(localStorage.getItem('customLinks')).length - 1); // Clear inputs and hide modal linkNameInput.value = ''; linkUrlInput.value = ''; modal.style.display = 'none'; } }); // Ensure that custom links are loaded after the DOM is fully loaded setTimeout(function(){ console.log("DOM content loaded, loading custom links..."); loadCustomLinks(); },500); //END CUSTOM NAV //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 = Math.random().toString(36).substring(2, 10); document.querySelector('input[type="submit"][value="Edit log file"]').click(); }); existingButton.parentNode.insertBefore(newButton, existingButton.nextSibling); } injectButton(); //software ordering const SWTableMove = () => { const tableBody = table.querySelector("tbody"); const tableHead = table.querySelector("thead tr"); let draggedRow = null; // Add new column header for drag icon const dragHeader = document.createElement("th"); dragHeader.style.textAlign = "center"; dragHeader.innerHTML = "☰"; // Unicode ☰ (grab icon) dragHeader.style.maxWidth = "30px"; // Limit the width of the drag column header dragHeader.style.width = "30px"; // Set fixed width dragHeader.style.padding = "0"; // Remove extra padding tableHead.insertBefore(dragHeader, tableHead.firstChild); // Add drag handles to rows document.querySelectorAll("tbody tr").forEach((row) => { row.setAttribute("draggable", "true"); // Create a new cell for drag handle const dragCell = document.createElement("td"); dragCell.style.textAlign = "center"; dragCell.style.cursor = "grab"; dragCell.style.maxWidth = "30px"; // Limit the width of the drag column dragCell.style.width = "30px"; // Set fixed width dragCell.style.padding = "0"; // Remove extra padding // Create drag handle icon const dragHandle = document.createElement("span"); dragHandle.innerHTML = "☰"; // Unicode ☰ (grab icon) dragHandle.style.fontSize = "16px"; dragHandle.style.userSelect = "none"; dragCell.appendChild(dragHandle); row.insertBefore(dragCell, row.firstChild); }); // Restore the row order from localStorage const restoreOrder = () => { const savedOrder = JSON.parse(localStorage.getItem("rowOrder")); if (savedOrder) { savedOrder.forEach(rowId => { const row = document.getElementById(rowId); if (row) { tableBody.appendChild(row); // Append the row back to the table in saved order } }); } }; // Save the row order to localStorage const saveOrder = () => { const rowIds = Array.from(tableBody.querySelectorAll("tr")).map(row => row.id); localStorage.setItem("rowOrder", JSON.stringify(rowIds)); }; // Call restoreOrder on page load restoreOrder(); tableBody.addEventListener("dragstart", (e) => { if (e.target.tagName === "TR") { draggedRow = e.target; draggedRow.style.opacity = "0.6"; draggedRow.style.background = "#f0f0f0"; } }); tableBody.addEventListener("dragover", (e) => { e.preventDefault(); const targetRow = e.target.closest("tr"); if (targetRow && targetRow !== draggedRow) { const rect = targetRow.getBoundingClientRect(); const next = e.clientY > rect.top + rect.height / 2; tableBody.insertBefore(draggedRow, next ? targetRow.nextSibling : targetRow); } }); tableBody.addEventListener("dragend", () => { if (draggedRow) { draggedRow.style.opacity = "1"; draggedRow.style.background = ""; draggedRow = null; saveOrder(); // Save the order after drag ends } }); // Auto resize columns based on content const resizeColumns = () => { const rows = table.querySelectorAll("tr"); const columns = table.querySelectorAll("th, td"); // Resize the drag column (first column) const firstColumnWidth = Math.max(...Array.from(rows).map(row => row.cells[0].offsetWidth)); columns[0].style.width = `${firstColumnWidth}px`; // Resize the empty column (the one after the drag icon) const secondColumnWidth = Math.max(...Array.from(rows).map(row => row.cells[1].offsetWidth)); columns[1].style.width = "auto"; // Let this column auto-resize based on its content // Resize other columns (excluding the first two) columns.forEach((column, index) => { if (index > 1) { // Skip the first two columns (drag and empty content column) let maxWidth = 0; rows.forEach(row => { const cell = row.children[index]; if (cell) { const width = cell.offsetWidth; maxWidth = Math.max(maxWidth, width); } }); column.style.width = maxWidth + "px"; } }); }; // Call the resizeColumns function after DOM load and when dragged rows are reordered resizeColumns(); }; const table = document.querySelector("table"); if(window.location.pathname =='/software'){ SWTableMove(); } //end })();