From 54f24d93a38b35cae693cfc5ba727390442d6eed Mon Sep 17 00:00:00 2001 From: MathieuG-P <40181755+Zagrios@users.noreply.github.com> Date: Sat, 6 Jan 2024 14:49:07 +0100 Subject: [PATCH] [bugfix] Handle oculus library doesnt have OriginaPath value Added a method to resolve GUID path to resolve Path value in oculus library reg --- src/main/helpers/fs.helpers.ts | 17 +++++++++++++ .../bs-launcher/oculus-launcher.service.ts | 6 ++++- src/main/services/oculus.service.ts | 25 ++++++++++++++++--- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/main/helpers/fs.helpers.ts b/src/main/helpers/fs.helpers.ts index ec64701e..03e833e4 100644 --- a/src/main/helpers/fs.helpers.ts +++ b/src/main/helpers/fs.helpers.ts @@ -5,6 +5,7 @@ import { Observable, concatMap, from } from "rxjs"; import log from "electron-log"; import { BsmException } from "shared/models/bsm-exception.model"; import crypto from "crypto"; +import { execSync } from "child_process"; export async function pathExist(path: string): Promise { try { @@ -232,6 +233,22 @@ export async function isJunction(path: string): Promise{ return lstats.isSymbolicLink() && stats.isDirectory(); } +export function resolveGUIDPath(guidPath: string): string { + log.info("resolveGUIDPath", guidPath); + const guidVolume = path.parse(guidPath).root; + log.info("guidVolume", guidVolume); + const command = `powershell -command "(Get-WmiObject -Class Win32_Volume | Where-Object { $_.DeviceID -like '${guidVolume}' }).DriveLetter"`; + log.info("command", command); + const driveLetter = execSync(command).toString().trim(); + log.info("driveLetter", driveLetter); + if (!driveLetter) { + log.error("Unable to resolve GUID path"); + throw new Error("Unable to resolve GUID path"); + } + log.info("result guid", path.join(driveLetter, path.relative(guidVolume, guidPath))); + return path.join(driveLetter, path.relative(guidVolume, guidPath)); +} + export interface Progression { total: number; current: number; diff --git a/src/main/services/bs-launcher/oculus-launcher.service.ts b/src/main/services/bs-launcher/oculus-launcher.service.ts index 2cf7f7e8..92831375 100644 --- a/src/main/services/bs-launcher/oculus-launcher.service.ts +++ b/src/main/services/bs-launcher/oculus-launcher.service.ts @@ -34,7 +34,10 @@ export class OculusLauncherService extends AbstractLauncherService implements St this.pathsService = InstallationLocationService.getInstance(); this.oculus.tryGetGameFolder([OCULUS_BS_DIR, OCULUS_BS_BACKUP_DIR]).then(async dirPath => { - if(dirPath){ return this.oculusLib$.next( path.join(dirPath, "..") ); } + if(dirPath){ + log.info("Oculus game found", dirPath); + return this.oculusLib$.next( path.join(dirPath, "..") ); + } const defaultLib = ((await this.oculus.getOculusLibs()) || []).find(lib => lib.isDefault); if(defaultLib?.path){ return this.oculusLib$.next(path.join(defaultLib.path, "Software")); } this.oculusLib$.next(null); @@ -48,6 +51,7 @@ export class OculusLauncherService extends AbstractLauncherService implements St const oculusLibPath = await lastValueFrom(this.oculusLib$.pipe(take(1), timeout(sToMs(30)), catchError(() => of(null)))); if(!oculusLibPath || !(await pathExists(oculusLibPath))){ + log.error("oculusLibPath value", oculusLibPath, "Path exists", await pathExists(oculusLibPath)); throw new Error("Oculus library not found, deleteBsSymlinks"); } diff --git a/src/main/services/oculus.service.ts b/src/main/services/oculus.service.ts index 349e96c0..dd4dc581 100644 --- a/src/main/services/oculus.service.ts +++ b/src/main/services/oculus.service.ts @@ -1,8 +1,9 @@ import { list } from "regedit-rs"; import path from "path"; -import { pathExist } from "../helpers/fs.helpers"; +import { pathExist, resolveGUIDPath } from "../helpers/fs.helpers"; import log from "electron-log"; import { lstat } from "fs-extra"; +import { tryit } from "../../shared/helpers/error.helpers"; export class OculusService { private static instance: OculusService; @@ -31,6 +32,11 @@ export class OculusService { const oculusLibsRegKey = "HKCU\\SOFTWARE\\Oculus VR, LLC\\Oculus\\Libraries"; const libsRegData = await list(oculusLibsRegKey).then(data => data[oculusLibsRegKey]); + log.info("Oculus libraries registry data", "exists:", libsRegData.exists, "keys:", "values:", libsRegData.keys, (() => { + const values = Object.entries(libsRegData.values ?? []); + return values.map(([name, value]) => [name, value.value]); + })()); + if (!libsRegData.keys?.length) { log.info("Registry key \"HKCU\\SOFTWARE\\Oculus VR, LLC\\Oculus\\Libraries\" not found"); return null; @@ -41,12 +47,22 @@ export class OculusService { const libsPath: OculusLibrary[] = ( await Promise.all(libsRegData.keys.map(async key => { const originalPath = await list([`${oculusLibsRegKey}\\${key}`]).then(res => res[`${oculusLibsRegKey}\\${key}`]); + + log.info("Value in key", key, "is", (() => { + const values = Object.entries(originalPath.values ?? []); + return values.map(([name, value]) => [name, value.value]); + })()); - if (!originalPath.values?.OriginalPath) { - return null; + if (originalPath.values?.OriginalPath) { + return { id: key, path: originalPath.values.OriginalPath.value, isDefault: defaultLibraryId === key } as OculusLibrary; + } + + if(originalPath.values?.Path) { + const { result } = tryit(() => resolveGUIDPath(originalPath.values.Path.value as string)); + return result ? { id: key, path: result, isDefault: defaultLibraryId === key } as OculusLibrary : null; } - return { id: key, path: originalPath.values.OriginalPath.value, isDefault: defaultLibraryId === key } as OculusLibrary + return null; }, [])) ).filter(Boolean); @@ -81,6 +97,7 @@ export class OculusService { public async tryGetGameFolder(gameFolders: string[]): Promise { for(const gameFolder of gameFolders){ const fullPath = await this.getGameFolder(gameFolder); + log.info("Oculus game folder", gameFolder, "fullPath", fullPath); if(fullPath){ return fullPath; } }