/** * Player info page — single player detail with quirk fixes. */ function PlayerInfoPage(params, container) { var userid = params[2]; // SteamID from URL var html = '
' + '
' + '
' + '

' + 'Player: ' + userid + '' + '' + '

' + '
' + '' + ' Steam Profile' + '' + '' + '' + '
' + '
' + '
' + '' + '
' + '
' + '
Loading…
' + '
' + '' + '
' + '
'; container.innerHTML = html; function refresh() { Rcon.getPlayers(function (players) { // Guard against navigation away while waiting for RCON response var nf = document.getElementById('pi-notfound'); var fields = document.getElementById('pi-fields'); var actions = document.getElementById('pi-actions'); if (!nf || !fields || !actions) return; var info = null; for (var i = 0; i < players.length; i++) { if (String(players[i].SteamID) === userid) { info = players[i]; break; } } if (!info) { nf.style.display = 'block'; fields.innerHTML = ''; actions.style.display = 'none'; return; } nf.style.display = 'none'; actions.style.display = 'block'; // Fix known Rust RCON quirk: VoiationLevel → ViolationLevel if (info.VoiationLevel !== undefined) { info.ViolationLevel = info.VoiationLevel; delete info.VoiationLevel; } // Remove XP remnants delete info.CurrentLevel; delete info.UnspentXp; var un = document.getElementById('pi-username'); if (un) un.textContent = info.DisplayName || userid; var fieldsHtml = ''; for (var key in info) { if (info.hasOwnProperty(key)) { var value = info[key]; if (key === 'Address') { value = maskIp(value); } else if (typeof value === 'object' && value !== null) { // e.g. Position: {x, y, z} value = 'x:' + (value.x || 0).toFixed(1) + ' y:' + (value.y || 0).toFixed(1) + ' z:' + (value.z || 0).toFixed(1); } fieldsHtml += '

' + key + ': ' + value + '

'; } } fields.innerHTML = fieldsHtml; }); } document.getElementById('pi-refresh').addEventListener('click', refresh); document.getElementById('pi-kick').addEventListener('click', function () { if (confirm('Kick player ' + (document.getElementById('pi-username').textContent) + '?')) { Rcon.command('kick ' + userid); } }); document.getElementById('pi-ban').addEventListener('click', function () { var reason = prompt('Ban reason:', ''); if (reason !== null) { Rcon.command('ban ' + userid + ' ' + (reason || 'No reason')); } }); var pname = document.getElementById('pi-username'); document.getElementById('pi-kill').addEventListener('click', function () { if (confirm('Kill ' + pname.textContent + '?')) { Rcon.command('global.kill ' + userid); } }); document.getElementById('pi-heal').addEventListener('click', function () { if (confirm('Heal ' + pname.textContent + '?')) { Rcon.command('heal ' + userid); } }); document.getElementById('pi-give').addEventListener('click', function () { var item = prompt('Item shortname (e.g. wood, rifle.ak):', ''); if (!item) return; var amount = prompt('Amount (default 1):', '1'); if (amount === null) return; Rcon.command('inventory.giveto ' + userid + ' ' + item.trim() + ' ' + (parseInt(amount) || 1)); }); document.getElementById('pi-teleport').addEventListener('click', function () { var target = prompt('Teleport ' + pname.textContent + ' to SteamID:', ''); if (target) { Rcon.command('entity.teleport ' + userid + ' ' + target.trim()); } }); // ---- Quick rewards ---- document.getElementById('pi-scrap').addEventListener('click', function () { Rcon.command('inventory.giveto ' + userid + ' scrap 500'); }); document.getElementById('pi-airdrop').addEventListener('click', function () { Rcon.command('inventory.giveto ' + userid + ' supply.signal 1'); }); document.getElementById('pi-sniper').addEventListener('click', function () { Rcon.command('inventory.giveto ' + userid + ' l96.weapon 1'); }); document.getElementById('pi-medkit').addEventListener('click', function () { Rcon.command('inventory.giveto ' + userid + ' large.medkit 3'); }); document.getElementById('pi-lootreset').addEventListener('click', function () { if (confirm('Respawn all loot crates and barrels across the entire map?')) { Rcon.command('server.fill_groups'); } }); document.getElementById('pi-mod').addEventListener('click', function () { if (confirm('Promote ' + pname.textContent + ' to Moderator?')) { Rcon.command('moderatorid ' + userid + ' ' + pname.textContent); } }); document.getElementById('pi-owner').addEventListener('click', function () { if (confirm('Promote ' + pname.textContent + ' to Owner?')) { Rcon.command('ownerid ' + userid + ' ' + pname.textContent); } }); if (Rcon.isConnected()) refresh(); else { var _c = function () { refresh(); Rcon.off('connected', _c); }; Rcon.on('connected', _c); } }