diff --git a/src/main/events/catalogue/save-game-shop-assets.ts b/src/main/events/catalogue/save-game-shop-assets.ts index 5fdba628..f0ec4343 100644 --- a/src/main/events/catalogue/save-game-shop-assets.ts +++ b/src/main/events/catalogue/save-game-shop-assets.ts @@ -8,7 +8,9 @@ const saveGameShopAssets = async ( shop: GameShop, assets: ShopAssets ): Promise => { - return gamesShopAssetsSublevel.put(levelKeys.game(shop, objectId), assets); + const key = levelKeys.game(shop, objectId); + const existingAssets = await gamesShopAssetsSublevel.get(key); + return gamesShopAssetsSublevel.put(key, { ...existingAssets, ...assets }); }; registerEvent("saveGameShopAssets", saveGameShopAssets); diff --git a/src/main/events/library/reset-game-achievements.ts b/src/main/events/library/reset-game-achievements.ts index b3d2daa2..e63afcec 100644 --- a/src/main/events/library/reset-game-achievements.ts +++ b/src/main/events/library/reset-game-achievements.ts @@ -16,7 +16,8 @@ const resetGameAchievements = async ( objectId: string ) => { try { - const game = await gamesSublevel.get(levelKeys.game(shop, objectId)); + const levelKey = levelKeys.game(shop, objectId); + const game = await gamesSublevel.get(levelKey); if (!game) return; @@ -29,8 +30,6 @@ const resetGameAchievements = async ( } } - const levelKey = levelKeys.game(game.shop, game.objectId); - await gameAchievementsSublevel .get(levelKey) .then(async (gameAchievements) => { diff --git a/src/main/events/user/get-unlocked-achievements.ts b/src/main/events/user/get-unlocked-achievements.ts index 2bf4c76e..b8677894 100644 --- a/src/main/events/user/get-unlocked-achievements.ts +++ b/src/main/events/user/get-unlocked-achievements.ts @@ -9,8 +9,6 @@ export const getUnlockedAchievements = async ( shop: GameShop, useCachedData: boolean ): Promise => { - AchievementWatcherManager.firstSyncWithRemoteIfNeeded(shop, objectId); - const cachedAchievements = await gameAchievementsSublevel.get( levelKeys.game(shop, objectId) ); @@ -65,7 +63,7 @@ export const getUnlockedAchievements = async ( !achievementData.hidden || showHiddenAchievementsDescription ? achievementData.description : undefined, - } as UserAchievement; + }; }) .sort((a, b) => { if (a.unlocked && !b.unlocked) return -1; @@ -82,6 +80,7 @@ const getUnlockedAchievementsEvent = async ( objectId: string, shop: GameShop ): Promise => { + AchievementWatcherManager.firstSyncWithRemoteIfNeeded(shop, objectId); return getUnlockedAchievements(objectId, shop, false); }; diff --git a/src/main/services/achievements/achievement-watcher-manager.ts b/src/main/services/achievements/achievement-watcher-manager.ts index cf9a544c..944a7be7 100644 --- a/src/main/services/achievements/achievement-watcher-manager.ts +++ b/src/main/services/achievements/achievement-watcher-manager.ts @@ -19,7 +19,6 @@ import { Cracker } from "@shared"; import { publishCombinedNewAchievementNotification } from "../notifications"; import { db, gamesSublevel, levelKeys } from "@main/level"; import { WindowManager } from "../window-manager"; -import { sleep } from "@main/helpers"; const fileStats: Map = new Map(); const fltFiles: Map> = new Map(); @@ -38,7 +37,7 @@ const watchAchievementsWindows = async () => { const gameAchievementFiles: AchievementFile[] = []; for (const objectId of getAlternativeObjectIds(game.objectId)) { - gameAchievementFiles.push(...(achievementFiles.get(objectId) || [])); + gameAchievementFiles.push(...(achievementFiles.get(objectId) ?? [])); gameAchievementFiles.push( ...findAchievementFileInExecutableDirectory(game) @@ -128,6 +127,11 @@ const compareFile = (game: Game, file: AchievementFile) => { ); return processAchievementFileDiff(game, file); } catch (err) { + achievementsLogger.error( + "Error reading file", + file.filePath, + err instanceof Error ? err.message : err + ); fileStats.set(file.filePath, -1); return; } @@ -147,10 +151,10 @@ const processAchievementFileDiff = async ( }; export class AchievementWatcherManager { - private static _hasFinishedMergingWithRemote = false; + private static _hasFinishedPreSearch = false; - public static get hasFinishedMergingWithRemote() { - return this._hasFinishedMergingWithRemote; + public static get hasFinishedPreSearch() { + return this._hasFinishedPreSearch; } public static readonly alreadySyncedGames: Map = new Map(); @@ -191,7 +195,7 @@ export class AchievementWatcherManager { } public static watchAchievements() { - if (!this.hasFinishedMergingWithRemote) return; + if (!this.hasFinishedPreSearch) return; if (process.platform === "win32") { return watchAchievementsWindows(); @@ -230,7 +234,11 @@ export class AchievementWatcherManager { } } - return mergeAchievements(game, unlockedAchievements, false); + if (unlockedAchievements.length) { + return mergeAchievements(game, unlockedAchievements, false); + } + + return 0; } private static async getGameAchievementFilesWindows() { @@ -280,8 +288,6 @@ export class AchievementWatcherManager { } public static async preSearchAchievements() { - await sleep(2000); - try { const gameAchievementFiles = process.platform === "win32" @@ -337,6 +343,6 @@ export class AchievementWatcherManager { achievementsLogger.error("Error on preSearchAchievements", err); } - this._hasFinishedMergingWithRemote = true; + this._hasFinishedPreSearch = true; } } diff --git a/src/main/services/achievements/find-achivement-files.ts b/src/main/services/achievements/find-achivement-files.ts index 9fb1977d..7a531388 100644 --- a/src/main/services/achievements/find-achivement-files.ts +++ b/src/main/services/achievements/find-achivement-files.ts @@ -303,7 +303,7 @@ export const findAchievementFileInExecutableDirectory = ( "achievements.ini" ), }, - ]; + ].filter((file) => fs.existsSync(file.filePath)) as AchievementFile[]; }; const mapFileLocationWithObjectId = ( diff --git a/src/main/services/achievements/get-game-achievement-data.ts b/src/main/services/achievements/get-game-achievement-data.ts index f4d66b6a..977adcec 100644 --- a/src/main/services/achievements/get-game-achievement-data.ts +++ b/src/main/services/achievements/get-game-achievement-data.ts @@ -9,15 +9,15 @@ export const getGameAchievementData = async ( shop: GameShop, useCachedData: boolean ) => { - const cachedAchievements = await gameAchievementsSublevel.get( - levelKeys.game(shop, objectId) - ); + const gameKey = levelKeys.game(shop, objectId); - if (cachedAchievements && useCachedData) + const cachedAchievements = await gameAchievementsSublevel.get(gameKey); + + if (cachedAchievements?.achievements && useCachedData) return cachedAchievements.achievements; if ( - cachedAchievements && + cachedAchievements?.achievements && Date.now() < (cachedAchievements.cacheExpiresTimestamp ?? 0) ) { return cachedAchievements.achievements; @@ -35,7 +35,7 @@ export const getGameAchievementData = async ( language, }) .then(async (achievements) => { - await gameAchievementsSublevel.put(levelKeys.game(shop, objectId), { + await gameAchievementsSublevel.put(gameKey, { unlockedAchievements: cachedAchievements?.unlockedAchievements ?? [], achievements, cacheExpiresTimestamp: achievements.length diff --git a/src/main/services/achievements/merge-achievements.ts b/src/main/services/achievements/merge-achievements.ts index 058c2bc6..32fa4206 100644 --- a/src/main/services/achievements/merge-achievements.ts +++ b/src/main/services/achievements/merge-achievements.ts @@ -68,7 +68,7 @@ export const mergeAchievements = async ( ); if (!localGameAchievement) { - await getGameAchievementData(game.objectId, game.shop, true); + await getGameAchievementData(game.objectId, game.shop, false); localGameAchievement = await gameAchievementsSublevel.get(gameKey); } @@ -154,8 +154,7 @@ export const mergeAchievements = async ( const shouldSyncWithRemote = game.remoteId && - (newAchievements.length || - AchievementWatcherManager.hasFinishedMergingWithRemote); + (newAchievements.length || AchievementWatcherManager.hasFinishedPreSearch); if (shouldSyncWithRemote) { await HydraApi.put(