Lint and format all backend code with standard.js

This commit is contained in:
Björn Dahlgren 2017-08-24 11:15:06 +02:00
parent f919f32bf3
commit 853a79546a
16 changed files with 555 additions and 546 deletions

View File

@ -11,3 +11,6 @@ node_js:
- "0.10" - "0.10"
before_install: before_install:
- cp config.js.example config.js - cp config.js.example config.js
script:
- npm run lint
- npm test

78
app.js
View File

@ -1,60 +1,60 @@
var express = require('express'); var express = require('express')
var basicAuth = require('express-basic-auth') var basicAuth = require('express-basic-auth')
var bodyParser = require('body-parser'); var bodyParser = require('body-parser')
var morgan = require('morgan'); var morgan = require('morgan')
var path = require('path'); var path = require('path')
var serveStatic = require('serve-static') var serveStatic = require('serve-static')
var config = require('./config'); var config = require('./config')
var Manager = require('./lib/manager'); var Manager = require('./lib/manager')
var Missions = require('./lib/missions'); var Missions = require('./lib/missions')
var Mods = require('./lib/mods'); var Mods = require('./lib/mods')
var Logs = require('./lib/logs'); var Logs = require('./lib/logs')
var app = express(); var app = express()
var server = require('http').Server(app); var server = require('http').Server(app)
var io = require('socket.io')(server); var io = require('socket.io')(server)
if (config.auth && config.auth.username && config.auth.password) { if (config.auth && config.auth.username && config.auth.password) {
var basicAuthUsers = {} var basicAuthUsers = {}
basicAuthUsers[config.auth.username] = config.auth.password; basicAuthUsers[config.auth.username] = config.auth.password
app.use(basicAuth({ app.use(basicAuth({
challenge: true, challenge: true,
users: basicAuthUsers users: basicAuthUsers
})); }))
} }
app.use(bodyParser.json()); app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.urlencoded({ extended: false }))
app.use(morgan('dev')); app.use(morgan('dev'))
app.use(serveStatic(path.join(__dirname, 'public'))); app.use(serveStatic(path.join(__dirname, 'public')))
var logs = new Logs(config); var logs = new Logs(config)
var manager = new Manager(config, logs); var manager = new Manager(config, logs)
manager.load(); manager.load()
var missions = new Missions(config); var missions = new Missions(config)
var mods = new Mods(config); var mods = new Mods(config)
mods.updateMods(); mods.updateMods()
app.use('/api/logs', require('./routes/logs')(logs)); app.use('/api/logs', require('./routes/logs')(logs))
app.use('/api/missions', require('./routes/missions')(missions)); app.use('/api/missions', require('./routes/missions')(missions))
app.use('/api/mods', require('./routes/mods')(mods)); app.use('/api/mods', require('./routes/mods')(mods))
app.use('/api/servers', require('./routes/servers')(manager, mods)); app.use('/api/servers', require('./routes/servers')(manager, mods))
app.use('/api/settings', require('./routes/settings')(config)); app.use('/api/settings', require('./routes/settings')(config))
io.on('connection', function (socket) { io.on('connection', function (socket) {
socket.emit('mods', mods.mods); socket.emit('mods', mods.mods)
socket.emit('servers', manager.getServers()); socket.emit('servers', manager.getServers())
}); })
mods.on('mods', function(mods) { mods.on('mods', function (mods) {
io.emit('mods', mods); io.emit('mods', mods)
}); })
manager.on('servers', function() { manager.on('servers', function () {
io.emit('servers', manager.getServers()); io.emit('servers', manager.getServers())
}); })
server.listen(config.port,config.host); server.listen(config.port, config.host)

View File

