Files
rust-rcon/js/pages/playerInfo.js
T
angryzeroandCopilot 7386e9f8cb fix: player info page shows 'not connected' for online players
SteamID from RCON JSON is parsed as a Number, but the URL param
from the regex match is a string. Strict === comparison always fails.
Changed to String() coercion so types match.

Also fixes subtle issue with large SteamID64 values exceeding
MAX_SAFE_INTEGER — string comparison avoids precision loss.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-13 18:48:29 +02:00

71 lines
2.6 KiB
JavaScript

/**
* Player info page — single player detail with quirk fixes.
*/
function PlayerInfoPage(params, container) {
var userid = params[2]; // SteamID from URL
var html =
'<div id="PlayerInfoController">' +
'<div class="row">' +
'<div class="col-lg-12">' +
'<h2 class="text-center">' +
'Player: <span id="pi-username">' + userid + '</span>' +
'<button id="pi-refresh" class="btn btn-secondary float-end" type="button"><i class="bi bi-arrow-clockwise"></i></button>' +
'</h2>' +
'<div class="d-grid mb-3">' +
'<a href="http://www.steamcommunity.com/profiles/' + userid + '" target="_blank" class="btn btn-secondary">' +
'<i class="bi bi-info-circle-fill"></i> Steam Profile' +
'</a>' +
'</div>' +
'</div>' +
'<div class="col-lg-12">' +
'<h2 class="text-center">Info</h2>' +
'<div id="pi-notfound" class="alert alert-warning" style="display:none">This Player is currently not connected to this server!</div>' +
'</div>' +
'<div id="pi-fields" class="col-sm-12"><span class="text-white-50">Loading…</span></div>' +
'</div>' +
'</div>';
container.innerHTML = html;
function refresh() {
Rcon.getPlayers(function (players) {
var info = null;
for (var i = 0; i < players.length; i++) {
if (String(players[i].SteamID) === userid) { info = players[i]; break; }
}
if (!info) {
document.getElementById('pi-notfound').style.display = 'block';
document.getElementById('pi-fields').innerHTML = '';
return;
}
document.getElementById('pi-notfound').style.display = 'none';
// 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;
document.getElementById('pi-username').textContent = info.DisplayName || userid;
var fieldsHtml = '';
for (var key in info) {
if (info.hasOwnProperty(key)) {
fieldsHtml += '<div class="col-sm-4"><p>' + key + ': <span class="badge">' + info[key] + '</span></p></div>';
}
}
document.getElementById('pi-fields').innerHTML = fieldsHtml;
});
}
document.getElementById('pi-refresh').addEventListener('click', refresh);
if (Rcon.isConnected()) refresh();
else { var _c = function () { refresh(); Rcon.off('connected', _c); }; Rcon.on('connected', _c); }
}