Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
Portable feature
Browse files Browse the repository at this point in the history
  • Loading branch information
igor725 committed May 19, 2024
1 parent 8600be4 commit a2b085f
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ node_modules/
config.json
bin/emulator/
gameinfo/
portable
out/
9 changes: 6 additions & 3 deletions libs/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ const fs = require('node:fs');
const path = require('node:path');

module.exports.Config = class Config {
#cfgfile = path.join(__dirname, '../config.json');
#cfgfile = undefined;
#default = {
emu_path: path.join(__dirname, '../bin/emulator'),
emu_path: undefined,
update_channel: 'release',
update_freq: 'weekly',
inpadcolor: '#3B3E95',
Expand Down Expand Up @@ -32,7 +32,10 @@ module.exports.Config = class Config {
#callbacks = [];
#data = null;

constructor() {
constructor(userdir) {
this.#cfgfile = path.join(userdir, '/config.json');
this.#default.emu_path = path.join(userdir, '/bin/emulator');

try {
this.#data = JSON.parse(fs.readFileSync(this.#cfgfile, { encoding: 'utf-8' }));

Expand Down
104 changes: 77 additions & 27 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { app, BrowserWindow, Menu, ipcMain, dialog } = require('electron');
const Convert = require('ansi-to-html');
const { Worker } = require('node:worker_threads');
const { spawn, exec, execSync } = require('node:child_process');
const { spawn, exec } = require('node:child_process');
const path = require('node:path');
const fs = require('node:fs');
const { Config } = require('./libs/settings.js');
Expand All @@ -11,31 +11,17 @@ const SCE_PIC_PATH = '/sce_sys/pic0.png';
const SCE_TROPHY_PATH = '/sce_sys/trophy/trophy00.trp';
const SCE_BGA_PATH = '/sce_sys/snd0.at9';
const LISTAUDIO_PATH = path.join(__dirname, '/bin/listaudio.exe');

let win = null;
let player = null;
let settwin = null;
let gameproc = null;
let updateWorker = null;
const PORTABLE_PATH = path.join(__dirname, '/portable');

let win = undefined;
let player = undefined;
let config = undefined;
let gipath = undefined;
let settwin = undefined;
let gameproc = undefined;
let updateWorker = undefined;
let binname = 'psoff.exe';

const config = new Config();

const emupath = config.getValue('emu_path');
const gipath = path.join(__dirname, '/gameinfo');

fs.mkdirSync(gipath, { recursive: true });

try {
const testfile = path.join(emupath, '/test');
fs.mkdirSync(emupath, { recursive: true });
fs.writeFileSync(testfile, 'test');
fs.unlinkSync(testfile);
} catch (e) {
console.error('Emulator directory is not writeable anymore, resetting to default one: ', e.toString());
config.resetValue('emu_path');
}

const converter = new Convert({
newline: true
});
Expand All @@ -61,6 +47,7 @@ const _runDownloadingProcess = (retry = false) => {

const loadTrophiesData = (gid) => {
try {
const emupath = config.getValue('emu_path');
const tfile = fs.readFileSync(`${emupath}/GAMEFILES/${gid}/tropinfo.${config.getInitialUser()}`);
const trophies = [];
const count = tfile.readUint32LE(0);
Expand Down Expand Up @@ -120,7 +107,7 @@ const updateGameSummary = (gid, update, loadtrophies = false) => {

const updateBinaryPath = (path, checkfirst = false) => {
binname = path ?? binname;
exec(`"${binname}" -h`, { cwd: emupath }).on('close', (code) => {
exec(`"${binname}" -h`, { cwd: config.getValue('emu_path') }).on('close', (code) => {
if (code === 0 || code === 4294967295) config.reloadEmulatorSettings();
else throw new Error('Failed to make a test emulator run!');
});
Expand Down Expand Up @@ -249,6 +236,7 @@ const commandHandler = (channel, cmd, info) => {
const patch = getGameSummary(info, false).patch;
if (patch) emuargs.push(`--update=${patch}`);

const emupath = config.getValue('emu_path');
gameproc = spawn(path.join(emupath, binname), emuargs, { cwd: emupath });
gameproc.stdout.on('data', terminalListener);
gameproc.stderr.on('data', terminalListener);
Expand Down Expand Up @@ -348,12 +336,35 @@ const commandHandler = (channel, cmd, info) => {
}
};

app.whenReady().then(() => {
const main = (userdir = __dirname) => {
fs.mkdirSync(userdir, { recursive: true });
config = new Config(userdir);

const emupath = config.getValue('emu_path');

gipath = path.join(userdir, '/gameinfo');
fs.mkdirSync(gipath, { recursive: true });

try {
const testfile = path.join(emupath, '/test');
fs.mkdirSync(emupath, { recursive: true });
fs.writeFileSync(testfile, 'test');
fs.unlinkSync(testfile);
} catch (e) {
console.error('Emulator directory is not writeable anymore, resetting to default one: ', e.toString());
config.resetValue('emu_path');
}

ipcMain.on('command', commandHandler);

ipcMain.handle('reqcfg', () => config.getFullConfig());

ipcMain.handle('reqadev', () => JSON.parse(execSync(`"${LISTAUDIO_PATH}"`, { cwd: emupath })));
ipcMain.handle('reqadev', () => new Promise((resolve, reject) => {
exec(`"${LISTAUDIO_PATH}"`, { cwd: emupath }, (err, stdout) => {
if (err) return reject(err);
resolve(JSON.parse(stdout));
});
}));

ipcMain.handle('opendir', async () => {
const { canceled, filePaths } = await dialog.showOpenDialog(win, { properties: ['openDirectory'] });
Expand Down Expand Up @@ -574,4 +585,43 @@ app.whenReady().then(() => {
});

win.loadFile('webroot/index.html');
};

const guessLaunch = () => {
if (fs.readFileSync(PORTABLE_PATH).readUint8(0) === 1) { // portable
return main();
}

return main(path.join(process.env.LOCALAPPDATA, '/psoff-advlaunch/'));
};

app.whenReady().then(() => {
try {
guessLaunch();
} catch (e) {
if (e.code === 'ENOENT') {
const portask = new BrowserWindow({
width: 550,
height: 154,
resizable: false,
frame: false,
webPreferences: {
allowRunningInsecureContent: false,
preload: path.join(__dirname, 'preload.js')
}
});

ipcMain.once('set-portable', (ev, value) => {
fs.writeFileSync(PORTABLE_PATH, value ? '\x01' : '\x00');
});

portask.on('closed', () => guessLaunch());

portask.loadFile('webroot/portable.html');
return;
}

// Rethrow if something else errored
throw e;
}
});
1 change: 1 addition & 0 deletions preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ contextBridge.exposeInMainWorld('electronAPI', {
requestAudioDevices: () => ipcRenderer.invoke('reqadev'),
requestConfig: () => ipcRenderer.invoke('reqcfg'),
selectFolder: () => ipcRenderer.invoke('opendir'),
setPortable: (state) => ipcRenderer.send('set-portable', state)
});
2 changes: 1 addition & 1 deletion services/updater.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ const commandHandler = async (msg) => {
validateEmulatorPath();
await download(newverinfo.url, newverinfo.tag).then(({ fpath, version }) => {
execSync('del *.dll *.exe', { cwd: emupath });
execSync(`"${path.join(emupath, '../7z.exe')}" x -y -aoa -o"${emupath}" "${fpath}"`);
execSync(`"${path.join(__dirname, '../bin/7z.exe')}" x -y -aoa -o"${emupath}" "${fpath}"`);
parentPort.postMessage({ resp: 'done', executable: path.basename(searchBinary()) });
updateVersionFile(version);
fs.unlinkSync(fpath);
Expand Down
11 changes: 11 additions & 0 deletions webroot/css/portable.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#wrapper {
text-align: center;
}

h4 a {
color: green;
}

#buttons {
width: 100%;
}
2 changes: 1 addition & 1 deletion webroot/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ window._onLangReady = (() => {
} else if (tgc.contains('minimize')) {
window.electronAPI.sendCommand('minimize');
} else if (tgc.contains('legal')) {
window.open('legal.html', '_blank', 'frame=no,minWidth=630,minHeight=380,maxWidth=630,maxHeight=380,width=630,height=380');
window.open('legal.html', '_blank', 'frame=no,resizable=no,width=630,height=380');
}
});

Expand Down
7 changes: 7 additions & 0 deletions webroot/js/portable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(() => {
$('#buttons').on('click', ({ target }) => {
if (target.tagName !== 'BUTTON') return;
window.electronAPI.setPortable(target.dataset.portable === '1');
window.close();
});
})();
28 changes: 28 additions & 0 deletions webroot/portable.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>

<head>
<meta http-equiv="Content-Security-Policy"
content="default-src 'none'; style-src 'self'; script-src 'self'; font-src 'self';">
<link rel="stylesheet" href="css/shared.css" />
<link rel="stylesheet" href="css/portable.css" />
<script src="js/vars.js"></script>
</head>

<body>
<div id="wrapper">
<h3>Do you want to run the Advanced Launcher in portable mode?</h3>
<h4>In non-portable mode the Advanced Launcher will save its <a title="Playtime, launcher settings etc.">data</a>*
to
<a>%LOCALAPPDATA%\psoff-advlaunch</a> folder.
</h4>
<div id="buttons">
<button data-portable="1">Portable mode</button>
<button data-portable="0">Non-portable mode</button>
</div>
</div>

<script src="js/portable.js"></script>
</body>

</html>

0 comments on commit a2b085f

Please sign in to comment.