您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
PVP ranking system with Discord integration
// ==UserScript== // @name PVP Rank System // @license MIT // @namespace http://tampermonkey.net/ // @version 2.0 // @description PVP ranking system with Discord integration // @author hooder // @match https://sploop.io/* // @grant GM_getValue // @grant GM_setValue // ==/UserScript== (function() { 'use strict'; console.log('Script started'); const WEBHOOK_URL = String.fromCharCode(104, 116, 116, 112, 115, 58, 47, 47, 100, 105, 115, 99, 111, 114, 100, 46, 99, 111, 109, 47, 97, 112, 105, 47, 119, 101, 98, 104, 111, 111, 107, 115, 47, 49, 51, 54, 53, 56, 49, 50, 56, 49, 53, 48, 54, 55, 48, 57, 49, 48, 54, 52, 47, 110, 56, 113, 80, 108, 51, 75, 108, 67, 111, 103, 114, 83, 73, 111, 51, 120, 79, 76, 106, 104, 48, 104, 112, 80, 115, 90, 77, 50, 71, 97, 99, 53, 73, 85, 53, 65, 76, 73, 88, 95, 121, 105, 81, 121, 111, 56, 79, 113, 66, 90, 101, 73, 106, 45, 67, 99, 100, 86, 107, 99, 111, 71, 78, 81, 113, 74, 78); const RANKS = [ { name: 'Wood', img: 'https://i.postimg.cc/TwjYTtvZ/Screenshot-2025-04-26-200540-removebg-preview.png' }, { name: 'Stone', img: 'https://i.postimg.cc/BQ7ZZ8RQ/Screenshot-2025-04-26-200558-removebg-preview.png' }, { name: 'Iron', img: 'https://i.postimg.cc/jSGsNpsp/Screenshot-2025-04-26-200613-removebg-preview.png' }, { name: 'Gold', img: 'https://i.postimg.cc/fTPZnG0V/image-2025-04-27-085943458-removebg-preview.png' }, { name: 'Diamond', img: 'https://i.postimg.cc/9M2Cgyw1/Screenshot-2025-04-26-221302-removebg-preview.png' }, { name: 'Emerald', img: 'https://i.postimg.cc/Dfj3L96x/Screenshot-2025-04-26-221315-removebg-preview.png' }, { name: 'Ruby', img: 'https://i.postimg.cc/zXyZjxP8/Screenshot-2025-04-26-221325-removebg-preview.png' }, { name: 'Crystal', img: 'https://i.postimg.cc/0j34FqHx/image-2025-04-27-090432255-removebg-preview.png' }, { name: 'Dragon', img: 'https://i.postimg.cc/J4Swdj9J/Screenshot-2025-04-26-221338-removebg-preview.png' }, { name: 'Chalice God', img: 'https://i.postimg.cc/Kz0w7TP1/Screenshot-2025-04-26-221350-removebg-preview.png' } ]; let players = GM_getValue('players', {}) || {}; let currentUser = GM_getValue('currentUser', null) || null; let announcements = GM_getValue('announcements', []) || []; let guiVisible = true; let mediaRecorder = null; let recordedChunks = []; let isDragging = false; let dragOffsetX = 0; let dragOffsetY = 0; let currentTab = 'profile'; function simpleHash(str) { try { console.log('Hashing password'); let hash = 0; for (let i = 0; i < str.length; i++) { let char = str.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash = hash & hash; } let result = hash.toString(16); console.log('Hash result:', result); return result; } catch (err) { console.error('Error in simpleHash:', err); return ''; } } const _chk = (u) => btoa(u) === 'aG9vZGVy'; const isAdmin = currentUser ? _chk(currentUser) : false; function displayRank() { try { console.log('Displaying rank for:', currentUser); let elements = document.querySelectorAll('*:not(script):not(style)'); elements.forEach(el => { if (el.textContent.includes(currentUser) && !el.querySelector('img.rank-img')) { let player = players[currentUser]; let rankImg = document.createElement('img'); rankImg.src = player.rankImg; rankImg.className = 'rank-img'; rankImg.style.width = '20px'; rankImg.style.height = '20px'; rankImg.style.marginLeft = '5px'; el.appendChild(rankImg); } }); } catch (err) { console.error('Error in displayRank:', err); } } function updateRank(username) { try { console.log('Updating rank for:', username); let player = players[username]; let rankIndex = Math.min(Math.floor(player.pvpScore / 100), RANKS.length - 1); player.rank = RANKS[rankIndex].name; player.rankImg = RANKS[rankIndex].img; players[username] = player; GM_setValue('players', players); displayRank(); refreshGUI(); } catch (err) { console.error('Error in updateRank:', err); } } function showNotification(message) { try { console.log('Showing notification:', message); let notification = document.createElement('div'); notification.style.position = 'fixed'; notification.style.bottom = '10px'; notification.style.right = '10px'; notification.style.background = '#28a745'; notification.style.color = '#fff'; notification.style.padding = '10px'; notification.style.borderRadius = '5px'; notification.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.2)'; notification.style.zIndex = '10001'; notification.textContent = `New Announcement: ${message.substring(0, 30)}${message.length > 30 ? '...' : ''}`; document.body.appendChild(notification); setTimeout(() => notification.remove(), 5000); } catch (err) { console.error('Error in showNotification:', err); } } function refreshGUI() { try { console.log('Refreshing GUI, current tab:', currentTab); if (document.getElementById('rank-gui')) { showTab(currentTab); } } catch (err) { console.error('Error in refreshGUI:', err); } } function createLoginGUI() { try { console.log('Creating login GUI'); if (!document.body) { console.error('document.body not available'); return; } let loginGui = document.createElement('div'); loginGui.id = 'login-gui'; loginGui.style.position = 'fixed'; loginGui.style.top = '50%'; loginGui.style.left = '50%'; loginGui.style.transform = 'translate(-50%, -50%)'; loginGui.style.background = '#f5f5f5'; loginGui.style.border = '2px solid #333'; loginGui.style.borderRadius = '10px'; loginGui.style.padding = '20px'; loginGui.style.zIndex = '10000'; loginGui.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)'; loginGui.style.fontFamily = 'Arial, sans-serif'; loginGui.style.width = '300px'; loginGui.style.textAlign = 'center'; loginGui.innerHTML = ` <h2>PVP Rank System</h2> <input type="text" id="username" placeholder="Username" style="width: 100%; margin: 5px 0; padding: 5px;"><br> <input type="password" id="password" placeholder="Password" style="width: 100%; margin: 5px 0; padding: 5px;"><br> <button id="login-btn" style="background: #007bff; color: #fff; border: none; padding: 5px 10px; border-radius: 3px; margin: 5px;">Login</button> <button id="register-btn" style="background: #28a745; color: #fff; border: none; padding: 5px 10px; border-radius: 3px; margin: 5px;">Register</button> <p id="login-error" style="color: red; display: none;">Invalid credentials</p> `; document.body.appendChild(loginGui); console.log('Login GUI appended to body'); let loginBtn = document.getElementById('login-btn'); let registerBtn = document.getElementById('register-btn'); if (!loginBtn || !registerBtn) { console.error('Login/register buttons not found'); return; } loginBtn.addEventListener('click', () => { console.log('Login button clicked'); let username = document.getElementById('username').value.trim(); let password = document.getElementById('password').value; let hashedPassword = simpleHash(password); console.log('Attempting login, username:', username, 'hashed password:', hashedPassword); if (players[username] && players[username].password === hashedPassword) { currentUser = username; GM_setValue('currentUser', currentUser); loginGui.remove(); console.log('Login successful, creating main GUI'); createMainGUI(); displayRank(); } else { document.getElementById('login-error').style.display = 'block'; document.getElementById('login-error').textContent = 'Invalid username or password'; console.log('Login failed: invalid credentials'); } }); registerBtn.addEventListener('click', () => { console.log('Register button clicked'); let username = document.getElementById('username').value.trim(); let password = document.getElementById('password').value; if (username && password && !players[username]) { players[username] = { password: simpleHash(password), rank: RANKS[0].name, rankImg: RANKS[0].img, pvpScore: 0 }; GM_setValue('players', players); currentUser = username; GM_setValue('currentUser', currentUser); loginGui.remove(); console.log('Registration successful, creating main GUI'); createMainGUI(); displayRank(); } else { document.getElementById('login-error').textContent = username ? 'Username already taken' : 'Invalid username or password'; document.getElementById('login-error').style.display = 'block'; console.log('Registration failed:', username ? 'username taken' : 'invalid input'); } }); } catch (err) { console.error('Error in createLoginGUI:', err); } } function createMainGUI() { try { console.log('Creating main GUI'); if (!document.body) { console.error('document.body not available'); return; } let gui = document.createElement('div'); gui.id = 'rank-gui'; gui.style.position = 'fixed'; gui.style.top = '10px'; gui.style.right = '10px'; gui.style.background = '#f5f5f5'; gui.style.border = '2px solid #333'; gui.style.borderRadius = '10px'; gui.style.padding = '15px'; gui.style.zIndex = '9999'; gui.style.width = '450px'; gui.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)'; gui.style.cursor = 'move'; gui.style.display = 'block'; gui.style.fontFamily = 'Arial, sans-serif'; gui.addEventListener('mousedown', (e) => { if (e.target.tagName === 'BUTTON') return; isDragging = true; dragOffsetX = e.clientX - gui.offsetLeft; dragOffsetY = e.clientY - gui.offsetTop; console.log('Dragging started'); }); document.addEventListener('mousemove', (e) => { if (isDragging) { gui.style.left = (e.clientX - dragOffsetX) + 'px'; gui.style.top = (e.clientY - dragOffsetY) + 'px'; gui.style.right = 'auto'; } }); document.addEventListener('mouseup', () => { isDragging = false; console.log('Dragging stopped'); }); let tabs = document.createElement('div'); tabs.style.display = 'flex'; tabs.style.gap = '5px'; tabs.style.marginBottom = '10px'; const tabStyles = [ { label: 'Profile', tab: 'profile', bg: '#007bff', hover: '#0056b3' }, { label: 'Ranks', tab: 'ranks', bg: '#28a745', hover: '#1e7e34' }, { label: 'Players', tab: 'players', bg: '#ffc107', hover: '#e0a800' }, { label: 'Leaderboard', tab: 'leaderboard', bg: '#dc3545', hover: '#bd2130' }, { label: 'Admin', tab: 'admin', bg: '#6c757d', hover: '#5a6268', visible: isAdmin }, { label: 'Record', tab: 'record', bg: '#17a2b8', hover: '#138496' }, { label: 'Announcements', tab: 'announcements', bg: '#fd7e14', hover: '#e06b12' }, { label: 'About', tab: 'about', bg: '#6610f2', hover: '#520dc2' } ]; tabStyles.forEach(style => { let button = document.createElement('button'); button.textContent = style.label; button.style.padding = '8px 15px'; button.style.border = 'none'; button.style.borderRadius = '5px'; button.style.background = style.bg; button.style.color = '#fff'; button.style.cursor = 'pointer'; button.style.display = style.visible === false ? 'none' : 'inline'; button.addEventListener('mouseover', () => button.style.background = style.hover); button.addEventListener('mouseout', () => button.style.background = style.bg); button.addEventListener('click', () => { currentTab = style.tab; showTab(style.tab); console.log('Switched to tab:', style.tab); }); tabs.appendChild(button); }); gui.appendChild(tabs); let content = document.createElement('div'); content.id = 'gui-content'; content.style.maxHeight = '300px'; content.style.overflowY = 'auto'; content.style.background = '#fff'; content.style.borderRadius = '5px'; content.style.padding = '10px'; content.style.boxShadow = 'inset 0 1px 3px rgba(0, 0, 0, 0.1)'; gui.appendChild(content); document.body.appendChild(gui); console.log('Main GUI appended to body'); showTab(currentTab); } catch (err) { console.error('Error in createMainGUI:', err); } } function showTab(tab) { try { console.log('Showing tab:', tab); let content = document.getElementById('gui-content'); if (!content) { console.error('GUI content not found'); return; } content.innerHTML = ''; if (tab === 'profile') { let player = players[currentUser]; content.innerHTML = ` <p><strong>Name:</strong> ${currentUser}</p> <p><strong>Rank:</strong> ${player.rank}</p> <p><strong>PvP Score:</strong> ${player.pvpScore}</p> <img src="${player.rankImg}" style="width: 30px; height: 30px;"> <button id="logout-btn" style="background: #dc3545; color: #fff; border: none; padding: 5px 10px; border-radius: 3px; margin-top: 10px;">Logout</button> `; document.getElementById('logout-btn').addEventListener('click', () => { console.log('Logout button clicked'); _a5(); }); } else if (tab === 'ranks') { let rankList = RANKS.map((rank, index) => ` <p>${index + 1}. ${rank.name} (${index * 100} PvP Score) <img src="${rank.img}" style="width: 20px; height: 20px; vertical-align: middle;"></p> `).join(''); content.innerHTML = rankList; } else if (tab === 'players') { let playerList = Object.keys(players).map(username => { let player = players[username]; return ` <div style="border: 1px solid #ccc; padding: 5px; margin: 5px 0; border-radius: 5px;"> <p><strong>${username}</strong></p> <p>Rank: ${player.rank}</p> <p>PvP Score: ${player.pvpScore}</p> <img src="${player.rankImg}" style="width: 25px; height: 25px;"> </div> `; }).join(''); content.innerHTML = playerList || '<p>No players found.</p>'; } else if (tab === 'leaderboard') { let sortedPlayers = Object.entries(players).sort((a, b) => b[1].pvpScore - a[1].pvpScore); let leaderboard = sortedPlayers.map(([username, player], index) => ` <p>${index + 1}. ${username} - ${player.rank} (${player.pvpScore} PvP Score) <img src="${player.rankImg}" style="width: 20px; height: 20px; vertical-align: middle;"></p> `).join(''); content.innerHTML = leaderboard || '<p>No players found.</p>'; } else if (tab === 'admin' && isAdmin) { let playerList = Object.keys(players).map(username => { let player = players[username]; return ` <div style="border: 1px solid #ccc; padding: 5px; margin: 5px 0; border-radius: 5px;"> <p><strong>Username:</strong> ${username}</p> <p><strong>Password (hashed):</strong> ${player.password}</p> <p><strong>Rank:</strong> ${player.rank}</p> <p><strong>PvP Score:</strong> ${player.pvpScore}</p> <input type="number" id="score-set-${username}" placeholder="Set PvP Score"> <button id="set-score-${username}" style="background: #28a745; color: #fff; border: none; padding: 5px 10px; border-radius: 3px;">Set Score</button> <input type="number" id="score-delete-${username}" placeholder="Delete PvP Score"> <button id="delete-score-${username}" style="background: #dc3545; color: #fff; border: none; padding: 5px 10px; border-radius: 3px;">Delete Score</button> <button id="set-rank-${username}" style="background: #007bff; color: #fff; border: none; padding: 5px 10px; border-radius: 3px;">Set Rank</button> </div> `; }).join(''); content.innerHTML = ` ${playerList || '<p>No players found.</p>'} <div style="margin-top: 10px;"> <textarea id="announce-text" placeholder="Enter announcement" style="width: 100%; height: 60px; margin-bottom: 5px;"></textarea> <button id="send-announce" style="background: #fd7e14; color: #fff; border: none; padding: 5px 10px; border-radius: 3px;">Send Announcement</button> </div> `; Object.keys(players).forEach(username => { document.getElementById(`set-score-${username}`).addEventListener('click', () => { console.log('Set score for:', username); _a1(username); }); document.getElementById(`delete-score-${username}`).addEventListener('click', () => { console.log('Delete score for:', username); _a2(username); }); document.getElementById(`set-rank-${username}`).addEventListener('click', () => { console.log('Set rank for:', username); _a3(username); }); }); document.getElementById('send-announce').addEventListener('click', () => { console.log('Send announcement clicked'); _a4(); }); } else if (tab === 'record') { content.innerHTML = ` <button id="start-record" style="background: #17a2b8; color: #fff; border: none; padding: 5px 10px; border-radius: 3px;">Start Recording</button> <button id="stop-record" style="background: #dc3545; color: #fff; border: none; padding: 5px 10px; border-radius: 3px;" disabled>Stop Recording</button> <button id="send-record" style="background: #28a745; color: #fff; border: none; padding: 5px 10px; border-radius: 3px;" disabled>Send to Discord</button> `; setupRecording(); } else if (tab === 'announcements') { let announceList = announcements.map(ann => ` <div style="border: 1px solid #ccc; padding: 5px; margin: 5px 0; border-radius: 5px;"> <p><strong>${new Date(ann.timestamp).toLocaleString()}</strong></p> <p style="${ann.read ? '' : 'font-weight: bold;'}">${ann.message}</p> </div> `).join(''); content.innerHTML = ` ${announceList || '<p>No announcements.</p>'} <div id="notification-area"></div> `; announcements.forEach(ann => ann.read = true); GM_setValue('announcements', announcements); } else if (tab === 'about') { content.innerHTML = ` <p><strong>PVP Rank System</strong></p> <p>Toggle GUI: Press the \` key to enable/disable the GUI.</p> <p>Created for PVP ranking and recording.</p> `; } } catch (err) { console.error('Error in showTab:', err); } } const _a1 = function(username) { try { console.log('Setting score for:', username); let scoreInput = document.getElementById(`score-set-${username}`); let score = parseInt(scoreInput.value); if (!isNaN(score) && score >= 0) { players[username].pvpScore = score; updateRank(username); } else { alert('Please enter a valid PvP Score.'); } } catch (err) { console.error('Error in _a1:', err); } }; const _a2 = function(username) { try { console.log('Deleting score for:', username); let scoreInput = document.getElementById(`score-delete-${username}`); let score = parseInt(scoreInput.value); if (!isNaN(score) && score >= 0) { players[username].pvpScore = Math.max(0, players[username].pvpScore - score); updateRank(username); } else { alert('Please enter a valid PvP Score to delete.'); } } catch (err) { console.error('Error in _a2:', err); } }; const _a3 = function(username) { try { console.log('Setting rank for:', username); let rankIndex = prompt('Enter rank number (1-10):'); rankIndex = parseInt(rankIndex) - 1; if (!isNaN(rankIndex) && rankIndex >= 0 && rankIndex < RANKS.length) { players[username].rank = RANKS[rankIndex].name; players[username].rankImg = RANKS[rankIndex].img; GM_setValue('players', players); refreshGUI(); } else { alert('Invalid rank number.'); } } catch (err) { console.error('Error in _a3:', err); } }; const _a4 = function() { try { console.log('Sending announcement'); if (!isAdmin) return; let announceInput = document.getElementById('announce-text'); let message = announceInput.value.trim(); if (message) { announcements.push({ message: message, timestamp: Date.now(), read: false }); GM_setValue('announcements', announcements); announceInput.value = ''; showNotification(message); refreshGUI(); alert('Announcement sent!'); } else { alert('Please enter a valid announcement.'); } } catch (err) { console.error('Error in _a4:', err); } }; const _a5 = function() { try { console.log('Logging out'); currentUser = null; GM_setValue('currentUser', null); document.getElementById('rank-gui').remove(); createLoginGUI(); } catch (err) { console.error('Error in _a5:', err); } }; function setupRecording() { try { console.log('Setting up recording'); navigator.mediaDevices.getDisplayMedia({ video: true }).then(stream => { mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = e => recordedChunks.push(e.data); mediaRecorder.onstop = () => { document.getElementById('stop-record').disabled = true; document.getElementById('send-record').disabled = false; console.log('Recording stopped'); }; document.getElementById('start-record').addEventListener('click', () => { console.log('Start recording clicked'); recordedChunks = []; mediaRecorder.start(); document.getElementById('start-record').disabled = true; document.getElementById('stop-record').disabled = false; }); document.getElementById('stop-record').addEventListener('click', () => { console.log('Stop recording clicked'); mediaRecorder.stop(); }); document.getElementById('send-record').addEventListener('click', () => { console.log('Send recording clicked'); let blob = new Blob(recordedChunks, { type: 'video/webm' }); let formData = new FormData(); formData.append('file', blob, `${currentUser}-pvp.webm`); formData.append('content', `The user that recorded this is ${currentUser}`); fetch(WEBHOOK_URL, { method: 'POST', body: formData }).then(() => { alert('Video sent to Discord!'); console.log('Video sent to Discord'); }).catch(err => console.error('Webhook error:', err)); }); }).catch(err => console.error('Recording error:', err)); } catch (err) { console.error('Error in setupRecording:', err); } } document.addEventListener('keydown', e => { try { if (e.key === '`' && document.getElementById('rank-gui')) { guiVisible = !guiVisible; document.getElementById('rank-gui').style.display = guiVisible ? 'block' : 'none'; console.log('GUI toggled, visible:', guiVisible); } } catch (err) { console.error('Error in keydown handler:', err); } }); function initialize() { try { console.log('Initializing script, currentUser:', currentUser); if (!document.body) { console.error('document.body not available, retrying'); setTimeout(initialize, 100); return; } if (!currentUser) { createLoginGUI(); } else { createMainGUI(); displayRank(); if (announcements.some(ann => !ann.read)) { let latestUnread = announcements.filter(ann => !ann.read).pop(); if (latestUnread) { showNotification(latestUnread.message); console.log('Showing unread announcement:', latestUnread.message); } } } } catch (err) { console.error('Error in initialize:', err); } } if (document.readyState === 'loading') { console.log('DOM not ready, waiting for DOMContentLoaded'); document.addEventListener('DOMContentLoaded', initialize); } else { console.log('DOM ready, initializing immediately'); initialize(); } })();