2014-06-04 22:19:54 +00:00
|
|
|
var events = require('events');
|
|
|
|
var fs = require('fs');
|
2014-11-09 18:07:00 +00:00
|
|
|
var gamedig = require('gamedig');
|
2014-09-12 23:51:31 +00:00
|
|
|
var slug = require('slug');
|
2014-06-04 22:19:54 +00:00
|
|
|
var spawn = require('child_process').spawn;
|
2014-02-13 22:47:51 +00:00
|
|
|
|
2014-09-12 23:51:31 +00:00
|
|
|
var ArmaServer = require('arma-server');
|
|
|
|
|
2014-02-13 22:47:51 +00:00
|
|
|
var config = require('./config');
|
2014-04-06 22:10:42 +00:00
|
|
|
var filePath = "servers.json";
|
2015-01-03 02:51:21 +00:00
|
|
|
var queryInterval = 5000;
|
2014-02-13 22:47:51 +00:00
|
|
|
|
2014-09-12 23:51:31 +00:00
|
|
|
var Server = function (options) {
|
|
|
|
this.update(options);
|
2014-06-04 22:19:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Server.prototype = new events.EventEmitter();
|
2014-02-13 22:47:51 +00:00
|
|
|
|
2014-09-12 23:51:31 +00:00
|
|
|
Server.prototype.update = function (options) {
|
|
|
|
this.admin_password = options.admin_password;
|
|
|
|
this.battle_eye = options.battle_eye;
|
|
|
|
this.max_players = options.max_players;
|
2015-01-16 22:09:53 +00:00
|
|
|
this.mods = options.mods || [];
|
2014-09-12 23:51:31 +00:00
|
|
|
this.password = options.password;
|
|
|
|
this.persistent = options.persistent;
|
2015-01-16 22:09:53 +00:00
|
|
|
this.port = options.port || 2302;
|
2014-09-12 23:51:31 +00:00
|
|
|
this.title = options.title;
|
|
|
|
this.von = options.von;
|
|
|
|
|
|
|
|
this.id = slug(this.title).replace('.', '-');
|
2015-01-17 02:40:22 +00:00
|
|
|
this.port = parseInt(this.port, 10); // If port is a string then gamedig fails
|
2014-06-04 22:19:54 +00:00
|
|
|
};
|
2014-02-13 22:47:51 +00:00
|
|
|
|
2014-11-09 18:07:00 +00:00
|
|
|
Server.prototype.queryStatus = function() {
|
|
|
|
var self = this;
|
|
|
|
Gamedig.query(
|
|
|
|
{
|
|
|
|
type: 'arma3',
|
2014-11-24 00:56:31 +00:00
|
|
|
host: '127.0.0.1',
|
2014-11-09 18:07:00 +00:00
|
|
|
port: self.port,
|
|
|
|
},
|
|
|
|
function(state) {
|
|
|
|
if(state.error) {
|
|
|
|
self.state = null;
|
|
|
|
} else {
|
|
|
|
self.state = state;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.emit('state');
|
|
|
|
}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2014-02-13 22:47:51 +00:00
|
|
|
Server.prototype.start = function() {
|
2014-09-12 23:51:31 +00:00
|
|
|
var server = new ArmaServer({
|
|
|
|
battleEye: this.battle_eye ? 1 : 0,
|
|
|
|
config: this.id,
|
2015-01-16 21:50:31 +00:00
|
|
|
disableVoN: this.von ? 0 : 1,
|
2014-09-12 23:51:31 +00:00
|
|
|
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();
|
2014-04-06 22:58:17 +00:00
|
|
|
var self = this;
|
2014-02-13 22:47:51 +00:00
|
|
|
|
2014-11-24 00:56:54 +00:00
|
|
|
instance.stdout.on('data', function (data) {
|
2014-02-13 22:47:51 +00:00
|
|
|
console.log('stdout: ' + data);
|
|
|
|
});
|
|
|
|
|
2014-11-24 00:56:54 +00:00
|
|
|
instance.stderr.on('data', function (data) {
|
2014-02-13 22:47:51 +00:00
|
|
|
console.log('stderr: ' + data);
|
|
|
|
});
|
|
|
|
|
2014-11-24 00:56:54 +00:00
|
|
|
instance.on('close', function (code) {
|
2014-02-13 22:47:51 +00:00
|
|
|
console.log('child process exited with code ' + code);
|
2014-11-09 18:07:00 +00:00
|
|
|
clearInterval(self.queryStatusInterval);
|
|
|
|
self.state = null;
|
2014-04-06 22:58:17 +00:00
|
|
|
self.pid = null;
|
2014-11-24 00:56:54 +00:00
|
|
|
self.instance = null;
|
2014-11-09 18:07:00 +00:00
|
|
|
|
|
|
|
self.emit('state');
|
2014-04-06 22:58:17 +00:00
|
|
|
});
|
|
|
|
|
2014-11-24 00:56:54 +00:00
|
|
|
this.pid = instance.pid;
|
|
|
|
this.instance = instance;
|
2014-11-09 18:07:00 +00:00
|
|
|
this.queryStatusInterval = setInterval(function () {
|
|
|
|
self.queryStatus();
|
|
|
|
}, queryInterval);
|
2014-04-06 22:58:17 +00:00
|
|
|
|
2014-11-09 18:07:00 +00:00
|
|
|
this.emit('state');
|
2014-06-04 22:19:54 +00:00
|
|
|
|
2014-04-06 22:58:17 +00:00
|
|
|
return this;
|
2014-06-04 22:19:54 +00:00
|
|
|
};
|
2014-04-06 22:58:17 +00:00
|
|
|
|
|
|
|
Server.prototype.stop = function(cb) {
|
|
|
|
var handled = false;
|
2014-06-04 22:19:54 +00:00
|
|
|
var self = this;
|
2014-04-06 22:58:17 +00:00
|
|
|
|
2014-11-24 00:56:54 +00:00
|
|
|
this.instance.on('close', function (code) {
|
2014-04-06 22:58:17 +00:00
|
|
|
if (!handled) {
|
|
|
|
handled = true;
|
2014-06-04 23:02:09 +00:00
|
|
|
|
|
|
|
if (cb) {
|
|
|
|
cb();
|
|
|
|
}
|
2014-04-06 22:58:17 +00:00
|
|
|
}
|
2014-02-13 22:47:51 +00:00
|
|
|
});
|
2014-04-06 22:58:17 +00:00
|
|
|
|
2014-11-24 00:56:54 +00:00
|
|
|
this.instance.kill();
|
2014-04-06 22:58:17 +00:00
|
|
|
|
|
|
|
setTimeout(function() {
|
|
|
|
if (!handled) {
|
|
|
|
handled = true;
|
2014-06-04 23:02:09 +00:00
|
|
|
|
|
|
|
if (cb) {
|
|
|
|
cb();
|
|
|
|
}
|
2014-04-06 22:58:17 +00:00
|
|
|
}
|
|
|
|
}, 5000);
|
|
|
|
|
|
|
|
return this;
|
2014-06-04 22:17:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Server.prototype.toJSON = function () {
|
|
|
|
return {
|
2014-09-12 23:51:31 +00:00
|
|
|
admin_password: this.admin_password,
|
|
|
|
battle_eye: this.battle_eye,
|
2014-06-04 22:17:18 +00:00
|
|
|
id: this.id,
|
2014-09-12 23:51:31 +00:00
|
|
|
max_players: this.max_players,
|
2014-06-04 22:17:18 +00:00
|
|
|
mods: this.mods,
|
2014-09-12 23:51:31 +00:00
|
|
|
password: this.password,
|
|
|
|
persistent: this.persistent,
|
2014-06-04 22:17:18 +00:00
|
|
|
pid: this.pid,
|
2014-09-12 23:51:31 +00:00
|
|
|
port: this.port,
|
2014-11-09 18:07:00 +00:00
|
|
|
state: this.state,
|
2014-09-12 23:51:31 +00:00
|
|
|
title: this.title,
|
|
|
|
von: this.von,
|
2014-06-04 22:17:18 +00:00
|
|
|
};
|
|
|
|
};
|
2014-02-13 22:47:51 +00:00
|
|
|
|
2014-06-04 22:19:54 +00:00
|
|
|
var Manager = function () {
|
2014-04-06 21:09:52 +00:00
|
|
|
this.serversArr = [];
|
2014-04-06 22:10:42 +00:00
|
|
|
this.serversHash = {};
|
2014-02-13 22:47:51 +00:00
|
|
|
};
|
|
|
|
|
2014-06-04 22:19:54 +00:00
|
|
|
Manager.prototype = new events.EventEmitter();
|
|
|
|
|
2014-09-12 23:51:31 +00:00
|
|
|
Manager.prototype.addServer = (function (options) {
|
|
|
|
var server = this._addServer(options);
|
2014-04-06 22:10:42 +00:00
|
|
|
this.save();
|
|
|
|
return server;
|
|
|
|
});
|
|
|
|
|
2014-06-04 23:02:09 +00:00
|
|
|
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;
|
|
|
|
});
|
|
|
|
|
2014-09-12 23:51:31 +00:00
|
|
|
Manager.prototype._addServer = (function (data) {
|
|
|
|
var server = new Server(data);
|
2014-04-06 21:09:52 +00:00
|
|
|
this.serversArr.push(server);
|
2014-07-28 17:50:06 +00:00
|
|
|
this.serversArr.sort(function(a, b) {
|
|
|
|
return a.title.localeCompare(b.title);
|
|
|
|
});
|
2014-09-12 23:51:31 +00:00
|
|
|
this.serversHash[server.id] = server;
|
2014-07-28 17:50:06 +00:00
|
|
|
|
2014-06-04 22:19:54 +00:00
|
|
|
var self = this;
|
|
|
|
var statusChanged = function () {
|
|
|
|
self.emit('servers');
|
|
|
|
};
|
2014-11-09 18:07:00 +00:00
|
|
|
server.on('state', statusChanged);
|
2014-06-04 22:19:54 +00:00
|
|
|
|
2014-02-14 01:16:05 +00:00
|
|
|
return server;
|
2014-02-13 22:47:51 +00:00
|
|
|
});
|
|
|
|
|
2014-04-06 21:09:52 +00:00
|
|
|
Manager.prototype.getServer = (function (id) {
|
|
|
|
return this.serversHash[id];
|
|
|
|
});
|
|
|
|
|
|
|
|
Manager.prototype.getServers = (function () {
|
|
|
|
return this.serversArr;
|
|
|
|
});
|
|
|
|
|
2014-04-06 22:10:42 +00:00
|
|
|
Manager.prototype.load = (function () {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
fs.readFile(filePath, function (err, data) {
|
|
|
|
if (err) {
|
|
|
|
console.log(err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-06-04 21:24:48 +00:00
|
|
|
try {
|
|
|
|
JSON.parse(data).forEach(function (server) {
|
2014-09-12 23:51:31 +00:00
|
|
|
self._addServer(server);
|
2014-06-04 21:24:48 +00:00
|
|
|
});
|
|
|
|
} catch(e) {
|
|
|
|
console.error("Manager load error: " + e);
|
|
|
|
}
|
2014-04-06 22:10:42 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
Manager.prototype.save = (function () {
|
2014-04-06 22:58:17 +00:00
|
|
|
var data = [];
|
2014-09-12 23:51:31 +00:00
|
|
|
var self = this;
|
2014-04-06 22:58:17 +00:00
|
|
|
|
2014-09-12 23:51:31 +00:00
|
|
|
this.serversHash = {};
|
2014-04-06 22:58:17 +00:00
|
|
|
this.serversArr.forEach(function (server) {
|
|
|
|
data.push({
|
2014-09-12 23:51:31 +00:00
|
|
|
admin_password: server.admin_password,
|
|
|
|
battle_eye: server.battle_eye,
|
|
|
|
max_players: server.max_players,
|
2014-04-06 22:58:17 +00:00
|
|
|
mods: server.mods,
|
2014-09-12 23:51:31 +00:00
|
|
|
password: server.password,
|
|
|
|
persistent: server.persistent,
|
|
|
|
port: server.port,
|
|
|
|
title: server.title,
|
|
|
|
von: server.von,
|
2014-06-04 22:19:54 +00:00
|
|
|
});
|
2014-04-06 22:58:17 +00:00
|
|
|
|
2014-09-12 23:51:31 +00:00
|
|
|
self.serversHash[server.id] = server;
|
|
|
|
});
|
2014-06-04 22:19:54 +00:00
|
|
|
|
2014-04-06 22:58:17 +00:00
|
|
|
fs.writeFile(filePath, JSON.stringify(data), function(err) {
|
2014-06-04 22:19:54 +00:00
|
|
|
if (err) {
|
|
|
|
throw err;
|
|
|
|
} else {
|
|
|
|
self.emit('servers');
|
|
|
|
}
|
2014-04-06 22:10:42 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2014-06-04 22:19:29 +00:00
|
|
|
var manager = new Manager();
|
|
|
|
manager.load();
|
|
|
|
|
|
|
|
module.exports = manager;
|