mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-09 11:42:21 +03:00
feat: remove awaits
This commit is contained in:
parent
af83152997
commit
7f09a7796f
@ -1,88 +1,45 @@
|
|||||||
import type { GameAchievement, GameShop } from "@types";
|
import type { GameAchievement, GameShop } from "@types";
|
||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
import { HydraApi } from "@main/services";
|
import { gameAchievementRepository } from "@main/repository";
|
||||||
import {
|
import { getGameAchievementData } from "@main/services/achievements/get-game-achievement-data";
|
||||||
gameAchievementRepository,
|
|
||||||
gameRepository,
|
|
||||||
userPreferencesRepository,
|
|
||||||
} from "@main/repository";
|
|
||||||
import { UserNotLoggedInError } from "@shared";
|
|
||||||
import { Game } from "@main/entity";
|
|
||||||
|
|
||||||
const getAchievementsDataFromApi = async (
|
|
||||||
objectId: string,
|
|
||||||
shop: string,
|
|
||||||
game: Game | null
|
|
||||||
) => {
|
|
||||||
const userPreferences = await userPreferencesRepository.findOne({
|
|
||||||
where: { id: 1 },
|
|
||||||
});
|
|
||||||
|
|
||||||
return HydraApi.get("/games/achievements", {
|
|
||||||
objectId,
|
|
||||||
shop,
|
|
||||||
language: userPreferences?.language || "en",
|
|
||||||
})
|
|
||||||
.then((achievements) => {
|
|
||||||
if (game) {
|
|
||||||
gameAchievementRepository.upsert(
|
|
||||||
{
|
|
||||||
objectId,
|
|
||||||
shop,
|
|
||||||
achievements: JSON.stringify(achievements),
|
|
||||||
},
|
|
||||||
["objectId", "shop"]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return achievements;
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
if (err instanceof UserNotLoggedInError) throw err;
|
|
||||||
return [];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getGameAchievements = async (
|
const getGameAchievements = async (
|
||||||
_event: Electron.IpcMainInvokeEvent,
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
objectId: string,
|
objectId: string,
|
||||||
shop: GameShop
|
shop: GameShop
|
||||||
): Promise<GameAchievement[]> => {
|
): Promise<GameAchievement[]> => {
|
||||||
const [game, cachedAchievements] = await Promise.all([
|
const cachedAchievements = await gameAchievementRepository.findOne({
|
||||||
gameRepository.findOne({
|
where: { objectId, shop },
|
||||||
where: { objectID: objectId, shop },
|
});
|
||||||
}),
|
|
||||||
gameAchievementRepository.findOne({ where: { objectId, shop } }),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const gameAchievements = cachedAchievements?.achievements
|
const achievementsData = cachedAchievements?.achievements
|
||||||
? JSON.parse(cachedAchievements.achievements)
|
? JSON.parse(cachedAchievements.achievements)
|
||||||
: await getAchievementsDataFromApi(objectId, shop, game);
|
: await getGameAchievementData(objectId, shop);
|
||||||
|
|
||||||
const unlockedAchievements = JSON.parse(
|
const unlockedAchievements = JSON.parse(
|
||||||
cachedAchievements?.unlockedAchievements || "[]"
|
cachedAchievements?.unlockedAchievements || "[]"
|
||||||
) as { name: string; unlockTime: number }[];
|
) as { name: string; unlockTime: number }[];
|
||||||
|
|
||||||
return gameAchievements
|
return achievementsData
|
||||||
.map((achievement) => {
|
.map((achievementData) => {
|
||||||
const unlockedAchiement = unlockedAchievements.find(
|
const unlockedAchiement = unlockedAchievements.find(
|
||||||
(localAchievement) => {
|
(localAchievement) => {
|
||||||
return (
|
return (
|
||||||
localAchievement.name.toUpperCase() ==
|
localAchievement.name.toUpperCase() ==
|
||||||
achievement.name.toUpperCase()
|
achievementData.name.toUpperCase()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (unlockedAchiement) {
|
if (unlockedAchiement) {
|
||||||
return {
|
return {
|
||||||
...achievement,
|
...achievementData,
|
||||||
unlocked: true,
|
unlocked: true,
|
||||||
unlockTime: unlockedAchiement.unlockTime,
|
unlockTime: unlockedAchiement.unlockTime,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return { ...achievement, unlocked: false, unlockTime: null };
|
return { ...achievementData, unlocked: false, unlockTime: null };
|
||||||
})
|
})
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (a.unlocked && !b.unlocked) return -1;
|
if (a.unlocked && !b.unlocked) return -1;
|
||||||
|
@ -44,10 +44,10 @@ const addGameToLibrary = async (
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLocalUnlockedAchivements(objectID);
|
|
||||||
|
|
||||||
const game = await gameRepository.findOne({ where: { objectID } });
|
const game = await gameRepository.findOne({ where: { objectID } });
|
||||||
|
|
||||||
|
updateLocalUnlockedAchivements(game!);
|
||||||
|
|
||||||
createGame(game!).catch(() => {});
|
createGame(game!).catch(() => {});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -53,10 +53,7 @@ const processAchievementFileDiff = async (
|
|||||||
game: Game,
|
game: Game,
|
||||||
file: AchievementFile
|
file: AchievementFile
|
||||||
) => {
|
) => {
|
||||||
const unlockedAchievements = await parseAchievementFile(
|
const unlockedAchievements = parseAchievementFile(file.filePath, file.type);
|
||||||
file.filePath,
|
|
||||||
file.type
|
|
||||||
);
|
|
||||||
|
|
||||||
logger.log("Achievements from file", file.filePath, unlockedAchievements);
|
logger.log("Achievements from file", file.filePath, unlockedAchievements);
|
||||||
|
|
||||||
|
@ -168,6 +168,7 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getAlternativeObjectIds = (objectId: string) => {
|
export const getAlternativeObjectIds = (objectId: string) => {
|
||||||
|
// Dishonored
|
||||||
if (objectId === "205100") {
|
if (objectId === "205100") {
|
||||||
return ["205100", "217980", "31292"];
|
return ["205100", "217980", "31292"];
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import { userPreferencesRepository } from "@main/repository";
|
import {
|
||||||
|
gameAchievementRepository,
|
||||||
|
userPreferencesRepository,
|
||||||
|
} from "@main/repository";
|
||||||
import { HydraApi } from "../hydra-api";
|
import { HydraApi } from "../hydra-api";
|
||||||
|
|
||||||
export const getGameAchievementData = async (
|
export const getGameAchievementData = async (
|
||||||
@ -13,5 +16,18 @@ export const getGameAchievementData = async (
|
|||||||
shop,
|
shop,
|
||||||
objectId,
|
objectId,
|
||||||
language: userPreferences?.language || "en",
|
language: userPreferences?.language || "en",
|
||||||
});
|
})
|
||||||
|
.then(async (achievements) => {
|
||||||
|
await gameAchievementRepository.upsert(
|
||||||
|
{
|
||||||
|
objectId,
|
||||||
|
shop,
|
||||||
|
achievements: JSON.stringify(achievements),
|
||||||
|
},
|
||||||
|
["objectId", "shop"]
|
||||||
|
);
|
||||||
|
|
||||||
|
return achievements;
|
||||||
|
})
|
||||||
|
.catch(() => []);
|
||||||
};
|
};
|
||||||
|
@ -1,57 +1,51 @@
|
|||||||
import { Cracker } from "@shared";
|
import { Cracker } from "@shared";
|
||||||
import { UnlockedAchievement } from "@types";
|
import { UnlockedAchievement } from "@types";
|
||||||
import {
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
||||||
existsSync,
|
|
||||||
createReadStream,
|
|
||||||
readFileSync,
|
|
||||||
readdirSync,
|
|
||||||
} from "node:fs";
|
|
||||||
import readline from "node:readline";
|
|
||||||
import { achievementsLogger } from "../logger";
|
import { achievementsLogger } from "../logger";
|
||||||
|
|
||||||
export const parseAchievementFile = async (
|
export const parseAchievementFile = (
|
||||||
filePath: string,
|
filePath: string,
|
||||||
type: Cracker
|
type: Cracker
|
||||||
): Promise<UnlockedAchievement[]> => {
|
): UnlockedAchievement[] => {
|
||||||
if (!existsSync(filePath)) return [];
|
if (!existsSync(filePath)) return [];
|
||||||
|
|
||||||
if (type == Cracker.codex) {
|
if (type == Cracker.codex) {
|
||||||
const parsed = await iniParse(filePath);
|
const parsed = iniParse(filePath);
|
||||||
return processDefault(parsed);
|
return processDefault(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == Cracker.rune) {
|
if (type == Cracker.rune) {
|
||||||
const parsed = await iniParse(filePath);
|
const parsed = iniParse(filePath);
|
||||||
return processDefault(parsed);
|
return processDefault(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === Cracker.onlineFix) {
|
if (type === Cracker.onlineFix) {
|
||||||
const parsed = await iniParse(filePath);
|
const parsed = iniParse(filePath);
|
||||||
return processOnlineFix(parsed);
|
return processOnlineFix(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === Cracker.goldberg) {
|
if (type === Cracker.goldberg) {
|
||||||
const parsed = await jsonParse(filePath);
|
const parsed = jsonParse(filePath);
|
||||||
return processGoldberg(parsed);
|
return processGoldberg(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == Cracker.userstats) {
|
if (type == Cracker.userstats) {
|
||||||
const parsed = await iniParse(filePath);
|
const parsed = iniParse(filePath);
|
||||||
return processUserStats(parsed);
|
return processUserStats(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == Cracker.rld) {
|
if (type == Cracker.rld) {
|
||||||
const parsed = await iniParse(filePath);
|
const parsed = iniParse(filePath);
|
||||||
return processRld(parsed);
|
return processRld(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === Cracker.skidrow) {
|
if (type === Cracker.skidrow) {
|
||||||
const parsed = await iniParse(filePath);
|
const parsed = iniParse(filePath);
|
||||||
return processSkidrow(parsed);
|
return processSkidrow(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === Cracker._3dm) {
|
if (type === Cracker._3dm) {
|
||||||
const parsed = await iniParse(filePath);
|
const parsed = iniParse(filePath);
|
||||||
return process3DM(parsed);
|
return process3DM(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,27 +61,24 @@ export const parseAchievementFile = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type === Cracker.creamAPI) {
|
if (type === Cracker.creamAPI) {
|
||||||
const parsed = await iniParse(filePath);
|
const parsed = iniParse(filePath);
|
||||||
return processCreamAPI(parsed);
|
return processCreamAPI(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
achievementsLogger.log(`${type} achievements found on ${filePath}`);
|
achievementsLogger.log(
|
||||||
|
`Unprocessed ${type} achievements found on ${filePath}`
|
||||||
|
);
|
||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
|
|
||||||
const iniParse = async (filePath: string) => {
|
const iniParse = (filePath: string) => {
|
||||||
try {
|
try {
|
||||||
const file = createReadStream(filePath);
|
const lines = readFileSync(filePath, "utf-8").split(/[\r\n]+/);
|
||||||
|
|
||||||
const lines = readline.createInterface({
|
|
||||||
input: file,
|
|
||||||
crlfDelay: Infinity,
|
|
||||||
});
|
|
||||||
|
|
||||||
let objectName = "";
|
let objectName = "";
|
||||||
const object: Record<string, Record<string, string | number>> = {};
|
const object: Record<string, Record<string, string | number>> = {};
|
||||||
|
|
||||||
for await (const line of lines) {
|
for (const line of lines) {
|
||||||
if (line.startsWith("###") || !line.length) continue;
|
if (line.startsWith("###") || !line.length) continue;
|
||||||
|
|
||||||
if (line.startsWith("[") && line.endsWith("]")) {
|
if (line.startsWith("[") && line.endsWith("]")) {
|
||||||
@ -100,7 +91,8 @@ const iniParse = async (filePath: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
} catch {
|
} catch (err) {
|
||||||
|
achievementsLogger.error(`Error parsing ${filePath}`, err);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -108,7 +100,8 @@ const iniParse = async (filePath: string) => {
|
|||||||
const jsonParse = (filePath: string) => {
|
const jsonParse = (filePath: string) => {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(readFileSync(filePath, "utf-8"));
|
return JSON.parse(readFileSync(filePath, "utf-8"));
|
||||||
} catch {
|
} catch (err) {
|
||||||
|
achievementsLogger.error(`Error parsing ${filePath}`, err);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -10,6 +10,7 @@ import { mergeAchievements } from "./merge-achievements";
|
|||||||
import type { UnlockedAchievement } from "@types";
|
import type { UnlockedAchievement } from "@types";
|
||||||
import { getGameAchievementData } from "./get-game-achievement-data";
|
import { getGameAchievementData } from "./get-game-achievement-data";
|
||||||
import { achievementsLogger } from "../logger";
|
import { achievementsLogger } from "../logger";
|
||||||
|
import { Game } from "@main/entity";
|
||||||
|
|
||||||
export const updateAllLocalUnlockedAchievements = async () => {
|
export const updateAllLocalUnlockedAchievements = async () => {
|
||||||
const gameAchievementFilesMap = findAllAchievementFiles();
|
const gameAchievementFilesMap = findAllAchievementFiles();
|
||||||
@ -28,29 +29,20 @@ export const updateAllLocalUnlockedAchievements = async () => {
|
|||||||
|
|
||||||
gameAchievementFiles.push(...achievementFileInsideDirectory);
|
gameAchievementFiles.push(...achievementFileInsideDirectory);
|
||||||
|
|
||||||
const localAchievements = await gameAchievementRepository.findOne({
|
gameAchievementRepository
|
||||||
where: { objectId: game.objectID, shop: "steam" },
|
.findOne({
|
||||||
});
|
where: { objectId: game.objectID, shop: "steam" },
|
||||||
|
})
|
||||||
if (!localAchievements || !localAchievements.achievements) {
|
.then((localAchievements) => {
|
||||||
await getGameAchievementData(game.objectID, "steam")
|
if (!localAchievements || !localAchievements.achievements) {
|
||||||
.then((achievements) => {
|
getGameAchievementData(game.objectID, "steam");
|
||||||
return gameAchievementRepository.upsert(
|
}
|
||||||
{
|
});
|
||||||
objectId: game.objectID,
|
|
||||||
shop: "steam",
|
|
||||||
achievements: JSON.stringify(achievements),
|
|
||||||
},
|
|
||||||
["objectId", "shop"]
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
}
|
|
||||||
|
|
||||||
const unlockedAchievements: UnlockedAchievement[] = [];
|
const unlockedAchievements: UnlockedAchievement[] = [];
|
||||||
|
|
||||||
for (const achievementFile of gameAchievementFiles) {
|
for (const achievementFile of gameAchievementFiles) {
|
||||||
const parsedAchievements = await parseAchievementFile(
|
const parsedAchievements = parseAchievementFile(
|
||||||
achievementFile.filePath,
|
achievementFile.filePath,
|
||||||
achievementFile.type
|
achievementFile.type
|
||||||
);
|
);
|
||||||
@ -72,19 +64,8 @@ export const updateAllLocalUnlockedAchievements = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateLocalUnlockedAchivements = async (objectId: string) => {
|
export const updateLocalUnlockedAchivements = async (game: Game) => {
|
||||||
const [game, localAchievements] = await Promise.all([
|
const gameAchievementFiles = findAchievementFiles(game);
|
||||||
gameRepository.findOne({
|
|
||||||
where: { objectID: objectId, shop: "steam", isDeleted: false },
|
|
||||||
}),
|
|
||||||
gameAchievementRepository.findOne({
|
|
||||||
where: { objectId, shop: "steam" },
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!game) return;
|
|
||||||
|
|
||||||
const gameAchievementFiles = await findAchievementFiles(game);
|
|
||||||
|
|
||||||
const achievementFileInsideDirectory =
|
const achievementFileInsideDirectory =
|
||||||
findAchievementFileInExecutableDirectory(game);
|
findAchievementFileInExecutableDirectory(game);
|
||||||
@ -93,25 +74,10 @@ export const updateLocalUnlockedAchivements = async (objectId: string) => {
|
|||||||
|
|
||||||
console.log("Achievements files for", game.title, gameAchievementFiles);
|
console.log("Achievements files for", game.title, gameAchievementFiles);
|
||||||
|
|
||||||
if (!localAchievements || !localAchievements.achievements) {
|
|
||||||
await getGameAchievementData(objectId, "steam")
|
|
||||||
.then((achievements) => {
|
|
||||||
return gameAchievementRepository.upsert(
|
|
||||||
{
|
|
||||||
objectId,
|
|
||||||
shop: "steam",
|
|
||||||
achievements: JSON.stringify(achievements),
|
|
||||||
},
|
|
||||||
["objectId", "shop"]
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
}
|
|
||||||
|
|
||||||
const unlockedAchievements: UnlockedAchievement[] = [];
|
const unlockedAchievements: UnlockedAchievement[] = [];
|
||||||
|
|
||||||
for (const achievementFile of gameAchievementFiles) {
|
for (const achievementFile of gameAchievementFiles) {
|
||||||
const localAchievementFile = await parseAchievementFile(
|
const localAchievementFile = parseAchievementFile(
|
||||||
achievementFile.filePath,
|
achievementFile.filePath,
|
||||||
achievementFile.type
|
achievementFile.type
|
||||||
);
|
);
|
||||||
@ -121,5 +87,5 @@ export const updateLocalUnlockedAchivements = async (objectId: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeAchievements(objectId, "steam", unlockedAchievements, false);
|
mergeAchievements(game.objectID, "steam", unlockedAchievements, false);
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,6 @@ export const startMainLoop = async () => {
|
|||||||
watchAchievements(),
|
watchAchievements(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await sleep(1000);
|
await sleep(1500);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user