mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-19 09:13:57 +00:00
159 lines
4.1 KiB
TypeScript
159 lines
4.1 KiB
TypeScript
import path from "node:path";
|
|
import fs from "node:fs";
|
|
import type { GameShop } from "@types";
|
|
import { downloadsSublevel, gamesSublevel, levelKeys } from "@main/level";
|
|
import { FILE_EXTENSIONS_TO_EXTRACT } from "@shared";
|
|
import { SevenZip } from "./7zip";
|
|
import { WindowManager } from "./window-manager";
|
|
import { publishExtractionCompleteNotification } from "./notifications";
|
|
import { logger } from "./logger";
|
|
|
|
export class GameFilesManager {
|
|
constructor(
|
|
private readonly shop: GameShop,
|
|
private readonly objectId: string
|
|
) {}
|
|
|
|
private async clearExtractionState() {
|
|
const gameKey = levelKeys.game(this.shop, this.objectId);
|
|
const download = await downloadsSublevel.get(gameKey);
|
|
|
|
await downloadsSublevel.put(gameKey, {
|
|
...download!,
|
|
extracting: false,
|
|
});
|
|
|
|
WindowManager.mainWindow?.webContents.send(
|
|
"on-extraction-complete",
|
|
this.shop,
|
|
this.objectId
|
|
);
|
|
}
|
|
|
|
async extractFilesInDirectory(directoryPath: string) {
|
|
if (!fs.existsSync(directoryPath)) return;
|
|
const files = await fs.promises.readdir(directoryPath);
|
|
|
|
const compressedFiles = files.filter((file) =>
|
|
FILE_EXTENSIONS_TO_EXTRACT.some((ext) => file.endsWith(ext))
|
|
);
|
|
|
|
const filesToExtract = compressedFiles.filter(
|
|
(file) => /part1\.rar$/i.test(file) || !/part\d+\.rar$/i.test(file)
|
|
);
|
|
|
|
await Promise.all(
|
|
filesToExtract.map((file) => {
|
|
return new Promise((resolve, reject) => {
|
|
SevenZip.extractFile(
|
|
{
|
|
filePath: path.join(directoryPath, file),
|
|
cwd: directoryPath,
|
|
passwords: ["online-fix.me", "steamrip.com"],
|
|
},
|
|
() => {
|
|
resolve(true);
|
|
},
|
|
() => {
|
|
reject(new Error(`Failed to extract file: ${file}`));
|
|
this.clearExtractionState();
|
|
}
|
|
);
|
|
});
|
|
})
|
|
);
|
|
|
|
compressedFiles.forEach((file) => {
|
|
const extractionPath = path.join(directoryPath, file);
|
|
|
|
if (fs.existsSync(extractionPath)) {
|
|
fs.unlink(extractionPath, (err) => {
|
|
if (err) {
|
|
logger.error(`Failed to delete file: ${file}`, err);
|
|
|
|
this.clearExtractionState();
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
async setExtractionComplete(publishNotification = true) {
|
|
const gameKey = levelKeys.game(this.shop, this.objectId);
|
|
|
|
const [download, game] = await Promise.all([
|
|
downloadsSublevel.get(gameKey),
|
|
gamesSublevel.get(gameKey),
|
|
]);
|
|
|
|
await downloadsSublevel.put(gameKey, {
|
|
...download!,
|
|
extracting: false,
|
|
});
|
|
|
|
WindowManager.mainWindow?.webContents.send(
|
|
"on-extraction-complete",
|
|
this.shop,
|
|
this.objectId
|
|
);
|
|
|
|
if (publishNotification) {
|
|
publishExtractionCompleteNotification(game!);
|
|
}
|
|
}
|
|
|
|
async extractDownloadedFile() {
|
|
const gameKey = levelKeys.game(this.shop, this.objectId);
|
|
|
|
const [download, game] = await Promise.all([
|
|
downloadsSublevel.get(gameKey),
|
|
gamesSublevel.get(gameKey),
|
|
]);
|
|
|
|
if (!download || !game) return false;
|
|
|
|
const filePath = path.join(download.downloadPath, download.folderName!);
|
|
|
|
const extractionPath = path.join(
|
|
download.downloadPath,
|
|
path.parse(download.folderName!).name
|
|
);
|
|
|
|
SevenZip.extractFile(
|
|
{
|
|
filePath,
|
|
outputPath: extractionPath,
|
|
passwords: ["online-fix.me", "steamrip.com"],
|
|
},
|
|
async () => {
|
|
await this.extractFilesInDirectory(extractionPath);
|
|
|
|
if (fs.existsSync(extractionPath) && fs.existsSync(filePath)) {
|
|
fs.unlink(filePath, (err) => {
|
|
if (err) {
|
|
logger.error(
|
|
`Failed to delete file: ${download.folderName}`,
|
|
err
|
|
);
|
|
|
|
this.clearExtractionState();
|
|
}
|
|
});
|
|
}
|
|
|
|
await downloadsSublevel.put(gameKey, {
|
|
...download!,
|
|
folderName: path.parse(download.folderName!).name,
|
|
});
|
|
|
|
this.setExtractionComplete();
|
|
},
|
|
() => {
|
|
this.clearExtractionState();
|
|
}
|
|
);
|
|
|
|
return true;
|
|
}
|
|
}
|