135 lines
2.9 KiB
JavaScript
135 lines
2.9 KiB
JavaScript
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);
|