mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-29 05:41:03 +00:00
feat: migrating games to level
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
import { gameRepository } from "@main/repository";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
import type { Game, GameShop } from "@types";
|
||||
@@ -8,7 +6,7 @@ import { steamGamesWorker } from "@main/workers";
|
||||
import { createGame } from "@main/services/library-sync";
|
||||
import { steamUrlBuilder } from "@shared";
|
||||
import { updateLocalUnlockedAchivements } from "@main/services/achievements/update-local-unlocked-achivements";
|
||||
import { gamesSublevel, levelKeys } from "@main/level";
|
||||
import { downloadsSublevel, gamesSublevel, levelKeys } from "@main/level";
|
||||
|
||||
const addGameToLibrary = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
@@ -16,41 +14,42 @@ const addGameToLibrary = async (
|
||||
objectId: string,
|
||||
title: string
|
||||
) => {
|
||||
return gameRepository
|
||||
.update(
|
||||
{
|
||||
objectID: objectId,
|
||||
},
|
||||
{
|
||||
shop,
|
||||
status: null,
|
||||
isDeleted: false,
|
||||
}
|
||||
)
|
||||
.then(async ({ affected }) => {
|
||||
if (!affected) {
|
||||
const steamGame = await steamGamesWorker.run(Number(objectId), {
|
||||
name: "getById",
|
||||
});
|
||||
const gameKey = levelKeys.game(shop, objectId);
|
||||
const game = await gamesSublevel.get(gameKey);
|
||||
|
||||
const iconUrl = steamGame?.clientIcon
|
||||
? steamUrlBuilder.icon(objectId, steamGame.clientIcon)
|
||||
: null;
|
||||
if (game) {
|
||||
await downloadsSublevel.del(gameKey);
|
||||
|
||||
const game: Game = {
|
||||
title,
|
||||
iconUrl,
|
||||
objectId,
|
||||
shop,
|
||||
};
|
||||
|
||||
await gamesSublevel.put(levelKeys.game(shop, objectId), game);
|
||||
}
|
||||
|
||||
updateLocalUnlockedAchivements(game!);
|
||||
|
||||
createGame(game!).catch(() => {});
|
||||
await gamesSublevel.put(gameKey, {
|
||||
...game,
|
||||
isDeleted: false,
|
||||
});
|
||||
} else {
|
||||
const steamGame = await steamGamesWorker.run(Number(objectId), {
|
||||
name: "getById",
|
||||
});
|
||||
|
||||
const iconUrl = steamGame?.clientIcon
|
||||
? steamUrlBuilder.icon(objectId, steamGame.clientIcon)
|
||||
: null;
|
||||
|
||||
const game: Game = {
|
||||
title,
|
||||
iconUrl,
|
||||
objectId,
|
||||
shop,
|
||||
remoteId: null,
|
||||
isDeleted: false,
|
||||
playTimeInMilliseconds: 0,
|
||||
lastTimePlayed: null,
|
||||
};
|
||||
|
||||
await gamesSublevel.put(levelKeys.game(shop, objectId), game);
|
||||
|
||||
updateLocalUnlockedAchivements(game!);
|
||||
|
||||
createGame(game!).catch(() => {});
|
||||
}
|
||||
};
|
||||
|
||||
registerEvent("addGameToLibrary", addGameToLibrary);
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { gamesSublevel } from "@main/level";
|
||||
import { downloadsSublevel, gamesSublevel } from "@main/level";
|
||||
|
||||
const getLibrary = async () => {
|
||||
// TODO: Add sorting
|
||||
return gamesSublevel
|
||||
.values()
|
||||
.iterator()
|
||||
.all()
|
||||
.then((results) => {
|
||||
return results.filter((game) => game.isDeleted === false);
|
||||
return Promise.all(
|
||||
results
|
||||
.filter(([_key, game]) => game.isDeleted === false)
|
||||
.map(async ([key, game]) => {
|
||||
const download = await downloadsSublevel.get(key);
|
||||
|
||||
return {
|
||||
...game,
|
||||
download,
|
||||
};
|
||||
})
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import { shell } from "electron";
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { spawnSync, exec } from "node:child_process";
|
||||
|
||||
import { generateYML } from "../helpers/generate-lutris-yaml";
|
||||
import { getDownloadsPath } from "../helpers/get-downloads-path";
|
||||
import { registerEvent } from "../register-event";
|
||||
import { gamesSublevel, levelKeys } from "@main/level";
|
||||
import { downloadsSublevel, levelKeys } from "@main/level";
|
||||
import { GameShop } from "@types";
|
||||
|
||||
const executeGameInstaller = (filePath: string) => {
|
||||
@@ -29,18 +27,18 @@ const openGameInstaller = async (
|
||||
shop: GameShop,
|
||||
objectId: string
|
||||
) => {
|
||||
const game = await gamesSublevel.get(levelKeys.game(shop, objectId));
|
||||
const downloadKey = levelKeys.game(shop, objectId);
|
||||
const download = await downloadsSublevel.get(downloadKey);
|
||||
|
||||
if (!game || game.isDeleted || !game.folderName) return true;
|
||||
if (!download || !download.folderName) return true;
|
||||
|
||||
const gamePath = path.join(
|
||||
game.downloadPath ?? (await getDownloadsPath()),
|
||||
game.folderName!
|
||||
download.downloadPath ?? (await getDownloadsPath()),
|
||||
download.folderName!
|
||||
);
|
||||
|
||||
if (!fs.existsSync(gamePath)) {
|
||||
// TODO: LEVELDB Remove download?
|
||||
// await gameRepository.update({ id: gameId }, { status: null });
|
||||
await downloadsSublevel.del(downloadKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -70,13 +68,6 @@ const openGameInstaller = async (
|
||||
);
|
||||
}
|
||||
|
||||
if (spawnSync("which", ["lutris"]).status === 0) {
|
||||
const ymlPath = path.join(gamePath, "setup.yml");
|
||||
await writeFile(ymlPath, generateYML(game));
|
||||
exec(`lutris --install "${ymlPath}"`);
|
||||
return true;
|
||||
}
|
||||
|
||||
shell.openPath(gamePath);
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -1,22 +1,31 @@
|
||||
import { gameRepository } from "@main/repository";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
import { shell } from "electron";
|
||||
import { parseExecutablePath } from "../helpers/parse-executable-path";
|
||||
import { levelKeys } from "@main/level";
|
||||
import { gamesSublevel } from "@main/level";
|
||||
import { GameShop } from "@types";
|
||||
|
||||
const openGame = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
gameId: number,
|
||||
shop: GameShop,
|
||||
objectId: string,
|
||||
executablePath: string,
|
||||
launchOptions: string | null
|
||||
) => {
|
||||
// TODO: revisit this for launchOptions
|
||||
const parsedPath = parseExecutablePath(executablePath);
|
||||
|
||||
await gameRepository.update(
|
||||
{ id: gameId },
|
||||
{ executablePath: parsedPath, launchOptions }
|
||||
);
|
||||
const gameKey = levelKeys.game(shop, objectId);
|
||||
|
||||
const game = await gamesSublevel.get(gameKey);
|
||||
|
||||
if (!game) return;
|
||||
|
||||
await gamesSublevel.put(gameKey, {
|
||||
...game,
|
||||
executablePath: parsedPath,
|
||||
launchOptions,
|
||||
});
|
||||
|
||||
shell.openPath(parsedPath);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user