fully load local maps, and prepare bsaver map infos

This commit is contained in:
MathieuG-P
2022-11-06 01:38:31 +01:00
parent df4df8add1
commit 5e2dd10035
14 changed files with 200 additions and 24 deletions
@@ -12,6 +12,11 @@ export class InstallationLocationService {
private readonly INSTALLATION_FOLDER = "BSManager";
private readonly VERSIONS_FOLDER = "BSInstances";
private readonly SHARED_CONTENT_FOLDER = "SharedContent";
private readonly SHARED_MAPS_FOLDER = "SharedMaps";
private readonly SHARED_PLAYLISTS_FOLDER = "SharedPlaylists";
private readonly STORE_INSTALLATION_PATH_KEY = "installation-folder";
@@ -36,9 +41,6 @@ export class InstallationLocationService {
this._installationDirectory = this.configService.get<string>(this.STORE_INSTALLATION_PATH_KEY) || app.getPath("documents");
}
public get installationDirectory(): string{ return path.join(this._installationDirectory, this.INSTALLATION_FOLDER); }
public get versionsDirectory(): string { return path.join(this.installationDirectory, this.VERSIONS_FOLDER); }
public setInstallationDirectory(newDir: string): Promise<string>{
const oldDir = this.installationDirectory;
const newDest = path.join(newDir, this.INSTALLATION_FOLDER);
@@ -53,7 +55,15 @@ export class InstallationLocationService {
log.error(err);
})
})
}
public get installationDirectory(): string{ return path.join(this._installationDirectory, this.INSTALLATION_FOLDER); }
public get versionsDirectory(): string { return path.join(this.installationDirectory, this.VERSIONS_FOLDER); }
public get sharedContentPath(): string { return path.join(this.installationDirectory, this.SHARED_CONTENT_FOLDER); }
public get sharedMapsPath(): string { return path.join(this.sharedContentPath, this.SHARED_MAPS_FOLDER); }
public get sharedPlaylistsPath(): string { return path.join(this.sharedContentPath, this.SHARED_PLAYLISTS_FOLDER); }
}
@@ -0,0 +1,91 @@
import path from "path";
import { BSVersion } from "shared/bs-version.interface";
import { RawMapInfoData } from "shared/models/maps";
import { BsmLocalMap } from "shared/models/maps/bsm-local-map.interface";
import { BSLocalVersionService } from "../bs-local-version.service";
import { InstallationLocationService } from "../installation-location.service";
import { UtilsService } from "../utils.service";
import crypto from "crypto";
export class LocalMapsManagerService {
private static instance: LocalMapsManagerService;
public static getInstance(): LocalMapsManagerService{
if(!LocalMapsManagerService.instance){ LocalMapsManagerService.instance = new LocalMapsManagerService(); }
return LocalMapsManagerService.instance;
}
private readonly LEVELS_ROOT_FOLDER = "Beat Saber_Data";
private readonly CUSTOM_LEVELS_FOLDER = "CustomLevels";
private readonly WIP_LEVELS_FOLDER = "CustomWIPLevels";
private readonly localVersion: BSLocalVersionService;
private readonly installLocation: InstallationLocationService;
private readonly utils: UtilsService;
private constructor(){
this.localVersion = BSLocalVersionService.getInstance();
this.installLocation = InstallationLocationService.getInstance();
this.utils = UtilsService.getInstance();
}
private async getMapsPath(version?: BSVersion): Promise<string>{
if(version){ return path.join(await this.localVersion.getVersionPath(version), this.LEVELS_ROOT_FOLDER); }
return this.installLocation.sharedMapsPath;
}
private async computeMapHash(mapPath: string, rawInfoString: string): Promise<string>{
const mapRawInfo = JSON.parse(rawInfoString);
let content = rawInfoString;
console.log("oui");
for(const set of mapRawInfo._difficultyBeatmapSets){
for(const diff of set._difficultyBeatmaps){
const diffFilePath = path.join(mapPath, diff._beatmapFilename);
if(!await this.utils.pathExist(diffFilePath)){ continue; }
const diffContent = (await this.utils.readFileAsync(diffFilePath)).toString()
content += diffContent;
}
}
const shasum = crypto.createHash("sha1");
shasum.update(content);
return shasum.digest("hex");
}
private async loadMapInfoFromPath(mapPath: string): Promise<BsmLocalMap>{
const infoFilePath = path.join(mapPath, "Info.dat");
if(!(await this.utils.pathExist(infoFilePath))){ return null; }
const rawInfoString = await (await (this.utils.readFileAsync(infoFilePath))).toString();
const rawInfo: RawMapInfoData = JSON.parse(rawInfoString);
const coverUrl = new URL(`file:///${path.join(mapPath, rawInfo._coverImageFilename)}`).href;
const songUrl = new URL(`file:///${path.join(mapPath, rawInfo._songFilename)}`).href;
const hash = await this.computeMapHash(mapPath, rawInfoString);
return {rawInfo, coverUrl, songUrl, hash};
}
public async getMaps(version?: BSVersion): Promise<BsmLocalMap[]>{
const levelsRoot = await this.getMapsPath(version);
const levelsFolder = path.join(levelsRoot, this.CUSTOM_LEVELS_FOLDER);
const levelsPath = (await this.utils.pathExist(levelsFolder)) ? this.utils.listDirsInDir(levelsFolder, true) : [];
const mapsInfo = await Promise.all(levelsPath.map(levelPath => this.loadMapInfoFromPath(levelPath)))
console.log(mapsInfo);
return mapsInfo.filter(info => !!info);
}
public deleteMap(version?: BSVersion){
}
}
+2 -2
View File
@@ -68,10 +68,10 @@ export class UtilsService{
});
}
public listDirsInDir(dirPath: string): string[]{
public listDirsInDir(dirPath: string, fullPath = false): string[]{
let files = readdirSync(dirPath, { withFileTypes:true});
files = files.filter(f => f.isDirectory())
return files.map(f => f.name);
return files.map(f => fullPath ? path.join(dirPath, f.name) : f.name);
}
public deleteFolder(folderPath: string): Promise<void>{