Change server config from manager. Uses new WIP arma-server module.

This commit is contained in:
Björn Dahlgren 2014-09-13 01:51:31 +02:00
parent e788973490
commit fbeb956361
12 changed files with 208 additions and 125 deletions

View File

@ -1,46 +1,33 @@
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 = 10000;
var Server = function (id, title, port, mods) {
this.id = id;
this.title = title;
this.port = port;
this.mods = mods;
var Server = function (options) {
this.update(options);
};
Server.prototype = new events.EventEmitter();
Server.prototype.armaServerPath = function() {
if (config.type === "linux") {
return config.path + '/arma3server';
}
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.title = options.title;
this.von = options.von;
return config.path + '/arma3server.exe';
};
Server.prototype.makeModsParameter = function() {
var mods = this.mods;
["@a3mp", "@a3mp_ap", "@agm"].forEach(function (modToMoveLast) {
if (mods.indexOf(modToMoveLast) > -1) {
mods = mods.filter(function (mod) {
return mod != modToMoveLast;
});
mods.push(modToMoveLast);
}
});
return '-mod=' + mods.join(';');
};
Server.prototype.makePortParameter = function() {
return '-port=' + this.port;
this.id = slug(this.title).replace('.', '-');
this.port = 2302;
};
Server.prototype.queryStatus = function() {
@ -64,35 +51,22 @@ Server.prototype.queryStatus = function() {
};
Server.prototype.start = function() {
var startParams = [];
var gamePath = this.armaServerPath();
var options = null;
if (config.type === "linux") {
options = {
cwd: config.path,
env: process.env,
};
}
if (config.type === "wine") {
gamePath = "wine";
startParams.push(this.armaServerPath());
}
startParams.push(this.makePortParameter());
startParams.push('-config=server.cfg');
startParams.push('-noSound');
startParams.push('-world=empty');
if (this.mods.length) {
startParams.push(this.makeModsParameter());
}
console.log(gamePath);
console.log(startParams);
var instance = spawn(gamePath, startParams, options);
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) {
@ -155,12 +129,18 @@ Server.prototype.stop = function(cb) {
Server.prototype.toJSON = function () {
return {
admin_password: this.admin_password,
battle_eye: this.battle_eye,
id: this.id,
title: this.title,
port: this.port,
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,
};
};
@ -171,10 +151,8 @@ var Manager = function () {
Manager.prototype = new events.EventEmitter();
Manager.prototype.addServer = (function (id, title) {
mods = [];
port = 2302;
var server = this._addServer(id, title, port, mods);
Manager.prototype.addServer = (function (options) {
var server = this._addServer(options);
this.save();
return server;
});
@ -190,7 +168,6 @@ Manager.prototype.removeServer = (function (id) {
if (index > -1) {
this.serversArr.splice(index, 1);
}
delete this.serversHash[id];
this.save();
if (server.pid) {
@ -200,14 +177,13 @@ Manager.prototype.removeServer = (function (id) {
return server;
});
Manager.prototype._addServer = (function (id, title, port, mods) {
var server = new Server(id, title, port, mods);
Manager.prototype._addServer = (function (data) {
var server = new Server(data);
this.serversArr.push(server);
this.serversHash[id] = server;
this.serversArr.sort(function(a, b) {
return a.title.localeCompare(b.title);
});
this.serversHash[server.id] = server;
var self = this;
var statusChanged = function () {
@ -237,7 +213,7 @@ Manager.prototype.load = (function () {
try {
JSON.parse(data).forEach(function (server) {
self._addServer(server.id, server.title, server.port, server.mods);
self._addServer(server);
});
} catch(e) {
console.error("Manager load error: " + e);
@ -247,17 +223,24 @@ Manager.prototype.load = (function () {
Manager.prototype.save = (function () {
var data = [];
var self = this;
this.serversHash = {};
this.serversArr.forEach(function (server) {
data.push({
id: server.id,
title: server.title,
port: server.port,
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,
});
});
var self = this;
self.serversHash[server.id] = server;
});
fs.writeFile(filePath, JSON.stringify(data), function(err) {
if (err) {

View File

@ -7,6 +7,7 @@
"start": "node app.js"
},
"dependencies": {
"arma-server": "git+https://github.com/Dahlgren/node-arma-server.git",
"async": "^0.9.0",
"express": "3.x",
"express-resource": "~1.0.0",

View File

@ -8,8 +8,15 @@ define(function (require) {
return Backbone.Model.extend({
defaults: {
title: '',
admin_password: '',
battle_eye: false,
max_players: null,
mods: [],
password: '',
persistent: false,
state: null,
title: '',
von: false,
},
urlRoot: '/api/servers/',
});

View File

@ -7,22 +7,32 @@ define(function (require) {
Backbone = require('backbone'),
Marionette = require('marionette'),
FormView = require('marionette-formview'),
Server = require('app/models/server'),
tpl = require('text!tpl/servers/add.html');
tpl = require('text!tpl/servers/form.html');
return Marionette.ItemView.extend({
template: _.template(tpl),
initialize: function (options) {
this.servers = options.servers;
this.model = new Server();
this.bind("ok", this.submit);
},
serialize : function() {
return {
admin_password: this.$("form .admin-password").val(),
battle_eye: this.$("form .battle-eye").prop("checked"),
max_players: this.$("form .max-players").val(),
password: this.$("form .password").val(),
persistent: this.$("form .persistent").prop("checked"),
title: this.$("form .title").val(),
von: this.$("form .von").prop("checked"),
};
},
submit: function (modal) {
modal.preventClose();
this.model.set('title', $("form #title").val());
this.model.set(this.serialize());
var self = this;

View File

@ -6,7 +6,8 @@ define(function (require) {
_ = require('underscore'),
Backbone = require('backbone'),
Marionette = require('marionette'),
AddServerView = require('app/views/servers/add'),
Server = require('app/models/server'),
AddServerView = require('app/views/servers/form'),
EmptyView = require('app/views/servers/empty'),
ListItemView = require('app/views/servers/list_item'),
tpl = require('text!tpl/servers/list.html'),
@ -39,7 +40,7 @@ define(function (require) {
},
addServer: function () {
var view = new AddServerView({servers: this.collection});
var view = new AddServerView({model: new Server(), servers: this.collection});
new Backbone.BootstrapModal({ content: view, servers: this.collection }).open()
},
});

View File

@ -15,24 +15,18 @@ define(function (require) {
itemView: ListItemView,
template: _.template(tpl),
events: {
"submit": "save",
},
buildItemView: function(item, ItemViewType, itemViewOptions){
var options = _.extend({model: item, server: this.options.server}, itemViewOptions);
var view = new ItemViewType(options);
return view;
},
save: function (event) {
event.preventDefault();
var enabledMods = $('input:checkbox:checked').map(function (idx, el) {
return $(el).val();
}).get();
this.options.server.set('mods', enabledMods);
this.options.server.save();
serialize: function() {
return {
mods: this.$('input:checkbox:checked').map(function (idx, el) {
return $(el).val();
}).get(),
}
},
});

View File

@ -7,6 +7,7 @@ define(function (require) {
Backbone = require('backbone'),
Marionette = require('marionette'),
Mods = require('app/collections/mods'),
FormView = require('app/views/servers/form'),
InfoView = require('app/views/servers/info'),
ModsListView = require('app/views/servers/mods/list'),
PlayersView = require('app/views/servers/players'),
@ -19,11 +20,12 @@ define(function (require) {
infoView: "#tab-info",
modsView: "#tab-mods",
playersView: "#tab-players",
settings: "#tab-settings",
settingsView: "#tab-settings",
},
events: {
"click .nav-tabs a" : "tabs",
"submit": "save",
},
modelEvents: {
@ -38,17 +40,40 @@ define(function (require) {
this.infoView.show(new InfoView({model: this.model}));
this.modsView.show(new ModsListView({collection: this.mods, server: this.model}));
this.playersView.show(new PlayersView({model: this.model}));
this.settingsView.show(new FormView({model: this.model}));
},
serverUpdated: function() {
this.infoView.currentView.render();
this.modsView.currentView.render();
this.playersView.currentView.render();
this.settingsView.currentView.render();
},
save: function (e) {
e.preventDefault();
var self = this;
var oldId = this.model.get('id');
var data = this.settingsView.currentView.serialize();
_.extend(data, this.modsView.currentView.serialize());
this.model.save(data, {
success: function() {
var newId = self.model.get('id');
if (oldId != newId) {
Backbone.history.navigate('#servers/' + newId, true);
} else {
self.serverUpdated();
}
},
error: function() {
alert("Error :(");
}
});
},
tabs: function(e) {
e.preventDefault()
$($(e.target).attr('href')).tab('show')
e.preventDefault();
$($(e.target).attr('href')).tab('show');
},
});

View File

@ -1,8 +0,0 @@
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="title" class="col-sm-2 control-label">Title</label>
<div class="col-sm-10">
<input type="text" class="form-control title" data-field="title" id="title" placeholder="Title">
</div>
</div>
</form>

View File

@ -0,0 +1,59 @@
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="title" class="col-sm-2 control-label">Title</label>
<div class="col-sm-10">
<input type="text" class="form-control title" data-field="title" placeholder="Title" value="<%- title %>">
</div>
</div>
<div class="form-group">
<label for="max-players" class="col-sm-2 control-label">Max Players</label>
<div class="col-sm-10">
<input type="number" class="form-control max-players" data-field="max-players" placeholder="Max Players" value="<%- max_players %>">
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="text" class="form-control password" data-field="password" placeholder="Password" value="<%- password %>">
</div>
</div>
<div class="form-group">
<label for="admin-password" class="col-sm-2 control-label">Admin Password</label>
<div class="col-sm-10">
<input type="text" class="form-control admin-password" data-field="admin-password" placeholder="Admin Password" value="<%- admin_password %>">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label>
<input type="checkbox" class="battle-eye" <% if (battle_eye) { %>checked="checked"<% } %>> BattleEye
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label>
<input type="checkbox" class="persistent" <% if (persistent) { %>checked="checked"<% } %>> Persistent
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label>
<input type="checkbox" class="von" <% if (von) { %>checked="checked"<% } %>> Voice over Net
</label>
</div>
</div>
</div>
</form>

View File

@ -9,6 +9,4 @@
<!-- want to insert collection items, here -->
<tbody></tbody>
</table>
<button class="btn btn-default btn-primary" type="submit">Save</button>
</form>

View File

@ -1,5 +1,9 @@
<h2><%-title%></h2>
<form>
<button class="btn btn-default btn-primary pull-right" type="submit">Save</button>
</form>
<!-- Nav tabs -->
<ul class="nav nav-tabs" style="margin-bottom: 15px;">
<li class="active"><a href="#tab-info" data-toggle="tab">Info</a></li>

View File

@ -1,5 +1,4 @@
var playwithsix = require('playwithsix');
var slug = require('slug');
var manager = require('./../manager');
@ -15,6 +14,21 @@ function removeDuplicates(mods) {
},[]);
}
function resolveMods(server, cb) {
var modsToResolve = server.mods.filter(function(mod) {
return !isPlayWithSixIgnoredMod(mod);
});
playwithsix.resolveDependencies(modsToResolve, function (err, mods) {
if (!err && mods) {
server.mods = removeDuplicates(server.mods.concat(mods));
manager.save();
}
cb(err);
});
}
exports.index = function (req, res){
var servers = [];
@ -32,9 +46,14 @@ exports.index = function (req, res){
};
exports.create = function (req, res){
var title = req.body.title;
var id = slug(title);
res.send(manager.addServer(id, title));
var server = manager.addServer(req.body);
if (server.mods.length > 0) {
resolveMods(server, function(err) {
res.send(server);
});
} else {
res.send(server);
}
};
exports.show = function (req, res){
@ -44,21 +63,11 @@ exports.show = function (req, res){
exports.update = function(req, res){
var server = manager.getServer(req.params.server);
server.update(req.body);
manager.save();
if (req.body.mods) {
server.mods = req.body.mods;
manager.save();
var modsToResolve = server.mods.filter(function(mod) {
return !isPlayWithSixIgnoredMod(mod);
});
playwithsix.resolveDependencies(modsToResolve, function (err, mods) {
if (!err && mods) {
server.mods = removeDuplicates(server.mods.concat(mods));
manager.save();
}
if (server.mods.length > 0) {
resolveMods(server, function(err) {
res.send(server);
});
} else {