From 2fef88c70ef4063c2edcbae6eb6c0ae87016d345 Mon Sep 17 00:00:00 2001 From: silentrald Date: Fri, 20 Dec 2024 23:24:49 +0800 Subject: [PATCH 1/2] [feat-706] show DepotDownloader missing executable error --- assets/jsons/translations/en.json | 2 + src/main/models/depot-downloader.class.ts | 42 +++++++++++++------ .../bs-steam-downloader.service.ts | 29 ++++++------- .../depot-downloader.model.ts | 5 ++- 4 files changed, 50 insertions(+), 28 deletions(-) diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index 4715bc5b2..32df3c4d3 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -323,6 +323,8 @@ "msg": { "401": "Steam doesn't seem to want to let us download Beat Saber 😢", "404": "Unable to contact Steam servers.", + "ExeNotFoundWindows": "\"DepotDownloader.exe\" is missing. Please check if the executable is quarantined by your anti-virus.", + "ExeNotFoundLinux": "\"DepotDownloader\" binary is missing.", "Password": "Password is invalid.", "InvalidCredentials": "Invalid login credentials, unapproved connection, or too many login attempts.", "NoManifest": "No manifest was found", diff --git a/src/main/models/depot-downloader.class.ts b/src/main/models/depot-downloader.class.ts index dcaa101ae..5c15fd189 100644 --- a/src/main/models/depot-downloader.class.ts +++ b/src/main/models/depot-downloader.class.ts @@ -1,30 +1,48 @@ +import path from "path"; +import fs from "fs"; import { ChildProcessWithoutNullStreams, SpawnOptionsWithoutStdio, spawn } from "child_process"; import { Observable, ReplaySubject, Subscriber, filter, map, share } from "rxjs"; import { DepotDownloaderArgsOptions, DepotDownloaderErrorEvent, DepotDownloaderEvent, DepotDownloaderEventType, DepotDownloaderEventTypes, DepotDownloaderInfoEvent, DepotDownloaderWarningEvent } from "../../shared/models/bs-version-download/depot-downloader.model"; +import { UtilsService } from 'main/services/utils.service'; +import { CustomError } from "shared/models/exceptions/custom-error.class"; export class DepotDownloader { + private static readonly EXE_PATH = path.join( + UtilsService.getInstance().getAssetsScriptsPath(), + process.platform === "win32" ? "DepotDownloader.exe" : "DepotDownloader" + ); + private process: ChildProcessWithoutNullStreams; private processOut$: Observable; private subscriber: Subscriber; + public constructor( options: { - command: string, args?: string[], options?: SpawnOptionsWithoutStdio, echoStartData?: unknown - }, + args?: string[], options?: SpawnOptionsWithoutStdio, echoStartData?: unknown + }, logger?: Logger - ){ - this.processOut$ = new Observable(subscriber => { + ) { + if (!fs.existsSync(DepotDownloader.EXE_PATH)) { + throw new CustomError( + "DepotDownloader executable not found", + process.platform === "win32" + ? DepotDownloaderErrorEvent.ExeNotFoundWindows + : DepotDownloaderErrorEvent.ExeNotFoundLinux + ); + } + this.processOut$ = new Observable(subscriber => { this.subscriber = subscriber; - this.process = spawn(options.command, options.args ?? [], options.options); + this.process = spawn(DepotDownloader.EXE_PATH, options.args ?? [], options.options); subscriber.next(`[Info]|[Start]|${JSON.stringify(options.echoStartData) ?? ""}`); - + this.process.stdout.on("data", data => { const stringData: string = data.toString(); - + if(!stringData.includes(DepotDownloaderInfoEvent.Progress) && !stringData.includes(DepotDownloaderInfoEvent.Validated)){ logger?.info("DepotDownloader stdout:", stringData); } @@ -32,7 +50,7 @@ export class DepotDownloader { const lines: string[] = stringData.split("\n"); lines.forEach(line => subscriber.next(line)); }); - + this.process.on("error", error => subscriber.error(error)); this.process.stderr.on("error", error => subscriber.error(error)); this.process.on("exit", () => subscriber.complete()); @@ -74,7 +92,7 @@ export class DepotDownloader { data: splitedLine[2], } - }), + }), filter(Boolean)); } @@ -93,7 +111,7 @@ export class DepotDownloader { const args: string[] = []; for(const [key, value] of Object.entries(depotDownloaderArgs)){ - + if(value === true){ args.push(`-${key}`); } @@ -102,7 +120,7 @@ export class DepotDownloader { args.push(`${value}`); } } - + return args; } @@ -112,4 +130,4 @@ interface Logger { info: (...args: unknown[]) => void, warn: (...args: unknown[]) => void, error: (...args: unknown[]) => void, -} \ No newline at end of file +} diff --git a/src/main/services/bs-version-download/bs-steam-downloader.service.ts b/src/main/services/bs-version-download/bs-steam-downloader.service.ts index fccb1b7b5..8484f8398 100644 --- a/src/main/services/bs-version-download/bs-steam-downloader.service.ts +++ b/src/main/services/bs-version-download/bs-steam-downloader.service.ts @@ -1,7 +1,6 @@ import { BS_APP_ID, BS_DEPOT } from "../../constants"; import path from "path"; import { BSVersion } from "shared/bs-version.interface"; -import { UtilsService } from "../utils.service"; import log from "electron-log"; import { InstallationLocationService } from "../installation-location.service"; import { BSLocalVersionService } from "../bs-local-version.service"; @@ -17,14 +16,12 @@ import { CustomError } from "shared/models/exceptions/custom-error.class"; export class BsSteamDownloaderService { private static instance: BsSteamDownloaderService; - private readonly utils: UtilsService; private readonly installLocationService: InstallationLocationService; private readonly localVersionService: BSLocalVersionService; private depotDownloader: DepotDownloader; private constructor() { - this.utils = UtilsService.getInstance(); this.installLocationService = InstallationLocationService.getInstance(); this.localVersionService = BSLocalVersionService.getInstance(); @@ -40,10 +37,6 @@ export class BsSteamDownloaderService { return BsSteamDownloaderService.instance; } - private getDepotDownloaderExePath(): string { - return path.join(this.utils.getAssetsScriptsPath(), process.platform === 'linux' ? "DepotDownloader" : "DepotDownloader.exe"); - } - private async buildDepotDownloaderInstance(downloadInfos: DownloadSteamInfo, qr?: boolean): Promise<{depotDownloader: DepotDownloader, depotDownloaderOptions: DepotDownloaderArgsOptions, version: BSVersion}> { const versionPath = await this.localVersionService.getVersionPath(downloadInfos.bsVersion); @@ -68,11 +61,9 @@ export class BsSteamDownloaderService { await ensureDir(this.installLocationService.versionsDirectory()); - const exePath = this.getDepotDownloaderExePath(); const args = DepotDownloader.buildArgs(depotDownloaderOptions); const depotDownloader = new DepotDownloader({ - command: exePath, args, options: { cwd: this.installLocationService.versionsDirectory() }, echoStartData: downloadVersion @@ -104,11 +95,21 @@ export class BsSteamDownloaderService { finalize(() => this.localVersionService.initVersionMetadata(version, { store: BsStore.STEAM })) ).subscribe(sub); - }).catch(err => sub.error({ - type: DepotDownloaderEventType.Error, - subType: DepotDownloaderErrorEvent.Unknown, - data: err - } as DepotDownloaderEvent)); + }).catch(err => { + if (err instanceof CustomError + && Object.values(DepotDownloaderErrorEvent).includes( + err.code as DepotDownloaderErrorEvent + ) + ) { + return sub.error(err); + } + + return sub.error({ + type: DepotDownloaderEventType.Error, + subType: DepotDownloaderErrorEvent.Unknown, + data: err + } as DepotDownloaderEvent) + }); return () => { depotDownloaderBuildPromise.then(({ depotDownloader }) => depotDownloader.stop()); diff --git a/src/shared/models/bs-version-download/depot-downloader.model.ts b/src/shared/models/bs-version-download/depot-downloader.model.ts index ae701b794..0e46a80e4 100644 --- a/src/shared/models/bs-version-download/depot-downloader.model.ts +++ b/src/shared/models/bs-version-download/depot-downloader.model.ts @@ -2,7 +2,6 @@ export enum DepotDownloaderEventType { Error = "Error", Warning = "Warning", Info = "Info", - } export interface DepotDownloaderEvent { @@ -27,6 +26,8 @@ export enum DepotDownloaderInfoEvent { } export enum DepotDownloaderErrorEvent { + ExeNotFoundWindows = "ExeNotFoundWindows", + ExeNotFoundLinux = "ExeNotFoundLinux", Password = "Password", InvalidCredentials = "InvalidCredentials", NoManifest = "NoManifest", @@ -66,4 +67,4 @@ export interface DepotDownloaderArgsOptions { dir: string, validate?: boolean, qr?: boolean, -} \ No newline at end of file +} From d74ba720f1a5e72ff034657aa147d5f381277ef0 Mon Sep 17 00:00:00 2001 From: silentrald Date: Sat, 21 Dec 2024 21:33:09 +0800 Subject: [PATCH 2/2] [translation-706] added translation --- assets/jsons/translations/de.json | 2 ++ assets/jsons/translations/en.json | 2 +- assets/jsons/translations/es.json | 2 ++ assets/jsons/translations/fr.json | 2 ++ assets/jsons/translations/ja.json | 2 ++ assets/jsons/translations/ko.json | 2 ++ assets/jsons/translations/ru.json | 2 ++ assets/jsons/translations/zh-tw.json | 2 ++ assets/jsons/translations/zh.json | 2 ++ 9 files changed, 17 insertions(+), 1 deletion(-) diff --git a/assets/jsons/translations/de.json b/assets/jsons/translations/de.json index a6c926878..51a1e2b02 100644 --- a/assets/jsons/translations/de.json +++ b/assets/jsons/translations/de.json @@ -323,6 +323,8 @@ "msg": { "401": "Steam scheint uns Beat Saber nicht herunterladen zu lassen 😢", "404": "Steam-Server können nicht kontaktiert werden.", + "ExeNotFoundWindows": "\"DepotDownloader.exe\" fehlt. Bitte überprüfen Sie, ob die ausführbare Datei von Ihrer Antivirensoftware quarantäneiert wurde.", + "ExeNotFoundLinux": "Die ausführbare Datei \"DepotDownloader\" fehlt.", "Password": "Passwort ist ungültig.", "InvalidCredentials": "Ungültige Anmeldedaten, nicht genehmigte Verbindung oder zu viele Anmeldeversuche.", "NoManifest": "Es wurde kein Manifest gefunden.", diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index 32df3c4d3..e379b9d2c 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -324,7 +324,7 @@ "401": "Steam doesn't seem to want to let us download Beat Saber 😢", "404": "Unable to contact Steam servers.", "ExeNotFoundWindows": "\"DepotDownloader.exe\" is missing. Please check if the executable is quarantined by your anti-virus.", - "ExeNotFoundLinux": "\"DepotDownloader\" binary is missing.", + "ExeNotFoundLinux": "\"DepotDownloader\" executable is missing.", "Password": "Password is invalid.", "InvalidCredentials": "Invalid login credentials, unapproved connection, or too many login attempts.", "NoManifest": "No manifest was found", diff --git a/assets/jsons/translations/es.json b/assets/jsons/translations/es.json index a3685349a..eadf8b000 100644 --- a/assets/jsons/translations/es.json +++ b/assets/jsons/translations/es.json @@ -323,6 +323,8 @@ "msg": { "401": "Parece que Steam no quiere dejarnos descargar Beat Saber 😢", "404": "No se puede contactar con los servidores de Steam", + "ExeNotFoundWindows": "Falta \"DepotDownloader.exe\". Por favor, verifique si el ejecutable está en cuarentena por su antivirus.", + "ExeNotFoundLinux": "Falta el ejecutable de \"DepotDownloader\".", "Password": "La contraseña es inválida.", "InvalidCredentials": "Credenciales de inicio de sesión inválidas, conexión no aprobada o demasiados intentos de inicio de sesión.", "NoManifest": "No se ha encontrado el manifiesto", diff --git a/assets/jsons/translations/fr.json b/assets/jsons/translations/fr.json index 53ba74abb..8f7ab7c2f 100644 --- a/assets/jsons/translations/fr.json +++ b/assets/jsons/translations/fr.json @@ -323,6 +323,8 @@ "msg": { "401": "Steam ne semble pas vouloir nous laisser télécharger Beat Saber 😢", "404": "Impossible de contacter les serveurs de Steam.", + "ExeNotFoundWindows": "\"DepotDownloader.exe\" est manquant. Veuillez vérifier si l'exécutable est mis en quarantaine par votre antivirus.", + "ExeNotFoundLinux": "L'exécutable \"DepotDownloader\" est manquanto.", "Password": "Le mot de passe est invalide.", "InvalidCredentials": "Identifiants de connexion invalides, connexion non approuvée, ou trop de tentatives de connexion.", "NoManifest": "Aucun manifest n'a été trouvé.", diff --git a/assets/jsons/translations/ja.json b/assets/jsons/translations/ja.json index 54ffa8f53..9d7dac7cf 100644 --- a/assets/jsons/translations/ja.json +++ b/assets/jsons/translations/ja.json @@ -323,6 +323,8 @@ "msg": { "401": "SteamがBeat Saberのダウンロードを許可してくれないようだ。😢", "404": "Steamサーバーに接続できません。", + "ExeNotFoundWindows": "「DepotDownloader.exe」が見つかりません。実行ファイルがアンチウイルスソフトによって隔離されていないか確認してください。", + "ExeNotFoundLinux": "「DepotDownloader」の実行ファイルが見つかりません。", "Password": "パスワードが不正です。", "InvalidCredentials": "無効なログイン認証情報、許可されていない接続、またはログイン試行回数が多すぎます。", "NoManifest": "マニフェストは見つかりませんでした", diff --git a/assets/jsons/translations/ko.json b/assets/jsons/translations/ko.json index e3cd35caf..d7f81a00e 100644 --- a/assets/jsons/translations/ko.json +++ b/assets/jsons/translations/ko.json @@ -323,6 +323,8 @@ "msg": { "401": "Steam이 Beat Saber 다운로드를 허용하지 않는 것 같습니다 😢", "404": "Steam 서버에 연결할 수 없습니다.", + "ExeNotFoundWindows": "「DepotDownloader.exe」가 없습니다. 실행 파일이 바이러스 백신 프로그램에 의해 격리되었는지 확인하십시오.", + "ExeNotFoundLinux": "「DepotDownloader」 실행 파일이 없습니다.", "Password": "비밀번호가 올바르지 않습니다.", "InvalidCredentials": "유효하지 않은 로그인 자격 증명, 허가되지 않은 연결 또는 너무 많은 로그인 시도입니다.", "NoManifest": "매니페스트를 찾을 수 없습니다", diff --git a/assets/jsons/translations/ru.json b/assets/jsons/translations/ru.json index 45eecce3b..7f4a4da5b 100644 --- a/assets/jsons/translations/ru.json +++ b/assets/jsons/translations/ru.json @@ -323,6 +323,8 @@ "msg": { "401": "Похоже Steam не хочет, чтобы мы скачали Beat Saber 😢", "404": "Нет связи с серверами Steam.", + "ExeNotFoundWindows": "Отсутствует \"DepotDownloader.exe\". Пожалуйста, проверьте, не находится ли исполняемый файл в карантине вашего антивируса.", + "ExeNotFoundLinux": "Отсутствует исполняемый файл \"DepotDownloader\".", "Password": "Неверный пароль.", "InvalidCredentials": "Неверные учетные данные для входа, неразрешенное соединение или слишком много попыток входа.", "NoManifest": "Файл манифеста не найден", diff --git a/assets/jsons/translations/zh-tw.json b/assets/jsons/translations/zh-tw.json index fa0661d77..ac143982e 100644 --- a/assets/jsons/translations/zh-tw.json +++ b/assets/jsons/translations/zh-tw.json @@ -323,6 +323,8 @@ "msg": { "401": "Steam 似乎不想讓我們下載 Beat Saber😢", "404": "無法聯繫 Steam 伺服器。", + "ExeNotFoundWindows": "\"DepotDownloader.exe\" 缺失。請檢查執行檔是否被您的防毒軟體隔離。", + "ExeNotFoundLinux": "\"DepotDownloader\" 的可執行檔缺失。", "Password": "密碼無效", "InvalidCredentials": "登錄憑據無效、連接未經批准或登錄嘗試次數過多。", "NoManifest": "未找到清單", diff --git a/assets/jsons/translations/zh.json b/assets/jsons/translations/zh.json index 9dc8c9c52..d28e12344 100644 --- a/assets/jsons/translations/zh.json +++ b/assets/jsons/translations/zh.json @@ -323,6 +323,8 @@ "msg": { "401": "Steam 似乎不想让我们下载 Beat Saber😢", "404": "无法联系 Steam 服务器。", + "ExeNotFoundWindows": "\"DepotDownloader.exe\" 缺失。请检查执行文件是否被您的防病毒软件隔离。", + "ExeNotFoundLinux": "\"DepotDownloader\" 的可执行文件缺失。", "Password": "密码无效", "InvalidCredentials": "登录凭据无效、连接未经批准或登录尝试次数过多。", "NoManifest": "未找到清单",