420 lines
12 KiB
JavaScript
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;
|