diff --git a/src/backend/launcher.ts b/src/backend/launcher.ts index c93b79f9a7..d9a6d66dc8 100644 --- a/src/backend/launcher.ts +++ b/src/backend/launcher.ts @@ -378,14 +378,18 @@ async function prepareWineLaunch( } } - if (gameSettings.eacRuntime && !isInstalled('eac_runtime') && isOnline()) { + if ( + gameSettings.eacRuntime && + isOnline() && + !(await isInstalled('eac_runtime')) + ) { await download('eac_runtime') } if ( gameSettings.battlEyeRuntime && - !isInstalled('battleye_runtime') && - isOnline() + isOnline() && + !(await isInstalled('battleye_runtime')) ) { await download('battleye_runtime') } diff --git a/src/backend/wine/runtimes/ipc_handler.ts b/src/backend/wine/runtimes/ipc_handler.ts index 5ba151650e..c4511af716 100644 --- a/src/backend/wine/runtimes/ipc_handler.ts +++ b/src/backend/wine/runtimes/ipc_handler.ts @@ -5,6 +5,6 @@ ipcMain.handle('downloadRuntime', async (e, runtime_name) => download(runtime_name) ) -ipcMain.handle('isRuntimeInstalled', (e, runtime_name) => +ipcMain.handle('isRuntimeInstalled', async (e, runtime_name) => isInstalled(runtime_name) ) diff --git a/src/backend/wine/runtimes/runtimes.ts b/src/backend/wine/runtimes/runtimes.ts index b54e344c88..1078209ddc 100644 --- a/src/backend/wine/runtimes/runtimes.ts +++ b/src/backend/wine/runtimes/runtimes.ts @@ -1,4 +1,11 @@ -import { existsSync, mkdirSync, unlinkSync } from 'graceful-fs' +import { + existsSync, + mkdirSync, + readFileSync, + unlinkSync, + writeFileSync, + rmSync +} from 'graceful-fs' import { join } from 'path' import { runtimePath } from './../../constants' import { logError, logInfo, LogPrefix } from './../../logger/logger' @@ -36,11 +43,21 @@ async function download(name: RuntimeName): Promise { await downloadFile(runtime.url, tarFilePath) const extractedFolderPath = join(runtimePath, name) + + if (existsSync(extractedFolderPath)) { + rmSync(extractedFolderPath, { recursive: true }) + } + await extractTarFile(tarFilePath, content_type, { extractedPath: extractedFolderPath, strip: 1 }) + writeFileSync( + join(extractedFolderPath, 'current_version'), + runtime.created_at + ) + unlinkSync(tarFilePath) return true @@ -53,8 +70,25 @@ async function download(name: RuntimeName): Promise { } } -function isInstalled(name: RuntimeName) { - return existsSync(join(runtimePath, name)) +async function isInstalled(name: RuntimeName) { + if (!existsSync(join(runtimePath, name))) return false + + const runtimes = await _get() + const runtime = runtimes.find((inst) => inst.name === name) + + // this should be impossible, so prevent redownload by faking it's installed + if (!runtime) { + logError('Runtime not found in runtime list', LogPrefix.Runtime) + return true + } + + const version_path = join(runtimePath, name, 'current_version') + + if (!existsSync(version_path)) return false + + const current_version = readFileSync(version_path) + + return runtime.created_at === current_version.toString() } export { download, isInstalled } diff --git a/src/common/typedefs/ipcBridge.d.ts b/src/common/typedefs/ipcBridge.d.ts index b33bcdbfb9..440040d514 100644 --- a/src/common/typedefs/ipcBridge.d.ts +++ b/src/common/typedefs/ipcBridge.d.ts @@ -247,7 +247,7 @@ interface AsyncIPCFunctions { disableEosOverlay: (appName: string) => Promise isEosOverlayEnabled: (appName?: string) => Promise downloadRuntime: (runtime_name: RuntimeName) => Promise - isRuntimeInstalled: (runtime_name: RuntimeName) => boolean + isRuntimeInstalled: (runtime_name: RuntimeName) => Promise getDMQueueInformation: () => { elements: DMQueueElement[] finished: DMQueueElement[]