feat: adding drive mapping

This commit is contained in:
Chubby Granny Chaser 2024-10-08 03:33:06 +01:00
parent 1705b89355
commit bcca701dc9
No known key found for this signature in database
4 changed files with 68 additions and 27 deletions

View file

@ -20,3 +20,5 @@ export const seedsPath = app.isPackaged
export const backupsPath = path.join(app.getPath("userData"), "Backups");
export const appVersion = app.getVersion();
export const artifactMetadataFileName = "hydra-launcher-metadata.json";

View file

@ -5,7 +5,7 @@ import { registerEvent } from "../register-event";
import axios from "axios";
import { app } from "electron";
import path from "node:path";
import { backupsPath } from "@main/constants";
import { artifactMetadataFileName, backupsPath } from "@main/constants";
import type { GameShop } from "@types";
import YAML from "yaml";
@ -20,10 +20,16 @@ export interface LudusaviBackup {
};
}
const getPathDrive = (key: string) => {
const parts = key.split("/");
return parts[0];
};
const replaceLudusaviBackupWithCurrentUser = (
gameBackupPath: string,
backupHomeDir: string
backupPath: string,
title: string
) => {
const gameBackupPath = path.join(backupPath, title);
const mappingYamlPath = path.join(gameBackupPath, "mapping.yaml");
const data = fs.readFileSync(mappingYamlPath, "utf8");
@ -32,32 +38,54 @@ const replaceLudusaviBackupWithCurrentUser = (
drives: Record<string, string>;
};
const metadataPath = path.join(backupPath, artifactMetadataFileName);
if (!fs.existsSync(metadataPath)) {
logger.error(`metadata not found in backup ${gameBackupPath}`);
return;
}
const metadata = JSON.parse(fs.readFileSync(metadataPath, "utf8")) as {
home: string;
documents: string;
};
const currentHomeDir = normalizePath(app.getPath("home"));
const currentDocumentsDir = normalizePath(app.getPath("documents"));
// TODO: Only works on Windows
const usersDirPath = path.join(gameBackupPath, "drive-C", "Users");
/* Renaming logic */
const mappedHomeDir = path.join(
gameBackupPath,
metadata.home.replace("C:", "drive-C")
);
const mappedDocumentsDir = path.join(
gameBackupPath,
metadata.documents.replace("C:", "drive-C")
);
const oldPath = path.join(usersDirPath, path.basename(backupHomeDir));
const newPath = path.join(usersDirPath, path.basename(currentHomeDir));
if (fs.existsSync(mappedHomeDir)) {
fs.renameSync(
mappedHomeDir,
path.join(gameBackupPath, currentHomeDir.replace("C:", "drive-C"))
);
}
// Directories are different, rename
if (backupHomeDir !== currentHomeDir) {
if (fs.existsSync(newPath)) {
// Ensures that the destination is empty
fs.rmSync(newPath, {
recursive: true,
force: true,
});
}
fs.renameSync(oldPath, newPath);
if (fs.existsSync(mappedDocumentsDir)) {
fs.renameSync(
mappedDocumentsDir,
path.join(gameBackupPath, currentDocumentsDir.replace("C:", "drive-C"))
);
}
const backups = manifest.backups.map((backup: LudusaviBackup) => {
const files = Object.entries(backup.files).reduce((prev, [key, value]) => {
const updatedKey = key
.replace(metadata.documents, currentDocumentsDir)
.replace(metadata.home, currentHomeDir);
return {
...prev,
[key.replace(backupHomeDir, currentHomeDir)]: value,
[updatedKey]: value,
};
}, {});
@ -76,10 +104,9 @@ const downloadGameArtifact = async (
shop: GameShop,
gameArtifactId: string
) => {
const { downloadUrl, objectKey, homeDir } = await HydraApi.post<{
const { downloadUrl, objectKey } = await HydraApi.post<{
downloadUrl: string;
objectKey: string;
homeDir: string;
}>(`/profile/games/artifacts/${gameArtifactId}/download`);
const zipLocation = path.join(app.getPath("userData"), objectKey);
@ -123,10 +150,7 @@ const downloadGameArtifact = async (
const [game] = await Ludusavi.findGames(shop, objectId);
if (!game) throw new Error("Game not found in Ludusavi manifest");
replaceLudusaviBackupWithCurrentUser(
path.join(backupPath, game),
normalizePath(path.normalize(homeDir))
);
replaceLudusaviBackupWithCurrentUser(backupPath, game);
Ludusavi.restoreBackup(backupPath).then(() => {
WindowManager.mainWindow?.webContents.send(

View file

@ -7,7 +7,7 @@ import crypto from "node:crypto";
import { GameShop } from "@types";
import axios from "axios";
import os from "node:os";
import { backupsPath } from "@main/constants";
import { artifactMetadataFileName, backupsPath } from "@main/constants";
import { app } from "electron";
import { normalizePath } from "@main/helpers";
@ -23,6 +23,21 @@ const bundleBackup = async (shop: GameShop, objectId: string) => {
const tarLocation = path.join(backupsPath, `${crypto.randomUUID()}.zip`);
fs.writeFileSync(
path.join(backupPath, artifactMetadataFileName),
JSON.stringify({
home: normalizePath(app.getPath("home")),
documents: normalizePath(app.getPath("documents")),
})
);
console.log(
JSON.stringify({
home: normalizePath(app.getPath("home")),
documents: normalizePath(app.getPath("documents")),
})
);
await tar.create(
{
gzip: false,

View file

@ -30,4 +30,4 @@ export const isPortableVersion = () =>
process.env.PORTABLE_EXECUTABLE_FILE !== null;
export const normalizePath = (str: string) =>
path.normalize(str.replace(/\\/g, "/"));
path.normalize(str).replace(/\\/g, "/");