feat: small refactor to achievements

This commit is contained in:
Zamitto
2025-06-03 09:42:44 -03:00
parent e9032ae6e4
commit 3a6693c8b1
7 changed files with 32 additions and 27 deletions

View File

@@ -8,7 +8,9 @@ const saveGameShopAssets = async (
shop: GameShop,
assets: ShopAssets
): Promise<void> => {
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);

View File

@@ -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) => {

View File

@@ -9,8 +9,6 @@ export const getUnlockedAchievements = async (
shop: GameShop,
useCachedData: boolean
): Promise<UserAchievement[]> => {
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<UserAchievement[]> => {
AchievementWatcherManager.firstSyncWithRemoteIfNeeded(shop, objectId);
return getUnlockedAchievements(objectId, shop, false);
};

View File

@@ -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<string, number> = new Map();
const fltFiles: Map<string, Set<string>> = 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<string, boolean> = 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;
}
}

View File

@@ -303,7 +303,7 @@ export const findAchievementFileInExecutableDirectory = (
"achievements.ini"
),
},
];
].filter((file) => fs.existsSync(file.filePath)) as AchievementFile[];
};
const mapFileLocationWithObjectId = (

View File

@@ -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

View File

@@ -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<UpdatedUnlockedAchievements | undefined>(