From f1d89c0e6b60e12c2c62748cd5f61207447ddb4b Mon Sep 17 00:00:00 2001 From: Daniel Scalzi Date: Mon, 13 Aug 2018 08:25:25 -0400 Subject: [PATCH] Fixed game status monitoring. Switched to version-safe regex for monitoring game launch progress. Game output is now encoded in utf-8 to avoid multiple conversions from Uint8Array to String. Note that game output has line breaks. Trim any content before testing it against regular expressions. --- app/assets/js/processbuilder.js | 15 ++++---- app/assets/js/scripts/landing.js | 59 +++++++++++++++++--------------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/app/assets/js/processbuilder.js b/app/assets/js/processbuilder.js index db07184..d96fb2b 100644 --- a/app/assets/js/processbuilder.js +++ b/app/assets/js/processbuilder.js @@ -37,9 +37,8 @@ class ProcessBuilder { const tempNativePath = path.join(os.tmpdir(), ConfigManager.getTempNativeFolder(), crypto.pseudoRandomBytes(16).toString('hex')) process.throwDeprecation = true this.setupLiteLoader() - console.log('using liteloader', this.usingLiteLoader) + console.log('%c[ProcessBuilder]', 'color: #003996; font-weight: bold', 'Using liteloader:', this.usingLiteLoader) const modObj = this.resolveModConfiguration(ConfigManager.getModConfiguration(this.server.getID()).mods, this.server.getModules()) - console.log(modObj) this.constructModList('forge', modObj.fMods, true) if(this.usingLiteLoader){ this.constructModList('liteloader', modObj.lMods, true) @@ -58,19 +57,21 @@ class ProcessBuilder { child.unref() } + child.stdout.setEncoding('utf8') + child.stdout.on('data', (data) => { - console.log('Minecraft:', data.toString('utf8')) + console.log('%c[Minecraft]', 'color: #36b030; font-weight: bold', data) }) child.stderr.on('data', (data) => { - console.log('Minecraft:', data.toString('utf8')) + console.log('%c[Minecraft]', 'color: #36b030; font-weight: bold', data) }) child.on('close', (code, signal) => { - console.log('Exited with code', code) + console.log('%c[ProcessBuilder]', 'color: #003996; font-weight: bold', 'Exited with code', code) rimraf(tempNativePath, (err) => { if(err){ - console.warn('Error while deleting temp dir', err) + console.warn('%c[ProcessBuilder]', 'color: #003996; font-weight: bold', 'Error while deleting temp dir', err) } else { - console.log('Temp dir deleted successfully.') + console.log('%c[ProcessBuilder]', 'color: #003996; font-weight: bold', 'Temp dir deleted successfully.') } }) }) diff --git a/app/assets/js/scripts/landing.js b/app/assets/js/scripts/landing.js index eef7826..1465e9b 100644 --- a/app/assets/js/scripts/landing.js +++ b/app/assets/js/scripts/landing.js @@ -424,9 +424,9 @@ let proc // Is DiscordRPC enabled let hasRPC = false // Joined server regex -const servJoined = /[[0-2][0-9]:[0-6][0-9]:[0-6][0-9]\] \[Client thread\/INFO\]: \[CHAT\] [a-zA-Z0-9_]{1,16} joined the game/g -const gameJoined = /\[[0-2][0-9]:[0-6][0-9]:[0-6][0-9]\] \[Client thread\/WARN\]: Skipping bad option: lastServer:/g -const gameJoined2 = /\[[0-2][0-9]:[0-6][0-9]:[0-6][0-9]\] \[Client thread\/INFO\]: Created: \d+x\d+ textures-atlas/g +const SERVER_JOINED_REGEX = /\[.+\]: \[CHAT\] [a-zA-Z0-9_]{1,16} joined the game/ +const GAME_JOINED_REGEX = /\[.+\]: Skipping bad option: lastServer:/ +const GAME_LAUNCH_REGEX = /^\[.+\]: MinecraftForge .+ Initialized$/ let aEx let serv @@ -585,37 +585,40 @@ function dlAsync(login = true){ console.log('authu', authUser) let pb = new ProcessBuilder(serv, versionData, forgeData, authUser) setLaunchDetails('Launching game..') + + // Attach a temporary listener to the client output. + // Will wait for a certain bit of text meaning that + // the client application has started, and we can hide + // the progress bar stuff. + const tempListener = function(data){ + if(GAME_LAUNCH_REGEX.test(data.trim())){ + toggleLaunchArea(false) + if(hasRPC){ + DiscordWrapper.updateDetails('Loading game..') + } + proc.stdout.on('data', gameStateChange) + proc.stdout.removeListener('data', tempListener) + } + } + + // Listener for Discord RPC. + const gameStateChange = function(data){ + data = data.trim() + if(SERVER_JOINED_REGEX.test(data)){ + DiscordWrapper.updateDetails('Exploring the Realm!') + } else if(GAME_JOINED_REGEX.test(data)){ + DiscordWrapper.updateDetails('Sailing to Westeros!') + } + } + try { // Build Minecraft process. proc = pb.build() - setLaunchDetails('Done. Enjoy the server!') - - // Attach a temporary listener to the client output. - // Will wait for a certain bit of text meaning that - // the client application has started, and we can hide - // the progress bar stuff. - const tempListener = function(data){ - if(data.indexOf('[Client thread/INFO]: -- System Details --') > -1){ - toggleLaunchArea(false) - if(hasRPC){ - DiscordWrapper.updateDetails('Loading game..') - } - proc.stdout.removeListener('data', tempListener) - } - } - - // Listener for Discord RPC. - const gameStateChange = function(data){ - if(servJoined.test(data)){ - DiscordWrapper.updateDetails('Exploring the Realm!') - } else if(gameJoined.test(data)){ - DiscordWrapper.updateDetails('Sailing to Westeros!') - } - } // Bind listeners to stdout. proc.stdout.on('data', tempListener) - proc.stdout.on('data', gameStateChange) + + setLaunchDetails('Done. Enjoy the server!') // Init Discord Hook const distro = DistroManager.getDistribution()