diff --git a/package.json b/package.json index ad178d55e..6bf12967e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hydralauncher", - "version": "3.0.1", + "version": "3.0.2", "description": "Hydra", "main": "./out/main/index.js", "author": "Los Broxas", diff --git a/src/main/services/achievements/achievement-watcher-manager.ts b/src/main/services/achievements/achievement-watcher-manager.ts index 2345e3bed..40f3024cf 100644 --- a/src/main/services/achievements/achievement-watcher-manager.ts +++ b/src/main/services/achievements/achievement-watcher-manager.ts @@ -242,10 +242,18 @@ export class AchievementWatcherManager { ? await this.preSearchAchievementsWindows() : await this.preSearchAchievementsWithWine(); + const totalNewGamesWithAchievements = newAchievementsCount.filter( + (achievements) => achievements + ).length; + const totalNewAchievements = newAchievementsCount.reduce( + (acc, val) => acc + val, + 0 + ); + WindowManager.notificationWindow?.webContents.send( "on-combined-achievements-unlocked", - newAchievementsCount.filter((achievements) => achievements).length, - newAchievementsCount.reduce((acc, val) => acc + val, 0) + totalNewGamesWithAchievements, + totalNewAchievements ); this.hasFinishedMergingWithRemote = true; diff --git a/src/main/services/achievements/find-achivement-files.ts b/src/main/services/achievements/find-achivement-files.ts index 85c5b7673..4fc6a4cd6 100644 --- a/src/main/services/achievements/find-achivement-files.ts +++ b/src/main/services/achievements/find-achivement-files.ts @@ -79,11 +79,11 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(publicDocuments, "Steam", "CODEX"), - fileLocation: ["achievements.ini"], + fileLocation: ["", "achievements.ini"], }, { folderPath: path.join(appData, "Steam", "CODEX"), - fileLocation: ["achievements.ini"], + fileLocation: ["", "achievements.ini"], }, ]; } @@ -92,7 +92,7 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(publicDocuments, "Steam", "RUNE"), - fileLocation: ["achievements.ini"], + fileLocation: ["", "achievements.ini"], }, ]; } @@ -101,11 +101,11 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(publicDocuments, "OnlineFix"), - fileLocation: ["Stats", "Achievements.ini"], + fileLocation: ["", "Stats", "Achievements.ini"], }, { folderPath: path.join(publicDocuments, "OnlineFix"), - fileLocation: ["Achievements.ini"], + fileLocation: ["", "Achievements.ini"], }, ]; } @@ -114,11 +114,11 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(appData, "Goldberg SteamEmu Saves"), - fileLocation: ["achievements.json"], + fileLocation: ["", "achievements.json"], }, { folderPath: path.join(appData, "GSE Saves"), - fileLocation: ["achievements.json"], + fileLocation: ["", "achievements.json"], }, ]; } @@ -131,19 +131,19 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(programData, "RLD!"), - fileLocation: ["achievements.ini"], + fileLocation: ["", "achievements.ini"], }, { folderPath: path.join(programData, "Steam", "Player"), - fileLocation: ["stats", "achievements.ini"], + fileLocation: ["", "stats", "achievements.ini"], }, { folderPath: path.join(programData, "Steam", "RLD!"), - fileLocation: ["stats", "achievements.ini"], + fileLocation: ["", "stats", "achievements.ini"], }, { folderPath: path.join(programData, "Steam", "dodi"), - fileLocation: ["stats", "achievements.ini"], + fileLocation: ["", "stats", "achievements.ini"], }, ]; } @@ -152,11 +152,16 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(appData, "EMPRESS", "remote"), - fileLocation: ["achievements.json"], + fileLocation: ["", "achievements.json"], }, { - folderPath: path.join(publicDocuments, "EMPRESS", "remote"), - fileLocation: ["achievements.json"], + folderPath: path.join(publicDocuments, "EMPRESS"), + fileLocation: [ + "", + "remote", + "", + "achievements.json", + ], }, ]; } @@ -165,15 +170,15 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(documents, "SKIDROW"), - fileLocation: ["SteamEmu", "UserStats", "achiev.ini"], + fileLocation: ["", "SteamEmu", "UserStats", "achiev.ini"], }, { folderPath: path.join(documents, "Player"), - fileLocation: ["SteamEmu", "UserStats", "achiev.ini"], + fileLocation: ["", "SteamEmu", "UserStats", "achiev.ini"], }, { folderPath: path.join(localAppData, "SKIDROW"), - fileLocation: ["SteamEmu", "UserStats", "achiev.ini"], + fileLocation: ["", "SteamEmu", "UserStats", "achiev.ini"], }, ]; } @@ -182,7 +187,7 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(appData, "CreamAPI"), - fileLocation: ["stats", "CreamAPI.Achievements.cfg"], + fileLocation: ["", "stats", "CreamAPI.Achievements.cfg"], }, ]; } @@ -191,7 +196,7 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(appData, "SmartSteamEmu"), - fileLocation: ["User", "Achievements.ini"], + fileLocation: ["", "User", "Achievements.ini"], }, ]; } @@ -213,11 +218,11 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(appData, "RLE"), - fileLocation: ["achievements.ini"], + fileLocation: ["", "achievements.ini"], }, { folderPath: path.join(appData, "RLE"), - fileLocation: ["Achievements.ini"], + fileLocation: ["", "Achievements.ini"], }, ]; } @@ -226,7 +231,7 @@ const getPathFromCracker = (cracker: Cracker) => { return [ { folderPath: path.join(appData, ".1911"), - fileLocation: ["achievement"], + fileLocation: ["", "achievement"], }, ]; } @@ -253,8 +258,7 @@ export const findAchievementFiles = (game: Game) => { const filePath = path.join( game.winePrefixPath ?? "", folderPath, - objectId, - ...fileLocation + ...mapFileLocationWithObjectId(fileLocation, objectId) ); if (fs.existsSync(filePath)) { @@ -303,6 +307,15 @@ export const findAchievementFileInExecutableDirectory = ( ]; }; +const mapFileLocationWithObjectId = ( + fileLocation: string[], + objectId: string +) => { + return fileLocation.map((location) => + location.replace("", objectId) + ); +}; + export const findAllAchievementFiles = () => { const gameAchievementFiles = new Map(); @@ -315,7 +328,10 @@ export const findAllAchievementFiles = () => { const objectIds = fs.readdirSync(folderPath); for (const objectId of objectIds) { - const filePath = path.join(folderPath, objectId, ...fileLocation); + const filePath = path.join( + folderPath, + ...mapFileLocationWithObjectId(fileLocation, objectId) + ); if (!fs.existsSync(filePath)) continue; diff --git a/src/main/services/achievements/parse-achievement-file.ts b/src/main/services/achievements/parse-achievement-file.ts index 38b388ca1..3aecadd67 100644 --- a/src/main/services/achievements/parse-achievement-file.ts +++ b/src/main/services/achievements/parse-achievement-file.ts @@ -65,6 +65,11 @@ export const parseAchievementFile = ( return processCreamAPI(parsed); } + if (type === Cracker.empress) { + const parsed = jsonParse(filePath); + return processGoldberg(parsed); + } + if (type === Cracker.razor1911) { return processRazor1911(filePath); } @@ -118,7 +123,7 @@ const jsonParse = (filePath: string) => { const processRazor1911 = (filePath: string): UnlockedAchievement[] => { try { const fileContent = readFileSync(filePath, "utf-8"); - achievementsLogger.log("processing file", filePath, fileContent); + const lines = fileContent.charCodeAt(0) === 0xfeff ? fileContent.slice(1).split(/[\r\n]+/) @@ -136,7 +141,7 @@ const processRazor1911 = (filePath: string): UnlockedAchievement[] => { }); } } - achievementsLogger.log("processing file", achievements); + return achievements; } catch (err) { achievementsLogger.error(`Error processing ${filePath}`, err); diff --git a/src/renderer/src/hooks/use-date.ts b/src/renderer/src/hooks/use-date.ts index 9486400ca..9a5172d35 100644 --- a/src/renderer/src/hooks/use-date.ts +++ b/src/renderer/src/hooks/use-date.ts @@ -77,6 +77,8 @@ export function useDate() { }, formatDate: (date: number | Date | string): string => { + if (isNaN(new Date(date).getDate())) return "N/A"; + const locale = getDateLocale(); return format(date, locale == enUS ? "MM/dd/yyyy" : "dd/MM/yyyy"); }, diff --git a/src/renderer/src/pages/game-details/hero/hero-panel.css.ts b/src/renderer/src/pages/game-details/hero/hero-panel.css.ts index c379c1c33..3fdbc73b8 100644 --- a/src/renderer/src/pages/game-details/hero/hero-panel.css.ts +++ b/src/renderer/src/pages/game-details/hero/hero-panel.css.ts @@ -18,7 +18,7 @@ export const panel = recipe({ position: "sticky", overflow: "hidden", top: "0", - zIndex: "1", + zIndex: "2", }, variants: { stuck: { diff --git a/src/renderer/src/pages/game-details/hero/hero-panel.tsx b/src/renderer/src/pages/game-details/hero/hero-panel.tsx index 7f010705d..e8675023d 100644 --- a/src/renderer/src/pages/game-details/hero/hero-panel.tsx +++ b/src/renderer/src/pages/game-details/hero/hero-panel.tsx @@ -1,8 +1,7 @@ -import { format } from "date-fns"; import { useContext } from "react"; import { useTranslation } from "react-i18next"; -import { useDownload } from "@renderer/hooks"; +import { useDate, useDownload } from "@renderer/hooks"; import { HeroPanelActions } from "./hero-panel-actions"; import * as styles from "./hero-panel.css"; @@ -17,6 +16,8 @@ export interface HeroPanelProps { export function HeroPanel({ isHeaderStuck }: HeroPanelProps) { const { t } = useTranslation("game_details"); + const { formatDate } = useDate(); + const { game, repacks, gameColor } = useContext(gameDetailsContext); const { lastPacket } = useDownload(); @@ -29,7 +30,9 @@ export function HeroPanel({ isHeaderStuck }: HeroPanelProps) { const [latestRepack] = repacks; if (latestRepack) { - const lastUpdate = format(latestRepack.uploadDate!, "dd/MM/yyyy"); + const lastUpdate = latestRepack.uploadDate + ? formatDate(latestRepack.uploadDate!) + : ""; const repacksCount = repacks.length; return ( diff --git a/src/renderer/src/pages/game-details/sidebar/sidebar.tsx b/src/renderer/src/pages/game-details/sidebar/sidebar.tsx index 21a940c67..c4ad640b7 100644 --- a/src/renderer/src/pages/game-details/sidebar/sidebar.tsx +++ b/src/renderer/src/pages/game-details/sidebar/sidebar.tsx @@ -126,7 +126,7 @@ export function Sidebar() {