mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-01-23 21:44:55 +03:00
Merge pull request #1289 from hydralauncher/fix/handle-achievement-exception
fix: handle achievement exception
This commit is contained in:
commit
1acafe5b8f
40
package.json
40
package.json
@ -34,24 +34,24 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron-toolkit/preload": "^3.0.0",
|
"@electron-toolkit/preload": "^3.0.0",
|
||||||
"@electron-toolkit/utils": "^3.0.0",
|
"@electron-toolkit/utils": "^3.0.0",
|
||||||
"@fontsource/noto-sans": "^5.0.22",
|
"@fontsource/noto-sans": "^5.1.0",
|
||||||
"@hookform/resolvers": "^3.9.0",
|
"@hookform/resolvers": "^3.9.1",
|
||||||
"@primer/octicons-react": "^19.9.0",
|
"@primer/octicons-react": "^19.9.0",
|
||||||
"@reduxjs/toolkit": "^2.2.3",
|
"@reduxjs/toolkit": "^2.2.3",
|
||||||
"@vanilla-extract/css": "^1.14.2",
|
"@vanilla-extract/css": "^1.14.2",
|
||||||
"@vanilla-extract/dynamic": "^2.1.1",
|
"@vanilla-extract/dynamic": "^2.1.2",
|
||||||
"@vanilla-extract/recipes": "^0.5.2",
|
"@vanilla-extract/recipes": "^0.5.2",
|
||||||
"auto-launch": "^5.0.6",
|
"auto-launch": "^5.0.6",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.9",
|
||||||
"better-sqlite3": "^11.3.0",
|
"better-sqlite3": "^11.7.0",
|
||||||
"check-disk-space": "^3.4.0",
|
"check-disk-space": "^3.4.0",
|
||||||
"classnames": "^2.5.1",
|
"classnames": "^2.5.1",
|
||||||
"color": "^4.2.3",
|
"color": "^4.2.3",
|
||||||
"color.js": "^1.2.0",
|
"color.js": "^1.2.0",
|
||||||
"create-desktop-shortcuts": "^1.11.0",
|
"create-desktop-shortcuts": "^1.11.0",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"dexie": "^4.0.9",
|
"dexie": "^4.0.10",
|
||||||
"electron-log": "^5.2.0",
|
"electron-log": "^5.2.4",
|
||||||
"electron-updater": "^6.3.9",
|
"electron-updater": "^6.3.9",
|
||||||
"file-type": "^19.6.0",
|
"file-type": "^19.6.0",
|
||||||
"flexsearch": "^0.7.43",
|
"flexsearch": "^0.7.43",
|
||||||
@ -72,14 +72,14 @@
|
|||||||
"sudo-prompt": "^9.2.1",
|
"sudo-prompt": "^9.2.1",
|
||||||
"tar": "^7.4.3",
|
"tar": "^7.4.3",
|
||||||
"typeorm": "^0.3.20",
|
"typeorm": "^0.3.20",
|
||||||
"user-agents": "^1.1.193",
|
"user-agents": "^1.1.387",
|
||||||
"yaml": "^2.4.1",
|
"yaml": "^2.6.1",
|
||||||
"yup": "^1.4.0",
|
"yup": "^1.5.0",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.24.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^19.5.0",
|
"@commitlint/cli": "^19.6.0",
|
||||||
"@commitlint/config-conventional": "^19.5.0",
|
"@commitlint/config-conventional": "^19.6.0",
|
||||||
"@electron-toolkit/eslint-config-prettier": "^2.0.0",
|
"@electron-toolkit/eslint-config-prettier": "^2.0.0",
|
||||||
"@electron-toolkit/eslint-config-ts": "^2.0.0",
|
"@electron-toolkit/eslint-config-ts": "^2.0.0",
|
||||||
"@electron-toolkit/tsconfig": "^1.0.1",
|
"@electron-toolkit/tsconfig": "^1.0.1",
|
||||||
@ -87,8 +87,8 @@
|
|||||||
"@types/auto-launch": "^5.0.5",
|
"@types/auto-launch": "^5.0.5",
|
||||||
"@types/color": "^3.0.6",
|
"@types/color": "^3.0.6",
|
||||||
"@types/folder-hash": "^4.0.4",
|
"@types/folder-hash": "^4.0.4",
|
||||||
"@types/jsdom": "^21.1.6",
|
"@types/jsdom": "^21.1.7",
|
||||||
"@types/jsonwebtoken": "^9.0.6",
|
"@types/jsonwebtoken": "^9.0.7",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^20.12.7",
|
"@types/node": "^20.12.7",
|
||||||
"@types/parse-torrent": "^5.8.7",
|
"@types/parse-torrent": "^5.8.7",
|
||||||
@ -98,15 +98,15 @@
|
|||||||
"@types/user-agents": "^1.0.4",
|
"@types/user-agents": "^1.0.4",
|
||||||
"@vanilla-extract/vite-plugin": "^4.0.7",
|
"@vanilla-extract/vite-plugin": "^4.0.7",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
"electron": "^30.3.0",
|
"electron": "^31.7.6",
|
||||||
"electron-builder": "^25.1.8",
|
"electron-builder": "^25.1.8",
|
||||||
"electron-vite": "^2.0.0",
|
"electron-vite": "^2.0.0",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-plugin-jsx-a11y": "^6.8.0",
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.37.2",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"husky": "^9.0.11",
|
"husky": "^9.1.7",
|
||||||
"prettier": "^3.2.4",
|
"prettier": "^3.4.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"sass-embedded": "^1.80.6",
|
"sass-embedded": "^1.80.6",
|
||||||
|
@ -236,24 +236,28 @@ export class AchievementWatcherManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public static preSearchAchievements = async () => {
|
public static preSearchAchievements = async () => {
|
||||||
const newAchievementsCount =
|
try {
|
||||||
process.platform === "win32"
|
const newAchievementsCount =
|
||||||
? await this.preSearchAchievementsWindows()
|
process.platform === "win32"
|
||||||
: await this.preSearchAchievementsWithWine();
|
? await this.preSearchAchievementsWindows()
|
||||||
|
: await this.preSearchAchievementsWithWine();
|
||||||
|
|
||||||
const totalNewGamesWithAchievements = newAchievementsCount.filter(
|
const totalNewGamesWithAchievements = newAchievementsCount.filter(
|
||||||
(achievements) => achievements
|
(achievements) => achievements
|
||||||
).length;
|
).length;
|
||||||
const totalNewAchievements = newAchievementsCount.reduce(
|
const totalNewAchievements = newAchievementsCount.reduce(
|
||||||
(acc, val) => acc + val,
|
(acc, val) => acc + val,
|
||||||
0
|
0
|
||||||
);
|
|
||||||
|
|
||||||
if (totalNewAchievements > 0) {
|
|
||||||
publishCombinedNewAchievementNotification(
|
|
||||||
totalNewAchievements,
|
|
||||||
totalNewGamesWithAchievements
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (totalNewAchievements > 0) {
|
||||||
|
publishCombinedNewAchievementNotification(
|
||||||
|
totalNewAchievements,
|
||||||
|
totalNewGamesWithAchievements
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
achievementsLogger.error("Error on preSearchAchievements", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hasFinishedMergingWithRemote = true;
|
this.hasFinishedMergingWithRemote = true;
|
||||||
|
@ -9,144 +9,134 @@ export const parseAchievementFile = (
|
|||||||
): UnlockedAchievement[] => {
|
): UnlockedAchievement[] => {
|
||||||
if (!existsSync(filePath)) return [];
|
if (!existsSync(filePath)) return [];
|
||||||
|
|
||||||
if (type == Cracker.codex) {
|
try {
|
||||||
const parsed = iniParse(filePath);
|
if (type == Cracker.codex) {
|
||||||
return processDefault(parsed);
|
const parsed = iniParse(filePath);
|
||||||
|
return processDefault(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == Cracker.rune) {
|
||||||
|
const parsed = iniParse(filePath);
|
||||||
|
return processDefault(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === Cracker.onlineFix) {
|
||||||
|
const parsed = iniParse(filePath);
|
||||||
|
return processOnlineFix(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === Cracker.goldberg) {
|
||||||
|
const parsed = jsonParse(filePath);
|
||||||
|
return processGoldberg(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == Cracker.userstats) {
|
||||||
|
const parsed = iniParse(filePath);
|
||||||
|
return processUserStats(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == Cracker.rld) {
|
||||||
|
const parsed = iniParse(filePath);
|
||||||
|
return processRld(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === Cracker.skidrow) {
|
||||||
|
const parsed = iniParse(filePath);
|
||||||
|
return processSkidrow(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === Cracker._3dm) {
|
||||||
|
const parsed = iniParse(filePath);
|
||||||
|
return process3DM(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === Cracker.flt) {
|
||||||
|
const achievements = readdirSync(filePath);
|
||||||
|
|
||||||
|
return achievements.map((achievement) => {
|
||||||
|
return {
|
||||||
|
name: achievement,
|
||||||
|
unlockTime: Date.now(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === Cracker.creamAPI) {
|
||||||
|
const parsed = iniParse(filePath);
|
||||||
|
return processCreamAPI(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === Cracker.empress) {
|
||||||
|
const parsed = jsonParse(filePath);
|
||||||
|
return processGoldberg(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === Cracker.razor1911) {
|
||||||
|
return processRazor1911(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
achievementsLogger.log(
|
||||||
|
`Unprocessed ${type} achievements found on ${filePath}`
|
||||||
|
);
|
||||||
|
return [];
|
||||||
|
} catch (err) {
|
||||||
|
achievementsLogger.error(`Error parsing ${type} - ${filePath}`, err);
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == Cracker.rune) {
|
|
||||||
const parsed = iniParse(filePath);
|
|
||||||
return processDefault(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === Cracker.onlineFix) {
|
|
||||||
const parsed = iniParse(filePath);
|
|
||||||
return processOnlineFix(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === Cracker.goldberg) {
|
|
||||||
const parsed = jsonParse(filePath);
|
|
||||||
return processGoldberg(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Cracker.userstats) {
|
|
||||||
const parsed = iniParse(filePath);
|
|
||||||
return processUserStats(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Cracker.rld) {
|
|
||||||
const parsed = iniParse(filePath);
|
|
||||||
return processRld(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === Cracker.skidrow) {
|
|
||||||
const parsed = iniParse(filePath);
|
|
||||||
return processSkidrow(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === Cracker._3dm) {
|
|
||||||
const parsed = iniParse(filePath);
|
|
||||||
return process3DM(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === Cracker.flt) {
|
|
||||||
const achievements = readdirSync(filePath);
|
|
||||||
|
|
||||||
return achievements.map((achievement) => {
|
|
||||||
return {
|
|
||||||
name: achievement,
|
|
||||||
unlockTime: Date.now(),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === Cracker.creamAPI) {
|
|
||||||
const parsed = iniParse(filePath);
|
|
||||||
return processCreamAPI(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === Cracker.empress) {
|
|
||||||
const parsed = jsonParse(filePath);
|
|
||||||
return processGoldberg(parsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === Cracker.razor1911) {
|
|
||||||
return processRazor1911(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
achievementsLogger.log(
|
|
||||||
`Unprocessed ${type} achievements found on ${filePath}`
|
|
||||||
);
|
|
||||||
return [];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const iniParse = (filePath: string) => {
|
const iniParse = (filePath: string) => {
|
||||||
try {
|
const fileContent = readFileSync(filePath, "utf-8");
|
||||||
const fileContent = readFileSync(filePath, "utf-8");
|
|
||||||
|
|
||||||
const lines =
|
const lines =
|
||||||
fileContent.charCodeAt(0) === 0xfeff
|
fileContent.charCodeAt(0) === 0xfeff
|
||||||
? fileContent.slice(1).split(/[\r\n]+/)
|
? fileContent.slice(1).split(/[\r\n]+/)
|
||||||
: fileContent.split(/[\r\n]+/);
|
: fileContent.split(/[\r\n]+/);
|
||||||
|
|
||||||
let objectName = "";
|
let objectName = "";
|
||||||
const object: Record<string, Record<string, string | number>> = {};
|
const object: Record<string, Record<string, string | number>> = {};
|
||||||
|
|
||||||
for (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("]")) {
|
||||||
objectName = line.slice(1, -1);
|
objectName = line.slice(1, -1);
|
||||||
object[objectName] = {};
|
object[objectName] = {};
|
||||||
} else {
|
} else {
|
||||||
const [name, ...value] = line.split("=");
|
const [name, ...value] = line.split("=");
|
||||||
object[objectName][name.trim()] = value.join("=").trim();
|
object[objectName][name.trim()] = value.join("=").trim();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return object;
|
|
||||||
} catch (err) {
|
|
||||||
achievementsLogger.error(`Error parsing ${filePath}`, err);
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
};
|
};
|
||||||
|
|
||||||
const jsonParse = (filePath: string) => {
|
const jsonParse = (filePath: string) => {
|
||||||
try {
|
return JSON.parse(readFileSync(filePath, "utf-8"));
|
||||||
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
||||||
} catch (err) {
|
|
||||||
achievementsLogger.error(`Error parsing ${filePath}`, err);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const processRazor1911 = (filePath: string): UnlockedAchievement[] => {
|
const processRazor1911 = (filePath: string): UnlockedAchievement[] => {
|
||||||
try {
|
const fileContent = readFileSync(filePath, "utf-8");
|
||||||
const fileContent = readFileSync(filePath, "utf-8");
|
|
||||||
|
|
||||||
const lines =
|
const lines =
|
||||||
fileContent.charCodeAt(0) === 0xfeff
|
fileContent.charCodeAt(0) === 0xfeff
|
||||||
? fileContent.slice(1).split(/[\r\n]+/)
|
? fileContent.slice(1).split(/[\r\n]+/)
|
||||||
: fileContent.split(/[\r\n]+/);
|
: fileContent.split(/[\r\n]+/);
|
||||||
|
|
||||||
const achievements: UnlockedAchievement[] = [];
|
const achievements: UnlockedAchievement[] = [];
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
if (!line.length) continue;
|
if (!line.length) continue;
|
||||||
|
|
||||||
const [name, unlocked, unlockTime] = line.split(" ");
|
const [name, unlocked, unlockTime] = line.split(" ");
|
||||||
if (unlocked === "1") {
|
if (unlocked === "1") {
|
||||||
achievements.push({
|
achievements.push({
|
||||||
name,
|
name,
|
||||||
unlockTime: Number(unlockTime) * 1000,
|
unlockTime: Number(unlockTime) * 1000,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return achievements;
|
|
||||||
} catch (err) {
|
|
||||||
achievementsLogger.error(`Error processing ${filePath}`, err);
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return achievements;
|
||||||
};
|
};
|
||||||
|
|
||||||
const processOnlineFix = (unlockedAchievements: any): UnlockedAchievement[] => {
|
const processOnlineFix = (unlockedAchievements: any): UnlockedAchievement[] => {
|
||||||
|
Loading…
Reference in New Issue
Block a user