Skip to content

Commit

Permalink
hotfix: system logs for findEmulator and launchGame
Browse files Browse the repository at this point in the history
  • Loading branch information
ryandavidmercado committed Feb 21, 2024
1 parent cb28e41 commit eb91e3b
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 7 deletions.
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"crc": "^4.3.2",
"date-fns": "^3.2.0",
"deepmerge": "^4.3.1",
"electron-log": "^5.1.1",
"electron-updater": "^6.1.1",
"fast-deep-equal": "^3.1.3",
"fast-sort": "^3.4.0",
Expand Down
3 changes: 3 additions & 0 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'

import log from 'electron-log/main'
log.initialize()

function createWindow(): void {
// Create the browser window.
const mainWindow = new BrowserWindow({
Expand Down
40 changes: 34 additions & 6 deletions src/preload/util/findEmulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { exec as execCb } from "child_process";
import { promisify } from "util"
import { raEmulatorEntry } from '@common/features/RetroArch'
import { AppConfig } from '@common/types/AppConfig'
import log from 'electron-log/renderer'

const exec = promisify(execCb);

Expand All @@ -25,12 +26,18 @@ const findEmulator = async (emulator: Emulator): Promise<string> => {
return `${await findRaPath()} -L ${emulator.location.core}`
}

log.info(`Attempting to find emulator: ${emulator.name}`)

switch (platform) {
case 'darwin': {
return await findDarwinEmulator(emulator)
const location = await findDarwinEmulator(emulator)
log.info(`Found emulator ${emulator.name} at ${location} !`)
return location
}
case 'linux': {
return await findLinuxEmulator(emulator)
const location = await findLinuxEmulator(emulator)
log.info(`Found emulator ${emulator.name} at ${location} !`)
return location
}
}

Expand All @@ -48,15 +55,18 @@ async function findDarwinEmulator(emulator: Emulator): Promise<string> {
}
}

log.info(`Searching for emulator ${emulator.name} in /Applications/${emulator.location.darwin.name}*.app ...`)
const appDir = await readdir('/Applications')
const matcher = new RegExp(`^${escapeRegExp(emulator.location.darwin.name)}.*\.app$`)

const emuDir = appDir.find((app) => app.match(matcher))
if (!emuDir)
if (!emuDir) {
log.error(`Couldn't find match for /Applications/${emulator.location.darwin.name}*.app !`)
throw {
type: 'emu-not-found',
data: emulator
}
}

const emuMacOSDir = path.join('/', 'Applications', emuDir, 'Contents', 'MacOS')
const binName = (await readdir(emuMacOSDir))?.[0]
Expand All @@ -79,13 +89,17 @@ async function findLinuxEmulator(emulator: Emulator): Promise<string> {
}

if (emulator.location.linux.appImage) {
log.info(`Attempting to find ${emulator.name} by AppImage ...`)
const matcher = new RegExp(`^${escapeRegExp(emulator.location.linux.appImage)}.*\.AppImage$`)

for (const applicationPath of LINUX_APPLICATION_PATHS) {
log.info(`Scanning ${applicationPath}`)

let dirContents: string[]
try {
dirContents = await readdir(applicationPath)
} catch {
log.warn(`Failed to read ${applicationPath}!`)
continue
}

Expand All @@ -100,9 +114,13 @@ async function findLinuxEmulator(emulator: Emulator): Promise<string> {
}
}

log.info('AppImage not found!')

if (emulator.location.linux.binName) {
log.info(`Attempting to find ${emulator.name} by bin ...`)
// see if we're linked in PATH
try {
log.info(`Scanning in PATH ...`)
const { stdout } = await exec(`which ${emulator.location.linux.binName}`)
if(stdout) return stdout
} catch {}
Expand All @@ -118,13 +136,17 @@ async function findLinuxEmulator(emulator: Emulator): Promise<string> {
}

for (const entry of dirContents) {
log.info(`Scanning ${applicationPath}`)

const entryPath = path.join(applicationPath, entry)
const entryStat = await stat(entryPath)

if (!entryStat.isDirectory()) {
if (entry.match(matcher)) return parseDesktopFile(path.join(applicationPath, entry))
} else {
// we can scan for binNames one layer deep; don't go deeper to keep this quick
log.info(`Scanning ${entryPath}`)

const entryContents = await readdir(entryPath)
const match = entryContents.find(
(entryContent) =>
Expand Down Expand Up @@ -162,20 +184,26 @@ async function findLinuxEmulator(emulator: Emulator): Promise<string> {
}
}

// super simple .desktop parse; we just use the Exec field
async function parseDesktopFile(filePath: string): Promise<string> {
// super simple .desktop parse; we just use the Exec field
if(path.extname(filePath).toLowerCase() !== '.desktop') return `"${filePath}"`;

log.info(`Parsing .desktop file: ${filePath}`)

const execMatcher = /^Exec=(.*)$/m

const file = await readFile(filePath, { encoding: 'utf8' })
const execString = file.match(execMatcher)?.[1]
if (!execString) throw 'desktop-could-not-parse'
if (!execString) {
log.error('Failed to parse .desktop file!')
throw 'desktop-could-not-parse'
}

log.info(`Parsed exec string from .desktop file: ${execString}`)
return execString;
}

function escapeRegExp(string) {
function escapeRegExp(string: string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') // $& means the whole matched string
} // https://stackoverflow.com/a/6969486

Expand Down
3 changes: 2 additions & 1 deletion src/preload/util/launchGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { readFileSync } from 'fs'
import findEmulator from './findEmulator'
import { AppConfig } from '@common/types/AppConfig'
import { raEmulatorEntry } from '@common/features/RetroArch'
import log from 'electron-log/renderer'

const parseLaunchCommand = (
command: string,
Expand Down Expand Up @@ -56,7 +57,7 @@ const launchGame = async (game: Game, emulator: Emulator, system: System) => {

const parsedCommand = parseLaunchCommand(launchCommand, emulatorLocation, romLocation)

console.log(`Launching ${game.name} with command: ${parsedCommand}`)
log.info(`Launching ${game.name} with command: ${parsedCommand}`)

const spawnedProcess = spawn(parsedCommand, [], { detached: true, shell: true, windowsHide: true })

Expand Down

0 comments on commit eb91e3b

Please sign in to comment.