adding support for playerlist info
This commit is contained in:
parent
4c88546d35
commit
8977cccbff
@ -5,96 +5,131 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>UNLOZE Server Status</title>
|
||||
<style>
|
||||
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #121212; color: #e0e0e0; padding: 20px; }
|
||||
body { font-family: 'Segoe UI', sans-serif; background: #121212; color: #e0e0e0; padding: 20px; margin: 0; }
|
||||
.container { max-width: 900px; margin: auto; }
|
||||
h1 { border-bottom: 2px solid #444; padding-bottom: 10px; color: #fff; }
|
||||
|
||||
.server-card {
|
||||
background: #1e1e1e;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
margin-bottom: 15px;
|
||||
border-left: 5px solid #00ff41; /* Green accent */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
transition: transform 0.2s;
|
||||
margin-bottom: 10px;
|
||||
border-left: 5px solid #00ff41;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.server-card:hover { transform: translateX(5px); background: #252525; }
|
||||
|
||||
.card-header { display: flex; justify-content: space-between; align-items: center; cursor: pointer; }
|
||||
|
||||
.info-main { flex-grow: 1; }
|
||||
.server-name { font-weight: bold; font-size: 1.1em; color: #00ff41; margin-bottom: 5px; }
|
||||
.server-name { font-weight: bold; font-size: 1.1em; color: #00ff41; }
|
||||
.server-sub { font-size: 0.9em; color: #aaa; }
|
||||
|
||||
.stats { text-align: right; min-width: 120px; }
|
||||
.players { font-size: 1.2em; font-weight: bold; color: #fff; }
|
||||
.stats { text-align: right; min-width: 100px; margin-right: 15px; }
|
||||
.players-count { font-size: 1.2em; font-weight: bold; color: #fff; }
|
||||
|
||||
.btn-connect {
|
||||
background: #00ff41;
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
padding: 8px 15px;
|
||||
border-radius: 4px;
|
||||
font-weight: bold;
|
||||
font-size: 0.8em;
|
||||
margin-left: 20px;
|
||||
background: #00ff41; color: #000; text-decoration: none;
|
||||
padding: 8px 15px; border-radius: 4px; font-weight: bold; font-size: 0.8em;
|
||||
}
|
||||
.btn-connect:hover { background: #00cc33; }
|
||||
|
||||
/* Player List Styling */
|
||||
.player-list-container {
|
||||
display: none; /* Hidden by default */
|
||||
margin-top: 15px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #333;
|
||||
}
|
||||
|
||||
.player-table { width: 100%; border-collapse: collapse; font-size: 0.85em; }
|
||||
.player-table th { text-align: left; color: #00ff41; padding-bottom: 5px; border-bottom: 1px solid #333; }
|
||||
.player-table td { padding: 5px 0; border-bottom: 1px solid #252525; }
|
||||
|
||||
.duration { color: #888; font-style: italic; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<h1>UNLOZE Server Info</h1>
|
||||
<div id="server-list">Loading servers...</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function loadServers() {
|
||||
try {
|
||||
const response = await fetch('servers.json');
|
||||
const data = await response.json();
|
||||
|
||||
const listContainer = document.getElementById('server-list');
|
||||
listContainer.innerHTML = '';
|
||||
|
||||
data.forEach(server => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'server-card';
|
||||
card.innerHTML = `
|
||||
<div class="info-main">
|
||||
<div class="server-name">${server.name}</div>
|
||||
<div class="server-sub">Map: <strong>${server.map}</strong></div>
|
||||
</div>
|
||||
<div class="stats">
|
||||
<div class="players">${server.players}</div>
|
||||
<div class="server-sub">${server.ip}</div>
|
||||
</div>
|
||||
<a href="steam://connect/${server.ip}" class="btn-connect">CONNECT</a>
|
||||
`;
|
||||
listContainer.appendChild(card);
|
||||
});
|
||||
|
||||
// --- ADD THIS LINE HERE ---
|
||||
// Tell the parent XenForo page to resize now that the content is actually here
|
||||
sendHeight();
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error loading JSON:', error);
|
||||
document.getElementById('server-list').innerText = 'Failed to load server data.';
|
||||
function formatTime(seconds) {
|
||||
const h = Math.floor(seconds / 3600);
|
||||
const m = Math.floor((seconds % 3600) / 60);
|
||||
return h > 0 ? `${h}h ${m}m` : `${m}m`;
|
||||
}
|
||||
}
|
||||
|
||||
function sendHeight() {
|
||||
// Add a little buffer (e.g., + 20) to ensure nothing is clipped
|
||||
const height = document.body.scrollHeight + 20;
|
||||
window.parent.postMessage({ type: 'setHeight', height: height }, '*');
|
||||
}
|
||||
function togglePlayers(id) {
|
||||
const el = document.getElementById(`players-${id}`);
|
||||
el.style.display = el.style.display === 'block' ? 'none' : 'block';
|
||||
sendHeight(); // Recalculate iframe height when expanding
|
||||
}
|
||||
|
||||
// Initial load
|
||||
loadServers();
|
||||
// Refresh every 30s
|
||||
setInterval(loadServers, 30000);
|
||||
async function loadServers() {
|
||||
try {
|
||||
const response = await fetch('servers.json');
|
||||
const data = await response.json();
|
||||
const listContainer = document.getElementById('server-list');
|
||||
listContainer.innerHTML = '';
|
||||
|
||||
data.forEach((server, index) => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'server-card';
|
||||
|
||||
// Build Player Table rows
|
||||
let playerRows = '';
|
||||
if (server.player_infos && server.player_infos.length > 0) {
|
||||
server.player_infos.forEach(p => {
|
||||
playerRows += `
|
||||
<tr>
|
||||
<td>${p.name}</td>
|
||||
<td>${p.score}</td>
|
||||
<td class="duration">${formatTime(p.duration)}</td>
|
||||
</tr>`;
|
||||
});
|
||||
} else {
|
||||
playerRows = '<tr><td colspan="3" style="text-align:center; padding:10px;">No players online</td></tr>';
|
||||
}
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="card-header" onclick="togglePlayers(${index})">
|
||||
<div class="info-main">
|
||||
<div class="server-name">${server.name}</div>
|
||||
<div class="server-sub">Map: <strong>${server.map}</strong></div>
|
||||
<div class="server-sub" style="color: #00ff41; font-family: monospace; margin-top: 4px;">
|
||||
IP: ${server.ip}
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats">
|
||||
<div class="players-count">${server.players}</div>
|
||||
<div class="server-sub">Players Online</div>
|
||||
</div>
|
||||
<a href="steam://connect/${server.ip}" class="btn-connect" onclick="event.stopPropagation()">CONNECT</a>
|
||||
</div>
|
||||
<div class="player-list-container" id="players-${index}">
|
||||
<table class="player-table">
|
||||
<thead>
|
||||
<tr><th>Player Name</th><th>Score</th><th>Time</th></tr>
|
||||
</thead>
|
||||
<tbody>${playerRows}</tbody>
|
||||
</table>
|
||||
</div>
|
||||
`;
|
||||
listContainer.appendChild(card);
|
||||
});
|
||||
sendHeight();
|
||||
} catch (error) {
|
||||
console.error('Error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function sendHeight() {
|
||||
const height = document.body.scrollHeight + 40;
|
||||
window.parent.postMessage({ type: 'setHeight', height: height }, '*');
|
||||
}
|
||||
|
||||
loadServers();
|
||||
setInterval(loadServers, 30000);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
@ -2,5 +2,6 @@ flask
|
||||
flask_cors
|
||||
waitress
|
||||
werkzeug
|
||||
python-a2s
|
||||
|
||||
python app.py
|
||||
|
||||
@ -1,17 +1,37 @@
|
||||
#!/home/nonroot/update_xenforo_server_info/venv/bin/python3
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
from flask_cors import CORS
|
||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||
import traceback
|
||||
import json
|
||||
from pprint import pprint
|
||||
from settings import ips, file_path
|
||||
|
||||
app = Flask(__name__)
|
||||
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1)
|
||||
#!/home/nonroot/update_xenforo_server_info/venv/bin/python3
|
||||
from flask import Flask
|
||||
from flask import request
|
||||
from flask_cors import CORS
|
||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||
import traceback
|
||||
import json
|
||||
from pprint import pprint
|
||||
import a2s
|
||||
from settings import ips, file_path
|
||||
|
||||
app = Flask(__name__)
|
||||
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1)
|
||||
CORS(app)
|
||||
|
||||
#AI slop
|
||||
def get_player_list(ip, port):
|
||||
address = (ip, int(port))
|
||||
try:
|
||||
# Get player information
|
||||
players = a2s.players(address)
|
||||
|
||||
player_data = []
|
||||
for p in players:
|
||||
player_data.append({
|
||||
"name": p.name,
|
||||
"score": p.score,
|
||||
"duration": p.duration # Seconds they've been online
|
||||
})
|
||||
return player_data
|
||||
except Exception as e:
|
||||
print(f"Error querying server: {e}")
|
||||
return []
|
||||
|
||||
#nginx used for reserve proxy
|
||||
@app.route('/', methods = ['POST'])
|
||||
def get_server_info():
|
||||
@ -30,7 +50,8 @@ def get_server_info():
|
||||
map_ = server.split("**")[1].split(" ")[0]
|
||||
players = server.split("(")[1].split(")")[0]
|
||||
ip = server.split("\n[")[1].split("]")[0]
|
||||
j = {"name": name, "map": map_, "players": players, "ip": ip}
|
||||
d = get_player_list(ip.split(":")[0], ip.split(":")[1])
|
||||
j = {"name": name, "map": map_, "players": players, "ip": ip, "player_infos": d}
|
||||
new_j.append(j)
|
||||
|
||||
#print(new_j)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user