mirror of
https://github.com/Zagrios/bs-manager.git
synced 2026-07-03 14:08:25 +02:00
fully load local maps, and prepare bsaver map infos
This commit is contained in:
@@ -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){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>{
|
||||
|
||||
Reference in New Issue
Block a user