diff --git a/src/LiveSplitClient.js b/src/LiveSplitClient.js index e4f12b6..0dbb211 100644 --- a/src/LiveSplitClient.js +++ b/src/LiveSplitClient.js @@ -54,10 +54,13 @@ class LiveSplitClient extends EventEmitter { }); this._socket.on('data', (data) => { - this.emit( - 'data', - data.toString('utf-8').replace('\r\n', '') - ); + // This should catch edge cases where multiple messages are sent by the server + // so fast that this listener only fires once with all of them (concatenated). + // This allows for polling at a much faster rate with fewer errors. + const messages = data.toString('utf-8').split('\r\n'); + messages.forEach(message => { + this.emit('data', message); + }); }); this._socket.on('error', (err) => { @@ -94,10 +97,10 @@ class LiveSplitClient extends EventEmitter { /** * Send command to the LiveSplit Server instance. * @param {string} command - Existing LiveSplit Server command without linebreaks. - * @param {boolean} [expectResponse=true] - Expect response from the server. + * @param {object} [data] - Additional data to be sent with the command. * @returns {Promise|boolean} - Promise if answer was expected, else true. */ - send(command, expectResponse = true) { + send(command, data) { if (!this._connected) throw new Error('Client must be connected to the server!'); @@ -106,12 +109,10 @@ class LiveSplitClient extends EventEmitter { this._checkDisallowedSymbols(command); - this._socket.write(`${command}\r\n`); + var jsonString = JSON.stringify({ command, data }); + this._socket.write(`${jsonString}\r\n`); - if (expectResponse) - return this._waitForResponse(); - else - return true; + return this._waitForResponse(); } _waitForResponse() { @@ -119,7 +120,7 @@ class LiveSplitClient extends EventEmitter { const responseRecieved = new Promise((resolve) => { listener = (data) => { - resolve(data); + resolve(JSON.parse(data)); }; this.once('data', listener); @@ -144,119 +145,119 @@ class LiveSplitClient extends EventEmitter { /** * Start timer - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ startTimer() { - return this.send('starttimer', false); + return this.send('starttimer'); } /** * Start or split - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ startOrSplit() { - return this.send('startorsplit', false); + return this.send('startorsplit'); } /** * Split - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ split() { - return this.send('split', false); + return this.send('split'); } /** * Unsplit - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ unsplit() { - return this.send('unsplit', false); + return this.send('unsplit'); } /** * Skip split - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ skipSplit() { - return this.send('skipsplit', false); + return this.send('skipsplit'); } /** * Pause - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ pause() { - return this.send('pause', false); + return this.send('pause'); } /** * Resume - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ resume() { - return this.send('resume', false); + return this.send('resume'); } /** * Reset - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ reset() { - return this.send('reset', false); + return this.send('reset'); } /** * Init game time. Could be called only once according to LiveSplit Server documentation. - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ initGameTime() { if (this._initGameTimeOnce) return false; this._initGameTimeOnce = true; - return this.send('initgametime', false); + return this.send('initgametime'); } /** * Set game time * @param {string} time - Game time - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ setGameTime(time) { - return this.send(`setgametime ${time}`, false); + return this.send('setgametime', { time }); } /** * Set loading times * @param {string} time - Game time - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ setLoadingTimes(time) { - return this.send(`setloadingtimes ${time}`, false); + return this.send('setloadingtimes', { time }); } /** * Pause game time - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ pauseGameTime() { - return this.send('pausegametime', false); + return this.send('pausegametime'); } /** * Unpause game time - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ unpauseGameTime() { - return this.send('unpausegametime', false); + return this.send('unpausegametime'); } /** * Set comparison * @param {string} comparison - Comparison - * @returns {boolean} + * @returns {Promise} Command result or null on timeout. */ setComparison(comparison) { - return this.send(`setcomparison ${comparison}`, false); + return this.send('setcomparison', { comparison }); } /** @@ -265,8 +266,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getDelta(comparison = '') { - if (comparison) comparison = ` ${comparison}`; - return this.send(`getdelta${comparison}`, true); + return this.send('getdelta', { comparison }); } /** @@ -274,7 +274,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getLastSplitTime() { - return this.send('getlastsplittime', true); + return this.send('getlastsplittime'); } /** @@ -282,7 +282,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getComparisonSplitTime() { - return this.send('getcomparisonsplittime', true); + return this.send('getcomparisonsplittime'); } /** @@ -290,7 +290,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getCurrentTime() { - return this.send('getcurrenttime', true); + return this.send('getcurrenttime'); } /** @@ -299,8 +299,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getFinalTime(comparison = '') { - if (comparison) comparison = ` ${comparison}`; - return this.send(`getfinaltime${comparison}`, true); + return this.send('getfinaltime', { comparison }); } /** @@ -309,8 +308,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getPredictedTime(comparison = '') { - if (comparison) comparison = ` ${comparison}`; - return this.send(`getpredictedtime${comparison}`, true); + return this.send('getpredictedtime', { comparison }); } /** @@ -318,7 +316,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getBestPossibleTime() { - return this.send('getbestpossibletime', true); + return this.send('getbestpossibletime'); } /** @@ -326,7 +324,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getSplitIndex() { - return this.send('getsplitindex', true); + return this.send('getsplitindex'); } /** @@ -334,7 +332,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getCurrentSplitName() { - return this.send('getcurrentsplitname', true); + return this.send('getcurrentsplitname'); } /** @@ -342,7 +340,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getPreviousSplitName() { - return this.send('getprevioussplitname', true); + return this.send('getprevioussplitname'); } getPreviousSplitname() { @@ -354,7 +352,7 @@ class LiveSplitClient extends EventEmitter { * @returns {Promise} Command result or null on timeout. */ getCurrentTimerPhase() { - return this.send('getcurrenttimerphase', true); + return this.send('getcurrenttimerphase'); } /** @@ -365,9 +363,8 @@ class LiveSplitClient extends EventEmitter { const output = {}; for (let method of ['getCurrentTimerPhase', 'getDelta', 'getLastSplitTime', 'getComparisonSplitTime', 'getCurrentTime', 'getFinalTime', 'getPredictedTime', 'getBestPossibleTime', 'getSplitIndex', 'getCurrentSplitName', 'getPreviousSplitName']) { - output[ - method.replace('get', '').charAt(0).toLowerCase() + method.replace('get', '').slice(1) - ] = await this[method](); + let response = await this[method](); + Object.assign(output, response.data); } return output;