Skip to content

Commit

Permalink
Improve auto-quit "other" on startTitle; move logic into Device
Browse files Browse the repository at this point in the history
Now API users can take advantage of this functionality, and also disable
it if desired.
  • Loading branch information
dhleong committed Sep 7, 2020
1 parent 13c9526 commit 1fc5b73
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 22 deletions.
6 changes: 5 additions & 1 deletion lib/cli/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ class CommandOnDevice {

return this._search(ui, async (device) => {
debug('await this.onDevice() ...');
await this.onDevice(ui, device);
try {
await this.onDevice(ui, device);
} catch (e) {
ui.logError(e);
}

debug('... onDevice complete; close()');
return device.close();
Expand Down
16 changes: 4 additions & 12 deletions lib/cli/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,9 @@ module.exports = class StartCommand extends CommandOnDevice {
}

async onDevice(ui, device) {
if (device.lastInfo['running-app-titleid'] === this.titleId) {
ui.logEvent('Requested titleId already running');
return device;
}

if (device.lastInfo['running-app-titleid']) {
const appName = device.lastInfo['running-app-name'];
ui.logEvent(`"${appName}" already running; quitting it first...`);
await device.sendKeys(['ps']);
}

return device.startTitle(this.titleId);
await device.startTitle(this.titleId, {
ui,
autoQuit: true, // default, but let's be explicit
});
}
};
70 changes: 62 additions & 8 deletions lib/device.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const HOME = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE

const DEFAULT_CREDS = joinPath(HOME, '.ps4-wake.credentials.json');

// I'm just guessing at the meaning of this error code...
const ERROR_OTHER_APP_RUNNING = 12;

/**
* Device is a high-level abstraction on top of a single
* PS4 device. It maintains a single, active connection
Expand Down Expand Up @@ -285,19 +288,59 @@ class Device extends EventEmitter {
* Start running the application with the given ID on this
* device, turning the device on if necessary. Resolves
* to this object.
*
* @param options (optional) If provided, a map:
* - ui: (optional) an object with a logEvent method
* - autoQuit: (optional) bool, defaults to `true`; when `true`,
* if another app is running when this method is called, we will
* automatically quit it if necessary.
*/
async startTitle(titleId) {
const socket = await this.openSocket();
async startTitle(titleId, options) {
await this.openSocket();

// ensure we're logged in properly
await this.login();

return new Promise((resolve, reject) => {
socket.startTitle(titleId, (err) => {
if (err) return reject(err);
return resolve(this);
});
});
const config = {
ui: { logEvent() { /* nop */ } },
autoQuit: true,

...options,
};

const lastInfo = this.lastInfo || {};

if (lastInfo['running-app-titleid'] === titleId) {
config.ui.logEvent('Requested titleId already running');
return this;
}

const willQuitRunningApp = lastInfo['running-app-titleid'];
if (willQuitRunningApp) {
const appName = lastInfo['running-app-name'];
config.ui.logEvent(`"${appName}" already running; quitting it first...`);
await this.sendKeys(['ps']);
}

try {
await this._startTitle(titleId);
} catch (e) {
if (
!willQuitRunningApp
|| e.status !== ERROR_OTHER_APP_RUNNING
|| !config.autoQuit
) {
// unexpected error, or we don't want to auto-quit
throw e;
}

// we're quitting a running app; if we're leaving one game for
// another, receiving this error code probably means we need to
// accept that the application will close.
await this.sendKeys(['enter']);
}

return this;
}

/**
Expand Down Expand Up @@ -540,6 +583,17 @@ class Device extends EventEmitter {
this._connectedAt = 0;
}

async _startTitle(titleId) {
const socket = await this.openSocket();

return new Promise((resolve, reject) => {
socket.startTitle(titleId, (err) => {
if (err) return reject(err);
return resolve(this);
});
});
}

/** Create a new Waker instance */
_waker() {
if (this.__waker) return this.__waker;
Expand Down
12 changes: 11 additions & 1 deletion lib/ps4socket.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ const SERVER_RESPONSE_TIMEOUT = 60000;

let KnownPackets;

class StartTitleError extends Error {
constructor(status, message) {
super(message);
this.status = status;
}
}

/**
* Ps4Socket constructor
*
Expand Down Expand Up @@ -374,7 +381,10 @@ Ps4Socket.prototype.startTitle = function(titleId, callback) {
if (callback) {
this.once('start_title_result', (packet) => {
if (packet.status) {
callback(new Error(`Error ${packet.status} starting ${titleId}`));
callback(new StartTitleError(
packet.status,
`Error ${packet.status} starting ${titleId}`,
));
} else {
callback();
}
Expand Down

0 comments on commit 1fc5b73

Please sign in to comment.