Client/Galaxy-Strike-Online-main/API/routes/servers.js

420 lines
12 KiB
JavaScript

const express = require('express');
const jwt = require('jsonwebtoken');
const GameServer = require('../models/GameServer');
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' });
}
};
// Register new game server (for GameServer instances to register themselves)
router.post('/register', async (req, res) => {
try {
const { serverId, name, type, region, maxPlayers, currentPlayers, gameServerUrl, owner } = req.body;
logger.info(`[API SERVER] Game server registration request:`, {
serverId, name, type, region, maxPlayers, currentPlayers, gameServerUrl, owner
});
// Check if server already exists
const existingServer = await GameServer.findOne({ serverId });
if (existingServer) {
// Update existing server
existingServer.name = name || existingServer.name;
existingServer.type = type || existingServer.type;
existingServer.region = region || existingServer.region;
existingServer.maxPlayers = maxPlayers || existingServer.maxPlayers;
existingServer.currentPlayers = currentPlayers !== undefined ? currentPlayers : existingServer.currentPlayers;
existingServer.gameServerUrl = gameServerUrl || existingServer.gameServerUrl;
existingServer.status = 'waiting';
existingServer.lastActivity = new Date();
await existingServer.save();
logger.info(`[API SERVER] Updated existing server: ${serverId} with ${existingServer.currentPlayers} players`);
return res.json({
success: true,
message: 'Server updated successfully',
server: existingServer
});
}
// Create new server
const newServer = new GameServer({
serverId,
name: name || `Game Server ${serverId}`,
type: type || 'public',
region: region || 'us-east',
maxPlayers: maxPlayers || 10,
currentPlayers: currentPlayers !== undefined ? currentPlayers : 0,
owner: owner || {
userId: 'system',
username: 'System'
},
status: 'waiting',
gameServerUrl,
createdAt: new Date(),
lastActivity: new Date()
});
await newServer.save();
logger.info(`[API SERVER] Registered new server: ${serverId}`);
res.status(201).json({
success: true,
message: 'Server registered successfully',
server: newServer
});
} catch (error) {
logger.error('[API SERVER] Error registering server:', error);
res.status(500).json({
success: false,
error: 'Failed to register server'
});
}
});
// Update server status (for GameServer instances to update their status)
router.post('/update-status/:serverId', async (req, res) => {
try {
const { serverId } = req.params;
const { currentPlayers, status } = req.body;
const server = await GameServer.findOne({ serverId });
if (!server) {
return res.status(404).json({
success: false,
error: 'Server not found'
});
}
if (currentPlayers !== undefined) {
server.currentPlayers = currentPlayers;
}
if (status) {
server.status = status;
}
server.lastActivity = new Date();
await server.save();
logger.info(`[API SERVER] Updated server ${serverId} status:`, {
currentPlayers: server.currentPlayers,
status: server.status
});
res.json({
success: true,
message: 'Server status updated successfully'
});
} catch (error) {
logger.error('[API SERVER] Error updating server status:', error);
res.status(500).json({
success: false,
error: 'Failed to update server status'
});
}
});
// Unregister game server (for GameServer instances to unregister themselves)
router.delete('/unregister/:serverId', async (req, res) => {
try {
const { serverId } = req.params;
logger.info(`[API SERVER] Game server unregistration request:`, { serverId });
// Find and remove server
const server = await GameServer.findOneAndDelete({ serverId });
if (!server) {
return res.status(404).json({
success: false,
error: 'Server not found'
});
}
logger.info(`[API SERVER] Unregistered server: ${serverId}`);
res.json({
success: true,
message: 'Server unregistered successfully'
});
} catch (error) {
logger.error('[API SERVER] Error unregistering server:', error);
res.status(500).json({
success: false,
error: 'Failed to unregister server'
});
}
});
// Get server list
router.get('/', authenticateToken, async (req, res) => {
try {
const { type, region } = req.query;
// Build filters
const filters = {};
if (type) filters.type = type;
if (region) filters.region = region;
logger.info(`[API SERVER] Fetching servers for user ${req.userId} with filters:`, filters);
// Get available servers from database
const servers = await GameServer.findAvailableServers(filters);
logger.info(`[API SERVER] Found ${servers.length} servers in database`);
// Format server list for client
const serverList = servers.map(server => ({
id: server.serverId,
name: server.name,
type: server.type,
region: server.region,
currentPlayers: server.currentPlayers,
maxPlayers: server.maxPlayers,
status: server.status,
ownerName: server.owner.username,
createdAt: server.createdAt,
lastActivity: server.lastActivity
}));
logger.info(`[API SERVER] Returning ${serverList.length} servers to client`);
res.json({
success: true,
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' });
}
// Generate unique server ID
const serverId = `server_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
// Get user info from token (you might want to fetch full user data)
const ownerUsername = req.body.username || 'Unknown'; // This should come from user data
// Create new server in database
const newServer = new GameServer({
serverId,
name,
type,
region,
maxPlayers,
owner: {
userId: req.userId,
username: ownerUsername
},
settings,
gameServerUrl: process.env.GAME_SERVER_URL || 'https://api.korvarix.com'
});
await newServer.save();
logger.info(`Server created: ${serverId} by user ${req.userId}`);
res.status(201).json({
message: 'Server created successfully',
server: {
id: newServer.serverId,
name: newServer.name,
type: newServer.type,
region: newServer.region,
currentPlayers: newServer.currentPlayers,
maxPlayers: newServer.maxPlayers,
status: newServer.status,
ownerName: newServer.owner.username,
createdAt: newServer.createdAt
}
});
} catch (error) {
logger.error('Error creating server:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Join server
router.post('/:serverId/join', authenticateToken, async (req, res) => {
try {
const { serverId } = req.params;
// Find server in database
const server = await GameServer.findOne({ serverId });
if (!server) {
return res.status(404).json({ error: 'Server not found' });
}
// Check if server can be joined
if (!server.canJoin()) {
return res.status(400).json({ error: 'Server is full or offline' });
}
// Add player to server
const playerAdded = server.addPlayer();
if (!playerAdded) {
return res.status(400).json({ error: 'Server is full' });
}
await server.save();
logger.info(`User ${req.userId} joined server ${serverId}`);
res.json({
message: 'Joined server successfully',
server: {
id: server.serverId,
name: server.name,
currentPlayers: server.currentPlayers,
maxPlayers: server.maxPlayers,
gameServerUrl: server.gameServerUrl
}
});
} catch (error) {
logger.error('Error joining server:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Leave server
router.post('/:serverId/leave', authenticateToken, async (req, res) => {
try {
const { serverId } = req.params;
// Find server in database
const server = await GameServer.findOne({ serverId });
if (!server) {
return res.status(404).json({ error: 'Server not found' });
}
// Remove player from server
const playerRemoved = server.removePlayer();
if (playerRemoved) {
await server.save();
logger.info(`User ${req.userId} left server ${serverId}`);
}
// Update player's current server
const Player = require('../models/Player');
await Player.findOneAndUpdate(
{ userId: req.userId },
{ currentServer: null }
);
res.json({
message: 'Left server successfully'
});
} catch (error) {
logger.error('Error leaving server:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Get server details
router.get('/:serverId', authenticateToken, async (req, res) => {
try {
const { serverId } = req.params;
const server = await GameServer.findOne({ serverId });
if (!server) {
return res.status(404).json({ error: 'Server not found' });
}
res.json({
server: {
id: server.serverId,
name: server.name,
type: server.type,
region: server.region,
currentPlayers: server.currentPlayers,
maxPlayers: server.maxPlayers,
status: server.status,
ownerName: server.owner.username,
settings: server.settings,
createdAt: server.createdAt,
lastActivity: server.lastActivity
}
});
} catch (error) {
logger.error('Error getting server details:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Get user's current server
router.get('/user/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 server = await GameServer.findOne({ serverId: player.currentServer });
if (!server) {
// Clear invalid server reference
await Player.findOneAndUpdate(
{ userId: req.userId },
{ currentServer: null }
);
return res.json({ currentServer: null });
}
res.json({
currentServer: {
id: server.serverId,
name: server.name,
currentPlayers: server.currentPlayers,
maxPlayers: server.maxPlayers
}
});
} catch (error) {
logger.error('Error getting current server:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
module.exports = router;