feat: saving achievements on open launcher

This commit is contained in:
Zamitto 2024-09-24 13:04:46 -03:00
parent 8fb62af0cf
commit 500cd2a531
7 changed files with 63 additions and 58 deletions

View file

@ -16,6 +16,9 @@ export class GameAchievement {
@JoinColumn() @JoinColumn()
game: Game; game: Game;
@Column("text", { nullable: true })
unlockedAchievements: string;
@Column("text", { nullable: true }) @Column("text", { nullable: true })
achievements: string; achievements: string;
} }

View file

@ -22,7 +22,9 @@ export const getGameAchievementsToWatch = async (
const steamId = Number(game.objectID); const steamId = Number(game.objectID);
const achievements = await steamGetAchivement(game); const achievements = await steamGetAchivement(game);
console.log(achievements); console.log(achievements);
if (!achievements || !achievements.length) return; if (!achievements || !achievements.length) return;
const achievementFiles = steamFindGameAchievementFiles(game.objectID)[ const achievementFiles = steamFindGameAchievementFiles(game.objectID)[
@ -50,7 +52,7 @@ export const getGameAchievementsToWatch = async (
game: { id: gameId }, game: { id: gameId },
}, },
{ {
achievements: JSON.stringify(checkedAchievements.all), unlockedAchievements: JSON.stringify(checkedAchievements.all),
} }
); );
} }

View file

@ -1,11 +1,7 @@
import { gameAchievementRepository, gameRepository } from "@main/repository"; import { gameAchievementRepository, gameRepository } from "@main/repository";
import { steamFindGameAchievementFiles } from "../steam/steam-find-game-achivement-files"; import { steamFindGameAchievementFiles } from "../steam/steam-find-game-achivement-files";
import { steamGlobalAchievementPercentages } from "../steam/steam-global-achievement-percentages";
import { steamAchievementInfo } from "../steam/steam-achievement-info";
import { steamAchievementMerge } from "../steam/steam-achievement-merge";
import { parseAchievementFile } from "../util/parseAchievementFile"; import { parseAchievementFile } from "../util/parseAchievementFile";
import { checkUnlockedAchievements } from "../util/check-unlocked-achievements"; import { HydraApi } from "@main/services";
import { CheckedAchievements } from "../types";
export const saveAllLocalSteamAchivements = async () => { export const saveAllLocalSteamAchivements = async () => {
const gameAchievementFiles = steamFindGameAchievementFiles(); const gameAchievementFiles = steamFindGameAchievementFiles();
@ -19,56 +15,56 @@ export const saveAllLocalSteamAchivements = async () => {
if (!game) continue; if (!game) continue;
const hasOnDb = await gameAchievementRepository.existsBy({ const savedGameAchievements = await gameAchievementRepository.findOneBy({
game: game, game: game,
}); });
if (hasOnDb) continue; if (!savedGameAchievements || !savedGameAchievements.achievements) {
HydraApi.get(
const achievementPercentage = "/games/achievements",
await steamGlobalAchievementPercentages(objectId); {
shop: "steam",
if (!achievementPercentage) { objectId,
await gameAchievementRepository.save({ },
game, { needsAuth: false }
achievements: "[]", )
}); .then((achievements) => {
continue; return gameAchievementRepository.upsert(
{
game: { id: game.id },
achievements: JSON.stringify(achievements),
},
["game"]
);
})
.catch(console.log);
} }
const achievementInfo = await steamAchievementInfo(objectId); const unlockedAchievements: { name: string; unlockTime: number }[] = [];
if (!achievementInfo) continue;
const achievements = steamAchievementMerge(
achievementPercentage,
achievementInfo
);
if (!achievements) continue;
const checkedAchievements: CheckedAchievements = {
all: achievements,
new: [],
};
for (const achievementFile of gameAchievementFiles[key]) { for (const achievementFile of gameAchievementFiles[key]) {
const localAchievementFile = await parseAchievementFile( const localAchievementFile = await parseAchievementFile(
achievementFile.filePath achievementFile.filePath
); );
checkedAchievements.new.push( console.log(achievementFile.filePath);
...checkUnlockedAchievements( console.log(localAchievementFile);
achievementFile.type,
localAchievementFile,
achievements
).new
);
}
await gameAchievementRepository.save({ for (const a of Object.keys(localAchievementFile)) {
game, // TODO: use checkUnlockedAchievements after refactoring it to be generic
achievements: JSON.stringify(checkedAchievements.all), unlockedAchievements.push({
name: a,
unlockTime: localAchievementFile[a].UnlockTime,
}); });
} }
}
await gameAchievementRepository.upsert(
{
game: { id: game.id },
unlockedAchievements: JSON.stringify(unlockedAchievements),
},
["game"]
);
}
}; };

