/** * Player list page — table with sort, filter, and kick. */ function PlayerListPage(params, container) { var address = Rcon.getAddress() || ''; var html = '
' + '
' + '
' + '' + '
' + '
' + '' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
ActionsUsernameSteam IDViolation LevelAddressPingDuration
Loading…
' + '
' + '
' + '
' + '
'; container.innerHTML = html; var players = []; var orderBy = '-ConnectedSeconds'; var filterText = ''; function sortPlayers(a, b) { var desc = orderBy[0] === '-'; var field = desc ? orderBy.substring(1) : orderBy; var va = a[field], vb = b[field]; if (typeof va === 'string') va = va.toLowerCase(); if (typeof vb === 'string') vb = vb.toLowerCase(); if (va < vb) return desc ? 1 : -1; if (va > vb) return desc ? -1 : 1; return 0; } function matchesFilter(p) { if (!filterText) return true; var ft = filterText.toLowerCase(); return (p.DisplayName && p.DisplayName.toLowerCase().indexOf(ft) !== -1) || (p.SteamID && p.SteamID.indexOf(ft) !== -1) || (p.Address && p.Address.toLowerCase().indexOf(ft) !== -1); } function render() { var filtered = players.filter(matchesFilter).sort(sortPlayers); var tbody = document.getElementById('player-tbody'); var html = ''; for (var i = 0; i < filtered.length; i++) { var p = filtered[i]; var fadeClass = (p.VoiationLevel === 0) ? ' class="fade"' : ''; html += '' + '' + '
' + '' + '' + '
' + '' + '' + (p.DisplayName || '') + '' + '' + p.SteamID + '' + '' + (p.VoiationLevel || 0) + '' + '' + (p.Address || '') + '' + '' + (p.Ping || 0) + '' + '' + secondsToDuration(p.ConnectedSeconds || 0) + '' + ''; } tbody.innerHTML = html; // Bind kick buttons var kicks = tbody.querySelectorAll('.kick-player'); for (var j = 0; j < kicks.length; j++) { kicks[j].addEventListener('click', function (e) { e.preventDefault(); Rcon.command('kick ' + this.dataset.id); refresh(); }); } } function refresh() { Rcon.getPlayers(function (list) { players = list; render(); }); } function updateSortHeaders() { var headers = document.querySelectorAll('#player-table .sortable'); for (var i = 0; i < headers.length; i++) { headers[i].className = headers[i].className.replace(/sorting(\s+descending)?/g, '').trim(); var field = headers[i].dataset.field; if (orderBy === field) headers[i].className += ' sorting'; else if (orderBy === '-' + field) headers[i].className += ' sorting descending'; } } document.getElementById('player-refresh').addEventListener('click', refresh); document.getElementById('player-filter').addEventListener('input', function () { filterText = this.value; render(); }); // Sort header clicks var sortHeaders = document.querySelectorAll('#player-table .sortable'); for (var k = 0; k < sortHeaders.length; k++) { sortHeaders[k].addEventListener('click', function () { var field = this.dataset.field; orderBy = (orderBy === field) ? '-' + field : field; updateSortHeaders(); render(); }); } if (Rcon.isConnected()) { refresh(); updateSortHeaders(); } else { var _c = function () { refresh(); updateSortHeaders(); Rcon.off('connected', _c); }; Rcon.on('connected', _c); } }