mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-12 06:16:17 +00:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a86ec89aa | ||
|
|
238d207590 | ||
|
|
98e2d2ec0d | ||
|
|
717dab5c90 | ||
|
|
d73a46aac2 | ||
|
|
9f9a4eba18 | ||
|
|
3bddd7e76b | ||
|
|
7cfc871be2 | ||
|
|
5705de7d7a | ||
|
|
b6fb29ca2d | ||
|
|
e89f459c78 | ||
|
|
0dac4d5cf3 | ||
|
|
93fb26c89b | ||
|
|
446d6b75c0 | ||
|
|
8dd29c7461 | ||
|
|
0ad1a2e3fe | ||
|
|
3c03d5ce16 | ||
|
|
8d8b714c68 | ||
|
|
7d79048a25 | ||
|
|
4a3ba43dae | ||
|
|
dc413736e8 | ||
|
|
2d98addd02 | ||
|
|
b85e712d8c | ||
|
|
582c276e95 | ||
|
|
430b07eb89 | ||
|
|
b46f46bc45 | ||
|
|
fd41ec5070 | ||
|
|
25d0f77c1d | ||
|
|
c5b2a8242c | ||
|
|
8b7ce6b062 | ||
|
|
db58ff0ba3 | ||
|
|
e951e11e62 | ||
|
|
0b854eda7c | ||
|
|
648083fbf4 | ||
|
|
09316dac9e | ||
|
|
670df826af | ||
|
|
912f9611ea | ||
|
|
d8254353b5 | ||
|
|
73185e7cbc | ||
|
|
c36c940a79 |
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
4
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,5 +1,5 @@
|
||||
name: Bug Report
|
||||
description: Create a report to help us improve. Write in English, please.
|
||||
description: Create a report to help us improve. Write in English.
|
||||
title: "[BUG] Write a title for your bug"
|
||||
labels: ["bug"]
|
||||
body:
|
||||
@@ -61,3 +61,5 @@ body:
|
||||
required: true
|
||||
- label: I am aware that Hydra team does not offer any support or help regarding the downloaded games.
|
||||
required: true
|
||||
- label: I have read the [Frequently Asked Questions (FAQ)](https://github.com/hydralauncher/hydra/wiki/FAQ).
|
||||
required: true
|
||||
|
||||
24
README.md
24
README.md
@@ -13,19 +13,19 @@
|
||||
[](https://github.com/hydralauncher/hydra/actions)
|
||||
[](https://github.com/hydralauncher/hydra/releases)
|
||||
|
||||
[](./README.pt-BR.md)
|
||||
[](./docs/README.pt-BR.md)
|
||||
[](./README.md)
|
||||
[](./README.ru.md)
|
||||
[](./README.uk-UA.md)
|
||||
[](./README.be.md)
|
||||
[](./README.es.md)
|
||||
[](./README.fr.md)
|
||||
[](./README.de.md)
|
||||
[](./README.it.md)
|
||||
[](./README.cs.md)
|
||||
[](./README.da.md)
|
||||
[](./README.nb.md)
|
||||
[](./README.et.md)
|
||||
[](./docs/README.ru.md)
|
||||
[](./docs/README.uk-UA.md)
|
||||
[](./docs/README.be.md)
|
||||
[](./docs/README.es.md)
|
||||
[](./docs/README.fr.md)
|
||||
[](./docs/README.de.md)
|
||||
[](./docs/README.it.md)
|
||||
[](./docs/README.cs.md)
|
||||
[](./docs/README.da.md)
|
||||
[](./docs/README.nb.md)
|
||||
[](./docs/README.et.md)
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hydralauncher",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.4",
|
||||
"description": "Hydra",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "Los Broxas",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -9,7 +9,8 @@
|
||||
"no_results": "Sin resultados encontrados",
|
||||
"start_typing": "Empieza a escribir para buscar...",
|
||||
"hot": "Popular Ahora",
|
||||
"weekly": "📅 Mejores juegos de la semana"
|
||||
"weekly": "📅 Mejores juegos de la semana",
|
||||
"achievements": "🏆 Juegos para completar"
|
||||
},
|
||||
"sidebar": {
|
||||
"catalogue": "Catálogo",
|
||||
@@ -160,7 +161,11 @@
|
||||
"no_download_option_info": "Sin información disponible",
|
||||
"backup_deletion_failed": "La eliminación de la copia de seguridad falló",
|
||||
"max_number_of_artifacts_reached": "Número máximo de copias de seguridad de este juego alcanzadas",
|
||||
"achievements_not_sync": "Tus logros no están sincronizadas"
|
||||
"achievements_not_sync": "Tus logros no están sincronizados",
|
||||
"manage_files_description": "Gestiona los archivos que serán respaldados y restaurados",
|
||||
"select_folder": "Seleccionar carpeta",
|
||||
"backup_from": "Copia de seguridad de {{date}}",
|
||||
"custom_backup_location_set": "Se configuró la carpeta de copia de seguridad"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Activar Hydra",
|
||||
@@ -347,7 +352,8 @@
|
||||
"profile_reported": "Perfil reportado",
|
||||
"your_friend_code": "Tu código de amigo:",
|
||||
"upload_banner": "Subir un banner",
|
||||
"uploading_banner": "Subiendo banner…"
|
||||
"uploading_banner": "Subiendo banner…",
|
||||
"background_image_updated": "Imagen de fondo actualizada"
|
||||
},
|
||||
"achievement": {
|
||||
"achievement_unlocked": "Logro desbloqueado",
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"no_results": "Tulemusi ei leitud",
|
||||
"start_typing": "Alusta otsimiseks kirjutamist...",
|
||||
"hot": "Praegu kuum",
|
||||
"weekly": "📅 Nädala top mängud"
|
||||
"weekly": "📅 Nädala top mängud",
|
||||
"achievements": "🏆 Mängud, mida läbida"
|
||||
},
|
||||
"sidebar": {
|
||||
"catalogue": "Kataloog",
|
||||
@@ -160,95 +161,11 @@
|
||||
"no_download_option_info": "Info pole saadaval",
|
||||
"backup_deletion_failed": "Varunduse kustutamine ebaõnnestus",
|
||||
"max_number_of_artifacts_reached": "Selle mängu varunduste maksimaalne arv on saavutatud",
|
||||
"achievements_not_sync": "Sinu saavutused pole sünkroniseeritud"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Aktiveeri Hydra",
|
||||
"installation_id": "Installatsiooni ID:",
|
||||
"enter_activation_code": "Sisesta oma aktiveerimiskood",
|
||||
"message": "Kui sa ei tea, kust seda küsida, siis sa ei peaks seda omama.",
|
||||
"activate": "Aktiveeri",
|
||||
"loading": "Laadimine…"
|
||||
},
|
||||
"downloads": {
|
||||
"resume": "Jätka",
|
||||
"pause": "Peata",
|
||||
"eta": "Lõpp {{eta}}",
|
||||
"paused": "Peatatud",
|
||||
"verifying": "Kontrollimine…",
|
||||
"completed": "Lõpetatud",
|
||||
"removed": "Pole alla laaditud",
|
||||
"cancel": "Tühista",
|
||||
"filter": "Filtreeri allalaaditud mänge",
|
||||
"remove": "Eemalda",
|
||||
"downloading_metadata": "Metaandmete allalaadimine…",
|
||||
"deleting": "Installeri kustutamine…",
|
||||
"delete": "Eemalda installer",
|
||||
"delete_modal_title": "Oled sa kindel?",
|
||||
"delete_modal_description": "See eemaldab kõik installifailid sinu arvutist",
|
||||
"install": "Installi",
|
||||
"download_in_progress": "Töös",
|
||||
"queued_downloads": "Järjekorras allalaadimised",
|
||||
"downloads_completed": "Lõpetatud",
|
||||
"queued": "Järjekorras",
|
||||
"no_downloads_title": "Nii tühi",
|
||||
"no_downloads_description": "Sa pole veel Hydraga midagi alla laadinud, aga pole kunagi hilja alustada.",
|
||||
"checking_files": "Failide kontrollimine…"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Allalaadimiste tee",
|
||||
"change": "Uuenda",
|
||||
"notifications": "Teavitused",
|
||||
"enable_download_notifications": "Kui allalaadimine on lõpetatud",
|
||||
"enable_repack_list_notifications": "Kui uus repack on lisatud",
|
||||
"real_debrid_api_token_label": "Real-Debrid API võti",
|
||||
"quit_app_instead_hiding": "Ära peida Hydrat sulgemisel",
|
||||
"launch_with_system": "Käivita Hydra süsteemi käivitamisel",
|
||||
"general": "Üldine",
|
||||
"behavior": "Käitumine",
|
||||
"download_sources": "Allalaadimise allikad",
|
||||
"language": "Keel",
|
||||
"real_debrid_api_token": "API Võti",
|
||||
"enable_real_debrid": "Luba Real-Debrid",
|
||||
"real_debrid_description": "Real-Debrid on piiranguteta allalaadija, mis võimaldab sul faile alla laadida koheselt ja sinu internetiühenduse parima kiirusega.",
|
||||
"real_debrid_invalid_token": "Vigane API võti",
|
||||
"real_debrid_api_token_hint": "Sa saad oma API võtme <0>siit</0>",
|
||||
"real_debrid_free_account_error": "Konto \"{{username}}\" on tasuta konto. Palun telli Real-Debrid",
|
||||
"real_debrid_linked_message": "Konto \"{{username}}\" ühendatud",
|
||||
"save_changes": "Salvesta muudatused",
|
||||
"changes_saved": "Muudatused edukalt salvestatud",
|
||||
"download_sources_description": "Hydra laeb allalaadimise lingid nendest allikatest. Allika URL peab olema otsene link .json failile, mis sisaldab allalaadimise linke.",
|
||||
"validate_download_source": "Valideeri",
|
||||
"remove_download_source": "Eemalda",
|
||||
"add_download_source": "Lisa allikas",
|
||||
"download_count_zero": "Allalaadimise valikuid pole",
|
||||
"download_count_one": "{{countFormatted}} allalaadimise valik",
|
||||
"download_count_other": "{{countFormatted}} allalaadimise valikut",
|
||||
"download_source_url": "Allalaadimise allika URL",
|
||||
"add_download_source_description": "Sisesta URL, mis sisaldab .json faili",
|
||||
"download_source_up_to_date": "Ajakohane",
|
||||
"download_source_errored": "Vigane",
|
||||
"sync_download_sources": "Sünkroniseeri allikad",
|
||||
"removed_download_source": "Allalaadimise allikas eemaldatud",
|
||||
"added_download_source": "Allalaadimise allikas lisatud",
|
||||
"download_sources_synced": "Kõik allalaadimise allikad on sünkroniseeritud",
|
||||
"insert_valid_json_url": "Sisesta kehtiv JSON url",
|
||||
"found_download_option_zero": "Allalaadimise valikuid ei leitud",
|
||||
"found_download_option_one": "Leitud {{countFormatted}} allalaadimise valik",
|
||||
"found_download_option_other": "Leitud {{countFormatted}} allalaadimise valikut",
|
||||
"import": "Impordi",
|
||||
"public": "Avalik",
|
||||
"private": "Privaatne",
|
||||
"friends_only": "Ainult sõpradele",
|
||||
"privacy": "Privaatsus",
|
||||
"profile_visibility": "Profiili nähtavus",
|
||||
"profile_visibility_description": "Vali, kes saavad näha sinu profiili ja kogu",
|
||||
"required_field": "See väli on kohustuslik",
|
||||
"source_already_exists": "See allikas on juba lisatud",
|
||||
"must_be_valid_url": "Allikas peab olema kehtiv URL",
|
||||
"blocked_users": "Blokeeritud kasutajad",
|
||||
"user_unblocked": "Kasutaja blokeering on eemaldatud",
|
||||
"enable_achievement_notifications": "Kui saavutus avatakse"
|
||||
"achievements_not_sync": "Sinu saavutused pole sünkroniseeritud",
|
||||
"manage_files_description": "Hallake, millised failid varundatakse ja taastatakse",
|
||||
"select_folder": "Vali kaust",
|
||||
"backup_from": "Varundamine kuupäevast {{date}}",
|
||||
"custom_backup_location_set": "Kohandatud varundamise asukoht määratud"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Aktiveeri Hydra",
|
||||
@@ -395,7 +312,7 @@
|
||||
"sending": "Saatmine",
|
||||
"friend_request_sent": "Sõbrakutse saadetud",
|
||||
"friends": "Sõbrad",
|
||||
"friends_list": "Sõbrade nimekiri",
|
||||
"friends_list": "Sõprade nimekiri",
|
||||
"user_not_found": "Kasutajat ei leitud",
|
||||
"block_user": "Blokeeri kasutaja",
|
||||
"add_friend": "Lisa sõbraks",
|
||||
@@ -435,7 +352,8 @@
|
||||
"profile_reported": "Profiilist teatatud",
|
||||
"your_friend_code": "Sinu sõbrakood:",
|
||||
"upload_banner": "Lae üles bänner",
|
||||
"uploading_banner": "Bänneri üleslaadimine…"
|
||||
"uploading_banner": "Bänneri üleslaadimine…",
|
||||
"background_image_updated": "Bänner uuendatud"
|
||||
},
|
||||
"achievement": {
|
||||
"achievement_unlocked": "Saavutus avatud",
|
||||
|
||||
@@ -57,14 +57,14 @@
|
||||
"remove_from_library": "Supprimer de la bibliothèque",
|
||||
"no_downloads": "Aucun téléchargement disponible",
|
||||
"next_suggestion": "Suggestion suivante",
|
||||
"play_time": "Joué pour {{montant}}",
|
||||
"play_time": "Joué pour {{amount}}",
|
||||
"install": "Installer",
|
||||
"play": "Jouer",
|
||||
"not_played_yet": "Vous n'avez pas encore joué à {{title}}",
|
||||
"close": "Fermer",
|
||||
"deleting": "Suppression du programme d'installation…",
|
||||
"playing_now": "Jeu en cours",
|
||||
"last_time_played": "Dernièrement joué {{période}}"
|
||||
"last_time_played": "Dernièrement joué {{period}}"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Activer Hydra",
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
"achievements": "Conquistas",
|
||||
"achievements_count": "Conquistas ({{unlockedCount}}/{{achievementsCount}})",
|
||||
"cloud_save": "Salvamento em nuvem",
|
||||
"cloud_save_description": "Matenha seu progresso na nuvem e continue de onde parou em qualquer dispositivo",
|
||||
"cloud_save_description": "Mantenha seu progresso na nuvem e continue de onde parou em qualquer dispositivo",
|
||||
"backups": "Backups",
|
||||
"install_backup": "Restaurar",
|
||||
"delete_backup": "Apagar",
|
||||
@@ -190,7 +190,7 @@
|
||||
"install": "Instalar",
|
||||
"download_in_progress": "Baixando agora",
|
||||
"queued_downloads": "Na fila",
|
||||
"downloads_completed": "Completo",
|
||||
"downloads_completed": "Concluído",
|
||||
"queued": "Na fila",
|
||||
"no_downloads_title": "Nada por aqui…",
|
||||
"no_downloads_description": "Você ainda não baixou nada pelo Hydra, mas nunca é tarde para começar.",
|
||||
|
||||
@@ -7,7 +7,7 @@ const { autoUpdater } = updater;
|
||||
const restartAndInstallUpdate = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
autoUpdater.removeAllListeners();
|
||||
if (app.isPackaged) {
|
||||
autoUpdater.quitAndInstall(true, true);
|
||||
autoUpdater.quitAndInstall(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ const createGameShortcut = async (
|
||||
const options = {
|
||||
filePath,
|
||||
name: removeSymbolsFromName(game.title),
|
||||
outputPath: app.getPath("desktop"),
|
||||
};
|
||||
|
||||
return createDesktopShortcut({
|
||||
|
||||
@@ -26,8 +26,9 @@ export const requestWebPage = async (url: string) => {
|
||||
return window.document;
|
||||
};
|
||||
|
||||
export const isPortableVersion = () =>
|
||||
process.env.PORTABLE_EXECUTABLE_FILE !== null;
|
||||
export const isPortableVersion = () => {
|
||||
return !!process.env.PORTABLE_EXECUTABLE_FILE;
|
||||
};
|
||||
|
||||
export const normalizePath = (str: string) =>
|
||||
path.posix.normalize(str).replace(/\\/g, "/");
|
||||
|
||||
@@ -219,7 +219,6 @@ export class AchievementWatcherManager {
|
||||
const games = await gameRepository.find({
|
||||
where: {
|
||||
isDeleted: false,
|
||||
winePrefixPath: Not(IsNull()),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -242,10 +241,18 @@ export class AchievementWatcherManager {
|
||||
? await this.preSearchAchievementsWindows()
|
||||
: await this.preSearchAchievementsWithWine();
|
||||
|
||||
const totalNewGamesWithAchievements = newAchievementsCount.filter(
|
||||
(achievements) => achievements
|
||||
).length;
|
||||
const totalNewAchievements = newAchievementsCount.reduce(
|
||||
(acc, val) => acc + val,
|
||||
0
|
||||
);
|
||||
|
||||
WindowManager.notificationWindow?.webContents.send(
|
||||
"on-combined-achievements-unlocked",
|
||||
newAchievementsCount.filter((achievements) => achievements).length,
|
||||
newAchievementsCount.reduce((acc, val) => acc + val, 0)
|
||||
totalNewGamesWithAchievements,
|
||||
totalNewAchievements
|
||||
);
|
||||
|
||||
this.hasFinishedMergingWithRemote = true;
|
||||
|
||||
@@ -79,11 +79,11 @@ const getPathFromCracker = (cracker: Cracker) => {
|
||||
return [
|
||||
{
|
||||
folderPath: path.join(publicDocuments, "Steam", "CODEX"),
|
||||
fileLocation: ["achievements.ini"],
|
||||
fileLocation: ["<objectId>", "achievements.ini"],
|
||||
},
|
||||
{
|
||||
folderPath: path.join(appData, "Steam", "CODEX"),
|
||||
fileLocation: ["achievements.ini"],
|
||||
fileLocation: ["<objectId>", "achievements.ini"],
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -92,7 +92,7 @@ const getPathFromCracker = (cracker: Cracker) => {
|
||||
return [
|
||||
{
|
||||
folderPath: path.join(publicDocuments, "Steam", "RUNE"),
|
||||
fileLocation: ["achievements.ini"],
|
||||
fileLocation: ["<objectId>", "achievements.ini"],
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -101,11 +101,11 @@ const getPathFromCracker = (cracker: Cracker) => {
|
||||
return [
|
||||
{
|
||||
folderPath: path.join(publicDocuments, "OnlineFix"),
|
||||
fileLocation: ["Stats", "Achievements.ini"],
|
||||
fileLocation: ["<objectId>", "Stats", "Achievements.ini"],
|
||||
},
|
||||
{
|
||||
folderPath: path.join(publicDocuments, "OnlineFix"),
|
||||
fileLocation: ["Achievements.ini"],
|
||||
fileLocation: ["<objectId>", "Achievements.ini"],
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -114,11 +114,11 @@ const getPathFromCracker = (cracker: Cracker) => {
|
||||
return [
|
||||
{
|
||||
folderPath: path.join(appData, "Goldberg SteamEmu Saves"),
|
||||
fileLocation: ["achievements.json"],
|
||||
fileLocation: ["<objectId>", "achievements.json"],
|
||||
},
|
||||
{
|
||||
folderPath: path.join(appData, "GSE Saves"),
|
||||
fileLocation: ["achievements.json"],
|
||||
fileLocation: ["<objectId>", "achievements.json"],
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -131,19 +131,19 @@ const getPathFromCracker = (cracker: Cracker) => {
|
||||
return [
|
||||
{
|
||||
folderPath: path.join(programData, "RLD!"),
|
||||
fileLocation: ["achievements.ini"],
|
||||
fileLocation: ["<objectId>", "achievements.ini"],
|
||||
},
|
||||
{
|
||||
folderPath: path.join(programData, "Steam", "Player"),
|
||||
fileLocation: ["stats", "achievements.ini"],
|
||||
fileLocation: ["<objectId>", "stats", "achievements.ini"],
|
||||
},
|
||||
{
|
||||
folderPath: path.join(programData, "Steam", "RLD!"),
|
||||
fileLocation: ["stats", "achievements.ini"],
|
||||
fileLocation: ["<objectId>", "stats", "achievements.ini"],
|
||||
},
|
||||
{
|
||||
folderPath: path.join(programData, "Steam", "dodi"),
|
||||
fileLocation: ["stats", "achievements.ini"],
|
||||
fileLocation: ["<objectId>", "stats", "achievements.ini"],
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -152,11 +152,16 @@ const getPathFromCracker = (cracker: Cracker) => {
|
||||
return [
|
||||
{
|
||||
folderPath: path.join(appData, "EMPRESS", "remote"),
|
||||
fileLocation: ["achievements.json"],
|
||||
fileLocation: ["<objectId>", "achievements.json"],
|
||||
},
|
||||
{
|
||||
folderPath: path.join(publicDocuments, "EMPRESS", "remote"),
|
||||
fileLocation: ["achievements.json"],
|
||||
folderPath: path.join(publicDocuments, "EMPRESS"),
|
||||
fileLocation: [
|
||||
"<objectId>",
|
||||
"remote",
|
||||
"<objectId>",
|
||||
"achievements.json",
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -165,15 +170,15 @@ const getPathFromCracker = (cracker: Cracker) => {
|
||||
return [
|
||||
{
|
||||
folderPath: path.join(documents, "SKIDROW"),
|
||||
fileLocation: ["SteamEmu", "UserStats", "achiev.ini"],
|
||||
fileLocation: ["<objectId>", "SteamEmu", "UserStats", "achiev.ini"],
|
||||
},
|
||||
{
|
||||
folderPath: path.join(documents, "Player"),
|
||||
fileLocation: ["SteamEmu", "UserStats", "achiev.ini"],
|
||||
fileLocation: ["<objectId>", "SteamEmu", "UserStats", "achiev.ini"],
|
||||
},
|
||||
{
|
||||
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 [
|
||||
{
|
||||
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 [
|
||||
{
|
||||
folderPath: path.join(appData, "SmartSteamEmu"),
|
||||
fileLocation: ["User", "Achievements.ini"],
|
||||
fileLocation: ["<objectId>", "User", "Achievements.ini"],
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -213,11 +218,11 @@ const getPathFromCracker = (cracker: Cracker) => {
|
||||
return [
|
||||
{
|
||||
folderPath: path.join(appData, "RLE"),
|
||||
fileLocation: ["achievements.ini"],
|
||||
fileLocation: ["<objectId>", "achievements.ini"],
|
||||
},
|
||||
{
|
||||
folderPath: path.join(appData, "RLE"),
|
||||
fileLocation: ["Achievements.ini"],
|
||||
fileLocation: ["<objectId>", "Achievements.ini"],
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -226,7 +231,7 @@ const getPathFromCracker = (cracker: Cracker) => {
|
||||
return [
|
||||
{
|
||||
folderPath: path.join(appData, ".1911"),
|
||||
fileLocation: ["achievement"],
|
||||
fileLocation: ["<objectId>", "achievement"],
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -253,8 +258,7 @@ export const findAchievementFiles = (game: Game) => {
|
||||
const filePath = path.join(
|
||||
game.winePrefixPath ?? "",
|
||||
folderPath,
|
||||
objectId,
|
||||
...fileLocation
|
||||
...mapFileLocationWithObjectId(fileLocation, objectId)
|
||||
);
|
||||
|
||||
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 = () => {
|
||||
const gameAchievementFiles = new Map<string, AchievementFile[]>();
|
||||
|
||||
@@ -315,7 +328,10 @@ export const findAllAchievementFiles = () => {
|
||||
const objectIds = fs.readdirSync(folderPath);
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import { HydraApi } from "../hydra-api";
|
||||
import { getUnlockedAchievements } from "@main/events/user/get-unlocked-achievements";
|
||||
import { Game } from "@main/entity";
|
||||
import { achievementsLogger } from "../logger";
|
||||
import { SubscriptionRequiredError } from "@shared";
|
||||
|
||||
const saveAchievementsOnLocal = async (
|
||||
objectId: string,
|
||||
@@ -119,14 +118,10 @@ export const mergeAchievements = async (
|
||||
const mergedLocalAchievements = unlockedAchievements.concat(newAchievements);
|
||||
|
||||
if (game.remoteId) {
|
||||
await HydraApi.put(
|
||||
"/profile/games/achievements",
|
||||
{
|
||||
id: game.remoteId,
|
||||
achievements: mergedLocalAchievements,
|
||||
},
|
||||
{ needsSubscription: true }
|
||||
)
|
||||
await HydraApi.put("/profile/games/achievements", {
|
||||
id: game.remoteId,
|
||||
achievements: mergedLocalAchievements,
|
||||
})
|
||||
.then((response) => {
|
||||
return saveAchievementsOnLocal(
|
||||
response.objectId,
|
||||
@@ -136,9 +131,7 @@ export const mergeAchievements = async (
|
||||
);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (!(err instanceof SubscriptionRequiredError)) {
|
||||
achievementsLogger.error(err);
|
||||
}
|
||||
achievementsLogger.error(err);
|
||||
|
||||
return saveAchievementsOnLocal(
|
||||
game.objectID,
|
||||
|
||||
@@ -65,6 +65,11 @@ export const parseAchievementFile = (
|
||||
return processCreamAPI(parsed);
|
||||
}
|
||||
|
||||
if (type === Cracker.empress) {
|
||||
const parsed = jsonParse(filePath);
|
||||
return processGoldberg(parsed);
|
||||
}
|
||||
|
||||
if (type === Cracker.razor1911) {
|
||||
return processRazor1911(filePath);
|
||||
}
|
||||
@@ -118,7 +123,7 @@ const jsonParse = (filePath: string) => {
|
||||
const processRazor1911 = (filePath: string): UnlockedAchievement[] => {
|
||||
try {
|
||||
const fileContent = readFileSync(filePath, "utf-8");
|
||||
achievementsLogger.log("processing file", filePath, fileContent);
|
||||
|
||||
const lines =
|
||||
fileContent.charCodeAt(0) === 0xfeff
|
||||
? fileContent.slice(1).split(/[\r\n]+/)
|
||||
@@ -136,7 +141,7 @@ const processRazor1911 = (filePath: string): UnlockedAchievement[] => {
|
||||
});
|
||||
}
|
||||
}
|
||||
achievementsLogger.log("processing file", achievements);
|
||||
|
||||
return achievements;
|
||||
} catch (err) {
|
||||
achievementsLogger.error(`Error processing ${filePath}`, err);
|
||||
|
||||
@@ -44,7 +44,7 @@ export class HydraApi {
|
||||
return this.userAuth.authToken !== "";
|
||||
}
|
||||
|
||||
private static hasCloudSubscription() {
|
||||
private static hasActiveSubscription() {
|
||||
return (
|
||||
this.userAuth.subscription?.expiresAt &&
|
||||
this.userAuth.subscription.expiresAt > new Date()
|
||||
@@ -279,7 +279,7 @@ export class HydraApi {
|
||||
}
|
||||
|
||||
if (needsSubscription) {
|
||||
if (!(await this.hasCloudSubscription())) {
|
||||
if (!(await this.hasActiveSubscription())) {
|
||||
throw new SubscriptionRequiredError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { UserFriendModalTab } from "@renderer/pages/shared-modals/user-friend-mo
|
||||
import SteamLogo from "@renderer/assets/steam-logo.svg?react";
|
||||
import { Avatar } from "../avatar/avatar";
|
||||
|
||||
const LONG_POLLING_INTERVAL = 60_000;
|
||||
const LONG_POLLING_INTERVAL = 120_000;
|
||||
|
||||
export function SidebarProfile() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -77,6 +77,8 @@ export function useDate() {
|
||||
},
|
||||
|
||||
formatDate: (date: number | Date | string): string => {
|
||||
if (isNaN(new Date(date).getDate())) return "N/A";
|
||||
|
||||
const locale = getDateLocale();
|
||||
return format(date, locale == enUS ? "MM/dd/yyyy" : "dd/MM/yyyy");
|
||||
},
|
||||
|
||||
@@ -128,12 +128,8 @@ export function useUserDetails() {
|
||||
const unblockUser = (userId: string) => window.electron.unblockUser(userId);
|
||||
|
||||
const hasActiveSubscription = useMemo(() => {
|
||||
if (!userDetails?.subscription?.plan) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
userDetails.subscription.expiresAt == null ||
|
||||
userDetails?.subscription?.expiresAt &&
|
||||
new Date(userDetails.subscription.expiresAt) > new Date()
|
||||
);
|
||||
}, [userDetails]);
|
||||
|
||||
@@ -167,7 +167,7 @@ export function GameDetailsContent() {
|
||||
>
|
||||
<Lottie
|
||||
animationData={cloudAnimation}
|
||||
loop
|
||||
loop={false}
|
||||
autoplay
|
||||
style={{ width: 26, position: "absolute", top: -3 }}
|
||||
/>
|
||||
|
||||
@@ -202,7 +202,7 @@ export default function GameDetails() {
|
||||
top: -28,
|
||||
left: -27,
|
||||
}}
|
||||
loop
|
||||
loop={false}
|
||||
/>
|
||||
</div>
|
||||
{t("next_suggestion")}
|
||||
|
||||
@@ -18,7 +18,7 @@ export const panel = recipe({
|
||||
position: "sticky",
|
||||
overflow: "hidden",
|
||||
top: "0",
|
||||
zIndex: "1",
|
||||
zIndex: "2",
|
||||
},
|
||||
variants: {
|
||||
stuck: {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { format } from "date-fns";
|
||||
import { useContext } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useDownload } from "@renderer/hooks";
|
||||
import { useDate, useDownload } from "@renderer/hooks";
|
||||
|
||||
import { HeroPanelActions } from "./hero-panel-actions";
|
||||
import * as styles from "./hero-panel.css";
|
||||
@@ -17,6 +16,8 @@ export interface HeroPanelProps {
|
||||
export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
|
||||
const { t } = useTranslation("game_details");
|
||||
|
||||
const { formatDate } = useDate();
|
||||
|
||||
const { game, repacks, gameColor } = useContext(gameDetailsContext);
|
||||
|
||||
const { lastPacket } = useDownload();
|
||||
@@ -29,7 +30,9 @@ export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
|
||||
const [latestRepack] = repacks;
|
||||
|
||||
if (latestRepack) {
|
||||
const lastUpdate = format(latestRepack.uploadDate!, "dd/MM/yyyy");
|
||||
const lastUpdate = latestRepack.uploadDate
|
||||
? formatDate(latestRepack.uploadDate!)
|
||||
: "";
|
||||
const repacksCount = repacks.length;
|
||||
|
||||
return (
|
||||
|
||||
@@ -126,7 +126,7 @@ export function Sidebar() {
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
zIndex: 2,
|
||||
zIndex: 1,
|
||||
inset: 0,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
|
||||
@@ -126,7 +126,7 @@ export default function Home() {
|
||||
<Lottie
|
||||
lottieRef={flameAnimationRef}
|
||||
animationData={flameAnimation}
|
||||
loop
|
||||
loop={false}
|
||||
autoplay={false}
|
||||
style={{
|
||||
width: 30,
|
||||
@@ -153,7 +153,7 @@ export default function Home() {
|
||||
<Lottie
|
||||
animationData={starsAnimation}
|
||||
style={{ width: 70, position: "absolute", top: -28, left: -27 }}
|
||||
loop={Boolean(randomGame)}
|
||||
loop={false}
|
||||
/>
|
||||
</div>
|
||||
{t("surprise_me")}
|
||||
@@ -165,7 +165,7 @@ export default function Home() {
|
||||
<div style={{ width: 24, height: 24, position: "relative" }}>
|
||||
<Lottie
|
||||
animationData={flameAnimation}
|
||||
loop
|
||||
loop={false}
|
||||
autoplay
|
||||
style={{
|
||||
width: 40,
|
||||
|
||||
Reference in New Issue
Block a user