View file

@ -1,21 +1,21 @@
import path from "node:path"; import path from "node:path";
import { existsSync, readdirSync } from "node:fs"; import fs from "node:fs";
import { Cracker, GameAchievementFiles } from "../types"; import { Cracker, GameAchievementFiles } from "../types";
import { app } from "electron"; import { app } from "electron";
const addGame = ( const addGame = (
achievementFiles: GameAchievementFiles, achievementFiles: GameAchievementFiles,
gamePath: string, achievementPath: string,
objectId: string, objectId: string,
fileLocation: string[], fileLocation: string[],
type: Cracker type: Cracker
) => { ) => {
const filePath = path.join(gamePath, objectId, ...fileLocation); const filePath = path.join(achievementPath, objectId, ...fileLocation);
if (existsSync(filePath)) { if (fs.existsSync(filePath)) {
const achivementFile = { const achivementFile = {
type, type,
filePath: filePath, filePath,
}; };
achievementFiles[objectId] achievementFiles[objectId]
@ -33,7 +33,7 @@ export const steamFindGameAchievementFiles = (
const gameAchievementFiles: GameAchievementFiles = {}; const gameAchievementFiles: GameAchievementFiles = {};
const crackers: Cracker[] = [ const crackers = [
Cracker.codex, Cracker.codex,
Cracker.goldberg, Cracker.goldberg,
Cracker.rune, Cracker.rune,
@ -55,9 +55,9 @@ export const steamFindGameAchievementFiles = (
fileLocation = ["achievements.ini"]; fileLocation = ["achievements.ini"];
} }
if (!existsSync(achievementPath)) continue; if (!fs.existsSync(achievementPath)) continue;
const objectIds = readdirSync(achievementPath); const objectIds = fs.readdirSync(achievementPath);
if (objectId) { if (objectId) {
if (objectIds.includes(objectId)) { if (objectIds.includes(objectId)) {

View file

@ -25,7 +25,7 @@ const iniParse = async (filePath: string) => {
}); });
let objectName = ""; let objectName = "";
const object: any = {}; const object: Record<string, Record<string, string | number>> = {};
for await (const line of lines) { for await (const line of lines) {
if (line.startsWith("###") || !line.length) continue; if (line.startsWith("###") || !line.length) continue;

View file

@ -16,6 +16,7 @@ import { publishNewRepacksNotifications } from "./services/notifications";
import { MoreThan } from "typeorm"; import { MoreThan } from "typeorm";
import { HydraApi } from "./services/hydra-api"; import { HydraApi } from "./services/hydra-api";
import { uploadGamesBatch } from "./services/library-sync"; import { uploadGamesBatch } from "./services/library-sync";
import { saveAllLocalSteamAchivements } from "./events/achievements/services/save-all-local-steam-achivements";
const loadState = async (userPreferences: UserPreferences | null) => { const loadState = async (userPreferences: UserPreferences | null) => {
RepacksManager.updateRepacks(); RepacksManager.updateRepacks();
@ -58,6 +59,8 @@ const loadState = async (userPreferences: UserPreferences | null) => {
if (newRepacksCount > 0) publishNewRepacksNotifications(newRepacksCount); if (newRepacksCount > 0) publishNewRepacksNotifications(newRepacksCount);
}); });
saveAllLocalSteamAchivements();
}; };
userPreferencesRepository userPreferencesRepository

View file

@ -3,16 +3,17 @@ import type { Knex } from "knex";
export const CreateGameAchievement: HydraMigration = { export const CreateGameAchievement: HydraMigration = {
name: "CreateGameAchievement", name: "CreateGameAchievement",
up: async (knex: Knex) => { up: (knex: Knex) => {
await knex.schema.createTable("game_achievement", (table) => { return knex.schema.createTable("game_achievement", (table) => {
table.increments("id").primary(); table.increments("id").primary();
table.integer("gameId").notNullable(); table.integer("gameId").notNullable().unique();
table.text("achievements"); table.text("achievements");
table.text("unlockedAchievements");
table.foreign("gameId").references("game.id").onDelete("CASCADE"); table.foreign("gameId").references("game.id").onDelete("CASCADE");
}); });
}, },
down: async (knex: Knex) => { down: (knex: Knex) => {
await knex.schema.dropTable("game_achievement"); return knex.schema.dropTable("game_achievement");
}, },
}; };