we can export all or specific maps

This commit is contained in:
MathieuG-P
2022-12-08 00:09:59 +01:00
parent 6df2c98955
commit 5bf674d782
11 changed files with 98 additions and 134 deletions
-47
View File
@@ -1,47 +0,0 @@
import path from "path";
import { BSVersion } from "shared/bs-version.interface";
import { BSLocalVersionService } from "./bs-local-version.service";
import archiver from "archiver";
import { createWriteStream } from "fs";
import log from "electron-log";
export class MapService{
private readonly MAP_PATH = path.join("Beat Saber_Data", "CustomLevels");
private static instance: MapService;
private readonly localVersionService: BSLocalVersionService;
public static getInstance(): MapService{
if(!MapService.instance){ MapService.instance = new MapService(); }
return MapService.instance;
}
private constructor(){
this.localVersionService = BSLocalVersionService.getInstance();
}
private getMapsPath(versionPath: string): string{
return path.join(versionPath, this.MAP_PATH);
}
public async exportVersionMaps(version: BSVersion, outputZip: string): Promise<void>{
const versionPath = await this.localVersionService.getVersionPath(version);
const mapsPath = this.getMapsPath(versionPath);
const output = createWriteStream(outputZip);
const archive = archiver("zip", {zlib: {level: 9}});
const promise = new Promise<void>((resolve, reject) => {
archive.pipe(output);
archive.directory(mapsPath, false);
archive.on("error", reject);
output.on("close", resolve);
archive.finalize()
});
return promise;
}
}
@@ -6,11 +6,12 @@ import { BSLocalVersionService } from "../bs-local-version.service";
import { InstallationLocationService } from "../installation-location.service";
import { UtilsService } from "../utils.service";
import crypto from "crypto";
import { lstatSync, symlinkSync, unlinkSync, readdirSync } from "fs";
import { lstatSync, symlinkSync, unlinkSync, readdirSync, createWriteStream } from "fs";
import { copySync } from "fs-extra";
import StreamZip from "node-stream-zip";
import { RequestService } from "../request.service";
import sanitize from "sanitize-filename";
import archiver from "archiver";
export class LocalMapsManagerService {
@@ -90,6 +91,28 @@ export class LocalMapsManagerService {
return {zip, zipPath};
}
private async getAbsoluteFolderOfMaps(maps: BsmLocalMap[], version: BSVersion): Promise<string[]>{
const mapsFolder = await this.getMapsFolderPath(version);
const res: string[] = [];
const mapHashs = maps.map(map => map.hash);
const mapsFolders = readdirSync(mapsFolder, {withFileTypes: true});
for(const content of mapsFolders){
if(!content.isDirectory()){ continue; }
const mapFolderPath = path.join(mapsFolder, content.name);
const { hash } = await this.loadMapInfoFromPath(mapFolderPath);
if(mapHashs.includes(hash)){
res.push(mapFolderPath);
}
}
return res;
}
public async getMaps(version?: BSVersion): Promise<BsmLocalMap[]>{
const levelsFolder = await this.getMapsFolderPath(version);
@@ -146,18 +169,13 @@ export class LocalMapsManagerService {
public async deleteMaps(maps: BsmLocalMap[], verion?: BSVersion){
const mapsFolder = await this.getMapsFolderPath(verion);
const mapsFolders = await this.getAbsoluteFolderOfMaps(maps, verion);
const mapsHashsToDelete = maps.map(map => map.hash);
const mapsHashsToDelete = maps.map(m => m.hash);
const mapsFolders = readdirSync(mapsFolder, {withFileTypes: true});
for(const content of mapsFolders){
if(!content.isDirectory()){ continue; }
const mapFolderPath = path.join(mapsFolder, content.name);
const { hash } = await this.loadMapInfoFromPath(mapFolderPath);
for(const folder of mapsFolders){
const { hash } = await this.loadMapInfoFromPath(folder);
if(mapsHashsToDelete.includes(hash)){
await this.utils.deleteFolder(mapFolderPath);
await this.utils.deleteFolder(folder);
}
}
@@ -187,6 +205,34 @@ export class LocalMapsManagerService {
unlinkSync(zipPath);
}
public async exportMaps(version: BSVersion, maps: BsmLocalMap[], outPath: string){
const output = createWriteStream(outPath);
const archive = archiver("zip", {zlib: {level: 9}});
archive.pipe(output);
archive.on("error", (e) => {throw e});
if(!maps || maps.length === 0){
const mapsFolder = await this.getMapsFolderPath(version);
archive.directory(mapsFolder, false);
}
else{
const mapsFolders = await this.getAbsoluteFolderOfMaps(maps, version);
for(const folder of mapsFolders){
archive.directory(folder, path.basename(folder));
}
}
await archive.finalize();
}
}