mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-24 19:31:03 +00:00
feat: adding initial download sources
This commit is contained in:
38
src/main/services/7zip.ts
Normal file
38
src/main/services/7zip.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { app } from "electron";
|
||||
import cp from "node:child_process";
|
||||
import path from "node:path";
|
||||
|
||||
export const binaryName = {
|
||||
linux: "7zzs",
|
||||
darwin: "7zz",
|
||||
win32: "7zr.exe",
|
||||
};
|
||||
|
||||
export class _7Zip {
|
||||
private static readonly binaryPath = app.isPackaged
|
||||
? path.join(process.resourcesPath, binaryName[process.platform])
|
||||
: path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"..",
|
||||
"binaries",
|
||||
binaryName[process.platform]
|
||||
);
|
||||
|
||||
public static extractFile(
|
||||
filePath: string,
|
||||
outputPath: string,
|
||||
cb: () => void
|
||||
) {
|
||||
const child = cp.spawn(this.binaryPath, [
|
||||
"x",
|
||||
filePath,
|
||||
"-o" + outputPath,
|
||||
"-y",
|
||||
]);
|
||||
|
||||
child.on("exit", () => {
|
||||
cb();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2,18 +2,15 @@ import path from "node:path";
|
||||
import cp from "node:child_process";
|
||||
import { app } from "electron";
|
||||
|
||||
export const startAria2 = () => {};
|
||||
|
||||
export class Aria2 {
|
||||
private static process: cp.ChildProcess | null = null;
|
||||
private static readonly binaryPath = app.isPackaged
|
||||
? path.join(process.resourcesPath, "aria2", "aria2c")
|
||||
: path.join(__dirname, "..", "..", "aria2", "aria2c");
|
||||
|
||||
public static spawn() {
|
||||
const binaryPath = app.isPackaged
|
||||
? path.join(process.resourcesPath, "aria2", "aria2c")
|
||||
: path.join(__dirname, "..", "..", "aria2", "aria2c");
|
||||
|
||||
this.process = cp.spawn(
|
||||
binaryPath,
|
||||
this.binaryPath,
|
||||
[
|
||||
"--enable-rpc",
|
||||
"--rpc-listen-all",
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { Downloader, DownloadError } from "@shared";
|
||||
import { WindowManager } from "../window-manager";
|
||||
import { publishDownloadCompleteNotification } from "../notifications";
|
||||
import {
|
||||
publishDownloadCompleteNotification,
|
||||
publishExtractionCompleteNotification,
|
||||
} from "../notifications";
|
||||
import type { Download, DownloadProgress, UserPreferences } from "@types";
|
||||
import {
|
||||
GofileApi,
|
||||
@@ -22,9 +25,11 @@ import { logger } from "../logger";
|
||||
import { db, downloadsSublevel, gamesSublevel, levelKeys } from "@main/level";
|
||||
import { sortBy } from "lodash-es";
|
||||
import { TorBoxClient } from "./torbox";
|
||||
import { _7Zip } from "../7zip";
|
||||
|
||||
export class DownloadManager {
|
||||
private static downloadingGameId: string | null = null;
|
||||
private static readonly extensionsToExtract = [".rar", ".zip", ".7z"];
|
||||
|
||||
public static async startRPC(
|
||||
download?: Download,
|
||||
@@ -150,13 +155,47 @@ export class DownloadManager {
|
||||
queued: false,
|
||||
});
|
||||
} else {
|
||||
const shouldExtract =
|
||||
download.downloader !== Downloader.Torrent &&
|
||||
this.extensionsToExtract.some((ext) =>
|
||||
download.folderName?.endsWith(ext)
|
||||
) &&
|
||||
download.automaticallyExtract;
|
||||
|
||||
downloadsSublevel.put(gameId, {
|
||||
...download,
|
||||
status: "complete",
|
||||
shouldSeed: false,
|
||||
queued: false,
|
||||
extracting: shouldExtract,
|
||||
});
|
||||
|
||||
if (shouldExtract) {
|
||||
_7Zip.extractFile(
|
||||
path.join(download.downloadPath, download.folderName!),
|
||||
path.join(
|
||||
download.downloadPath,
|
||||
path.parse(download.folderName!).name
|
||||
),
|
||||
async () => {
|
||||
const download = await downloadsSublevel.get(gameId);
|
||||
|
||||
downloadsSublevel.put(gameId, {
|
||||
...download!,
|
||||
extracting: false,
|
||||
});
|
||||
|
||||
WindowManager.mainWindow?.webContents.send(
|
||||
"on-extraction-complete",
|
||||
game.shop,
|
||||
game.objectId
|
||||
);
|
||||
|
||||
publishExtractionCompleteNotification(game);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
this.cancelDownload(gameId);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,3 +8,4 @@ export * from "./main-loop";
|
||||
export * from "./hydra-api";
|
||||
export * from "./ludusavi";
|
||||
export * from "./cloud-sync";
|
||||
export * from "./7zip";
|
||||
|
||||
@@ -128,6 +128,17 @@ export const publishCombinedNewAchievementNotification = async (
|
||||
}
|
||||
};
|
||||
|
||||
export const publishExtractionCompleteNotification = async (game: Game) => {
|
||||
new Notification({
|
||||
title: t("extraction_complete", { ns: "notifications" }),
|
||||
body: t("game_extracted", {
|
||||
ns: "notifications",
|
||||
title: game.title,
|
||||
}),
|
||||
icon: trayIcon,
|
||||
}).show();
|
||||
};
|
||||
|
||||
export const publishNewAchievementNotification = async (info: {
|
||||
achievements: { displayName: string; iconUrl: string }[];
|
||||
unlockedAchievementCount: number;
|
||||
|
||||
@@ -6,9 +6,9 @@ import axios from "axios";
|
||||
import { exec } from "child_process";
|
||||
import { ProcessPayload } from "./download/types";
|
||||
import { gamesSublevel, levelKeys } from "@main/level";
|
||||
import { t } from "i18next";
|
||||
import i18next, { t } from "i18next";
|
||||
import { CloudSync } from "./cloud-sync";
|
||||
import { format } from "date-fns";
|
||||
import { formatDate } from "date-fns";
|
||||
|
||||
const commands = {
|
||||
findWineDir: `lsof -c wine 2>/dev/null | grep '/drive_c/windows$' | head -n 1 | awk '{for(i=9;i<=NF;i++) printf "%s ", $i; print ""}'`,
|
||||
@@ -229,6 +229,8 @@ function onOpenGame(game: Game) {
|
||||
if (game.remoteId) {
|
||||
updateGamePlaytime(game, 0, new Date()).catch(() => {});
|
||||
|
||||
const { language } = i18next;
|
||||
|
||||
if (game.automaticCloudSync) {
|
||||
CloudSync.uploadSaveGame(
|
||||
game.objectId,
|
||||
@@ -236,7 +238,7 @@ function onOpenGame(game: Game) {
|
||||
null,
|
||||
t("automatic_backup_from", {
|
||||
ns: "game_details",
|
||||
date: format(new Date(), "dd/MM/yyyy"),
|
||||
date: formatDate(new Date(), language),
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -296,6 +298,8 @@ const onCloseGame = (game: Game) => {
|
||||
)!;
|
||||
gamesPlaytime.delete(levelKeys.game(game.shop, game.objectId));
|
||||
|
||||
const { language } = i18next;
|
||||
|
||||
if (game.remoteId) {
|
||||
updateGamePlaytime(
|
||||
game,
|
||||
@@ -310,7 +314,7 @@ const onCloseGame = (game: Game) => {
|
||||
null,
|
||||
t("automatic_backup_from", {
|
||||
ns: "game_details",
|
||||
date: format(new Date(), "dd/MM/yyyy"),
|
||||
date: formatDate(new Date(), language),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user