const express = require('express'); const jwt = require('jsonwebtoken'); const { getGameSystem } = require('../systems/GameSystem'); const logger = require('../utils/logger'); const router = express.Router(); // Middleware to authenticate JWT token const authenticateToken = (req, res, next) => { const token = req.header('Authorization')?.replace('Bearer ', ''); if (!token) { return res.status(401).json({ error: 'Access token required' }); } try { const decoded = jwt.verify(token, process.env.JWT_SECRET || 'fallback_secret'); req.userId = decoded.userId; next(); } catch (error) { res.status(401).json({ error: 'Invalid token' }); } }; // Get server list router.get('/', authenticateToken, async (req, res) => { try { const gameSystem = getGameSystem(); const serverList = gameSystem.getServerList(); res.json({ servers: serverList, totalServers: serverList.length }); } catch (error) { logger.error('Error getting server list:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Create new server router.post('/create', authenticateToken, async (req, res) => { try { const { name, type = 'public', maxPlayers = 10, region = 'us-east', settings = {} } = req.body; if (!name) { return res.status(400).json({ error: 'Server name required' }); } if (name.length < 3 || name.length > 50) { return res.status(400).json({ error: 'Server name must be between 3 and 50 characters' }); } const gameSystem = getGameSystem(); const serverData = { name, type, maxPlayers, region, settings, ownerId: req.userId, ownerName: req.username || 'Unknown' }; const server = await gameSystem.createServer(serverData); // Auto-join the creator to the server await gameSystem.joinServer(server.id, req.userId); logger.info(`Server created: ${server.id} by user ${req.userId}`); res.status(201).json({ message: 'Server created successfully', server: { id: server.id, name: server.name, type: server.type, maxPlayers: server.maxPlayers, currentPlayers: server.players.length, region: server.region, status: server.status, ownerId: server.ownerId, createdAt: server.createdAt } }); } catch (error) { logger.error('Error creating server:', error); res.status(500).json({ error: error.message }); } }); // Join server router.post('/:serverId/join', authenticateToken, async (req, res) => { try { const { serverId } = req.params; const { password } = req.body; // For private servers if (!serverId) { return res.status(400).json({ error: 'Server ID required' }); } const gameSystem = getGameSystem(); const server = await gameSystem.joinServer(serverId, req.userId); // Update player's current server const Player = require('../models/Player'); await Player.findOneAndUpdate( { userId: req.userId }, { currentServer: serverId } ); logger.info(`User ${req.userId} joined server ${serverId}`); res.json({ message: 'Joined server successfully', server: { id: server.id, name: server.name, type: server.type, maxPlayers: server.maxPlayers, currentPlayers: server.players.length, region: server.region } }); } catch (error) { logger.error('Error joining server:', error); res.status(500).json({ error: error.message }); } }); // Leave server router.post('/:serverId/leave', authenticateToken, async (req, res) => { try { const { serverId } = req.params; if (!serverId) { return res.status(400).json({ error: 'Server ID required' }); } const gameSystem = getGameSystem(); const server = await gameSystem.leaveServer(serverId, req.userId); // Update player's current server const Player = require('../models/Player'); await Player.findOneAndUpdate( { userId: req.userId }, { currentServer: null } ); logger.info(`User ${req.userId} left server ${serverId}`); res.json({ message: 'Left server successfully', server: server || null }); } catch (error) { logger.error('Error leaving server:', error); res.status(500).json({ error: error.message }); } }); // Get server details router.get('/:serverId', authenticateToken, async (req, res) => { try { const { serverId } = req.params; if (!serverId) { return res.status(400).json({ error: 'Server ID required' }); } const gameSystem = getGameSystem(); const server = gameSystem.servers.get(serverId); if (!server) { return res.status(404).json({ error: 'Server not found' }); } // Get player details for all players in the server const Player = require('../models/Player'); const players = await Player.find({ userId: { $in: server.players } }).select('userId username info stats'); res.json({ server: { id: server.id, name: server.name, type: server.type, maxPlayers: server.maxPlayers, currentPlayers: server.players.length, region: server.region, status: server.status, ownerId: server.ownerId, createdAt: server.createdAt, settings: server.settings }, players: players.map(player => ({ userId: player.userId, username: player.username, level: player.stats.level, title: player.info.title, rank: player.info.rank })) }); } catch (error) { logger.error('Error getting server details:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Get user's current server router.get('/current', authenticateToken, async (req, res) => { try { const Player = require('../models/Player'); const player = await Player.findOne({ userId: req.userId }); if (!player || !player.currentServer) { return res.json({ currentServer: null }); } const gameSystem = getGameSystem(); const server = gameSystem.servers.get(player.currentServer); if (!server) { // Clear the invalid server reference player.currentServer = null; await player.save(); return res.json({ currentServer: null }); } res.json({ currentServer: { id: server.id, name: server.name, type: server.type, maxPlayers: server.maxPlayers, currentPlayers: server.players.length, region: server.region, status: server.status } }); } catch (error) { logger.error('Error getting current server:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Update server settings (owner only) router.put('/:serverId/settings', authenticateToken, async (req, res) => { try { const { serverId } = req.params; const { settings } = req.body; if (!serverId) { return res.status(400).json({ error: 'Server ID required' }); } const gameSystem = getGameSystem(); const server = gameSystem.servers.get(serverId); if (!server) { return res.status(404).json({ error: 'Server not found' }); } // Check if user is the server owner if (server.ownerId !== req.userId) { return res.status(403).json({ error: 'Only server owner can update settings' }); } // Update server settings server.settings = { ...server.settings, ...settings }; logger.info(`Server settings updated: ${serverId} by user ${req.userId}`); res.json({ message: 'Server settings updated successfully', settings: server.settings }); } catch (error) { logger.error('Error updating server settings:', error); res.status(500).json({ error: 'Internal server error' }); } }); // Delete server (owner only) router.delete('/:serverId', authenticateToken, async (req, res) => { try { const { serverId } = req.params; if (!serverId) { return res.status(400).json({ error: 'Server ID required' }); } const gameSystem = getGameSystem(); const server = gameSystem.servers.get(serverId); if (!server) { return res.status(404).json({ error: 'Server not found' }); } // Check if user is the server owner if (server.ownerId !== req.userId) { return res.status(403).json({ error: 'Only server owner can delete server' }); } // Remove all players from the server for (const playerId of server.players) { await gameSystem.leaveServer(serverId, playerId); // Update player's current server const Player = require('../models/Player'); await Player.findOneAndUpdate( { userId: playerId }, { currentServer: null } ); } // Delete the server gameSystem.servers.delete(serverId); logger.info(`Server deleted: ${serverId} by user ${req.userId}`); res.json({ message: 'Server deleted successfully' }); } catch (error) { logger.error('Error deleting server:', error); res.status(500).json({ error: 'Internal server error' }); } }); module.exports = router;