From cd4f7918c81ad32a5e3f664b93db50e2bf40a22e Mon Sep 17 00:00:00 2001 From: Daniel Scalzi Date: Mon, 7 May 2018 18:15:59 -0400 Subject: [PATCH] Pipe output from forked processes back to parent. Also cleaned up the code a bit. Switched to use lambda declarations in promises and renamed 'fulfill' to 'resolve', as it should be, --- app/assets/js/assetguard.js | 95 ++++++++++++++----------------- app/assets/js/authmanager.js | 2 +- app/assets/js/mojang.js | 22 +++---- app/assets/js/scripts/landing.js | 36 +++++++++--- app/assets/js/scripts/uibinder.js | 2 +- 5 files changed, 84 insertions(+), 73 deletions(-) diff --git a/app/assets/js/assetguard.js b/app/assets/js/assetguard.js index cbe9cb7..b925d33 100644 --- a/app/assets/js/assetguard.js +++ b/app/assets/js/assetguard.js @@ -98,7 +98,7 @@ class Library extends Asset { if(rules == null) return true let result = true - rules.forEach(function(rule){ + rules.forEach((rule) => { const action = rule['action'] const osProp = rule['os'] if(action != null){ @@ -381,7 +381,7 @@ class AssetGuard extends EventEmitter { * @returns {Promise.} A promise which resolves to the distribution data object. */ static retrieveDistributionData(launcherPath, cached = true){ - return new Promise(function(resolve, reject){ + return new Promise((resolve, reject) => { if(!cached || distributionData == null){ // TODO Download file from upstream. const distroURL = 'http://mc.westeroscraft.com/WesterosCraftLauncher/westeroscraft.json' @@ -401,7 +401,7 @@ class AssetGuard extends EventEmitter { // Workaround while file is not hosted. /*fs.readFile(path.join(__dirname, '..', 'westeroscraft.json'), 'utf-8', (err, data) => { distributionData = JSON.parse(data) - fulfill(distributionData) + resolve(distributionData) })*/ } else { resolve(distributionData) @@ -477,7 +477,11 @@ class AssetGuard extends EventEmitter { * @returns {Promise.} An empty promise to indicate the extraction has completed. */ static _extractPackXZ(filePaths, javaExecutable){ - return new Promise(function(resolve, reject){ + console.log('[PackXZExtract] Starting') + return new Promise((resolve, reject) => { + + + let libPath if(isDev){ libPath = path.join(process.cwd(), 'libraries', 'java', 'PackXZExtract.jar') @@ -488,17 +492,17 @@ class AssetGuard extends EventEmitter { libPath = path.join(process.cwd(), 'resources', 'libraries', 'java', 'PackXZExtract.jar') } } - + const filePath = filePaths.join(',') const child = child_process.spawn(javaExecutable, ['-jar', libPath, '-packxz', filePath]) child.stdout.on('data', (data) => { - console.log('PackXZExtract:', data.toString('utf8')) + console.log('[PackXZExtract]', data.toString('utf8')) }) child.stderr.on('data', (data) => { - console.log('PackXZExtract:', data.toString('utf8')) + console.log('[PackXZExtract]', data.toString('utf8')) }) child.on('close', (code, signal) => { - console.log('PackXZExtract: Exited with code', code) + console.log('[PackXZExtract]', 'Exited with code', code) resolve() }) }) @@ -515,7 +519,7 @@ class AssetGuard extends EventEmitter { * @returns {Promise.} A promise which resolves to the contents of forge's version.json. */ static _finalizeForgeAsset(asset, basePath){ - return new Promise(function(resolve, reject){ + return new Promise((resolve, reject) => { fs.readFile(asset.to, (err, data) => { const zip = new AdmZip(data) const zipEntries = zip.getEntries() @@ -1066,9 +1070,9 @@ class AssetGuard extends EventEmitter { */ validateAssets(versionData, force = false){ const self = this - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { self._assetChainIndexData(versionData, force).then(() => { - fulfill() + resolve() }) }) } @@ -1083,7 +1087,7 @@ class AssetGuard extends EventEmitter { */ _assetChainIndexData(versionData, force = false){ const self = this - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { //Asset index constants. const assetIndex = versionData.assetIndex const name = assetIndex.id + '.json' @@ -1095,16 +1099,16 @@ class AssetGuard extends EventEmitter { console.log('Downloading ' + versionData.id + ' asset index.') mkpath.sync(indexPath) const stream = request(assetIndex.url).pipe(fs.createWriteStream(assetIndexLoc)) - stream.on('finish', function() { + stream.on('finish', () => { data = JSON.parse(fs.readFileSync(assetIndexLoc, 'utf-8')) self._assetChainValidateAssets(versionData, data).then(() => { - fulfill() + resolve() }) }) } else { data = JSON.parse(fs.readFileSync(assetIndexLoc, 'utf-8')) self._assetChainValidateAssets(versionData, data).then(() => { - fulfill() + resolve() }) } }) @@ -1119,7 +1123,7 @@ class AssetGuard extends EventEmitter { */ _assetChainValidateAssets(versionData, indexData){ const self = this - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { //Asset constants const resourceURL = 'http://resources.download.minecraft.net/' @@ -1132,7 +1136,7 @@ class AssetGuard extends EventEmitter { let acc = 0 const total = Object.keys(indexData.objects).length //const objKeys = Object.keys(data.objects) - async.forEachOfLimit(indexData.objects, 10, function(value, key, cb){ + async.forEachOfLimit(indexData.objects, 10, (value, key, cb) => { acc++ self.emit('assetVal', {acc, total}) const hash = value.hash @@ -1144,9 +1148,9 @@ class AssetGuard extends EventEmitter { assetDlQueue.push(ast) } cb() - }, function(err){ + }, (err) => { self.assets = new DLTracker(assetDlQueue, dlSize) - fulfill() + resolve() }) }) } @@ -1167,7 +1171,7 @@ class AssetGuard extends EventEmitter { */ validateLibraries(versionData){ const self = this - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { const libArr = versionData.libraries const libPath = path.join(self.basePath, 'libraries') @@ -1176,7 +1180,7 @@ class AssetGuard extends EventEmitter { let dlSize = 0 //Check validity of each library. If the hashs don't match, download the library. - async.eachLimit(libArr, 5, function(lib, cb){ + async.eachLimit(libArr, 5, (lib, cb) => { if(Library.validateRules(lib.rules)){ let artifact = (lib.natives == null) ? lib.downloads.artifact : lib.downloads.classifiers[lib.natives[Library.mojangFriendlyOS()]] const libItm = new Library(lib.name, artifact.sha1, artifact.size, artifact.url, path.join(libPath, artifact.path)) @@ -1186,9 +1190,9 @@ class AssetGuard extends EventEmitter { } } cb() - }, function(err){ + }, (err) => { self.libraries = new DLTracker(libDlQueue, dlSize) - fulfill() + resolve() }) }) } @@ -1207,10 +1211,10 @@ class AssetGuard extends EventEmitter { */ validateMiscellaneous(versionData){ const self = this - return new Promise(async function(fulfill, reject){ + return new Promise(async (resolve, reject) => { await self.validateClient(versionData) await self.validateLogConfig(versionData) - fulfill() + resolve() }) } @@ -1223,7 +1227,7 @@ class AssetGuard extends EventEmitter { */ validateClient(versionData, force = false){ const self = this - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { const clientData = versionData.downloads.client const version = versionData.id const targetPath = path.join(self.basePath, 'versions', version) @@ -1234,9 +1238,9 @@ class AssetGuard extends EventEmitter { if(!AssetGuard._validateLocal(client.to, 'sha1', client.hash) || force){ self.files.dlqueue.push(client) self.files.dlsize += client.size*1 - fulfill() + resolve() } else { - fulfill() + resolve() } }) } @@ -1250,7 +1254,7 @@ class AssetGuard extends EventEmitter { */ validateLogConfig(versionData){ const self = this - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { const client = versionData.logging.client const file = client.file const targetPath = path.join(self.basePath, 'assets', 'log_configs') @@ -1260,9 +1264,9 @@ class AssetGuard extends EventEmitter { if(!AssetGuard._validateLocal(logConfig.to, 'sha1', logConfig.hash)){ self.files.dlqueue.push(logConfig) self.files.dlsize += logConfig.size*1 - fulfill() + resolve() } else { - fulfill() + resolve() } }) } @@ -1280,7 +1284,7 @@ class AssetGuard extends EventEmitter { */ validateDistribution(serverpackid){ const self = this - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { AssetGuard.retrieveDistributionData(self.launcherPath, false).then((value) => { /*const servers = value.servers let serv = null @@ -1300,29 +1304,16 @@ class AssetGuard extends EventEmitter { // Correct our workaround here. let decompressqueue = self.forge.callback self.extractQueue = decompressqueue - self.forge.callback = function(asset, self){ + self.forge.callback = (asset, self) => { if(asset.type === 'forge-hosted' || asset.type === 'forge'){ AssetGuard._finalizeForgeAsset(asset, self.basePath) } } - fulfill(serv) + resolve(serv) }) }) } - /*//TODO The file should be hosted, the following code is for local testing. - _chainValidateDistributionIndex(basePath){ - return new Promise(function(fulfill, reject){ - //const distroURL = 'http://mc.westeroscraft.com/WesterosCraftLauncher/westeroscraft.json' - //const targetFile = path.join(basePath, 'westeroscraft.json') - - //TEMP WORKAROUND TO TEST WHILE THIS IS NOT HOSTED - fs.readFile(path.join(__dirname, '..', 'westeroscraft.json'), 'utf-8', (err, data) => { - fulfill(JSON.parse(data)) - }) - }) - }*/ - _parseDistroModules(modules, version){ let alist = [] let asize = 0; @@ -1378,7 +1369,7 @@ class AssetGuard extends EventEmitter { */ loadForgeData(serverpack){ const self = this - return new Promise(async function(fulfill, reject){ + return new Promise(async (resolve, reject) => { let distro = AssetGuard.retrieveDistributionDataSync(self.launcherPath) const servers = distro.servers @@ -1398,7 +1389,7 @@ class AssetGuard extends EventEmitter { let obPath = obArtifact.path == null ? path.join(self.basePath, 'libraries', AssetGuard._resolvePath(ob.id, obArtifact.extension)) : obArtifact.path let asset = new DistroModule(ob.id, obArtifact.MD5, obArtifact.size, obArtifact.url, obPath, ob.type) let forgeData = await AssetGuard._finalizeForgeAsset(asset, self.basePath) - fulfill(forgeData) + resolve(forgeData) return } } @@ -1541,7 +1532,7 @@ class AssetGuard extends EventEmitter { if(concurrentDlQueue.length === 0){ return false } else { - async.eachLimit(concurrentDlQueue, limit, function(asset, cb){ + async.eachLimit(concurrentDlQueue, limit, (asset, cb) => { let count = 0; mkpath.sync(path.join(asset.to, "..")) let req = request(asset.from) @@ -1570,14 +1561,14 @@ class AssetGuard extends EventEmitter { req.on('error', (err) => { self.emit('dlerror', err) }) - req.on('data', function(chunk){ + req.on('data', (chunk) => { count += chunk.length self.progress += chunk.length acc += chunk.length self.emit(identifier + 'dlprogress', acc) self.emit('totaldlprogress', {acc: self.progress, total: self.totaldlsize}) }) - }, function(err){ + }, (err) => { if(err){ self.emit(identifier + 'dlerror') console.log('An item in ' + identifier + ' failed to process'); diff --git a/app/assets/js/authmanager.js b/app/assets/js/authmanager.js index 240c8fb..d20935d 100644 --- a/app/assets/js/authmanager.js +++ b/app/assets/js/authmanager.js @@ -24,7 +24,7 @@ const Mojang = require('./mojang.js') * @returns {Promise.} Promise which resolves the resolved authenticated account object. */ exports.addAccount = async function(username, password){ - try{ + try { const session = await Mojang.authenticate(username, password, ConfigManager.getClientToken) const ret = ConfigManager.addAuthAccount(session.selectedProfile.id, session.accessToken, username, session.selectedProfile.name) ConfigManager.save() diff --git a/app/assets/js/mojang.js b/app/assets/js/mojang.js index cb7491e..1a6ad21 100644 --- a/app/assets/js/mojang.js +++ b/app/assets/js/mojang.js @@ -80,7 +80,7 @@ exports.statusToHex = function(status){ * @see http://wiki.vg/Mojang_API#API_Status */ exports.status = function(){ - return new Promise(function(fulfill, reject) { + return new Promise((resolve, reject) => { request.get('https://status.mojang.com/check', { json: true @@ -102,7 +102,7 @@ exports.status = function(){ } } } - fulfill(statuses) + resolve(statuses) } }) }) @@ -120,7 +120,7 @@ exports.status = function(){ * @see http://wiki.vg/Authentication#Authenticate */ exports.authenticate = function(username, password, clientToken, requestUser = true, agent = minecraftAgent){ - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { request.post(authpath + '/authenticate', { json: true, @@ -138,7 +138,7 @@ exports.authenticate = function(username, password, clientToken, requestUser = t reject(error) } else { if(response.statusCode === 200){ - fulfill(body) + resolve(body) } else { reject(body || {code: 'ENOTFOUND'}) } @@ -157,7 +157,7 @@ exports.authenticate = function(username, password, clientToken, requestUser = t * @see http://wiki.vg/Authentication#Validate */ exports.validate = function(accessToken, clientToken){ - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { request.post(authpath + '/validate', { json: true, @@ -172,10 +172,10 @@ exports.validate = function(accessToken, clientToken){ reject(error) } else { if(response.statusCode === 403){ - fulfill(false) + resolve(false) } else { // 204 if valid - fulfill(true) + resolve(true) } } }) @@ -192,7 +192,7 @@ exports.validate = function(accessToken, clientToken){ * @see http://wiki.vg/Authentication#Invalidate */ exports.invalidate = function(accessToken, clientToken){ - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { request.post(authpath + '/invalidate', { json: true, @@ -207,7 +207,7 @@ exports.invalidate = function(accessToken, clientToken){ reject(error) } else { if(response.statusCode === 204){ - fulfill() + resolve() } else { reject(body) } @@ -228,7 +228,7 @@ exports.invalidate = function(accessToken, clientToken){ * @see http://wiki.vg/Authentication#Refresh */ exports.refresh = function(accessToken, clientToken, requestUser = true){ - return new Promise(function(fulfill, reject){ + return new Promise((resolve, reject) => { request.post(authpath + '/refresh', { json: true, @@ -244,7 +244,7 @@ exports.refresh = function(accessToken, clientToken, requestUser = true){ reject(error) } else { if(response.statusCode === 200){ - fulfill(body) + resolve(body) } else { reject(body) } diff --git a/app/assets/js/scripts/landing.js b/app/assets/js/scripts/landing.js index 00a3103..799a8d3 100644 --- a/app/assets/js/scripts/landing.js +++ b/app/assets/js/scripts/landing.js @@ -6,12 +6,12 @@ const cp = require('child_process') const {URL} = require('url') // Internal Requirements -const {AssetGuard} = require(path.join(__dirname, 'assets', 'js', 'assetguard.js')) -const AuthManager = require(path.join(__dirname, 'assets', 'js', 'authmanager.js')) -const DiscordWrapper = require(path.join(__dirname, 'assets', 'js', 'discordwrapper.js')) -const Mojang = require(path.join(__dirname, 'assets', 'js', 'mojang.js')) -const ProcessBuilder = require(path.join(__dirname, 'assets', 'js', 'processbuilder.js')) -const ServerStatus = require(path.join(__dirname, 'assets', 'js', 'serverstatus.js')) +const {AssetGuard} = require('./assets/js/assetguard.js') +const AuthManager = require('./assets/js/authmanager.js') +const DiscordWrapper = require('./assets/js/discordwrapper.js') +const Mojang = require('./assets/js/mojang.js') +const ProcessBuilder = require('./assets/js/processbuilder.js') +const ServerStatus = require('./assets/js/serverstatus.js') // Launch Elements const launch_content = document.getElementById('launch_content') @@ -223,7 +223,17 @@ function asyncSystemScan(launchAfter = true){ ConfigManager.getGameDirectory(), ConfigManager.getLauncherDirectory(), ConfigManager.getJavaExecutable() - ]) + ], { + stdio: 'pipe' + }) + // Stdout + sysAEx.stdio[1].on('data', (data) => { + console.log('%c[SysAEx]', 'color: #353232; font-weight: bold', data.toString('utf-8')) + }) + // Stderr + sysAEx.stdio[2].on('data', (data) => { + console.log('%c[SysAEx]', 'color: #353232; font-weight: bold', data.toString('utf-8')) + }) sysAEx.on('message', (m) => { if(m.content === 'validateJava'){ @@ -392,7 +402,17 @@ function dlAsync(login = true){ ConfigManager.getGameDirectory(), ConfigManager.getLauncherDirectory(), ConfigManager.getJavaExecutable() - ]) + ], { + stdio: 'pipe' + }) + // Stdout + aEx.stdio[1].on('data', (data) => { + console.log('%c[AEx]', 'color: #353232; font-weight: bold', data.toString('utf-8')) + }) + // Stderr + aEx.stdio[2].on('data', (data) => { + console.log('%c[AEx]', 'color: #353232; font-weight: bold', data.toString('utf-8')) + }) // Establish communications between the AssetExec and current process. aEx.on('message', (m) => { diff --git a/app/assets/js/scripts/uibinder.js b/app/assets/js/scripts/uibinder.js index 9c5ee4c..b7d2d71 100644 --- a/app/assets/js/scripts/uibinder.js +++ b/app/assets/js/scripts/uibinder.js @@ -4,7 +4,7 @@ */ // Requirements const path = require('path') -const ConfigManager = require(path.join(__dirname, 'assets', 'js', 'configmanager.js')) +const ConfigManager = require('./assets/js/configmanager.js') let rscShouldLoad = false