@jtff/miztemplate-lib 2.2.0 → 3.0.0-rc10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +4 -3
- package/lib/jtff-lib-ci.js +4 -308
- package/lib/mizlib.js +321 -0
- package/lua/lib/Hercules_Cargo.lua +686 -0
- package/lua/lib/Moose_.lua +117314 -0
- package/lua/lib/Splash_Damage_2_0.lua +472 -0
- package/lua/lib/gemman.lua +1 -0
- package/lua/lib/mist_4_5_107.lua +9084 -0
- package/lua/lib/skynet-iads-compiled.lua +3864 -0
- package/lua/settings/settings-RAT.lua +235 -0
- package/lua/settings/settings-airboss.lua +142 -0
- package/lua/settings/settings-atis.lua +31 -0
- package/lua/settings/settings-awacs.lua +58 -0
- package/lua/settings/settings-awacsondemand.lua +26 -0
- package/lua/settings/settings-beacons.lua +10 -0
- package/lua/settings/settings-capwarzone.lua +164 -0
- package/lua/settings/settings-capzone.lua +32 -0
- package/lua/settings/settings-fac_ranges.lua +17 -0
- package/lua/settings/settings-foxzone.lua +14 -0
- package/lua/settings/settings-gemman.lua +6 -0
- package/lua/settings/settings-global.lua +31 -0
- package/lua/settings/settings-intercept.lua +23 -0
- package/lua/settings/settings-logistics.lua +22 -0
- package/lua/settings/settings-ondemandawacs.lua +29 -0
- package/lua/settings/settings-ondemandtankers.lua +29 -0
- package/lua/settings/settings-pedros.lua +11 -0
- package/lua/settings/settings-ranges.lua +28 -0
- package/lua/settings/settings-reapers.lua +25 -0
- package/lua/settings/settings-sams.lua +19 -0
- package/lua/settings/settings-skynet.lua +239 -0
- package/lua/settings/settings-tankers.lua +32 -0
- package/lua/settings/settings-training_ranges.lua +37 -0
- package/lua/src/010-root_menus.lua +5 -0
- package/lua/src/020-mission_functions.lua +1059 -0
- package/lua/src/110-set_clients.lua +61 -0
- package/lua/src/120-tankers.lua +589 -0
- package/lua/src/130-airboss.lua +621 -0
- package/lua/src/135-pedro.lua +21 -0
- package/lua/src/140-beacons.lua +19 -0
- package/lua/src/150-awacs.lua +599 -0
- package/lua/src/160-atis.lua +53 -0
- package/lua/src/170-cap_zone_training.lua +127 -0
- package/lua/src/172-cap_zone_war.lua +190 -0
- package/lua/src/173-fox_zone_training.lua +87 -0
- package/lua/src/176-random_air_traffic.lua +73 -0
- package/lua/src/178-training-intercept.lua +263 -0
- package/lua/src/180-logistics.lua +80 -0
- package/lua/src/190-ranges.lua +54 -0
- package/lua/src/191-sams.lua +49 -0
- package/lua/src/193-training_ranges.lua +191 -0
- package/lua/src/195-reaper-ondemand.lua +522 -0
- package/lua/src/196-fac_ranges.lua +34 -0
- package/lua/src/199-skynet.lua +721 -0
- package/lua/src/200-mission.lua +3 -0
- package/package.json +4 -3
- package/resources/radios/.gitkeep +0 -0
- package/resources/sounds/CTLD/beacon.ogg +0 -0
- package/resources/sounds/CTLD/beaconsilent.ogg +0 -0
- package/resources/sounds/Misc/.gitkeep +0 -0
- package/resources/sounds/Misc/2_Bips.ogg +0 -0
- package/resources/sounds/Misc/Bip.ogg +0 -0
- package/resources/sounds/Misc/crash_wood.ogg +0 -0
- package/scripts/build.js +1 -1
- package/scripts/inject-scripts.js +124 -228
- package/scripts/template-update.js +1 -1
package/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
const
|
|
1
|
+
const MizTemplateCI = require("./lib/jtff-lib-ci.js");
|
|
2
|
+
const Mizlib = require("./lib/mizlib.js");
|
|
2
3
|
const build = require("./scripts/build.js");
|
|
3
4
|
const clean = require("./scripts/clean.js");
|
|
4
5
|
const ftpupload = require("./scripts/ftpupload.js");
|
|
@@ -12,7 +13,7 @@ const templateUpdate = require("./scripts/template-update.js");
|
|
|
12
13
|
|
|
13
14
|
module.exports = {
|
|
14
15
|
MizTemplateCI: MizTemplateCI,
|
|
15
|
-
|
|
16
|
+
Mizlib: Mizlib,
|
|
16
17
|
build:build,
|
|
17
18
|
clean:clean,
|
|
18
19
|
ftpupload:ftpupload,
|
|
@@ -23,5 +24,5 @@ module.exports = {
|
|
|
23
24
|
injectScripts:injectScripts,
|
|
24
25
|
nextversionPrepare:nextversionPrepare,
|
|
25
26
|
release:release,
|
|
26
|
-
templateUpdate:templateUpdate
|
|
27
|
+
templateUpdate:templateUpdate,
|
|
27
28
|
};
|
package/lib/jtff-lib-ci.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const jszip = require("jszip");
|
|
4
3
|
const fs = require("fs");
|
|
5
4
|
const path = require("path");
|
|
6
|
-
const { promisify } = require('util');
|
|
7
|
-
const lstat = promisify(fs.lstat);
|
|
8
5
|
const { google } = require("googleapis");
|
|
9
|
-
const { format, parse } = require("lua-json");
|
|
10
6
|
const ftpClient = require('ftp');
|
|
7
|
+
const Mizlib = require("./mizlib");
|
|
11
8
|
|
|
12
9
|
class MizTemplateCI{
|
|
13
10
|
constructor(config) {
|
|
14
|
-
this.config = config
|
|
15
|
-
this.mizlib = new
|
|
11
|
+
this.config = config;
|
|
12
|
+
this.mizlib = new Mizlib();
|
|
16
13
|
}
|
|
17
14
|
|
|
18
15
|
getVersion() {
|
|
@@ -192,307 +189,6 @@ class MizTemplateCI{
|
|
|
192
189
|
}
|
|
193
190
|
}
|
|
194
191
|
|
|
195
|
-
class MizLib{
|
|
196
|
-
constructor() {
|
|
197
|
-
}
|
|
198
|
-
injectScripts(tObject, trObject, mrObject, strTitle, scriptFilesArray, timingInSeconds, hexColor) {
|
|
199
|
-
let nextIndex = Object.keys(trObject).length + 1;
|
|
200
|
-
if (nextIndex === 1) {
|
|
201
|
-
tObject['actions'] = {};
|
|
202
|
-
tObject['func'] = {};
|
|
203
|
-
tObject['conditions'] = {};
|
|
204
|
-
tObject['flag'] = {};
|
|
205
|
-
trObject = {};
|
|
206
|
-
}
|
|
207
|
-
let actionSentence = "";
|
|
208
|
-
let actionsObject = {};
|
|
209
|
-
for (const [index, scriptFile] of scriptFilesArray.entries()) {
|
|
210
|
-
actionSentence += "a_do_script_file(getValueResourceByKey(\"" + scriptFile + "\")); "
|
|
211
|
-
actionsObject[index + 1] = {
|
|
212
|
-
file: scriptFile,
|
|
213
|
-
predicate: 'a_do_script_file',
|
|
214
|
-
};
|
|
215
|
-
mrObject[scriptFile] = scriptFile;
|
|
216
|
-
}
|
|
217
|
-
actionSentence += "mission.trig.func[" + nextIndex + "]=nil;"
|
|
218
|
-
tObject['actions'][nextIndex] = actionSentence;
|
|
219
|
-
tObject['func'][nextIndex] = "if mission.trig.conditions[" + nextIndex + "]() then mission.trig.actions[" + nextIndex + "]() end";
|
|
220
|
-
tObject['conditions'][nextIndex] = "return(c_time_after(" + timingInSeconds + ") )";
|
|
221
|
-
tObject['flag'][nextIndex] = true;
|
|
222
|
-
trObject[nextIndex] = {
|
|
223
|
-
rules: {
|
|
224
|
-
1: {
|
|
225
|
-
coalitionlist: 'red',
|
|
226
|
-
seconds: timingInSeconds,
|
|
227
|
-
predicate: 'c_time_after',
|
|
228
|
-
zone: ''
|
|
229
|
-
}
|
|
230
|
-
},
|
|
231
|
-
eventlist: '',
|
|
232
|
-
comment: strTitle,
|
|
233
|
-
actions: actionsObject,
|
|
234
|
-
predicate: 'triggerOnce',
|
|
235
|
-
colorItem: hexColor
|
|
236
|
-
};
|
|
237
|
-
return { tObject: tObject, trObject: trObject, mrObject: mrObject };
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
async mizOpen(mizPath) {
|
|
241
|
-
var MizFile = new jszip();
|
|
242
|
-
const mizData = fs.readFileSync(mizPath);
|
|
243
|
-
return MizFile.loadAsync(mizData);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
async mizUpdate(mizPath, copyPath, strTheatreSettings) {
|
|
247
|
-
const zip = await this.mizOpen(mizPath);
|
|
248
|
-
this.mizUpdateSrcLuaFiles(zip);
|
|
249
|
-
this.mizUpdateLibLuaFiles(zip);
|
|
250
|
-
if (strTheatreSettings === null) {
|
|
251
|
-
// TODO: Inject fake data
|
|
252
|
-
console.log("NO THEATRE SPECIFIED. RADIO PRESETS WILL NOT BE AVAILABLE !");
|
|
253
|
-
} else {
|
|
254
|
-
await this.mizUpdateRadioPresets(zip, 'resources/radios/' + strTheatreSettings);
|
|
255
|
-
}
|
|
256
|
-
this.mizUpdateSettingsLuaFiles(zip, strTheatreSettings);
|
|
257
|
-
await this.mizUpdateSoundFolders(zip);
|
|
258
|
-
const inputZip = await zip.generateAsync({
|
|
259
|
-
type: 'nodebuffer',
|
|
260
|
-
streamFiles: true,
|
|
261
|
-
compression: "DEFLATE",
|
|
262
|
-
compressionOptions: {
|
|
263
|
-
level: 9
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
fs.writeFileSync(copyPath ? copyPath : mizPath, inputZip);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
async mizInjectMissionDataFile(mizPath, missionObject) {
|
|
270
|
-
const zip = await this.mizOpen(mizPath);
|
|
271
|
-
this.mizUpdateMissionDataFile(zip, missionObject);
|
|
272
|
-
const inputZip = await zip.generateAsync({
|
|
273
|
-
type: 'nodebuffer',
|
|
274
|
-
streamFiles: true,
|
|
275
|
-
compression: "DEFLATE",
|
|
276
|
-
compressionOptions: {
|
|
277
|
-
level: 9
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
fs.writeFileSync(mizPath, inputZip);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
async mizInjectSettingsFolder(mizPath, settingsFolder) {
|
|
284
|
-
const zip = await this.mizOpen(mizPath);
|
|
285
|
-
for (let file of fs.readdirSync(settingsFolder).filter(file => file.endsWith(".lua"))) {
|
|
286
|
-
this.mizUpdateLuaFile(zip, [
|
|
287
|
-
settingsFolder,
|
|
288
|
-
"/",
|
|
289
|
-
file].join(""));
|
|
290
|
-
}
|
|
291
|
-
const inputZip = await zip.generateAsync({
|
|
292
|
-
type: 'nodebuffer',
|
|
293
|
-
streamFiles: true,
|
|
294
|
-
compression: "DEFLATE",
|
|
295
|
-
compressionOptions: {
|
|
296
|
-
level: 9
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
fs.writeFileSync(mizPath, inputZip);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
async mizInjectMapResourceFile(mizPath, mapResourceObject) {
|
|
303
|
-
const zip = await this.mizOpen(mizPath);
|
|
304
|
-
this.mizUpdateMapResourceFile(zip, mapResourceObject);
|
|
305
|
-
const inputZip = await zip.generateAsync({
|
|
306
|
-
type: 'nodebuffer',
|
|
307
|
-
streamFiles: true,
|
|
308
|
-
compression: "DEFLATE",
|
|
309
|
-
compressionOptions: {
|
|
310
|
-
level: 9
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
|
-
fs.writeFileSync(mizPath, inputZip);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
mizUpdateLuaFile(zip, filePath) {
|
|
317
|
-
zip.remove("l10n/DEFAULT/" + path.basename(filePath));
|
|
318
|
-
var stream = fs.createReadStream(filePath);
|
|
319
|
-
zip.file("l10n/DEFAULT/" + path.basename(filePath), stream);
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
mizUpdateSrcLuaFiles(zip) {
|
|
323
|
-
for (let file of fs.readdirSync('src').filter(file => file.endsWith(".lua"))) {
|
|
324
|
-
console.log('updating src/' + file + ' file in miz file');
|
|
325
|
-
this.mizUpdateLuaFile(zip, "src/" + file);
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
mizUpdateMissionDataFile(zip, missionObject) {
|
|
330
|
-
zip.remove("mission");
|
|
331
|
-
let missionLuaT = format(missionObject, { singleQuote: false })
|
|
332
|
-
missionLuaT = missionLuaT
|
|
333
|
-
.split('\n')
|
|
334
|
-
.slice(1, -1)
|
|
335
|
-
.join('\n')
|
|
336
|
-
.slice(0, -1)
|
|
337
|
-
.replace(/\[\"(\d+)\"\] = /g, "[$1] = ");
|
|
338
|
-
zip.file("mission", missionLuaT);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
mizUpdateMapResourceFile(zip, mapResourceObject) {
|
|
342
|
-
zip.remove("l10n/DEFAULT/mapResource");
|
|
343
|
-
let mapResourceLuaT = format(mapResourceObject, { singleQuote: false })
|
|
344
|
-
mapResourceLuaT = mapResourceLuaT
|
|
345
|
-
.split('\n')
|
|
346
|
-
.slice(1, -1)
|
|
347
|
-
.join('\n')
|
|
348
|
-
.slice(0, -1)
|
|
349
|
-
.replace(/\[\"(\d+)\"\] = /g, "[$1] = ");
|
|
350
|
-
zip.file("l10n/DEFAULT/mapResource", mapResourceLuaT);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
mizOpenMissionData(zipStream) {
|
|
354
|
-
return zipStream.file("mission").async("string");
|
|
355
|
-
}
|
|
356
192
|
|
|
357
|
-
mizOpenMapResource(zipStream) {
|
|
358
|
-
return zipStream.file("l10n/DEFAULT/mapResource").async("string");
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
mizUpdateLibLuaFiles(zip) {
|
|
362
|
-
for (let file of fs.readdirSync('lib').filter(file => file.endsWith(".lua"))) {
|
|
363
|
-
console.log('updating lib/' + file + ' file in miz file');
|
|
364
|
-
this.mizUpdateLuaFile(zip, "lib/" + file);
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
async mizUpdateRadioPresets(zip, preset_folder) {
|
|
369
|
-
// Create folder Avionics to make sure it exists then delete it to remove any old preset in the template
|
|
370
|
-
// Allows adding presets for A-10C
|
|
371
|
-
zip.folder("Avionics");
|
|
372
|
-
zip.remove("Avionics");
|
|
373
|
-
|
|
374
|
-
const mission_object = await this.getMissionObjectFromZip(zip);
|
|
375
|
-
for (let file of fs.readdirSync(preset_folder).filter(file => file.endsWith(".lua"))) {
|
|
376
|
-
const file_data = fs.readFileSync(preset_folder + '/' + file).toString();
|
|
377
|
-
const lua_string = file_data.substring(0, file_data.indexOf("radio_descriptor_table =") - 1);
|
|
378
|
-
const radio_descriptor_table = parse("return {" + lua_string + "}").descriptor;
|
|
379
|
-
|
|
380
|
-
console.log('updating radio presets (aircraft: ' + radio_descriptor_table["aircraft"] + ', group_name: ' + radio_descriptor_table["group_name"] + ') with preset in ' + preset_folder + ' folder');
|
|
381
|
-
const dcs_radio_presets = file_data.substring(file_data.indexOf("radio_descriptor_table =") + 24);
|
|
382
|
-
|
|
383
|
-
for (const coalition_key in mission_object.coalition) {
|
|
384
|
-
const coalition = mission_object.coalition[coalition_key];
|
|
385
|
-
for (const country_list_key in coalition) {
|
|
386
|
-
if (country_list_key != "country") continue;
|
|
387
|
-
const country_list = coalition[country_list_key];
|
|
388
|
-
for (const country_key in country_list) {
|
|
389
|
-
const country = country_list[country_key];
|
|
390
|
-
for (const plane_key in country["plane"]) {
|
|
391
|
-
const plane = country["plane"][plane_key];
|
|
392
|
-
for (const group_key in plane) {
|
|
393
|
-
const group = plane[group_key];
|
|
394
|
-
if (group["name"].match(radio_descriptor_table["group_name"]) == null) continue;
|
|
395
|
-
for (const unit_key in group) {
|
|
396
|
-
if (unit_key != "units") continue;
|
|
397
|
-
const unit = group[unit_key];
|
|
398
|
-
for (const sub_unit_key in unit) {
|
|
399
|
-
const sub_unit = unit[sub_unit_key];
|
|
400
|
-
if (sub_unit["skill"] != "Client") continue;
|
|
401
|
-
// Aircraft is an A10CII, use A10C mode by creating files in the root with the unit id
|
|
402
|
-
// if (radio_descriptor_table["aircraft"] == 'A-10C_2') {
|
|
403
|
-
// const unit_id = sub_unit["unitId"];
|
|
404
|
-
// ["UHF_RADIO", "VHF_AM_RADIO", "VHF_FM_RADIO"].forEach(folder => {
|
|
405
|
-
// var zip_folder = zip.folder("Avionics/A-10C_2/" + unit_id + "/" + folder);
|
|
406
|
-
// var file = parse("return " + dcs_radio_presets)[folder];
|
|
407
|
-
// file = format(file, { singleQuote: false });
|
|
408
|
-
// file = file
|
|
409
|
-
// .split('\n')
|
|
410
|
-
// .slice(1, -1)
|
|
411
|
-
// .join('\n')
|
|
412
|
-
// .slice(0, -1)
|
|
413
|
-
// .replace(/\[\"(\d+)\"\] = /g, "[$1] = ");
|
|
414
|
-
// zip_folder.file("SETTINGS.lua", file);
|
|
415
|
-
// });
|
|
416
|
-
// continue;
|
|
417
|
-
// }
|
|
418
|
-
if (sub_unit["type"] != radio_descriptor_table["aircraft"]) continue;
|
|
419
|
-
// GROUP FOUND, SET RADIOS
|
|
420
|
-
sub_unit["Radio"] = parse("return " + dcs_radio_presets)
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
};
|
|
429
|
-
this.mizUpdateMissionDataFile(zip, {mission: mission_object});
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
mizUpdateSettingsLuaFiles(zip, strTheatre) {
|
|
433
|
-
for (let file of fs.readdirSync('settings/' + strTheatre).filter(file => file.endsWith(".lua"))) {
|
|
434
|
-
console.log('updating settings/' + strTheatre + '/' + file + ' file in miz file');
|
|
435
|
-
this.mizUpdateLuaFile(zip, 'settings/' + strTheatre + '/' + file);
|
|
436
|
-
};
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
async mizUpdateSoundFolders(zip) {
|
|
440
|
-
const folderArray = fs.readdirSync('resources/sounds');
|
|
441
|
-
for (const folder of folderArray) {
|
|
442
|
-
// if(zip.folder(new RegExp(folder)).length > 0 ) {
|
|
443
|
-
if (fs.existsSync('resources/sounds/' + folder) && fs.lstatSync('resources/sounds/' + folder).isDirectory()) {
|
|
444
|
-
await this.mizUpdateSingleSoundFolder(zip, folder);
|
|
445
|
-
}
|
|
446
|
-
// }
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
async mizUpdateSingleSoundFolder(zip, folder) {
|
|
451
|
-
console.log('adding sound files from resources/sounds/' + folder + ' folder...');
|
|
452
|
-
zip = zip.remove(folder).folder(folder);
|
|
453
|
-
await this.addFilesToZip(zip, 'resources/sounds/' + folder, fs.readdirSync('resources/sounds/' + folder));
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
async addFilesToZip(zip, directoryPath, filesToInclude) {
|
|
457
|
-
const promiseArr = await filesToInclude.map(async file => {
|
|
458
|
-
const filePath = path.join(directoryPath, file)
|
|
459
|
-
try {
|
|
460
|
-
const fileStats = await lstat(filePath)
|
|
461
|
-
const isDirectory = fileStats.isDirectory()
|
|
462
|
-
if (isDirectory) {
|
|
463
|
-
const directory = zip.remove(file).folder(file)
|
|
464
|
-
const subFiles = fs.readdirSync(filePath)
|
|
465
|
-
return this.addFilesToZip(directory, filePath, subFiles)
|
|
466
|
-
} else {
|
|
467
|
-
// console.log('added file : '+file);
|
|
468
|
-
return zip.file(file, fs.createReadStream(filePath))
|
|
469
|
-
}
|
|
470
|
-
} catch (err) {
|
|
471
|
-
console.log(err)
|
|
472
|
-
return Promise.resolve()
|
|
473
|
-
}
|
|
474
|
-
})
|
|
475
|
-
return Promise.all(promiseArr)
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
async copyMiz(srcMizPath, dstMizPath) {
|
|
479
|
-
await fs.createReadStream(srcMizPath).pipe(fs.createWriteStream(dstMizPath));
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
async getMissionObjectFromMiz(MizPath) {
|
|
483
|
-
let luaTable = 'return { \n' + await this.mizOpenMissionData(await this.mizOpen(MizPath)) + ' }';
|
|
484
|
-
return parse(luaTable).mission;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
async getMissionObjectFromZip(zip) {
|
|
488
|
-
let luaTable = 'return { \n' + await this.mizOpenMissionData(zip) + ' }';
|
|
489
|
-
return parse(luaTable).mission;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
async getMapResourceObjectFromMiz(MizPath) {
|
|
493
|
-
let luaTable = 'return { \n' + await this.mizOpenMapResource(await this.mizOpen(MizPath)) + ' }';
|
|
494
|
-
return parse(luaTable).mapResource;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
193
|
|
|
498
|
-
module.exports =
|
|
194
|
+
module.exports = MizTemplateCI;
|
package/lib/mizlib.js
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const jszip = require("jszip");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const {format, parse} = require("lua-json");
|
|
6
|
+
const {promisify} = require("util");
|
|
7
|
+
const fs = require("fs");
|
|
8
|
+
const lstat = promisify(fs.lstat);
|
|
9
|
+
|
|
10
|
+
class Mizlib {
|
|
11
|
+
constructor() {
|
|
12
|
+
// no need for initialization
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
injectLuaScriptsInMissionObject(tObject, trObject, mrObject, strTitle, scriptFilesArray, timingInSeconds, hexColor) {
|
|
16
|
+
let nextIndex = Object.keys(trObject).length + 1;
|
|
17
|
+
if (nextIndex === 1) {
|
|
18
|
+
tObject['actions'] = {};
|
|
19
|
+
tObject['func'] = {};
|
|
20
|
+
tObject['conditions'] = {};
|
|
21
|
+
tObject['flag'] = {};
|
|
22
|
+
trObject = {};
|
|
23
|
+
}
|
|
24
|
+
let actionSentence = "";
|
|
25
|
+
let actionsObject = {};
|
|
26
|
+
for (const [index, scriptFile] of scriptFilesArray.entries()) {
|
|
27
|
+
actionSentence += "a_do_script_file(getValueResourceByKey(\"" + scriptFile + "\")); "
|
|
28
|
+
actionsObject[index + 1] = {
|
|
29
|
+
file: scriptFile,
|
|
30
|
+
predicate: 'a_do_script_file',
|
|
31
|
+
};
|
|
32
|
+
mrObject[scriptFile] = scriptFile;
|
|
33
|
+
}
|
|
34
|
+
actionSentence += "mission.trig.func[" + nextIndex + "]=nil;"
|
|
35
|
+
tObject['actions'][nextIndex] = actionSentence;
|
|
36
|
+
tObject['func'][nextIndex] = "if mission.trig.conditions[" + nextIndex + "]() then mission.trig.actions[" + nextIndex + "]() end";
|
|
37
|
+
tObject['conditions'][nextIndex] = "return(c_time_after(" + timingInSeconds + ") )";
|
|
38
|
+
tObject['flag'][nextIndex] = true;
|
|
39
|
+
trObject[nextIndex] = {
|
|
40
|
+
rules: {
|
|
41
|
+
1: {
|
|
42
|
+
coalitionlist: 'red',
|
|
43
|
+
seconds: timingInSeconds,
|
|
44
|
+
predicate: 'c_time_after',
|
|
45
|
+
zone: ''
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
eventlist: '',
|
|
49
|
+
comment: strTitle,
|
|
50
|
+
actions: actionsObject,
|
|
51
|
+
predicate: 'triggerOnce',
|
|
52
|
+
colorItem: hexColor
|
|
53
|
+
};
|
|
54
|
+
return {tObject: tObject, trObject: trObject, mrObject: mrObject};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async getZipObjectFromMizPath(mizPath) {
|
|
58
|
+
var MizFile = new jszip();
|
|
59
|
+
const mizData = fs.readFileSync(mizPath);
|
|
60
|
+
return MizFile.loadAsync(mizData);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async mizUpdate(mizPath, copyPath, strTheatreSettings) {
|
|
64
|
+
const zip = await this.getZipObjectFromMizPath(mizPath);
|
|
65
|
+
this.injectLuaFilesFromFolderIntoZipObject(zip, 'src');
|
|
66
|
+
this.injectLuaFilesFromFolderIntoZipObject(zip, 'lib');
|
|
67
|
+
if (strTheatreSettings === null) {
|
|
68
|
+
// TODO: Inject fake data
|
|
69
|
+
console.log("NO THEATRE SPECIFIED. RADIO PRESETS WILL NOT BE AVAILABLE !");
|
|
70
|
+
} else {
|
|
71
|
+
await this.mizUpdateRadioPresets(zip, 'resources/radios/' + strTheatreSettings);
|
|
72
|
+
}
|
|
73
|
+
this.mizUpdateSettingsLuaFiles(zip, strTheatreSettings);
|
|
74
|
+
await this.mizUpdateSoundFolders(zip);
|
|
75
|
+
const inputZip = await zip.generateAsync({
|
|
76
|
+
type: 'nodebuffer',
|
|
77
|
+
streamFiles: true,
|
|
78
|
+
compression: "DEFLATE",
|
|
79
|
+
compressionOptions: {
|
|
80
|
+
level: 9
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
fs.writeFileSync(copyPath ? copyPath : mizPath, inputZip);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async mizInjectMissionDataFile(mizPath, missionObject) {
|
|
87
|
+
const zip = await this.getZipObjectFromMizPath(mizPath);
|
|
88
|
+
this.mizUpdateMissionDataFile(zip, missionObject);
|
|
89
|
+
const inputZip = await zip.generateAsync({
|
|
90
|
+
type: 'nodebuffer',
|
|
91
|
+
streamFiles: true,
|
|
92
|
+
compression: "DEFLATE",
|
|
93
|
+
compressionOptions: {
|
|
94
|
+
level: 9
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
fs.writeFileSync(mizPath, inputZip);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async injectLuaSettingsFromFolderPathToMizPath(mizPath, settingsFolder) {
|
|
101
|
+
const zip = await this.getZipObjectFromMizPath(mizPath);
|
|
102
|
+
await this.injectLuaSettingsFromFolderPathToZipObject(zip, settingsFolder);
|
|
103
|
+
const outputZip = await zip.generateAsync({
|
|
104
|
+
type: 'nodebuffer',
|
|
105
|
+
streamFiles: true,
|
|
106
|
+
compression: "DEFLATE",
|
|
107
|
+
compressionOptions: {
|
|
108
|
+
level: 9
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
fs.writeFileSync(mizPath, outputZip);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async injectLuaSettingsFromFolderPathToZipObject(zip, settingsFolder) {
|
|
115
|
+
for (let file of fs.readdirSync(settingsFolder).filter(file => file.endsWith(".lua"))) {
|
|
116
|
+
this.injectFileIntoZipObject(zip, [
|
|
117
|
+
settingsFolder,
|
|
118
|
+
"/",
|
|
119
|
+
file].join(""));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
async mizInjectMapResourceFile(mizPath, mapResourceObject) {
|
|
125
|
+
const zip = await this.getZipObjectFromMizPath(mizPath);
|
|
126
|
+
this.mizUpdateMapResourceFile(zip, mapResourceObject);
|
|
127
|
+
const inputZip = await zip.generateAsync({
|
|
128
|
+
type: 'nodebuffer',
|
|
129
|
+
streamFiles: true,
|
|
130
|
+
compression: "DEFLATE",
|
|
131
|
+
compressionOptions: {
|
|
132
|
+
level: 9
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
fs.writeFileSync(mizPath, inputZip);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
injectFileIntoZipObject(zip, filePath) {
|
|
139
|
+
zip.remove("l10n/DEFAULT/" + path.basename(filePath));
|
|
140
|
+
var stream = fs.createReadStream(filePath);
|
|
141
|
+
zip.file("l10n/DEFAULT/" + path.basename(filePath), stream);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
mizUpdateMissionDataFile(zip, missionObject) {
|
|
145
|
+
zip.remove("mission");
|
|
146
|
+
let missionLuaT = format(missionObject, {singleQuote: false})
|
|
147
|
+
missionLuaT = missionLuaT
|
|
148
|
+
.split('\n')
|
|
149
|
+
.slice(1, -1)
|
|
150
|
+
.join('\n')
|
|
151
|
+
.slice(0, -1)
|
|
152
|
+
.replace(/\[\"(\d+)\"\] = /g, "[$1] = ");
|
|
153
|
+
zip.file("mission", missionLuaT);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
mizUpdateMapResourceFile(zip, mapResourceObject) {
|
|
157
|
+
zip.remove("l10n/DEFAULT/mapResource");
|
|
158
|
+
let mapResourceLuaT = format(mapResourceObject, {singleQuote: false})
|
|
159
|
+
mapResourceLuaT = mapResourceLuaT
|
|
160
|
+
.split('\n')
|
|
161
|
+
.slice(1, -1)
|
|
162
|
+
.join('\n')
|
|
163
|
+
.slice(0, -1)
|
|
164
|
+
.replace(/\[\"(\d+)\"\] = /g, "[$1] = ");
|
|
165
|
+
zip.file("l10n/DEFAULT/mapResource", mapResourceLuaT);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
getMissionLuaStringFromZipObject(zipStream) {
|
|
169
|
+
return zipStream.file("mission").async("string");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
getMapResourceLuaStringFromZipObject(zipStream) {
|
|
173
|
+
return zipStream.file("l10n/DEFAULT/mapResource").async("string");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
injectLuaFilesFromFolderIntoZipObject(zip, folderPath) {
|
|
177
|
+
for (let file of fs.readdirSync(folderPath).filter(file => file.endsWith(".lua"))) {
|
|
178
|
+
console.log('injecting up2date ' + folderPath + '/' + file + ' file in archive');
|
|
179
|
+
this.injectFileIntoZipObject(zip, folderPath + "/" + file);
|
|
180
|
+
}
|
|
181
|
+
;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
async mizUpdateRadioPresets(zip, preset_folder) {
|
|
186
|
+
// Create folder Avionics to make sure it exists then delete it to remove any old preset in the template
|
|
187
|
+
// Allows adding presets for A-10C
|
|
188
|
+
zip.folder("Avionics");
|
|
189
|
+
zip.remove("Avionics");
|
|
190
|
+
|
|
191
|
+
const mission_object = await this.getMissionObjectFromZipObject(zip);
|
|
192
|
+
for (let file of fs.readdirSync(preset_folder).filter(file => file.endsWith(".lua"))) {
|
|
193
|
+
const file_data = fs.readFileSync(preset_folder + '/' + file).toString();
|
|
194
|
+
const lua_string = file_data.substring(0, file_data.indexOf("radio_descriptor_table =") - 1);
|
|
195
|
+
const radio_descriptor_table = parse("return {" + lua_string + "}").descriptor;
|
|
196
|
+
|
|
197
|
+
console.log('updating radio presets (aircraft: ' + radio_descriptor_table["aircraft"] + ', group_name: ' + radio_descriptor_table["group_name"] + ') with preset in ' + preset_folder + ' folder');
|
|
198
|
+
const dcs_radio_presets = file_data.substring(file_data.indexOf("radio_descriptor_table =") + 24);
|
|
199
|
+
|
|
200
|
+
for (const coalition_key in mission_object.coalition) {
|
|
201
|
+
const coalition = mission_object.coalition[coalition_key];
|
|
202
|
+
for (const country_list_key in coalition) {
|
|
203
|
+
if (country_list_key != "country") continue;
|
|
204
|
+
const country_list = coalition[country_list_key];
|
|
205
|
+
for (const country_key in country_list) {
|
|
206
|
+
const country = country_list[country_key];
|
|
207
|
+
for (const plane_key in country["plane"]) {
|
|
208
|
+
const plane = country["plane"][plane_key];
|
|
209
|
+
for (const group_key in plane) {
|
|
210
|
+
const group = plane[group_key];
|
|
211
|
+
if (group["name"].match(radio_descriptor_table["group_name"]) == null) continue;
|
|
212
|
+
for (const unit_key in group) {
|
|
213
|
+
if (unit_key != "units") continue;
|
|
214
|
+
const unit = group[unit_key];
|
|
215
|
+
for (const sub_unit_key in unit) {
|
|
216
|
+
const sub_unit = unit[sub_unit_key];
|
|
217
|
+
if (sub_unit["skill"] != "Client") continue;
|
|
218
|
+
// Aircraft is an A10CII, use A10C mode by creating files in the root with the unit id
|
|
219
|
+
// if (radio_descriptor_table["aircraft"] == 'A-10C_2') {
|
|
220
|
+
// const unit_id = sub_unit["unitId"];
|
|
221
|
+
// ["UHF_RADIO", "VHF_AM_RADIO", "VHF_FM_RADIO"].forEach(folder => {
|
|
222
|
+
// var zip_folder = zip.folder("Avionics/A-10C_2/" + unit_id + "/" + folder);
|
|
223
|
+
// var file = parse("return " + dcs_radio_presets)[folder];
|
|
224
|
+
// file = format(file, { singleQuote: false });
|
|
225
|
+
// file = file
|
|
226
|
+
// .split('\n')
|
|
227
|
+
// .slice(1, -1)
|
|
228
|
+
// .join('\n')
|
|
229
|
+
// .slice(0, -1)
|
|
230
|
+
// .replace(/\[\"(\d+)\"\] = /g, "[$1] = ");
|
|
231
|
+
// zip_folder.file("SETTINGS.lua", file);
|
|
232
|
+
// });
|
|
233
|
+
// continue;
|
|
234
|
+
// }
|
|
235
|
+
if (sub_unit["type"] != radio_descriptor_table["aircraft"]) continue;
|
|
236
|
+
// GROUP FOUND, SET RADIOS
|
|
237
|
+
sub_unit["Radio"] = parse("return " + dcs_radio_presets)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
this.mizUpdateMissionDataFile(zip, {mission: mission_object});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
mizUpdateSettingsLuaFiles(zip, strTheatre) {
|
|
250
|
+
for (let file of fs.readdirSync('settings/' + strTheatre).filter(file => file.endsWith(".lua"))) {
|
|
251
|
+
console.log('updating settings/' + strTheatre + '/' + file + ' file in miz file');
|
|
252
|
+
this.injectFileIntoZipObject(zip, 'settings/' + strTheatre + '/' + file);
|
|
253
|
+
}
|
|
254
|
+
;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async mizUpdateSoundFolders(zip) {
|
|
258
|
+
if (fs.existsSync('resources/sounds') && fs.lstatSync('resources/sounds').isDirectory()) {
|
|
259
|
+
const folderArray = fs.readdirSync('resources/sounds');
|
|
260
|
+
for (const folder of folderArray) {
|
|
261
|
+
await this.mizUpdateSingleSoundFolder(zip, folder);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async mizUpdateSingleSoundFolder(zip, folder) {
|
|
267
|
+
if (fs.existsSync('resources/sounds/' + folder) && fs.lstatSync('resources/sounds/' + folder).isDirectory()) {
|
|
268
|
+
console.log('adding sound files from resources/sounds/' + folder + ' folder...');
|
|
269
|
+
zip = zip.remove(folder).folder(folder);
|
|
270
|
+
await this.addFilesToZip(zip, 'resources/sounds/' + folder, fs.readdirSync('resources/sounds/' + folder));
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async addFilesToZip(zip, directoryPath, filesToInclude) {
|
|
275
|
+
const promiseArr = await filesToInclude.map(async file => {
|
|
276
|
+
const filePath = path.join(directoryPath, file)
|
|
277
|
+
try {
|
|
278
|
+
const fileStats = await lstat(filePath)
|
|
279
|
+
const isDirectory = fileStats.isDirectory()
|
|
280
|
+
if (isDirectory) {
|
|
281
|
+
const directory = zip.remove(file).folder(file)
|
|
282
|
+
const subFiles = fs.readdirSync(filePath)
|
|
283
|
+
return this.addFilesToZip(directory, filePath, subFiles)
|
|
284
|
+
} else {
|
|
285
|
+
// console.log('added file : '+file);
|
|
286
|
+
return zip.file(file, fs.createReadStream(filePath))
|
|
287
|
+
}
|
|
288
|
+
} catch (err) {
|
|
289
|
+
console.log(err)
|
|
290
|
+
return Promise.resolve()
|
|
291
|
+
}
|
|
292
|
+
})
|
|
293
|
+
return Promise.all(promiseArr)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
async copyMiz(srcMizPath, dstMizPath) {
|
|
297
|
+
await fs.createReadStream(srcMizPath).pipe(fs.createWriteStream(dstMizPath));
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
async getMissionObjectFromMizPath(MizPath) {
|
|
301
|
+
let luaTable = 'return { \n' + await this.getMissionLuaStringFromZipObject(await this.getZipObjectFromMizPath(MizPath)) + ' }';
|
|
302
|
+
return parse(luaTable).mission;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
async getMissionObjectFromZipObject(zip) {
|
|
306
|
+
let luaTable = 'return { \n' + await this.getMissionLuaStringFromZipObject(zip) + ' }';
|
|
307
|
+
return parse(luaTable).mission;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
async getMapResourceObjectFromMizPath(MizPath) {
|
|
311
|
+
let luaTable = 'return { \n' + await this.getMapResourceLuaStringFromZipObject(await this.getZipObjectFromMizPath(MizPath)) + ' }';
|
|
312
|
+
return parse(luaTable).mapResource;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async getMapResourceObjectFromZipObject(zip) {
|
|
316
|
+
let luaTable = 'return { \n' + await this.getMapResourceLuaStringFromZipObject(zip) + ' }';
|
|
317
|
+
return parse(luaTable).mapResource;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
module.exports = Mizlib
|