@ -1,96 +1,96 @@
var async = require('async'); var async = require('async')
var fs = require('fs.extra'); var fs = require('fs.extra')
var path = require('path'); var path = require('path')
var userhome = require('userhome'); var userhome = require('userhome')
var Logs = function (config) { var Logs = function (config) {
this.config = config; this.config = config
if (this.config.type === 'linux') { if (this.config.type === 'linux') {
fs.mkdirp(this.logsPath()); fs.mkdirp(this.logsPath())
} }
}; }
Logs.generateLogFileName = function () { Logs.generateLogFileName = function () {
var dateStr = new Date().toISOString(). var dateStr = new Date().toISOString()
replace(/:/g, '-'). // Replace time dividers with dash .replace(/:/g, '-') // Replace time dividers with dash
replace(/T/, '_'). // Remove date and time divider .replace(/T/, '_') // Remove date and time divider
replace(/\..+/, ''); // Remove milliseconds .replace(/\..+/, '') // Remove milliseconds
return 'arma3server_' + dateStr + '.log'; return 'arma3server_' + dateStr + '.log'
}; }
Logs.prototype.generateLogFilePath = function () { Logs.prototype.generateLogFilePath = function () {
return path.join(this.logsPath(), Logs.generateLogFileName()); return path.join(this.logsPath(), Logs.generateLogFileName())
}; }
Logs.prototype.logsPath = function () { Logs.prototype.logsPath = function () {
if (this.config.type === 'linux') { if (this.config.type === 'linux') {
return path.join(this.config.path, 'logs'); return path.join(this.config.path, 'logs')
} }
if (this.config.type === 'windows') { if (this.config.type === 'windows') {
return userhome('AppData', 'Local', 'Arma 3'); return userhome('AppData', 'Local', 'Arma 3')
} }
if (this.config.type === 'wine') { if (this.config.type === 'wine') {
var username = process.env.USER; var username = process.env.USER
return userhome('.wine', 'drive_c', 'users', username, 'Local Settings', 'Application Data', 'Arma 3'); return userhome('.wine', 'drive_c', 'users', username, 'Local Settings', 'Application Data', 'Arma 3')
} }
return null; return null
}; }
Logs.prototype.logFiles = function (callback) { Logs.prototype.logFiles = function (callback) {
var directory = this.logsPath(); var directory = this.logsPath()
if (directory === null) { if (directory === null) {
callback(null, []); callback(null, [])
} }
fs.readdir(directory, function (err, files) { fs.readdir(directory, function (err, files) {
if (err) { if (err) {
callback (err); callback(err)
return; return
} }
files = files.map(function (file) { files = files.map(function (file) {
return { return {
name: file, name: file,
path: path.join(directory, file), path: path.join(directory, file)
}; }
}); })
async.filter(files, function(file, cb) { async.filter(files, function (file, cb) {
fs.stat(file.path, function (err, stat) { fs.stat(file.path, function (err, stat) {
file.size = stat.size; file.size = stat.size
cb(!err && stat.isFile()); cb(!err && stat.isFile())
}); })
}, function (files) { }, function (files) {
files.sort(function (a, b) { files.sort(function (a, b) {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase()); return a.name.toLowerCase().localeCompare(b.name.toLowerCase())
}); })
callback(null, files); callback(null, files)
}); })
}); })
}; }
Logs.prototype.getLogFile = function (filename, callback) { Logs.prototype.getLogFile = function (filename, callback) {
this.logFiles(function (err, files) { this.logFiles(function (err, files) {
if (err) { if (err) {
callback(err); callback(err)
} else { } else {
var validLogs = files.filter(function (file) { var validLogs = files.filter(function (file) {
return file.name === filename; return file.name === filename
}); })
if (validLogs.length > 0) { if (validLogs.length > 0) {
callback(null, validLogs[0]); callback(null, validLogs[0])
} else { } else {
callback(null, null); callback(null, null)
} }
} }
}); })
}; }
module.exports = Logs; module.exports = Logs

View File

