Skip to content

Commit

Permalink
[FIX] Only try to do EOS operations on a path if there's actually a W…
Browse files Browse the repository at this point in the history
…ineprefix there (#3410)

Previously, trying to enable/disable/check the status of the EOS overlay
for a game with an invalid prefix directory would lead to an error
message.
We're now handling this correctly (not enabling/disabling it, always
reporting that it's disabled)
  • Loading branch information
CommandMC authored Jan 7, 2024
1 parent 8bdee13 commit 9d128f7
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 37 deletions.
6 changes: 6 additions & 0 deletions src/backend/storeManagers/legendary/commands/base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { z } from 'zod'
import path from 'path'
import { hasGame } from '../library'
import { existsSync } from 'graceful-fs'

export const LegendaryAppName = z
.string()
Expand Down Expand Up @@ -35,3 +36,8 @@ export type URL = z.infer<typeof URL>
// FIXME: This doesn't feel right
export const URI = z.union([Path, URL])
export type URI = z.infer<typeof URI>

export const ValidWinePrefix = Path.refine((potPath) =>
existsSync(path.join(potPath, 'user.reg'))
).brand('ValidWinePrefix')
export type ValidWinePrefix = z.infer<typeof ValidWinePrefix>
4 changes: 2 additions & 2 deletions src/backend/storeManagers/legendary/commands/eos_overlay.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { z } from 'zod'
import { LegendaryAppName, NonEmptyString, Path } from './base'
import { LegendaryAppName, NonEmptyString, Path, ValidWinePrefix } from './base'

const EosOverlayAction = z.enum([
'install',
Expand All @@ -15,7 +15,7 @@ interface EosOverlayCommand {
subcommand: 'eos-overlay'
action: EosOverlayAction
'--path'?: Path
'--prefix'?: Path
'--prefix'?: ValidWinePrefix
'--app'?: LegendaryAppName
'--bottle'?: NonEmptyString
}
Expand Down
79 changes: 44 additions & 35 deletions src/backend/storeManagers/legendary/eos_overlay/eos_overlay.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { gameManagerMap } from '../../index'
import { callAbortController } from '../../../utils/aborthandler/aborthandler'
import { dialog } from 'electron'
import { existsSync, readFileSync } from 'graceful-fs'
import { t } from 'i18next'
import { join } from 'path'

import { toolsPath, isLinux, legendaryConfigPath } from '../../../constants'
import { logError, LogPrefix, logWarning } from '../../../logger/logger'
import { runRunnerCommand as runLegendaryCommand } from '../library'
import { verifyWinePrefix } from '../../../launcher'
import { setCurrentDownloadSize } from '../games'
import { Path } from '../commands/base'
import { LegendaryCommand } from '../commands'
import { toolsPath, isLinux, legendaryConfigPath } from 'backend/constants'
import { logError, LogPrefix, logWarning } from 'backend/logger/logger'
import { callAbortController } from 'backend/utils/aborthandler/aborthandler'
import { sendGameStatusUpdate } from 'backend/utils'
import { gameManagerMap } from '../..'
import { LegendaryCommand } from '../commands'
import { Path, ValidWinePrefix } from '../commands/base'
import { setCurrentDownloadSize } from '../games'
import { runRunnerCommand as runLegendaryCommand } from '../library'

import type { Runner } from 'common/types'

const currentVersionPath = () =>
join(legendaryConfigPath, 'overlay_version.json')
Expand Down Expand Up @@ -187,14 +188,6 @@ async function remove(): Promise<boolean> {
async function enable(
appName: string
): Promise<{ wasEnabled: boolean; installNow?: boolean }> {
let prefix = ''
if (isLinux) {
const gameSettings = await gameManagerMap['legendary'].getSettings(appName)
await verifyWinePrefix(gameSettings)
const { winePrefix, wineVersion } = gameSettings
prefix =
wineVersion.type === 'proton' ? join(winePrefix, 'pfx') : winePrefix
}
if (!isInstalled()) {
const { response } = await dialog.showMessageBox({
title: t('setting.eosOverlay.notInstalledTitle', 'Overlay not installed'),
Expand All @@ -208,11 +201,16 @@ async function enable(
return { wasEnabled: false, installNow: response === 0 }
}

const prefix = await getWinePrefixFolder(appName)
// Can't install the overlay if we don't have a valid prefix
// FIXME: Notify the user about this
if (prefix === false) return { wasEnabled: false }

const command: LegendaryCommand = {
subcommand: 'eos-overlay',
action: 'enable'
}
if (prefix) command['--prefix'] = Path.parse(prefix)
if (prefix) command['--prefix'] = prefix

await runLegendaryCommand(command, {
abortId: eosOverlayAppName,
Expand All @@ -223,19 +221,15 @@ async function enable(
}

async function disable(appName: string) {
let prefix = ''
if (isLinux) {
const { winePrefix, wineVersion } =
await gameManagerMap['legendary'].getSettings(appName)
prefix =
wineVersion.type === 'proton' ? join(winePrefix, 'pfx') : winePrefix
}
const prefix = await getWinePrefixFolder(appName)
// If we don't have a valid prefix anymore, we have nothing to disable
if (prefix === false) return

const command: LegendaryCommand = {
subcommand: 'eos-overlay',
action: 'disable'
}
if (prefix) command['--prefix'] = Path.parse(prefix)
if (prefix) command['--prefix'] = prefix

await runLegendaryCommand(command, {
abortId: eosOverlayAppName,
Expand All @@ -252,22 +246,17 @@ function isInstalled() {
* @param appName required on Linux, does nothing on Windows
* @returns Enabled = True; Disabled = False
*/
async function isEnabled(appName?: string) {
async function isEnabled(appName?: string): Promise<boolean> {
let enabled = false

let prefix = ''
if (isLinux && appName) {
const { winePrefix, wineVersion } =
await gameManagerMap['legendary'].getSettings(appName)
prefix =
wineVersion.type === 'proton' ? join(winePrefix, 'pfx') : winePrefix
}
const prefix = await getWinePrefixFolder(appName)
if (prefix === false) return false

const command: LegendaryCommand = {
subcommand: 'eos-overlay',
action: 'info'
}
if (prefix) command['--prefix'] = Path.parse(prefix)
if (prefix) command['--prefix'] = prefix

await runLegendaryCommand(command, {
abortId: eosOverlayAppName,
Expand All @@ -282,6 +271,26 @@ async function isEnabled(appName?: string) {
return enabled
}

/**
* Returns the path to the "real" Wineprefix folder (where "drive_c" and "user.reg" is) for a game
* @returns null if a prefix can't be returned (we're not on Linux / don't have an AppName)
* @returns false if parsing the prefix path failed (in other words there is a prefix path set, but it doesn't contain a valid prefix)
* @returns ValidWinePrefix (a folder that is verified to contain a Wineprefix) otherwise
*/
async function getWinePrefixFolder(
appName?: string,
runner: Runner = 'legendary'
): Promise<ValidWinePrefix | null | false> {
if (!isLinux || !appName) return null

const { winePrefix, wineVersion } =
await gameManagerMap[runner].getSettings(appName)
const prefixPath =
wineVersion.type === 'proton' ? join(winePrefix, 'pfx') : winePrefix
const maybePrefix = ValidWinePrefix.safeParse(prefixPath)
return maybePrefix.success ? maybePrefix.data : false
}

export {
getStatus,
getLatestVersion,
Expand Down

0 comments on commit 9d128f7

Please sign in to comment.