mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-03 00:33:49 +03:00
Merge pull request #1094 from hydralauncher/feat/refactor-achievements-files
feat: refactor achievements file
This commit is contained in:
commit
7d79048a25
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydralauncher",
|
"name": "hydralauncher",
|
||||||
"version": "3.0.1",
|
"version": "3.0.2",
|
||||||
"description": "Hydra",
|
"description": "Hydra",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "Los Broxas",
|
"author": "Los Broxas",
|
||||||
|
@ -242,10 +242,18 @@ export class AchievementWatcherManager {
|
|||||||
? await this.preSearchAchievementsWindows()
|
? await this.preSearchAchievementsWindows()
|
||||||
: await this.preSearchAchievementsWithWine();
|
: await this.preSearchAchievementsWithWine();
|
||||||
|
|
||||||
|
const totalNewGamesWithAchievements = newAchievementsCount.filter(
|
||||||
|
(achievements) => achievements
|
||||||
|
).length;
|
||||||
|
const totalNewAchievements = newAchievementsCount.reduce(
|
||||||
|
(acc, val) => acc + val,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
WindowManager.notificationWindow?.webContents.send(
|
WindowManager.notificationWindow?.webContents.send(
|
||||||
"on-combined-achievements-unlocked",
|
"on-combined-achievements-unlocked",
|
||||||
newAchievementsCount.filter((achievements) => achievements).length,
|
totalNewGamesWithAchievements,
|
||||||
newAchievementsCount.reduce((acc, val) => acc + val, 0)
|
totalNewAchievements
|
||||||
);
|
);
|
||||||
|
|
||||||
this.hasFinishedMergingWithRemote = true;
|
this.hasFinishedMergingWithRemote = true;
|
||||||
|
@ -79,11 +79,11 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(publicDocuments, "Steam", "CODEX"),
|
folderPath: path.join(publicDocuments, "Steam", "CODEX"),
|
||||||
fileLocation: ["achievements.ini"],
|
fileLocation: ["<objectId>", "achievements.ini"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
folderPath: path.join(appData, "Steam", "CODEX"),
|
folderPath: path.join(appData, "Steam", "CODEX"),
|
||||||
fileLocation: ["achievements.ini"],
|
fileLocation: ["<objectId>", "achievements.ini"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(publicDocuments, "Steam", "RUNE"),
|
folderPath: path.join(publicDocuments, "Steam", "RUNE"),
|
||||||
fileLocation: ["achievements.ini"],
|
fileLocation: ["<objectId>", "achievements.ini"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -101,11 +101,11 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(publicDocuments, "OnlineFix"),
|
folderPath: path.join(publicDocuments, "OnlineFix"),
|
||||||
fileLocation: ["Stats", "Achievements.ini"],
|
fileLocation: ["<objectId>", "Stats", "Achievements.ini"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
folderPath: path.join(publicDocuments, "OnlineFix"),
|
folderPath: path.join(publicDocuments, "OnlineFix"),
|
||||||
fileLocation: ["Achievements.ini"],
|
fileLocation: ["<objectId>", "Achievements.ini"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -114,11 +114,11 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(appData, "Goldberg SteamEmu Saves"),
|
folderPath: path.join(appData, "Goldberg SteamEmu Saves"),
|
||||||
fileLocation: ["achievements.json"],
|
fileLocation: ["<objectId>", "achievements.json"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
folderPath: path.join(appData, "GSE Saves"),
|
folderPath: path.join(appData, "GSE Saves"),
|
||||||
fileLocation: ["achievements.json"],
|
fileLocation: ["<objectId>", "achievements.json"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -131,19 +131,19 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(programData, "RLD!"),
|
folderPath: path.join(programData, "RLD!"),
|
||||||
fileLocation: ["achievements.ini"],
|
fileLocation: ["<objectId>", "achievements.ini"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
folderPath: path.join(programData, "Steam", "Player"),
|
folderPath: path.join(programData, "Steam", "Player"),
|
||||||
fileLocation: ["stats", "achievements.ini"],
|
fileLocation: ["<objectId>", "stats", "achievements.ini"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
folderPath: path.join(programData, "Steam", "RLD!"),
|
folderPath: path.join(programData, "Steam", "RLD!"),
|
||||||
fileLocation: ["stats", "achievements.ini"],
|
fileLocation: ["<objectId>", "stats", "achievements.ini"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
folderPath: path.join(programData, "Steam", "dodi"),
|
folderPath: path.join(programData, "Steam", "dodi"),
|
||||||
fileLocation: ["stats", "achievements.ini"],
|
fileLocation: ["<objectId>", "stats", "achievements.ini"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -152,11 +152,16 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(appData, "EMPRESS", "remote"),
|
folderPath: path.join(appData, "EMPRESS", "remote"),
|
||||||
fileLocation: ["achievements.json"],
|
fileLocation: ["<objectId>", "achievements.json"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
folderPath: path.join(publicDocuments, "EMPRESS", "remote"),
|
folderPath: path.join(publicDocuments, "EMPRESS"),
|
||||||
fileLocation: ["achievements.json"],
|
fileLocation: [
|
||||||
|
"<objectId>",
|
||||||
|
"remote",
|
||||||
|
"<objectId>",
|
||||||
|
"achievements.json",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -165,15 +170,15 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(documents, "SKIDROW"),
|
folderPath: path.join(documents, "SKIDROW"),
|
||||||
fileLocation: ["SteamEmu", "UserStats", "achiev.ini"],
|
fileLocation: ["<objectId>", "SteamEmu", "UserStats", "achiev.ini"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
folderPath: path.join(documents, "Player"),
|
folderPath: path.join(documents, "Player"),
|
||||||
fileLocation: ["SteamEmu", "UserStats", "achiev.ini"],
|
fileLocation: ["<objectId>", "SteamEmu", "UserStats", "achiev.ini"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
folderPath: path.join(localAppData, "SKIDROW"),
|
folderPath: path.join(localAppData, "SKIDROW"),
|
||||||
fileLocation: ["SteamEmu", "UserStats", "achiev.ini"],
|
fileLocation: ["<objectId>", "SteamEmu", "UserStats", "achiev.ini"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -182,7 +187,7 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(appData, "CreamAPI"),
|
folderPath: path.join(appData, "CreamAPI"),
|
||||||
fileLocation: ["stats", "CreamAPI.Achievements.cfg"],
|
fileLocation: ["<objectId>", "stats", "CreamAPI.Achievements.cfg"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -191,7 +196,7 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(appData, "SmartSteamEmu"),
|
folderPath: path.join(appData, "SmartSteamEmu"),
|
||||||
fileLocation: ["User", "Achievements.ini"],
|
fileLocation: ["<objectId>", "User", "Achievements.ini"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -213,11 +218,11 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(appData, "RLE"),
|
folderPath: path.join(appData, "RLE"),
|
||||||
fileLocation: ["achievements.ini"],
|
fileLocation: ["<objectId>", "achievements.ini"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
folderPath: path.join(appData, "RLE"),
|
folderPath: path.join(appData, "RLE"),
|
||||||
fileLocation: ["Achievements.ini"],
|
fileLocation: ["<objectId>", "Achievements.ini"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -226,7 +231,7 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
folderPath: path.join(appData, ".1911"),
|
folderPath: path.join(appData, ".1911"),
|
||||||
fileLocation: ["achievement"],
|
fileLocation: ["<objectId>", "achievement"],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -253,8 +258,7 @@ export const findAchievementFiles = (game: Game) => {
|
|||||||
const filePath = path.join(
|
const filePath = path.join(
|
||||||
game.winePrefixPath ?? "",
|
game.winePrefixPath ?? "",
|
||||||
folderPath,
|
folderPath,
|
||||||
objectId,
|
...mapFileLocationWithObjectId(fileLocation, objectId)
|
||||||
...fileLocation
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (fs.existsSync(filePath)) {
|
if (fs.existsSync(filePath)) {
|
||||||
@ -303,6 +307,15 @@ export const findAchievementFileInExecutableDirectory = (
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mapFileLocationWithObjectId = (
|
||||||
|
fileLocation: string[],
|
||||||
|
objectId: string
|
||||||
|
) => {
|
||||||
|
return fileLocation.map((location) =>
|
||||||
|
location.replace("<objectId>", objectId)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const findAllAchievementFiles = () => {
|
export const findAllAchievementFiles = () => {
|
||||||
const gameAchievementFiles = new Map<string, AchievementFile[]>();
|
const gameAchievementFiles = new Map<string, AchievementFile[]>();
|
||||||
|
|
||||||
@ -315,7 +328,10 @@ export const findAllAchievementFiles = () => {
|
|||||||
const objectIds = fs.readdirSync(folderPath);
|
const objectIds = fs.readdirSync(folderPath);
|
||||||
|
|
||||||
for (const objectId of objectIds) {
|
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;
|
if (!fs.existsSync(filePath)) continue;
|
||||||
|
|
||||||
|
@ -65,6 +65,11 @@ export const parseAchievementFile = (
|
|||||||
return processCreamAPI(parsed);
|
return processCreamAPI(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === Cracker.empress) {
|
||||||
|
const parsed = jsonParse(filePath);
|
||||||
|
return processGoldberg(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
if (type === Cracker.razor1911) {
|
if (type === Cracker.razor1911) {
|
||||||
return processRazor1911(filePath);
|
return processRazor1911(filePath);
|
||||||
}
|
}
|
||||||
@ -118,7 +123,7 @@ const jsonParse = (filePath: string) => {
|
|||||||
const processRazor1911 = (filePath: string): UnlockedAchievement[] => {
|
const processRazor1911 = (filePath: string): UnlockedAchievement[] => {
|
||||||
try {
|
try {
|
||||||
const fileContent = readFileSync(filePath, "utf-8");
|
const fileContent = readFileSync(filePath, "utf-8");
|
||||||
achievementsLogger.log("processing file", filePath, fileContent);
|
|
||||||
const lines =
|
const lines =
|
||||||
fileContent.charCodeAt(0) === 0xfeff
|
fileContent.charCodeAt(0) === 0xfeff
|
||||||
? fileContent.slice(1).split(/[\r\n]+/)
|
? fileContent.slice(1).split(/[\r\n]+/)
|
||||||
@ -136,7 +141,7 @@ const processRazor1911 = (filePath: string): UnlockedAchievement[] => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
achievementsLogger.log("processing file", achievements);
|
|
||||||
return achievements;
|
return achievements;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
achievementsLogger.error(`Error processing ${filePath}`, err);
|
achievementsLogger.error(`Error processing ${filePath}`, err);
|
||||||
|
@ -77,6 +77,8 @@ export function useDate() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
formatDate: (date: number | Date | string): string => {
|
formatDate: (date: number | Date | string): string => {
|
||||||
|
if (isNaN(new Date(date).getDate())) return "N/A";
|
||||||
|
|
||||||
const locale = getDateLocale();
|
const locale = getDateLocale();
|
||||||
return format(date, locale == enUS ? "MM/dd/yyyy" : "dd/MM/yyyy");
|
return format(date, locale == enUS ? "MM/dd/yyyy" : "dd/MM/yyyy");
|
||||||
},
|
},
|
||||||
|
@ -18,7 +18,7 @@ export const panel = recipe({
|
|||||||
position: "sticky",
|
position: "sticky",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
top: "0",
|
top: "0",
|
||||||
zIndex: "1",
|
zIndex: "2",
|
||||||
},
|
},
|
||||||
variants: {
|
variants: {
|
||||||
stuck: {
|
stuck: {
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { format } from "date-fns";
|
|
||||||
import { useContext } from "react";
|
import { useContext } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { useDownload } from "@renderer/hooks";
|
import { useDate, useDownload } from "@renderer/hooks";
|
||||||
|
|
||||||
import { HeroPanelActions } from "./hero-panel-actions";
|
import { HeroPanelActions } from "./hero-panel-actions";
|
||||||
import * as styles from "./hero-panel.css";
|
import * as styles from "./hero-panel.css";
|
||||||
@ -17,6 +16,8 @@ export interface HeroPanelProps {
|
|||||||
export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
|
export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
|
||||||
const { t } = useTranslation("game_details");
|
const { t } = useTranslation("game_details");
|
||||||
|
|
||||||
|
const { formatDate } = useDate();
|
||||||
|
|
||||||
const { game, repacks, gameColor } = useContext(gameDetailsContext);
|
const { game, repacks, gameColor } = useContext(gameDetailsContext);
|
||||||
|
|
||||||
const { lastPacket } = useDownload();
|
const { lastPacket } = useDownload();
|
||||||
@ -29,7 +30,9 @@ export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
|
|||||||
const [latestRepack] = repacks;
|
const [latestRepack] = repacks;
|
||||||
|
|
||||||
if (latestRepack) {
|
if (latestRepack) {
|
||||||
const lastUpdate = format(latestRepack.uploadDate!, "dd/MM/yyyy");
|
const lastUpdate = latestRepack.uploadDate
|
||||||
|
? formatDate(latestRepack.uploadDate!)
|
||||||
|
: "";
|
||||||
const repacksCount = repacks.length;
|
const repacksCount = repacks.length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -126,7 +126,7 @@ export function Sidebar() {
|
|||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
zIndex: 2,
|
zIndex: 1,
|
||||||
inset: 0,
|
inset: 0,
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
|
Loading…
Reference in New Issue
Block a user