@ -1,104 +1,104 @@
var events = require('events'); var events = require('events')
var fs = require('fs'); var fs = require('fs')
var Server = require('./server'); var Server = require('./server')
var filePath = "servers.json"; var filePath = 'servers.json'
var Manager = function (config, logs) { var Manager = function (config, logs) {
this.config = config; this.config = config
this.logs = logs; this.logs = logs
this.serversArr = []; this.serversArr = []
this.serversHash = {}; this.serversHash = {}
}; }
Manager.prototype = new events.EventEmitter(); Manager.prototype = new events.EventEmitter()
Manager.prototype.addServer = (function (options) { Manager.prototype.addServer = function (options) {
var server = this._addServer(options); var server = this._addServer(options)
this.save(); this.save()
return server; return server
}); }
Manager.prototype.removeServer = (function (id) { Manager.prototype.removeServer = function (id) {
var server = this.serversHash[id]; var server = this.serversHash[id]
if (!server) { if (!server) {
return {}; return {}
} }
var index = this.serversArr.indexOf(server); var index = this.serversArr.indexOf(server)
if (index > -1) { if (index > -1) {
this.serversArr.splice(index, 1); this.serversArr.splice(index, 1)
} }
this.save(); this.save()
if (server.pid) { if (server.pid) {
server.stop(); server.stop()
} }
return server; return server
}); }
Manager.prototype._addServer = (function (data) { Manager.prototype._addServer = function (data) {
var server = new Server(this.config, this.logs, data); var server = new Server(this.config, this.logs, data)
this.serversArr.push(server); this.serversArr.push(server)
this.serversArr.sort(function(a, b) { this.serversArr.sort(function (a, b) {
return a.title.localeCompare(b.title); return a.title.localeCompare(b.title)
}); })
this.serversHash[server.id] = server; this.serversHash[server.id] = server
var self = this; var self = this
var statusChanged = function () { var statusChanged = function () {
self.emit('servers'); self.emit('servers')
}; }
server.on('state', statusChanged); server.on('state', statusChanged)
return server; return server
}); }
Manager.prototype.getServer = (function (id) { Manager.prototype.getServer = function (id) {
return this.serversHash[id]; return this.serversHash[id]
}); }
Manager.prototype.getServers = (function () { Manager.prototype.getServers = function () {
return this.serversArr; return this.serversArr
}); }
Manager.prototype.load = (function () { Manager.prototype.load = function () {
var self = this; var self = this
fs.readFile(filePath, function (err, data) { fs.readFile(filePath, function (err, data) {
if (err) { if (err) {
console.log("Could not load any existing servers configuration, starting fresh"); console.log('Could not load any existing servers configuration, starting fresh')
return; return
} }
try { try {
JSON.parse(data).forEach(function (server) { JSON.parse(data).forEach(function (server) {
self._addServer(server); self._addServer(server)
}); })
} catch(e) { } catch (e) {
console.error("Manager load error: " + e); console.error('Manager load error: ' + e)
} }
self.getServers().map(function (server) { self.getServers().map(function (server) {
if (server.auto_start) { if (server.auto_start) {
server.start(); server.start()
} }
}); })
}); })
}); }
Manager.prototype.save = (function () { Manager.prototype.save = function () {
var data = []; var data = []
var self = this; var self = this
this.serversArr.sort(function (a, b) { this.serversArr.sort(function (a, b) {
return a.title.toLowerCase().localeCompare(b.title.toLowerCase()); return a.title.toLowerCase().localeCompare(b.title.toLowerCase())
}); })
this.serversHash = {}; this.serversHash = {}
this.serversArr.forEach(function (server) { this.serversArr.forEach(function (server) {
data.push({ data.push({
admin_password: server.admin_password, admin_password: server.admin_password,
@ -114,19 +114,19 @@ Manager.prototype.save = (function () {
port: server.port, port: server.port,
title: server.title, title: server.title,
von: server.von, von: server.von,
verify_signatures: server.verify_signatures, verify_signatures: server.verify_signatures
}); })
self.serversHash[server.id] = server; self.serversHash[server.id] = server
}); })
fs.writeFile(filePath, JSON.stringify(data), function(err) { fs.writeFile(filePath, JSON.stringify(data), function (err) {
if (err) { if (err) {
throw err; throw err
} else { } else {
self.emit('servers'); self.emit('servers')
} }
}); })
}); }
module.exports = Manager; module.exports = Manager

View File

@ -1,32 +1,32 @@
var async = require('async'); var async = require('async')
var filesize = require('filesize'); var filesize = require('filesize')
var fs = require ('fs.extra'); var fs = require('fs.extra')
var path = require('path'); var path = require('path')
var SteamWorkshop = require('steam-workshop'); var SteamWorkshop = require('steam-workshop')
var Missions = function (config) { var Missions = function (config) {
this.config = config; this.config = config
this.steamWorkshop = new SteamWorkshop(this.missionsPath()); this.steamWorkshop = new SteamWorkshop(this.missionsPath())
};
Missions.prototype.missionsPath = function() {
return path.join(this.config.path, 'mpmissions');
};
Missions.prototype.missionPath = function (name) {
return path.join(this.missionsPath(), name);
} }
Missions.prototype.list = function (cb){ Missions.prototype.missionsPath = function () {
var self = this; return path.join(this.config.path, 'mpmissions')
}
Missions.prototype.missionPath = function (name) {
return path.join(this.missionsPath(), name)
}
Missions.prototype.list = function (cb) {
var self = this
fs.readdir(this.missionsPath(), function (err, files) { fs.readdir(this.missionsPath(), function (err, files) {
if (err) { if (err) {
cb(err); cb(err)
} else { } else {
async.map(files, function (filename, cb) { async.map(files, function (filename, cb) {
fs.stat(self.missionPath(filename), function (err, stat) { fs.stat(self.missionPath(filename), function (err, stat) {
if (err) { if (err) {
cb(err); cb(err)
} }
cb(null, { cb(null, {
@ -34,35 +34,35 @@ Missions.prototype.list = function (cb){
dateModified: new Date(stat.mtime), dateModified: new Date(stat.mtime),
name: filename, name: filename,
size: stat.size, size: stat.size,
sizeFormatted: filesize(stat.size), sizeFormatted: filesize(stat.size)
}); })
}); })
}, function (err, missions) { }, function (err, missions) {
if (cb) { if (cb) {
cb(err, missions); cb(err, missions)
} }
}); })
} }
}); })
}; }
Missions.prototype.handleUpload = function (uploadedFile, cb) { Missions.prototype.handleUpload = function (uploadedFile, cb) {
var filename = decodeURI(uploadedFile.originalname.toLowerCase()); var filename = decodeURI(uploadedFile.originalname.toLowerCase())
fs.move (uploadedFile.path, path.join(this.missionsPath(), filename), function (err) { fs.move(uploadedFile.path, path.join(this.missionsPath(), filename), function (err) {
cb(err); cb(err)
}); })
}; }
Missions.prototype.delete = function (missionName, cb) { Missions.prototype.delete = function (missionName, cb) {
fs.unlink(path.join(this.missionsPath(), missionName), cb); fs.unlink(path.join(this.missionsPath(), missionName), cb)
}; }
Missions.prototype.downloadSteamWorkshop = function (id, cb) { Missions.prototype.downloadSteamWorkshop = function (id, cb) {
if (!id) { if (!id) {
return cb(new Error('Not a valid Steam Workshop ID: ' + id)); return cb(new Error('Not a valid Steam Workshop ID: ' + id))
} }
this.steamWorkshop.downloadFile(id, cb); this.steamWorkshop.downloadFile(id, cb)
} }
module.exports = Missions; module.exports = Missions

View File

@ -1,131 +1,132 @@
var async = require('async'); var async = require('async')
var events = require('events'); var events = require('events')
var filesize = require('filesize'); var filesize = require('filesize')
var fs = require('fs.extra'); var fs = require('fs.extra')
var _ = require('lodash'); var _ = require('lodash')
var path = require('path'); var path = require('path')
var playwithsix = require('playwithsix'); var playwithsix = require('playwithsix')
var Mods = function (config) { var Mods = function (config) {
this.config = config; this.config = config
this.liteMods = true; this.liteMods = true
this.mods = []; this.mods = []
}
var self = this; Mods.prototype = new events.EventEmitter()
};
Mods.prototype = new events.EventEmitter();
Mods.prototype.delete = function (mod, cb) { Mods.prototype.delete = function (mod, cb) {
var self = this; var self = this
fs.rmrf(path.join(this.config.path, mod), function (err) { fs.rmrf(path.join(this.config.path, mod), function (err) {
cb(err); cb(err)
if (!err) { if (!err) {
self.updateMods(); self.updateMods()
} }
}); })
}; }
Mods.prototype.download = function (mod, cb) { Mods.prototype.download = function (mod, cb) {
var self = this; var self = this
var currentDownloadMod = null; var currentDownloadMod = null
var currentDownloadProgress = 0;
playwithsix.downloadMod(this.config.path, mod, {lite: this.liteMods}, function(err, mods) { playwithsix.downloadMod(this.config.path, mod, {lite: this.liteMods}, function (err, mods) {
if (currentDownloadMod) { if (currentDownloadMod) {
currentDownloadMod.progress = null; currentDownloadMod.progress = null
self.emit('mods', self.mods); self.emit('mods', self.mods)
} }
self.updateMods(); self.updateMods()
if (cb) { if (cb) {
cb(err, mods); cb(err, mods)
} }
}).on('progress', function (progress) { }).on('progress', function (progress) {
var modName = progress.mod; var modName = progress.mod
if (!currentDownloadMod || currentDownloadMod.name != modName) { if (!currentDownloadMod || currentDownloadMod.name !== modName) {
if (currentDownloadMod) { if (currentDownloadMod) {
currentDownloadMod.progress = null; currentDownloadMod.progress = null
} }
var mod = _.find(self.mods, {name: modName}); var mod = _.find(self.mods, {name: modName})
if (mod) { if (mod) {
currentDownloadMod = mod; currentDownloadMod = mod
} else { } else {
currentDownloadMod = { currentDownloadMod = {
name: modName, name: modName,
outdated: false, outdated: false,
playWithSix: true, playWithSix: true
}; }
self.mods.push(currentDownloadMod); self.mods.push(currentDownloadMod)
} }
} }
// Progress in whole percent // Progress in whole percent
var newProgress = parseInt(progress.completed / progress.size * 100, 10); var newProgress = parseInt(progress.completed / progress.size * 100, 10)
if (newProgress != currentDownloadMod.progress) { if (newProgress !== currentDownloadMod.progress) {
currentDownloadMod.progress = newProgress; currentDownloadMod.progress = newProgress
self.emit('mods', self.mods); self.emit('mods', self.mods)
} }
}); })
}; }
Mods.prototype.updateMods = function () { Mods.prototype.updateMods = function () {
var self = this; var self = this
fs.readdir(self.config.path, function (err, files) { fs.readdir(self.config.path, function (err, files) {
if (err) { if (err) {
console.log(err); console.log(err)
} else { } else {
var mods = files.filter(function (file) { var mods = files.filter(function (file) {
return file.charAt(0) == "@"; return file.charAt(0) === '@'
}); })
playwithsix.checkOutdated(self.config.path, function (err, outdatedMods) { playwithsix.checkOutdated(self.config.path, function (err, outdatedMods) {
if (err) {
console.log('Error checking for outdated mods: ' + err)
}
async.map(mods, function (mod, cb) { async.map(mods, function (mod, cb) {
var modPath = path.join(self.config.path, mod); var modPath = path.join(self.config.path, mod)
self.isPlayWithSixMod(modPath, function (isPlayWithSixMod) { self.isPlayWithSixMod(modPath, function (isPlayWithSixMod) {
cb(null, { cb(null, {
name: mod, name: mod,
outdated: outdatedMods && outdatedMods.indexOf(mod) >= 0, outdated: outdatedMods && outdatedMods.indexOf(mod) >= 0,
progress: null, progress: null,
playWithSix: isPlayWithSixMod, playWithSix: isPlayWithSixMod
}); })
}); })
}, function (err, mods) { }, function (err, mods) {
if (!err) { if (!err) {
self.mods = mods; self.mods = mods
self.emit('mods', mods); self.emit('mods', mods)
} }
}); })
}); })
} }
}); })
}; }
Mods.prototype.isPlayWithSixMod = function (modPath, cb) { Mods.prototype.isPlayWithSixMod = function (modPath, cb) {
var pwsFile = path.join(modPath, '.synq.json'); var pwsFile = path.join(modPath, '.synq.json')
fs.exists(pwsFile, function (exists) { fs.exists(pwsFile, function (exists) {
if (cb) { if (cb) {
cb(exists); cb(exists)
} }
}); })
}; }
Mods.prototype.search = function (query, cb) { Mods.prototype.search = function (query, cb) {
playwithsix.search(query, function (err, mods) { playwithsix.search(query, function (err, mods) {
if (err) { if (err) {
cb(err); cb(err)
} else { } else {
mods.map(function (mod) { mods.map(function (mod) {
mod.formattedSize = filesize(mod.size); mod.formattedSize = filesize(mod.size)
}); })
cb(null, mods); cb(null, mods)
} }
}); })
}; }
module.exports = Mods; module.exports = Mods

View File

@ -1,15 +1,14 @@
var _ = require('lodash'); var _ = require('lodash')
var events = require('events'); var events = require('events')
var fs = require('fs'); var fs = require('fs')
var gamedig = require('gamedig'); var Gamedig = require('gamedig')
var slugify = require('slugify'); var slugify = require('slugify')
var spawn = require('child_process').spawn;
var ArmaServer = require('arma-server'); var ArmaServer = require('arma-server')
var config = require('../config.js'); var config = require('../config.js')
var queryInterval = 5000; var queryInterval = 5000
var queryTypes = { var queryTypes = {
arma1: 'arma', arma1: 'arma',
arma2: 'arma2', arma2: 'arma2',
@ -18,105 +17,105 @@ var queryTypes = {
arma3_x64: 'arma3', arma3_x64: 'arma3',
cwa: 'operationflashpoint', cwa: 'operationflashpoint',
ofp: 'operationflashpoint', ofp: 'operationflashpoint',
ofpresistance: 'operationflashpoint', ofpresistance: 'operationflashpoint'
}; }
var createServerTitle = function(title) { var createServerTitle = function (title) {
if (config.prefix) { if (config.prefix) {
title = config.prefix + title; title = config.prefix + title
} }
if (config.suffix) { if (config.suffix) {
title = title + config.suffix; title = title + config.suffix
} }
return title; return title
}; }
var Server = function (config, logs, options) { var Server = function (config, logs, options) {
this.config = config; this.config = config
this.logs = logs; this.logs = logs
this.update(options); this.update(options)
}; }
Server.prototype = new events.EventEmitter(); Server.prototype = new events.EventEmitter()
Server.prototype.generateId = function () { Server.prototype.generateId = function () {
return slugify(this.title).replace(/\./g, '-'); return slugify(this.title).replace(/\./g, '-')
}; }
Server.prototype.update = function (options) { Server.prototype.update = function (options) {
this.admin_password = options.admin_password; this.admin_password = options.admin_password
this.auto_start = options.auto_start; this.auto_start = options.auto_start
this.battle_eye = options.battle_eye; this.battle_eye = options.battle_eye
this.max_players = options.max_players; this.max_players = options.max_players
this.missions = options.missions; this.missions = options.missions
this.mods = options.mods || []; this.mods = options.mods || []
this.number_of_headless_clients = options.number_of_headless_clients || 0; this.number_of_headless_clients = options.number_of_headless_clients || 0
this.password = options.password; this.password = options.password
this.parameters = options.parameters; this.parameters = options.parameters
this.persistent = options.persistent; this.persistent = options.persistent
this.port = options.port || 2302; this.port = options.port || 2302
this.title = options.title; this.title = options.title
this.von = options.von; this.von = options.von
this.verify_signatures = options.verify_signatures; this.verify_signatures = options.verify_signatures
this.id = this.generateId(); this.id = this.generateId()
this.port = parseInt(this.port, 10); // If port is a string then gamedig fails this.port = parseInt(this.port, 10) // If port is a string then gamedig fails
}; }
Server.prototype.queryStatus = function() { Server.prototype.queryStatus = function () {
if (!this.instance) { if (!this.instance) {
return; return
} }
var self = this; var self = this
Gamedig.query( Gamedig.query(
{ {
type: queryTypes[config.game], type: queryTypes[config.game],
host: '127.0.0.1', host: '127.0.0.1',
port: self.port, port: self.port
}, },
function(state) { function (state) {
if (!self.instance) { if (!self.instance) {
return; return
} }
if(state.error) { if (state.error) {
self.state = null; self.state = null
} else { } else {
self.state = state; self.state = state
} }
self.emit('state'); self.emit('state')
} }
); )
}; }
Server.prototype.getParameters = function() { Server.prototype.getParameters = function () {
var parameters = []; var parameters = []
if (config.parameters && Array.isArray(config.parameters)) { if (config.parameters && Array.isArray(config.parameters)) {
parameters = parameters.concat(config.parameters); parameters = parameters.concat(config.parameters)
} }
if (this.parameters && Array.isArray(this.parameters)) { if (this.parameters && Array.isArray(this.parameters)) {
parameters = parameters.concat(this.parameters); parameters = parameters.concat(this.parameters)
} }
return parameters; return parameters
} }
Server.prototype.start = function() { Server.prototype.start = function () {
var parameters = this.getParameters(); var parameters = this.getParameters()
var server = new ArmaServer.Server({ var server = new ArmaServer.Server({
battleEye: this.battle_eye ? 1 : 0, battleEye: this.battle_eye ? 1 : 0,
config: this.id, config: this.id,
disableVoN: this.von ? 0 : 1, disableVoN: this.von ? 0 : 1,
game: config.game, game: config.game,
headlessClients: this.number_of_headless_clients > 0 ? ["127.0.0.1"] : null, headlessClients: this.number_of_headless_clients > 0 ? ['127.0.0.1'] : null,
hostname: createServerTitle(this.title), hostname: createServerTitle(this.title),
localClient: this.number_of_headless_clients > 0 ? ["127.0.0.1"] : null, localClient: this.number_of_headless_clients > 0 ? ['127.0.0.1'] : null,
missions: this.missions, missions: this.missions,
mods: this.mods, mods: this.mods,
parameters: parameters, parameters: parameters,
@ -128,142 +127,141 @@ Server.prototype.start = function() {
players: this.max_players, players: this.max_players,
port: this.port, port: this.port,
serverMods: config.serverMods, serverMods: config.serverMods,
verifySignatures: this.verify_signatures ? 2 : 0, verifySignatures: this.verify_signatures ? 2 : 0
}); })
server.writeServerConfig(); server.writeServerConfig()
var instance = server.start(); var instance = server.start()
var self = this; var self = this
var logStream = null; var logStream = null
if (this.config.type === 'linux') { if (this.config.type === 'linux') {
logStream = fs.createWriteStream(this.logs.generateLogFilePath(), { logStream = fs.createWriteStream(this.logs.generateLogFilePath(), {
'flags': 'a' 'flags': 'a'
}); })
} }
instance.stdout.on('data', function (data) { instance.stdout.on('data', function (data) {
if (logStream) { if (logStream) {
logStream.write(data); logStream.write(data)
} }
}); })
instance.stderr.on('data', function (data) { instance.stderr.on('data', function (data) {
if (logStream) { if (logStream) {
logStream.write(data); logStream.write(data)
} }
}); })
instance.on('close', function (code) { instance.on('close', function (code) {
if (logStream) { if (logStream) {
logStream.end(); logStream.end()
} }
clearInterval(self.queryStatusInterval); clearInterval(self.queryStatusInterval)
self.state = null; self.state = null
self.pid = null; self.pid = null
self.instance = null; self.instance = null
self.stopHeadlessClients(); self.stopHeadlessClients()
self.emit('state'); self.emit('state')
}); })
instance.on('error', function (err) { instance.on('error', function (err) {
console.log(err); console.log(err)
}); })
this.pid = instance.pid; this.pid = instance.pid
this.instance = instance; this.instance = instance
this.queryStatusInterval = setInterval(function () { this.queryStatusInterval = setInterval(function () {
self.queryStatus(); self.queryStatus()
}, queryInterval); }, queryInterval)
this.startHeadlessClients() this.startHeadlessClients()
this.emit('state'); this.emit('state')
return this; return this
}; }
Server.prototype.startHeadlessClients = function() { Server.prototype.startHeadlessClients = function () {
var parameters = this.getParameters(); var parameters = this.getParameters()
var self = this; var self = this
var headlessClientInstances = _.times(this.number_of_headless_clients, function (i) { var headlessClientInstances = _.times(this.number_of_headless_clients, function (i) {
var headless = new ArmaServer.Headless({ var headless = new ArmaServer.Headless({
game: config.game, game: config.game,
host: "127.0.0.1", host: '127.0.0.1',
mods: self.mods, mods: self.mods,
parameters: parameters, parameters: parameters,
password: self.password, password: self.password,
path: self.config.path, path: self.config.path,
platform: self.config.type, platform: self.config.type,
port: self.port, port: self.port
}); })
var headlessInstance = headless.start(); var headlessInstance = headless.start()
var name = 'HC_' + i; var name = 'HC_' + i
var logPrefix = self.id + ' ' + name; var logPrefix = self.id + ' ' + name
console.log(logPrefix + ' starting'); console.log(logPrefix + ' starting')
headlessInstance.stdout.on('data', function (data) { headlessInstance.stdout.on('data', function (data) {
console.log(logPrefix + ' stdout: ' + data); console.log(logPrefix + ' stdout: ' + data)
}); })
headlessInstance.stderr.on('data', function (data) { headlessInstance.stderr.on('data', function (data) {
console.log(logPrefix + ' stderr: ' + data); console.log(logPrefix + ' stderr: ' + data)
}); })
headlessInstance.on('close', function (code) { headlessInstance.on('close', function (code) {
console.log(logPrefix + ' exited: ' + code); console.log(logPrefix + ' exited: ' + code)
var elementIndex = headlessClientInstances.indexOf(headlessInstance); var elementIndex = headlessClientInstances.indexOf(headlessInstance)
if (elementIndex != -1) { if (elementIndex !== -1) {
headlessClientInstances.splice(elementIndex, 1); headlessClientInstances.splice(elementIndex, 1)
} }
}); })
headlessInstance.on('error', function (err) { headlessInstance.on('error', function (err) {
console.log(logPrefix + ' error: ' + err); console.log(logPrefix + ' error: ' + err)
}); })
return headlessInstance; return headlessInstance
}); })
this.headlessClientInstances = headlessClientInstances; this.headlessClientInstances = headlessClientInstances
} }
Server.prototype.stop = function(cb) { Server.prototype.stop = function (cb) {
var handled = false; var handled = false
var self = this;
this.instance.on('close', function (code) { this.instance.on('close', function (code) {
if (!handled) { if (!handled) {
handled = true; handled = true
if (cb) { if (cb) {
cb(); cb()
} }
} }
}); })
this.instance.kill(); this.instance.kill()
setTimeout(function() { setTimeout(function () {
if (!handled) { if (!handled) {
handled = true; handled = true
if (cb) { if (cb) {
cb(); cb()
} }
} }
}, 5000); }, 5000)
return this; return this
}; }
Server.prototype.stopHeadlessClients = function() { Server.prototype.stopHeadlessClients = function () {
this.headlessClientInstances.map(function (headlessClientInstance) { this.headlessClientInstances.map(function (headlessClientInstance) {
headlessClientInstance.kill(); headlessClientInstance.kill()
}); })
} }
Server.prototype.toJSON = function () { Server.prototype.toJSON = function () {
@ -284,8 +282,8 @@ Server.prototype.toJSON = function () {
state: this.state, state: this.state,
title: this.title, title: this.title,
von: this.von, von: this.von,
verify_signatures: this.verify_signatures, verify_signatures: this.verify_signatures
}; }
}; }
module.exports = Server; module.exports = Server

View File

@ -6,9 +6,15 @@
"scripts": { "scripts": {
"install-windows-service": "winser -i -a -c", "install-windows-service": "winser -i -a -c",
"uninstall-windows-service": "winser -r -x -c", "uninstall-windows-service": "winser -r -x -c",
"lint": "standard --verbose lib/**/*.js routes/**/*.js test/**/*.js app.js",
"start": "node app.js", "start": "node app.js",
"test": "node node_modules/mocha/bin/mocha --recursive" "test": "node node_modules/mocha/bin/mocha --recursive"
}, },
"standard": {
"env": [
"mocha"
]
},
"dependencies": { "dependencies": {
"arma-server": "0.0.5", "arma-server": "0.0.5",
"async": "^0.9.0", "async": "^0.9.0",
@ -31,7 +37,8 @@
}, },
"devDependencies": { "devDependencies": {
"mocha": "~3.2.0", "mocha": "~3.2.0",
"should": "~5.0.0", "should": "~13.0.1",
"standard": "^10.0.3",
"timekeeper": "0.0.5" "timekeeper": "0.0.5"
} }
} }

View File

@ -1,33 +1,33 @@
var express = require('express'); var express = require('express')
module.exports = function (logsManager) { module.exports = function (logsManager) {
var router = express.Router(); var router = express.Router()
router.get('/', function (req, res) { router.get('/', function (req, res) {
logsManager.logFiles(function (err, files) { logsManager.logFiles(function (err, files) {
if (err) { if (err) {
res.status(500).send(err); res.status(500).send(err)
} else { } else {
res.json(files); res.json(files)
} }
}); })
}); })
router.get('/:log', function(req, res) { router.get('/:log', function (req, res) {
var requestedFilename = req.params.log; var requestedFilename = req.params.log
logsManager.getLogFile(requestedFilename, function (err, file) { logsManager.getLogFile(requestedFilename, function (err, file) {
if (err) { if (err) {
res.status(500).send(err); res.status(500).send(err)
} else { } else {
if (file) { if (file) {
res.download(file.path); res.download(file.path)
} else { } else {
res.status(404).send(new Error("File not found")); res.status(404).send(new Error('File not found'))
} }
} }
}); })
}); })
return router; return router
}; }

View File

@ -1,65 +1,65 @@
var express = require('express'); var express = require('express')
var multer = require('multer'); var multer = require('multer')
var upload = multer({ storage: multer.diskStorage({}) }); var upload = multer({ storage: multer.diskStorage({}) })
module.exports = function (missionsManager) { module.exports = function (missionsManager) {
var router = express.Router(); var router = express.Router()
router.get('/', function (req, res) { router.get('/', function (req, res) {
missionsManager.list(function (err, missions) { missionsManager.list(function (err, missions) {
if (err) { if (err) {
res.status(500).send(err); res.status(500).send(err)
} else { } else {
res.json(missions); res.json(missions)
} }
}); })
}); })
router.post('/', upload.single('mission'), function (req, res) { router.post('/', upload.single('mission'), function (req, res) {
var missionFile = req.file; var missionFile = req.file
if (!missionFile) { if (!missionFile) {
return res.status(400).send('No mission file uploaded');; return res.status(400).send('No mission file uploaded')
} }
missionsManager.handleUpload(missionFile, function (err) { missionsManager.handleUpload(missionFile, function (err) {
if (err) { if (err) {
res.status(500).send(err); res.status(500).send(err)
} else { } else {
res.status(200).json({success: true}); res.status(200).json({success: true})
} }
}); })
}); })
router.get('/:mission', function (req, res) { router.get('/:mission', function (req, res) {
var filename = req.params.mission; var filename = req.params.mission
res.download(missionsManager.missionPath(filename), decodeURI(filename)); res.download(missionsManager.missionPath(filename), decodeURI(filename))
}); })
router.delete('/:mission', function (req, res) { router.delete('/:mission', function (req, res) {
var filename = req.params.mission; var filename = req.params.mission
missionsManager.delete(filename, function (err) { missionsManager.delete(filename, function (err) {
if (err) { if (err) {
res.status(500).send(err); res.status(500).send(err)
} else { } else {
res.json({success: true}); res.json({success: true})
} }
}); })
}); })
router.post('/workshop', function (req, res) { router.post('/workshop', function (req, res) {
var id = req.body.id; var id = req.body.id
missionsManager.downloadSteamWorkshop(id, function (err, files) { missionsManager.downloadSteamWorkshop(id, function (err, files) {
if (err) { if (err) {
res.status(500).send(err); res.status(500).send(err)
} else { } else {
res.json({success: true}); res.json({success: true})
} }
}); })
}); })
return router; return router
}; }

View File

@ -1,47 +1,47 @@
var express = require('express'); var express = require('express')
module.exports = function (modsManager) { module.exports = function (modsManager) {
var router = express.Router(); var router = express.Router()
router.get('/', function (req, res) { router.get('/', function (req, res) {
res.send(modsManager.mods); res.send(modsManager.mods)
}); })
router.post('/', function (req, res) { router.post('/', function (req, res) {
modsManager.download(req.body.name); modsManager.download(req.body.name)
res.status(204); res.status(204)
}); })
router.put('/:mod', function (req, res) { router.put('/:mod', function (req, res) {
modsManager.download(req.params.mod); modsManager.download(req.params.mod)
res.status(204); res.status(204)
}); })
router.delete('/:mod', function (req, res) { router.delete('/:mod', function (req, res) {
modsManager.delete(req.params.mod, function (err) { modsManager.delete(req.params.mod, function (err) {
if (err) { if (err) {
res.status(500).send(err); res.status(500).send(err)
} else { } else {
res.status(204); res.status(204)
} }
}); })
}); })
router.post('/refresh', function (req, res) { router.post('/refresh', function (req, res) {
modsManager.updateMods(); modsManager.updateMods()
res.status(204); res.status(204)
}); })
router.post('/search', function (req, res) { router.post('/search', function (req, res) {
var query = req.body.query || ""; var query = req.body.query || ''
modsManager.search(query, function (err, mods) { modsManager.search(query, function (err, mods) {
if (err || !mods) { if (err || !mods) {
res.status(500).send(err); res.status(500).send(err)
} else { } else {
res.send(mods); res.send(mods)
} }
}); })
}); })
return router; return router
}; }

View File

@ -1,50 +1,50 @@
var express = require('express'); var express = require('express')
module.exports = function (manager, mods) { module.exports = function (manager, mods) {
var router = express.Router(); var router = express.Router()
router.get('/', function (req, res) { router.get('/', function (req, res) {
res.json(manager.getServers()); res.json(manager.getServers())
}); })
router.post('/', function (req, res) { router.post('/', function (req, res) {
var server = manager.addServer(req.body); var server = manager.addServer(req.body)
res.json(server); res.json(server)
}); })
router.get('/:server', function (req, res) { router.get('/:server', function (req, res) {
var server = manager.getServer(req.params.server); var server = manager.getServer(req.params.server)
res.json(server); res.json(server)
}); })
router.put('/:server', function (req, res) { router.put('/:server', function (req, res) {
var server = manager.getServer(req.params.server); var server = manager.getServer(req.params.server)
server.update(req.body); server.update(req.body)
manager.save(); manager.save()
res.json(server); res.json(server)
}); })
router.delete('/:server', function (req, res) { router.delete('/:server', function (req, res) {
var server = manager.removeServer(req.params.server); var server = manager.removeServer(req.params.server)
res.json(server); res.json(server)
}); })
router.post('/:server/start', function (req, res) { router.post('/:server/start', function (req, res) {
var server = manager.getServer(req.params.server); var server = manager.getServer(req.params.server)
server.start(); server.start()
res.json({status:"ok", pid: server.pid}); res.json({status: 'ok', pid: server.pid})
}); })
router.post('/:server/stop', function (req, res) { router.post('/:server/stop', function (req, res) {
var server = manager.getServer(req.params.server); var server = manager.getServer(req.params.server)
server.stop(function () { server.stop(function () {
if (!server.pid) { if (!server.pid) {
res.json({status: true, pid: server.pid}); res.json({status: true, pid: server.pid})
} else { } else {
res.json({status: false, pid: server.pid}); res.json({status: false, pid: server.pid})
} }
}); })
}); })
return router; return router
}; }

View File

@ -1,11 +1,11 @@
var express = require('express'); var express = require('express')
module.exports = function (config) { module.exports = function (config) {
var router = express.Router(); var router = express.Router()
router.get('/', function (req, res) { router.get('/', function (req, res) {
res.json(config); res.json(config)
}); })
return router; return router
}; }

View File

@ -1,30 +1,30 @@
var should = require('should'); require('should')
var tk = require('timekeeper'); var tk = require('timekeeper')
var Logs = require('../../lib/logs.js'); var Logs = require('../../lib/logs.js')
var logs = new Logs({ var logs = new Logs({
path: '/tmp/', path: '/tmp/',
type: 'linux' type: 'linux'
}); })
describe('Logs', function() { describe('Logs', function () {
beforeEach(function() { beforeEach(function () {
tk.freeze(1445455712000); // 2015-10-21 19:28:32 tk.freeze(1445455712000) // 2015-10-21 19:28:32
}); })
afterEach(function() { afterEach(function () {
tk.reset(); tk.reset()
}); })
describe('generateLogFileName()', function() { describe('generateLogFileName()', function () {
it('should generate valid file name', function() { it('should generate valid file name', function () {
Logs.generateLogFileName().should.eql('arma3server_2015-10-21_19-28-32.log'); Logs.generateLogFileName().should.eql('arma3server_2015-10-21_19-28-32.log')
}); })
}); })
describe('generateLogFilePath()', function() { describe('generateLogFilePath()', function () {
it('should generate valid file path', function() { it('should generate valid file path', function () {
logs.generateLogFilePath().should.eql('/tmp/logs/arma3server_2015-10-21_19-28-32.log'); logs.generateLogFilePath().should.eql('/tmp/logs/arma3server_2015-10-21_19-28-32.log')
}); })
}); })
}); })

View File

@ -1,16 +1,16 @@
var should = require('should'); var should = require('should')
var Mods = require('../../lib/mods.js'); var Mods = require('../../lib/mods.js')
describe('Mods', function() { describe('Mods', function () {
describe('search()', function() { describe('search()', function () {
it('should find mods', function(done) { it('should find mods', function (done) {
var mods = new Mods(); var mods = new Mods()
mods.search('', function (err, mods) { mods.search('', function (err, mods) {
should(err).be.null; should(err).be.null()
mods.should.not.be.empty; mods.should.not.be.empty()
done(); done()
}); })
}); })
}); })
}); })

View File

@ -1,19 +1,19 @@
var should = require('should'); require('should')
var Server = require('../../lib/server.js'); var Server = require('../../lib/server.js')
describe('Server', function() { describe('Server', function () {
describe('generateId()', function() { describe('generateId()', function () {
it('should include title', function() { it('should include title', function () {
var server = new Server(null, null, {title: 'title.with.lot.of.dots'}); var server = new Server(null, null, {title: 'title.with.lot.of.dots'})
server.generateId().should.eql('title-with-lot-of-dots'); server.generateId().should.eql('title-with-lot-of-dots')
}); })
}); })
describe('toJSON()', function() { describe('toJSON()', function () {
it('should include title', function() { it('should include title', function () {
var server = new Server(null, null, {title: 'test'}); var server = new Server(null, null, {title: 'test'})
server.toJSON().should.have.property('title', 'test'); server.toJSON().should.have.property('title', 'test')
}); })
}); })
}); })