mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-18 08:43:57 +00:00
feat: small refactor to achievements
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ export const findAchievementFileInExecutableDirectory = (
|
||||
"achievements.ini"
|
||||
),
|
||||
},
|
||||
];
|
||||
].filter((file) => fs.existsSync(file.filePath)) as AchievementFile[];
|
||||
};
|
||||
|
||||
const mapFileLocationWithObjectId = (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>(
|
||||
|
||||
Reference in New Issue
Block a user