mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-23 10:51:02 +00:00
added proper image saving for custom games + edited game settings to hide buttons if game is custom
This commit is contained in:
@@ -39,7 +39,9 @@ import "./library/reset-game-achievements";
|
||||
import "./library/change-game-playtime";
|
||||
import "./library/toggle-automatic-cloud-sync";
|
||||
import "./library/get-default-wine-prefix-selection-path";
|
||||
import "./library/cleanup-unused-assets";
|
||||
import "./library/create-steam-shortcut";
|
||||
import "./library/copy-custom-game-asset";
|
||||
import "./misc/open-checkout";
|
||||
import "./misc/open-external";
|
||||
import "./misc/show-open-dialog";
|
||||
|
||||
73
src/main/events/library/cleanup-unused-assets.ts
Normal file
73
src/main/events/library/cleanup-unused-assets.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { ipcMain } from "electron";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { ASSETS_PATH } from "@main/constants";
|
||||
|
||||
const getCustomGamesAssetsPath = () => {
|
||||
return path.join(ASSETS_PATH, "custom-games");
|
||||
};
|
||||
|
||||
const getAllCustomGameAssets = async (): Promise<string[]> => {
|
||||
const assetsPath = getCustomGamesAssetsPath();
|
||||
|
||||
if (!fs.existsSync(assetsPath)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const files = await fs.promises.readdir(assetsPath);
|
||||
return files.map(file => path.join(assetsPath, file));
|
||||
};
|
||||
|
||||
const getUsedAssetPaths = async (): Promise<Set<string>> => {
|
||||
// Get all custom games from the level database
|
||||
const { gamesSublevel } = await import("@main/level");
|
||||
const allGames = await gamesSublevel.iterator().all();
|
||||
|
||||
const customGames = allGames
|
||||
.map(([_key, game]) => game)
|
||||
.filter(game => game.shop === "custom" && !game.isDeleted);
|
||||
|
||||
const usedPaths = new Set<string>();
|
||||
|
||||
customGames.forEach(game => {
|
||||
// Extract file paths from local URLs
|
||||
if (game.iconUrl?.startsWith("local:")) {
|
||||
usedPaths.add(game.iconUrl.replace("local:", ""));
|
||||
}
|
||||
if (game.logoImageUrl?.startsWith("local:")) {
|
||||
usedPaths.add(game.logoImageUrl.replace("local:", ""));
|
||||
}
|
||||
if (game.libraryHeroImageUrl?.startsWith("local:")) {
|
||||
usedPaths.add(game.libraryHeroImageUrl.replace("local:", ""));
|
||||
}
|
||||
});
|
||||
|
||||
return usedPaths;
|
||||
};
|
||||
|
||||
export const cleanupUnusedAssets = async (): Promise<{ deletedCount: number; errors: string[] }> => {
|
||||
try {
|
||||
const allAssets = await getAllCustomGameAssets();
|
||||
const usedAssets = await getUsedAssetPaths();
|
||||
|
||||
const errors: string[] = [];
|
||||
let deletedCount = 0;
|
||||
|
||||
for (const assetPath of allAssets) {
|
||||
if (!usedAssets.has(assetPath)) {
|
||||
try {
|
||||
await fs.promises.unlink(assetPath);
|
||||
deletedCount++;
|
||||
} catch (error) {
|
||||
errors.push(`Failed to delete ${assetPath}: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { deletedCount, errors };
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to cleanup unused assets: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
ipcMain.handle("cleanupUnusedAssets", cleanupUnusedAssets);
|
||||
42
src/main/events/library/copy-custom-game-asset.ts
Normal file
42
src/main/events/library/copy-custom-game-asset.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { randomUUID } from "crypto";
|
||||
import { ASSETS_PATH } from "@main/constants";
|
||||
|
||||
const copyCustomGameAsset = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
sourcePath: string,
|
||||
assetType: "icon" | "logo" | "hero"
|
||||
): Promise<string> => {
|
||||
if (!sourcePath || !fs.existsSync(sourcePath)) {
|
||||
throw new Error("Source file does not exist");
|
||||
}
|
||||
|
||||
// Ensure assets directory exists
|
||||
if (!fs.existsSync(ASSETS_PATH)) {
|
||||
fs.mkdirSync(ASSETS_PATH, { recursive: true });
|
||||
}
|
||||
|
||||
// Create custom games assets subdirectory
|
||||
const customGamesAssetsPath = path.join(ASSETS_PATH, "custom-games");
|
||||
if (!fs.existsSync(customGamesAssetsPath)) {
|
||||
fs.mkdirSync(customGamesAssetsPath, { recursive: true });
|
||||
}
|
||||
|
||||
// Get file extension
|
||||
const fileExtension = path.extname(sourcePath);
|
||||
|
||||
// Generate unique filename
|
||||
const uniqueId = randomUUID();
|
||||
const fileName = `${assetType}-${uniqueId}${fileExtension}`;
|
||||
const destinationPath = path.join(customGamesAssetsPath, fileName);
|
||||
|
||||
// Copy the file
|
||||
await fs.promises.copyFile(sourcePath, destinationPath);
|
||||
|
||||
// Return the local URL format
|
||||
return `local:${destinationPath}`;
|
||||
};
|
||||
|
||||
registerEvent("copyCustomGameAsset", copyCustomGameAsset);
|
||||
Reference in New Issue
Block a user