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.
This commit is contained in:
Daniel Scalzi 2018-08-13 08:25:25 -04:00
parent 4f416220c2
commit f1d89c0e6b
No known key found for this signature in database
GPG Key ID: 5CA2F145B63535F9
2 changed files with 39 additions and 35 deletions

View File

@ -37,9 +37,8 @@ class ProcessBuilder {
const tempNativePath = path.join(os.tmpdir(), ConfigManager.getTempNativeFolder(), crypto.pseudoRandomBytes(16).toString('hex')) const tempNativePath = path.join(os.tmpdir(), ConfigManager.getTempNativeFolder(), crypto.pseudoRandomBytes(16).toString('hex'))
process.throwDeprecation = true process.throwDeprecation = true
this.setupLiteLoader() 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()) const modObj = this.resolveModConfiguration(ConfigManager.getModConfiguration(this.server.getID()).mods, this.server.getModules())
console.log(modObj)
this.constructModList('forge', modObj.fMods, true) this.constructModList('forge', modObj.fMods, true)
if(this.usingLiteLoader){ if(this.usingLiteLoader){
this.constructModList('liteloader', modObj.lMods, true) this.constructModList('liteloader', modObj.lMods, true)
@ -58,19 +57,21 @@ class ProcessBuilder {
child.unref() child.unref()
} }
child.stdout.setEncoding('utf8')
child.stdout.on('data', (data) => { 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) => { 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) => { 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) => { rimraf(tempNativePath, (err) => {
if(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 { } else {
console.log('Temp dir deleted successfully.') console.log('%c[ProcessBuilder]', 'color: #003996; font-weight: bold', 'Temp dir deleted successfully.')
} }
}) })
}) })

View File

@ -424,9 +424,9 @@ let proc
// Is DiscordRPC enabled // Is DiscordRPC enabled
let hasRPC = false let hasRPC = false
// Joined server regex // 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 SERVER_JOINED_REGEX = /\[.+\]: \[CHAT\] [a-zA-Z0-9_]{1,16} joined the game/
const gameJoined = /\[[0-2][0-9]:[0-6][0-9]:[0-6][0-9]\] \[Client thread\/WARN\]: Skipping bad option: lastServer:/g const GAME_JOINED_REGEX = /\[.+\]: Skipping bad option: lastServer:/
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 GAME_LAUNCH_REGEX = /^\[.+\]: MinecraftForge .+ Initialized$/
let aEx let aEx
let serv let serv
@ -585,37 +585,40 @@ function dlAsync(login = true){
console.log('authu', authUser) console.log('authu', authUser)
let pb = new ProcessBuilder(serv, versionData, forgeData, authUser) let pb = new ProcessBuilder(serv, versionData, forgeData, authUser)
setLaunchDetails('Launching game..') setLaunchDetails('Launching game..')
try {
// Build Minecraft process.
proc = pb.build()
setLaunchDetails('Done. Enjoy the server!')
// Attach a temporary listener to the client output. // Attach a temporary listener to the client output.
// Will wait for a certain bit of text meaning that // Will wait for a certain bit of text meaning that
// the client application has started, and we can hide // the client application has started, and we can hide
// the progress bar stuff. // the progress bar stuff.
const tempListener = function(data){ const tempListener = function(data){
if(data.indexOf('[Client thread/INFO]: -- System Details --') > -1){ if(GAME_LAUNCH_REGEX.test(data.trim())){
toggleLaunchArea(false) toggleLaunchArea(false)
if(hasRPC){ if(hasRPC){
DiscordWrapper.updateDetails('Loading game..') DiscordWrapper.updateDetails('Loading game..')
} }
proc.stdout.on('data', gameStateChange)
proc.stdout.removeListener('data', tempListener) proc.stdout.removeListener('data', tempListener)
} }
} }
// Listener for Discord RPC. // Listener for Discord RPC.
const gameStateChange = function(data){ const gameStateChange = function(data){
if(servJoined.test(data)){ data = data.trim()
if(SERVER_JOINED_REGEX.test(data)){
DiscordWrapper.updateDetails('Exploring the Realm!') DiscordWrapper.updateDetails('Exploring the Realm!')
} else if(gameJoined.test(data)){ } else if(GAME_JOINED_REGEX.test(data)){
DiscordWrapper.updateDetails('Sailing to Westeros!') DiscordWrapper.updateDetails('Sailing to Westeros!')
} }
} }
try {
// Build Minecraft process.
proc = pb.build()
// Bind listeners to stdout. // Bind listeners to stdout.
proc.stdout.on('data', tempListener) proc.stdout.on('data', tempListener)
proc.stdout.on('data', gameStateChange)
setLaunchDetails('Done. Enjoy the server!')
// Init Discord Hook // Init Discord Hook
const distro = DistroManager.getDistribution() const distro = DistroManager.getDistribution()