Show server state and players currently connected

This commit is contained in:
Björn Dahlgren 2014-11-09 19:07:00 +01:00
parent d42b5bd0f9
commit 9cb1a912b1
8 changed files with 129 additions and 8 deletions

View File

@ -1,9 +1,12 @@
var events = require('events');
var fs = require('fs');
var gamedig = require('gamedig');
var ip = require('ip');
var spawn = require('child_process').spawn;
var config = require('./config');
var filePath = "servers.json";
var queryInterval = 10000;
var Server = function (id, title, port, mods) {
this.id = id;
@ -41,6 +44,26 @@ Server.prototype.makePortParameter = function() {
return '-port=' + this.port;
};
Server.prototype.queryStatus = function() {
var self = this;
Gamedig.query(
{
type: 'arma3',
host: ip.address(),
port: self.port,
},
function(state) {
if(state.error) {
self.state = null;
} else {
self.state = state;
}
self.emit('state');
}
);
};
Server.prototype.start = function() {
var startParams = [];
var gamePath = this.armaServerPath();
@ -75,14 +98,21 @@ Server.prototype.start = function() {
process.on('close', function (code) {
console.log('child process exited with code ' + code);
clearInterval(self.queryStatusInterval);
self.state = null;
self.pid = null;
self.process = null;
self.emit('state');
});
this.pid = process.pid;
this.process = process;
this.queryStatusInterval = setInterval(function () {
self.queryStatus();
}, queryInterval);
this.emit('started');
this.emit('state');
return this;
};
@ -94,7 +124,6 @@ Server.prototype.stop = function(cb) {
this.process.on('close', function (code) {
if (!handled) {
handled = true;
self.emit('stopped');
if (cb) {
cb();
@ -107,7 +136,6 @@ Server.prototype.stop = function(cb) {
setTimeout(function() {
if (!handled) {
handled = true;
self.emit('stopped');
if (cb) {
cb();
@ -125,6 +153,7 @@ Server.prototype.toJSON = function () {
port: this.port,
mods: this.mods,
pid: this.pid,
state: this.state,
};
};
@ -177,8 +206,7 @@ Manager.prototype._addServer = (function (id, title, port, mods) {
var statusChanged = function () {
self.emit('servers');
};
server.on('started', statusChanged);
server.on('stopped', statusChanged);
server.on('state', statusChanged);
return server;
});

View File

@ -10,6 +10,8 @@
"async": "^0.9.0",
"express": "3.x",
"express-resource": "~1.0.0",
"gamedig": "^0.2.11",
"ip": "^0.3.2",
"playwithsix": "0.0.6",
"slug": "~0.4.0",
"socket.io": "^1.0.4",

View File

@ -8,7 +8,8 @@ define(function (require) {
return Backbone.Model.extend({
defaults: {
title: ''
title: '',
state: null,
},
urlRoot: '/api/servers/',
});

View File

@ -0,0 +1,22 @@
define(function (require) {
"use strict";
var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
Marionette = require('marionette'),
tpl = require('text!tpl/servers/players.html');
return Marionette.Layout.extend({
template: _.template(tpl),
templateHelpers: {
players: function(){
return _.sortBy(this.state.players, function (player) {
return player.name;
});
}
},
});
});

View File

@ -9,6 +9,7 @@ define(function (require) {
Mods = require('app/collections/mods'),
InfoView = require('app/views/servers/info'),
ModsListView = require('app/views/servers/mods/list'),
PlayersView = require('app/views/servers/players'),
tpl = require('text!tpl/servers/view.html');
return Marionette.Layout.extend({
@ -17,7 +18,8 @@ define(function (require) {
regions: {
infoView: "#tab-info",
modsView: "#tab-mods",
settings: "#tab-settings"
playersView: "#tab-players",
settings: "#tab-settings",
},
events: {
@ -35,11 +37,13 @@ define(function (require) {
onRender: function() {
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}));
},
serverUpdated: function() {
this.infoView.currentView.render();
this.modsView.currentView.render();
this.playersView.currentView.render();
},
tabs: function(e) {

View File

@ -4,7 +4,12 @@
<div class="col-sm-11">
<p class="form-control-static">
<% if (typeof(pid) != "undefined" && pid) { %>
<span class="label label-success">Online</span>
<% if (state) { %>
<span class="label label-success">Online</span>
<% } else { %>
<span class="label label-info">Launching</span>
<% } %>
<a class="btn btn-primary btn-xs" href="#" id="stop">
<span class="glyphicon glyphicon-stop"></span>
Stop
@ -33,4 +38,38 @@
<p class="form-control-static"><%- mods %></p>
</div>
</div>
<% if (state) { %>
<div class="form-group">
<label class="col-sm-1 control-label">Name</label>
<div class="col-sm-11">
<p class="form-control-static"><%= state.name %></p>
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label">Map</label>
<div class="col-sm-11">
<p class="form-control-static"><%= state.map %></p>
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label">Mission</label>
<div class="col-sm-11">
<p class="form-control-static"><%= state.raw.game %></p>
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label">Players</label>
<div class="col-sm-11">
<p class="form-control-static">
<%= state.players.length %> / <%= state.maxplayers %>
</p>
</div>
</div>
<% } %>
</form>

View File

@ -0,0 +1,23 @@
<% if (state) { %>
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Score</th>
</tr>
</thead>
<tbody>
<% _.each(players(), function(player) { %>
<tr>
<td><%= player.name %></td>
<td><%= player.score %></td>
</tr>
<% }); %>
</tbody>
</table>
<% } else { %>
<tr>
<td>Server not online</td>
<td>&nbsp;</td>
</tr>
<% } %>

View File

@ -4,6 +4,7 @@
<ul class="nav nav-tabs" style="margin-bottom: 15px;">
<li class="active"><a href="#tab-info" data-toggle="tab">Info</a></li>
<li><a href="#tab-mods" data-toggle="tab">Mods</a></li>
<li><a href="#tab-players" data-toggle="tab">Players</a></li>
<li><a href="#tab-settings" data-toggle="tab">Settings</a></li>
</ul>
@ -11,5 +12,6 @@
<div class="tab-content">
<div class="tab-pane active" id="tab-info"></div>
<div class="tab-pane" id="tab-mods"></div>
<div class="tab-pane" id="tab-players"></div>
<div class="tab-pane" id="tab-settings"></div>
</div>