Skip to content

Commit a1e36b0

Browse files
committed
Virtual server folder with keys management
1 parent 6dffd9c commit a1e36b0

File tree

2 files changed

+121
-9
lines changed

2 files changed

+121
-9
lines changed

Diff for: lib/server.js

+120-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
var _ = require('lodash')
22
var events = require('events')
33
var fs = require('fs')
4+
var fsExtra = require('fs.extra')
45
var Gamedig = require('gamedig')
6+
var glob = require('glob')
7+
var path = require('path')
58
var slugify = require('slugify')
69

710
var ArmaServer = require('arma-server')
@@ -134,6 +137,104 @@ Server.prototype.start = function () {
134137
return this
135138
}
136139

140+
var self = this
141+
142+
const requiredFileExtensions = ['.dll', '.exe', '.so', '.txt']
143+
const serverFolders = [
144+
'addons',
145+
'argo',
146+
'battleye',
147+
'contact',
148+
'curator',
149+
'dll',
150+
'dta',
151+
'enoch',
152+
'expansion',
153+
'gm',
154+
'heli',
155+
'jets',
156+
'kart',
157+
'mark',
158+
'mpmissions',
159+
'orange',
160+
'tacops',
161+
'tank'
162+
]
163+
const symlinkFolders = serverFolders.concat(self.mods).concat(config.serverMods)
164+
165+
return fs.promises.mkdtemp(path.join(self.config.path, 'arma-server-'))
166+
.then((serverFolder) => {
167+
self.virtualServerFolder = serverFolder
168+
console.log('Created virtual server folder:', serverFolder)
169+
170+
return fs.promises.readdir(self.config.path)
171+
.then((files) => {
172+
// Copy needed files, file symlinks on Windows are sketchy
173+
const serverFiles = files.filter((file) => requiredFileExtensions.indexOf(path.extname(file)) >= 0 || path.basename(file) === 'arma3server')
174+
return Promise.all(serverFiles.map((file) => {
175+
return fs.promises.copyFile(path.join(self.config.path, file), path.join(serverFolder, file))
176+
}))
177+
})
178+
.then(() => {
179+
// Create virtual folders from default Arma and mods
180+
return Promise.all(symlinkFolders.map((symlink) => {
181+
return fs.promises.access(path.join(self.config.path, symlink))
182+
.then(() => {
183+
return fs.promises.symlink(path.join(self.config.path, symlink), path.join(serverFolder, symlink), 'junction')
184+
})
185+
.catch((err) => {
186+
console.error('Could create symlink for', symlink, 'due to', err)
187+
})
188+
}))
189+
})
190+
.then(() => {
191+
// Copy needed keys, file symlinks on Windows are sketchy
192+
const keysFolder = path.join(serverFolder, 'keys')
193+
return fs.promises.mkdir(keysFolder, { recursive: true })
194+
.then(() => {
195+
const defaultKeysPath = path.join(self.config.path, 'keys')
196+
const defaultKeysPromise = fs.promises.readdir(defaultKeysPath)
197+
.then((files) => files.filter((file) => path.extname(file) === '.bikey'))
198+
.then((files) => files.map((file) => path.join(defaultKeysPath, file)))
199+
200+
const modKeysPromise = Promise.all(self.mods.map(mod => {
201+
return new Promise((resolve, reject) => {
202+
const modPath = path.join(this.config.path, mod)
203+
glob(`${modPath}/**/*.bikey`, function (err, files) {
204+
if (err) {
205+
return reject(err)
206+
}
207+
208+
return resolve(files)
209+
})
210+
})
211+
})).then((modsFiles) => modsFiles.flat())
212+
213+
return Promise.all([defaultKeysPromise, modKeysPromise].map((promise) => {
214+
return promise.then((keyFiles) => {
215+
return Promise.all(keyFiles.map((keyFile) => {
216+
return fs.promises.copyFile(keyFile, path.join(keysFolder, path.basename(keyFile)))
217+
}))
218+
})
219+
})).catch((err) => {
220+
console.error('Error copying keys:', err)
221+
})
222+
})
223+
})
224+
.then(() => {
225+
self.realStart(serverFolder)
226+
})
227+
.catch((err) => {
228+
console.error('Error creating virtual server folder:', err)
229+
})
230+
})
231+
}
232+
233+
Server.prototype.realStart = function (path) {
234+
if (this.instance) {
235+
return this
236+
}
237+
137238
var parameters = this.getParameters()
138239
var server = new ArmaServer.Server({
139240
additionalConfigurationOptions: this.getAdditionalConfigurationOptions(),
@@ -154,7 +255,7 @@ Server.prototype.start = function () {
154255
parameters: parameters,
155256
password: this.password,
156257
passwordAdmin: this.admin_password,
157-
path: this.config.path,
258+
path: path,
158259
persistent: this.persistent ? 1 : 0,
159260
platform: this.config.type,
160261
players: this.max_players,
@@ -196,8 +297,18 @@ Server.prototype.start = function () {
196297
self.instance = null
197298

198299
self.stopHeadlessClients()
199-
200-
self.emit('state')
300+
.then(() => {
301+
if (self.virtualServerFolder) {
302+
fsExtra.rmrf(self.virtualServerFolder, function (err) {
303+
if (err) {
304+
console.log('Error removing virtual server folder', err)
305+
}
306+
})
307+
self.virtualServerFolder = null
308+
}
309+
310+
self.emit('state')
311+
})
201312
})
202313

203314
instance.on('error', function (err) {
@@ -210,14 +321,14 @@ Server.prototype.start = function () {
210321
self.queryStatus()
211322
}, queryInterval)
212323

213-
this.startHeadlessClients()
324+
this.startHeadlessClients(path)
214325

215326
this.emit('state')
216327

217328
return this
218329
}
219330

220-
Server.prototype.startHeadlessClients = function () {
331+
Server.prototype.startHeadlessClients = function (path) {
221332
var parameters = this.getParameters()
222333
var self = this
223334
var headlessClientInstances = _.times(this.number_of_headless_clients, function (i) {
@@ -228,7 +339,7 @@ Server.prototype.startHeadlessClients = function () {
228339
mods: self.mods,
229340
parameters: parameters,
230341
password: self.password,
231-
path: self.config.path,
342+
path: path,
232343
platform: self.config.type,
233344
port: self.port
234345
})
@@ -293,9 +404,9 @@ Server.prototype.stop = function (cb) {
293404
}
294405

295406
Server.prototype.stopHeadlessClients = function () {
296-
this.headlessClientInstances.map(function (headlessClientInstance) {
297-
headlessClientInstance.kill()
298-
})
407+
return Promise.all(this.headlessClientInstances.map(function (headlessClientInstance) {
408+
return headlessClientInstance.kill()
409+
}))
299410
}
300411

301412
Server.prototype.toJSON = function () {

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"filesize": "^3.1.0",
3232
"fs.extra": "~1.3.2",
3333
"gamedig": "^0.2.30",
34+
"glob": "^7.1.6",
3435
"jquery": "^3.5.0",
3536
"jquery.iframe-transport": "^1.0.0",
3637
"ladda": "1.0.5",

0 commit comments

Comments
 (0)