Compare commits

...

351 Commits

Author SHA1 Message Date
Chubby Granny Chaser
16c45692da Merge pull request #982 from hydralauncher/feature/adding-flame-animation
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
chore: bump version
2024-09-17 16:53:06 +01:00
Chubby Granny Chaser
30aa3f5470 chore: bump version 2024-09-17 16:50:26 +01:00
Chubby Granny Chaser
ef16732c0a Merge pull request #981 from hydralauncher/feature/adding-flame-animation
feat: adding flame animation
2024-09-17 16:42:24 +01:00
Chubby Granny Chaser
84c472a3fa chore: bump version 2024-09-17 16:37:25 +01:00
Chubby Granny Chaser
2610f8b17b Merge branch 'feature/adding-flame-animation' of github.com:hydralauncher/hydra into feature/adding-flame-animation 2024-09-17 16:32:11 +01:00
Chubby Granny Chaser
705b12019f Merge branch 'main' of github.com:hydralauncher/hydra into feature/adding-flame-animation 2024-09-17 16:31:44 +01:00
Zamitto
39be8fdf53 Merge branch 'main' into feature/adding-flame-animation 2024-09-17 12:28:59 -03:00
Chubby Granny Chaser
cc7c3455fa feat: adding flame animation 2024-09-17 16:28:59 +01:00
Chubby Granny Chaser
d1f4bc7207 feat: adding flame animation 2024-09-17 16:26:12 +01:00
Chubby Granny Chaser
aa4ca25653 feat: adding flame animation 2024-09-17 16:25:19 +01:00
Zamitto
405ea0a824 fix: playtime count 2024-09-17 11:10:44 -03:00
Zamitto
43bc0cb08f Merge pull request #977 from hydralauncher/feat/polling-from-sync
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
feat: polling from sync
2024-09-16 16:46:29 -03:00
Zamitto
3c200aa2eb fix: rename variable 2024-09-16 14:48:15 -03:00
Zamitto
cc5967814b fix: adjust when calling /games/download 2024-09-16 14:07:00 -03:00
Zamitto
ec16efed2f feat: create use details functions 2024-09-16 14:03:54 -03:00
Zamitto
09d0e5b4ef Merge pull request #976 from hydralauncher/feat/update-typing-to-match-get-me
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
feat: update typing to match get me
2024-09-16 13:36:26 -03:00
Zamitto
5b18aba2b8 feat: omit username and tokens in logs 2024-09-16 13:09:50 -03:00
Zamitto
192008c76c fix: not showing repacks and stats if game details request fails 2024-09-16 12:56:29 -03:00
Zamitto
1de3a9836c feat: update typing to match get me endpoint 2024-09-16 11:22:41 -03:00
Zamitto
ee02811aea chore: remove space in version string
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
2024-09-15 12:21:41 -03:00
Zamitto
c21ebe1ce2 fix: database migration 2024-09-15 12:09:51 -03:00
Zamitto
214e39adda chore: version
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
2024-09-15 01:17:16 -03:00
Zamitto
8258127616 chore: version 2024-09-15 01:07:46 -03:00
Zamitto
f9906bfe95 fix: message and migration 2024-09-15 01:00:44 -03:00
Chubby Granny Chaser
ff91284a91 chore: fix version
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
2024-09-15 03:46:38 +01:00
Chubby Granny Chaser
b4f99418e9 chore: changing auth url 2024-09-15 03:39:13 +01:00
Zamitto
3d132de860 Merge pull request #950 from hydralauncher/feature/profile-redesign
Feature/profile redesign
2024-09-14 17:57:41 -03:00
Zamitto
8af91c1375 fix: adjust string 2024-09-14 17:56:07 -03:00
Zamitto
449ca2adc3 fix: text wrap game running 2024-09-14 17:47:42 -03:00
Chubby Granny Chaser
1ef7e58bb5 fix: adding translations for spanish 2024-09-14 21:41:52 +01:00
Chubby Granny Chaser
5757ec8b40 Merge branch 'feature/profile-redesign' of github.com:hydralauncher/hydra into feature/profile-redesign 2024-09-14 21:41:00 +01:00
Chubby Granny Chaser
aa8b685108 fix: adding translations for spanish 2024-09-14 21:40:34 +01:00
Zamitto
09b0bfe832 Merge pull request #954 from Lianela/main
typing and error added - es translation
2024-09-14 17:05:13 -03:00
Zamitto
d92a9ab410 Merge pull request #960 from hydralauncher/feat/message-warning-hydra-close
feat: message warning hydra closing while downloading
2024-09-14 17:01:01 -03:00
Chubby Granny Chaser
5432ef311a Merge branch 'feature/profile-redesign' of github.com:hydralauncher/hydra into feature/profile-redesign 2024-09-14 21:00:02 +01:00
Chubby Granny Chaser
9621702e19 feat: adding user report 2024-09-14 20:58:12 +01:00
Zamitto
19cb7c0627 feat: comment HLTB 2024-09-14 16:57:39 -03:00
Chubby Granny Chaser
91cfb42ff5 feat: adding user report 2024-09-14 20:56:32 +01:00
Chubby Granny Chaser
06d5ed4491 feat: adding user report 2024-09-14 20:56:20 +01:00
Chubby Granny Chaser
8799378bf2 feat: adding user report 2024-09-14 20:55:00 +01:00
Zamitto
b0876b93ed feat: message warning hydra close 2024-09-14 16:51:09 -03:00
Zamitto
f2211ec6ce Merge pull request #959 from hydralauncher/feat/executable-and-play-button
feat: executable and play button
2024-09-14 15:42:04 -03:00
Zamitto
e3fa401667 feat: show download button if game has no executable selected 2024-09-14 15:32:27 -03:00
Zamitto
939133fcc3 feat: block executable 1:N game 2024-09-14 15:29:52 -03:00
Chubby Granny Chaser
fcc24d6b94 fix: best grid constraint 2024-09-14 18:16:07 +01:00
Chubby Granny Chaser
00528b6ca1 Merge branch 'feature/profile-redesign' of github.com:hydralauncher/hydra into feature/profile-redesign 2024-09-14 18:11:52 +01:00
Chubby Granny Chaser
806b086c7f feat: fixing download error for gofile 2024-09-14 18:11:23 +01:00
Chubby Granny Chaser
268ac3d5a4 feat: fixing download error for gofile 2024-09-14 18:10:38 +01:00
Chubby Granny Chaser
b122489b34 feat: fixing download error for gofile 2024-09-14 18:10:02 +01:00
Zamitto
8037101a2b Merge pull request #958 from hydralauncher/fix/ensure-i18n-matches-language-in-db
fix: ensure renderer i18n matches db language
2024-09-14 13:58:59 -03:00
Zamitto
15e86338d9 feat: add game logo back again 2024-09-14 13:21:32 -03:00
Zamitto
92e43b90a2 feat: add game logo back again 2024-09-14 13:16:31 -03:00
Zamitto
378ad74b43 fix: ensure renderer i18n matches db language 2024-09-14 12:32:04 -03:00
Chubby Granny Chaser
702b141f7b Merge branch 'feature/profile-redesign' of github.com:hydralauncher/hydra into feature/profile-redesign 2024-09-14 02:34:33 +01:00
Zamitto
dbb7cac308 Merge pull request #956 from hydralauncher/fix/language
fix: languages
2024-09-13 22:34:14 -03:00
Chubby Granny Chaser
14b204b1c3 Merge branch 'feature/profile-redesign' of github.com:hydralauncher/hydra into feature/profile-redesign 2024-09-14 02:33:40 +01:00
Zamitto
88a94bbb82 fix: languages 2024-09-13 22:32:51 -03:00
Chubby Granny Chaser
d15ca88714 fix: using local state for game running 2024-09-14 02:27:58 +01:00
Zamitto
f21c6848c6 Merge pull request #955 from hydralauncher/feat/accumulate-ticks-when-update-playtime-fails
feat: accumulate ticks when update playtime fails
2024-09-13 22:15:55 -03:00
Zamitto
608a53e8df feat: accumulate ticks when request to update playtime fails 2024-09-13 21:02:59 -03:00
Zamitto
f439b6809c feat: add needsAuth: false to /games/download 2024-09-13 20:30:54 -03:00
Chubby Granny Chaser
7846ecbd4f Merge pull request #953 from hydralauncher/fix/add-language-migration
feat: add language migration
2024-09-14 00:19:38 +01:00
Chubby Granny Chaser
6368bd66d3 feat: adding image processing 2024-09-14 00:10:12 +01:00
Chubby Granny Chaser
6e543fecb4 feat: adding image processing 2024-09-14 00:09:34 +01:00
Lianela
3d5b41821c typing and error added 2024-09-13 17:00:24 -06:00
Chubby Granny Chaser
2b2b5afd79 feat: moving visibility update to settings 2024-09-13 23:56:27 +01:00
Zamitto
2ea6285744 feat: add language migration 2024-09-13 19:45:37 -03:00
Zamitto
863a3b7d1f Merge pull request #952 from hydralauncher/feat/process-profile-image
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
feat: process profile image
2024-09-13 17:32:35 -03:00
Zamitto
a03ac26b80 feat: add error toast 2024-09-13 17:30:18 -03:00
Zamitto
e8515e1990 feat: process profile image 2024-09-13 17:25:33 -03:00
Zamitto
797a09f583 feat: process profile image 2024-09-13 17:18:03 -03:00
Zamitto
a295003ad4 Merge pull request #951 from hydralauncher/fix/knex-not-creating-database-directory
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
fix: ensure database directory exists before running knex
2024-09-13 11:43:40 -03:00
Zamitto
123812ad81 fix: ensure database directory exists before running knex 2024-09-13 10:52:48 -03:00
Chubby Granny Chaser
383578bca2 chore: sync with main 2024-09-13 01:04:38 +01:00
Chubby Granny Chaser
02ca506079 Merge pull request #949 from hydralauncher/feat/get-trending-games-from-api
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
feat: get trending games from api
2024-09-13 01:02:17 +01:00
Chubby Granny Chaser
d9a7672113 feat: profile redesign 2024-09-13 01:02:01 +01:00
Zamitto
b0bc754ffc feat: catch error 2024-09-12 20:56:10 -03:00
Zamitto
813a46bf3e feat: refactor 2024-09-12 20:52:54 -03:00
Zamitto
3199e56661 feat: get trending games from api 2024-09-12 20:50:40 -03:00
Chubby Granny Chaser
8f0003298f Merge branch 'main' of github.com:hydralauncher/hydra 2024-09-13 00:04:07 +01:00
Chubby Granny Chaser
2304e19558 feat: returning with edit profile modal 2024-09-13 00:03:58 +01:00
Zamitto
87cacdf16c Merge pull request #948 from hydralauncher/feat/search-games-from-api
feat: search games from api
2024-09-12 19:57:53 -03:00
Zamitto
ad3c2df024 feat: refactor 2024-09-12 19:42:44 -03:00
Zamitto
b0164b6948 feat: simplify conditional 2024-09-12 13:15:24 -03:00
Zamitto
0fce444df8 feat: abort controller and i18n 2024-09-12 13:12:42 -03:00
Zamitto
5c363810c8 feat: search updates 2024-09-12 12:43:55 -03:00
Zamitto
b8c8e534b4 feat: refactor 2024-09-12 11:35:14 -03:00
Zamitto
2e82c29f4c feat: searching from api 2024-09-12 11:12:52 -03:00
Zamitto
262e95e4db Merge pull request #939 from GearCzech/main
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
Czech translation
2024-09-12 01:19:39 -03:00
Chubby Granny Chaser
ada7b452a0 feat: initial profile refactor 2024-09-12 00:53:16 +01:00
Gear
4da116150f little polishing changes 2024-09-10 23:05:15 +02:00
Gear
d2c7780b13 translation fix 2024-09-10 16:49:34 +02:00
Gear
43ca4764bb fixed prettier error 2024-09-10 16:03:57 +02:00
Gear
53e5124521 Added czech readme 2024-09-10 15:56:11 +02:00
Gear
83cba67c24 added empty space 2024-09-10 11:15:44 +02:00
Gear
ba3001bc88 Added czech translation to index.ts 2024-09-10 11:09:29 +02:00
Gear
6caa9825bd Czech translation
Adds czech translation
2024-09-10 10:48:08 +02:00
Zamitto
59fd5f0347 Merge pull request #929 from thaleseuflauzino/main
Some checks failed
Release / build (ubuntu-latest) (push) Has been cancelled
Release / build (windows-latest) (push) Has been cancelled
Add italian README and patterns of README translations (and solve #471)
2024-09-10 00:12:16 -03:00
Thales Euflauzino
69c39fe6c4 fix: spaces after "[" 2024-09-09 20:57:44 -03:00
Thales Euflauzino
46ee202b7c fix: spaces after "[" 2024-09-09 20:57:21 -03:00
Thales Euflauzino
57a43c6358 fix: spaces after "[" 2024-09-09 20:57:01 -03:00
Thales Euflauzino
c311cc3fb6 fix: spaces after "[" 2024-09-09 20:56:12 -03:00
Thales Euflauzino
f6f304ef6f fix: spaces after "[" 2024-09-09 20:55:48 -03:00
Thales Euflauzino
ffdbf755f9 fix: spaces after "[" 2024-09-09 20:55:22 -03:00
Thales Euflauzino
ae9111975b fix: spaces after "[" 2024-09-09 20:54:00 -03:00
Thales Euflauzino
692e38cd7e fix: spaces after "[" 2024-09-09 20:53:16 -03:00
Thales Euflauzino
5733f8ae6b Merge branch 'main' into main 2024-09-09 20:44:55 -03:00
Thales Euflauzino
4dd80bfc6b 📚 docs: update readme's 2024-09-09 20:40:16 -03:00
Zamitto
68051c76af Merge pull request #936 from Squomsh/german-translations
Some checks are pending
Release / build (ubuntu-latest) (push) Waiting to run
Release / build (windows-latest) (push) Waiting to run
feat: Locale - Add German translations
2024-09-09 20:03:06 -03:00
Squomsh (Squomsh (Squomsh))
0a3921bacf Merge branch 'hydralauncher:main' into german-translations 2024-09-09 19:43:27 +00:00
Squomsh
7e848a1869 feat: added German localisation
added translation entry src/locales/index.ts; added translation src/locales/de/translation.json
2024-09-09 21:39:28 +02:00
Squomsh
5b7c9bf9c1 feat: added links to German README 2024-09-09 18:03:33 +02:00
Squomsh
cc7738cf1b feat: translation - added German README 2024-09-09 18:02:08 +02:00
Zamitto
276a6d5c65 Merge branch 'main' into main 2024-09-09 12:51:47 -03:00
Zamitto
5b7bdbf4e7 Merge pull request #932 from Lianela/main
undo friendship string added
2024-09-09 12:48:09 -03:00
Lianela
1aa741f661 fixed mistake 2024-09-08 20:47:55 -06:00
Lianela
b87f1c1248 fixed mistake 2024-09-08 20:47:02 -06:00
Lianela
5e5585e7eb Merge branch 'hydralauncher:main' into main 2024-09-08 20:44:53 -06:00
Zamitto
07913713fc Merge pull request #823 from damnkrat/main
Support building for arch based distributions
2024-09-08 22:32:39 -03:00
Zamitto
1b9f763012 Merge branch 'main' into main 2024-09-08 22:22:39 -03:00
Zamitto
ebb17ea829 Merge pull request #930 from hydralauncher/feat/refactor-languages
feat: refactor languages
2024-09-08 22:21:01 -03:00
Lianela
987cd2bf99 undo friendship string added 2024-09-07 00:32:12 -06:00
Zamitto
dc4aa0f608 feat: remove dev db 2024-09-05 21:06:49 -03:00
Zamitto
40f4bbc124 feat: refactor languages 2024-09-04 23:43:52 -03:00
Thales Euflauzino
5c5c9faf00 📚 docs: add patterns of translations 2024-09-04 17:16:17 -03:00
Thales Euflauzino
a05cd87542 📚 docs: add patterns of translations 2024-09-04 17:16:11 -03:00
Thales Euflauzino
6e60ab3c90 📚 docs: add patterns of translations 2024-09-04 17:16:04 -03:00
Thales Euflauzino
0617dfbb62 📚 docs: add patterns of translations 2024-09-04 17:15:56 -03:00
Thales Euflauzino
26f1839752 📚 docs: add patterns of translations 2024-09-04 17:15:44 -03:00
Thales Euflauzino
0abdeca93a 📚 docs: add patterns of translations 2024-09-04 17:15:38 -03:00
Thales Euflauzino
8c874fc5a1 📚 docs: add patterns of translations 2024-09-04 17:15:31 -03:00
Thales Euflauzino
da0894e2b8 📚 docs: add patterns of translations 2024-09-04 17:15:23 -03:00
Thales Euflauzino
8f9eec124d 📚 docs: add text of italian readme 2024-09-04 17:12:58 -03:00
Thales Euflauzino
44dab630f1 📚 docs: create italian README 2024-09-04 17:08:46 -03:00
Zamitto
02907d84e1 Merge pull request #918 from thaleseuflauzino/main
Adding translation for Portuguese-Portugal and Portuguese-Brazil
2024-09-04 16:59:54 -03:00
Zamitto
6464cea576 Delete src/locales/br/translation.json 2024-09-04 16:40:31 -03:00
Thales Euflauzino
74d3aa10cb Merge branch 'main' of https://github.com/hydralauncher/hydra 2024-09-02 13:27:08 -03:00
Zamitto
6273ca1376 Merge pull request #920 from thaleseuflauzino/patch-4
docs: Create SECURITY.md
2024-09-02 13:22:46 -03:00
Zamitto
453378020b Merge branch 'main' into patch-4 2024-09-02 13:11:38 -03:00
Zamitto
ff43f827b9 Merge pull request #903 from hydralauncher/feat/remove-synchronize-typeorm
feat: use knex migrations
2024-09-02 13:09:38 -03:00
Zamitto
6b3d3c8f5b Merge branch 'main' into feat/remove-synchronize-typeorm 2024-09-02 12:58:08 -03:00
Zamitto
2dcfccedce Merge pull request #917 from hydralauncher/feat/add-undo-friendship-confirm-modal
feat: add undo friendship confirm modal and fixes text overflows
2024-09-02 12:57:49 -03:00
Zamitto
88737cf80d feat: refactor knex promises 2024-09-02 12:54:55 -03:00
Zamitto
158b878883 feat: catch hltb error 2024-08-31 14:31:18 -03:00
Zamitto
567d9f540d feat: refactor 2024-08-30 14:13:10 -03:00
Zamitto
7659c9094b Merge branch 'main' into feat/add-undo-friendship-confirm-modal 2024-08-30 10:15:31 -03:00
Zamitto
d4d94dfc4c feat: use function expression for component 2024-08-30 10:13:18 -03:00
Zamitto
40d2b36a20 feat: remove unnecessary react fragment 2024-08-30 10:06:10 -03:00
Thales Euflauzino
70f120a62c delete: removing unused translation json 2024-08-28 04:42:10 -03:00
Thales Euflauzino
f4cf33d369 feat: add a new library in setting general 2024-08-27 14:41:24 -03:00
Thales Euflauzino
15c21164e4 chore: updating translation location 2024-08-27 14:40:16 -03:00
Thales Euflauzino
dab12cb316 feat: add a new library for support differents type of "PT" translation 2024-08-27 14:40:01 -03:00
Thales Euflauzino
d2d00516a8 chore: updating translation location 2024-08-27 14:38:07 -03:00
Thales Euflauzino
f2c4598351 chore: update suggestion translation
Co-authored-by: Agnaldo Junior <agnaldo.junior01@gmail.com>
2024-08-27 14:34:31 -03:00
Thales Euflauzino
9e6484ad11 chore: update suggestion translation
Co-authored-by: Agnaldo Junior <agnaldo.junior01@gmail.com>
2024-08-27 14:34:27 -03:00
Thales Euflauzino
629f204714 chore: update suggestion translation
Co-authored-by: Agnaldo Junior <agnaldo.junior01@gmail.com>
2024-08-27 14:34:21 -03:00
Thales Euflauzino
7c08668a03 chore: update suggestion translation
Co-authored-by: Agnaldo Junior <agnaldo.junior01@gmail.com>
2024-08-27 14:34:14 -03:00
Thales Euflauzino
563e56e54d chore: update suggestion translation
Co-authored-by: Agnaldo Junior <agnaldo.junior01@gmail.com>
2024-08-27 14:34:04 -03:00
Thales Euflauzino
e4917c1a07 docs: Create SECURITY.md 2024-08-27 03:01:10 -03:00
Thales Euflauzino
a809c84151 fix: run prettier 2024-08-27 02:58:00 -03:00
Thales Euflauzino
f4e4f7a61c fix: error in index.ts, was ptbr 2024-08-27 02:45:38 -03:00
Thales Euflauzino
5b493d8050 fix: change name "ptbr" to "br" for prettier 2024-08-27 02:43:12 -03:00
Thales Euflauzino
e6f296aba3 fix: gap between lines and missing "," 2024-08-27 02:36:27 -03:00
Thales Euflauzino
0b54a33084 chore: Update index.ts 2024-08-27 02:31:39 -03:00
Thales Euflauzino
75bc386048 feat: add pt(portugal) translate 2024-08-27 02:29:51 -03:00
Thales Euflauzino
7867b7c838 chore: add ptbr translate 2024-08-27 02:00:15 -03:00
Thales Euflauzino
84c6951d30 chore: rename pt to ptbr to add portugal language to hydra 2024-08-27 01:59:41 -03:00
Zamitto
89399a6da4 feat: write migrations 2024-08-26 16:36:01 -03:00
Zamitto
cc10186ec3 feat: add trycatch for handleDeepLinkPath 2024-08-26 15:24:32 -03:00
Zamitto
c553697df9 Update bug_report.yml 2024-08-26 15:16:48 -03:00
Zamitto
0bedb7c9b7 fix: header overflow text 2024-08-26 14:14:51 -03:00
Zamitto
3293320926 fix: sidebar profile layout 2024-08-26 13:21:21 -03:00
Zamitto
9e02504e14 fix: profile display name 2024-08-26 12:45:52 -03:00
Zamitto
fb60c91c83 feat: add undo friendship confirm modal 2024-08-26 12:23:32 -03:00
Zamitto
a608e11be2 Merge pull request #915 from Lianela/main
removed strings / added new translations (es)
2024-08-25 23:01:59 -03:00
Zamitto
c0babcfdca Merge branch 'main' into main 2024-08-25 20:42:22 -03:00
Zamitto
31adb77d9e Merge pull request #907 from xxDRV/patch-12
Updated RU to fit new features
2024-08-25 20:38:28 -03:00
Zamitto
c6e313f5ad Merge branch 'main' into main 2024-08-25 20:37:49 -03:00
Lianela
f9979a38da removed strings / added new translations (es) 2024-08-25 16:58:48 -06:00
Zamitto
5fcca9888d Revert "feat: write migrations"
This reverts commit 81aa25fa52.
2024-08-23 00:07:50 -03:00
Zamitto
81aa25fa52 feat: write migrations 2024-08-22 23:56:46 -03:00
Antecess
1542b346af Updated RU to fit new features 2024-08-23 01:22:28 +05:00
Zamitto
52069f7036 feat: set typeorm synchrozine to false 2024-08-20 21:27:34 -03:00
Zamitto
cc9d254a32 Merge pull request #902 from hydralauncher/feat/show-current-game-user-profile
feat: show current game user profile
2024-08-19 21:44:08 -03:00
Zamitto
54516c1a5a Merge branch 'main' into feat/show-current-game-user-profile 2024-08-19 21:36:15 -03:00
Zamitto
c72fa08d40 feat: undo api logs comment 2024-08-19 21:36:07 -03:00
Zamitto
7e7c4dae1d Merge pull request #837 from hydralauncher/feat/logs-python-process-errors
feat: logs python process
2024-08-19 21:35:14 -03:00
Zamitto
24689cad5a Merge branch 'main' into feat/logs-python-process-errors 2024-08-19 21:24:38 -03:00
Chubby Granny Chaser
aaf20b2aac Merge pull request #901 from hydralauncher/fix/http-downloads-duplicate
feat: reducing http downloads duplicate
2024-08-20 01:22:47 +01:00
Zamitto
ac6ff04e69 chore: lint warnings 2024-08-19 21:04:51 -03:00
Zamitto
bab041b5f7 feat: call update game endpoint on process watcher at each 120 ticks 2024-08-19 20:53:34 -03:00
Zamitto
856a4c706a feat: remove unused vars from ci 2024-08-19 20:30:51 -03:00
Zamitto
629b005ea4 feat: show current game on other users profile 2024-08-19 20:02:13 -03:00
Zamitto
bde396c7db feat: update endpoints 2024-08-19 19:55:40 -03:00
Zamitto
5369274c6e feat: remove synchronize true from typeorm 2024-08-19 12:42:50 -03:00
Zamitto
5101684154 feat: add property 2024-08-19 12:32:06 -03:00
Chubby Granny Chaser
c1bd1d30d7 feat: adding support to qiwi 2024-08-18 16:21:05 +01:00
Chubby Granny Chaser
6c24a523b7 feat: adding support to qiwi 2024-08-18 16:19:06 +01:00
Chubby Granny Chaser
76d3fead66 fix: adding default to uris 2024-08-18 03:38:12 +01:00
Chubby Granny Chaser
73a12488cd fix: adding default to uris 2024-08-18 03:06:35 +01:00
Chubby Granny Chaser
c76ef630e1 fix: removing menu 2024-08-18 02:45:05 +01:00
Chubby Granny Chaser
7a9247278d fix: removing menu 2024-08-18 02:31:20 +01:00
Chubby Granny Chaser
42ea35441c fix: showing multiple download options 2024-08-18 01:39:50 +01:00
Chubby Granny Chaser
c218070463 Merge branch 'fix/http-downloads-duplicate' of github.com:hydralauncher/hydra into fix/http-downloads-duplicate 2024-08-17 21:54:19 +01:00
Chubby Granny Chaser
dd7229dc59 feat: reducing http downloads duplicate 2024-08-17 21:51:03 +01:00
Chubby Granny Chaser
f7027f4319 Merge branch 'main' into fix/http-downloads-duplicate 2024-08-17 21:46:05 +01:00
Chubby Granny Chaser
bbe68a0aff feat: reducing http downloads duplicate 2024-08-17 21:43:56 +01:00
Chubby Granny Chaser
3a3b7b908c Merge pull request #887 from hydralauncher/hyd-332-friendsblocks-list-pagination-and-set-privacy-settings
set profile visibility and list blocked users
2024-08-17 05:12:06 +01:00
Zamitto
3febe9b418 feat: adjust edit profile modal 2024-08-16 16:18:45 -03:00
Zamitto
e31655a96e feat: infinite scroll block list 2024-08-16 15:56:03 -03:00
Zamitto
515a08a3a6 feat: infinite scroll friend list 2024-08-16 15:43:29 -03:00
Zamitto
b1e263814c feat: i18n toast friend code copied 2024-08-16 13:28:20 -03:00
Zamitto
f3276dd8fe feat: add texts for no invites, no friends and no blocks 2024-08-16 13:23:38 -03:00
Zamitto
d809317d62 Merge branch 'main' into hyd-332-friendsblocks-list-pagination-and-set-privacy-settings 2024-08-16 12:16:29 -03:00
Zamitto
5cb57bd5b3 feat: show friend code 2024-08-16 12:16:22 -03:00
Zamitto
b4c260233f chore: lint 2024-08-15 18:52:52 -03:00
Zamitto
d098887c51 Merge pull request #894 from Lianela/main
Update ES translation.json
2024-08-15 18:28:52 -03:00
Zamitto
baf4eafa68 Merge branch 'main' into main 2024-08-15 17:31:51 -03:00
Zamitto
a99058805b Merge branch 'main' into hyd-332-friendsblocks-list-pagination-and-set-privacy-settings
# Conflicts:
#	src/renderer/src/pages/user/user-content.tsx
2024-08-15 17:28:48 -03:00
Zamitto
80123d67e1 feat: adjust ui 2024-08-15 17:27:17 -03:00
Chubby Granny Chaser
c549d53492 Merge pull request #807 from hydralauncher/feature/adding-generic-http-downloads
feat: adding generic http downloads
2024-08-15 20:53:36 +01:00
Chubby Granny Chaser
68b361e605 feat: fixing real debrid download 2024-08-15 20:46:21 +01:00
Zamitto
fbe3c1973a feat: list blocked users 2024-08-14 19:46:01 -03:00
Zamitto
7e6b9ca825 feat: conditional to show user content section based on visibility 2024-08-14 19:13:44 -03:00
Zamitto
fffea84ef7 Merge branch 'main' into feature/adding-generic-http-downloads 2024-08-14 11:58:30 -03:00
Lianela
51e86819c1 Update ES translation.json 2024-08-11 15:29:05 -06:00
Zamitto
6806787ca0 feat: set profile visibility 2024-08-06 23:18:27 -03:00
Zamitto
1dcf746fa4 Merge branch 'main' into feat/logs-python-process-errors 2024-08-06 11:22:47 -03:00
Zamitto
42a78802a6 Merge pull request #885 from BayuWilanda4L/fix/videos-wont-load
fix: video won't load due to Content Security Policy restrictions
2024-08-06 09:42:01 -03:00
Bayu Wilanda
e44c15e9e1 fix: video won't load due to Content Security Policy restrictions 2024-08-06 11:11:05 +07:00
Zamitto
4a149aa62d feat: remove aria2 (again) 2024-08-05 20:47:37 -03:00
Zamitto
f3f78248ef fix: start another download after finishing one 2024-08-05 19:49:10 -03:00
Zamitto
4b7a0ff402 feat: setting folder name 2024-08-05 19:48:43 -03:00
Zamitto
4d60317475 fix: passing complete download path to setSavePath 2024-08-05 19:39:55 -03:00
Zamitto
19b1d29713 fix: reset downloadingGame and torrentId on cancelDownload 2024-08-05 19:15:46 -03:00
Zamitto
fab248de99 fix: duplicate download with real debrid 2024-08-05 18:55:35 -03:00
Zamitto
e1ef8a9193 feat: pass headers correctly to downloadURL 2024-08-05 15:21:05 -03:00
Zamitto
070340b34f Merge branch 'main' into feature/adding-generic-http-downloads 2024-08-05 11:35:31 -03:00
Zamitto
55635878a5 Merge pull request #875 from BayuWilanda4L/feature/translation-update
feat: improve Indonesian translations for better readability and naturalness
2024-08-05 11:20:04 -03:00
Zamitto
e851600814 Format id/translation.json 2024-08-05 11:07:44 -03:00
Zamitto
c1454bfbe9 Merge branch 'main' into feature/translation-update 2024-08-05 11:05:03 -03:00
Zamitto
f75378a271 Merge pull request #861 from aniol/patch-2
Update Catalan translation.json
2024-08-05 11:04:42 -03:00
Zamitto
77280788a7 Format ca/translation.json 2024-08-05 10:44:55 -03:00
Zamitto
49ed55abfc Merge branch 'main' into patch-2 2024-08-05 10:42:18 -03:00
Zamitto
78dfda0c93 Merge pull request #855 from hydralauncher/hyd-271-rework-the-profile-page-to-allow-other-users-to-see-your
feat: friends part 2
2024-08-05 10:41:41 -03:00
Chubby Granny Chaser
a6d291a741 Merge branch 'main' into hyd-271-rework-the-profile-page-to-allow-other-users-to-see-your 2024-08-05 13:39:36 +01:00
Bayu Wilanda
ba8201daba feat: improve Indonesian translations for better readability and naturalness 2024-08-03 09:50:22 +07:00
Zamitto
ae45547c17 Merge pull request #863 from Lianela/main
Friend strings translated (ES)
2024-08-02 22:44:46 -03:00
Zamitto
d9c140b2ab feat: implement undo friendship on friendlist modal 2024-07-30 16:42:48 -03:00
Zamitto
f631cd3013 feat: make getUserFriends throws exception 2024-07-30 15:55:51 -03:00
Zamitto
4dcd97bce8 feat: update return types 2024-07-30 15:15:50 -03:00
Zamitto
c38422f635 feat: add generic to HydraApi calls 2024-07-30 15:15:34 -03:00
Zamitto
d60242a62c feat: code review 2024-07-29 20:11:20 -03:00
Aniol
b188e93343 Update Catalan translation.json
Update Catalan translation.json.
2024-07-27 13:05:15 +02:00
Zamitto
c0198b49ef Merge branch 'main' into feature/adding-generic-http-downloads 2024-07-26 13:38:48 -03:00
Zamitto
10d7e0e8aa Merge branch 'main' into hyd-271-rework-the-profile-page-to-allow-other-users-to-see-your 2024-07-26 11:35:45 -03:00
Zamitto
15269f3908 feat: show confirm modal for block action 2024-07-26 11:30:01 -03:00
Zamitto
00c46bc981 feat: implement undo friendship 2024-07-25 23:03:11 -03:00
Zamitto
edf920fed3 feat: block and unblock events 2024-07-25 20:08:53 -03:00
Zamitto
304aa011ad feat: action buttons on user profile page 2024-07-25 19:27:03 -03:00
Zamitto
102299e42f feat: remove tab title 2024-07-25 19:12:34 -03:00
Zamitto
94bd691209 fet: show only received friends request on sidebar icon 2024-07-25 19:12:14 -03:00
Zamitto
abdc9f6e98 feat: show friends component 2024-07-23 21:24:27 -03:00
Zamitto
a196b91cb9 feat: pass userId to modal 2024-07-23 20:31:50 -03:00
Zamitto
010f07373d feat: add getUserFriends event 2024-07-23 18:37:19 -03:00
Zamitto
380143c780 feat: correctly get own friends 2024-07-23 15:30:04 -03:00
damnkrat
4d001cca36 Merge branch 'main' into main 2024-07-23 21:07:00 +03:00
Lianela
11c29355e3 Friend strings translated (ES) 2024-07-22 19:38:34 -06:00
Zamitto
e642bf71b1 feat: rename functions 2024-07-21 20:49:54 -03:00
Zamitto
6b8f2e6978 feat: add friends button on user profile 2024-07-21 20:07:15 -03:00
Zamitto
27610aa8cf fix: edit profile modal avatar 2024-07-21 17:00:36 -03:00
Zamitto
91862cd2fe Update README.md 2024-07-21 16:45:44 -03:00
Zamitto
d350aa950d feat: get friends event 2024-07-21 16:35:02 -03:00
Zamitto
909e288bec feat: background on profile page for other users profile 2024-07-21 15:45:31 -03:00
Zamitto
6c5d3793ae Merge pull request #838 from Ezequiel9898/patch-2
Update translation.json
2024-07-21 15:42:56 -03:00
Zamitto
43c5fdbab9 Merge branch 'main' into patch-2 2024-07-21 15:37:02 -03:00
Zamitto
3952f106fc Merge pull request #814 from hydralauncher/hyd-270-create-a-section-under-library-games-in-profile-page-for
feat: add friends
2024-07-20 19:11:39 -03:00
Zamitto
8a1931f75c feat: use new electron version to get download speed 2024-07-20 16:52:27 -03:00
Ezequiel Neri Ferreira
2e386528a4 update 2024-07-18 00:27:10 -03:00
Ezequiel Neri Ferreira
b6727be3cf update 2024-07-18 00:01:31 -03:00
Ezequiel Neri Ferreira
05f9703c25 Update translation.json 2024-07-17 23:06:29 -03:00
Zamitto
3d8c63bc40 feat: truncate game title on tray 2024-07-17 21:21:19 -03:00
Zamitto
8c0c3e617b feat: add logs for python process 2024-07-17 21:05:06 -03:00
Zamitto
929be48495 feat: remove nullables 2024-07-17 19:03:46 -03:00
Zamitto
8c67dda84e feat: refactor 2024-07-17 19:03:46 -03:00
Zamitto
6d277cd1d8 feat: adjust ui 2024-07-17 19:03:45 -03:00
Zamitto
d4902a5ab1 feat: use empty list 2024-07-17 19:03:45 -03:00
Zamitto
004ccd0db5 feat: add comment 2024-07-17 19:03:45 -03:00
Zamitto
e55dc20c7d feat: open modal in correct tab 2024-07-17 19:03:45 -03:00
Zamitto
7f3d7a56c3 feat: create tabs on user friend modal 2024-07-17 19:03:45 -03:00
Zamitto
d0406282ce feat: organize code 2024-07-17 19:03:44 -03:00
Zamitto
c6e99f8599 feat: update i18n and texts 2024-07-17 19:03:44 -03:00
Zamitto
5aec973882 feat: show friend request modal when click on sidebar 2024-07-17 19:03:44 -03:00
Zamitto
49fd34c3c0 feat: moving friends request button to sidebar 2024-07-17 19:03:44 -03:00
Zamitto
198a283752 feat: add logs 2024-07-17 19:03:43 -03:00
Zamitto
46b12f2bc2 simplify code 2024-07-17 19:03:43 -03:00
Zamitto
cb93fbcb72 feat: add buttons gap 2024-07-17 19:03:43 -03:00
Zamitto
22b66149b3 fix: buttons on friend request item 2024-07-17 19:03:43 -03:00
Zamitto
6f70b529a2 feat: refactor hydra api 2024-07-17 19:03:43 -03:00
Zamitto
a81b016500 feat: sending friend request 2024-07-17 19:03:42 -03:00
Zamitto
ef0699dbea feat: refactor friends requests 2024-07-17 19:03:42 -03:00
Zamitto
b3f87d5662 feat: get friends requests from api 2024-07-17 19:03:42 -03:00
Zamitto
6ff48605da feat: show friends from response 2024-07-17 19:03:42 -03:00
Zamitto
0f0a1e98a3 feat: ui adjustments 2024-07-17 19:03:41 -03:00
Zamitto
007da03837 feat: finish ui for modal showing pending requests 2024-07-17 19:03:41 -03:00
Zamitto
6cc8e8f5fe feat: pending requests on modal 2024-07-17 19:03:41 -03:00
Zamitto
6ccbff0160 feat: creating friends section 2024-07-17 19:03:41 -03:00
Zamitto
202f5b60de Merge pull request #800 from Ezequiel9898/patch-1
Update portuguese translation
2024-07-17 18:52:56 -03:00
Zamitto
b9558907ec Merge pull request #806 from Lianela/main
Improvements in ES translation
2024-07-17 18:50:01 -03:00
Lianela
8a01352eab updated es-translation.json
Reverted changes on accuracy
2024-07-17 12:56:24 -06:00
damnkrat
35879c7afe Merge branch 'main' into main 2024-07-16 16:38:37 +03:00
dannkunt
1366ca0087 Also build arch at release 2024-07-16 16:38:06 +03:00
Zamitto
e008478e53 Merge branch 'main' into main 2024-07-15 22:46:58 -03:00
Zamitto
6a195eb566 Merge pull request #832 from xxDRV/patch-11
Updated RU to fit new features
2024-07-15 22:44:57 -03:00
Zamitto
781e0f4102 feat: update headers 2024-07-15 22:29:34 -03:00
Zamitto
b5b7fe31ae use webContents.downloadURL to download http 2024-07-15 17:55:50 -03:00
Antecess
e2b089e0f8 Updated RU to fit new features 2024-07-15 13:47:09 +05:00
dannkunt
b5af73cec4 Do not install bsdtar on windows 2024-07-14 14:11:35 +03:00
dannkunt
d8e4eef107 Fix build workflows 2024-07-14 04:03:35 +03:00
damnkrat
2d09ea18a7 Support building for arch linux 2024-07-12 23:09:55 +03:00
Chubby Granny Chaser
6c6fff71fe feat: adding generic http downloads 2024-07-09 19:24:02 +01:00
Lianela
a9b92f3fc1 accuracy fixed 2024-07-09 10:35:19 -06:00
Ezequiel Neri Ferreira
6822ed8447 Update translation.json 2024-07-07 23:42:12 -03:00
Lianela
5683a0ba49 variation of one line
changed in a different variation a translation
2024-07-06 16:53:02 -06:00
Lianela
18488490c1 fixed some strings
changed some words and translations to a new one making some things easier to understand
2024-07-06 16:44:36 -06:00
Lianela
2ee3fdc223 updated es-translation.json
added new string
fixed one string
2024-07-05 12:40:16 -06:00
Chubby Granny Chaser
6fce60f9f7 ci: increasing version 2024-07-05 17:10:04 +01:00
Chubby Granny Chaser
c8aa9fd681 Merge branch 'main' of github.com:hydralauncher/hydra 2024-07-05 17:09:43 +01:00
Chubby Granny Chaser
0f12dfae88 ci: increasing version 2024-07-05 17:08:27 +01:00
Zamitto
be48306ca2 Merge pull request #768 from hydralauncher/hyd-229-improve-visibility-of-update-message
feat: add color to update icon and notify when update is ready to install
2024-07-05 12:45:53 -03:00
Zamitto
ab81e21341 feat: update font size 2024-07-05 12:38:53 -03:00
Zamitto
b7f94102da feat: add version string to notification 2024-07-05 12:30:34 -03:00
Zamitto
9e7b27afe6 feat: undo change 2024-07-05 12:22:13 -03:00
Zamitto
c24523e8e6 feat: update i18n 2024-07-05 12:18:37 -03:00
Zamitto
b58330ed35 feat: undo change 2024-07-05 12:13:47 -03:00
Zamitto
dde40f39e9 Merge branch 'main' into hyd-229-improve-visibility-of-update-message 2024-07-05 12:10:30 -03:00
Zamitto
d2b3017de9 feat: show notification only when update is ready to install 2024-07-05 12:10:19 -03:00
Chubby Granny Chaser
64f4dad7cc Merge pull request #783 from hydralauncher/fix/replacing-underscore-with-whitespace
feat: replacing underscore with whitespace
2024-07-05 16:04:49 +01:00
Chubby Granny Chaser
154d211b21 Merge branch 'main' into fix/replacing-underscore-with-whitespace 2024-07-05 15:54:42 +01:00
Chubby Granny Chaser
7905ef6c10 feat: replacing underscore with whitespace 2024-07-05 15:53:32 +01:00
Zamitto
b09f2c055f feat: creating notification for update available 2024-07-04 20:00:20 -03:00
Chubby Granny Chaser
2c5b3b4ffa Merge pull request #778 from hydralauncher/feature/adding-directors-cut-filter
Feature/adding directors cut filter
2024-07-04 23:41:07 +01:00
Chubby Granny Chaser
fdefc0c165 feat: adding directors cut filter 2024-07-04 23:14:09 +01:00
Chubby Granny Chaser
47ca2535e3 feat: adding directors cut filter 2024-07-04 23:12:20 +01:00
Chubby Granny Chaser
f706836a43 feat: adding directors cut filter 2024-07-04 23:11:21 +01:00
Chubby Granny Chaser
d8158bb80e Merge branch 'main' of github.com:hydralauncher/hydra into fix/adding-sorting-to-repacks-modal 2024-07-04 18:36:15 +01:00
Chubby Granny Chaser
4e422bdf91 feat: migrating download source validation to worker thread 2024-07-04 18:35:47 +01:00
Zamitto
4be3db8007 feat: add error logs 2024-07-03 18:03:11 -03:00
Zamitto
29b64237ed feat: remove old vbs file 2024-07-03 17:57:03 -03:00
Zamitto
d481164bf3 feat: add color to update icon and notify 2024-07-03 17:44:04 -03:00
Chubby Granny Chaser
dc94a886e6 fix: sorting repacks modal 2024-07-02 17:34:46 +01:00
226 changed files with 10214 additions and 2849 deletions

View File

@@ -1,3 +1,4 @@
MAIN_VITE_STEAMGRIDDB_API_KEY=YOUR_API_KEY
MAIN_VITE_API_URL=API_URL
MAIN_VITE_SENTRY_DSN=YOUR_SENTRY_DSN
SENTRY_AUTH_TOKEN=

View File

@@ -2,3 +2,4 @@ node_modules
dist
out
.gitignore
migration.stub

View File

@@ -27,7 +27,7 @@ body:
label: Expected behavior
description: A clear and concise description of what you expected to happen.
validations:
required: true
required: false
- type: textarea
id: screenshots
attributes:
@@ -56,3 +56,12 @@ body:
description: Please provide any additional information and context about your problem.
validations:
required: false
- type: checkboxes
id: terms
attributes:
label: Before opening this Issue
options:
- label: I have searched the issues of this repository and believe that this is not a duplicate.
required: true
- label: I am aware that Hydra team does not offer any support or help regarding the downloaded games.
required: true

View File

@@ -35,10 +35,11 @@ jobs:
- name: Build Linux
if: matrix.os == 'ubuntu-latest'
run: yarn build:linux
run: |
sudo apt-get update
sudo apt-get install -y libarchive-tools
yarn build:linux
env:
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
MAIN_VITE_API_URL: ${{ vars.MAIN_VITE_API_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
MAIN_VITE_SENTRY_DSN: ${{ vars.MAIN_VITE_SENTRY_DSN }}
@@ -48,8 +49,6 @@ jobs:
if: matrix.os == 'windows-latest'
run: yarn build:win
env:
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
MAIN_VITE_API_URL: ${{ vars.MAIN_VITE_API_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
MAIN_VITE_SENTRY_DSN: ${{ vars.MAIN_VITE_SENTRY_DSN }}
@@ -69,3 +68,4 @@ jobs:
dist/*.tar.gz
dist/*.yml
dist/*.blockmap
dist/*.pacman

View File

@@ -37,10 +37,11 @@ jobs:
- name: Build Linux
if: matrix.os == 'ubuntu-latest'
run: yarn build:linux
run: |
sudo apt-get update
sudo apt-get install -y libarchive-tools
yarn build:linux
env:
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
MAIN_VITE_API_URL: ${{ vars.MAIN_VITE_API_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
MAIN_VITE_SENTRY_DSN: ${{ vars.MAIN_VITE_SENTRY_DSN }}
@@ -50,8 +51,6 @@ jobs:
if: matrix.os == 'windows-latest'
run: yarn build:win
env:
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
MAIN_VITE_API_URL: ${{ vars.MAIN_VITE_API_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
MAIN_VITE_SENTRY_DSN: ${{ vars.MAIN_VITE_SENTRY_DSN }}
@@ -72,5 +71,6 @@ jobs:
dist/*.tar.gz
dist/*.yml
dist/*.blockmap
dist/*.pacman
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

1
.gitignore vendored
View File

@@ -1,7 +1,6 @@
.vscode
node_modules
hydra-download-manager/
aria2/
fastlist.exe
__pycache__
dist

View File

@@ -5,7 +5,7 @@
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra - гэта гульнявы лаўнчар з уласным убудаваным кліентам BitTorrent і самастойным scraper`ам для рэпакаў.</strong>
</p>
@@ -20,6 +20,9 @@
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Hydra Catalogue](./docs/screenshot.png)
@@ -27,11 +30,12 @@
## Змест
- [Змест](#змест)
- [Апісанне](#апісанне)
- [Асаблівасці](#асаблівасці)
- [Усталёўка](#усталёўка)
- [Уклад](#contributing)
- [Далучайцеся да нашага Telegram](#join-our-telegram)
- [Уклад](#-уклад)
- [Далучайцеся да нашага Telegram](#-далучайцеся-да-нашага-telegram)
- [Форк і кланаванне рэпазітара](#форк-і-кланаванне-рэпазітара)
- [Спосабы ўнесці свой уклад](#спосабы-ўнесці-свой-уклад)
- [Структура праекту](#структура-праекту)
@@ -47,6 +51,7 @@
- [Зборка кліента BitTorrent](#зборка-кліента-bittorrent)
- [Зборка прыкладання Electron](#зборка-прыкладання-electron)
- [Удзельнікі](#удзельнікі)
- [Ліцэнзія](#ліцэнзія)
## Апісанне

185
README.cs.md Normal file
View File

@@ -0,0 +1,185 @@
<br>
<div align="center">
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra je herní launcher s vlastním vestavěným Bittorrent klientem.</strong>
</p>
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Hydra Katalog](./docs/screenshot.png)
</div>
## Seznam obsahu
- [Seznam obsahu](#seznam-obsahu)
- [O projektu](#o-projektu)
- [Funkce](#funkce)
- [Instalace](#instalace)
- [Přispívání](#přispívání)
- [Připoj se na náš telegram](#připoj-se-na-náš-telegram)
- [Vytvořte fork a naklonujte svůj repozitář](#vytvořte-fork-a-naklonujte-svůj-repozitář)
- [Způsoby jak můžete přispět](#způsoby-jak-můžete-přispět)
- [Struktura projektu](#struktura-projektu)
- [Sestavení ze zdroje](#sestavení-ze-zdroje)
- [Instalace Node.js](#instalace-nodejs)
- [Instalace Yarn](#instalace-yarn)
- [Instalace Požadavků pro Node.js](#instalace-požadavků-pro-nodejs)
- [Instalace Pythonu 3.9](#instalace-pythonu-39)
- [Instalace Požadavků pro Python](#instalace-požadavků-pro-python)
- [Proměnné prostředí](#proměnné-prostředí)
- [Spuštění](#spuštění)
- [Sestavení](#sestavení)
- [Sestavení bittorrent klientu](#sestavení-bittorrent-klientu)
- [Sestavení electron aplikace](#sestavení-electron-aplikace)
- [Přispěvatelé](#přispěvatelé)
- [Licence](#licence)
## O projektu
**Hydra** je **Herní Launcher** s jeho vlastním vestavěným **BitTorrent Klientem**.
<br>
Launcher je napsán v TypeScriptu (Electron) a Pythonu, který má na starosti torrentovací systém za pomocí knihovny libtorrent.
## Funkce
- Vlastní vestavěný BitTorrent klient
- How Long To Beat (HLTB) integrace na stránce hry
- Vlastní místa pro uložení hry
- Windows a Linux podpora
- Časté aktualizace
- A další ...
## Instalace
Následuj kroky:
1. Stáhni nejnovější verzi Hydry ze stránky [Vydání](https://github.com/hydralauncher/hydra/releases/latest).
- Stáhni .exe, pokud chceš instalovat Hydru na Windows.
- Stáhni .deb nebo .rpm nebo .zip, pokud chceš instalovat Hydru na Linux. (záleží na tvé Linux distribuci)
2. Spusť stažený instalační soubor.
3. Užívej Hydru!
## <a name="contributing"> Přispívání
### <a name="join-our-telegram"></a> Připoj se na náš telegram
Vedeme diskuzi v našem [Telegramovém](https://t.me/hydralauncher) kanálu.
### Vytvořte fork a naklonujte svůj repozitář
1. Vytvoř fork repozitáře [(klikni sem pro vytvoření forku)](https://github.com/hydralauncher/hydra/fork)
2. Naklonuj kód forku `git clone https://github.com/tvoje_jméno/hydra`
3. Vytvoř nové odvětví (branch)
4. Odešli svoje změny
5. Odešli nový Pull Request
### Způsoby jak můžete přispět
- Překládání: Chceme, aby Hydra byla co nejvíce dostupná. Můžete přispět novým jazykem, nebo úpravou současného!
- Kód: Hydra je postavena na Typescriptu, Electronu a trochou Pythonu. Pokud chceš přispět, připoj se na náš [Telegram](https://t.me/hydralauncher)!
### Struktura projektu
- torrent-client: Používáme libtorrent, Pythonovou knihovnu, pro správu torrent stahování
- src/renderer: uživatelské rozhraní aplikace (UI)
- src/main: celá logika projektu
## Sestavení ze zdroje
### Instalace Node.js
Ujistěte se, že máte Node.js nainstalován na svém zařízení. Pokud ne, stáhněte ho, a nainstalujte z [nodejs.org](https://nodejs.org/).
### Instalace Yarn
Yarn je balíčkový správce pro Node.js. Pokud ještě nemáte yarn, můžete ho stáhnout za pomoci pokynů na [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/).
### Instalace Požadavků pro Node.js
Jděte do složky projektu, otevřte v ní konzole a nainstalujte požadavky pro Node pomocí Yarn:
```bash
cd hydra
yarn
```
### Instalace Pythonu 3.9
Ujistěte se, že máte Python 3.9 nainstalován na svém zařízení. Můžete ho stáhnout z [python.org](https://www.python.org/downloads/release/python-3913/).
### Instalace Požadavků pro Python
Nainstalujte požadavky pro Python za pomoci pip:
```bash
pip install -r requirements.txt
```
## Proměnné prostředí
Budete potřebovat SteamGridDB API klíč, abyste mohli načítat ikony u her.
Jakmile ho máte, můžete zkopírovat, nebo přejmenovat `.env.example` soubor na `.env` a dát ho do `STEAMGRIDDB_API_KEY`.
## Spuštění
Jakmile máte vše nastaveno, můžete spustit jak Electron proces tak bittorrent client:
```bash
yarn dev
```
## Sestavení
### Sestavení bittorrent klientu
Sestavit bittorrent klient můžete pomocí:
```bash
python torrent-client/setup.py build
```
### Sestavení electron aplikace
Sestavit Electron aplikaci můžete pomocí následujících kroků:
Na Windows:
```bash
yarn build:win
```
Na Linux:
```bash
yarn build:linux
```
## Přispěvatelé
<a href="https://github.com/hydralauncher/hydra/graphs/contributors">
<img src="https://contrib.rocks/image?repo=hydralauncher/hydra" />
</a>
## Licence
Hydra je licencována pod [MIT Licencí](LICENSE).

183
README.de.md Normal file
View File

@@ -0,0 +1,183 @@
<br>
<div align="center">
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra ist ein Launcher für Spiele mit einem eigenen eingebetteten BitTorrent-Client.</strong>
</p>
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Hydra Katalog](./docs/screenshot.png)
</div>
## Inhaltsverzeichnis
- [Über Hydra](#über-hydra)
- [Eigenschaften](#eigenschaften)
- [Installation](#installation)
- [Mitwirken](#mitwirken)
- [Tritt uns auf Telegram bei](#tritt-uns-auf-telegram-bei)
- [Forke und klone dein Repo](#forke-und-klone-dein-repo)
- [Wie du mitwirken kannst](#wie-du-mitwirken-kannst)
- [Projektstruktur](#projektstruktur)
- [Den Quellcode kompilieren](#den-quellcode-kompilieren)
- [Installiere Node.js](#installiere-nodejs)
- [Installiere Yarn](#installiere-yarn)
- [Installiere Node-Abhängigkeiten](#installiere-node-abhängigkeiten)
- [Installiere Python 3.9](#installiere-python-39)
- [Installiere Python-Abhängigkeiten](#installiere-python-abhängigkeiten)
- [Umgebungsvariablen](#umgebungsvariablen)
- [Ausführung](#ausführung)
- [Kompilation](#kompilation)
- [Kompiliere den BitTorrent-Client](#kompiliere-den-bittorrent-client)
- [Kompiliere die Electron-Applikation](#kompiliere-die-electron-applikation)
- [Mitwirkende](#mitwirkende)
## Über Hydra
**Hydra** ist ein **Launcher für Spiele** mit einem eigenen eingebetteten **BitTorrent-Client**.
<br>
Der Launcher ist in TypeScript (Electron) und Python, womit das Torrentingsystem durch Einsatz von libtorrent geregelt ist, geschrieben.
## Eigenschaften
- Eigener eingebetteter BitTorrent-Client
- How Long to Beat (HLTB) Integration auf der Spielseite
- Anpassbarkeit des Downloadverzeichnisses
- Unterstützung von Windows und Linux
- Regelmäßig aktualisiert
- Und mehr ...
## Installation
Die folgenden Schritte beschreiben den Installationsprozess:
1. Lade die neueste Version von Hydra von der [Releases](https://github.com/hydralauncher/hydra/releases/latest) Seite herunter.
- Für die Installation von Hydra auf Windows, wähle die .exe Datei.
- Für die Installation von Hydra auf Linux, wähle die .deb, .rpm oder .zip Datei. (Abhängig von deiner Linux-Distribution)
2. Führe die heruntergeladene Datei aus.
3. Genieße Hydra!
## Mitwirken
### Tritt uns auf Telegram bei
Wir konzentrieren unsere Diskussionen in unserem [Telegram](https://t.me/hydralauncher) Kanal.
### Forke und klone dein Repo
1. Forke das Repo [(Klicke hier, um direkt zu forken)](https://github.com/hydralauncher/hydra/fork)
2. Klone deinen geforketen Code `git clone https://github.com/dein_nutzername/hydra`
3. Erstelle einen neuen Branch
4. Pushe deine Commits
5. Stelle eine neue Pull-Anfrage
### Wie du mitwirken kannst
- Übersetzung: Wir wollen Hydra so vielen Menschen wie möglich zugänglich machen. Gerne kannst du uns helfen neue Sprachen zu übersetzen oder für Hydra bereits verfügbare Sprachen zu aktualisieren und verbessern.
- Code: Hydra ist mit TypeScript, Electron und etwas Python gebaut. Wenn du mitwirken möchtest, tritt unserem [Telegram](https://t.me/hydralauncher) bei!
### Projektstruktur
- torrent-client: Wir verwenden die Python-Bibliothek libtorrent zur Verwaltung von Torrent-Downloads.
- src/renderer: die UI der Applikation.
- src/main: sämtliche Logik liegt hier.
## Den Quellcode kompilieren
### Installiere Node.js
Stelle sicher, dass du Node.js auf deinem System installiert hast. Falls nicht, installiere es von [nodejs.org](https://nodejs.org/).
### Installiere Yarn
Yarn ist ein Packetmanager für Node.js. Sollte er dir fehlen, installiere ihn mithilfe der Anleitung auf [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/).
### Installiere Node-Abhängigkeiten
Navigiere zum Projektverzeichnis und installiere die Node-Abhängigkeiten mit Yarn:
```bash
cd hydra
yarn
```
### Installiere Python 3.9
Stelle sicher, dass du Python 3.9 auf deinem System installiert hast. Ansonsten kannst du es von [python.org](https://www.python.org/downloads/release/python-3913/) herunterladen und installieren.
### Installiere Python-Abhängigkeiten
Installiere die benötigten Python-Abhängigkeiten mit pip:
```bash
pip install -r requirements.txt
```
## Umgebungsvariablen
Du wirst einen SteamGridDB API Schlüssel benötigen, um die Spielicons bei Installation abzurufen.
Sobald du einen hast, kannst du die .env.example Datei zu .env kopieren oder umbenennen und den Schlüssel bei STEAMGRIDDB_API_KEY einfügen.
## Ausführung
Sobald du alles eingerichtet hast, kannst du den folgenden Befehl nutzen, um sowohl den Electron-Prozess als auch den BitTorrent-Client zu starten:
```bash
yarn dev
```
## Kompilation
### Kompiliere den BitTorrent-Client
Kompiliere den BitTorrent-Client mit folgendem Befehl:
```bash
python torrent-client/setup.py build
```
### Kompiliere die Electron-Applikation
Kompiliere die Electron-Applikation mit folgendem Befehl:
Auf Windows:
```bash
yarn build:win
```
Auf Linux:
```bash
yarn build:linux
```
## Mitwirkende
<a href="https://github.com/hydralauncher/hydra/graphs/contributors">
<img src="https://contrib.rocks/image?repo=hydralauncher/hydra" />
</a>
## Lizenz
Hydra ist unter der [MIT Lizenz](LICENSE) lizensiert.

View File

@@ -5,7 +5,7 @@
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra es un launcher de juegos con su propio cliente de bittorrent y gestor propio de repacks.</strong>
</p>
@@ -13,13 +13,16 @@
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Hydra Catalogue](./docs/screenshot.png)
@@ -27,11 +30,12 @@
## Tabla de Contenidos
- [Tabla de Contenidos](#tabla-de-contenidos)
- [Acerca de](#acerca-de)
- [Características](#caracteristicas)
- [Instalación](#Instalacion)
- [Contribuir](#contribuir)
- [Únete a nuestro Telegram](#unete-a-nuestro-telegram)
- [Caracteristicas](#caracteristicas)
- [Instalacion](#instalacion)
- [Contribuir](#-contribuir)
- [Unete a nuestro Telegram](#-unete-a-nuestro-telegram)
- [Haz un fork y clona tu repositorio](#haz-un-fork-y-clona-tu-repositorio)
- [Maneras en las que puedes contribuir](#maneras-en-las-que-puedes-contribuir)
- [Estructura del proyecto](#estructura-del-proyecto)
@@ -40,13 +44,14 @@
- [Instalar Yarn](#instalar-yarn)
- [Instalar Dependencias de Node](#instalar-dependencias-de-node)
- [Instalar Python 3.9](#instalar-python-39)
- [Instalar Dependencias de Python](#Instalar-dependencias-de-python)
- [Instalar Dependencias de Python](#instalar-dependencias-de-python)
- [Variables del Entorno](#variables-del-entorno)
- [Ejecución](#ejecucion)
- [Compilación](#compilacion)
- [Ejecucion](#ejecucion)
- [Compilacion](#compilacion)
- [Compilar el cliente de bittorrent](#compilar-el-cliente-de-bittorrent)
- [Compilar la aplicación Electron](#compilar-la-aplicacion-electron)
- [Compilar la aplicacion Electron](#compilar-la-aplicacion-electron)
- [Colaboradores](#colaboradores)
- [Licencia](#licencia)
## Acerca de

View File

@@ -5,7 +5,7 @@
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra est un lanceur de jeux avec son propre client bittorrent intégré et un scraper de repack auto-géré.</strong>
</p>
@@ -13,13 +13,16 @@
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Catalogue Hydra](./docs/screenshot.png)
@@ -27,6 +30,7 @@
## Table des Matières
- [Table des Matières](#table-des-matières)
- [À propos](#à-propos)
- [Fonctionnalités](#fonctionnalités)
- [Installation](#installation)
@@ -47,6 +51,7 @@
- [Compiler le client bittorrent](#compiler-le-client-bittorrent)
- [Compiler l'application Electron](#compiler-lapplication-electron)
- [Contributeurs](#contributeurs)
- [License](#license)
## À propos

188
README.it.md Normal file
View File

@@ -0,0 +1,188 @@
<br>
<div align="center">
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra è un game launcher con il proprio client bittorrent e autogestore di repacks.</strong>
</p>
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Hydra Catalogue](./docs/screenshot.png)
</div>
## Table of Contents
- [Table of Contents](#table-of-contents)
- [A proposito](#a-proposito)
- [Caratteristiche](#caratteristiche)
- [Installazione](#installazione)
- [Contribuire](#-contribuire)
- [Unisciti su Telegram](#-unisciti-su-telegram)
- [Forka e Clona la repository](#forka-e-clona-la-repository)
- [Modi in cui contribuire](#modi-in-cui-contribuire)
- [Struttura del Progetto](#struttura-del-progetto)
- [Compilazione](#compilazione)
- [Installa Node.js](#installa-nodejs)
- [Installa Yarn](#installa-yarn)
- [Installa le dipendenze Node](#installa-le-dipendenze-node)
- [Installa Python 3.9](#installa-python-39)
- [Installa le Dipendenze Python](#installa-le-dipendenze-python)
- [Variabili d'ambiente](#variabili-dambiente)
- [Esecuzione](#esecuzione)
- [Compilazione](#compilazione-1)
- [Compila il bittorrent](#compila-il-bittorrent)
- [Compila l'applicazione Electron](#compila-lapplicazione-electron)
- [Collaboratori](#collaboratori)
- [Licenza](#licenza)
## A proposito
**Hydra** è un **Game Launcher** con il proprio **Client BitTorrent** e **autogestore di repack**.
<br>
Il launcher è scritto in TypeScript (Electron) and Python, che gestisce il sistema di torrenting appoggiandosi a libtorrent.
## Caratteristiche
- Motore di ricerca automatizzato sulle fonti di repack dal [Megathread]("https://www.reddit.com/r/Piracy/wiki/megathread/")
- Client Bittorrent integrato
- Integrazione How Long To Beat (HLTB) nella pagina del gioco
- Percorso del download Personalizzato
- Notifiche di aggiornamenti sulla list dei repacks
- Supporto Windows e Linux
- Costantemente Aggiornato
- E molto altro ...
## Installazione
Segui i seguenti passi:
1. Scarica l'ultima versione di Hydra dalla pagina [Releases](https://github.com/hydralauncher/hydra/releases/latest).
- Scarica solo il file .exe per installare Hydra su Windows.
- Scarica il file .deb o .rpm o .zip per Linux. (Dipende dalla tua distro Linux)
2. Esegui il file scaricato.
3. Goditi Hydra!
## <a name="contribuire"> Contribuire
### <a name="unisciti-su-telegram"></a> Unisciti su Telegram
Puoi unirti alle nostre conversazioni sul canale [Telegram](https://t.me/hydralauncher).
### Forka e Clona la repository
1. Forka la repository [(clicca qui per forkare)](https://github.com/hydralauncher/hydra/fork)
2. Clona il tuo codice forkato `git clone https://github.com/your_username/hydra`
3. Crea un nuovo branch
4. Aggiungi le modifiche (push)
5. Invia la richiesta di pull
### Modi in cui contribuire
- Traduzione: Vogliamo rendere Hydra disponibile a più persone possibile. Sentiti libero di tradurre in altre lingue o aggiornare e migliorare quelle già disponibili su Hydra.
- Programmazione: Hydra è programmato in TypeScript, Electron e un po' di Python. Se intendi contribuire unisciti al nostro [Telegram](https://t.me/hydralauncher)!
### Struttura del Progetto
- client-torrent: Usiamo libtorrent, una libreria Python, per gestire i download dei torrent
- src/renderer: l'UI dell'applicazione
- src/main: tutta la logica qui.
## Compilazione
### Installa Node.js
Assicurati di avere Node.js installato sulla tua macchina. Scaricalo e installalo da [nodejs.org](https://nodejs.org/).
### Installa Yarn
Yarn è un gestore di pacchetti per Node.js. Se non hai ancora installato Yarn segui le istruzioni su [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/).
### Installa le dipendenze Node
Naviga alla cartella del progetto e installa le dipendenze Node con Yarn:
```bash
cd hydra
yarn
```
### Installa Python 3.9
Assicurati di avere Python 3.9 installato. Puoi scaricarlo da [python.org](https://www.python.org/downloads/release/python-3913/).
### Installa le Dipendenze Python
Installa le dipendenze con pip:
```bash
pip install -r requirements.txt
```
## Variabili d'ambiente
Avrai bisogno di una chiave API SteamGridDB per poter caricare le icone di gioco.
Se intendi avere onlinefix come repacker dovrai aggiungere le tue credenziali al file .env
Una volta ottenuta, puoi copiare e rinominare il file `.env.example` a `.env` e metterlo in `STEAMGRIDDB_API_KEY`, `ONLINEFIX_USERNAME`, `ONLINEFIX_PASSWORD`.
## Esecuzione
Una volta impostato tutto, puoi eseguire il seguente comando per avviare il processo Electron e il client bittorrent:
```bash
yarn dev
```
## Compilazione
### Compila il bittorrent
Usa il comando:
```bash
python torrent-client/setup.py build
```
### Compila l'applicazione Electron
Usa il comando:
Per Windows:
```bash
yarn build:win
```
Per Linux:
```bash
yarn build:linux
```
## Collaboratori
<a href="https://github.com/hydralauncher/hydra/graphs/contributors">
<img src="https://contrib.rocks/image?repo=hydralauncher/hydra" />
</a>
## Licenza
Hydra è concesso in licenza secondo la [MIT License](LICENSE).

View File

@@ -5,21 +5,24 @@
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra is a game launcher with its own embedded bittorrent client and a self-managed repack scraper.</strong>
<strong>Hydra is a game launcher with its own embedded bittorrent client.</strong>
</p>
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Hydra Catalogue](./docs/screenshot.png)
@@ -27,11 +30,12 @@
## Table of Contents
- [Table of Contents](#table-of-contents)
- [About](#about)
- [Features](#features)
- [Installation](#installation)
- [Contributing](#contributing)
- [Join our Telegram](#join-our-telegram)
- [Contributing](#-contributing)
- [Join our Telegram](#-join-our-telegram)
- [Fork and clone your repository](#fork-and-clone-your-repository)
- [Ways you can contribute](#ways-you-can-contribute)
- [Project Structure](#project-structure)
@@ -47,20 +51,19 @@
- [Build the bittorrent client](#build-the-bittorrent-client)
- [Build the Electron application](#build-the-electron-application)
- [Contributors](#contributors)
- [License](#license)
## About
**Hydra** is a **Game Launcher** with its own embedded **BitTorrent Client** and a **self-managed repack scraper**.
**Hydra** is a **Game Launcher** with its own embedded **BitTorrent Client**.
<br>
The launcher is written in TypeScript (Electron) and Python, which handles the torrenting system by using libtorrent.
## Features
- Self-Managed repack scraper among all the most reliable websites on the [Megathread]("https://www.reddit.com/r/Piracy/wiki/megathread/")
- Own embedded bittorrent client
- How Long To Beat (HLTB) integration on game page
- Downloads path customization
- Repack list update notifications
- Windows and Linux support
- Constantly updated
- And more ...
@@ -134,9 +137,8 @@ pip install -r requirements.txt
## Environment variables
You'll need an SteamGridDB API Key in order to fetch the game icons on installation.
If you want to have onlinefix as a repacker you'll need to add your credentials to the .env
Once you have it, you can copy or rename the `.env.example` file to `.env` and put it on`STEAMGRIDDB_API_KEY`, `ONLINEFIX_USERNAME`, `ONLINEFIX_PASSWORD`.
Once you have it, you can copy or rename the `.env.example` file to `.env` and put it on`STEAMGRIDDB_API_KEY`.
## Running

View File

@@ -5,7 +5,7 @@
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra - to program uruchamiający gry z własnym wbudowanym klientem bittorrent i samodzielnie zarządzanym repackagerem..</strong>
</p>
@@ -13,13 +13,16 @@
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Hydra Catalogue](./docs/screenshot.png)
@@ -27,26 +30,28 @@
## Zawartość.
- [Zawartość.](#zawartość)
- [O nas](#o-nas)
- [Cechy.](#cechy)
- [Cechy](#cechy)
- [Instalacja](#instalacja)
- [Dokonaj wpłaty](#dokonaj-wpłaty)
- [Dołącz do naszego kanału Telegram](#dołącz-do-naszego-kanału-telegram)
- [Dokonaj wpłaty](#-dokonaj-wpłaty)
- [Dołącz do naszego kanału Telegram](#-dołącz-do-naszego-kanału-telegram)
- [Rozwidlenie i sklonowanie repozytorium](#rozwidlenie-i-sklonowanie-repozytorium)
- [Jak możesz wnieść swój wkład](#jak-możesz-pomóc)
- [Jak możesz pomóc](#jak-możesz-pomóc)
- [Struktura projektu](#struktura-projektu)
- [Utwórz kompilację z kodu źródłowego](#utwórz-kompilację-z-kodu-źródłowego)
- [Instalacja Node.js](#zainstaluj-nodejs)
- [Instalacja Yarn](#zainstaluj-yarn)
- [Instalacja Node zależności](#zainstaluj-zależności-node)
- [Instalacja Python 3.9](#zainstaluj-python-39)
- [Instalacja Python zależności](#zainstaluj-zależności-pythona)
- [Zainstaluj Node.js](#zainstaluj-nodejs)
- [Zainstaluj Yarn](#zainstaluj-yarn)
- [Zainstaluj zależności Node](#zainstaluj-zależności-node)
- [Zainstaluj Python 3.9](#zainstaluj-python-39)
- [Zainstaluj zależności Pythona](#zainstaluj-zależności-pythona)
- [Zmienne środowiskowe](#zmienne-środowiskowe)
- [Uruchomienie](#utwórz-kompilację-z-kodu-źródłowego)
- [Run](#run)
- [Tworzenie kompilacji](#tworzenie-kompilacji)
- [Tworzenie klienta bittorrent](#zbuduj-klienta-bittorrent)
- [Tworzenie kompilacji aplikacji Electron](#tworzenie-aplikacji-electron)
- [Zbuduj klienta bittorrent](#zbuduj-klienta-bittorrent)
- [Tworzenie aplikacji Electron](#tworzenie-aplikacji-electron)
- [Współtwórcy](#współtwórcy)
- [License](#license)
## O nas

View File

@@ -5,7 +5,7 @@
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra é um Launcher de Jogos com seu próprio cliente de bittorrent integrado e um wrapper autogerenciado para busca de repacks.</strong>
</p>
@@ -13,13 +13,16 @@
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Hydra Catalogue](./docs/screenshot.png)
@@ -27,26 +30,28 @@
## Índice
- [Sobre](#about)
- [Recursos](#features)
- [Instalação](#installation)
- [Contribuindo](#contributing)
- [Junte-se ao nosso Telegram](#join-our-telegram)
- [Fork e clone seu repositorio](#fork-and-clone-your-repository)
- [Como contribuir](#ways-you-can-contribute)
- [Estrutura do projeto](#project-structure)
- [Compile a partir do código-fonte](#build-from-source)
- [Instale Node.js](#install-nodejs)
- [Instale Yarn](#install-yarn)
- [Instale Node Dependencies](#install-node-dependencies)
- [Instale Python 3.9](#install-python-39)
- [Instale Python Dependencies](#install-python-dependencies)
- [variaveis de ambiente](#environment-variables)
- [Rodando o programa](#running)
- [Compilando](#build)
- [Compile o client bittorrent](#build-the-bittorrent-client)
- [Compile a aplicação Electron](#build-the-electron-application)
- [Contribuidores](#contributors)
- [Índice](#índice)
- [Sobre](#-sobre)
- [Recursos](#-recursos)
- [Instalação](#-instalação)
- [Contribuindo](#-contribuindo)
- [Junte-se ao nosso Telegram](#-junte-se-ao-nosso-telegram)
- [Fork e clone o seu repositório](#-fork-e-clone-o-seu-repositório)
- [Formas de contribuir](#-formas-de-contribuir)
- [Estrutura do Projeto](#-estrutura-do-projeto)
- [Compile a partir do código-fonte](#-compile-a-partir-do-código-fonte)
- [Instale Node.js](#-instale-nodejs)
- [Instale Yarn](#-instale-yarn)
- [Instale Dependencias do Node](#-instale-dependencias-do-node)
- [Instale Python 3.9](#-instale-python-39)
- [Instale Python Dependencies](#-instale-python-dependencies)
- [Environment variables](#-environment-variables)
- [Running](#-running)
- [Build](#-build)
- [Build the bittorrent client](#-build-the-bittorrent-client)
- [Build the Electron application](#-build-the-electron-application)
- [Contributors](#-contributors)
- [Licença](#-licença)
## <a name="about"> Sobre

View File

@@ -5,7 +5,7 @@
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra - это игровой лаунчер с собственным встроенным клиентом BitTorrent и самостоятельным scraper`ом для репаков.</strong>
</p>
@@ -13,13 +13,16 @@
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Hydra Catalogue](./docs/screenshot.png)
@@ -27,11 +30,12 @@
## Содержание
- [Содержание](#содержание)
- [Описание](#описание)
- [Особенности](#особенности)
- [Установка](#установка)
- [Вклад](#contributing)
- [Присоединяйтесь к нашему Telegram](#join-our-telegram)
- [Вклад](#-вклад)
- [Присоединяйтесь к нашему Telegram](#-присоединяйтесь-к-нашему-telegram)
- [Форк и клонирование репозитория](#форк-и-клонирование-репозитория)
- [Способы внести свой вклад](#способы-внести-свой-вклад)
- [Структура проекта](#структура-проекта)
@@ -47,6 +51,7 @@
- [Сборка клиента BitTorrent](#сборка-клиента-bittorrent)
- [Сборка приложения Electron](#сборка-приложения-electron)
- [Участники](#участники)
- [License](#license)
## Описание

View File

@@ -5,7 +5,7 @@
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
<h1 align="center">Hydra Launcher</h1>
<p align="center">
<strong>Hydra - це ігровий лаунчер з власним вбудованим bittorrent-клієнтом і самокерованим збирачем репаків.</strong>
</p>
@@ -13,13 +13,16 @@
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
[![es](https://img.shields.io/badge/lang-es-red)](README.es.md)
[![fr](https://img.shields.io/badge/lang-fr-blue)](README.fr.md)
[![de](https://img.shields.io/badge/lang-de-black)](README.de.md)
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
![Hydra Catalogue](./docs/screenshot.png)
@@ -27,11 +30,12 @@
## Зміст
- [Зміст](#зміст)
- [Про нас](#про-нас)
- [Функції](#функції)
- [Встановлення](#встановлення)
- [Зробити свій внесок](#contributing)
- [Приєднуйтесь до нашого Telegram](#join-our-telegram)
- [Зробити свій внесок](#-зробити-свій-внесок)
- [Приєднуйтесь до нашого Telegram](#-приєднуйтесь-до-нашого-telegram)
- [Форк і клонування вашого репозиторію](#форк-і-клонування-вашого-репозиторію)
- [Як ви можете зробити свій внесок](#як-ви-можете-зробити-свій-внесок)
- [Структура проекту](#структура-проекту)
@@ -47,6 +51,7 @@
- [Зробіть білд bittorrent client](#зробіть-білд-bittorrent-client)
- [Зробіть білд Electron застосунку](#зробіть-білд-electron-застосунку)
- [Контриб'ютори](#контрибютори)
- [License](#license)
## Про нас

68
SECURITY.md Normal file
View File

@@ -0,0 +1,68 @@
# Security Policy
## Purpose of the Policy
The purpose of this Security Policy is to ensure the security of our project and maintain the trust of the community.
## Who is Affected by the Policy
This policy applies to all members of our project community, including developers, testers, repository administrators, and users.
## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
| 2.0.x | :white_check_mark: |
| < 1.2.0 | :x: |
## Development Recommendations
### Best Practices
- Follow secure coding principles.
- Use well-established libraries and frameworks.
- Regularly update dependencies.
- Conduct thorough testing, including security-related tests.
### Unrecommended Practices
- Do not use known vulnerabilities that have not been patched.
- Do not publish sensitive information such as API keys or passwords.
- Do not vote for changes that degrade the security of the project.
### User-Generated Content
- Ensure that user-generated content does not contain hidden threats.
- Be cautious when handling user data.
### Community Interaction
- Treat each other with respect and politeness.
- Do not spread spam or spam bots.
- Follow community guidelines.
### Vulnerability Discovery and Reporting
- If you discover a vulnerability, report it as an issue on GitHub.
- Your report should contain detailed information about the vulnerability, including steps to resolve it.
### Reporting Method
To report a vulnerability, create a new issue on GitHub and use branch isolation to provide details about the vulnerability.
### Details to Provide
Please provide the following information about the vulnerability:
- Description of the vulnerability
- Steps to resolve the vulnerability
- Versions on which the vulnerability was found
- Code examples illustrating the vulnerability (if it is safe to do so)
### Expected Behavior
- If we accept the reported vulnerability, we will release a patch and update the security information on GitHub.
- If we reject the reported vulnerability, we will provide an explanation.

View File

@@ -3,7 +3,6 @@ productName: Hydra
directories:
buildResources: build
extraResources:
- aria2
- hydra-download-manager
- seeds
- from: node_modules/create-desktop-shortcuts/src/windows.vbs
@@ -45,6 +44,7 @@ linux:
- AppImage
- snap
- deb
- pacman
- rpm
maintainer: electronjs.org
category: Game

View File

@@ -1,6 +1,6 @@
{
"name": "hydralauncher",
"version": "2.0.2",
"version": "2.1.4",
"description": "Hydra",
"main": "./out/main/index.js",
"author": "Los Broxas",
@@ -23,28 +23,28 @@
"start": "electron-vite preview",
"dev": "electron-vite dev",
"build": "npm run typecheck && electron-vite build",
"postinstall": "electron-builder install-app-deps && node ./postinstall.cjs",
"postinstall": "electron-builder install-app-deps",
"build:unpack": "npm run build && electron-builder --dir",
"build:win": "electron-vite build && electron-builder --win",
"build:mac": "electron-vite build && electron-builder --mac",
"build:linux": "electron-vite build && electron-builder --linux",
"prepare": "husky",
"typeorm:migration-create": "yarn typeorm migration:create"
"knex:migrate:make": "knex --knexfile src/main/knexfile.ts migrate:make --esm"
},
"dependencies": {
"@electron-toolkit/preload": "^3.0.0",
"@electron-toolkit/utils": "^3.0.0",
"@fontsource/fira-mono": "^5.0.13",
"@fontsource/fira-sans": "^5.0.20",
"@fontsource/noto-sans": "^5.0.22",
"@hookform/resolvers": "^3.9.0",
"@primer/octicons-react": "^19.9.0",
"@reduxjs/toolkit": "^2.2.3",
"@sentry/electron": "^5.1.0",
"@vanilla-extract/css": "^1.14.2",
"@vanilla-extract/dynamic": "^2.1.1",
"@vanilla-extract/recipes": "^0.5.2",
"aria2": "^4.1.2",
"auto-launch": "^5.0.6",
"axios": "^1.6.8",
"better-sqlite3": "^9.5.0",
"axios": "^1.7.7",
"better-sqlite3": "^11.2.1",
"check-disk-space": "^3.4.0",
"classnames": "^2.5.1",
"color": "^4.2.3",
@@ -54,18 +54,18 @@
"electron-log": "^5.1.4",
"electron-updater": "^6.1.8",
"fetch-cookie": "^3.0.1",
"file-type": "^19.0.0",
"flexsearch": "^0.7.43",
"i18next": "^23.11.2",
"i18next-browser-languagedetector": "^7.2.1",
"icojs": "^0.19.3",
"iso-639-1": "3.1.2",
"jsdom": "^24.0.0",
"jsonwebtoken": "^9.0.2",
"knex": "^3.1.0",
"lodash-es": "^4.17.21",
"lottie-react": "^2.4.0",
"parse-torrent": "^11.0.16",
"piscina": "^4.5.1",
"react-hook-form": "^7.53.0",
"react-i18next": "^14.1.0",
"react-loading-skeleton": "^3.4.0",
"react-redux": "^9.1.1",
@@ -74,6 +74,7 @@
"typeorm": "^0.3.20",
"user-agents": "^1.1.193",
"yaml": "^2.4.1",
"yup": "^1.4.0",
"zod": "^3.23.8"
},
"devDependencies": {
@@ -96,7 +97,7 @@
"@types/user-agents": "^1.0.4",
"@vanilla-extract/vite-plugin": "^4.0.7",
"@vitejs/plugin-react": "^4.2.1",
"electron": "^30.0.9",
"electron": "^30.3.0",
"electron-builder": "^24.9.1",
"electron-vite": "^2.0.0",
"eslint": "^8.56.0",
@@ -107,6 +108,7 @@
"prettier": "^3.2.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"ts-node": "^10.9.2",
"typescript": "^5.3.3",
"vite": "^5.0.12",
"vite-plugin-svgr": "^4.2.0"

View File

@@ -1,50 +0,0 @@
const { default: axios } = require("axios");
const util = require("node:util");
const fs = require("node:fs");
const exec = util.promisify(require("node:child_process").exec);
const downloadAria2 = async () => {
if (fs.existsSync("aria2")) {
console.log("Aria2 already exists, skipping download...");
return;
}
const file =
process.platform === "win32"
? "aria2-1.37.0-win-64bit-build1.zip"
: "aria2-1.37.0-1-x86_64.pkg.tar.zst";
const downloadUrl =
process.platform === "win32"
? `https://github.com/aria2/aria2/releases/download/release-1.37.0/${file}`
: "https://archlinux.org/packages/extra/x86_64/aria2/download/";
console.log(`Downloading ${file}...`);
const response = await axios.get(downloadUrl, { responseType: "stream" });
const stream = response.data.pipe(fs.createWriteStream(file));
stream.on("finish", async () => {
console.log(`Downloaded ${file}, extracting...`);
if (process.platform === "win32") {
await exec(`npx extract-zip ${file}`);
console.log("Extracted. Renaming folder...");
fs.renameSync(file.replace(".zip", ""), "aria2");
} else {
await exec(`tar --zstd -xvf ${file} usr/bin/aria2c`);
console.log("Extracted. Copying binary file...");
fs.mkdirSync("aria2");
fs.copyFileSync("usr/bin/aria2c", "aria2/aria2c");
fs.rmSync("usr", { recursive: true });
}
console.log(`Extracted ${file}, removing compressed downloaded file...`);
fs.rmSync(file);
});
};
downloadAria2();

View File

@@ -4,3 +4,4 @@ cx_Logging; sys_platform == 'win32'
lief; sys_platform == 'win32'
pywin32; sys_platform == 'win32'
psutil
Pillow

View File

@@ -1,4 +1,5 @@
{
"language_name": "اَلْعَرَبِيَّةُ",
"home": {
"featured": "مميّز",
"trending": "شائع",

View File

@@ -1,4 +1,5 @@
{
"language_name": "беларуская мова",
"home": {
"featured": "Рэкамэндаванае",
"trending": "Актуальнае",

View File

@@ -1,4 +1,8 @@
{
"language_name": "Català",
"app": {
"successfully_signed_in": "Has entrat correctament"
},
"home": {
"featured": "Destacats",
"trending": "Populars",
@@ -14,7 +18,10 @@
"paused": "{{title}} (Pausat)",
"downloading": "{{title}} ({{percentage}} - S'està baixant…)",
"filter": "Filtra la biblioteca",
"home": "Inici"
"home": "Inici",
"queued": "{{title}} (En espera)",
"game_has_no_executable": "El joc encara no té un executable seleccionat",
"sign_in": "Entra"
},
"header": {
"search": "Cerca jocs",
@@ -29,7 +36,9 @@
"bottom_panel": {
"no_downloads_in_progress": "Cap baixada en curs",
"downloading_metadata": "S'estan baixant les metadades de: {{title}}…",
"downloading": "S'està baixant: {{title}}… ({{percentage}} complet) - Finalització: {{eta}} - {{speed}}"
"downloading": "S'està baixant: {{title}}… ({{percentage}} complet) - Finalització: {{eta}} - {{speed}}",
"calculating_eta": "Descarregant {{title}}… ({{percentage}} completat) - Calculant el temps restant…",
"checking_files": "Comprovant els fitxers de {{title}}… ({{percentage}} completat)"
},
"catalogue": {
"next_page": "Pàgina següent",
@@ -47,12 +56,14 @@
"cancel": "Cancel·la",
"remove": "Elimina",
"space_left_on_disk": "{{space}} lliures al disc",
"eta": "Finalització: {{eta}}",
"eta": "Finalitza en: {{eta}}",
"calculating_eta": "Calculant temps estimat…",
"downloading_metadata": "S'estan baixant les metadades…",
"filter": "Filtra els reempaquetats",
"requirements": "Requisits del sistema",
"minimum": "Mínims",
"recommended": "Recomanats",
"paused": "Paused",
"release_date": "Publicat el {{date}}",
"publisher": "Publicat per {{publisher}}",
"hours": "hores",
@@ -81,7 +92,29 @@
"previous_screenshot": "Captura anterior",
"next_screenshot": "Captura següent",
"screenshot": "Captura {{number}}",
"open_screenshot": "Obre la captura {{number}}"
"open_screenshot": "Obre la captura {{number}}",
"download_settings": "Configuració de descàrrega",
"downloader": "Descarregador",
"select_executable": "Selecciona",
"no_executable_selected": "No hi ha executable selccionat",
"open_folder": "Obre carpeta",
"open_download_location": "Visualitzar fitxers descarregats",
"create_shortcut": "Crear accés directe a l'escriptori",
"remove_files": "Elimina fitxers",
"remove_from_library_title": "Segur?",
"remove_from_library_description": "Això eliminarà el videojoc {{game}} del teu catàleg",
"options": "Opcions",
"executable_section_title": "Executable",
"executable_section_description": "Directori del fitxer des d'on s'executarà quan es cliqui a \"Executar\"",
"downloads_secion_title": "Descàrregues",
"downloads_section_description": "Comprova actualitzacions o altres versions del videojoc",
"danger_zone_section_title": "Zona de perill",
"danger_zone_section_description": "Elimina aquest videojoc del teu catàleg o els fitxers descarregats per Hydra",
"download_in_progress": "Descàrrega en progrés",
"download_paused": "Descàrrega en pausa",
"last_downloaded_option": "Opció de l'última descàrrega",
"create_shortcut_success": "Accés directe creat satisfactòriament",
"create_shortcut_error": "Error al crear l'accés directe"
},
"activation": {
"title": "Activa l'Hydra",
@@ -98,6 +131,7 @@
"paused": "Pausada",
"verifying": "S'està verificant…",
"completed": "Completada",
"removed": "No descarregat",
"cancel": "Cancel·la",
"filter": "Filtra els jocs baixats",
"remove": "Elimina",
@@ -106,7 +140,14 @@
"delete": "Elimina l'instal·lador",
"delete_modal_title": "N'estàs segur?",
"delete_modal_description": "S'eliminaran de l'ordinador tots els fitxers d'instal·lació",
"install": "Instal·la"
"install": "Instal·la",
"download_in_progress": "En progrés",
"queued_downloads": "Descàrregues en espera",
"downloads_completed": "Completat",
"queued": "En espera",
"no_downloads_title": "Buit",
"no_downloads_description": "No has descarregat res amb Hydra encara, però mai és tard per començar a fer-ho.",
"checking_files": "Comprovant fitxers…"
},
"settings": {
"downloads_path": "Ruta de baixades",
@@ -119,16 +160,49 @@
"launch_with_system": "Inicia l'Hydra quan s'iniciï el sistema",
"general": "General",
"behavior": "Comportament",
"download_sources": "Fonts de descàrrega",
"language": "Idioma",
"real_debrid_api_token": "Testimoni API",
"enable_real_debrid": "Activa el Real Debrid",
"real_debrid_description": "Real-Debrid és un programa de descàrrega sense restriccions que us permet descarregar fitxers a l'instant i al màxim de la vostra velocitat d'Internet.",
"real_debrid_invalid_token": "Invalida el testimoni de l'API",
"real_debrid_api_token_hint": "Pots obtenir la teva clau de l'API <0>aquí</0>.",
"save_changes": "Desa els canvis"
"real_debrid_free_account_error": "L'usuari \"{{username}}\" és un compte gratuït. Si us plau subscriu-te a Real-Debrid",
"real_debrid_linked_message": "Compte \"{{username}}\" vinculat",
"save_changes": "Desa els canvis",
"changes_saved": "Els canvis s'han desat correctament",
"download_sources_description": "Hydra buscarà els enllaços de descàrrega d'aquestes fonts. L'URL d'origen ha de ser un enllaç directe a un fitxer .json que contingui els enllaços de descàrrega.",
"validate_download_source": "Valida",
"remove_download_source": "Elimina",
"add_download_source": "Afegeix font",
"download_count_zero": "No hi ha baixades a la llista",
"download_count_one": "{{countFormatted}} a la llista de baixades",
"download_count_other": "{{countFormatted}} baixades a la llista",
"download_options_zero": "No hi ha cap descàrrega disponible",
"download_options_one": "{{countFormatted}} descàrrega disponible",
"download_options_other": "{{countFormatted}} baixades disponibles",
"download_source_url": "Descarrega l'URL de la font",
"add_download_source_description": "Inseriu la URL que conté el fitxer .json",
"download_source_up_to_date": "Actualitzat",
"download_source_errored": "S'ha produït un error",
"sync_download_sources": "Sincronitza fonts",
"removed_download_source": "S'ha eliminat la font de descàrrega",
"added_download_source": "Added download source",
"download_sources_synced": "Totes les fonts de descàrrega estan sincronitzades",
"insert_valid_json_url": "Insereix una URL JSON vàlida",
"found_download_option_zero": "No s'ha trobat cap opció de descàrrega",
"found_download_option_one": "S'ha trobat l'opció de baixada de {{countFormatted}}",
"found_download_option_other": "S'han trobat {{countFormatted}} opcions de baixada",
"import": "Import"
},
"notifications": {
"download_complete": "La baixada ha finalitzat",
"game_ready_to_install": "{{title}} ja es pot instal·lar",
"repack_list_updated": "S'ha actualitzat la llista de reempaquetats",
"repack_count_one": "S'ha afegit {{count}} reempaquetat",
"repack_count_other": "S'han afegit {{count}} reempaquetats"
"repack_count_other": "S'han afegit {{count}} reempaquetats",
"new_update_available": "Versió {{version}} disponible",
"restart_to_install_update": "Reinicieu Hydra per instal·lar l'actualització"
},
"system_tray": {
"open": "Obre l'Hydra",
@@ -144,5 +218,39 @@
},
"modal": {
"close": "Botó de tancar"
},
"forms": {
"toggle_password_visibility": "Commuta la visibilitat de la contrasenya"
},
"user_profile": {
"amount_hours": "{{amount}} hores",
"amount_minutes": "{{amount}} minuts",
"last_time_played": "Última partida {{period}}",
"activity": "Activitat recent",
"library": "Biblioteca",
"total_play_time": "Temps total de joc:{{amount}}",
"no_recent_activity_title": "Hmmm… encara no res",
"no_recent_activity_description": "No has jugat a cap joc recentment. És el moment de canviar-ho!",
"display_name": "Nom de visualització",
"saving": "Desant",
"save": "Desa",
"edit_profile": "Edita el Perfil",
"saved_successfully": "S'ha desat correctament",
"try_again": "Siusplau torna-ho a provar",
"sign_out_modal_title": "Segur?",
"cancel": "Cancel·la",
"successfully_signed_out": "S'ha tancat la sessió correctament",
"sign_out": "Tanca sessió",
"playing_for": "Jugant per {{amount}}",
"sign_out_modal_text": "La vostra biblioteca està enllaçada amb el vostre compte actual. Quan tanqueu la sessió, la vostra biblioteca ja no serà visible i cap progrés no es desarà. Voleu continuar amb tancar la sessió?",
"add_friends": "Afegeix amics",
"add": "Afegeix",
"friend_code": "Codi de l'amic",
"see_profile": "Veure Perfil",
"sending": "Enviant",
"friend_request_sent": "Sol·licitud d'amistat enviada",
"friends": "Amistats",
"friends_list": "Llista d'amistats",
"user_not_found": "Usuari no trobat"
}
}

View File

@@ -0,0 +1,272 @@
{
"language_name": "Čeština",
"app": {
"successfully_signed_in": "Úspěšně přihlášen"
},
"home": {
"featured": "Doporučené",
"trending": "Trendy",
"surprise_me": "Překvap mě",
"no_results": "Výsledek nenalezen"
},
"sidebar": {
"catalogue": "Katalog",
"downloads": "Stažené",
"settings": "Nastavení",
"my_library": "Moje knihovna",
"downloading_metadata": "{{title}} (Stahuji metadata…)",
"paused": "{{title}} (Pozastaveno)",
"downloading": "{{title}} ({{percentage}} - Stahuji…)",
"filter": "Filtrovat knihovnu",
"home": "Domov",
"queued": "{{title}} (V řadě)",
"game_has_no_executable": "Hra nemá zvolen žádný spustitelný soubor",
"sign_in": "Přihlásit se"
},
"header": {
"search": "Vyhledat hry",
"home": "Domov",
"catalogue": "Katalog",
"downloads": "Stažené",
"search_results": "Výsledky vyhledávání",
"settings": "Nastavení",
"version_available_install": "Je dostupná nová verze: {{version}}. Klikni sem pro restart a instalaci.",
"version_available_download": "Je dostupná nová verze: {{version}}. Klikni sem pro stažení."
},
"bottom_panel": {
"no_downloads_in_progress": "Neprobíhá žádné stahování",
"downloading_metadata": "Stahuji metadata: {{title}}…",
"downloading": "Stahuji {{title}}… ({{percentage}} staženo) - Odhadovaný čas {{eta}} - {{speed}}",
"calculating_eta": "Stahuji {{title}}… ({{percentage}} staženo) - Počítám zbývající čas…",
"checking_files": "Kontroluji soubory: {{title}}… ({{percentage}} ověřeno)"
},
"catalogue": {
"next_page": "Další strana",
"previous_page": "Předchozí strana"
},
"game_details": {
"open_download_options": "Otevřít možnosti stahování",
"download_options_zero": "Žádné možnosti stahování",
"download_options_one": "{{count}} možnost stažení",
"download_options_other": "{{count}} možnosti stažení",
"updated_at": "Aktualizováno {{updated_at}}",
"install": "Instalovat",
"resume": "Obnovit",
"pause": "Pozastavit",
"cancel": "Zrušit",
"remove": "Odebrat",
"space_left_on_disk": "{{space}} zbývá na disku",
"eta": "Odhadovaný čas: {{eta}}",
"calculating_eta": "Počítám zbývající čas…",
"downloading_metadata": "Stahuji metadata…",
"filter": "Filtrovat repacky",
"requirements": "Systémové požadavky",
"minimum": "Minimální",
"recommended": "Doporučené",
"paused": "Pozastaveno",
"release_date": "Datum vydání: {{date}}",
"publisher": "Publikováno: {{publisher}}",
"hours": "hodiny",
"minutes": "minuty",
"amount_hours": "{{amount}} hodin",
"amount_minutes": "{{amount}} minut",
"accuracy": "Přesnost {{accuracy}}%",
"add_to_library": "Přidat do knihovny",
"remove_from_library": "Odebrat z knihovny",
"no_downloads": "Žádné možnosti stahování nejsou dostupné",
"play_time": "Odehraný čas: {{amount}}",
"last_time_played": "Naposledy hráno {{period}}",
"not_played_yet": "Ješte jste nehráli {{title}}",
"next_suggestion": "Další doporučení",
"play": "Hrát",
"deleting": "Odstraňuji instalační program…",
"close": "Zavřít",
"playing_now": "Právě hraje",
"change": "Změnit",
"repacks_modal_description": "Vyber repack který chceš stáhnout",
"select_folder_hint": "Pro změnu základní složky, jdi do <0>Nastavení</0>",
"download_now": "Stáhnout",
"no_shop_details": "Nepodařilo se mi načíst informace o obchodu.",
"download_options": "Možnosti stahování",
"download_path": "Umístění stahování",
"previous_screenshot": "Předchozí snímek obrazovky",
"next_screenshot": "Následující snímek obrazovky",
"screenshot": "Snímek obrazovky {{number}}",
"open_screenshot": "Otevřít snímek obrazovky {{number}}",
"download_settings": "Nastavení stahování",
"downloader": "Správce stahování",
"select_executable": "Vybrat",
"no_executable_selected": "Nebyl vybrán spustitelný soubor",
"open_folder": "Otevřít složku",
"open_download_location": "Zobrazit stažené soubory",
"create_shortcut": "Vytvořit zástupce na ploše",
"remove_files": "Odebrat soubory",
"remove_from_library_title": "Jste si jisti?",
"remove_from_library_description": "Tohle odstraní {{game}} z vaší knihovny",
"options": "Možnosti",
"executable_section_title": "Spustitelné",
"executable_section_description": "Umístění souboru který bude spuštěn při kliknutí na \"Hrát\"",
"downloads_secion_title": "Stažené soubory",
"downloads_section_description": "Zkontrolovat jestli není nová / odlišná verze hry",
"danger_zone_section_title": "Nebezpečná zóna",
"danger_zone_section_description": "Odebrat hru z knihovny / soubory stažené Hydrou",
"download_in_progress": "Probíhá stahování",
"download_paused": "Stahování pozastaveno",
"last_downloaded_option": "Poslední stažená možnost",
"create_shortcut_success": "Zástupce vytvořen úspěšně",
"create_shortcut_error": "Chyba při pokusu vytvořit zástupce"
},
"activation": {
"title": "Aktivovat hydru",
"installation_id": "ID instalace:",
"enter_activation_code": "Zadej svůj aktivační kód",
"message": "Pokud nevíš, kde ten kód sehnat, tak by jsi k tomuhle neměl mít přístup.",
"activate": "Aktivovat",
"loading": "Načítání…"
},
"downloads": {
"resume": "Pokračovat",
"pause": "Pozastavit",
"eta": "Odhadovaný čas: {{eta}}",
"paused": "Pozastaveno",
"verifying": "Ověřuji…",
"completed": "Hotovo",
"removed": "Není staženo",
"cancel": "Zrušit",
"filter": "Filtrovat stažené hry",
"remove": "Odebrat",
"downloading_metadata": "Stahuji metadata…",
"deleting": "Odstraňuji instalační program…",
"delete": "Odebrat instalační program",
"delete_modal_title": "Jste si jisti?",
"delete_modal_description": "Tohle odstraní všechny instalační soubory",
"install": "Instalovat",
"download_in_progress": "Probíhá stahování",
"queued_downloads": "Stahování v řadě",
"downloads_completed": "Dokončeno",
"queued": "V řadě",
"no_downloads_title": "Prázdno..",
"no_downloads_description": "Ještě jsi zatím nic nestáhl přes Hydru, ale furt není pozdě začít.",
"checking_files": "Kontroluji soubory…"
},
"settings": {
"downloads_path": "Umístění stahování",
"change": "Aktualizovat",
"notifications": "Upozornění",
"enable_download_notifications": "Až bude stahování dokončeno",
"enable_repack_list_notifications": "Když bude přidán nový repack",
"real_debrid_api_token_label": "Real-Debrid API token",
"quit_app_instead_hiding": "Nezavírat Hydru při zavření okna",
"launch_with_system": "Spustit Hydru při startu systému",
"general": "Hlavní",
"behavior": "Chování",
"download_sources": "Zdroje stahování",
"language": "Jazyk",
"real_debrid_api_token": "API Token",
"enable_real_debrid": "Povolit Real-Debrid",
"real_debrid_description": "Real-Debrid je neomezený správce stahování, který umožňuje stahovat soubory v nejvyšší rychlosti vašeho internetu.",
"real_debrid_invalid_token": "Neplatný API token",
"real_debrid_api_token_hint": "API token můžeš sehnat <0>zde</0>",
"real_debrid_free_account_error": "Účet \"{{username}}\" má základní úroveň. Prosím předplaťte si Real-Debrid",
"real_debrid_linked_message": "Účet \"{{username}}\" je propojen",
"save_changes": "Uložit změny",
"changes_saved": "Změny úspěšně uloženy",
"download_sources_description": "Hydra bude odsud sbírat soubory. Zdrojový odkaz musí být .json soubor obsahující odkazy na soubory.",
"validate_download_source": "Ověřit",
"remove_download_source": "Odebrat",
"add_download_source": "Přidat zdroj",
"download_count_zero": "Žádná možnost stažení",
"download_count_one": "{{countFormatted}} možnost stažení",
"download_count_other": "{{countFormatted}} možnosti stažení",
"download_source_url": "Stáhnout zdrojový odkaz",
"add_download_source_description": "Zadej odkaz odkazující na .json soubor",
"download_source_up_to_date": "Aktuální",
"download_source_errored": "Chyba",
"sync_download_sources": "Synchronizovat zdroje",
"removed_download_source": "Zdroj odebrán",
"added_download_source": "Zdroj přidán",
"download_sources_synced": "Všechny zdroje jsou synchronizovány",
"insert_valid_json_url": "Zadej platnou JSON adresu",
"found_download_option_zero": "Nenalezena žádná možnost stahování",
"found_download_option_one": "Nalezena {{countFormatted}} možnost stahování",
"found_download_option_other": "Nalezeny {{countFormatted}} možnosti stahování",
"import": "Importovat"
},
"notifications": {
"download_complete": "Stahování dokončeno",
"game_ready_to_install": "{{title}} je připraveno k instalaci",
"repack_list_updated": "Seznam repacků byl aktualizován",
"repack_count_one": "{{count}} repack přidán",
"repack_count_other": "{{count}} repacky přidány",
"new_update_available": "Version {{version}} je dostupná",
"restart_to_install_update": "Restartuj Hydru pro aktualizaci"
},
"system_tray": {
"open": "Otevřít Hydru",
"quit": "Odejít"
},
"game_card": {
"no_downloads": "Žádné možnosti stahování nenalezeny"
},
"binary_not_found_modal": {
"title": "Programy nenainstalovány",
"description": "Spustitelné soubory Wine nebo Lutris nebyly nalezeny ve vašem systému",
"instructions": "Zkonstroluj oficiální cestu jak je nainstalovat na tvoji Linux Distribuci, aby hry mohly běžet normálně"
},
"modal": {
"close": "Tlačítko zavřít"
},
"forms": {
"toggle_password_visibility": "Přepnout viditelnost hesla"
},
"user_profile": {
"amount_hours": "{{amount}} hodin",
"amount_minutes": "{{amount}} minut",
"last_time_played": "Naposledy hráno {{period}}",
"activity": "Nedávná aktivita",
"library": "Knihovna",
"total_play_time": "Celkový odehraný čas: {{amount}}",
"no_recent_activity_title": "Hmmm… nic tu není",
"no_recent_activity_description": "V poslední době si nehrál žádnout hru, můžeš to ale napravit!",
"display_name": "Zobrazované jméno",
"saving": "Ukládání",
"save": "Uložit",
"edit_profile": "Upravit profil",
"saved_successfully": "Úspěšně uloženo",
"try_again": "Prosím, zkuste to znovu",
"sign_out_modal_title": "Jste si jisti?",
"cancel": "Zrušit",
"successfully_signed_out": "Úspěšně odhlášeno",
"sign_out": "Odhlásit se",
"playing_for": "Hraje po: {{amount}}",
"sign_out_modal_text": "Vaše knihovna je propojena s vaším současným účtem. Po odhlášení vaše knihovna již nebude vidět, a postup nebude uložen. Pokračovat?",
"add_friends": "Přidat přátele",
"add": "Přidat",
"friend_code": "Kód přítele",
"see_profile": "Zobrazit profil",
"sending": "Odesílání",
"friend_request_sent": "Žádost odeslána",
"friends": "Přátelé",
"friends_list": "Seznam přátel",
"user_not_found": "Uživatel nenalezen",
"block_user": "Zablokovat uživatele",
"add_friend": "Přidat přítele",
"request_sent": "Žádost odeslána",
"request_received": "Žádost obdržena",
"accept_request": "Přijmout žádost",
"ignore_request": "Ignorovat žádost",
"cancel_request": "Zrušit žádost",
"undo_friendship": "Odvolat přátelství",
"request_accepted": "Žádost přijata",
"user_blocked_successfully": "Uživatel úspěšně zablokován",
"user_block_modal_text": "Tohle zablokuje {{displayName}}",
"blocked_users": "Zablokovaní uživatelé",
"unblock": "Odblokovat",
"no_friends_added": "Nemáš přidané žádné přátele",
"pending": "Odchozí",
"no_pending_invites": "Nemáte žádné příchozí žádosti",
"no_blocked_users": "Nemáte nikoho zablokovaného",
"friend_code_copied": "Kód přítele zkopírován",
"undo_friendship_modal_text": "Tímto zrušíte své přátelství s {{displayName}}"
}
}

View File

@@ -1,4 +1,5 @@
{
"language_name": "Dansk",
"home": {
"featured": "Anbefalet",
"trending": "Trender",

View File

@@ -0,0 +1,272 @@
{
"language_name": "Deutsch",
"app": {
"successfully_signed_in": "Erfolgreich angemeldet"
},
"home": {
"featured": "Empfohlen",
"trending": "Beliebt",
"surprise_me": "Überrasche mich",
"no_results": "Keine Ergebnisse gefunden"
},
"sidebar": {
"catalogue": "Katalog",
"downloads": "Downloads",
"settings": "Einstellungen",
"my_library": "Meine Bibliothek",
"downloading_metadata": "{{title}} (Metadaten werden heruntergeladen…)",
"paused": "{{title}} (Pausiert)",
"downloading": "{{title}} ({{percentage}} - Wird heruntergeladen…)",
"filter": "Bibliothek filtern",
"home": "Home",
"queued": "{{title}} (In Warteschlange)",
"game_has_no_executable": "Spiel hat keine ausführbare Datei gewählt",
"sign_in": "Anmelden"
},
"header": {
"search": "Spiele suchen",
"home": "Home",
"catalogue": "Katalog",
"downloads": "Downloads",
"search_results": "Suchergebnisse",
"settings": "Einstellungen",
"version_available_install": "Version {{version}} verfügbar. Klicke hier, um neuzustarten und sie zu installieren.",
"version_available_download": "Version {{version}} verfügbar. Klicke hier, um sie herunterzuladen."
},
"bottom_panel": {
"no_downloads_in_progress": "Keine aktive Downloads",
"downloading_metadata": "Metadaten von {{title}} werden heruntergeladen…",
"downloading": "{{title}} wird heruntergeladen… ({{percentage}} abgeschlossen) - Abschluss {{eta}} - {{speed}}",
"calculating_eta": "{{title}} wird heruntergeladen… ({{percentage}} abgeschlossen) - Verbleibende Zeit wird berechnet…",
"checking_files": "Prüfe Dateien von {{title}}… ({{percentage}} abgeschlossen)"
},
"catalogue": {
"next_page": "Nächste Seite",
"previous_page": "Vorherige Seite"
},
"game_details": {
"open_download_options": "Download-Optionen öffnen",
"download_options_zero": "Keine Download-Optionen",
"download_options_one": "{{count}} Download-Option",
"download_options_other": "{{count}} Download-Optionen",
"updated_at": "Aktualisiert {{updated_at}}",
"install": "Installieren",
"resume": "Fortfahren",
"pause": "Pausieren",
"cancel": "Abbrechen",
"remove": "Entfernen",
"space_left_on_disk": "{{space}} auf Festplatte verfügbar",
"eta": "Abschluss {{eta}}",
"calculating_eta": "Verbleibende Zeit wird berechnet…",
"downloading_metadata": "Metadaten werden heruntergeladen…",
"filter": "Repacks filtern",
"requirements": "Systemanforderungen",
"minimum": "Minimum",
"recommended": "Empfohlen",
"paused": "Pausiert",
"release_date": "Veröffentlicht am {{date}}",
"publisher": "Veröffentlicht von {{publisher}}",
"hours": "Stunden",
"minutes": "Minuten",
"amount_hours": "{{amount}} Stunden",
"amount_minutes": "{{amount}} Minuten",
"accuracy": "{{accuracy}}% Genauigkeit",
"add_to_library": "Zu Bibliothek hinzufügen",
"remove_from_library": "Von Bibliothek entfernen",
"no_downloads": "Keine Downloads verfügbar",
"play_time": "{{amount}} lang gespielt",
"last_time_played": "Zuletzt gespielt {{period}}",
"not_played_yet": "{{title}} wurde noch nicht gespielt",
"next_suggestion": "Nächste Empfehlung",
"play": "Spielen",
"deleting": "Installer wird gelöscht…",
"close": "Schließen",
"playing_now": "Spielt jetzt",
"change": "Ändern",
"repacks_modal_description": "Wähle das Repack, das du herunterladen möchtest",
"select_folder_hint": "Um das Standardverzeichnis zu ändern, gehe zu den <0>Einstellungen</0>",
"download_now": "Jetzt herunterladen",
"no_shop_details": "Shop-Details konnten nicht abgerufen werden.",
"download_options": "Download-Optionen",
"download_path": "Download-Verzeichnis",
"previous_screenshot": "Vorheriger Screenshot",
"next_screenshot": "Nächster Screenshot",
"screenshot": "Screenshot {{number}}",
"open_screenshot": "Screenshot {{number}} öffnen",
"download_settings": "Download-Einstellungen",
"downloader": "Downloader",
"select_executable": "Auswählen",
"no_executable_selected": "Keine ausführbare Datei gewählt",
"open_folder": "Verzeichnis öffnen",
"open_download_location": "Heruntergeladene Dateien anzeigen",
"create_shortcut": "Desktop-Verknüpfung erstellen",
"remove_files": "Dateien entfernen",
"remove_from_library_title": "Bist du dir sicher?",
"remove_from_library_description": "Dies wird {{game}} aus deiner Bibliothek entfernen",
"options": "Optionen",
"executable_section_title": "Ausführbare Datei",
"executable_section_description": "Pfad der Datei, die bei Klick auf \"Play\" ausgeführt wird",
"downloads_secion_title": "Downloads",
"downloads_section_description": "Sieh dir Updates oder andere Versionen dieses Spiels an",
"danger_zone_section_title": "Gefahrenzone",
"danger_zone_section_description": "Entferne dieses Spiel aus deiner Bibliothek oder die von Hydra heruntergeladenen Dateien",
"download_in_progress": "Download erfolgt",
"download_paused": "Download ist pausiert",
"last_downloaded_option": "Letzte Download-Option",
"create_shortcut_success": "Verknüpfung erfolgreich erstellt",
"create_shortcut_error": "Fehler bei Erstellung von Verknüpfung"
},
"activation": {
"title": "Hydra aktivieren",
"installation_id": "Installations ID:",
"enter_activation_code": "Aktivierungscode eingeben",
"message": "Wenn du nicht weißt wo du fragen musst, solltest du dies nicht haben.",
"activate": "Aktivieren",
"loading": "Lädt…"
},
"downloads": {
"resume": "Fortfahren",
"pause": "Pause",
"eta": "Abschluss {{eta}}",
"paused": "Pausiert",
"verifying": "Verifiziere…",
"completed": "Abgeschlossen",
"removed": "Nicht heruntergeladen",
"cancel": "Abbrechen",
"filter": "Heruntergeladene Spiele filtern",
"remove": "Entfernen",
"downloading_metadata": "Metadaten werden heruntergeladen…",
"deleting": "Installer wird entfernt…",
"delete": "Installer entfernen",
"delete_modal_title": "Bist du dir sicher?",
"delete_modal_description": "Dies wird alle Installationsdateien von deinem Computer entfernen",
"install": "Installieren",
"download_in_progress": "Läuft",
"queued_downloads": "Downloads in Warteschlange",
"downloads_completed": "Abgeschlossen",
"queued": "In Warteschlange",
"no_downloads_title": "Welch Leere",
"no_downloads_description": "Du hast mit Hydra noch nichts heruntergeladen, aber es ist nie zu spät anzufangen.",
"checking_files": "Dateien werden überprüft…"
},
"settings": {
"downloads_path": "Download-Pfad",
"change": "Aktualisieren",
"notifications": "Benachrichtigungen",
"enable_download_notifications": "Wenn ein Download abgeschlossen wird",
"enable_repack_list_notifications": "Wenn ein neues Repack hinzugefügt wird",
"real_debrid_api_token_label": "Real-Debrid API Token",
"quit_app_instead_hiding": "Hydra verlassen statt minimieren beim Schließen",
"launch_with_system": "Hydra bei Systemstart starten",
"general": "Allgemein",
"behavior": "Verhalten",
"download_sources": "Download-Quellen",
"language": "Sprache",
"real_debrid_api_token": "API Token",
"enable_real_debrid": "Real-Debrid aktivieren",
"real_debrid_description": "Real-Debrid ist ein unrestriktiver Downloader, der es dir ermöglicht Dateien sofort und mit deiner maximalen Internetgeschwindigkeit herunterzuladen.",
"real_debrid_invalid_token": "API token nicht gültig",
"real_debrid_api_token_hint": "<0>Hier</0> kannst du dir deinen API Token holen",
"real_debrid_free_account_error": "Das Konto \"{{username}}\" ist ein gratis account. Bitte abonniere Real-Debrid",
"real_debrid_linked_message": "Konto \"{{username}}\" verknüpft",
"save_changes": "Änderungen speichern",
"changes_saved": "Änderungen erfolgreich gespeichert",
"download_sources_description": "Hydra wird die Download-Links von diesen Quellen abrufen. Die Quell-URL muss ein direkter Link zu einer .json Datei, welche die Download-Links enthält, sein.",
"validate_download_source": "Validieren",
"remove_download_source": "Entfernen",
"add_download_source": "Quelle hinzufügen",
"download_count_zero": "Keine Download-Option",
"download_count_one": "{{countFormatted}} Download-Option",
"download_count_other": "{{countFormatted}} Download-Optionen",
"download_source_url": "Download Quell-URL",
"add_download_source_description": "Füge die URL, welche die .json Datei enthält, ein",
"download_source_up_to_date": "Auf aktuellem Stand",
"download_source_errored": "Fehlgeschlagen",
"sync_download_sources": "Quellen synchronisieren",
"removed_download_source": "Download-Quelle entfernt",
"added_download_source": "Download-Quelle hinzugefügt",
"download_sources_synced": "Alle Download-Quellen sind synchronisiert",
"insert_valid_json_url": "Füge eine gültige JSON URL ein",
"found_download_option_zero": "Keine Download-Option gefunden",
"found_download_option_one": "{{countFormatted}} Download-Option gefunden",
"found_download_option_other": "{{countFormatted}} Download-Optionen gefunden",
"import": "Importieren"
},
"notifications": {
"download_complete": "Download abgeschlossen",
"game_ready_to_install": "{{title}} ist bereit zur Installation",
"repack_list_updated": "Repack-Liste aktualisiert",
"repack_count_one": "{{count}} Repack hinzugefügt",
"repack_count_other": "{{count}} Repacks hinzugefügt",
"new_update_available": "Version {{version}} verfügbar",
"restart_to_install_update": "Um das Update zu installieren, starte Hydra neu"
},
"system_tray": {
"open": "Hydra öffnen",
"quit": "Schließen"
},
"game_card": {
"no_downloads": "Keine Downloads verfügbar"
},
"binary_not_found_modal": {
"title": "Programme nicht installiert",
"description": "Ausführbare Dateien für Wine oder Lutris wurden auf deinem System nicht gefunden",
"instructions": "Überprüfe die korrekte Installation dieser für deine Linux-Distro, damit das Spiel normal laufen kann"
},
"modal": {
"close": "Knopf schließen"
},
"forms": {
"toggle_password_visibility": "Sichtbarkeit des Passworts umschalten"
},
"user_profile": {
"amount_hours": "{{amount}} Stunden",
"amount_minutes": "{{amount}} Minuten",
"last_time_played": "Zuletzt gespielt {{period}}",
"activity": "Letzte Aktivität",
"library": "Bibliothek",
"total_play_time": "Gesamtspielzeit: {{amount}}",
"no_recent_activity_title": "Hmmm… hier ist nichts",
"no_recent_activity_description": "Du hast in letzter Zeit keine Spiele gespielt. Es wird Zeit das zu ändern!",
"display_name": "Anzeigename",
"saving": "Speichert",
"save": "Speichern",
"edit_profile": "Profil Bearbeiten",
"saved_successfully": "Erfolgreich gespeichert",
"try_again": "Bitte versuche es erneut",
"sign_out_modal_title": "Bist du dir sicher?",
"cancel": "Abbrechen",
"successfully_signed_out": "Erfolgreich abgemeldet",
"sign_out": "Abmelden",
"playing_for": "Spielt {{amount}} lang",
"sign_out_modal_text": "Deine Bibliothek ist mit deinem aktuellen Konto verknüpft. Wenn du dich abmeldest, wird deine Bibliothek nicht mehr sichtbar sein und jeglicher Fortschritt wird nicht gespeichert. Abmelden fortführen?",
"add_friends": "Freunde hinzufügen",
"add": "Hinzufügen",
"friend_code": "Freundescode",
"see_profile": "Profil anzeigen",
"sending": "Sendet",
"friend_request_sent": "Freundschaftsanfrage versendet",
"friends": "Freunde",
"friends_list": "Freundesliste",
"user_not_found": "Nutzer nicht gefunden",
"block_user": "Nutzer blockieren",
"add_friend": "Freund hinzufügen",
"request_sent": "Anfrage versendet",
"request_received": "Anfrage erhalten",
"accept_request": "Anfrage annehmen",
"ignore_request": "Anfrage ignorieren",
"cancel_request": "Anfrage zurückziehen",
"undo_friendship": "Freundschaft kündigen",
"request_accepted": "Anfrage akzeptiert",
"user_blocked_successfully": "Nutzer erfolgreich blockiert",
"user_block_modal_text": "{{displayName}} wird dadurch blockiert",
"blocked_users": "Blockierte Nutzer",
"unblock": "Freigeben",
"no_friends_added": "Du hast noch keine Freunde hinzugefügt",
"pending": "Ausstehend",
"no_pending_invites": "Du hast keine ausstehenden Einladungen",
"no_blocked_users": "Du hast keine blockierten Nutzer",
"friend_code_copied": "Freundescode kopiert",
"undo_friendship_modal_text": "Freundschaft mit {{displayName}} wird dadurch gekündigt"
}
}

View File

@@ -1,4 +1,5 @@
{
"language_name": "English",
"app": {
"successfully_signed_in": "Successfully signed in"
},
@@ -6,7 +7,10 @@
"featured": "Featured",
"trending": "Trending",
"surprise_me": "Surprise me",
"no_results": "No results found"
"no_results": "No results found",
"start_typing": "Starting typing to search...",
"hot": "Hot now",
"weekly": "📅 Top games of the week"
},
"sidebar": {
"catalogue": "Catalogue",
@@ -20,7 +24,8 @@
"home": "Home",
"queued": "{{title}} (Queued)",
"game_has_no_executable": "Game has no executable selected",
"sign_in": "Sign in"
"sign_in": "Sign in",
"friends": "Friends"
},
"header": {
"search": "Search games",
@@ -113,7 +118,19 @@
"download_paused": "Download paused",
"last_downloaded_option": "Last downloaded option",
"create_shortcut_success": "Shortcut created successfully",
"create_shortcut_error": "Error creating shortcut"
"create_shortcut_error": "Error creating shortcut",
"nsfw_content_title": "This game contains innapropriate content",
"nsfw_content_description": "{{title}} contains content that may not be suitable for all ages. Are you sure you want to continue?",
"allow_nsfw_content": "Continue",
"refuse_nsfw_content": "Go back",
"stats": "Stats",
"download_count": "Downloads",
"player_count": "Active players",
"download_error": "This download option is not available",
"download": "Download",
"executable_path_in_use": "Executable already in use by \"{{game}}\"",
"warning": "Warning:",
"hydra_needs_to_remain_open": "for this download, Hydra needs to remain open util its conclusion. In case Hydra closes before the conclusion, you will lose your progress."
},
"activation": {
"title": "Activate Hydra",
@@ -174,12 +191,9 @@
"validate_download_source": "Validate",
"remove_download_source": "Remove",
"add_download_source": "Add source",
"download_count_zero": "No downloads in list",
"download_count_one": "{{countFormatted}} download in list",
"download_count_other": "{{countFormatted}} downloads in list",
"download_options_zero": "No download available",
"download_options_one": "{{countFormatted}} download available",
"download_options_other": "{{countFormatted}} downloads available",
"download_count_zero": "No download options",
"download_count_one": "{{countFormatted}} download option",
"download_count_other": "{{countFormatted}} download options",
"download_source_url": "Download source URL",
"add_download_source_description": "Insert the URL containing the .json file",
"download_source_up_to_date": "Up-to-date",
@@ -192,14 +206,27 @@
"found_download_option_zero": "No download option found",
"found_download_option_one": "Found {{countFormatted}} download option",
"found_download_option_other": "Found {{countFormatted}} download options",
"import": "Import"
"import": "Import",
"public": "Public",
"private": "Private",
"friends_only": "Friends only",
"privacy": "Privacy",
"profile_visibility": "Profile visibility",
"profile_visibility_description": "Choose who can see your profile and library",
"required_field": "This field is required",
"source_already_exists": "This source has been already added",
"must_be_valid_url": "The source must be a valid URL",
"blocked_users": "Blocked users",
"user_unblocked": "User has been unblocked"
},
"notifications": {
"download_complete": "Download complete",
"game_ready_to_install": "{{title}} is ready to install",
"repack_list_updated": "Repack list updated",
"repack_count_one": "{{count}} repack added",
"repack_count_other": "{{count}} repacks added"
"repack_count_other": "{{count}} repacks added",
"new_update_available": "Version {{version}} available",
"restart_to_install_update": "Restart Hydra to install the update"
},
"system_tray": {
"open": "Open Hydra",
@@ -239,6 +266,51 @@
"successfully_signed_out": "Successfully signed out",
"sign_out": "Sign out",
"playing_for": "Playing for {{amount}}",
"sign_out_modal_text": "Your library is linked with your current account. When signing out, your library will not be visible anymore, and any progress will not be saved. Continue with sign out?"
"sign_out_modal_text": "Your library is linked with your current account. When signing out, your library will not be visible anymore, and any progress will not be saved. Continue with sign out?",
"add_friends": "Add Friends",
"add": "Add",
"friend_code": "Friend code",
"see_profile": "See profile",
"sending": "Sending",
"friend_request_sent": "Friend request sent",
"friends": "Friends",
"friends_list": "Friends list",
"user_not_found": "User not found",
"block_user": "Block user",
"add_friend": "Add friend",
"request_sent": "Request sent",
"request_received": "Request received",
"accept_request": "Accept request",
"ignore_request": "Ignore request",
"cancel_request": "Cancel request",
"undo_friendship": "Undo friendship",
"request_accepted": "Request accepted",
"user_blocked_successfully": "User blocked successfully",
"user_block_modal_text": "This will block {{displayName}}",
"blocked_users": "Blocked users",
"unblock": "Unblock",
"no_friends_added": "You still don't have added friends",
"pending": "Pending",
"no_pending_invites": "You have no pending invites",
"no_blocked_users": "You have no blocked users",
"friend_code_copied": "Friend code copied",
"undo_friendship_modal_text": "This will undo your friendship with {{displayName}}",
"privacy_hint": "To adjust who can see this, go to the <0>Settings</0>",
"locked_profile": "This profile is private",
"image_process_failure": "Failure while processing the image",
"required_field": "This field is required",
"displayname_min_length": "Display name must be at least 3 characters long",
"displayname_max_length": "Display name must be at most 50 characters long",
"report_profile": "Report this profile",
"report_reason": "Why are you reporting this profile?",
"report_description": "Additional information",
"report_description_placeholder": "Additional information",
"report": "Report",
"report_reason_hate": "Hate speech",
"report_reason_sexual_content": "Sexual content",
"report_reason_violence": "Violence",
"report_reason_spam": "Spam",
"report_reason_other": "Other",
"profile_reported": "Profile reported"
}
}

View File

@@ -1,4 +1,5 @@
{
"language_name": "Español",
"app": {
"successfully_signed_in": "Sesión iniciada correctamente"
},
@@ -6,7 +7,10 @@
"featured": "Destacado",
"trending": "Tendencias",
"surprise_me": "¡Sorpréndeme!",
"no_results": "No se encontraron resultados"
"no_results": "No se encontraron resultados",
"hot": "Caliente ahora",
"weekly": "📅 Los mejores juegos de la semana",
"start_typing": "Empieza a escribir para buscar..."
},
"sidebar": {
"catalogue": "Catálogo",
@@ -20,7 +24,8 @@
"home": "Inicio",
"queued": "{{title}} (En Cola)",
"game_has_no_executable": "El juego no tiene un ejecutable",
"sign_in": "Iniciar sesión"
"sign_in": "Iniciar sesión",
"friends": "Amigos"
},
"header": {
"search": "Buscar juegos",
@@ -48,7 +53,7 @@
"download_options_zero": "No hay opciones de descargas disponibles",
"download_options_one": "{{count}} opción de descarga",
"download_options_other": "{{count}} opciones de descargas",
"updated_at": "Actualizado el {{updated_at}}",
"updated_at": "Actualizado el: {{updated_at}}",
"install": "Instalar",
"resume": "Continuar",
"pause": "Pausa",
@@ -74,7 +79,7 @@
"remove_from_library": "Eliminar de la biblioteca",
"no_downloads": "No hay descargas disponibles",
"play_time": "Jugado por {{amount}}",
"last_time_played": "Jugado por última vez {{period}}",
"last_time_played": "Jugado por última vez: {{period}}",
"not_played_yet": "Aún no has jugado a {{title}}",
"next_suggestion": "Siguiente sugerencia",
"play": "Jugar",
@@ -107,13 +112,23 @@
"executable_section_description": "Ruta del archivo que se ejecutará cuando se presione \"Jugar\"",
"downloads_secion_title": "Descargas",
"downloads_section_description": "Buscar actualizaciones u otras versiones de este juego",
"danger_zone_section_title": "Zona de Peligro",
"danger_zone_section_description": "Eliminar este juego de tu librería o los archivos descargados por Hydra",
"danger_zone_section_title": "Opciones Avanzadas",
"danger_zone_section_description": "Eliminar este juego de tu librería o los archivos descargados por Hydra (Esto solo eliminará los archivos de instalación y no el juego instalado)",
"download_in_progress": "Descarga en progreso",
"download_paused": "Descarga pausada",
"last_downloaded_option": "Última opción descargada",
"create_shortcut_success": "Atajo creado con éxito",
"create_shortcut_error": "Error al crear un atajo"
"create_shortcut_error": "Error al crear un atajo",
"allow_nsfw_content": "Continuar",
"download": "Descargar",
"download_count": "Descargas",
"download_error": "Esta opción de descarga no está disponible.",
"executable_path_in_use": "Ejecutable ya en uso por \"{{game}}\"",
"nsfw_content_description": "{{title}} incluye contenido que puede no ser adecuado para todas las edades. \n¿Estás seguro de que quieres continuar?",
"nsfw_content_title": "Este juego contiene contenido inapropiado.",
"player_count": "Jugadores activos",
"refuse_nsfw_content": "Volver",
"stats": "Estadísticas"
},
"activation": {
"title": "Activar Hydra",
@@ -138,7 +153,7 @@
"deleting": "Eliminando instalador…",
"delete": "Eliminar instalador",
"delete_modal_title": "¿Estás seguro?",
"delete_modal_description": "Esto eliminará todos los archivos de instalación de tu computadora.",
"delete_modal_description": "Esto eliminará todos los archivos de la instalación del repack del juego de tu computadora. (Si ya instalaste el juego, puedes eliminar esto, no afectará al juego)",
"install": "Instalar",
"download_in_progress": "En progreso",
"queued_downloads": "Descargas en cola",
@@ -177,9 +192,6 @@
"download_count_zero": "No hay descargas en la lista",
"download_count_one": "{{countFormatted}} descarga en la lista",
"download_count_other": "{{countFormatted}} descargas en la lista",
"download_options_zero": "No hay descargas disponibles",
"download_options_one": "{{countFormatted}} descarga disponible",
"download_options_other": "{{countFormatted}} descargas disponibles",
"download_source_url": "Descargar URL de origen",
"add_download_source_description": "Introduce la URL con el archivo .json",
"download_source_up_to_date": "Al día",
@@ -192,14 +204,30 @@
"found_download_option_zero": "No se encontró una opción de descarga",
"found_download_option_one": "Se encontró {{countFormatted}} opción de descarga",
"found_download_option_other": "Se encontraron {{countFormatted}} opciones de descarga",
"import": "Importar"
"import": "Importar",
"blocked_users": "Usuarios bloqueados",
"download_options_one": "",
"download_options_other": "",
"download_options_zero": "",
"friends_only": "solo amigos",
"must_be_valid_url": "La fuente debe ser una URL válida.",
"privacy": "Privacidad",
"private": "Privado",
"profile_visibility": "Visibilidad del perfil",
"profile_visibility_description": "Elige quién puede ver tu perfil y biblioteca",
"public": "Público",
"required_field": "Este campo es obligatorio",
"source_already_exists": "Esta fuente ya ha sido agregada.",
"user_unblocked": "El usuario ha sido desbloqueado"
},
"notifications": {
"download_complete": "Descarga completada",
"game_ready_to_install": "{{title}} está listo para instalarse",
"repack_list_updated": "Lista de repacks actualizadas",
"repack_count_one": "{{count}} repack ha sido añadido",
"repack_count_other": "{{count}} repacks añadidos"
"repack_count_other": "{{count}} repacks añadidos",
"new_update_available": "Version {{version}} disponible",
"restart_to_install_update": "Reinicia Hydra para instalar la actualización"
},
"system_tray": {
"open": "Abrir Hydra",
@@ -222,13 +250,13 @@
"user_profile": {
"amount_hours": "{{amount}} horas",
"amount_minutes": "{{amount}} minutos",
"last_time_played": "Última vez jugado {{period}}",
"last_time_played": "Última vez jugado: {{period}}",
"activity": "Actividad reciente",
"library": "Biblioteca",
"total_play_time": "Total de tiempo jugado: {{amount}}",
"no_recent_activity_title": "Que raro, no hay nada por acá, ¿que tal si jugamos algo para empezar?",
"no_recent_activity_title": "Que raro, no hay nada por acá...",
"no_recent_activity_description": "No has jugado ningún juego recientemente, ¡vamos a cambiar eso ahora!",
"display_name": "Nombre a mostrar",
"display_name": "Nombre en pantalla",
"saving": "Guardando",
"save": "Guardar",
"edit_profile": "Editar perfil",
@@ -239,6 +267,52 @@
"successfully_signed_out": "Sesión cerrada exitosamente",
"sign_out": "Cerrar sesión",
"playing_for": "Jugando por {{amount}}",
"sign_out_modal_text": "Tu biblioteca se ha vinculado con tu cuenta. Cuando cierres sesión, tú biblioteca ya no será visible y cualquier progreso no se guardará. ¿Continuar con el cierre de sesión?"
"sign_out_modal_text": "Tu biblioteca se ha vinculado con tu cuenta. Cuando cierres sesión, tú biblioteca ya no será visible y cualquier progreso no se guardará. ¿Continuar con el cierre de sesión?",
"add_friends": "Añadir amigos",
"add": "Añadir",
"friend_code": "Código de amigo",
"see_profile": "Ver perfil",
"sending": "Enviando",
"friend_request_sent": "Solicitud de amistad enviada",
"friends": "Amigos",
"friends_list": "Lista de amigos",
"user_not_found": "Usuario no encontrado",
"block_user": "Bloquear usuario",
"add_friend": "Añadir amigo",
"request_sent": "Solicitud enviada",
"request_received": "Solicitud recibida",
"accept_request": "Aceptar solicitud",
"ignore_request": "Ignorar solicitud",
"cancel_request": "Cancelar solicitud",
"undo_friendship": "Eliminar amistad",
"request_accepted": "Solicitud aceptada",
"user_blocked_successfully": "Usuario bloqueado exitosamente",
"user_block_modal_text": "Esto va a bloquear a {{displayName}}",
"blocked_users": "Usuarios bloqueados",
"unblock": "Desbloquear",
"no_friends_added": "Todavía no tienes amigos añadidos",
"pending": "Pendiente",
"no_pending_invites": "No tienes invitaciones pendientes",
"no_blocked_users": "No has bloqueado a ningún usuario",
"friend_code_copied": "Código de amigo copiado",
"undo_friendship_modal_text": "Esto deshará tu amistad con {{displayName}}",
"displayname_max_length": "El nombre para mostrar debe tener como máximo 50 caracteres",
"displayname_min_length": "El nombre para mostrar debe tener al menos 3 caracteres",
"locked_profile": "Este perfil es privado.",
"privacy_hint": "Para ajustar quién puede ver esto, ve a <0>Configuración</0>.",
"profile_locked": "",
"profile_reported": "Perfil reportado",
"report": "Informe",
"report_description": "Información adicional",
"report_description_placeholder": "Información adicional",
"report_profile": "Reportar este perfil",
"report_reason": "¿Por qué estás denunciando este perfil?",
"report_reason_hate": "Discurso de odio",
"report_reason_other": "Otro",
"report_reason_sexual_content": "Contenido sexual",
"report_reason_spam": "Correo basura",
"report_reason_violence": "Violencia",
"required_field": "Este campo es obligatorio",
"image_process_failure": "Error al procesar la imagen"
}
}

View File

@@ -1,4 +1,5 @@
{
"language_name": "فارسی",
"home": {
"featured": "پیشنهادی",
"trending": "پرطرفدار",

View File

@@ -1,4 +1,5 @@
{
"language_name": "Français",
"home": {
"featured": "En vedette",
"trending": "Tendance",

View File

@@ -1,4 +1,5 @@
{
"language_name": "Magyar",
"home": {
"featured": "Featured",
"trending": "Népszerű",

View File

@@ -1,134 +1,256 @@
{
"language_name": "Bahasa Indonesia",
"app": {
"successfully_signed_in": "Berhasil masuk"
},
"home": {
"featured": "Unggulan",
"trending": "Trending",
"surprise_me": "Kejutkan Saya",
"no_results": "Tidak ada hasil"
"trending": "Sedang Tren",
"surprise_me": "Kejutkan saya",
"no_results": "Tidak ada hasil ditemukan"
},
"sidebar": {
"catalogue": "Katalog",
"downloads": "Unduhan",
"settings": "Pengaturan",
"my_library": "Koleksi saya",
"my_library": "Perpustakaan saya",
"downloading_metadata": "{{title}} (Mengunduh metadata…)",
"paused": "{{title}} (Terhenti)",
"paused": "{{title}} (Dijeda)",
"downloading": "{{title}} ({{percentage}} - Mengunduh…)",
"filter": "Filter koleksi",
"home": "Beranda"
"filter": "Filter perpustakaan",
"home": "Beranda",
"queued": "{{title}} (Antrian)",
"game_has_no_executable": "Game tidak punya file eksekusi yang dipilih",
"sign_in": "Masuk"
},
"header": {
"search": "Pencarian",
"search": "Cari game",
"home": "Beranda",
"catalogue": "Katalog",
"downloads": "Unduhan",
"search_results": "Hasil pencarian",
"settings": "Pengaturan"
"settings": "Pengaturan",
"version_available_install": "Versi {{version}} tersedia. Klik di sini untuk restart dan instal.",
"version_available_download": "Versi {{version}} tersedia. Klik di sini untuk unduh."
},
"bottom_panel": {
"no_downloads_in_progress": "Tidak ada unduhan berjalan",
"downloading_metadata": "Mengunduh metadata {{title}}...",
"downloading": "Mengunduh {{title}}… ({{percentage}} selesai) - Perkiraan {{eta}} - {{speed}}"
"no_downloads_in_progress": "Tidak ada unduhan yang sedang berjalan",
"downloading_metadata": "Mengunduh metadata {{title}}",
"downloading": "Mengunduh {{title}}… ({{percentage}} selesai) - Estimasi selesai {{eta}} - {{speed}}",
"calculating_eta": "Mengunduh {{title}}… ({{percentage}} selesai) - Menghitung waktu yang tersisa…",
"checking_files": "Memeriksa file {{title}}… ({{percentage}} selesai)"
},
"catalogue": {
"next_page": "Halaman berikutnya",
"previous_page": "Halaman sebelumnya"
"next_page": "Halaman Berikutnya",
"previous_page": "Halaman Sebelumnya"
},
"game_details": {
"open_download_options": "Buka opsi unduhan",
"download_options_zero": "Tidak ada opsi unduhan",
"download_options_one": "{{count}} opsi unduhan",
"download_options_other": "{{count}} opsi unduhan",
"updated_at": "Diperbarui {{updated_at}}",
"install": "Install",
"updated_at": "Diperbarui pada {{updated_at}}",
"install": "Instal",
"resume": "Lanjutkan",
"pause": "Hentikan sementara",
"cancel": "Batalkan",
"pause": "Jeda",
"cancel": "Batal",
"remove": "Hapus",
"space_left_on_disk": "{{space}} tersisa pada disk",
"eta": "Perkiraan {{eta}}",
"space_left_on_disk": "{{space}} tersisa di disk",
"eta": "Estimasi {{eta}}",
"calculating_eta": "Menghitung waktu yang tersisa…",
"downloading_metadata": "Mengunduh metadata…",
"filter": "Saring repacks",
"requirements": "Keperluan sistem",
"filter": "Filter repack",
"requirements": "Persyaratan sistem",
"minimum": "Minimum",
"recommended": "Rekomendasi",
"recommended": "Dianjurkan",
"paused": "Dijeda",
"release_date": "Dirilis pada {{date}}",
"publisher": "Dipublikasikan oleh {{publisher}}",
"publisher": "Diterbitkan oleh {{publisher}}",
"hours": "jam",
"minutes": "menit",
"amount_hours": "{{amount}} jam",
"amount_minutes": "{{amount}} menit",
"accuracy": "{{accuracy}}% akurasi",
"add_to_library": "Tambahkan ke koleksi",
"remove_from_library": "Hapus dari koleksi",
"no_downloads": "Tidak ada unduhan tersedia",
"add_to_library": "Tambah ke perpustakaan",
"remove_from_library": "Hapus dari perpustakaan",
"no_downloads": "Tidak ada yang bisa diunduh",
"play_time": "Dimainkan selama {{amount}}",
"last_time_played": "Terakhir dimainkan {{period}}",
"not_played_yet": "Kamu belum memainkan {{title}}",
"next_suggestion": "Rekomendasi berikutnya",
"play": "Mainkan",
"next_suggestion": "Saran berikutnya",
"play": "Main",
"deleting": "Menghapus installer…",
"close": "Tutup",
"playing_now": "Memainkan sekarang",
"playing_now": "Sedang dimainkan",
"change": "Ubah",
"repacks_modal_description": "Pilih repack yang kamu ingin unduh",
"select_folder_hint": "Untuk merubah folder bawaan, akses melalui",
"download_now": "Unduh sekarang"
"repacks_modal_description": "Pilih repack yang ingin kamu unduh",
"select_folder_hint": "Untuk ganti folder default, buka <0>Pengaturan</0>",
"download_now": "Unduh sekarang",
"no_shop_details": "Gagal mendapatkan detail toko.",
"download_options": "Opsi unduhan",
"download_path": "Path unduhan",
"previous_screenshot": "Screenshot sebelumnya",
"next_screenshot": "Screenshot berikutnya",
"screenshot": "Screenshot {{number}}",
"open_screenshot": "Buka screenshot {{number}}",
"download_settings": "Pengaturan unduhan",
"downloader": "Pengunduh",
"select_executable": "Pilih",
"no_executable_selected": "Tidak ada file eksekusi yang dipilih",
"open_folder": "Buka folder",
"open_download_location": "Lihat file yang diunduh",
"create_shortcut": "Buat pintasan desktop",
"remove_files": "Hapus file",
"remove_from_library_title": "Apa kamu yakin?",
"remove_from_library_description": "Ini akan menghapus {{game}} dari perpustakaan kamu",
"options": "Opsi",
"executable_section_title": "Eksekusi",
"executable_section_description": "Path file eksekusi saat \"Main\" diklik",
"downloads_secion_title": "Unduhan",
"downloads_section_description": "Cek update atau versi lain dari game ini",
"danger_zone_section_title": "Zona Berbahaya",
"danger_zone_section_description": "Hapus game ini dari perpustakaan kamu atau file yang diunduh oleh Hydra",
"download_in_progress": "Sedang mengunduh",
"download_paused": "Unduhan dijeda",
"last_downloaded_option": "Opsi terakhir diunduh",
"create_shortcut_success": "Pintasan berhasil dibuat",
"create_shortcut_error": "Gagal membuat pintasan"
},
"activation": {
"title": "Aktivasi Hydra",
"installation_id": "ID instalasi:",
"enter_activation_code": "Masukkan kode aktivasi",
"message": "Jika kamu tidak tau dimana bertanya untuk ini, maka kamu tidak seharusnya memiliki ini.",
"title": "Aktifkan Hydra",
"installation_id": "ID Instalasi:",
"enter_activation_code": "Masukkan kode aktivasi kamu",
"message": "Kalau tidak tahu harus tanya ke siapa, berarti kamu tidak perlu ini.",
"activate": "Aktifkan",
"loading": "Memuat…"
},
"downloads": {
"resume": "Lanjutkan",
"pause": "Hentikan sementara",
"eta": "Perkiraan {{eta}}",
"paused": "Terhenti sementara",
"verifying": "Memeriksa…",
"pause": "Jeda",
"eta": "Estimasi {{eta}}",
"paused": "Dijeda",
"verifying": "Verifikasi…",
"completed": "Selesai",
"cancel": "Batalkan",
"filter": "Saring game yang diunduh",
"removed": "Tidak diunduh",
"cancel": "Batal",
"filter": "Filter game yang diunduh",
"remove": "Hapus",
"downloading_metadata": "Mengunduh metadata…",
"deleting": "Menghapus file instalasi…",
"delete": "Hapus file instalasi",
"delete_modal_title": "Kamu yakin?",
"delete_modal_description": "Proses ini akan menghapus semua file instalasi dari komputer kamu",
"install": "Install"
"deleting": "Menghapus installer…",
"delete": "Hapus installer",
"delete_modal_title": "Apa kamu yakin?",
"delete_modal_description": "Ini akan menghapus semua file instalasi dari komputer kamu",
"install": "Instal",
"download_in_progress": "Sedang berlangsung",
"queued_downloads": "Unduhan dalam antrian",
"downloads_completed": "Selesai",
"queued": "Dalam antrian",
"no_downloads_title": "Kosong",
"no_downloads_description": "Kamu belum mengunduh apa pun dengan Hydra, tapi belum terlambat untuk mulai.",
"checking_files": "Memeriksa file…"
},
"settings": {
"downloads_path": "Lokasi unduhan",
"change": "Perbarui",
"notifications": "Pengingat",
"downloads_path": "Path unduhan",
"change": "Ganti",
"notifications": "Notifikasi",
"enable_download_notifications": "Saat unduhan selesai",
"enable_repack_list_notifications": "Saat repack terbaru ditambahkan",
"enable_repack_list_notifications": "Saat ada repack baru",
"real_debrid_api_token_label": "Token API Real-Debrid",
"quit_app_instead_hiding": "Jangan sembunyikan Hydra saat ditutup",
"launch_with_system": "Jalankan Hydra saat sistem dinyalakan",
"general": "Umum",
"behavior": "Perilaku",
"quit_app_instead_hiding": "Tutup aplikasi alih-alih menyembunyikan aplikasi",
"launch_with_system": "Jalankan saat memulai sistem"
"download_sources": "Sumber unduhan",
"language": "Bahasa",
"real_debrid_api_token": "Token API",
"enable_real_debrid": "Aktifkan Real-Debrid",
"real_debrid_description": "Real-Debrid adalah downloader tanpa batas yang memungkinkan kamu untuk mengunduh file dengan cepat dan pada kecepatan terbaik dari Internet kamu.",
"real_debrid_invalid_token": "Token API tidak valid",
"real_debrid_api_token_hint": "Kamu bisa dapatkan token API di <0>sini</0>",
"real_debrid_free_account_error": "Akun \"{{username}}\" adalah akun gratis. Silakan berlangganan Real-Debrid",
"real_debrid_linked_message": "Akun \"{{username}}\" terhubung",
"save_changes": "Simpan perubahan",
"changes_saved": "Perubahan disimpan berhasil",
"download_sources_description": "Hydra akan mencari link unduhan dari sini. URL harus menuju file .json dengan link unduhan.",
"validate_download_source": "Validasi",
"remove_download_source": "Hapus",
"add_download_source": "Tambahkan sumber",
"download_count_zero": "Tidak ada unduhan dalam daftar",
"download_count_one": "{{countFormatted}} unduhan dalam daftar",
"download_count_other": "{{countFormatted}} unduhan dalam daftar",
"download_options_zero": "Tidak ada unduhan tersedia",
"download_options_one": "{{countFormatted}} unduhan tersedia",
"download_options_other": "{{countFormatted}} unduhan tersedia",
"download_source_url": "URL sumber unduhan",
"add_download_source_description": "Masukkan URL yang berisi file .json",
"download_source_up_to_date": "Terkini",
"download_source_errored": "Terjadi kesalahan",
"sync_download_sources": "Sinkronkan sumber",
"removed_download_source": "Sumber unduhan dihapus",
"added_download_source": "Sumber unduhan ditambahkan",
"download_sources_synced": "Semua sumber unduhan disinkronkan",
"insert_valid_json_url": "Masukkan URL JSON yang valid",
"found_download_option_zero": "Tidak ada opsi unduhan ditemukan",
"found_download_option_one": "Ditemukan {{countFormatted}} opsi unduhan",
"found_download_option_other": "Ditemukan {{countFormatted}} opsi unduhan",
"import": "Impor"
},
"notifications": {
"download_complete": "Unduhan selesai",
"game_ready_to_install": "{{title}} sudah siap untuk instalasi",
"game_ready_to_install": "{{title}} siap untuk diinstal",
"repack_list_updated": "Daftar repack diperbarui",
"repack_count_one": "{{count}} repack ditambahkan",
"repack_count_other": "{{count}} repack ditambahkan"
"repack_count_other": "{{count}} repack ditambahkan",
"new_update_available": "Versi {{version}} tersedia",
"restart_to_install_update": "Restart Hydra untuk instal pembaruan"
},
"system_tray": {
"open": "Buka Hydra",
"quit": "Tutup"
"quit": "Keluar"
},
"game_card": {
"no_downloads": "Tidak ada unduhan tersedia"
"no_downloads": "Tidak ada unduhan yang tersedia"
},
"binary_not_found_modal": {
"title": "Program tidak terinstal",
"description": "Wine atau Lutris exe tidak ditemukan pada sistem kamu",
"instructions": "Periksa cara instalasi yang benar pada Linux distro-mu agar game dapat dimainkan dengan benar"
"title": "Program tidak terpasang",
"description": "Executable Wine atau Lutris tidak ditemukan di sistem kamu",
"instructions": "Cek cara instalasi yang benar di distro Linux kamu agar game bisa jalan normal"
},
"modal": {
"close": "Tombol tutup"
"close": "Tutup"
},
"forms": {
"toggle_password_visibility": "Tampilkan/Sembunyikan kata sandi"
},
"user_profile": {
"amount_hours": "{{amount}} jam",
"amount_minutes": "{{amount}} menit",
"last_time_played": "Terakhir dimainkan {{period}}",
"activity": "Aktivitas terbaru",
"library": "Perpustakaan",
"total_play_time": "Total waktu bermain: {{amount}}",
"no_recent_activity_title": "Hmm… kosong di sini",
"no_recent_activity_description": "Kamu belum main game baru-baru ini. Yuk, mulai main!",
"display_name": "Nama tampilan",
"saving": "Menyimpan",
"save": "Simpan",
"edit_profile": "Edit Profil",
"saved_successfully": "Berhasil disimpan",
"try_again": "Coba lagi yuk",
"sign_out_modal_title": "Apa kamu yakin?",
"cancel": "Batal",
"successfully_signed_out": "Berhasil keluar",
"sign_out": "Keluar",
"playing_for": "Bermain selama {{amount}}",
"sign_out_modal_text": "Perpustakaan kamu terhubung dengan akun saat ini. Saat keluar, perpustakaan kamu tidak akan terlihat lagi, dan progres tidak akan disimpan. Lanjutkan keluar?",
"add_friends": "Tambah Teman",
"add": "Tambah",
"friend_code": "Kode teman",
"see_profile": "Lihat profil",
"sending": "Mengirim",
"friend_request_sent": "Permintaan teman terkirim",
"friends": "Teman",
"friends_list": "Daftar teman",
"user_not_found": "Pengguna tidak ditemukan"
}
}

View File

@@ -1,21 +1,51 @@
export { default as en } from "./en/translation.json";
export { default as pt } from "./pt/translation.json";
export { default as es } from "./es/translation.json";
export { default as nl } from "./nl/translation.json";
export { default as fr } from "./fr/translation.json";
export { default as hu } from "./hu/translation.json";
export { default as it } from "./it/translation.json";
export { default as pl } from "./pl/translation.json";
export { default as ru } from "./ru/translation.json";
export { default as tr } from "./tr/translation.json";
export { default as be } from "./be/translation.json";
export { default as uk } from "./uk/translation.json";
export { default as zh } from "./zh/translation.json";
export { default as id } from "./id/translation.json";
export { default as ko } from "./ko/translation.json";
export { default as da } from "./da/translation.json";
export { default as ar } from "./ar/translation.json";
export { default as fa } from "./fa/translation.json";
export { default as ro } from "./ro/translation.json";
export { default as ca } from "./ca/translation.json";
export { default as kk } from "./kk/translation.json";
import en from "./en/translation.json";
import ptPT from "./pt-PT/translation.json";
import ptBR from "./pt-BR/translation.json";
import es from "./es/translation.json";
import nl from "./nl/translation.json";
import fr from "./fr/translation.json";
import hu from "./hu/translation.json";
import it from "./it/translation.json";
import de from "./de/translation.json";
import pl from "./pl/translation.json";
import ru from "./ru/translation.json";
import tr from "./tr/translation.json";
import be from "./be/translation.json";
import uk from "./uk/translation.json";
import zh from "./zh/translation.json";
import id from "./id/translation.json";
import ko from "./ko/translation.json";
import da from "./da/translation.json";
import ar from "./ar/translation.json";
import fa from "./fa/translation.json";
import ro from "./ro/translation.json";
import ca from "./ca/translation.json";
import kk from "./kk/translation.json";
import cs from "./cs/translation.json";
export default {
"pt-BR": ptBR,
"pt-PT": ptPT,
en,
de,
es,
nl,
fr,
hu,
it,
pl,
ru,
tr,
be,
uk,
zh,
id,
ko,
da,
ar,
fa,
ro,
ca,
kk,
cs,
};

View File

@@ -1,4 +1,5 @@
{
"language_name": "Italiano",
"home": {
"featured": "In primo piano",
"trending": "Di tendenza",

View File

@@ -1,4 +1,5 @@
{
"language_name": "қазақ тілі",
"app": {
"successfully_signed_in": "Сәтті кіру"
},

View File

@@ -1,4 +1,5 @@
{
"language_name": "한국어",
"home": {
"featured": "추천",
"trending": "인기",

View File

@@ -1,4 +1,5 @@
{
"language_name": "Nederlands",
"home": {
"featured": "Uitgelicht",
"trending": "Trending",

View File

@@ -1,4 +1,5 @@
{
"language_name": "Polski",
"home": {
"featured": "Wyróżnione",
"trending": "Trendujące",

View File

@@ -1,26 +1,31 @@
{
"language_name": "Português (Brasil)",
"app": {
"successfully_signed_in": "Autenticado com sucesso"
},
"home": {
"featured": "Destaques",
"trending": "Populares",
"hot": "Populares agora",
"weekly": "📅 Mais baixados da semana",
"surprise_me": "Surpreenda-me",
"no_results": "Nenhum resultado encontrado"
"no_results": "Nenhum resultado encontrado",
"start_typing": "Comece a digitar para pesquisar…"
},
"sidebar": {
"catalogue": "Catálogo",
"downloads": "Downloads",
"settings": "Ajustes",
"my_library": "Minha biblioteca",
"my_library": "Biblioteca",
"downloading_metadata": "{{title}} (Baixando metadados…)",
"paused": "{{title}} (Pausado)",
"downloading": "{{title}} ({{percentage}} - Baixando…)",
"filter": "Filtrar biblioteca",
"filter": "Buscar",
"home": "Início",
"queued": "{{title}} (Na fila)",
"game_has_no_executable": "Jogo não possui executável selecionado",
"sign_in": "Login"
"sign_in": "Login",
"friends": "Amigos"
},
"header": {
"search": "Buscar jogos",
@@ -45,7 +50,7 @@
"download_options_one": "{{count}} opção de download",
"download_options_other": "{{count}} opções de download",
"updated_at": "Atualizado {{updated_at}}",
"resume": "Resumir",
"resume": "Retomar",
"pause": "Pausar",
"cancel": "Cancelar",
"remove": "Remover",
@@ -54,7 +59,7 @@
"calculating_eta": "Calculando tempo restante…",
"downloading_metadata": "Baixando metadados…",
"filter": "Filtrar repacks",
"requirements": "Requisitos do sistema",
"requirements": "Requisitos de sistema",
"minimum": "Mínimos",
"recommended": "Recomendados",
"paused": "Pausado",
@@ -68,16 +73,16 @@
"add_to_library": "Adicionar à biblioteca",
"remove_from_library": "Remover da biblioteca",
"no_downloads": "Nenhum download disponível",
"play_time": "Jogado por {{amount}}",
"play_time": "Jogou por {{amount}}",
"next_suggestion": "Próxima sugestão",
"install": "Instalar",
"last_time_played": "Jogou por último {{period}}",
"last_time_played": "Última sessão {{period}}",
"play": "Jogar",
"not_played_yet": "Você ainda não jogou {{title}}",
"close": "Fechar",
"deleting": "Excluindo instalador…",
"playing_now": "Jogando agora",
"change": "Mudar",
"change": "Explorar",
"repacks_modal_description": "Escolha o repack do jogo que deseja baixar",
"select_folder_hint": "Para trocar o diretório padrão, acesse a <0>Tela de Ajustes</0>",
"download_now": "Iniciar download",
@@ -90,13 +95,13 @@
"open_screenshot": "Ver captura de tela {{number}}",
"download_settings": "Ajustes do download",
"downloader": "Downloader",
"select_executable": "Selecionar",
"select_executable": "Explorar",
"no_executable_selected": "Nenhum executável selecionado",
"open_folder": "Abrir pasta",
"open_download_location": "Ver arquivos baixados",
"create_shortcut": "Criar atalho na área de trabalho",
"remove_files": "Remover arquivos",
"options": "Opções",
"options": "Gerenciar",
"remove_from_library_description": "Isso irá remover {{game}} da sua biblioteca",
"remove_from_library_title": "Tem certeza?",
"executable_section_title": "Executável",
@@ -109,7 +114,19 @@
"download_paused": "Download pausado",
"last_downloaded_option": "Última opção baixada",
"create_shortcut_success": "Atalho criado com sucesso",
"create_shortcut_error": "Erro ao criar atalho"
"create_shortcut_error": "Erro ao criar atalho",
"nsfw_content_title": "Este jogo contém conteúdo inapropriado",
"nsfw_content_description": "{{title}} contém conteúdo que pode não ser apropriado para todas as idades. Você deseja continuar?",
"allow_nsfw_content": "Continuar",
"refuse_nsfw_content": "Voltar",
"stats": "Estatísticas",
"download_count": "Downloads",
"player_count": "Jogadores ativos",
"download_error": "Essa opção de download falhou",
"download": "Baixar",
"executable_path_in_use": "Executável em uso por \"{{game}}\"",
"warning": "Aviso:",
"hydra_needs_to_remain_open": "para este download, o Hydra precisa ficar aberto até a conclusão. Caso o Hydra encerre antes da conclusão, perderá seu progresso."
},
"activation": {
"title": "Ativação",
@@ -120,7 +137,7 @@
"loading": "Carregando…"
},
"downloads": {
"resume": "Resumir",
"resume": "Retomar",
"pause": "Pausar",
"eta": "Conclusão {{eta}}",
"paused": "Pausado",
@@ -146,12 +163,12 @@
},
"settings": {
"downloads_path": "Diretório dos downloads",
"change": "Mudar",
"change": "Explorar...",
"notifications": "Notificações",
"enable_download_notifications": "Quando um download for concluído",
"enable_repack_list_notifications": "Quando a lista de repacks for atualizada",
"real_debrid_api_token_label": "Token de API do Real-Debrid",
"quit_app_instead_hiding": "Encerrar o Hydra ao invés de minimizá-lo ao fechar",
"quit_app_instead_hiding": "Encerrar o Hydra em vez de apenas minimizá-lo ao fechar.",
"launch_with_system": "Iniciar o Hydra junto com o sistema",
"general": "Geral",
"behavior": "Comportamento",
@@ -166,7 +183,7 @@
"real_debrid_linked_message": "Conta \"{{username}}\" vinculada",
"save_changes": "Salvar mudanças",
"changes_saved": "Ajustes salvos com sucesso",
"download_sources_description": "Hydra vai buscar links de download em todas as fonte habilitadas. A URL da fonte deve ser um link direto para um arquivo .json contendo uma lista de links.",
"download_sources_description": "Hydra vai buscar links de download em todas as fontes habilitadas. A URL da fonte deve ser um link direto para um arquivo .json contendo uma lista de links.",
"validate_download_source": "Validar",
"remove_download_source": "Remover",
"add_download_source": "Adicionar fonte",
@@ -188,14 +205,27 @@
"found_download_option_zero": "Nenhuma opção de download encontrada",
"found_download_option_one": "{{countFormatted}} opção de download encontrada",
"found_download_option_other": "{{countFormatted}} opções de download encontradas",
"import": "Importar"
"import": "Importar",
"privacy": "Privacidade",
"private": "Privado",
"friends_only": "Apenas amigos",
"public": "Público",
"profile_visibility": "Visibilidade do perfil",
"profile_visibility_description": "Escolha quem pode ver seu perfil e biblioteca",
"required_field": "Este campo é obrigatório",
"source_already_exists": "Essa fonte já foi adicionada",
"must_be_valid_url": "A fonte deve ser uma URL válida",
"blocked_users": "Usuários bloqueados",
"user_unblocked": "Usuário desbloqueado"
},
"notifications": {
"download_complete": "Download concluído",
"game_ready_to_install": "{{title}} está pronto para ser instalado",
"repack_list_updated": "Lista de repacks atualizada",
"repack_count_one": "{{count}} novo repack",
"repack_count_other": "{{count}} novos repacks"
"repack_count_other": "{{count}} novos repacks",
"new_update_available": "Versão {{version}} disponível",
"restart_to_install_update": "Reinicie o Hydra para instalar a nova versão"
},
"system_tray": {
"open": "Abrir Hydra",
@@ -206,7 +236,7 @@
},
"binary_not_found_modal": {
"title": "Programas não instalados",
"description": "Não foram encontrados no seu sistema os executáveis do Wine ou Lutris",
"description": "Os executáveis do Wine ou Lutris não foram encontrados em seu sistema.",
"instructions": "Verifique a forma correta de instalar algum deles no seu distro Linux, garantindo assim a execução normal do jogo"
},
"catalogue": {
@@ -222,8 +252,8 @@
"user_profile": {
"amount_hours": "{{amount}} horas",
"amount_minutes": "{{amount}} minutos",
"last_time_played": "Jogou {{period}}",
"activity": "Atividade recente",
"last_time_played": "Última sessão {{period}}",
"activity": "Atividades recentes",
"library": "Biblioteca",
"total_play_time": "Tempo total de jogo: {{amount}}",
"no_recent_activity_title": "Hmmm… nada por aqui",
@@ -231,14 +261,60 @@
"display_name": "Nome de exibição",
"saving": "Salvando…",
"save": "Salvar",
"edit_profile": "Editar Perfil",
"edit_profile": "Editar perfil",
"saved_successfully": "Salvo com sucesso",
"try_again": "Por favor, tente novamente",
"cancel": "Cancelar",
"successfully_signed_out": "Deslogado com sucesso",
"sign_out": "Sair da conta",
"sign_out_modal_title": "Tem certeza?",
"sign_out_modal_title": "Deseja mesmo sair?",
"playing_for": "Jogando por {{amount}}",
"sign_out_modal_text": "Sua biblioteca de jogos está associada com a sua conta atual. Ao sair, sua biblioteca não aparecerá mais no Hydra e qualquer progresso não será salvo. Deseja continuar?"
"sign_out_modal_text": "Sua biblioteca de jogos está associada com a sua conta atual. Ao sair, sua biblioteca não aparecerá mais no Hydra e qualquer progresso não será salvo. Deseja continuar?",
"add_friends": "Adicionar Amigos",
"friend_code": "Código de amigo",
"see_profile": "Ver perfil",
"friend_request_sent": "Pedido de amizade enviado",
"friends": "Amigos",
"add": "Adicionar",
"sending": "Enviando",
"friends_list": "Lista de amigos",
"user_not_found": "Usuário não encontrado",
"block_user": "Bloquear",
"add_friend": "Adicionar amigo",
"request_sent": "Pedido enviado",
"request_received": "Pedido recebido",
"accept_request": "Aceitar pedido",
"ignore_request": "Ignorar pedido",
"cancel_request": "Cancelar pedido",
"undo_friendship": "Desfazer amizade",
"request_accepted": "Pedido de amizade aceito",
"user_blocked_successfully": "Usuário bloqueado com sucesso",
"user_block_modal_text": "Bloquear {{displayName}}",
"blocked_users": "Usuários bloqueados",
"unblock": "Desbloquear",
"no_friends_added": "Você ainda não possui amigos adicionados",
"pending": "Pendentes",
"no_pending_invites": "Você não possui convites de amizade pendentes",
"no_blocked_users": "Você não tem nenhum usuário bloqueado",
"friend_code_copied": "Código de amigo copiado",
"undo_friendship_modal_text": "Isso irá remover sua amizade com {{displayName}}",
"privacy_hint": "Pra controlar quem pode ver seu perfil, acesse a <0>Tela de Configurações</0>",
"profile_locked": "Este perfil é privado",
"image_process_failure": "Falha ao processar a imagem",
"required_field": "Este campo é obrigatório",
"displayname_min_length": "Nome de exibição deve ter pelo menos 3 caracteres",
"displayname_max_length": "Nome de exibição deve ter no máximo 50 caracteres",
"locked_profile": "Este perfil é privado",
"report_profile": "Reportar este perfil",
"report_reason": "Por que você deseja reportar este perfil?",
"report_description": "Informações adicionais",
"report_description_placeholder": "Insira aqui",
"report": "Reportar",
"report_reason_hate": "Discurso de ódio",
"report_reason_sexual_content": "Conteúdo sexual",
"report_reason_violence": "Violência",
"report_reason_spam": "Spam",
"report_reason_other": "Outro",
"profile_reported": "Perfil reportado"
}
}

View File

@@ -0,0 +1,280 @@
{
"language_name": "Português (Portugal)",
"app": {
"successfully_signed_in": "Sessão iniciada com sucesso"
},
"home": {
"featured": "Destaques",
"trending": "Populares",
"surprise_me": "Surpreende-me",
"no_results": "Nenhum resultado encontrado",
"start_typing": "Comece a digitar para pesquisar…"
},
"sidebar": {
"catalogue": "Catálogo",
"downloads": "Transferências",
"settings": "Definições",
"my_library": "Biblioteca",
"downloading_metadata": "{{title}} (A transferir metadados…)",
"paused": "{{title}} (Pausado)",
"downloading": "{{title}} ({{percentage}} - A transferir…)",
"filter": "Procurar",
"home": "Início",
"queued": "{{title}} (Na fila)",
"game_has_no_executable": "Jogo não tem executável selecionado",
"sign_in": "Iniciar sessão"
},
"header": {
"search": "Procurar jogos",
"catalogue": "Catálogo",
"downloads": "Transferências",
"search_results": "Resultados da pesquisa",
"settings": "Definições",
"home": "Início",
"version_available_install": "Versão {{version}} disponível. Clique aqui para reiniciar e instalar.",
"version_available_download": "Versão {{version}} disponível. Clique aqui para fazer o download."
},
"bottom_panel": {
"no_downloads_in_progress": "Sem transferências em andamento",
"downloading_metadata": "A transferir metadados de {{title}}…",
"downloading": "A transferir {{title}}… ({{percentage}} concluído) - Conclusão {{eta}} - {{speed}}",
"calculating_eta": "A transferir {{title}}… ({{percentage}} concluído) - A calcular tempo restante…",
"checking_files": "A verificar ficheiros de {{title}}…"
},
"game_details": {
"open_download_options": "Ver opções de transferência",
"download_options_zero": "Sem opções de transferência",
"download_options_one": "{{count}} opção de transferência",
"download_options_other": "{{count}} opções de transferência",
"updated_at": "Atualizado a {{updated_at}}",
"resume": "Retomar",
"pause": "Pausar",
"cancel": "Cancelar",
"remove": "Remover",
"space_left_on_disk": "{{space}} livres no disco",
"eta": "Conclusão {{eta}}",
"calculating_eta": "A calcular tempo restante…",
"downloading_metadata": "A transferir metadados…",
"filter": "Filtrar repacks",
"requirements": "Requisitos do sistema",
"minimum": "Mínimos",
"recommended": "Recomendados",
"paused": "Pausado",
"release_date": "Lançado em {{date}}",
"publisher": "Publicado por {{publisher}}",
"hours": "horas",
"minutes": "minutos",
"amount_hours": "{{amount}} horas",
"amount_minutes": "{{amount}} minutos",
"accuracy": "{{accuracy}}% de precisão",
"add_to_library": "Adicionar à biblioteca",
"remove_from_library": "Remover da biblioteca",
"no_downloads": "Nenhuma transferência disponível",
"play_time": "Jogou por {{amount}}",
"next_suggestion": "Próxima sugestão",
"install": "Instalar",
"last_time_played": "Última sessão {{period}}",
"play": "Jogar",
"not_played_yet": "Ainda não jogou {{title}}",
"close": "Fechar",
"deleting": "A eliminar instalador…",
"playing_now": "A jogar agora",
"change": "Explorar",
"repacks_modal_description": "Escolha o repack do jogo que deseja transferir",
"select_folder_hint": "Para trocar o diretório padrão, aceda à <0>Tela de Definições</0>",
"download_now": "Iniciar transferência",
"no_shop_details": "Não foi possível obter os detalhes da loja.",
"download_options": "Opções de transferência",
"download_path": "Diretório de transferência",
"previous_screenshot": "Captura de ecrã anterior",
"next_screenshot": "Próxima captura de ecrã",
"screenshot": "Captura de ecrã {{number}}",
"open_screenshot": "Ver captura de ecrã {{number}}",
"download_settings": "Definições de transferência",
"downloader": "Downloader",
"select_executable": "Explorar",
"no_executable_selected": "Nenhum executável selecionado",
"open_folder": "Abrir pasta",
"open_download_location": "Ver ficheiros transferidos",
"create_shortcut": "Criar atalho no ambiente de trabalho",
"remove_files": "Remover ficheiros",
"options": "Gerir",
"remove_from_library_description": "Isto irá remover {{game}} da sua biblioteca",
"remove_from_library_title": "Tem a certeza?",
"executable_section_title": "Executável",
"executable_section_description": "O caminho do ficheiro que será executado ao clicar em \"Jogar\"",
"downloads_secion_title": "Transferências",
"downloads_section_description": "Confira atualizações ou versões diferentes para este mesmo título",
"danger_zone_section_title": "Zona de perigo",
"danger_zone_section_description": "Remova o jogo da sua biblioteca ou os ficheiros que foram transferidos pelo Hydra",
"download_in_progress": "Transferência em andamento",
"download_paused": "Transferência pausada",
"last_downloaded_option": "Última opção transferida",
"create_shortcut_success": "Atalho criado com sucesso",
"create_shortcut_error": "Erro ao criar atalho",
"download": "Transferir",
"executable_path_in_use": "Executável em uso por \"{{game}}\"",
"warning": "Aviso:",
"hydra_needs_to_remain_open": "para este download, o Hydra precisa ficar aberto até a conclusão. Caso o Hydra encerre antes da conclusão, perderá seu progresso."
},
"activation": {
"title": "Ativação",
"installation_id": "ID da instalação:",
"enter_activation_code": "Insira o seu código de ativação",
"message": "Se não sabe onde conseguir o código, talvez não devesse estar aqui.",
"activate": "Ativar",
"loading": "A carregar…"
},
"downloads": {
"resume": "Retomar",
"pause": "Pausar",
"eta": "Conclusão {{eta}}",
"paused": "Pausado",
"verifying": "A verificar…",
"completed": "Concluído",
"removed": "Cancelado",
"cancel": "Cancelar",
"filter": "Filtrar jogos transferidos",
"remove": "Remover",
"downloading_metadata": "A transferir metadados…",
"delete": "Remover instalador",
"delete_modal_description": "Isto removerá todos os ficheiros de instalação do seu computador",
"delete_modal_title": "Tem a certeza?",
"deleting": "A eliminar instalador…",
"install": "Instalar",
"download_in_progress": "A transferir agora",
"queued_downloads": "Na fila",
"downloads_completed": "Concluído",
"queued": "Na fila",
"no_downloads_title": "Nada por aqui…",
"no_downloads_description": "Ainda não transferiu nada pelo Hydra, mas nunca é tarde para começar.",
"checking_files": "A verificar ficheiros…"
},
"settings": {
"downloads_path": "Diretório das transferências",
"change": "Explorar...",
"notifications": "Notificações",
"enable_download_notifications": "Quando uma transferência for concluída",
"enable_repack_list_notifications": "Quando a lista de repacks for atualizada",
"real_debrid_api_token_label": "Token de API do Real-Debrid",
"quit_app_instead_hiding": "Encerrar o Hydra em vez de apenas minimizá-lo ao fechar.",
"launch_with_system": "Iniciar o Hydra com o sistema",
"general": "Geral",
"behavior": "Comportamento",
"download_sources": "Fontes de transferência",
"language": "Idioma",
"real_debrid_api_token": "Token de API",
"enable_real_debrid": "Ativar Real-Debrid",
"real_debrid_api_token_hint": "Pode obter o seu token de API <0>aqui</0>",
"real_debrid_description": "O Real-Debrid é um downloader sem restrições que permite transferir ficheiros instantaneamente e com a melhor velocidade da sua Internet.",
"real_debrid_invalid_token": "Token de API inválido",
"real_debrid_free_account_error": "A conta \"{{username}}\" é uma conta gratuita. Por favor, subscreva o Real-Debrid",
"real_debrid_linked_message": "Conta \"{{username}}\" vinculada",
"save_changes": "Guardar alterações",
"changes_saved": "Definições guardadas com sucesso",
"download_sources_description": "O Hydra vai procurar links de transferência em todas as fontes ativadas. A URL da página de detalhes da loja não é guardada no seu dispositivo. Utilizamos um sistema de metadados criado pela comunidade para fornecer suporte a mais fontes de transferência de jogos.",
"validate_download_source": "Validar",
"remove_download_source": "Remover",
"add_download_source": "Adicionar fonte",
"download_count_zero": "Sem transferências na lista",
"download_count_one": "{{countFormatted}} transferência na lista",
"download_count_other": "{{countFormatted}} transferências na lista",
"download_options_zero": "Sem transferências disponíveis",
"download_options_one": "{{countFormatted}} transferência disponível",
"download_options_other": "{{countFormatted}} transferências disponíveis",
"download_source_url": "URL da fonte",
"add_download_source_description": "Insira o URL contendo o arquivo .json",
"download_source_up_to_date": "Sincronizada",
"download_source_errored": "Falhou",
"sync_download_sources": "Sincronizar",
"removed_download_source": "Fonte removida",
"added_download_source": "Fonte adicionada",
"download_sources_synced": "As fontes foram sincronizadas",
"insert_valid_json_url": "Insira o URL de um JSON válido",
"found_download_option_zero": "Nenhuma opção de transferência encontrada",
"found_download_option_one": "{{countFormatted}} opção de transferência encontrada",
"found_download_option_other": "{{countFormatted}} opções de transferências encontradas",
"import": "Importar"
},
"notifications": {
"download_complete": "Transferência concluída",
"game_ready_to_install": "{{title}} está pronto para ser descarregado",
"repack_list_updated": "Lista de repacks atualizada",
"repack_count_one": "{{count}} novo repack",
"repack_count_other": "{{count}} novos repacks",
"new_update_available": "Versão {{version}} disponível",
"restart_to_install_update": "Reinicie o Hydra para instalar a nova versão"
},
"system_tray": {
"open": "Abrir Hydra",
"quit": "Fechar"
},
"game_card": {
"no_downloads": "Sem transferências disponíveis"
},
"binary_not_found_modal": {
"title": "Programas não instalados",
"description": "Os executáveis do Wine ou Lutris não foram encontrados em seu sistema.",
"instructions": "Verifique a forma correta de instalar algum deles na sua distro Linux, garantindo assim a execução normal do jogo."
},
"catalogue": {
"next_page": "Próxima página",
"previous_page": "Página anterior"
},
"modal": {
"close": "Botão de fechar"
},
"forms": {
"toggle_password_visibility": "Alternar visibilidade da palavra-passe"
},
"user_profile": {
"amount_hours": "{{amount}} horas",
"amount_minutes": "{{amount}} minutos",
"last_time_played": "Última sessão {{period}}",
"activity": "Atividades recentes",
"library": "Biblioteca",
"total_play_time": "Tempo total de jogo: {{amount}}",
"no_recent_activity_title": "Hmmm… nada por aqui",
"no_recent_activity_description": "Parece que não jogaste nada recentemente. Que tal começar agora?",
"display_name": "Nome de exibição",
"saving": "a guardar…",
"save": "Guardar",
"edit_profile": "Editar perfil",
"saved_successfully": "Guardado com sucesso",
"try_again": "Por favor, tenta novamente",
"cancel": "Cancelar",
"successfully_signed_out": "Terminado com sucesso",
"sign_out": "Terminar sessão",
"sign_out_modal_title": "Tens a certeza?",
"playing_for": "A jogar há {{amount}}",
"sign_out_modal_text": "A tua biblioteca de jogos está associada com a tua conta atual. Ao sair, a tua biblioteca não aparecerá mais no Hydra e qualquer progresso não será guardado. Desejas continuar?",
"add_friends": "Adicionar Amigos",
"friend_code": "Código de amigo",
"see_profile": "Ver perfil",
"friend_request_sent": "Pedido de amizade enviado",
"friends": "Amigos",
"add": "Adicionar",
"sending": "A enviar",
"friends_list": "Lista de amigos",
"user_not_found": "Utilizador não encontrado",
"block_user": "Bloquear",
"add_friend": "Adicionar amigo",
"request_sent": "Pedido enviado",
"request_received": "Pedido recebido",
"accept_request": "Aceitar pedido",
"ignore_request": "Ignorar pedido",
"cancel_request": "Cancelar pedido",
"undo_friendship": "Desfazer amizade",
"request_accepted": "Pedido de amizade aceito",
"user_blocked_successfully": "Utilizador bloqueado com sucesso",
"user_block_modal_text": "Bloquear {{displayName}}",
"blocked_users": "Utilizadores bloqueados",
"unblock": "Desbloquear",
"no_friends_added": "Ainda não adicionaste amigos",
"pending": "Pendentes",
"no_pending_invites": "Não tens convites de amizade pendentes",
"no_blocked_users": "Não tens nenhum utilizador bloqueado",
"friend_code_copied": "Código de amigo copiado",
"image_process_failure": "Falha ao processar a imagem"
}
}

View File

@@ -1,4 +1,5 @@
{
"language_name": "Română",
"home": {
"featured": "Recomandate",
"trending": "Populare",

View File

@@ -1,4 +1,5 @@
{
"language_name": "Русский",
"app": {
"successfully_signed_in": "Успешный вход"
},
@@ -6,7 +7,10 @@
"featured": "Рекомендованное",
"trending": "В тренде",
"surprise_me": "Удиви меня",
"no_results": "Ничего не найдено"
"no_results": "Ничего не найдено",
"hot": "Сейчас жарко",
"start_typing": "Начинаю вводить текст для поиска...",
"weekly": "📅 Лучшие игры недели"
},
"sidebar": {
"catalogue": "Каталог",
@@ -20,7 +24,8 @@
"home": "Главная",
"queued": "{{title}} (В очереди)",
"game_has_no_executable": "Файл запуска игры не выбран",
"sign_in": "Войти"
"sign_in": "Войти",
"friends": "Друзья"
},
"header": {
"search": "Поиск",
@@ -36,7 +41,8 @@
"no_downloads_in_progress": "Нет активных загрузок",
"downloading_metadata": "Загрузка метаданных {{title}}…",
"downloading": "Загрузка {{title}}… ({{percentage}} завершено) - Окончание {{eta}} - {{speed}}",
"calculating_eta": "Загрузка {{title}}… ({{percentage}} завершено) - Подсчёт оставшегося времени…"
"calculating_eta": "Загрузка {{title}}… ({{percentage}} завершено) - Подсчёт оставшегося времени…",
"checking_files": "Проверка файлов {{title}}… ({{percentage}} завершено)"
},
"catalogue": {
"next_page": "Следующая страница",
@@ -112,7 +118,17 @@
"download_paused": "Загрузка приостановлена",
"last_downloaded_option": "Последний вариант загрузки",
"create_shortcut_success": "Ярлык создан",
"create_shortcut_error": "Не удалось создать ярлык"
"create_shortcut_error": "Не удалось создать ярлык",
"allow_nsfw_content": "Продолжать",
"download": "Скачать",
"download_count": "Загрузки",
"download_error": "Этот вариант загрузки недоступен",
"executable_path_in_use": "Исполняемый файл уже используется \"{{game}}\"",
"nsfw_content_description": "{{title}} содержит контент, который может не подходить для всех возрастов. \nВы уверены, что хотите продолжить?",
"nsfw_content_title": "Эта игра содержит неприемлемый контент",
"player_count": "Активные игроки",
"refuse_nsfw_content": "Возвращаться",
"stats": "Статистика"
},
"activation": {
"title": "Активировать Hydra",
@@ -144,7 +160,8 @@
"downloads_completed": "Завершено",
"queued": "В очереди",
"no_downloads_title": "Здесь так пусто...",
"no_downloads_description": "Вы ещё ничего не скачали через Hydra, но никогда не поздно начать."
"no_downloads_description": "Вы ещё ничего не скачали через Hydra, но никогда не поздно начать.",
"checking_files": "Проверка файлов…"
},
"settings": {
"downloads_path": "Путь загрузок",
@@ -175,9 +192,6 @@
"download_count_zero": "В списке нет загрузок",
"download_count_one": "{{countFormatted}} загрузка в списке",
"download_count_other": "{{countFormatted}} загрузок в списке",
"download_options_zero": "Нет доступных загрузок",
"download_options_one": "{{countFormatted}} вариант загрузки доступен",
"download_options_other": "{{countFormatted}} вариантов загрузки доступно",
"download_source_url": "Ссылка на источник",
"add_download_source_description": "Вставьте ссылку на .json-файл",
"download_source_up_to_date": "Обновлён",
@@ -190,14 +204,30 @@
"found_download_option_zero": "Не найдено вариантов загрузки",
"found_download_option_one": "Найден {{countFormatted}} вариант загрузки",
"found_download_option_other": "Найдено {{countFormatted}} вариантов загрузки",
"import": "Импортировать"
"import": "Импортировать",
"blocked_users": "Заблокированные пользователи",
"download_options_one": "",
"download_options_other": "",
"download_options_zero": "",
"friends_only": "Только друзья",
"must_be_valid_url": "Источник должен быть действительным URL-адресом.",
"privacy": "Конфиденциальность",
"private": "Частный",
"profile_visibility": "Видимость профиля",
"profile_visibility_description": "Выберите, кто может видеть ваш профиль и библиотеку",
"public": "Общественный",
"required_field": "Это поле обязательно к заполнению",
"source_already_exists": "Этот источник уже добавлен",
"user_unblocked": "Пользователь разблокирован"
},
"notifications": {
"download_complete": "Загрузка завершена",
"game_ready_to_install": "{{title}} готова к установке",
"repack_list_updated": "Список репаков обновлен",
"repack_count_one": "{{count}} репак добавлен",
"repack_count_other": "{{count}} репаков добавлено"
"repack_count_other": "{{count}} репаков добавлено",
"new_update_available": "Доступна версия {{version}}",
"restart_to_install_update": "Перезапустите Hydra для установки обновления"
},
"system_tray": {
"open": "Открыть Hydra",
@@ -237,6 +267,52 @@
"successfully_signed_out": "Успешный выход из аккаунта",
"sign_out": "Выйти",
"playing_for": "Сыграно {{amount}}",
"sign_out_modal_text": "Ваша библиотека связана с текущей учетной записью. При выходе из системы ваша библиотека станет недоступна, и прогресс не будет сохранен. Выйти?"
"sign_out_modal_text": "Ваша библиотека связана с текущей учетной записью. При выходе из системы ваша библиотека станет недоступна, и прогресс не будет сохранен. Выйти?",
"add_friends": "Добавить друзей",
"add": "Добавить",
"friend_code": "Код друга",
"see_profile": "Просмотреть профиль",
"sending": "Отправка",
"friend_request_sent": "Запрос в друзья отправлен",
"friends": "Друзья",
"friends_list": "Список друзей",
"user_not_found": "Пользователь не найден",
"block_user": "Заблокировать пользователя",
"add_friend": "Добавить друга",
"request_sent": "Запрос отправлен",
"request_received": "Запрос получен",
"accept_request": "Принять запрос",
"ignore_request": "Игнорировать запрос",
"cancel_request": "Отменить запрос",
"undo_friendship": "Удалить друга",
"request_accepted": "Запрос принят",
"user_blocked_successfully": "Пользователь успешно заблокирован",
"user_block_modal_text": "{{displayName}} будет заблокирован",
"blocked_users": "Заблокированные пользователи",
"unblock": "Разблокировать",
"no_friends_added": "Вы ещё не добавили ни одного друга",
"pending": "Ожидание",
"no_pending_invites": "У вас нет запросов ожидающих ответа",
"no_blocked_users": "Вы не заблокировали ни одного пользователя",
"friend_code_copied": "Код друга скопирован",
"displayname_max_length": "Отображаемое имя должно содержать не более 50 символов.",
"displayname_min_length": "Отображаемое имя должно содержать не менее 3 символов.",
"image_process_failure": "Сбой при обработке изображения",
"locked_profile": "Этот профиль является частным",
"privacy_hint": "Чтобы указать, кто может это видеть, перейдите в <0>Настройки</0>.",
"profile_locked": "",
"profile_reported": "Профиль сообщил",
"report": "Отчет",
"report_description": "Дополнительная информация",
"report_description_placeholder": "Дополнительная информация",
"report_profile": "Пожаловаться на этот профиль",
"report_reason": "Почему вы жалуетесь на этот профиль?",
"report_reason_hate": "Разжигание ненависти",
"report_reason_other": "Другой",
"report_reason_sexual_content": "Сексуальный контент",
"report_reason_spam": "Спам",
"report_reason_violence": "Насилие",
"required_field": "Это поле обязательно к заполнению",
"undo_friendship_modal_text": "Это отменит вашу дружбу с {{displayName}}."
}
}

View File

@@ -1,4 +1,5 @@
{
"language_name": "Türkçe",
"home": {
"featured": "Öne çıkan",
"trending": "Popüler",

View File

@@ -1,4 +1,5 @@
{
"language_name": "Українська",
"app": {
"successfully_signed_in": "Успішний вхід в систему"
},

View File

@@ -1,4 +1,5 @@
{
"language_name": "中文",
"app": {
"successfully_signed_in": "已成功登录"
},

View File

@@ -3,11 +3,8 @@ import path from "node:path";
export const defaultDownloadsPath = app.getPath("downloads");
export const databasePath = path.join(
app.getPath("appData"),
"hydra",
"hydra.db"
);
export const databaseDirectory = path.join(app.getPath("appData"), "hydra");
export const databasePath = path.join(databaseDirectory, "hydra.db");
export const logsPath = path.join(app.getPath("appData"), "hydra", "logs");

View File

@@ -6,32 +6,22 @@ import {
GameShopCache,
Repack,
UserPreferences,
UserAuth,
} from "@main/entity";
import type { BetterSqlite3ConnectionOptions } from "typeorm/driver/better-sqlite3/BetterSqlite3ConnectionOptions";
import { databasePath } from "./constants";
import migrations from "./migrations";
import { UserAuth } from "./entity/user-auth";
export const createDataSource = (
options: Partial<BetterSqlite3ConnectionOptions>
) =>
new DataSource({
type: "better-sqlite3",
entities: [
Game,
Repack,
UserPreferences,
GameShopCache,
DownloadSource,
DownloadQueue,
UserAuth,
],
synchronize: true,
database: databasePath,
...options,
});
export const dataSource = createDataSource({
migrations,
export const dataSource = new DataSource({
type: "better-sqlite3",
entities: [
Game,
Repack,
UserPreferences,
GameShopCache,
DownloadSource,
DownloadQueue,
UserAuth,
],
synchronize: false,
database: databasePath,
});

View File

@@ -1,80 +0,0 @@
declare module "aria2" {
export type Aria2Status =
| "active"
| "waiting"
| "paused"
| "error"
| "complete"
| "removed";
export interface StatusResponse {
gid: string;
status: Aria2Status;
totalLength: string;
completedLength: string;
uploadLength: string;
bitfield: string;
downloadSpeed: string;
uploadSpeed: string;
infoHash?: string;
numSeeders?: string;
seeder?: boolean;
pieceLength: string;
numPieces: string;
connections: string;
errorCode?: string;
errorMessage?: string;
followedBy?: string[];
following: string;
belongsTo: string;
dir: string;
files: {
path: string;
length: string;
completedLength: string;
selected: string;
}[];
bittorrent?: {
announceList: string[][];
comment: string;
creationDate: string;
mode: "single" | "multi";
info: {
name: string;
verifiedLength: string;
verifyIntegrityPending: string;
};
};
}
export default class Aria2 {
constructor(options: any);
open: () => Promise<void>;
call(
method: "addUri",
uris: string[],
options: { dir: string }
): Promise<string>;
call(
method: "tellStatus",
gid: string,
keys?: string[]
): Promise<StatusResponse>;
call(method: "pause", gid: string): Promise<string>;
call(method: "forcePause", gid: string): Promise<string>;
call(method: "unpause", gid: string): Promise<string>;
call(method: "remove", gid: string): Promise<string>;
call(method: "forceRemove", gid: string): Promise<string>;
call(method: "pauseAll"): Promise<string>;
call(method: "forcePauseAll"): Promise<string>;
listNotifications: () => [
"onDownloadStart",
"onDownloadPause",
"onDownloadStop",
"onDownloadComplete",
"onDownloadError",
"onBtDownloadComplete",
];
on: (event: string, callback: (params: any) => void) => void;
}
}

View File

@@ -16,15 +16,12 @@ export class Repack {
@Column("text", { unique: true })
title: string;
/**
* @deprecated Use uris instead
*/
@Column("text", { unique: true })
magnet: string;
/**
* @deprecated
*/
@Column("int", { nullable: true })
page: number;
@Column("text")
repacker: string;
@@ -37,6 +34,9 @@ export class Repack {
@ManyToOne(() => DownloadSource, { nullable: true, onDelete: "CASCADE" })
downloadSource: DownloadSource;
@Column("text", { default: "[]" })
uris: string;
@CreateDateColumn()
createdAt: Date;

View File

@@ -1,6 +1,11 @@
import { registerEvent } from "../register-event";
import * as Sentry from "@sentry/electron/main";
import { HydraApi, PythonInstance, gamesPlaytime } from "@main/services";
import {
DownloadManager,
HydraApi,
PythonInstance,
gamesPlaytime,
} from "@main/services";
import { dataSource } from "@main/data-source";
import { DownloadQueue, Game, UserAuth } from "@main/entity";
@@ -23,9 +28,14 @@ const signOut = async (_event: Electron.IpcMainInvokeEvent) => {
/* Removes user from Sentry */
Sentry.setUser(null);
/* Cancels any ongoing downloads */
DownloadManager.cancelDownload();
/* Disconnects libtorrent */
PythonInstance.killTorrent();
HydraApi.handleSignOut();
await Promise.all([
databaseOperations,
HydraApi.post("/auth/logout").catch(() => {}),

View File

@@ -3,6 +3,7 @@ import { registerEvent } from "../register-event";
import updater, { UpdateInfo } from "electron-updater";
import { WindowManager } from "@main/services";
import { app } from "electron";
import { publishNotificationUpdateReadyToInstall } from "@main/services/notifications";
const { autoUpdater } = updater;
@@ -20,13 +21,17 @@ const mockValuesForDebug = () => {
sendEvent({ type: "update-downloaded" });
};
const newVersionInfo = { version: "" };
const checkForUpdates = async (_event: Electron.IpcMainInvokeEvent) => {
autoUpdater
.once("update-available", (info: UpdateInfo) => {
sendEvent({ type: "update-available", info });
newVersionInfo.version = info.version;
})
.once("update-downloaded", () => {
sendEvent({ type: "update-downloaded" });
publishNotificationUpdateReadyToInstall(newVersionInfo.version);
});
if (app.isPackaged) {

View File

@@ -1,36 +1,44 @@
import { getSteamAppAsset } from "@main/helpers";
import type { CatalogueEntry, GameShop } from "@types";
import type { GameShop } from "@types";
import { registerEvent } from "../register-event";
import { RepacksManager, requestSteam250 } from "@main/services";
import { formatName } from "@shared";
import { HydraApi, RepacksManager } from "@main/services";
import { CatalogueCategory, formatName, steamUrlBuilder } from "@shared";
import { steamGamesWorker } from "@main/workers";
const resultSize = 12;
const getCatalogue = async (
_event: Electron.IpcMainInvokeEvent,
category: CatalogueCategory
) => {
const params = new URLSearchParams({
take: "12",
skip: "0",
});
const getCatalogue = async (_event: Electron.IpcMainInvokeEvent) => {
const trendingGames = await requestSteam250("/90day");
const results: CatalogueEntry[] = [];
const response = await HydraApi.get<{ objectId: string; shop: GameShop }[]>(
`/games/${category}?${params.toString()}`,
{},
{ needsAuth: false }
);
for (let i = 0; i < resultSize; i++) {
if (!trendingGames[i]) {
i++;
continue;
}
return Promise.all(
response.map(async (game) => {
const steamGame = await steamGamesWorker.run(Number(game.objectId), {
name: "getById",
});
const { title, objectID } = trendingGames[i]!;
const repacks = RepacksManager.search({ query: formatName(title) });
const repacks = RepacksManager.search({
query: formatName(steamGame.name),
});
const catalogueEntry = {
objectID,
title,
shop: "steam" as GameShop,
cover: getSteamAppAsset("library", objectID),
};
results.push({ ...catalogueEntry, repacks });
}
return results;
return {
title: steamGame.name,
shop: game.shop,
repacks,
cover: steamUrlBuilder.library(game.objectId),
objectID: game.objectId,
};
})
);
};
registerEvent("getCatalogue", getCatalogue);

View File

@@ -0,0 +1,23 @@
import type { GameShop } from "@types";
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import type { GameStats } from "@types";
const getGameStats = async (
_event: Electron.IpcMainInvokeEvent,
objectId: string,
shop: GameShop
) => {
const params = new URLSearchParams({
objectId,
shop,
});
const response = await HydraApi.get<GameStats>(
`/games/stats?${params.toString()}`
);
return response;
};
registerEvent("getGameStats", getGameStats);

View File

@@ -3,7 +3,7 @@ import { shuffle } from "lodash-es";
import { getSteam250List } from "@main/services";
import { registerEvent } from "../register-event";
import { searchSteamGames } from "../helpers/search-games";
import { getSteamGameById } from "../helpers/search-games";
import type { Steam250Game } from "@types";
const state = { games: Array<Steam250Game>(), index: 0 };
@@ -12,14 +12,10 @@ const filterGames = async (games: Steam250Game[]) => {
const results: Steam250Game[] = [];
for (const game of games) {
const catalogue = await searchSteamGames({ query: game.title });
const steamGame = await getSteamGameById(game.objectID);
if (catalogue.length) {
const [steamGame] = catalogue;
if (steamGame.repacks.length) {
results.push(game);
}
if (steamGame?.repacks.length) {
results.push(game);
}
}

View File

@@ -0,0 +1,22 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import { userPreferencesRepository } from "@main/repository";
import { TrendingGame } from "@types";
const getTrendingGames = async (_event: Electron.IpcMainInvokeEvent) => {
const userPreferences = await userPreferencesRepository.findOne({
where: { id: 1 },
});
const language = userPreferences?.language || "en";
const trendingGames = await HydraApi.get<TrendingGame[]>(
"/games/trending",
{ language },
{ needsAuth: false }
).catch(() => []);
return trendingGames;
};
registerEvent("getTrendingGames", getTrendingGames);

View File

@@ -1,10 +1,25 @@
import { registerEvent } from "../register-event";
import { searchSteamGames } from "../helpers/search-games";
import { convertSteamGameToCatalogueEntry } from "../helpers/search-games";
import { CatalogueEntry } from "@types";
import { HydraApi, RepacksManager } from "@main/services";
const searchGamesEvent = async (
_event: Electron.IpcMainInvokeEvent,
query: string
): Promise<CatalogueEntry[]> => searchSteamGames({ query, limit: 12 });
): Promise<CatalogueEntry[]> => {
const games = await HydraApi.get<
{ objectId: string; title: string; shop: string }[]
>("/games/search", { title: query, take: 12, skip: 0 }, { needsAuth: false });
const steamGames = games.map((game) => {
return convertSteamGameToCatalogueEntry({
id: Number(game.objectId),
name: game.title,
clientIcon: null,
});
});
return RepacksManager.findRepacksForCatalogueEntries(steamGames);
};
registerEvent("searchGames", searchGamesEvent);

View File

@@ -1,16 +1,11 @@
import { downloadSourceRepository } from "@main/repository";
import { registerEvent } from "../register-event";
const getDownloadSources = async (_event: Electron.IpcMainInvokeEvent) => {
return downloadSourceRepository
.createQueryBuilder("downloadSource")
.leftJoin("downloadSource.repacks", "repacks")
.orderBy("downloadSource.createdAt", "DESC")
.loadRelationCountAndMap(
"downloadSource.repackCount",
"downloadSource.repacks"
)
.getMany();
};
const getDownloadSources = async (_event: Electron.IpcMainInvokeEvent) =>
downloadSourceRepository.find({
order: {
createdAt: "DESC",
},
});
registerEvent("getDownloadSources", getDownloadSources);

View File

@@ -1,17 +1,12 @@
import { registerEvent } from "../register-event";
import axios from "axios";
import { downloadSourceRepository } from "@main/repository";
import { downloadSourceSchema } from "../helpers/validators";
import { RepacksManager } from "@main/services";
import { downloadSourceWorker } from "@main/workers";
const validateDownloadSource = async (
_event: Electron.IpcMainInvokeEvent,
url: string
) => {
const response = await axios.get(url);
const source = downloadSourceSchema.parse(response.data);
const existingSource = await downloadSourceRepository.findOne({
where: { url },
});
@@ -21,14 +16,12 @@ const validateDownloadSource = async (
const repacks = RepacksManager.repacks;
const existingUris = source.downloads
.flatMap((download) => download.uris)
.filter((uri) => repacks.some((repack) => repack.magnet === uri));
return {
name: source.name,
downloadCount: source.downloads.length - existingUris.length,
};
return downloadSourceWorker.run(
{ url, repacks },
{
name: "validateDownloadSource",
}
);
};
registerEvent("validateDownloadSource", validateDownloadSource);

View File

@@ -1,11 +1,8 @@
import { orderBy } from "lodash-es";
import flexSearch from "flexsearch";
import type { GameShop, CatalogueEntry, SteamGame } from "@types";
import { getSteamAppAsset } from "@main/helpers";
import { steamGamesWorker } from "@main/workers";
import { RepacksManager } from "@main/services";
import { steamUrlBuilder } from "@shared";
export interface SearchGamesArgs {
query?: string;
@@ -19,24 +16,22 @@ export const convertSteamGameToCatalogueEntry = (
objectID: String(game.id),
title: game.name,
shop: "steam" as GameShop,
cover: getSteamAppAsset("library", String(game.id)),
cover: steamUrlBuilder.library(String(game.id)),
repacks: [],
});
export const searchSteamGames = async (
options: flexSearch.SearchOptions
): Promise<CatalogueEntry[]> => {
const steamGames = (await steamGamesWorker.run(options, {
name: "search",
})) as SteamGame[];
export const getSteamGameById = async (
objectId: string
): Promise<CatalogueEntry | null> => {
const steamGame = await steamGamesWorker.run(Number(objectId), {
name: "getById",
});
const result = RepacksManager.findRepacksForCatalogueEntries(
steamGames.map((game) => convertSteamGameToCatalogueEntry(game))
);
if (!steamGame) return null;
return orderBy(
result,
[({ repacks }) => repacks.length, "repacks"],
["desc"]
);
const catalogueEntry = convertSteamGameToCatalogueEntry(steamGame);
const result = RepacksManager.findRepacksForCatalogueEntry(catalogueEntry);
return result;
};

View File

@@ -8,6 +8,8 @@ import "./catalogue/get-how-long-to-beat";
import "./catalogue/get-random-game";
import "./catalogue/search-games";
import "./catalogue/search-game-repacks";
import "./catalogue/get-game-stats";
import "./catalogue/get-trending-games";
import "./hardware/get-disk-free-space";
import "./library/add-game-to-library";
import "./library/create-game-shortcut";
@@ -20,6 +22,7 @@ import "./library/open-game-executable-path";
import "./library/open-game-installer";
import "./library/open-game-installer-path";
import "./library/update-executable-path";
import "./library/verify-executable-path";
import "./library/remove-game";
import "./library/remove-game-from-library";
import "./misc/open-external";
@@ -43,13 +46,23 @@ import "./auth/sign-out";
import "./auth/open-auth-window";
import "./auth/get-session-hash";
import "./user/get-user";
import "./user/get-blocked-users";
import "./user/block-user";
import "./user/unblock-user";
import "./user/get-user-friends";
import "./user/get-user-stats";
import "./user/report-user";
import "./profile/get-friend-requests";
import "./profile/get-me";
import "./profile/undo-friendship";
import "./profile/update-friend-request";
import "./profile/update-profile";
import "./profile/process-profile-image";
import "./profile/send-friend-request";
import "./profile/sync-friend-requests";
import { isPortableVersion } from "@main/helpers";
ipcMain.handle("ping", () => "pong");
ipcMain.handle("getVersion", () => app.getVersion());
ipcMain.handle(
"isPortableVersion",
() => process.env.PORTABLE_EXECUTABLE_FILE != null
);
ipcMain.handle("isPortableVersion", () => isPortableVersion());
ipcMain.handle("getDefaultDownloadsPath", () => defaultDownloadsPath);

View File

@@ -3,10 +3,11 @@ import { gameRepository } from "@main/repository";
import { registerEvent } from "../register-event";
import type { GameShop } from "@types";
import { getFileBase64, getSteamAppAsset } from "@main/helpers";
import { getFileBase64 } from "@main/helpers";
import { steamGamesWorker } from "@main/workers";
import { createGame } from "@main/services/library-sync";
import { steamUrlBuilder } from "@shared";
const addGameToLibrary = async (
_event: Electron.IpcMainInvokeEvent,
@@ -32,7 +33,7 @@ const addGameToLibrary = async (
});
const iconUrl = steamGame?.clientIcon
? getSteamAppAsset("icon", objectID, steamGame.clientIcon)
? steamUrlBuilder.icon(objectID, steamGame.clientIcon)
: null;
await gameRepository
@@ -53,7 +54,7 @@ const addGameToLibrary = async (
const game = await gameRepository.findOne({ where: { objectID } });
createGame(game!);
createGame(game!).catch(() => {});
});
};

View File

@@ -20,7 +20,7 @@ const removeRemoveGameFromLibrary = async (gameId: number) => {
const game = await gameRepository.findOne({ where: { id: gameId } });
if (game?.remoteId) {
HydraApi.delete(`/games/${game.remoteId}`).catch(() => {});
HydraApi.delete(`/profile/games/${game.remoteId}`).catch(() => {});
}
};

View File

@@ -0,0 +1,13 @@
import { gameRepository } from "@main/repository";
import { registerEvent } from "../register-event";
const verifyExecutablePathInUse = async (
_event: Electron.IpcMainInvokeEvent,
executablePath: string
) => {
return gameRepository.findOne({
where: { executablePath },
});
};
registerEvent("verifyExecutablePathInUse", verifyExecutablePathInUse);

View File

@@ -0,0 +1,11 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import { FriendRequest } from "@types";
const getFriendRequests = async (
_event: Electron.IpcMainInvokeEvent
): Promise<FriendRequest[]> => {
return HydraApi.get(`/profile/friend-requests`).catch(() => []);
};
registerEvent("getFriendRequests", getFriendRequests);

View File

@@ -1,17 +1,15 @@
import { registerEvent } from "../register-event";
import * as Sentry from "@sentry/electron/main";
import { HydraApi } from "@main/services";
import { UserProfile } from "@types";
import { ProfileVisibility, UserDetails } from "@types";
import { userAuthRepository } from "@main/repository";
import { UserNotLoggedInError } from "@shared";
const getMe = async (
_event: Electron.IpcMainInvokeEvent
): Promise<UserProfile | null> => {
return HydraApi.get(`/profile/me`)
.then((response) => {
const me = response.data;
): Promise<UserDetails | null> => {
return HydraApi.get<UserDetails>(`/profile/me`)
.then(async (me) => {
userAuthRepository.upsert(
{
id: 1,
@@ -26,12 +24,24 @@ const getMe = async (
return me;
})
.catch((err) => {
.catch(async (err) => {
if (err instanceof UserNotLoggedInError) {
return null;
}
return userAuthRepository.findOne({ where: { id: 1 } });
const loggedUser = await userAuthRepository.findOne({ where: { id: 1 } });
if (loggedUser) {
return {
...loggedUser,
id: loggedUser.userId,
username: "",
bio: "",
profileVisibility: "PUBLIC" as ProfileVisibility,
};
}
return null;
});
};

View File

@@ -0,0 +1,11 @@
import { registerEvent } from "../register-event";
import { PythonInstance } from "@main/services";
const processProfileImage = async (
_event: Electron.IpcMainInvokeEvent,
path: string
) => {
return PythonInstance.processProfileImage(path);
};
registerEvent("processProfileImage", processProfileImage);

View File

@@ -0,0 +1,11 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
const sendFriendRequest = async (
_event: Electron.IpcMainInvokeEvent,
userId: string
) => {
return HydraApi.post("/profile/friend-requests", { friendCode: userId });
};
registerEvent("sendFriendRequest", sendFriendRequest);

View File

@@ -0,0 +1,9 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import { FriendRequestSync } from "@types";
const syncFriendRequests = async (_event: Electron.IpcMainInvokeEvent) => {
return HydraApi.get<FriendRequestSync>(`/profile/friend-requests/sync`);
};
registerEvent("syncFriendRequests", syncFriendRequests);

View File

@@ -0,0 +1,11 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
const undoFriendship = async (
_event: Electron.IpcMainInvokeEvent,
userId: string
) => {
await HydraApi.delete(`/profile/friends/${userId}`);
};
registerEvent("undoFriendship", undoFriendship);

View File

@@ -0,0 +1,19 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import { FriendRequestAction } from "@types";
const updateFriendRequest = async (
_event: Electron.IpcMainInvokeEvent,
userId: string,
action: FriendRequestAction
) => {
if (action == "CANCEL") {
return HydraApi.delete(`/profile/friend-requests/${userId}`);
}
return HydraApi.patch(`/profile/friend-requests/${userId}`, {
requestState: action,
});
};
registerEvent("updateFriendRequest", updateFriendRequest);

View File

@@ -1,63 +1,56 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import axios from "axios";
import { HydraApi, PythonInstance } from "@main/services";
import fs from "node:fs";
import path from "node:path";
import { fileTypeFromFile } from "file-type";
import { UserProfile } from "@types";
import type { UpdateProfileRequest, UserProfile } from "@types";
import { omit } from "lodash-es";
import axios from "axios";
const patchUserProfile = async (
displayName: string,
profileImageUrl?: string
) => {
if (profileImageUrl) {
return HydraApi.patch("/profile", {
displayName,
profileImageUrl,
interface PresignedResponse {
presignedUrl: string;
profileImageUrl: string;
}
const patchUserProfile = async (updateProfile: UpdateProfileRequest) => {
return HydraApi.patch<UserProfile>("/profile", updateProfile);
};
const getNewProfileImageUrl = async (localImageUrl: string) => {
const { imagePath, mimeType } =
await PythonInstance.processProfileImage(localImageUrl);
const stats = fs.statSync(imagePath);
const fileBuffer = fs.readFileSync(imagePath);
const fileSizeInBytes = stats.size;
const { presignedUrl, profileImageUrl } =
await HydraApi.post<PresignedResponse>(`/presigned-urls/profile-image`, {
imageExt: path.extname(imagePath).slice(1),
imageLength: fileSizeInBytes,
});
} else {
return HydraApi.patch("/profile", {
displayName,
});
}
await axios.put(presignedUrl, fileBuffer, {
headers: {
"Content-Type": mimeType,
},
});
return profileImageUrl;
};
const updateProfile = async (
_event: Electron.IpcMainInvokeEvent,
displayName: string,
newProfileImagePath: string | null
updateProfile: UpdateProfileRequest
) => {
if (!newProfileImagePath) {
return patchUserProfile(displayName).then(
(response) => response.data as UserProfile
);
if (!updateProfile.profileImageUrl) {
return patchUserProfile(omit(updateProfile, "profileImageUrl"));
}
const stats = fs.statSync(newProfileImagePath);
const fileBuffer = fs.readFileSync(newProfileImagePath);
const fileSizeInBytes = stats.size;
const profileImageUrl = await getNewProfileImageUrl(
updateProfile.profileImageUrl
).catch(() => undefined);
const profileImageUrl = await HydraApi.post(`/presigned-urls/profile-image`, {
imageExt: path.extname(newProfileImagePath).slice(1),
imageLength: fileSizeInBytes,
})
.then(async (preSignedResponse) => {
const { presignedUrl, profileImageUrl } = preSignedResponse.data;
const mimeType = await fileTypeFromFile(newProfileImagePath);
await axios.put(presignedUrl, fileBuffer, {
headers: {
"Content-Type": mimeType?.mime,
},
});
return profileImageUrl;
})
.catch(() => undefined);
return patchUserProfile(displayName, profileImageUrl).then(
(response) => response.data as UserProfile
);
return patchUserProfile({ ...updateProfile, profileImageUrl });
};
registerEvent("updateProfile", updateProfile);

View File

@@ -1,106 +1,123 @@
import {
downloadQueueRepository,
gameRepository,
repackRepository,
} from "@main/repository";
import { registerEvent } from "../register-event";
import type { StartGameDownloadPayload } from "@types";
import { getFileBase64, getSteamAppAsset } from "@main/helpers";
import { DownloadManager } from "@main/services";
import { getFileBase64 } from "@main/helpers";
import { DownloadManager, HydraApi, logger } from "@main/services";
import { Not } from "typeorm";
import { steamGamesWorker } from "@main/workers";
import { createGame } from "@main/services/library-sync";
import { steamUrlBuilder } from "@shared";
import { dataSource } from "@main/data-source";
import { DownloadQueue, Game, Repack } from "@main/entity";
const startGameDownload = async (
_event: Electron.IpcMainInvokeEvent,
payload: StartGameDownloadPayload
) => {
const { repackId, objectID, title, shop, downloadPath, downloader } = payload;
const { repackId, objectID, title, shop, downloadPath, downloader, uri } =
payload;
const [game, repack] = await Promise.all([
gameRepository.findOne({
return dataSource.transaction(async (transactionalEntityManager) => {
const gameRepository = transactionalEntityManager.getRepository(Game);
const repackRepository = transactionalEntityManager.getRepository(Repack);
const downloadQueueRepository =
transactionalEntityManager.getRepository(DownloadQueue);
const [game, repack] = await Promise.all([
gameRepository.findOne({
where: {
objectID,
shop,
},
}),
repackRepository.findOne({
where: {
id: repackId,
},
}),
]);
if (!repack) return;
await DownloadManager.pauseDownload();
await gameRepository.update(
{ status: "active", progress: Not(1) },
{ status: "paused" }
);
if (game) {
await gameRepository.update(
{
id: game.id,
},
{
status: "active",
progress: 0,
bytesDownloaded: 0,
downloadPath,
downloader,
uri,
isDeleted: false,
}
);
} else {
const steamGame = await steamGamesWorker.run(Number(objectID), {
name: "getById",
});
const iconUrl = steamGame?.clientIcon
? steamUrlBuilder.icon(objectID, steamGame.clientIcon)
: null;
await gameRepository
.insert({
title,
iconUrl,
objectID,
downloader,
shop,
status: "active",
downloadPath,
uri,
})
.then((result) => {
if (iconUrl) {
getFileBase64(iconUrl).then((base64) =>
gameRepository.update({ objectID }, { iconUrl: base64 })
);
}
return result;
});
}
const updatedGame = await gameRepository.findOne({
where: {
objectID,
shop,
},
}),
repackRepository.findOne({
where: {
id: repackId,
},
}),
]);
if (!repack) return;
await DownloadManager.pauseDownload();
await gameRepository.update(
{ status: "active", progress: Not(1) },
{ status: "paused" }
);
if (game) {
await gameRepository.update(
{
id: game.id,
},
{
status: "active",
progress: 0,
bytesDownloaded: 0,
downloadPath,
downloader,
uri: repack.magnet,
isDeleted: false,
}
);
} else {
const steamGame = await steamGamesWorker.run(Number(objectID), {
name: "getById",
});
const iconUrl = steamGame?.clientIcon
? getSteamAppAsset("icon", objectID, steamGame.clientIcon)
: null;
createGame(updatedGame!).catch(() => {});
await gameRepository
.insert({
title,
iconUrl,
objectID,
downloader,
shop,
status: "active",
downloadPath,
uri: repack.magnet,
})
.then((result) => {
if (iconUrl) {
getFileBase64(iconUrl).then((base64) =>
gameRepository.update({ objectID }, { iconUrl: base64 })
);
}
HydraApi.post(
"/games/download",
{
objectId: updatedGame!.objectID,
shop: updatedGame!.shop,
},
{ needsAuth: false }
).catch((err) => {
logger.error("Failed to create game download", err);
});
return result;
});
}
await DownloadManager.cancelDownload(updatedGame!.id);
await DownloadManager.startDownload(updatedGame!);
const updatedGame = await gameRepository.findOne({
where: {
objectID,
},
await downloadQueueRepository.delete({ game: { id: updatedGame!.id } });
await downloadQueueRepository.insert({ game: { id: updatedGame!.id } });
});
createGame(updatedGame!);
await downloadQueueRepository.delete({ game: { id: updatedGame!.id } });
await downloadQueueRepository.insert({ game: { id: updatedGame!.id } });
await DownloadManager.startDownload(updatedGame!);
};
registerEvent("startGameDownload", startGameDownload);

View File

@@ -1,6 +1,18 @@
import { registerEvent } from "../register-event";
import AutoLaunch from "auto-launch";
import { app } from "electron";
import path from "path";
import fs from "node:fs";
import { logger } from "@main/services";
const windowsStartupPath = path.join(
app.getPath("appData"),
"Microsoft",
"Windows",
"Start Menu",
"Programs",
"Startup"
);
const autoLaunch = async (
_event: Electron.IpcMainInvokeEvent,
@@ -13,9 +25,17 @@ const autoLaunch = async (
});
if (enabled) {
appLauncher.enable().catch(() => {});
appLauncher.enable().catch((err) => {
logger.error(err);
});
} else {
appLauncher.disable().catch(() => {});
if (process.platform == "win32") {
fs.rm(path.join(windowsStartupPath, "Hydra.vbs"), () => {});
}
appLauncher.disable().catch((err) => {
logger.error(err);
});
}
};

View File

@@ -0,0 +1,11 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
const blockUser = async (
_event: Electron.IpcMainInvokeEvent,
userId: string
) => {
await HydraApi.post(`/users/${userId}/block`);
};
registerEvent("blockUser", blockUser);

View File

@@ -0,0 +1,13 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import { UserBlocks } from "@types";
export const getBlockedUsers = async (
_event: Electron.IpcMainInvokeEvent,
take: number,
skip: number
): Promise<UserBlocks> => {
return HydraApi.get(`/profile/blocks`, { take, skip });
};
registerEvent("getBlockedUsers", getBlockedUsers);

View File

@@ -0,0 +1,29 @@
import { userAuthRepository } from "@main/repository";
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import { UserFriends } from "@types";
export const getUserFriends = async (
userId: string,
take: number,
skip: number
): Promise<UserFriends> => {
const loggedUser = await userAuthRepository.findOne({ where: { id: 1 } });
if (loggedUser?.userId === userId) {
return HydraApi.get(`/profile/friends`, { take, skip });
}
return HydraApi.get(`/users/${userId}/friends`, { take, skip });
};
const getUserFriendsEvent = async (
_event: Electron.IpcMainInvokeEvent,
userId: string,
take: number,
skip: number
) => {
return getUserFriends(userId, take, skip);
};
registerEvent("getUserFriends", getUserFriendsEvent);

View File

@@ -0,0 +1,12 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import type { UserStats } from "@types";
export const getUserStats = async (
_event: Electron.IpcMainInvokeEvent,
userId: string
): Promise<UserStats> => {
return HydraApi.get(`/users/${userId}/stats`);
};
registerEvent("getUserStats", getUserStats);

View File

@@ -1,54 +1,79 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
import { HydraApi, logger } from "@main/services";
import { steamGamesWorker } from "@main/workers";
import { UserProfile } from "@types";
import { convertSteamGameToCatalogueEntry } from "../helpers/search-games";
import { getSteamAppAsset } from "@main/helpers";
import type { UserProfile } from "@types";
import { steamUrlBuilder } from "@shared";
const getSteamGame = async (objectId: string) => {
try {
const steamGame = await steamGamesWorker.run(Number(objectId), {
name: "getById",
});
return {
title: steamGame.name,
iconUrl: steamUrlBuilder.icon(objectId, steamGame.clientIcon),
};
} catch (err) {
logger.error("Failed to get Steam game", err);
return null;
}
};
const getUser = async (
_event: Electron.IpcMainInvokeEvent,
userId: string
): Promise<UserProfile | null> => {
try {
const response = await HydraApi.get(`/user/${userId}`);
const profile = response.data;
const profile = await HydraApi.get<UserProfile | null>(`/users/${userId}`);
if (!profile) return null;
const recentGames = await Promise.all(
profile.recentGames.map(async (game) => {
const steamGame = await steamGamesWorker.run(Number(game.objectId), {
name: "getById",
});
const iconUrl = steamGame?.clientIcon
? getSteamAppAsset("icon", game.objectId, steamGame.clientIcon)
: null;
profile.recentGames
.map(async (game) => {
const steamGame = await getSteamGame(game.objectId);
return {
...game,
...convertSteamGameToCatalogueEntry(steamGame),
iconUrl,
};
})
return {
...game,
...steamGame,
};
})
.filter((game) => game)
);
const libraryGames = await Promise.all(
profile.libraryGames.map(async (game) => {
const steamGame = await steamGamesWorker.run(Number(game.objectId), {
name: "getById",
});
const iconUrl = steamGame?.clientIcon
? getSteamAppAsset("icon", game.objectId, steamGame.clientIcon)
: null;
profile.libraryGames
.map(async (game) => {
const steamGame = await getSteamGame(game.objectId);
return {
...game,
...convertSteamGameToCatalogueEntry(steamGame),
iconUrl,
};
})
return {
...game,
...steamGame,
};
})
.filter((game) => game)
);
return { ...profile, libraryGames, recentGames };
if (profile.currentGame) {
const steamGame = await getSteamGame(profile.currentGame.objectId);
if (steamGame) {
profile.currentGame = {
...profile.currentGame,
...steamGame,
};
}
}
return {
...profile,
libraryGames,
recentGames,
};
} catch (err) {
console.log(err);
return null;
}
};

View File

@@ -0,0 +1,16 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
export const reportUser = async (
_event: Electron.IpcMainInvokeEvent,
userId: string,
reason: string,
description: string
): Promise<void> => {
return HydraApi.post(`/users/${userId}/report`, {
reason,
description,
});
};
registerEvent("reportUser", reportUser);

View File

@@ -0,0 +1,11 @@
import { registerEvent } from "../register-event";
import { HydraApi } from "@main/services";
const unblockUser = async (
_event: Electron.IpcMainInvokeEvent,
userId: string
) => {
await HydraApi.post(`/users/${userId}/unblock`);
};
registerEvent("unblockUser", unblockUser);

View File

@@ -17,7 +17,8 @@ export const insertDownloadsFromSource = async (
const repacks: QueryDeepPartialEntity<Repack>[] = downloads.map(
(download) => ({
title: download.title,
magnet: download.uris[0],
uris: JSON.stringify(download.uris),
magnet: download.uris[0]!,
fileSize: download.fileSize,
repacker: downloadSource.name,
uploadDate: download.uploadDate,

View File

@@ -1,23 +1,7 @@
import axios from "axios";
import { JSDOM } from "jsdom";
import UserAgent from "user-agents";
export const getSteamAppAsset = (
category: "library" | "hero" | "logo" | "icon",
objectID: string,
clientIcon?: string
) => {
if (category === "library")
return `https://steamcdn-a.akamaihd.net/steam/apps/${objectID}/header.jpg`;
if (category === "hero")
return `https://steamcdn-a.akamaihd.net/steam/apps/${objectID}/library_hero.jpg`;
if (category === "logo")
return `https://cdn.cloudflare.steamstatic.com/steam/apps/${objectID}/logo.png`;
return `https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/${objectID}/${clientIcon}.ico`;
};
export const getFileBuffer = async (url: string) =>
fetch(url, { method: "GET" }).then((response) =>
response.arrayBuffer().then((buffer) => Buffer.from(buffer))
@@ -33,28 +17,25 @@ export const getFileBase64 = async (url: string) =>
})
);
export const steamUrlBuilder = {
library: (objectID: string) =>
`https://steamcdn-a.akamaihd.net/steam/apps/${objectID}/header.jpg`,
libraryHero: (objectID: string) =>
`https://steamcdn-a.akamaihd.net/steam/apps/${objectID}/library_hero.jpg`,
logo: (objectID: string) =>
`https://cdn.cloudflare.steamstatic.com/steam/apps/${objectID}/logo.png`,
};
export const sleep = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));
export const requestWebPage = async (url: string) => {
const userAgent = new UserAgent();
return axios
const data = await axios
.get(url, {
headers: {
"User-Agent": userAgent.toString(),
},
})
.then((response) => response.data);
const { window } = new JSDOM(data);
return window.document;
};
export const isPortableVersion = () =>
process.env.PORTABLE_EXECUTABLE_FILE != null;
export * from "./download-source";

View File

@@ -4,11 +4,14 @@ import updater from "electron-updater";
import i18n from "i18next";
import path from "node:path";
import url from "node:url";
import fs from "node:fs";
import { electronApp, optimizer } from "@electron-toolkit/utils";
import { logger, PythonInstance, WindowManager } from "@main/services";
import { dataSource } from "@main/data-source";
import * as resources from "@locales";
import resources from "@locales";
import { userPreferencesRepository } from "@main/repository";
import { knexClient, migrationConfig } from "./knex-client";
import { databaseDirectory } from "./constants";
const { autoUpdater } = updater;
@@ -52,6 +55,22 @@ if (process.defaultApp) {
app.setAsDefaultProtocolClient(PROTOCOL);
}
const runMigrations = async () => {
if (!fs.existsSync(databaseDirectory)) {
fs.mkdirSync(databaseDirectory, { recursive: true });
}
await knexClient.migrate.list(migrationConfig).then((result) => {
logger.log(
"Migrations to run:",
result[1].map((migration) => migration.name)
);
});
await knexClient.migrate.latest(migrationConfig);
await knexClient.destroy();
};
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
@@ -63,8 +82,15 @@ app.whenReady().then(async () => {
return net.fetch(url.pathToFileURL(decodeURI(filePath)).toString());
});
await runMigrations()
.then(() => {
logger.log("Migrations executed successfully");
})
.catch((err) => {
logger.log("Migrations failed to run:", err);
});
await dataSource.initialize();
await dataSource.runMigrations();
await import("./main");
@@ -86,10 +112,15 @@ app.on("browser-window-created", (_, window) => {
const handleDeepLinkPath = (uri?: string) => {
if (!uri) return;
const url = new URL(uri);
if (url.host === "install-source") {
WindowManager.redirect(`settings${url.search}`);
try {
const url = new URL(uri);
if (url.host === "install-source") {
WindowManager.redirect(`settings${url.search}`);
}
} catch (error) {
logger.error("Error handling deep link", uri, error);
}
};

38
src/main/knex-client.ts Normal file
View File

@@ -0,0 +1,38 @@
import knex, { Knex } from "knex";
import { databasePath } from "./constants";
import { Hydra2_0_3 } from "./migrations/20240830143811_Hydra_2_0_3";
import { RepackUris } from "./migrations/20240830143906_RepackUris";
import { UpdateUserLanguage } from "./migrations/20240913213944_update_user_language";
import { EnsureRepackUris } from "./migrations/20240915035339_ensure_repack_uris";
import { app } from "electron";
export type HydraMigration = Knex.Migration & { name: string };
class MigrationSource implements Knex.MigrationSource<HydraMigration> {
getMigrations(): Promise<HydraMigration[]> {
return Promise.resolve([
Hydra2_0_3,
RepackUris,
UpdateUserLanguage,
EnsureRepackUris,
]);
}
getMigrationName(migration: HydraMigration): string {
return migration.name;
}
getMigration(migration: HydraMigration): Promise<Knex.Migration> {
return Promise.resolve(migration);
}
}
export const knexClient = knex({
debug: !app.isPackaged,
client: "better-sqlite3",
connection: {
filename: databasePath,
},
});
export const migrationConfig: Knex.MigratorConfig = {
migrationSource: new MigrationSource(),
};

10
src/main/knexfile.ts Normal file
View File

@@ -0,0 +1,10 @@
const config = {
development: {
migrations: {
extension: "ts",
stub: "migrations/migration.stub",
},
},
};
export default config;

View File

@@ -18,12 +18,13 @@ import { HydraApi } from "./services/hydra-api";
import { uploadGamesBatch } from "./services/library-sync";
const loadState = async (userPreferences: UserPreferences | null) => {
await RepacksManager.updateRepacks();
RepacksManager.updateRepacks();
import("./events");
if (userPreferences?.realDebridApiToken)
if (userPreferences?.realDebridApiToken) {
RealDebridClient.authorize(userPreferences?.realDebridApiToken);
}
HydraApi.setupApi().then(() => {
uploadGamesBatch();

View File

@@ -1,11 +0,0 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class FixRepackUploadDate1715900413313 implements MigrationInterface {
public async up(_: QueryRunner): Promise<void> {
return;
}
public async down(_: QueryRunner): Promise<void> {
return;
}
}

View File

@@ -1,49 +0,0 @@
import { Game } from "@main/entity";
import { MigrationInterface, QueryRunner } from "typeorm";
export class AlterLastTimePlayedToDatime1716776027208
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
// 2024-05-27 02:08:17
// Mon, 27 May 2024 02:08:17 GMT
const updateLastTimePlayedValues = `
UPDATE game SET lastTimePlayed = (SELECT
SUBSTR(lastTimePlayed, 13, 4) || '-' || -- Year
CASE SUBSTR(lastTimePlayed, 9, 3)
WHEN 'Jan' THEN '01'
WHEN 'Feb' THEN '02'
WHEN 'Mar' THEN '03'
WHEN 'Apr' THEN '04'
WHEN 'May' THEN '05'
WHEN 'Jun' THEN '06'
WHEN 'Jul' THEN '07'
WHEN 'Aug' THEN '08'
WHEN 'Sep' THEN '09'
WHEN 'Oct' THEN '10'
WHEN 'Nov' THEN '11'
WHEN 'Dec' THEN '12'
END || '-' || -- Month
SUBSTR(lastTimePlayed, 6, 2) || ' ' || -- Day
SUBSTR(lastTimePlayed, 18, 8) -- hh:mm:ss;
FROM game)
WHERE lastTimePlayed IS NOT NULL;
`;
await queryRunner.query(updateLastTimePlayedValues);
}
public async down(queryRunner: QueryRunner): Promise<void> {
const queryBuilder = queryRunner.manager.createQueryBuilder(Game, "game");
const result = await queryBuilder.getMany();
for (const game of result) {
if (!game.lastTimePlayed) continue;
await queryRunner.query(
`UPDATE game set lastTimePlayed = ? WHERE id = ?;`,
[game.lastTimePlayed.toUTCString(), game.id]
);
}
}
}

View File

@@ -0,0 +1,171 @@
import type { HydraMigration } from "@main/knex-client";
import type { Knex } from "knex";
export const Hydra2_0_3: HydraMigration = {
name: "Hydra_2_0_3",
up: async (knex: Knex) => {
const timestamp = new Date().getTime();
await knex.schema.hasTable("migrations").then(async (exists) => {
if (exists) {
await knex.schema.dropTable("migrations");
}
});
await knex.schema.hasTable("download_source").then(async (exists) => {
if (!exists) {
await knex.schema.createTable("download_source", (table) => {
table.increments("id").primary();
table
.text("url")
.unique({ indexName: "download_source_url_unique_" + timestamp });
table.text("name").notNullable();
table.text("etag");
table.integer("downloadCount").notNullable().defaultTo(0);
table.text("status").notNullable().defaultTo(0);
table.datetime("createdAt").notNullable().defaultTo(knex.fn.now());
table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now());
});
}
});
await knex.schema.hasTable("repack").then(async (exists) => {
if (!exists) {
await knex.schema.createTable("repack", (table) => {
table.increments("id").primary();
table
.text("title")
.notNullable()
.unique({ indexName: "repack_title_unique_" + timestamp });
table
.text("magnet")
.notNullable()
.unique({ indexName: "repack_magnet_unique_" + timestamp });
table.integer("page");
table.text("repacker").notNullable();
table.text("fileSize").notNullable();
table.datetime("uploadDate").notNullable();
table.datetime("createdAt").notNullable().defaultTo(knex.fn.now());
table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now());
table
.integer("downloadSourceId")
.references("download_source.id")
.onDelete("CASCADE");
});
}
});
await knex.schema.hasTable("game").then(async (exists) => {
if (!exists) {
await knex.schema.createTable("game", (table) => {
table.increments("id").primary();
table
.text("objectID")
.notNullable()
.unique({ indexName: "game_objectID_unique_" + timestamp });
table
.text("remoteId")
.unique({ indexName: "game_remoteId_unique_" + timestamp });
table.text("title").notNullable();
table.text("iconUrl");
table.text("folderName");
table.text("downloadPath");
table.text("executablePath");
table.integer("playTimeInMilliseconds").notNullable().defaultTo(0);
table.text("shop").notNullable();
table.text("status");
table.integer("downloader").notNullable().defaultTo(1);
table.float("progress").notNullable().defaultTo(0);
table.integer("bytesDownloaded").notNullable().defaultTo(0);
table.datetime("lastTimePlayed");
table.float("fileSize").notNullable().defaultTo(0);
table.text("uri");
table.boolean("isDeleted").notNullable().defaultTo(0);
table.datetime("createdAt").notNullable().defaultTo(knex.fn.now());
table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now());
table
.integer("repackId")
.references("repack.id")
.unique("repack_repackId_unique_" + timestamp);
});
}
});
await knex.schema.hasTable("user_preferences").then(async (exists) => {
if (!exists) {
await knex.schema.createTable("user_preferences", (table) => {
table.increments("id").primary();
table.text("downloadsPath");
table.text("language").notNullable().defaultTo("en");
table.text("realDebridApiToken");
table
.boolean("downloadNotificationsEnabled")
.notNullable()
.defaultTo(0);
table
.boolean("repackUpdatesNotificationsEnabled")
.notNullable()
.defaultTo(0);
table.boolean("preferQuitInsteadOfHiding").notNullable().defaultTo(0);
table.boolean("runAtStartup").notNullable().defaultTo(0);
table.datetime("createdAt").notNullable().defaultTo(knex.fn.now());
table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now());
});
}
});
await knex.schema.hasTable("game_shop_cache").then(async (exists) => {
if (!exists) {
await knex.schema.createTable("game_shop_cache", (table) => {
table.text("objectID").primary().notNullable();
table.text("shop").notNullable();
table.text("serializedData");
table.text("howLongToBeatSerializedData");
table.text("language");
table.datetime("createdAt").notNullable().defaultTo(knex.fn.now());
table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now());
});
}
});
await knex.schema.hasTable("download_queue").then(async (exists) => {
if (!exists) {
await knex.schema.createTable("download_queue", (table) => {
table.increments("id").primary();
table
.integer("gameId")
.references("game.id")
.unique("download_queue_gameId_unique_" + timestamp);
table.datetime("createdAt").notNullable().defaultTo(knex.fn.now());
table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now());
});
}
});
await knex.schema.hasTable("user_auth").then(async (exists) => {
if (!exists) {
await knex.schema.createTable("user_auth", (table) => {
table.increments("id").primary();
table.text("userId").notNullable().defaultTo("");
table.text("displayName").notNullable().defaultTo("");
table.text("profileImageUrl");
table.text("accessToken").notNullable().defaultTo("");
table.text("refreshToken").notNullable().defaultTo("");
table.integer("tokenExpirationTimestamp").notNullable().defaultTo(0);
table.datetime("createdAt").notNullable().defaultTo(knex.fn.now());
table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now());
});
}
});
},
down: async (knex: Knex) => {
await knex.schema.dropTableIfExists("game");
await knex.schema.dropTableIfExists("repack");
await knex.schema.dropTableIfExists("download_queue");
await knex.schema.dropTableIfExists("user_auth");
await knex.schema.dropTableIfExists("game_shop_cache");
await knex.schema.dropTableIfExists("user_preferences");
await knex.schema.dropTableIfExists("download_source");
},
};

View File

@@ -0,0 +1,18 @@
import type { HydraMigration } from "@main/knex-client";
import type { Knex } from "knex";
export const RepackUris: HydraMigration = {
name: "RepackUris",
up: async (knex: Knex) => {
await knex.schema.alterTable("repack", (table) => {
table.text("uris").notNullable().defaultTo("[]");
});
},
down: async (knex: Knex) => {
await knex.schema.alterTable("repack", (table) => {
table.integer("page");
table.dropColumn("uris");
});
},
};

View File

@@ -0,0 +1,13 @@
import type { HydraMigration } from "@main/knex-client";
import type { Knex } from "knex";
export const UpdateUserLanguage: HydraMigration = {
name: "UpdateUserLanguage",
up: async (knex: Knex) => {
await knex("user_preferences")
.update("language", "pt-BR")
.where("language", "pt");
},
down: async (_knex: Knex) => {},
};

View File

@@ -0,0 +1,17 @@
import type { HydraMigration } from "@main/knex-client";
import type { Knex } from "knex";
export const EnsureRepackUris: HydraMigration = {
name: "EnsureRepackUris",
up: async (knex: Knex) => {
await knex.schema.hasColumn("repack", "uris").then(async (exists) => {
if (!exists) {
await knex.schema.table("repack", (table) => {
table.text("uris").notNullable().defaultTo("[]");
});
}
});
},
down: async (_knex: Knex) => {},
};

View File

@@ -1,7 +0,0 @@
import { FixRepackUploadDate1715900413313 } from "./1715900413313-fix_repack_uploadDate";
import { AlterLastTimePlayedToDatime1716776027208 } from "./1716776027208-alter_lastTimePlayed_to_datime";
export default [
FixRepackUploadDate1715900413313,
AlterLastTimePlayedToDatime1716776027208,
];

View File

@@ -0,0 +1,11 @@
import type { HydraMigration } from "@main/knex-client";
import type { Knex } from "knex";
export const MigrationName: HydraMigration = {
name: "MigrationName",
up: async (knex: Knex) => {
await knex.schema.createTable("table_name", (table) => {});
},
down: async (knex: Knex) => {},
};

View File

@@ -1,20 +0,0 @@
import path from "node:path";
import { spawn } from "node:child_process";
import { app } from "electron";
export const startAria2 = () => {
const binaryPath = app.isPackaged
? path.join(process.resourcesPath, "aria2", "aria2c")
: path.join(__dirname, "..", "..", "aria2", "aria2c");
return spawn(
binaryPath,
[
"--enable-rpc",
"--rpc-listen-all",
"--file-allocation=none",
"--allow-overwrite=true",
],
{ stdio: "inherit", windowsHide: true }
);
};

View File

@@ -6,17 +6,22 @@ import { downloadQueueRepository, gameRepository } from "@main/repository";
import { publishDownloadCompleteNotification } from "../notifications";
import { RealDebridDownloader } from "./real-debrid-downloader";
import type { DownloadProgress } from "@types";
import { GofileApi, QiwiApi } from "../hosters";
import { GenericHttpDownloader } from "./generic-http-downloader";
export class DownloadManager {
private static currentDownloader: Downloader | null = null;
private static downloadingGameId: number | null = null;
public static async watchDownloads() {
let status: DownloadProgress | null = null;
if (this.currentDownloader === Downloader.RealDebrid) {
if (this.currentDownloader === Downloader.Torrent) {
status = await PythonInstance.getStatus();
} else if (this.currentDownloader === Downloader.RealDebrid) {
status = await RealDebridDownloader.getStatus();
} else {
status = await PythonInstance.getStatus();
status = await GenericHttpDownloader.getStatus();
}
if (status) {
@@ -62,44 +67,73 @@ export class DownloadManager {
}
static async pauseDownload() {
if (this.currentDownloader === Downloader.RealDebrid) {
if (this.currentDownloader === Downloader.Torrent) {
await PythonInstance.pauseDownload();
} else if (this.currentDownloader === Downloader.RealDebrid) {
await RealDebridDownloader.pauseDownload();
} else {
await PythonInstance.pauseDownload();
await GenericHttpDownloader.pauseDownload();
}
WindowManager.mainWindow?.setProgressBar(-1);
this.currentDownloader = null;
this.downloadingGameId = null;
}
static async resumeDownload(game: Game) {
if (game.downloader === Downloader.RealDebrid) {
RealDebridDownloader.startDownload(game);
this.currentDownloader = Downloader.RealDebrid;
} else {
PythonInstance.startDownload(game);
this.currentDownloader = Downloader.Torrent;
}
return this.startDownload(game);
}
static async cancelDownload(gameId: number) {
if (this.currentDownloader === Downloader.RealDebrid) {
static async cancelDownload(gameId = this.downloadingGameId!) {
if (this.currentDownloader === Downloader.Torrent) {
PythonInstance.cancelDownload(gameId);
} else if (this.currentDownloader === Downloader.RealDebrid) {
RealDebridDownloader.cancelDownload(gameId);
} else {
PythonInstance.cancelDownload(gameId);
GenericHttpDownloader.cancelDownload(gameId);
}
WindowManager.mainWindow?.setProgressBar(-1);
this.currentDownloader = null;
this.downloadingGameId = null;
}
static async startDownload(game: Game) {
if (game.downloader === Downloader.RealDebrid) {
RealDebridDownloader.startDownload(game);
this.currentDownloader = Downloader.RealDebrid;
} else {
PythonInstance.startDownload(game);
this.currentDownloader = Downloader.Torrent;
switch (game.downloader) {
case Downloader.Gofile: {
const id = game!.uri!.split("/").pop();
const token = await GofileApi.authorize();
const downloadLink = await GofileApi.getDownloadLink(id!);
GenericHttpDownloader.startDownload(game, downloadLink, {
Cookie: `accountToken=${token}`,
});
break;
}
case Downloader.PixelDrain: {
const id = game!.uri!.split("/").pop();
await GenericHttpDownloader.startDownload(
game,
`https://pixeldrain.com/api/file/${id}?download`
);
break;
}
case Downloader.Qiwi: {
const downloadUrl = await QiwiApi.getDownloadUrl(game.uri!);
await GenericHttpDownloader.startDownload(game, downloadUrl);
break;
}
case Downloader.Torrent:
PythonInstance.startDownload(game);
break;
case Downloader.RealDebrid:
RealDebridDownloader.startDownload(game);
}
this.currentDownloader = game.downloader;
this.downloadingGameId = game.id;
}
}

View File

@@ -0,0 +1,109 @@
import { Game } from "@main/entity";
import { gameRepository } from "@main/repository";
import { calculateETA } from "./helpers";
import { DownloadProgress } from "@types";
import { HttpDownload } from "./http-download";
export class GenericHttpDownloader {
public static downloads = new Map<number, HttpDownload>();
public static downloadingGame: Game | null = null;
public static async getStatus() {
if (this.downloadingGame) {
const download = this.downloads.get(this.downloadingGame.id)!;
const status = download.getStatus();
if (status) {
const progress =
Number(status.completedLength) / Number(status.totalLength);
await gameRepository.update(
{ id: this.downloadingGame!.id },
{
bytesDownloaded: Number(status.completedLength),
fileSize: Number(status.totalLength),
progress,
status: "active",
folderName: status.folderName,
}
);
const result = {
numPeers: 0,
numSeeds: 0,
downloadSpeed: status.downloadSpeed,
timeRemaining: calculateETA(
status.totalLength,
status.completedLength,
status.downloadSpeed
),
isDownloadingMetadata: false,
isCheckingFiles: false,
progress,
gameId: this.downloadingGame!.id,
} as DownloadProgress;
if (progress === 1) {
this.downloads.delete(this.downloadingGame.id);
this.downloadingGame = null;
}
return result;
}
}
return null;
}
static async pauseDownload() {
if (this.downloadingGame) {
const httpDownload = this.downloads.get(this.downloadingGame!.id!);
if (httpDownload) {
await httpDownload.pauseDownload();
}
this.downloadingGame = null;
}
}
static async startDownload(
game: Game,
downloadUrl: string,
headers?: Record<string, string>
) {
this.downloadingGame = game;
if (this.downloads.has(game.id)) {
await this.resumeDownload(game.id!);
return;
}
const httpDownload = new HttpDownload(
game.downloadPath!,
downloadUrl,
headers
);
httpDownload.startDownload();
this.downloads.set(game.id!, httpDownload);
}
static async cancelDownload(gameId: number) {
const httpDownload = this.downloads.get(gameId);
if (httpDownload) {
await httpDownload.cancelDownload();
this.downloads.delete(gameId);
}
}
static async resumeDownload(gameId: number) {
const httpDownload = this.downloads.get(gameId);
if (httpDownload) {
await httpDownload.resumeDownload();
}
}
}

View File

@@ -1,68 +1,54 @@
import type { ChildProcess } from "node:child_process";
import { logger } from "../logger";
import { sleep } from "@main/helpers";
import { startAria2 } from "../aria2c";
import Aria2 from "aria2";
import { WindowManager } from "../window-manager";
import path from "node:path";
export class HttpDownload {
private static connected = false;
private static aria2c: ChildProcess | null = null;
private downloadItem: Electron.DownloadItem;
private static aria2 = new Aria2({});
constructor(
private downloadPath: string,
private downloadUrl: string,
private headers?: Record<string, string>
) {}
private static async connect() {
this.aria2c = startAria2();
let retries = 0;
while (retries < 4 && !this.connected) {
try {
await this.aria2.open();
logger.log("Connected to aria2");
this.connected = true;
} catch (err) {
await sleep(100);
logger.log("Failed to connect to aria2, retrying...");
retries++;
}
}
}
public static getStatus(gid: string) {
if (this.connected) {
return this.aria2.call("tellStatus", gid);
}
return null;
}
public static disconnect() {
if (this.aria2c) {
this.aria2c.kill();
this.connected = false;
}
}
static async cancelDownload(gid: string) {
await this.aria2.call("forceRemove", gid);
}
static async pauseDownload(gid: string) {
await this.aria2.call("forcePause", gid);
}
static async resumeDownload(gid: string) {
await this.aria2.call("unpause", gid);
}
static async startDownload(downloadPath: string, downloadUrl: string) {
if (!this.connected) await this.connect();
const options = {
dir: downloadPath,
public getStatus() {
return {
completedLength: this.downloadItem.getReceivedBytes(),
totalLength: this.downloadItem.getTotalBytes(),
downloadSpeed: this.downloadItem.getCurrentBytesPerSecond(),
folderName: this.downloadItem.getFilename(),
};
}
return this.aria2.call("addUri", [downloadUrl], options);
async cancelDownload() {
this.downloadItem.cancel();
}
async pauseDownload() {
this.downloadItem.pause();
}
async resumeDownload() {
this.downloadItem.resume();
}
async startDownload() {
return new Promise((resolve) => {
const options = this.headers ? { headers: this.headers } : {};
WindowManager.mainWindow?.webContents.downloadURL(
this.downloadUrl,
options
);
WindowManager.mainWindow?.webContents.session.once(
"will-download",
(_event, item, _webContents) => {
this.downloadItem = item;
item.setSavePath(path.join(this.downloadPath, item.getFilename()));
resolve(null);
}
);
});
}
}

Some files were not shown because too many files have changed in this diff Show More