diff --git a/src/main/services/achievements/achievement-file-observer.ts b/src/main/services/achievements/achievement-file-observer.ts index d8610ec8..d008304e 100644 --- a/src/main/services/achievements/achievement-file-observer.ts +++ b/src/main/services/achievements/achievement-file-observer.ts @@ -55,7 +55,7 @@ const compareFile = async (game: Game, file: AchievementFile) => { }; export const checkAchievementFileChange = async (games: Game[]) => { - const achievementFiles = findAllAchievementFiles(); + const achievementFiles = await findAllAchievementFiles(); for (const game of games) { const gameAchievementFiles = achievementFiles.get(game.objectID) || []; diff --git a/src/main/services/achievements/find-achivement-files.ts b/src/main/services/achievements/find-achivement-files.ts index 73122b9e..d2dfe85e 100644 --- a/src/main/services/achievements/find-achivement-files.ts +++ b/src/main/services/achievements/find-achivement-files.ts @@ -9,54 +9,120 @@ import { Game } from "@main/entity"; const publicDir = path.join("C:", "Users", "Public", "Documents"); const programData = path.join("C:", "ProgramData"); const appData = app.getPath("appData"); +const documents = app.getPath("documents"); const crackers = [ Cracker.codex, Cracker.goldberg, - Cracker.goldberg2, Cracker.rune, Cracker.onlineFix, Cracker.userstats, Cracker.rld, + Cracker.creamAPI, + Cracker.skidrow, + Cracker.smartSteamEmu, + Cracker.empress, ]; -const getPathFromCracker = (cracker: Cracker) => { - let folderPath: string; - let fileLocation: string[]; - - if (cracker === Cracker.onlineFix) { - folderPath = path.join(publicDir, Cracker.onlineFix); - fileLocation = ["Stats", "Achievements.ini"]; - } else if (cracker === Cracker.goldberg) { - folderPath = path.join(appData, "Goldberg SteamEmu Saves"); - fileLocation = ["achievements.json"]; - } else if (cracker === Cracker.goldberg2) { - folderPath = path.join(appData, "GSE Saves"); - fileLocation = ["achievements.json"]; - } else if (cracker === Cracker.rld) { - folderPath = path.join(programData, Cracker.rld); - fileLocation = ["achievements.ini"]; - } else { - folderPath = path.join(publicDir, "Steam", cracker); - fileLocation = ["achievements.ini"]; +const getPathFromCracker = async (cracker: Cracker) => { + if (cracker === Cracker.smartSteamEmu) { + return [ + { + folderPath: path.join(appData, "SmartSteamEmu"), + fileLocation: ["User", "Achievements"], + }, + ]; } - return { folderPath, fileLocation }; + if (cracker === Cracker.onlineFix) { + return [ + { + folderPath: path.join(publicDir, Cracker.onlineFix), + fileLocation: ["Stats", "Achievements.ini"], + }, + ]; + } + + if (cracker === Cracker.goldberg) { + return [ + { + folderPath: path.join(appData, "Goldberg SteamEmu Saves"), + fileLocation: ["achievements.json"], + }, + { + folderPath: path.join(appData, "GSE Saves"), + fileLocation: ["achievements.json"], + }, + ]; + } + + if (cracker === Cracker.rld) { + return [ + { + folderPath: path.join(programData, "RLD!"), + fileLocation: ["achievements.ini"], + }, + ]; + } + + if (cracker === Cracker.creamAPI) { + return [ + { + folderPath: path.join(appData, "CreamAPI"), + fileLocation: ["achievements.ini"], + }, + ]; + } + + if (cracker === Cracker.skidrow) { + return [ + { + folderPath: path.join(documents, "SKIDROW"), + fileLocation: ["SteamEmu", "UserStats", "achiev.ini"], + }, + { + folderPath: path.join(documents, "Player"), + fileLocation: ["SteamEmu", "UserStats", "achiev.ini"], + }, + ]; + } + + if (cracker === Cracker.codex) { + return [ + { + folderPath: path.join(publicDir, "Steam", "CODEX"), + fileLocation: ["achievements.ini"], + }, + { + folderPath: path.join(appData, "Steam", "CODEX"), + fileLocation: ["achievements.ini"], + }, + ]; + } + + return [ + { + folderPath: path.join(publicDir, "Steam", cracker), + fileLocation: ["achievements.ini"], + }, + ]; }; -export const findAchievementFiles = (game: Game) => { +export const findAchievementFiles = async (game: Game) => { const achievementFiles: AchievementFile[] = []; for (const cracker of crackers) { - const { folderPath, fileLocation } = getPathFromCracker(cracker); + for (const { folderPath, fileLocation } of await getPathFromCracker( + cracker + )) { + const filePath = path.join(folderPath, game.objectID, ...fileLocation); - const filePath = path.join(folderPath, game.objectID, ...fileLocation); - - if (fs.existsSync(filePath)) { - achievementFiles.push({ - type: cracker, - filePath: path.join(folderPath, game.objectID, ...fileLocation), - }); + if (fs.existsSync(filePath)) { + achievementFiles.push({ + type: cracker, + filePath, + }); + } } } @@ -83,31 +149,33 @@ export const findAchievementFileInExecutableDirectory = ( }; }; -export const findAllAchievementFiles = () => { +export const findAllAchievementFiles = async () => { const gameAchievementFiles = new Map(); for (const cracker of crackers) { - const { folderPath, fileLocation } = getPathFromCracker(cracker); + for (const { folderPath, fileLocation } of await getPathFromCracker( + cracker + )) { + if (!fs.existsSync(folderPath)) { + continue; + } - if (!fs.existsSync(folderPath)) { - return gameAchievementFiles; - } + const objectIds = fs.readdirSync(folderPath); - const objectIds = fs.readdirSync(folderPath); + for (const objectId of objectIds) { + const filePath = path.join(folderPath, objectId, ...fileLocation); - for (const objectId of objectIds) { - const filePath = path.join(folderPath, objectId, ...fileLocation); + if (!fs.existsSync(filePath)) continue; - if (!fs.existsSync(filePath)) continue; + const achivementFile = { + type: cracker, + filePath, + }; - const achivementFile = { - type: cracker, - filePath, - }; - - gameAchievementFiles.get(objectId) - ? gameAchievementFiles.get(objectId)!.push(achivementFile) - : gameAchievementFiles.set(objectId, [achivementFile]); + gameAchievementFiles.get(objectId) + ? gameAchievementFiles.get(objectId)!.push(achivementFile) + : gameAchievementFiles.set(objectId, [achivementFile]); + } } } diff --git a/src/main/services/achievements/parse-achievement-file.ts b/src/main/services/achievements/parse-achievement-file.ts index c00c5d87..a2fe8f1b 100644 --- a/src/main/services/achievements/parse-achievement-file.ts +++ b/src/main/services/achievements/parse-achievement-file.ts @@ -9,11 +9,28 @@ export const parseAchievementFile = async ( ): Promise => { if (!existsSync(filePath)) return []; + if (type === Cracker.empress) { + return []; + } + + if (type === Cracker.skidrow) { + const parsed = await iniParse(filePath); + return processSkidrow(parsed); + } + + if (type === Cracker.smartSteamEmu) { + return []; + } + + if (type === Cracker.creamAPI) { + return []; + } + if (type === Cracker.onlineFix) { const parsed = await iniParse(filePath); return processOnlineFix(parsed); } - if (type === Cracker.goldberg || type === Cracker.goldberg2) { + if (type === Cracker.goldberg) { const parsed = await jsonParse(filePath); return processGoldberg(parsed); } @@ -88,6 +105,24 @@ const processOnlineFix = (unlockedAchievements: any): UnlockedAchievement[] => { return parsedUnlockedAchievements; }; +const processSkidrow = (unlockedAchievements: any): UnlockedAchievement[] => { + const parsedUnlockedAchievements: UnlockedAchievement[] = []; + const achievements = unlockedAchievements["Achievements"]; + + for (const achievement of Object.keys(achievements)) { + const unlockedAchievement = achievements[achievement].split("@"); + + if (unlockedAchievement[0] === "1") { + parsedUnlockedAchievements.push({ + name: achievement, + unlockTime: unlockedAchievement[unlockedAchievement.length - 1], + }); + } + } + + return parsedUnlockedAchievements; +}; + const processGoldberg = (unlockedAchievements: any): UnlockedAchievement[] => { const newUnlockedAchievements: UnlockedAchievement[] = []; diff --git a/src/main/services/achievements/update-local-unlocked-achivements.ts b/src/main/services/achievements/update-local-unlocked-achivements.ts index 16ed0ae2..6c0fed8f 100644 --- a/src/main/services/achievements/update-local-unlocked-achivements.ts +++ b/src/main/services/achievements/update-local-unlocked-achivements.ts @@ -9,7 +9,7 @@ import type { UnlockedAchievement } from "@types"; import { getGameAchievementData } from "./get-game-achievement-data"; export const updateAllLocalUnlockedAchievements = async () => { - const gameAchievementFilesMap = findAllAchievementFiles(); + const gameAchievementFilesMap = await findAllAchievementFiles(); for (const objectId of gameAchievementFilesMap.keys()) { const gameAchievementFiles = gameAchievementFilesMap.get(objectId)!; @@ -69,7 +69,7 @@ export const updateLocalUnlockedAchivements = async (objectId: string) => { if (!game) return; - const gameAchievementFiles = findAchievementFiles(game); + const gameAchievementFiles = await findAchievementFiles(game); console.log("Achievements files for", game.title, gameAchievementFiles); diff --git a/src/shared/constants.ts b/src/shared/constants.ts index 62c51418..e22d7712 100644 --- a/src/shared/constants.ts +++ b/src/shared/constants.ts @@ -29,7 +29,10 @@ export enum Cracker { rune = "RUNE", onlineFix = "OnlineFix", goldberg = "Goldberg", - goldberg2 = "Goldberg2", userstats = "user_stats", rld = "RLD!", + empress = "EMPRESS", + skidrow = "SKIDROW", + creamAPI = "CreamAPI", + smartSteamEmu = "SmartSteamEmu", }