arma-server-web-admin/manager.js
2015-01-17 03:40:22 +01:00

259 lines
5.2 KiB
JavaScript

var events = require('events');
var fs = require('fs');
var gamedig = require('gamedig');
var slug = require('slug');
var spawn = require('child_process').spawn;
var ArmaServer = require('arma-server');
var config = require('./config');
var filePath = "servers.json";
var queryInterval = 5000;
var Server = function (options) {
this.update(options);
};
Server.prototype = new events.EventEmitter();
Server.prototype.update = function (options) {
this.admin_password = options.admin_password;
this.battle_eye = options.battle_eye;
this.max_players = options.max_players;
this.mods = options.mods || [];
this.password = options.password;
this.persistent = options.persistent;
this.port = options.port || 2302;
this.title = options.title;
this.von = options.von;
this.id = slug(this.title).replace('.', '-');
this.port = parseInt(this.port, 10); // If port is a string then gamedig fails
};
Server.prototype.queryStatus = function() {
var self = this;
Gamedig.query(
{
type: 'arma3',
host: '127.0.0.1',
port: self.port,
},
function(state) {
if(state.error) {
self.state = null;
} else {
self.state = state;
}
self.emit('state');
}
);
};
Server.prototype.start = function() {
var server = new ArmaServer({
battleEye: this.battle_eye ? 1 : 0,
config: this.id,
disableVoN: this.von ? 0 : 1,
hostname: this.title,
mods: this.mods,
password: this.password,
passwordAdmin: this.admin_password,
path: config.path,
persistent: this.persistent ? 1 : 0,
platform: config.type,
players: this.max_players,
port: this.port,
});
server.writeServerConfig();
var instance = server.start();
var self = this;
instance.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
instance.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
instance.on('close', function (code) {
console.log('child process exited with code ' + code);
clearInterval(self.queryStatusInterval);
self.state = null;
self.pid = null;
self.instance = null;
self.emit('state');
});
this.pid = instance.pid;
this.instance = instance;
this.queryStatusInterval = setInterval(function () {
self.queryStatus();
}, queryInterval);
this.emit('state');
return this;
};
Server.prototype.stop = function(cb) {
var handled = false;
var self = this;
this.instance.on('close', function (code) {
if (!handled) {
handled = true;
if (cb) {
cb();
}
}
});
this.instance.kill();
setTimeout(function() {
if (!handled) {
handled = true;
if (cb) {
cb();
}
}
}, 5000);
return this;
};
Server.prototype.toJSON = function () {
return {
admin_password: this.admin_password,
battle_eye: this.battle_eye,
id: this.id,
max_players: this.max_players,
mods: this.mods,
password: this.password,
persistent: this.persistent,
pid: this.pid,
port: this.port,
state: this.state,
title: this.title,
von: this.von,
};
};
var Manager = function () {
this.serversArr = [];
this.serversHash = {};
};
Manager.prototype = new events.EventEmitter();
Manager.prototype.addServer = (function (options) {
var server = this._addServer(options);
this.save();
return server;
});
Manager.prototype.removeServer = (function (id) {
var server = this.serversHash[id];
if (!server) {
return {};
}
var index = this.serversArr.indexOf(server);
if (index > -1) {
this.serversArr.splice(index, 1);
}
this.save();
if (server.pid) {
server.stop();
}
return server;
});
Manager.prototype._addServer = (function (data) {
var server = new Server(data);
this.serversArr.push(server);
this.serversArr.sort(function(a, b) {
return a.title.localeCompare(b.title);
});
this.serversHash[server.id] = server;
var self = this;
var statusChanged = function () {
self.emit('servers');
};
server.on('state', statusChanged);
return server;
});
Manager.prototype.getServer = (function (id) {
return this.serversHash[id];
});
Manager.prototype.getServers = (function () {
return this.serversArr;
});
Manager.prototype.load = (function () {
var self = this;
fs.readFile(filePath, function (err, data) {
if (err) {
console.log(err);
return;
}
try {
JSON.parse(data).forEach(function (server) {
self._addServer(server);
});
} catch(e) {
console.error("Manager load error: " + e);
}
});
});
Manager.prototype.save = (function () {
var data = [];
var self = this;
this.serversHash = {};
this.serversArr.forEach(function (server) {
data.push({
admin_password: server.admin_password,
battle_eye: server.battle_eye,
max_players: server.max_players,
mods: server.mods,
password: server.password,
persistent: server.persistent,
port: server.port,
title: server.title,
von: server.von,
});
self.serversHash[server.id] = server;
});
fs.writeFile(filePath, JSON.stringify(data), function(err) {
if (err) {
throw err;
} else {
self.emit('servers');
}
});
});
var manager = new Manager();
manager.load();
module.exports = manager;