mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-19 09:13:57 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydralauncher",
|
"name": "hydralauncher",
|
||||||
"version": "3.0.0",
|
"version": "3.0.3",
|
||||||
"description": "Hydra",
|
"description": "Hydra",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "Los Broxas",
|
"author": "Los Broxas",
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
"no_results": "Sin resultados encontrados",
|
"no_results": "Sin resultados encontrados",
|
||||||
"start_typing": "Empieza a escribir para buscar...",
|
"start_typing": "Empieza a escribir para buscar...",
|
||||||
"hot": "Popular Ahora",
|
"hot": "Popular Ahora",
|
||||||
"weekly": "📅 Mejores juegos de la semana"
|
"weekly": "📅 Mejores juegos de la semana",
|
||||||
|
"achievements": "🏆 Juegos para completar"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"catalogue": "Catálogo",
|
"catalogue": "Catálogo",
|
||||||
@@ -160,7 +161,11 @@
|
|||||||
"no_download_option_info": "Sin información disponible",
|
"no_download_option_info": "Sin información disponible",
|
||||||
"backup_deletion_failed": "La eliminación de la copia de seguridad falló",
|
"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",
|
"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": {
|
"activation": {
|
||||||
"title": "Activar Hydra",
|
"title": "Activar Hydra",
|
||||||
@@ -347,7 +352,8 @@
|
|||||||
"profile_reported": "Perfil reportado",
|
"profile_reported": "Perfil reportado",
|
||||||
"your_friend_code": "Tu código de amigo:",
|
"your_friend_code": "Tu código de amigo:",
|
||||||
"upload_banner": "Subir un banner",
|
"upload_banner": "Subir un banner",
|
||||||
"uploading_banner": "Subiendo banner…"
|
"uploading_banner": "Subiendo banner…",
|
||||||
|
"background_image_updated": "Imagen de fondo actualizada"
|
||||||
},
|
},
|
||||||
"achievement": {
|
"achievement": {
|
||||||
"achievement_unlocked": "Logro desbloqueado",
|
"achievement_unlocked": "Logro desbloqueado",
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
"no_results": "Tulemusi ei leitud",
|
"no_results": "Tulemusi ei leitud",
|
||||||
"start_typing": "Alusta otsimiseks kirjutamist...",
|
"start_typing": "Alusta otsimiseks kirjutamist...",
|
||||||
"hot": "Praegu kuum",
|
"hot": "Praegu kuum",
|
||||||
"weekly": "📅 Nädala top mängud"
|
"weekly": "📅 Nädala top mängud",
|
||||||
|
"achievements": "🏆 Mängud, mida läbida"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"catalogue": "Kataloog",
|
"catalogue": "Kataloog",
|
||||||
@@ -160,95 +161,11 @@
|
|||||||
"no_download_option_info": "Info pole saadaval",
|
"no_download_option_info": "Info pole saadaval",
|
||||||
"backup_deletion_failed": "Varunduse kustutamine ebaõnnestus",
|
"backup_deletion_failed": "Varunduse kustutamine ebaõnnestus",
|
||||||
"max_number_of_artifacts_reached": "Selle mängu varunduste maksimaalne arv on saavutatud",
|
"max_number_of_artifacts_reached": "Selle mängu varunduste maksimaalne arv on saavutatud",
|
||||||
"achievements_not_sync": "Sinu saavutused pole sünkroniseeritud"
|
"achievements_not_sync": "Sinu saavutused pole sünkroniseeritud",
|
||||||
},
|
"manage_files_description": "Hallake, millised failid varundatakse ja taastatakse",
|
||||||
"activation": {
|
"select_folder": "Vali kaust",
|
||||||
"title": "Aktiveeri Hydra",
|
"backup_from": "Varundamine kuupäevast {{date}}",
|
||||||
"installation_id": "Installatsiooni ID:",
|
"custom_backup_location_set": "Kohandatud varundamise asukoht määratud"
|
||||||
"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"
|
|
||||||
},
|
},
|
||||||
"activation": {
|
"activation": {
|
||||||
"title": "Aktiveeri Hydra",
|
"title": "Aktiveeri Hydra",
|
||||||
@@ -435,7 +352,8 @@
|
|||||||
"profile_reported": "Profiilist teatatud",
|
"profile_reported": "Profiilist teatatud",
|
||||||
"your_friend_code": "Sinu sõbrakood:",
|
"your_friend_code": "Sinu sõbrakood:",
|
||||||
"upload_banner": "Lae üles bänner",
|
"upload_banner": "Lae üles bänner",
|
||||||
"uploading_banner": "Bänneri üleslaadimine…"
|
"uploading_banner": "Bänneri üleslaadimine…",
|
||||||
|
"background_image_updated": "Bänner uuendatud"
|
||||||
},
|
},
|
||||||
"achievement": {
|
"achievement": {
|
||||||
"achievement_unlocked": "Saavutus avatud",
|
"achievement_unlocked": "Saavutus avatud",
|
||||||
|
|||||||
@@ -130,7 +130,7 @@
|
|||||||
"achievements": "Conquistas",
|
"achievements": "Conquistas",
|
||||||
"achievements_count": "Conquistas ({{unlockedCount}}/{{achievementsCount}})",
|
"achievements_count": "Conquistas ({{unlockedCount}}/{{achievementsCount}})",
|
||||||
"cloud_save": "Salvamento em nuvem",
|
"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",
|
"backups": "Backups",
|
||||||
"install_backup": "Restaurar",
|
"install_backup": "Restaurar",
|
||||||
"delete_backup": "Apagar",
|
"delete_backup": "Apagar",
|
||||||
@@ -190,7 +190,7 @@
|
|||||||
"install": "Instalar",
|
"install": "Instalar",
|
||||||
"download_in_progress": "Baixando agora",
|
"download_in_progress": "Baixando agora",
|
||||||
"queued_downloads": "Na fila",
|
"queued_downloads": "Na fila",
|
||||||
"downloads_completed": "Completo",
|
"downloads_completed": "Concluído",
|
||||||
"queued": "Na fila",
|
"queued": "Na fila",
|
||||||
"no_downloads_title": "Nada por aqui…",
|
"no_downloads_title": "Nada por aqui…",
|
||||||
"no_downloads_description": "Você ainda não baixou nada pelo Hydra, mas nunca é tarde para começar.",
|
"no_downloads_description": "Você ainda não baixou nada pelo Hydra, mas nunca é tarde para começar.",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const createGameShortcut = async (
|
|||||||
const options = {
|
const options = {
|
||||||
filePath,
|
filePath,
|
||||||
name: removeSymbolsFromName(game.title),
|
name: removeSymbolsFromName(game.title),
|
||||||
|
outputPath: app.getPath("desktop"),
|
||||||
};
|
};
|
||||||
|
|
||||||
return createDesktopShortcut({
|
return createDesktopShortcut({
|
||||||
|
|||||||
@@ -26,8 +26,9 @@ export const requestWebPage = async (url: string) => {
|
|||||||
return window.document;
|
return window.document;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isPortableVersion = () =>
|
export const isPortableVersion = () => {
|
||||||
process.env.PORTABLE_EXECUTABLE_FILE !== null;
|
return !!process.env.PORTABLE_EXECUTABLE_FILE;
|
||||||
|
};
|
||||||
|
|
||||||
export const normalizePath = (str: string) =>
|
export const normalizePath = (str: string) =>
|
||||||
path.posix.normalize(str).replace(/\\/g, "/");
|
path.posix.normalize(str).replace(/\\/g, "/");
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export class HydraApi {
|
|||||||
return this.userAuth.authToken !== "";
|
return this.userAuth.authToken !== "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static hasCloudSubscription() {
|
private static hasActiveSubscription() {
|
||||||
return (
|
return (
|
||||||
this.userAuth.subscription?.expiresAt &&
|
this.userAuth.subscription?.expiresAt &&
|
||||||
this.userAuth.subscription.expiresAt > new Date()
|
this.userAuth.subscription.expiresAt > new Date()
|
||||||
@@ -279,7 +279,7 @@ export class HydraApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needsSubscription) {
|
if (needsSubscription) {
|
||||||
if (!(await this.hasCloudSubscription())) {
|
if (!(await this.hasActiveSubscription())) {
|
||||||
throw new SubscriptionRequiredError();
|
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 SteamLogo from "@renderer/assets/steam-logo.svg?react";
|
||||||
import { Avatar } from "../avatar/avatar";
|
import { Avatar } from "../avatar/avatar";
|
||||||
|
|
||||||
const LONG_POLLING_INTERVAL = 60_000;
|
const LONG_POLLING_INTERVAL = 120_000;
|
||||||
|
|
||||||
export function SidebarProfile() {
|
export function SidebarProfile() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|||||||
@@ -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");
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -128,12 +128,8 @@ export function useUserDetails() {
|
|||||||
const unblockUser = (userId: string) => window.electron.unblockUser(userId);
|
const unblockUser = (userId: string) => window.electron.unblockUser(userId);
|
||||||
|
|
||||||
const hasActiveSubscription = useMemo(() => {
|
const hasActiveSubscription = useMemo(() => {
|
||||||
if (!userDetails?.subscription?.plan) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
userDetails.subscription.expiresAt == null ||
|
userDetails?.subscription?.expiresAt &&
|
||||||
new Date(userDetails.subscription.expiresAt) > new Date()
|
new Date(userDetails.subscription.expiresAt) > new Date()
|
||||||
);
|
);
|
||||||
}, [userDetails]);
|
}, [userDetails]);
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ export function GameDetailsContent() {
|
|||||||
>
|
>
|
||||||
<Lottie
|
<Lottie
|
||||||
animationData={cloudAnimation}
|
animationData={cloudAnimation}
|
||||||
loop
|
loop={false}
|
||||||
autoplay
|
autoplay
|
||||||
style={{ width: 26, position: "absolute", top: -3 }}
|
style={{ width: 26, position: "absolute", top: -3 }}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ export default function GameDetails() {
|
|||||||
top: -28,
|
top: -28,
|
||||||
left: -27,
|
left: -27,
|
||||||
}}
|
}}
|
||||||
loop
|
loop={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{t("next_suggestion")}
|
{t("next_suggestion")}
|
||||||
|
|||||||
@@ -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%",
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export default function Home() {
|
|||||||
<Lottie
|
<Lottie
|
||||||
lottieRef={flameAnimationRef}
|
lottieRef={flameAnimationRef}
|
||||||
animationData={flameAnimation}
|
animationData={flameAnimation}
|
||||||
loop
|
loop={false}
|
||||||
autoplay={false}
|
autoplay={false}
|
||||||
style={{
|
style={{
|
||||||
width: 30,
|
width: 30,
|
||||||
@@ -153,7 +153,7 @@ export default function Home() {
|
|||||||
<Lottie
|
<Lottie
|
||||||
animationData={starsAnimation}
|
animationData={starsAnimation}
|
||||||
style={{ width: 70, position: "absolute", top: -28, left: -27 }}
|
style={{ width: 70, position: "absolute", top: -28, left: -27 }}
|
||||||
loop={Boolean(randomGame)}
|
loop={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{t("surprise_me")}
|
{t("surprise_me")}
|
||||||
@@ -165,7 +165,7 @@ export default function Home() {
|
|||||||
<div style={{ width: 24, height: 24, position: "relative" }}>
|
<div style={{ width: 24, height: 24, position: "relative" }}>
|
||||||
<Lottie
|
<Lottie
|
||||||
animationData={flameAnimation}
|
animationData={flameAnimation}
|
||||||
loop
|
loop={false}
|
||||||
autoplay
|
autoplay
|
||||||
style={{
|
style={{
|
||||||
width: 40,
|
width: 40,
|
||||||
|
|||||||
Reference in New Issue
Block a user