feat: optimizations

This commit is contained in:
Zamitto
2025-06-26 19:37:28 -03:00
parent cb758cceda
commit bf8fd0dacf
14 changed files with 46 additions and 51 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "hydralauncher",
"version": "3.6.1",
"version": "3.6.2",
"description": "Hydra",
"main": "./out/main/index.js",
"author": "Los Broxas",

View File

@@ -102,7 +102,12 @@ def process_list():
if auth_error:
return auth_error
process_list = [proc.info for proc in psutil.process_iter(['exe', 'cwd', 'pid', 'name', 'environ'])]
iter_list = ['exe', 'pid', 'name']
if sys.platform != 'win32':
iter_list.append('cwd')
iter_list.append('environ')
process_list = [proc.info for proc in psutil.process_iter(iter_list)]
return jsonify(process_list), 200
@app.route("/profile-image", methods=["POST"])

View File

@@ -1,17 +1,38 @@
import type { GameShop, GameStats } from "@types";
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import { gamesStatsCacheSublevel, levelKeys } from "@main/level";
const LOCAL_CACHE_EXPIRATION = 1000 * 60 * 30; // 30 minutes
const getGameStats = async (
_event: Electron.IpcMainInvokeEvent,
objectId: string,
shop: GameShop
) => {
const cachedStats = await gamesStatsCacheSublevel.get(
levelKeys.game(shop, objectId)
);
if (
cachedStats &&
cachedStats.updatedAt + LOCAL_CACHE_EXPIRATION > Date.now()
) {
return cachedStats;
}
return HydraApi.get<GameStats>(
`/games/stats`,
{ objectId, shop },
{ needsAuth: false }
);
).then(async (data) => {
await gamesStatsCacheSublevel.put(levelKeys.game(shop, objectId), {
...data,
updatedAt: Date.now(),
});
return data;
});
};
registerEvent("getGameStats", getGameStats);

View File

@@ -20,7 +20,6 @@ import "./library/create-game-shortcut";
import "./library/close-game";
import "./library/delete-game-folder";
import "./library/get-game-by-object-id";
import "./library/sync-game-by-object-id";
import "./library/get-library";
import "./library/extract-game-download";
import "./library/open-game";

View File

@@ -1,32 +0,0 @@
import { registerEvent } from "../register-event";
import { gamesSublevel, levelKeys } from "@main/level";
import { HydraApi } from "@main/services";
import type { GameShop, UserGameDetails } from "@types";
const syncGameByObjectId = async (
_event: Electron.IpcMainInvokeEvent,
shop: GameShop,
objectId: string
) => {
return HydraApi.get<UserGameDetails>(
`/profile/games/${shop}/${objectId}`
).then(async (res) => {
const { id, playTimeInSeconds, isFavorite, ...rest } = res;
const gameKey = levelKeys.game(shop, objectId);
const currentData = await gamesSublevel.get(gameKey);
await gamesSublevel.put(gameKey, {
...currentData,
...rest,
remoteId: id,
playTimeInMilliseconds: playTimeInSeconds * 1000,
favorite: isFavorite ?? currentData?.favorite,
});
return res;
});
};
registerEvent("syncGameByObjectId", syncGameByObjectId);

View File

@@ -0,0 +1,11 @@
import type { GameStats } from "@types";
import { db } from "../level";
import { levelKeys } from "./keys";
export const gamesStatsCacheSublevel = db.sublevel<
string,
GameStats & { updatedAt: number }
>(levelKeys.gameStatsCache, {
valueEncoding: "json",
});

View File

@@ -2,6 +2,7 @@ export * from "./downloads";
export * from "./games";
export * from "./game-shop-assets";
export * from "./game-shop-cache";
export * from "./game-stats-cache";
export * from "./game-achievements";
export * from "./keys";
export * from "./themes";

View File

@@ -7,6 +7,7 @@ export const levelKeys = {
auth: "auth",
themes: "themes",
gameShopAssets: "gameShopAssets",
gameStatsCache: "gameStatsAssets",
gameShopCache: "gameShopCache",
gameShopCacheItem: (shop: GameShop, objectId: string, language: string) =>
`${shop}:${objectId}:${language}`,

View File

@@ -5,7 +5,7 @@ import { logger } from "../logger";
import { db, gameAchievementsSublevel, levelKeys } from "@main/level";
import { AxiosError } from "axios";
const LOCAL_CACHE_EXPIRATION = 1000 * 60 * 30; // 30 minutes
const LOCAL_CACHE_EXPIRATION = 1000 * 60 * 60; // 1 hour
const getModifiedSinceHeader = (
cachedAchievements: GameAchievement | undefined

View File

@@ -31,8 +31,8 @@ export interface ProcessPayload {
exe: string | null;
pid: number;
name: string;
environ: Record<string, string> | null;
cwd: string | null;
environ?: Record<string, string> | null;
cwd?: string | null;
}
export interface PauseSeedingPayload {

View File

@@ -25,7 +25,7 @@ interface GameExecutables {
[key: string]: ExecutableInfo[];
}
const TICKS_TO_UPDATE_API = 80;
const TICKS_TO_UPDATE_API = 120;
let currentTick = 1;
const platform = process.platform;

View File

@@ -187,8 +187,6 @@ contextBridge.exposeInMainWorld("electron", {
ipcRenderer.invoke("deleteGameFolder", shop, objectId),
getGameByObjectId: (shop: GameShop, objectId: string) =>
ipcRenderer.invoke("getGameByObjectId", shop, objectId),
syncGameByObjectId: (shop: GameShop, objectId: string) =>
ipcRenderer.invoke("syncGameByObjectId", shop, objectId),
resetGameAchievements: (shop: GameShop, objectId: string) =>
ipcRenderer.invoke("resetGameAchievements", shop, objectId),
extractGameDownload: (shop: GameShop, objectId: string) =>

View File

@@ -182,14 +182,6 @@ export function GameDetailsContextProvider({
})
.catch(() => {});
}
window.electron
.syncGameByObjectId(shop, objectId)
.then(() => {
if (abortController.signal.aborted) return;
updateGame();
})
.catch(() => {});
}, [
updateGame,
dispatch,

View File

@@ -155,7 +155,6 @@ declare global {
shop: GameShop,
objectId: string
) => Promise<LibraryGame | null>;
syncGameByObjectId: (shop: GameShop, objectId: string) => Promise<void>;
onGamesRunning: (
cb: (
gamesRunning: Pick<GameRunning, "id" | "sessionDurationInMillis">[]