From 7a8b0672aac23e07a65974ad275501a4486e1df6 Mon Sep 17 00:00:00 2001 From: Robert MacRae Date: Sat, 24 Jan 2026 22:01:08 -0400 Subject: [PATCH] fixed server list --- API/server.js | 73 ++++++++++++++++++++++++++++++++++++++++++++ GameServer/server.js | 49 +++++++++++++++++++++++------ 2 files changed, 112 insertions(+), 10 deletions(-) diff --git a/API/server.js b/API/server.js index fdc3062..7a61cd7 100644 --- a/API/server.js +++ b/API/server.js @@ -11,6 +11,7 @@ const connectDB = require('./config/database'); const authRoutes = require('./routes/auth'); const serverRoutes = require('./routes/servers'); const { errorHandler, notFound } = require('./middleware/errorHandler'); +const GameServer = require('./models/GameServer'); // Override console.error to properly log error objects const originalConsoleError = console.error; @@ -70,6 +71,17 @@ app.use('/api/', async (req, res, next) => { app.use('/api/auth', authRoutes); app.use('/api/servers', serverRoutes); +// Manual cleanup endpoint (for testing) +app.post('/api/admin/cleanup-dead-servers', async (req, res) => { + try { + await cleanupDeadServers(); + res.json({ success: true, message: 'Dead server cleanup completed' }); + } catch (error) { + logger.error('Manual cleanup error:', error); + res.status(500).json({ success: false, error: 'Cleanup failed' }); + } +}); + // Health check app.get('/health', (req, res) => { res.status(200).json({ @@ -114,6 +126,64 @@ app.get('*', (req, res) => { app.use(notFound); app.use(errorHandler); +// Clean up dead servers +async function cleanupDeadServers() { + try { + logger.info('[API SERVER] Starting dead server cleanup...'); + + // Find servers that haven't been updated in the last 5 minutes + const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000); + + const deadServers = await GameServer.find({ + lastActivity: { $lt: fiveMinutesAgo } + }); + + if (deadServers.length > 0) { + logger.info(`[API SERVER] Found ${deadServers.length} potentially dead servers, checking...`); + + for (const server of deadServers) { + const isAlive = await checkServerHealth(server.gameServerUrl); + + if (!isAlive) { + logger.info(`[API SERVER] Removing dead server: ${server.name} (${server.serverId})`); + await GameServer.deleteOne({ _id: server._id }); + } else { + logger.info(`[API SERVER] Server ${server.name} is still alive, updating lastActivity`); + server.lastActivity = new Date(); + await server.save(); + } + } + } else { + logger.info('[API SERVER] No dead servers found'); + } + + } catch (error) { + logger.error('[API SERVER] Error during dead server cleanup:', error); + } +} + +// Check if a server is healthy +async function checkServerHealth(serverUrl) { + try { + if (!serverUrl) { + return false; + } + + // Add /health endpoint to the URL + const healthUrl = serverUrl.endsWith('/') ? `${serverUrl}health` : `${serverUrl}/health`; + + const response = await fetch(healthUrl, { + method: 'GET', + timeout: 5000 // 5 second timeout + }); + + return response.ok; + } catch (error) { + logger.warn(`[API SERVER] Health check failed for ${serverUrl}:`, error.message); + return false; + } +} + // Initialize database only (no game systems for API server) async function startServer() { try { @@ -126,6 +196,9 @@ async function startServer() { server.listen(PORT, () => { logger.info(`API Server running on port ${PORT}`); logger.info('API Server handles: Authentication, Server Browser, User Data'); + + // Start dead server cleanup (every 2 minutes) + setInterval(cleanupDeadServers, 120000); }); } catch (error) { logger.error('Failed to start API server:', error); diff --git a/GameServer/server.js b/GameServer/server.js index 64a4c11..b3e67f9 100644 --- a/GameServer/server.js +++ b/GameServer/server.js @@ -117,6 +117,9 @@ io.on('connection', (socket) => { instanceId: null }); + // Update player count on API server when new player connects + updatePlayerCountOnAPI(); + // Authentication (similar to LocalServer) socket.on('authenticate', (data) => { console.log('[GAME SERVER] Authenticating client:', socket.id, data); @@ -246,19 +249,42 @@ io.on('connection', (socket) => { } connectedClients.delete(socket.id); - }); - - // Welcome message (similar to LocalServer) - socket.emit('welcome', { - message: 'Connected to game server', - serverInfo: { - mode: 'multiplayer', - activeInstances: gameInstances.size, - timestamp: new Date().toISOString() - } + + // Update player count on API server + updatePlayerCountOnAPI(); }); }); +// Update player count on API server +async function updatePlayerCountOnAPI() { + try { + const apiServerUrl = 'http://localhost:3001'; + const currentPlayers = connectedClients.size; + + console.log(`[GAME SERVER] Updating player count: ${currentPlayers} players`); + + const response = await fetch(`${apiServerUrl}/api/servers/update-status/devgame-server-3002`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + currentPlayers: currentPlayers, + status: currentPlayers > 0 ? 'active' : 'waiting' + }) + }); + + if (response.ok) { + const result = await response.json(); + console.log(`[GAME SERVER] Player count updated:`, result); + } else { + console.error(`[GAME SERVER] Failed to update player count: ${response.status}`); + } + } catch (error) { + console.error('[GAME SERVER] Error updating player count:', error); + } +} + // Start server const PORT = process.env.PORT || 3002; @@ -273,6 +299,9 @@ async function startServer() { // Register with API server await registerWithAPIServer(); + + // Start periodic player count updates + setInterval(updatePlayerCountOnAPI, 30000); // Update every 30 seconds }); } catch (error) { console.error('[GAME SERVER] Failed to start server:', error);