Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/prevent being able to launch currently downloading version #355

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions src/main/services/bs-local-version.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import log from "electron-log";
import { OculusService } from "./oculus.service";
import { DownloadLinkType } from "shared/models/mods";
import sanitize from "sanitize-filename";
import { Progression, copyDirectoryWithJunctions, deleteFolder, ensurePathNotAlreadyExist, getFoldersInFolder, pathExist, rxCopy } from "../helpers/fs.helpers";
import { Progression, copyDirectoryWithJunctions, deleteFolder, ensurePathNotAlreadyExist, getFoldersInFolder, rxCopy } from "../helpers/fs.helpers";
import { FolderLinkerService } from "./folder-linker.service";
import { ReadStream, createReadStream, readFile, writeFile } from "fs-extra";
import { ReadStream, createReadStream, pathExists, readFile, writeFile } from "fs-extra";
import readline from "readline";
import { Observable, Subject, catchError, finalize, from, map, switchMap, throwError } from "rxjs";
import { BsStore } from "../../shared/models/bs-store.enum";
Expand Down Expand Up @@ -53,7 +53,10 @@ export class BSLocalVersionService {

private async getVersionFromGlobalGameManagerFile(versionFilePath: string): Promise<BSVersion> {

if(!(await pathExist(versionFilePath))){ return null; }
if(!(await pathExists(versionFilePath))){
log.info("globalgamemanagers file not found", versionFilePath);
return null;
}

const versionsDict = await this.remoteVersionService.getAvailableVersions();

Expand Down Expand Up @@ -81,6 +84,8 @@ export class BSLocalVersionService {
stream?.close();
}

log.info("unable to get version from globalgamemanagers file", versionFilePath);

return null;
}

Expand All @@ -92,6 +97,8 @@ export class BSLocalVersionService {
}
): Promise<BSVersion>{

log.info("getVersionOfBSFolder", bsPath, options);

if(!bsPath){ return null; }

const versionFilePath = path.join(bsPath, 'Beat Saber_Data', 'globalgamemanagers');
Expand Down Expand Up @@ -129,7 +136,7 @@ export class BSLocalVersionService {
const contents = await readFile(path.join(versionPath, this.METADATA_FILE), "utf-8");
return JSON.parse(contents);
})().catch(e => {
log.warn(e);
log.warn("Not a critical error", e);
return {};
}).then(metadata => ({...defaultMetadata, ...metadata}));
}
Expand All @@ -139,7 +146,7 @@ export class BSLocalVersionService {
const metadata = await this.getAllVersionMetadata(version);
return metadata?.[key];
})().catch(e => {
log.warn(e);
log.warn("Not a critical error", e);
return null;
}).then(value => (value ?? defaultValue) as T);
}
Expand Down Expand Up @@ -196,7 +203,7 @@ export class BSLocalVersionService {
*/
public async getInstalledVersionPath(version: BSVersion): Promise<string>{
const versionPath = await this.getVersionPath(version);
if(await pathExist(versionPath)){ return versionPath; }
if(await pathExists(versionPath)){ return versionPath; }

const versionFolders = await getFoldersInFolder(await this.installLocationService.versionsDirectory());

Expand Down Expand Up @@ -227,7 +234,7 @@ export class BSLocalVersionService {
private async getSteamVersion(): Promise<BSVersion> {
const steamBsFolder = await this.steamService.getGameFolder(BS_APP_ID, "Beat Saber");

if (!steamBsFolder || !(await pathExist(steamBsFolder))) {
if (!steamBsFolder || !(await pathExists(steamBsFolder))) {
return null;
}

Expand All @@ -247,26 +254,35 @@ export class BSLocalVersionService {
public async getInstalledVersions(): Promise<BSVersion[]> {
const versions: BSVersion[] = [];

const steamVersion = await this.getSteamVersion();
const steamVersion = await this.getSteamVersion().catch(e => {
log.error("unable to get original Steam version", e);
});

if (steamVersion) {
versions.push(steamVersion);
}

const oculusVersion = await this.getOculusVersion();
const oculusVersion = await this.getOculusVersion().catch(e => {
log.error("unable to get original Oculus version", e);
});

if (oculusVersion) {
versions.push(oculusVersion);
}

if (!(await pathExist(await this.installLocationService.versionsDirectory()))) {
if (!(await pathExists(await this.installLocationService.versionsDirectory()))) {
return versions;
}

const folderInInstallation = await getFoldersInFolder(await this.installLocationService.versionsDirectory());

log.info("Finded versions folders", folderInInstallation);

for (const f of folderInInstallation) {
log.info("try get version from folder", f);

const version = await this.getVersionOfBSFolder(f);
const version = await this.getVersionOfBSFolder(f).catch(e => {
log.error("unable to get version of folder", f, e);
});

if(!version){ continue; }

Expand All @@ -283,7 +299,7 @@ export class BSLocalVersionService {
public async deleteVersion(version: BSVersion): Promise<boolean>{
if(version.steam || version.oculus){ return false; }
const versionFolder = await this.getVersionPath(version);
if(!(await pathExist(versionFolder))){ return true; }
if(!(await pathExists(versionFolder))){ return true; }

return deleteFolder(versionFolder)
.then(() => { return true; })
Expand All @@ -304,7 +320,7 @@ export class BSLocalVersionService {
return editedVersion;
}

if((await pathExist(newPath)) && newPath === oldPath){ throw {title: "VersionAlreadExist"} as BsmException; }
if((await pathExists(newPath)) && newPath === oldPath){ throw {title: "VersionAlreadExist"} as BsmException; }

return rename(oldPath, newPath).then(() => {
this.deleteCustomVersion(version);
Expand All @@ -328,7 +344,7 @@ export class BSLocalVersionService {
this.addCustomVersion(cloneVersion);
}

if(await pathExist(newPath)){ throw {title: "VersionAlreadExist"} as BsmException; }
if(await pathExists(newPath)){ throw {title: "VersionAlreadExist"} as BsmException; }

return copyDirectoryWithJunctions(originPath, newPath).then(() => {
this.addCustomVersion(cloneVersion);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BSVersion } from "shared/bs-version.interface";
import { Link, useLocation } from "react-router-dom";
import { useState } from "react";
import { distinctUntilChanged, lastValueFrom, map, of, Subscription, switchMap } from "rxjs";
import { distinctUntilChanged, lastValueFrom, map, of, Subscription, switchMap, take } from "rxjs";
import { BSLauncherService, LaunchMods } from "renderer/services/bs-launcher.service";
import { ConfigurationService } from "renderer/services/configuration.service";
import { BSUninstallerService } from "renderer/services/bs-uninstaller.service";
Expand Down Expand Up @@ -55,7 +55,9 @@ export function BsVersionItem(props: { version: BSVersion }) {
return props.version?.BSVersion === state?.BSVersion && props?.version.steam === state?.steam && props?.version.oculus === state?.oculus && props?.version.name === state?.name;
};

const handleDoubleClick = () => {
const handleDoubleClick = async () => {
const downloadingVersion = await lastValueFrom(bsDownloader.downloadingVersion$.pipe(take(1)));
if(equal(downloadingVersion, props.version)){ return; }
const launch$ = launcherService.launch({
version: state,
oculus: !!configService.get<boolean>(LaunchMods.OCULUS_MOD),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { BsmImage } from "renderer/components/shared/bsm-image.component";
import { useService } from "renderer/hooks/use-service.hook";
import { BsStore } from "shared/models/bs-store.enum";
import { lastValueFrom } from "rxjs";
import { BsDownloaderService } from "renderer/services/bs-version-download/bs-downloader.service";
import equal from "fast-deep-equal";

type Props = { version: BSVersion };

Expand All @@ -20,12 +22,14 @@ export function LaunchSlide({ version }: Props) {

const configService = useService(ConfigurationService);
const bsLauncherService = useService(BSLauncherService);
const bsDownloader = useService(BsDownloaderService);

const [oculusMode, setOculusMode] = useState(!!configService.get<boolean>(LaunchMods.OCULUS_MOD));
const [desktopMode, setDesktopMode] = useState(!!configService.get<boolean>(LaunchMods.DESKTOP_MOD));
const [debugMode, setDebugMode] = useState(!!configService.get<boolean>(LaunchMods.DEBUG_MOD));
const [advancedLaunch, setAdvancedLaunch] = useState(false);
const [additionalArgsString, setAdditionalArgsString] = useState<string>(configService.get<string>("additionnal-args") || "");
const versionDownloading = useObservable(bsDownloader.downloadingVersion$);

const versionRunning = useObservable(bsLauncherService.versionRunning$);

Expand Down Expand Up @@ -96,7 +100,13 @@ export function LaunchSlide({ version }: Props) {
</motion.div>
</div>
<div className='grow flex justify-center items-center'>
<BsmButton onClick={launch} active={JSON.stringify(version) === JSON.stringify(versionRunning)} className='relative -translate-y-1/2 text-5xl text-gray-800 dark:text-gray-200 font-bold tracking-wide pt-1 pb-3 px-7 rounded-lg shadow-md italic shadow-black active:scale-90 transition-transform' text="misc.launch"/>
<BsmButton
onClick={launch}
active={JSON.stringify(version) === JSON.stringify(versionRunning)}
className='relative -translate-y-1/2 text-5xl text-gray-800 dark:text-gray-200 font-bold tracking-wide pt-1 pb-3 px-7 rounded-lg shadow-md italic shadow-black active:scale-90 transition-transform'
text="misc.launch"
disabled={equal(version, versionDownloading)}
/>
</div>
</div>
);
Expand Down
Loading