const mongoose = require('mongoose'); const gameServerSchema = new mongoose.Schema({ serverId: { type: String, required: true, unique: true }, name: { type: String, required: true }, type: { type: String, enum: ['public', 'private'], default: 'public' }, region: { type: String, default: 'us-east' }, maxPlayers: { type: Number, default: 10, min: 1, max: 100 }, currentPlayers: { type: Number, default: 0 }, owner: { userId: { type: String, required: true }, username: { type: String, required: true } }, settings: { password: { type: String, default: null }, description: { type: String, default: '' }, tags: [{ type: String }] }, status: { type: String, enum: ['waiting', 'active', 'full', 'offline'], default: 'waiting' }, gameServerUrl: { type: String, default: null }, createdAt: { type: Date, default: Date.now }, lastActivity: { type: Date, default: Date.now } }, { timestamps: true }); // Indexes for performance (only for non-unique fields) gameServerSchema.index({ type: 1 }); gameServerSchema.index({ region: 1 }); gameServerSchema.index({ status: 1 }); gameServerSchema.index({ 'owner.userId': 1 }); // Methods gameServerSchema.methods.addPlayer = function() { if (this.currentPlayers < this.maxPlayers) { this.currentPlayers += 1; this.lastActivity = new Date(); if (this.currentPlayers >= this.maxPlayers) { this.status = 'full'; } else if (this.currentPlayers > 0) { this.status = 'active'; } return true; } return false; }; gameServerSchema.methods.removePlayer = function() { if (this.currentPlayers > 0) { this.currentPlayers -= 1; this.lastActivity = new Date(); if (this.currentPlayers === 0) { this.status = 'waiting'; } else if (this.currentPlayers < this.maxPlayers) { this.status = 'active'; } return true; } return false; }; gameServerSchema.methods.isFull = function() { return this.currentPlayers >= this.maxPlayers; }; gameServerSchema.methods.canJoin = function() { return this.status !== 'offline' && !this.isFull(); }; // Static methods gameServerSchema.statics.findAvailableServers = function(filters = {}) { const query = { status: { $ne: 'offline' } }; if (filters.type) { query.type = filters.type; } if (filters.region) { query.region = filters.region; } return this.find(query).sort({ lastActivity: -1 }); }; gameServerSchema.statics.cleanupOldServers = function(maxAge = 24 * 60 * 60 * 1000) { // 24 hours const cutoffTime = new Date(Date.now() - maxAge); return this.deleteMany({ $or: [ { lastActivity: { $lt: cutoffTime }, currentPlayers: 0 }, { status: 'offline', lastActivity: { $lt: cutoffTime } } ] }); }; module.exports = mongoose.model('GameServer', gameServerSchema);