Compare commits

...

27 Commits

Author SHA1 Message Date
MathieuG-P 109d560953 bumb to 1.3.2 2023-10-08 23:03:00 +02:00
MathieuG-P bfc853ee55 Merge pull request #337 from Zagrios/bugfix/one-click-download-playlist-conflict-with-shared-maps
[bugfix] Fix error when downloading playlist with OneClick and having maps linked
2023-10-08 22:53:00 +02:00
MathieuG-P fc2cb676d2 [bugfix] Fix error when downloading playlist with OneClick and having maps linked 2023-10-08 22:38:34 +02:00
MathieuG-P 226468aa00 Merge pull request #336 from Zagrios/bugfix/fix-english-translation-typos
[bugfix] Fix english translation typos
2023-10-08 11:28:24 +02:00
MathieuG-P 767bbf389b [bugfix] Fix english translation typos 2023-10-08 11:24:14 +02:00
MathieuG-P 0de2ea44d3 Merge pull request #335 from Zagrios/bugfix/advanced-launch-arguments-not-work-with-shortcuts
[bugfix] when only one advanced launch arg was set for a shortcut it was mishandled
2023-10-07 21:41:18 +02:00
MathieuG-P 1dde41f4f6 [bugfix] when only one advanced launch arg was set for a shortcut it was mishandled 2023-10-07 21:28:57 +02:00
Iluhadesu 029df85ddb Add v1.32.0 to bs_versions.json 2023-10-05 20:14:17 +02:00
MathieuG-P 139f17d7fc Merge pull request #331 from Zagrios/bugfix/one-click-map-download-may-not-work-with-shared-maps
[bugfix] Fix OneClick map download may not work with multiple maps sharing
2023-10-04 00:21:22 +02:00
MathieuG-P 92fd59be1e [bugfix] Fix OneClick map download may not work with multiple maps sharing 2023-10-04 00:10:05 +02:00
MathieuG-P d61f59c714 bumb to 1.3.1 2023-10-02 13:36:22 +02:00
MathieuG-P 64e3652b60 Merge pull request #330 from Zagrios/bugfix/steam-vr-restored-before-beatsaber-was-launched
[bugfix] increase timout for restoring SteamVR after launching Beat Saber
2023-10-02 13:35:46 +02:00
MathieuG-P 6f018e6a32 [bugfix] increase timout for restoring SteamVR after launching Beat Saber 2023-10-02 13:30:23 +02:00
MathieuG-P da3b2b13a8 Merge pull request #328 from Zagrios/bugfix/replace-resvg-that-need-dll-by-sharp
[bugfix] Remove resvg lib that need DLL by Sharp that doesnt
2023-09-25 12:52:40 +02:00
MathieuG-P 381daa80a4 [bufix] install node-abi 2023-09-25 12:34:05 +02:00
MathieuG-P bdfe8ce535 [bugfix] Remove resvg lib that need DLL by Sharp that doesnt 2023-09-25 11:55:34 +02:00
MathieuG-P 7f71d3006c bumb to 1.3.1-alpha.2 2023-09-25 08:12:50 +02:00
MathieuG-P 120470de5e Merge pull request #326 from Zagrios/bugfix/bsm-was-using-the-parent-of-bs-content-folder
[bugfix] fix of using the parent of installation folder when it was set in the config
2023-09-23 16:14:27 +02:00
MathieuG-P 8efe5be63f [bugfix] fix of using the parent of installation folder when it was set in the config 2023-09-23 16:09:24 +02:00
MathieuG-P 7378b234eb Merge pull request #325 from Insprill/fix/liv-linux
Skip Liv initialization on Linux
2023-09-21 17:17:37 +02:00
Pierce Thompson d256f2989f Pass noError instead of using a dummy impl 2023-09-21 10:59:13 -04:00
Pierce Thompson 85d43639af Skip Liv initialization on Linux 2023-09-20 22:47:59 -04:00
MathieuG-P f849b0d570 Merge pull request #323 from Zagrios/bugfix/steam-and-oculus-are-not-at-the-top
[bugfix] Steam and Oculus are not at the top of the versions list
2023-09-20 17:38:37 +02:00
MathieuG-P 34936f6666 [bugfix] Steam and Oculus are not at the top of the versions list 2023-09-20 17:32:45 +02:00
MathieuG-P d8a4889298 Merge pull request #321 from Zagrios/bugfix/add-no-yeet-args-prevent-mods-to-be-yeeted
[bugfix] Add no-yeet agrs to prevent mods to be yeeted
2023-09-18 15:29:35 +02:00
MathieuG-P 21c7f9d225 [bugfix] Add no-yeet agrs to prevent mods to be moved when UserData folder is linked 2023-09-18 15:24:53 +02:00
MathieuG-P 1048ca6b9b remove code sign verification 2023-09-18 15:14:09 +02:00
17 changed files with 967 additions and 310 deletions
+1 -1
View File
@@ -218,7 +218,7 @@ https://user-images.githubusercontent.com/40648115/213435051-7feb815d-f32b-4135-
<div>
<h1><b>Credits</b></h1>
<ul>
<li><a href="https://github.com/Zagrios">Zagrios</a> - Founder & Lead Developer (Mathieu GRIES)</li>
<li><a href="https://github.com/Zagrios">Zagrios</a> - Founder & Lead Developer</li>
<li><a href="https://github.com/Iluhadesu">Iluhadesu</a> - Project Team & Developpement help</li>
<li><a href="https://github.com/GaetanGrd">GaetanGrd</a> - Project Team & Developpement help</li>
<li><a href="https://github.com/cheddZy">cheddZy</a> - Icon creator</li>
+8
View File
@@ -573,5 +573,13 @@
"ReleaseImg": "https://clan.akamai.steamstatic.com/images/32055887/58621b3cb8bf42fcfbf3b97fe47aa91b290eea04.png",
"ReleaseDate": "1693824747",
"year": "2023"
},
{
"BSVersion": "1.32.0",
"BSManifest": "1660149393914874041",
"ReleaseURL": "https://steamcommunity.com/games/620980/announcements/detail/3723971545002767483",
"ReleaseImg": "https://clan.cloudflare.steamstatic.com/images/32055887/02284793f06188caf740da66939679afc25415e4.png",
"ReleaseDate": "1696517680",
"year": "2023"
}
]
+2 -2
View File
@@ -44,7 +44,7 @@
"maps": {
"title": "Shared maps",
"search-bar": {
"search-placeholder": "Search installed maps",
"search-placeholder": "Search a map",
"filters-btn": "Filters",
"dropdown": {
"export-maps": "Export maps",
@@ -738,7 +738,7 @@
},
"panel": {
"actions": {
"search": "Search installed models",
"search": "Search a model",
"drop-down": {
"delete": "Delete models",
"export": "Export models"
+7 -8
View File
@@ -24,6 +24,7 @@
"history": "^5.3.0",
"jszip": "^3.10.1",
"md5-file": "^5.0.0",
"node-abi": "^3.47.0",
"node-fetch": "^2.6.7",
"node-stream-zip": "^1.15.0",
"ps-list": "^7.2.0",
@@ -13509,10 +13510,9 @@
}
},
"node_modules/node-abi": {
"version": "3.28.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.28.0.tgz",
"integrity": "sha512-fRlDb4I0eLcQeUvGq7IY3xHrSb0c9ummdvDSYWfT9+LKP+3jCKw/tKoqaM7r1BAoiAC6GtwyjaGnOz6B3OtF+A==",
"dev": true,
"version": "3.47.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.47.0.tgz",
"integrity": "sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==",
"dependencies": {
"semver": "^7.3.5"
},
@@ -29518,10 +29518,9 @@
}
},
"node-abi": {
"version": "3.28.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.28.0.tgz",
"integrity": "sha512-fRlDb4I0eLcQeUvGq7IY3xHrSb0c9ummdvDSYWfT9+LKP+3jCKw/tKoqaM7r1BAoiAC6GtwyjaGnOz6B3OtF+A==",
"dev": true,
"version": "3.47.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.47.0.tgz",
"integrity": "sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==",
"requires": {
"semver": "^7.3.5"
}
+1
View File
@@ -244,6 +244,7 @@
"history": "^5.3.0",
"jszip": "^3.10.1",
"md5-file": "^5.0.0",
"node-abi": "^3.47.0",
"node-fetch": "^2.6.7",
"node-stream-zip": "^1.15.0",
"ps-list": "^7.2.0",
+855 -246
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "bs-manager",
"version": "1.3.1-alpha.1",
"version": "1.3.2",
"description": "BSManager",
"main": "./dist/main/main.js",
"author": {
@@ -14,8 +14,8 @@
"postinstall": "npm run electron-rebuild && npm run link-modules"
},
"dependencies": {
"@resvg/resvg-js": "^2.4.1",
"ps-list": "^7.2.0"
"ps-list": "^7.2.0",
"sharp": "^0.32.6"
},
"license": "MIT"
}
+2
View File
@@ -6,6 +6,7 @@ import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface";
import { BsvMapDetail } from "shared/models/maps";
import { IpcService } from "../services/ipc.service";
import { from } from "rxjs";
import log from "electron-log"
const ipc = IpcService.getInstance();
@@ -71,6 +72,7 @@ ipc.on("one-click-install-map", async (request: IpcRequest<BsvMapDetail>) => {
utils.ipcSend(request.responceChannel, { success: true });
})
.catch(err => {
log.error(err);
utils.ipcSend(request.responceChannel, { success: false, error: err });
});
});
+2
View File
@@ -2,6 +2,7 @@ import { ipcMain } from "electron";
import { IpcRequest } from "shared/models/ipc";
import { LocalPlaylistsManagerService } from "../services/additional-content/local-playlists-manager.service";
import { UtilsService } from "../services/utils.service";
import log from "electron-log";
ipcMain.on("one-click-install-playlist", async (event, request: IpcRequest<string>) => {
const utils = UtilsService.getInstance();
@@ -13,6 +14,7 @@ ipcMain.on("one-click-install-playlist", async (event, request: IpcRequest<strin
utils.ipcSend(request.responceChannel, { success: true });
})
.catch(e => {
log.error(e);
utils.ipcSend(request.responceChannel, { success: false, error: e });
});
});
@@ -7,7 +7,7 @@ import { InstallationLocationService } from "../installation-location.service";
import { UtilsService } from "../utils.service";
import crypto from "crypto";
import { lstatSync } from "fs";
import { copy, createReadStream, ensureDir, unlink } from "fs-extra";
import { copy, createReadStream, ensureDir, realpath, unlink } from "fs-extra";
import StreamZip from "node-stream-zip";
import { RequestService } from "../request.service";
import sanitize from "sanitize-filename";
@@ -290,10 +290,16 @@ export class LocalMapsManagerService {
const versions = await this.localVersion.getInstalledVersions();
const downloadedMap = await this.downloadMap(map, versions.pop());
const downloadedMapRealFolder = await realpath(path.dirname(downloadedMap.path));
for (const version of versions) {
const versionMapsPath = await this.getMapsFolderPath(version);
await ensureDir(versionMapsPath);
if((await realpath(versionMapsPath)) === downloadedMapRealFolder){
continue;
}
await copy(downloadedMap.path, path.join(versionMapsPath, path.basename(downloadedMap.path)), { overwrite: true });
}
}
@@ -14,7 +14,7 @@ import { IpcRequest } from "shared/models/ipc";
import { BPList, DownloadPlaylistProgression } from "shared/models/playlists/playlist.interface";
import { copyFileSync, readFileSync } from "fs";
import { BeatSaverService } from "../thrid-party/beat-saver/beat-saver.service";
import { copySync } from "fs-extra";
import { copy, realpath } from "fs-extra";
import { ensureFolderExist, pathExist } from "../../helpers/fs.helpers";
export class LocalPlaylistsManagerService {
@@ -180,14 +180,27 @@ export class LocalPlaylistsManagerService {
const { bpListPath, mapsPath } = await lastValueFrom(this.downloadPlaylist(bpListUrl, versions.pop()));
if(mapsPath?.length === 0 || !bpListPath) {
return;
}
const realSourceMapsFolder = await realpath(path.dirname(mapsPath[0]));
for (const version of versions) {
await this.installBPListFile(bpListPath, version);
const versionMapsFolder = await this.maps.getMapsFolderPath(version);
const realDestMapsFolder = await realpath(versionMapsFolder);
if(realSourceMapsFolder === realDestMapsFolder) {
continue;
}
for (const mapPath of mapsPath) {
const versionMapsFolder = await this.maps.getMapsFolderPath(version);
const mapDest = path.join(versionMapsFolder, path.basename(mapPath));
copySync(mapPath, mapDest, { overwrite: true });
await copy(mapPath, mapDest, { overwrite: true });
}
}
}
+15 -12
View File
@@ -11,7 +11,6 @@ import log from "electron-log";
import { Observable, of } from "rxjs";
import { BsmProtocolService } from "./bsm-protocol.service";
import { app, shell} from "electron";
import { Resvg } from "@resvg/resvg-js";
import Color from "color";
import { ensureDir, writeFile } from "fs-extra";
import toIco from "to-ico";
@@ -20,6 +19,7 @@ import { WindowManagerService } from "./window-manager.service";
import { IpcService } from "./ipc.service";
import { BSVersionLibService } from "./bs-version-lib.service";
import { execOnOs } from "../helpers/env.helpers";
import sharp from "sharp";
export class BSLauncherService {
private static instance: BSLauncherService;
@@ -80,7 +80,7 @@ export class BSLauncherService {
}
private buildBsLaunchArgs(launchOptions: LaunchOption): string[]{
const launchArgs = [];
const launchArgs = ["--no-yeet"];
if (launchOptions.oculus) {
launchArgs.push("-vrmode");
@@ -161,7 +161,7 @@ export class BSLauncherService {
bsProcess.removeAllListeners("error");
bsProcess.removeAllListeners("exit");
resolve(-1);
}, 15_000);
}, 30_000);
}).then(exitCode => {
log.info("BS process exit code", exitCode);
@@ -183,7 +183,13 @@ export class BSLauncherService {
shortcutLink = new URL(shortcutLink);
}
return objectFromEntries(shortcutLink.searchParams.entries()) as ShortcutParams;
const params = objectFromEntries(shortcutLink.searchParams.entries()) as ShortcutParams;
if(typeof params.additionalArgs === "string"){
params.additionalArgs = [params.additionalArgs];
}
return params;
}
public shortcutLinkToLaunchOptions(shortcutLink: string|URL): LaunchOption{
@@ -224,19 +230,16 @@ export class BSLauncherService {
return res;
}
private createShortcutPngBuffer(color: Color): Buffer{
private createShortcutPngBuffer(color: Color): Promise<Buffer>{
const svgIcon = `
const svgBuffer = Buffer.from(`
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 406.4 406.4" height="406.4" width="406.4">
<rect rx="69.453" height="406.4" width="406.4" fill="${color.hex()}"/>
<path d="M65.467 60.6H336.4v33.867L200.933 162.2 65.467 94.467z" fill="#fff"/>
</svg>
`;
return new Resvg(svgIcon, {
fitTo: { mode: "width", value: 256 }
}).render().asPng();
`);
return sharp(svgBuffer).resize(256).png().toBuffer();
}
/**
@@ -262,7 +265,7 @@ export class BSLauncherService {
* @returns {Promise<string>} Path of the icon
*/
private async createShortcutIco(color: Color): Promise<string>{
const pngBuffer = this.createShortcutPngBuffer(color);
const pngBuffer = await this.createShortcutPngBuffer(color);
const icoBuffer = await toIco([pngBuffer]);
await ensureDir(IMAGE_CACHE_PATH);
@@ -38,11 +38,11 @@ export class InstallationLocationService {
}
public async setInstallationDirectory(newDir: string): Promise<string> {
newDir = path.basename(newDir) === this.INSTALLATION_FOLDER ? newDir : path.join(newDir, this.INSTALLATION_FOLDER);
newDir = path.basename(newDir) === this.INSTALLATION_FOLDER ? path.join(newDir, "..") : newDir;
const oldDir = await this.installationDirectory();
await ensureFolderExist(oldDir);
await copyDirectoryWithJunctions(oldDir, newDir, { overwrite: true });
await copyDirectoryWithJunctions(oldDir, path.join(newDir, this.INSTALLATION_FOLDER), { overwrite: true });
this._installationDirectory = newDir;
this.installPathConfig.set(this.STORE_INSTALLATION_PATH_KEY, newDir);
@@ -57,23 +57,27 @@ export class InstallationLocationService {
}
public async installationDirectory(): Promise<string> {
if(this._installationDirectory) {
return this._installationDirectory;
}
if(this.installPathConfig.has(this.STORE_INSTALLATION_PATH_KEY)) {
this._installationDirectory = this.installPathConfig.get(this.STORE_INSTALLATION_PATH_KEY) as string;
return this._installationDirectory;
}
const oldPath = path.join(app.getPath("documents"), this.INSTALLATION_FOLDER);
if(await pathExist(oldPath)){
this._installationDirectory = oldPath;
return this._installationDirectory;
}
const installParentPath = async () => {
if(this._installationDirectory) {
return this._installationDirectory;
}
this._installationDirectory = path.join(app.getPath("home"), this.INSTALLATION_FOLDER);
return this._installationDirectory;
if(this.installPathConfig.has(this.STORE_INSTALLATION_PATH_KEY)) {
return this.installPathConfig.get(this.STORE_INSTALLATION_PATH_KEY) as string;
}
const oldPath = path.join(app.getPath("documents"), this.INSTALLATION_FOLDER);
if(await pathExist(oldPath)){
return app.getPath("documents");
}
return app.getPath("home");
};
this._installationDirectory = await installParentPath();
return path.join(this._installationDirectory, this.INSTALLATION_FOLDER);
}
public async versionsDirectory(): Promise<string> {
+3 -3
View File
@@ -20,13 +20,13 @@ export class LivService {
}
public isLivInstalled(): Promise<boolean> {
public async isLivInstalled(): Promise<boolean> {
return execOnOs({
win32: async () => {
const regRes = await regedit.promisified.list([this.livRegeditKey]).then(res => res[this.livRegeditKey]);
return regRes?.exists;
}
});
},
}, true);
}
public async createLivShortcut(entry: LivEntry): Promise<void> {
@@ -30,7 +30,7 @@ export function NavBar() {
if (downloadingVersion){ versions.push(downloadingVersion); }
const sorted = versions.sort((a, b) => +b.ReleaseDate - +a.ReleaseDate);
const sorted = BSVersionManagerService.sortVersions(versions);
return BSVersionManagerService.removeDuplicateVersions(sorted);
}
@@ -5,7 +5,7 @@ import { ModalExitCode, ModalService } from "./modale.service";
import { NotificationService } from "./notification.service";
import { ProgressBarService } from "./progress-bar.service";
import { EditVersionModal } from "renderer/components/modal/modal-types/edit-version-modal.component";
import { swapElements } from "shared/helpers/array.helpers";
import { popElement } from "shared/helpers/array.helpers";
export class BSVersionManagerService {
private static instance: BSVersionManagerService;
@@ -34,18 +34,7 @@ export class BSVersionManagerService {
}
public setInstalledVersions(versions: BSVersion[]) {
const sorted: BSVersion[] = versions.sort((a, b) => +b.ReleaseDate - +a.ReleaseDate);
const steamIndex = sorted.findIndex(v => v.steam);
const oculusIndex = sorted.findIndex(v => v.oculus);
if (steamIndex > 0) {
swapElements(steamIndex, 0, sorted);
}
if (oculusIndex > 0) {
swapElements(oculusIndex, steamIndex >= 0 ? 1 : 0, sorted);
}
const sorted = BSVersionManagerService.sortVersions(versions);
this.installedVersions$.next(BSVersionManagerService.removeDuplicateVersions(sorted));
}
@@ -123,6 +112,19 @@ export class BSVersionManagerService {
return this.ipcService.sendV2("get-version-full-path", { args: version });
}
public static sortVersions(versions: BSVersion[]): BSVersion[] {
const steamVersion = popElement(v => v.steam, versions);
const oculusVersion = popElement(v => v.oculus, versions);
const compare = (a: BSVersion, b: BSVersion) => ( +b.ReleaseDate - +a.ReleaseDate )
const sorted: BSVersion[] = versions.sort(compare);
sorted.unshift(...[steamVersion, oculusVersion].filter(Boolean).sort(compare));
return sorted;
}
public static removeDuplicateVersions(versions: BSVersion[]): BSVersion[] {
return Array.from(new Map(versions.map(version => ([
JSON.stringify([
+8
View File
@@ -10,3 +10,11 @@ export function swapElements<T = unknown>(from: number, to: number, arr: T[]): T
[arr[from], arr[to]] = [arr[to], arr[from]];
return arr;
}
export function popElement<T = unknown>(func: (element: T) => boolean, arr: T[]): T {
const index = arr.findIndex(func);
if (index === -1) {
return null;
}
return arr.splice(index, 1)[0];
}