mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-21 01:53:57 +00:00
Merge branch 'feature/game-achievements' of github.com:hydralauncher/hydra into feature/cloud-sync
This commit is contained in:
@@ -51,7 +51,7 @@ const getAchievementLocalUser = async (shop: string, objectId: string) => {
|
||||
...achievementData,
|
||||
unlocked: false,
|
||||
unlockTime: null,
|
||||
icon: icongray,
|
||||
icongray: icongray,
|
||||
} as UserAchievement;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
@@ -110,7 +110,7 @@ const getAchievementsRemoteUser = async (
|
||||
...achievementData,
|
||||
unlocked: false,
|
||||
unlockTime: null,
|
||||
icon: icongray,
|
||||
icongray: icongray,
|
||||
} as UserAchievement;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
|
||||
@@ -50,6 +50,7 @@ import "./user/unblock-user";
|
||||
import "./user/get-user-friends";
|
||||
import "./user/get-user-stats";
|
||||
import "./user/report-user";
|
||||
import "./user/get-compared-unlocked-achievements";
|
||||
import "./profile/get-friend-requests";
|
||||
import "./profile/get-me";
|
||||
import "./profile/undo-friendship";
|
||||
|
||||
44
src/main/events/user/get-compared-unlocked-achievements.ts
Normal file
44
src/main/events/user/get-compared-unlocked-achievements.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import type { ComparedAchievements, GameShop } from "@types";
|
||||
import { registerEvent } from "../register-event";
|
||||
import { userPreferencesRepository } from "@main/repository";
|
||||
import { HydraApi } from "@main/services";
|
||||
|
||||
const getComparedUnlockedAchievements = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
objectId: string,
|
||||
shop: GameShop,
|
||||
userId: string
|
||||
) => {
|
||||
const userPreferences = await userPreferencesRepository.findOne({
|
||||
where: { id: 1 },
|
||||
});
|
||||
|
||||
return HydraApi.get<ComparedAchievements>(
|
||||
`/users/${userId}/games/achievements/compare`,
|
||||
{
|
||||
shop,
|
||||
objectId,
|
||||
language: userPreferences?.language || "en",
|
||||
}
|
||||
).then((achievements) => {
|
||||
const sortedAchievements = achievements.achievements.sort((a, b) => {
|
||||
if (a.otherUserStat.unlocked && !b.otherUserStat.unlocked) return -1;
|
||||
if (!a.otherUserStat.unlocked && b.otherUserStat.unlocked) return 1;
|
||||
if (a.otherUserStat.unlocked && b.otherUserStat.unlocked) {
|
||||
return b.otherUserStat.unlockTime! - a.otherUserStat.unlockTime!;
|
||||
}
|
||||
|
||||
return Number(a.hidden) - Number(b.hidden);
|
||||
});
|
||||
|
||||
return {
|
||||
...achievements,
|
||||
achievements: sortedAchievements,
|
||||
} as ComparedAchievements;
|
||||
});
|
||||
};
|
||||
|
||||
registerEvent(
|
||||
"getComparedUnlockedAchievements",
|
||||
getComparedUnlockedAchievements
|
||||
);
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
getAlternativeObjectIds,
|
||||
} from "./find-achivement-files";
|
||||
import type { AchievementFile } from "@types";
|
||||
import { achievementsLogger, logger } from "../logger";
|
||||
import { achievementsLogger } from "../logger";
|
||||
import { Cracker } from "@shared";
|
||||
|
||||
const fileStats: Map<string, number> = new Map();
|
||||
@@ -55,8 +55,6 @@ const processAchievementFileDiff = async (
|
||||
) => {
|
||||
const unlockedAchievements = parseAchievementFile(file.filePath, file.type);
|
||||
|
||||
logger.log("Achievements from file", file.filePath, unlockedAchievements);
|
||||
|
||||
if (unlockedAchievements.length) {
|
||||
return mergeAchievements(
|
||||
game.objectID,
|
||||
@@ -80,7 +78,7 @@ const compareFltFolder = async (game: Game, file: AchievementFile) => {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.log("Detected change in FLT folder", file.filePath);
|
||||
achievementsLogger.log("Detected change in FLT folder", file.filePath);
|
||||
await processAchievementFileDiff(game, file);
|
||||
} catch (err) {
|
||||
achievementsLogger.error(err);
|
||||
@@ -101,6 +99,13 @@ const compareFile = async (game: Game, file: AchievementFile) => {
|
||||
|
||||
if (!previousStat) {
|
||||
if (currentStat.mtimeMs) {
|
||||
achievementsLogger.log(
|
||||
"First change in file",
|
||||
file.filePath,
|
||||
previousStat,
|
||||
currentStat.mtimeMs
|
||||
);
|
||||
|
||||
await processAchievementFileDiff(game, file);
|
||||
return;
|
||||
}
|
||||
@@ -110,7 +115,7 @@ const compareFile = async (game: Game, file: AchievementFile) => {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.log(
|
||||
achievementsLogger.log(
|
||||
"Detected change in file",
|
||||
file.filePath,
|
||||
previousStat,
|
||||
|
||||
@@ -42,7 +42,9 @@ export const getGameAchievementData = async (
|
||||
where: { objectId, shop },
|
||||
})
|
||||
.then((gameAchievements) => {
|
||||
return JSON.parse(gameAchievements?.achievements || "[]");
|
||||
return JSON.parse(
|
||||
gameAchievements?.achievements || "[]"
|
||||
) as AchievementData[];
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -64,7 +64,13 @@ export const mergeAchievements = async (
|
||||
localGameAchievement?.unlockedAchievements || "[]"
|
||||
).filter((achievement) => achievement.name) as UnlockedAchievement[];
|
||||
|
||||
const newAchievements = achievements
|
||||
const newAchievementsMap = new Map(
|
||||
achievements.reverse().map((achievement) => {
|
||||
return [achievement.name.toUpperCase(), achievement];
|
||||
})
|
||||
);
|
||||
|
||||
const newAchievements = [...newAchievementsMap.values()]
|
||||
.filter((achievement) => {
|
||||
return !unlockedAchievements.some((localAchievement) => {
|
||||
return (
|
||||
@@ -114,7 +120,7 @@ export const mergeAchievements = async (
|
||||
|
||||
const mergedLocalAchievements = unlockedAchievements.concat(newAchievements);
|
||||
|
||||
if (game?.remoteId) {
|
||||
if (game.remoteId) {
|
||||
return HydraApi.put(
|
||||
"/profile/games/achievements",
|
||||
{
|
||||
|
||||
@@ -242,15 +242,23 @@ const processRld = (unlockedAchievements: any): UnlockedAchievement[] => {
|
||||
const unlockedAchievement = unlockedAchievements[achievement];
|
||||
|
||||
if (unlockedAchievement?.State) {
|
||||
newUnlockedAchievements.push({
|
||||
name: achievement,
|
||||
unlockTime:
|
||||
new DataView(
|
||||
new Uint8Array(
|
||||
Buffer.from(unlockedAchievement.Time.toString(), "hex")
|
||||
).buffer
|
||||
).getUint32(0, true) * 1000,
|
||||
});
|
||||
const unlocked = new DataView(
|
||||
new Uint8Array(
|
||||
Buffer.from(unlockedAchievement.State.toString(), "hex")
|
||||
).buffer
|
||||
).getUint32(0, true);
|
||||
|
||||
if (unlocked === 1) {
|
||||
newUnlockedAchievements.push({
|
||||
name: achievement,
|
||||
unlockTime:
|
||||
new DataView(
|
||||
new Uint8Array(
|
||||
Buffer.from(unlockedAchievement.Time.toString(), "hex")
|
||||
).buffer
|
||||
).getUint32(0, true) * 1000,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,14 +49,14 @@ export const updateAllLocalUnlockedAchievements = async () => {
|
||||
|
||||
if (parsedAchievements.length) {
|
||||
unlockedAchievements.push(...parsedAchievements);
|
||||
}
|
||||
|
||||
achievementsLogger.log(
|
||||
"Achievement file for",
|
||||
game.title,
|
||||
achievementFile.filePath,
|
||||
parsedAchievements
|
||||
);
|
||||
achievementsLogger.log(
|
||||
"Achievement file for",
|
||||
game.title,
|
||||
achievementFile.filePath,
|
||||
parsedAchievements
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
mergeAchievements(game.objectID, "steam", unlockedAchievements, false);
|
||||
|
||||
@@ -80,6 +80,10 @@ export class WindowManager {
|
||||
|
||||
this.mainWindow.webContents.session.webRequest.onBeforeSendHeaders(
|
||||
(details, callback) => {
|
||||
if (details.webContentsId !== this.mainWindow?.webContents.id) {
|
||||
return callback(details);
|
||||
}
|
||||
|
||||
const userAgent = new UserAgent();
|
||||
|
||||
callback({
|
||||
|
||||
Reference in New Issue
Block a user