mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-11 13:56:16 +00:00
Compare commits
604 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11dffd1b7a | ||
|
|
66d03197f4 | ||
|
|
d62d73e04a | ||
|
|
c055dcfeb4 | ||
|
|
22c8fdfe66 | ||
|
|
16a4680029 | ||
|
|
2e66e88609 | ||
|
|
c8482b3852 | ||
|
|
9bef2341be | ||
|
|
f219634b78 | ||
|
|
6d3b04fc3c | ||
|
|
1b2b8c8218 | ||
|
|
be5f045a06 | ||
|
|
c31935de0b | ||
|
|
fbcacd7c39 | ||
|
|
dcdc6a7114 | ||
|
|
9da67920b6 | ||
|
|
9a1b42a29f | ||
|
|
37b9eca0e1 | ||
|
|
92a3061f8d | ||
|
|
edc90d9ebe | ||
|
|
ebda8eccc6 | ||
|
|
6e2136e155 | ||
|
|
ac9df910f8 | ||
|
|
a615ff35cb | ||
|
|
d4cb3ef857 | ||
|
|
9ef6329799 | ||
|
|
458acb0b70 | ||
|
|
cee6f373eb | ||
|
|
519022525e | ||
|
|
fb416b6483 | ||
|
|
2f4d1396a9 | ||
|
|
8afb3c27dc | ||
|
|
b115bf632a | ||
|
|
9e9fb26deb | ||
|
|
0ac17e95ff | ||
|
|
93298f0bc2 | ||
|
|
4ab54780e0 | ||
|
|
92e6dfabff | ||
|
|
5bd8e35b9e | ||
|
|
68227278f5 | ||
|
|
beba2cf3e5 | ||
|
|
7a7afef799 | ||
|
|
98bef62a2f | ||
|
|
9eff4010d7 | ||
|
|
57de748ad3 | ||
|
|
7b453852b6 | ||
|
|
48a6b6e31d | ||
|
|
abe9e3099f | ||
|
|
adcb505ab7 | ||
|
|
468af807b0 | ||
|
|
c928d6fd4b | ||
|
|
8aa02e33f5 | ||
|
|
9de7d4a61e | ||
|
|
633bb7820b | ||
|
|
67f8b609ba | ||
|
|
a02eac4ecb | ||
|
|
973db98090 | ||
|
|
48e05dcaa5 | ||
|
|
f019820458 | ||
|
|
e092d701b4 | ||
|
|
d347991e0b | ||
|
|
b3ca63c62a | ||
|
|
6b6b472315 | ||
|
|
0fe57fbc3b | ||
|
|
570259c5c7 | ||
|
|
94a25a2383 | ||
|
|
b1b48e2ec0 | ||
|
|
8a9892bdbe | ||
|
|
71d79a4a15 | ||
|
|
b60d9aa4db | ||
|
|
e4f1abaa5a | ||
|
|
c01c589f2a | ||
|
|
678f63fdef | ||
|
|
6b31586734 | ||
|
|
188fe4537a | ||
|
|
884ba47b9b | ||
|
|
33c827d6ec | ||
|
|
5944fc5c4b | ||
|
|
54c419804c | ||
|
|
571947cd23 | ||
|
|
800e99fda0 | ||
|
|
4f32043966 | ||
|
|
fc8e62cdea | ||
|
|
b337fd8d64 | ||
|
|
c6da57995d | ||
|
|
56c3607400 | ||
|
|
4a59a52174 | ||
|
|
e933cec888 | ||
|
|
e56a8209e1 | ||
|
|
0805728a79 | ||
|
|
93c6ef8510 | ||
|
|
335ae5b3dc | ||
|
|
887d97fd20 | ||
|
|
17cfc7bb02 | ||
|
|
6b03705d54 | ||
|
|
4dd0e43611 | ||
|
|
dc662b1c7d | ||
|
|
ee094dd7af | ||
|
|
61c5fc3957 | ||
|
|
1fb1c9e81a | ||
|
|
1ef8e3fce3 | ||
|
|
e42ba4d527 | ||
|
|
411a08247f | ||
|
|
191023ac38 | ||
|
|
50d9b9f022 | ||
|
|
c1d1dec49d | ||
|
|
aa33635912 | ||
|
|
3b2b78dc7c | ||
|
|
2e5a324669 | ||
|
|
dce2f1b333 | ||
|
|
2c9129c7b6 | ||
|
|
944f3891bf | ||
|
|
634fc61c09 | ||
|
|
ca81281f1f | ||
|
|
b07451e91d | ||
|
|
ab4cf23f97 | ||
|
|
6179fb9cf6 | ||
|
|
cf84bf56b3 | ||
|
|
1eef86a40c | ||
|
|
a8624058e4 | ||
|
|
eea19d43c2 | ||
|
|
9c37711bbf | ||
|
|
30fb588d3c | ||
|
|
27ef85f653 | ||
|
|
e467bbff66 | ||
|
|
59b2096d06 | ||
|
|
af69509c61 | ||
|
|
19c45644d6 | ||
|
|
7eb69f6e16 | ||
|
|
c01ed86071 | ||
|
|
7fc376b47f | ||
|
|
da5cc11bff | ||
|
|
79ca354da1 | ||
|
|
b3e2346808 | ||
|
|
2ae10decf7 | ||
|
|
e14e49cdcc | ||
|
|
ce13f6aa21 | ||
|
|
15176a12de | ||
|
|
16f862d389 | ||
|
|
e7ba7b87b6 | ||
|
|
524bfe91ef | ||
|
|
63e74648c4 | ||
|
|
d048d562a3 | ||
|
|
05cb66f2a4 | ||
|
|
8b8494ee64 | ||
|
|
ab5e6c1f7a | ||
|
|
54d137e3ae | ||
|
|
38e6f010d6 | ||
|
|
16c4460011 | ||
|
|
1bf2c8faf9 | ||
|
|
1f72bb6138 | ||
|
|
32566e5dfc | ||
|
|
55c214eae6 | ||
|
|
3ac06fbce5 | ||
|
|
76259c2b54 | ||
|
|
aeaeb1f086 | ||
|
|
1997dbcd5d | ||
|
|
e8a1aa0616 | ||
|
|
ca21d8afe6 | ||
|
|
fa2a92d5ed | ||
|
|
d05150a078 | ||
|
|
6b2549ed13 | ||
|
|
c8fa8f99d2 | ||
|
|
ee7b139093 | ||
|
|
3f0a1207e9 | ||
|
|
56f0439aaf | ||
|
|
83122bb864 | ||
|
|
4e73009997 | ||
|
|
b8895afc0a | ||
|
|
a974141360 | ||
|
|
8fad9b05e6 | ||
|
|
1797abb2da | ||
|
|
9e5118d1dc | ||
|
|
7bbaae91c9 | ||
|
|
ba08e0b112 | ||
|
|
f21a8bf784 | ||
|
|
81f2e509c5 | ||
|
|
d31d056e5e | ||
|
|
aa21f7815d | ||
|
|
e5a261e75f | ||
|
|
a8f9478815 | ||
|
|
50665b4472 | ||
|
|
0b8cc4e335 | ||
|
|
55d1bfb34d | ||
|
|
713a3f4c50 | ||
|
|
95ce191533 | ||
|
|
33e9caf614 | ||
|
|
5cd497d0c9 | ||
|
|
9840418257 | ||
|
|
c68cb3211d | ||
|
|
4d37dddcab | ||
|
|
abd33d737d | ||
|
|
bc82cf2539 | ||
|
|
8c1851bb4c | ||
|
|
bcef86fd94 | ||
|
|
d2aef7ca98 | ||
|
|
4b97639972 | ||
|
|
bf33fa7ed9 | ||
|
|
53f4394a49 | ||
|
|
2af875fc51 | ||
|
|
9e2e317938 | ||
|
|
ac5ad7e962 | ||
|
|
4a194b3be5 | ||
|
|
d700e2706c | ||
|
|
80a25bf409 | ||
|
|
ca73316ee9 | ||
|
|
cc9a38acf8 | ||
|
|
dc8276bb34 | ||
|
|
e3d0ef598b | ||
|
|
c7d72b0adc | ||
|
|
2e427b33e2 | ||
|
|
f1b30eb969 | ||
|
|
d8446263eb | ||
|
|
9eef445b1a | ||
|
|
163b17324e | ||
|
|
97abef740c | ||
|
|
6946fd3bd0 | ||
|
|
8669c1d660 | ||
|
|
ceb8f164b7 | ||
|
|
08eda5573d | ||
|
|
cead92d900 | ||
|
|
3a86e3569a | ||
|
|
c6105bcdfd | ||
|
|
81a3ede4bd | ||
|
|
b51b185323 | ||
|
|
f5055c42aa | ||
|
|
7013f7c65d | ||
|
|
b7a61f4567 | ||
|
|
0faca5c9a1 | ||
|
|
06d2733fc5 | ||
|
|
4f4ada8d54 | ||
|
|
58dff75f64 | ||
|
|
1494d64da4 | ||
|
|
95a7922806 | ||
|
|
de178d672e | ||
|
|
e8b28ccf90 | ||
|
|
45d8923561 | ||
|
|
086ee8ac04 | ||
|
|
6dfd7279dc | ||
|
|
4a4a800b07 | ||
|
|
366cb1ac2f | ||
|
|
87eaf021b4 | ||
|
|
6b8ab895e3 | ||
|
|
d123f63095 | ||
|
|
9eb90bac62 | ||
|
|
ef036d6f57 | ||
|
|
5b85a9f2b7 | ||
|
|
038cc377ec | ||
|
|
13a4708a02 | ||
|
|
581f7983aa | ||
|
|
48b6d1c941 | ||
|
|
2c26fed478 | ||
|
|
7ac7d92a28 | ||
|
|
3f50738e37 | ||
|
|
d6e57c20c7 | ||
|
|
1290d25ae5 | ||
|
|
c7ae4db79d | ||
|
|
4f34743f94 | ||
|
|
76fc992d65 | ||
|
|
588cb983c2 | ||
|
|
73b4b2c13c | ||
|
|
0b68ddda78 | ||
|
|
34e6947a6a | ||
|
|
ea923d5082 | ||
|
|
4559e23610 | ||
|
|
5afe78467e | ||
|
|
0ea2cd39db | ||
|
|
7ec082be23 | ||
|
|
3da751a67b | ||
|
|
b32f1f9210 | ||
|
|
6eed76268b | ||
|
|
c6242fa3e1 | ||
|
|
467ea29ec2 | ||
|
|
4b1248b865 | ||
|
|
577c2da6e5 | ||
|
|
8fccbb6d81 | ||
|
|
3aa20aa7d9 | ||
|
|
0722868c35 | ||
|
|
1dd13303d5 | ||
|
|
485ee11449 | ||
|
|
5a85033486 | ||
|
|
eb3eb88f23 | ||
|
|
3a16eb2913 | ||
|
|
59066117c9 | ||
|
|
28de50b244 | ||
|
|
48e07370e4 | ||
|
|
299cf801ea | ||
|
|
a9e2996e90 | ||
|
|
334d487be6 | ||
|
|
8a1c3ac642 | ||
|
|
062bc6cf19 | ||
|
|
d505ccb4c5 | ||
|
|
8bdd70e7d3 | ||
|
|
7ebd91a652 | ||
|
|
b742a464c9 | ||
|
|
5f08fd0f5e | ||
|
|
fc9990bb72 | ||
|
|
4ea04b3dbc | ||
|
|
e45991cb7c | ||
|
|
078d18c75e | ||
|
|
5528330265 | ||
|
|
89464f4d3e | ||
|
|
a29562641c | ||
|
|
227eb6ff2d | ||
|
|
2038bd1fbe | ||
|
|
4ba82d3e82 | ||
|
|
95a0d55426 | ||
|
|
45f30a9208 | ||
|
|
81f453d60f | ||
|
|
f88cd61a23 | ||
|
|
0cdb25e705 | ||
|
|
2138aa9711 | ||
|
|
fdd7f753b3 | ||
|
|
a354d76652 | ||
|
|
521921d90e | ||
|
|
e93f02ca76 | ||
|
|
e83e7dc680 | ||
|
|
a9edb5a9cf | ||
|
|
257d331343 | ||
|
|
6b4e0108f1 | ||
|
|
290f305ee0 | ||
|
|
61580d5765 | ||
|
|
5f292bc53a | ||
|
|
2a02936648 | ||
|
|
eaa5b46b1f | ||
|
|
8705efc9b6 | ||
|
|
1bfb90f1a0 | ||
|
|
2de142dd73 | ||
|
|
2e41d16afe | ||
|
|
b66f58d120 | ||
|
|
42d36a01ea | ||
|
|
bbd11bb0b7 | ||
|
|
d62039fba1 | ||
|
|
5e019c41f4 | ||
|
|
8543aecda8 | ||
|
|
9308982eaa | ||
|
|
3690154cb6 | ||
|
|
37b5cb6b60 | ||
|
|
08bdad8bfd | ||
|
|
ddd9ea69df | ||
|
|
244db861a4 | ||
|
|
94a517bdfb | ||
|
|
9980e2f737 | ||
|
|
c9cb279213 | ||
|
|
e6829ca39b | ||
|
|
1171e95b87 | ||
|
|
84c746ef35 | ||
|
|
50c3503e37 | ||
|
|
a34a774fb7 | ||
|
|
4d61b8586d | ||
|
|
077f78c252 | ||
|
|
0a7ebc5c78 | ||
|
|
0751d6093f | ||
|
|
34a44e7fa9 | ||
|
|
d353002eab | ||
|
|
ffb3d79954 | ||
|
|
85516c1744 | ||
|
|
08a336b392 | ||
|
|
183b85d66a | ||
|
|
3dcd60d675 | ||
|
|
8b580ab789 | ||
|
|
ab14eb4bea | ||
|
|
aaedfb13f2 | ||
|
|
f14b4d25aa | ||
|
|
15d95a1ff2 | ||
|
|
7300d6383a | ||
|
|
a71958b550 | ||
|
|
0c97deaa48 | ||
|
|
7c1d9565ba | ||
|
|
d6ea0d817e | ||
|
|
2db32f270c | ||
|
|
f9996d0646 | ||
|
|
05bef7f80c | ||
|
|
85cb2a4cc8 | ||
|
|
f252abc7a7 | ||
|
|
bd9b4d3385 | ||
|
|
1299eecc12 | ||
|
|
cdd18a8ce2 | ||
|
|
179db348e1 | ||
|
|
016f47d17f | ||
|
|
dda8791f6d | ||
|
|
21305d3e39 | ||
|
|
965046db27 | ||
|
|
35e3339519 | ||
|
|
cbb48fbea6 | ||
|
|
c648ce3d59 | ||
|
|
b105dbfb77 | ||
|
|
8f6175b319 | ||
|
|
ff948016ea | ||
|
|
008f91f05a | ||
|
|
41d8f06112 | ||
|
|
67c39af6db | ||
|
|
b6e2b8e00c | ||
|
|
9aa106a63f | ||
|
|
2cf20332f4 | ||
|
|
0809104052 | ||
|
|
1e84a1558f | ||
|
|
5d9d4e5985 | ||
|
|
cd6a21d4f3 | ||
|
|
f859d51717 | ||
|
|
de2f61b592 | ||
|
|
06686c8a9b | ||
|
|
b16acd181d | ||
|
|
bbb4b8d16b | ||
|
|
1a2b415a27 | ||
|
|
7469c005d4 | ||
|
|
f68ce9248f | ||
|
|
5dfdbbe3e2 | ||
|
|
e9561080f3 | ||
|
|
4d72392f1d | ||
|
|
ee17b5106c | ||
|
|
e5cffbe598 | ||
|
|
43197ee153 | ||
|
|
d0b5fe54eb | ||
|
|
797a2ed456 | ||
|
|
86816dc3c3 | ||
|
|
d431c01d1b | ||
|
|
83c32de0c2 | ||
|
|
00ba2e01d1 | ||
|
|
274377f119 | ||
|
|
9af2e69b58 | ||
|
|
38255eb41d | ||
|
|
cf5710e461 | ||
|
|
5f8a5a857e | ||
|
|
36f1fc1242 | ||
|
|
b5f2650704 | ||
|
|
8572b02315 | ||
|
|
3b35d3fc52 | ||
|
|
0d43dcec8e | ||
|
|
952b10fb06 | ||
|
|
8f63bc5f15 | ||
|
|
676da22690 | ||
|
|
d8e8dceadf | ||
|
|
48cebe729e | ||
|
|
19e26cba28 | ||
|
|
cdb876fa72 | ||
|
|
a921887271 | ||
|
|
2099d72840 | ||
|
|
8924f25d7c | ||
|
|
7c9e15e75c | ||
|
|
5031ee47ca | ||
|
|
a240c3ae24 | ||
|
|
a21a381e2a | ||
|
|
0162ebd133 | ||
|
|
bffe74f0c7 | ||
|
|
bf97d744e2 | ||
|
|
d4bebd18e8 | ||
|
|
b3480eb70b | ||
|
|
e3da07141c | ||
|
|
7280429162 | ||
|
|
0b0d2d6b10 | ||
|
|
551b0b3c91 | ||
|
|
d20d3d0b77 | ||
|
|
a5dc101e6b | ||
|
|
8957b1b1dd | ||
|
|
42626efd05 | ||
|
|
69828e6926 | ||
|
|
9c28a6e9d0 | ||
|
|
a817a26be1 | ||
|
|
0b33cb339c | ||
|
|
41908433c5 | ||
|
|
fab15ccded | ||
|
|
5667c813d9 | ||
|
|
39ceb38ecd | ||
|
|
06f58291f7 | ||
|
|
07cfbab77f | ||
|
|
3670c4f0ff | ||
|
|
485d396b91 | ||
|
|
5aa6c72594 | ||
|
|
6fdb591784 | ||
|
|
ae6edaa058 | ||
|
|
3062b88f4a | ||
|
|
f90dd82cbd | ||
|
|
a8f072dd1b | ||
|
|
05a1cf9343 | ||
|
|
da607fe741 | ||
|
|
399d47ca9d | ||
|
|
317fe48927 | ||
|
|
4941709296 | ||
|
|
20bf7009e5 | ||
|
|
a01a105afa | ||
|
|
33c6203f29 | ||
|
|
b9f5baef34 | ||
|
|
811878e364 | ||
|
|
3b17953a82 | ||
|
|
484e79dba3 | ||
|
|
7eee942dcb | ||
|
|
a89e6760da | ||
|
|
e2257d7ca5 | ||
|
|
be13ecc5aa | ||
|
|
5b864367e8 | ||
|
|
0ccaed8d55 | ||
|
|
0491124a7d | ||
|
|
ac4956c25b | ||
|
|
c7920fe9f7 | ||
|
|
f31ae47ab2 | ||
|
|
3f305eaca0 | ||
|
|
9290d94e2a | ||
|
|
756cf19c23 | ||
|
|
7a13ecd2b7 | ||
|
|
19f022e0f6 | ||
|
|
026729e8c9 | ||
|
|
7f918aaaca | ||
|
|
d98a01df2f | ||
|
|
2cb76a9ad4 | ||
|
|
250c6901b7 | ||
|
|
e5fec91062 | ||
|
|
6fd38df79e | ||
|
|
d924c64710 | ||
|
|
6ae5f92ba9 | ||
|
|
4e1927a7eb | ||
|
|
1d4547c2c8 | ||
|
|
10943408e9 | ||
|
|
cdad2f5554 | ||
|
|
b0bf42f754 | ||
|
|
7e321ea9d1 | ||
|
|
01c3ddf167 | ||
|
|
f8770a03f7 | ||
|
|
3b7725d774 | ||
|
|
2679b143ed | ||
|
|
2b0f57f967 | ||
|
|
622107a6f1 | ||
|
|
5908544602 | ||
|
|
b330c94dca | ||
|
|
4b0f998830 | ||
|
|
d3d9315102 | ||
|
|
689fe5715e | ||
|
|
6a52c26874 | ||
|
|
60907cdc4b | ||
|
|
1b00e2ed57 | ||
|
|
6479049256 | ||
|
|
e739f3a483 | ||
|
|
d8937b3672 | ||
|
|
18f27e76d7 | ||
|
|
47018ace60 | ||
|
|
a8332c858e | ||
|
|
d93e580d0f | ||
|
|
0e7e62d596 | ||
|
|
1d05551f4e | ||
|
|
4908d07ef2 | ||
|
|
be4d13533c | ||
|
|
7231848bd8 | ||
|
|
fb5ed9aae3 | ||
|
|
e908cc6273 | ||
|
|
5e670aab24 | ||
|
|
75a9d56624 | ||
|
|
28bd70e745 | ||
|
|
38d652c507 | ||
|
|
539f444ab5 | ||
|
|
3cbbb71768 | ||
|
|
2034e0a157 | ||
|
|
653afa7210 | ||
|
|
72aa822655 | ||
|
|
4e8f260b33 | ||
|
|
7a2b693397 | ||
|
|
04a5dbb71d | ||
|
|
20dab9c4c1 | ||
|
|
7bdf7f8c2d | ||
|
|
8f3306fd87 | ||
|
|
95e802372f | ||
|
|
9c261551c3 | ||
|
|
4e9e9deec1 | ||
|
|
1c56227fa3 | ||
|
|
81ea790d73 | ||
|
|
3560295416 | ||
|
|
0d089bb5c4 | ||
|
|
d99bb7e46b | ||
|
|
ec77de5e1d | ||
|
|
82edc6d438 | ||
|
|
26db88966f | ||
|
|
f2af65d4cd | ||
|
|
e6b62399f7 | ||
|
|
713392ee29 | ||
|
|
c7da83cae1 | ||
|
|
f9343ca0c2 | ||
|
|
6053b7cd67 | ||
|
|
0333282915 | ||
|
|
23ab98294a | ||
|
|
27bff9d2e6 | ||
|
|
6b9f902b2c | ||
|
|
a65ec67820 | ||
|
|
4616f69a29 | ||
|
|
02417dda40 | ||
|
|
5f468d5b2e | ||
|
|
0aa36c5a57 | ||
|
|
2f0cd24fb8 | ||
|
|
dce700b189 | ||
|
|
e55d41889d | ||
|
|
ac18b5388a | ||
|
|
de4307e2a5 | ||
|
|
8f6922fc8a | ||
|
|
ff6a204686 | ||
|
|
92f35bad9f | ||
|
|
b84df28f39 | ||
|
|
09bd7dcc36 | ||
|
|
06ed5e07bf | ||
|
|
ada218cea1 | ||
|
|
2662ba3875 | ||
|
|
58693fdb00 | ||
|
|
1872ff1d24 | ||
|
|
08c4906465 | ||
|
|
a0344ea491 | ||
|
|
02c4f0a0e6 |
@@ -1,4 +1,3 @@
|
||||
MAIN_VITE_STEAMGRIDDB_API_KEY=YOUR_API_KEY
|
||||
MAIN_VITE_ONLINEFIX_USERNAME=YOUR_USERNAME
|
||||
MAIN_VITE_ONLINEFIX_PASSWORD=YOUR_PASSWORD
|
||||
MAIN_VITE_API_URL=API_URL
|
||||
|
||||
|
||||
40
.github/workflows/build.yml
vendored
40
.github/workflows/build.yml
vendored
@@ -1,8 +1,6 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: main
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -24,33 +22,22 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install -r requirements.txt
|
||||
|
||||
- name: Build with cx_Freeze
|
||||
run: python torrent-client/setup.py build
|
||||
|
||||
- name: Build Linux
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: yarn build:linux
|
||||
env:
|
||||
MAIN_VITE_STEAMGRIDDB_API_KEY: ${{ secrets.STEAMGRIDDB_API_KEY }}
|
||||
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
|
||||
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
|
||||
MAIN_VITE_API_URL: ${{ vars.MAIN_VITE_API_URL }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build Windows
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: yarn build:win
|
||||
env:
|
||||
MAIN_VITE_STEAMGRIDDB_API_KEY: ${{ secrets.STEAMGRIDDB_API_KEY }}
|
||||
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
|
||||
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
|
||||
MAIN_VITE_API_URL: ${{ vars.MAIN_VITE_API_URL }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create artifact
|
||||
@@ -58,7 +45,8 @@ jobs:
|
||||
with:
|
||||
name: Build-${{ matrix.os }}
|
||||
path: |
|
||||
dist/*.exe
|
||||
dist/win-unpacked/**
|
||||
dist/*-portable.exe
|
||||
dist/*.zip
|
||||
dist/*.dmg
|
||||
dist/*.deb
|
||||
@@ -66,21 +54,3 @@ jobs:
|
||||
dist/*.tar.gz
|
||||
dist/*.yml
|
||||
dist/*.blockmap
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
draft: true
|
||||
files: |
|
||||
dist/*.exe
|
||||
dist/*.zip
|
||||
dist/*.dmg
|
||||
dist/*.AppImage
|
||||
dist/*.snap
|
||||
dist/*.deb
|
||||
dist/*.rpm
|
||||
dist/*.tar.gz
|
||||
dist/*.yml
|
||||
dist/*.blockmap
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: Lint
|
||||
|
||||
on: [pull_request]
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
|
||||
61
.github/workflows/release.yml
vendored
Normal file
61
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, ubuntu-latest]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20.11.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
- name: Build Linux
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: 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 }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build Windows
|
||||
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 }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
draft: true
|
||||
files: |
|
||||
dist/*.exe
|
||||
dist/*.zip
|
||||
dist/*.dmg
|
||||
dist/*.AppImage
|
||||
dist/*.snap
|
||||
dist/*.deb
|
||||
dist/*.rpm
|
||||
dist/*.tar.gz
|
||||
dist/*.yml
|
||||
dist/*.blockmap
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,6 +1,6 @@
|
||||
.vscode
|
||||
node_modules
|
||||
hydra-download-manager
|
||||
aria2/
|
||||
fastlist.exe
|
||||
__pycache__
|
||||
dist
|
||||
@@ -9,4 +9,3 @@ out
|
||||
*.log*
|
||||
.env
|
||||
.vite
|
||||
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
yarn lint
|
||||
yarn typecheck
|
||||
yarn format
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
yarn format
|
||||
yarn lint
|
||||
yarn typecheck
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
out
|
||||
dist
|
||||
seeds
|
||||
pnpm-lock.yaml
|
||||
LICENSE.md
|
||||
tsconfig.json
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
[](README.ru.md)
|
||||
[](README.uk-UA.md)
|
||||
[](README.be.md)
|
||||
[](README.es.md)
|
||||
[](README.fr.md)
|
||||
|
||||

|
||||
|
||||
@@ -119,7 +121,7 @@ yarn
|
||||
|
||||
### Усталёўка Python 3.9
|
||||
|
||||
Упэўніцеся, што ў вас усталяваны Python 3.9 на вашым кампутары. Вы можаце загрузіць і ўсталяваць яго з [python.org](https://www.python.org/downloads/release/python-3919/).
|
||||
Упэўніцеся, што ў вас усталяваны Python 3.9 на вашым кампутары. Вы можаце загрузіць і ўсталяваць яго з [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||
|
||||
### Усталёўка залежнасцяў Python
|
||||
|
||||
|
||||
183
README.es.md
Normal file
183
README.es.md
Normal 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 es un launcher de juegos con su propio cliente de bittorrent y gestor propio de repacks.</strong>
|
||||
</p>
|
||||
|
||||
[](https://github.com/hydralauncher/hydra/actions)
|
||||
[](https://github.com/hydralauncher/hydra/releases)
|
||||
|
||||
[](README.be.md)
|
||||
[](README.pl.md)
|
||||
[](README.pt-BR.md)
|
||||
[](README.ru.md)
|
||||
[](README.uk-UA.md)
|
||||
[](README.md)
|
||||
[](README.fr.md)
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
## Tabla de Contenidos
|
||||
|
||||
- [Acerca de](#acerca-de)
|
||||
- [Características](#caracteristicas)
|
||||
- [Instalación](#Instalacion)
|
||||
- [Contribuir](#contribuir)
|
||||
- [Únete 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)
|
||||
- [Compilar desde el código fuente](#compilar-desde-el-código-fuente)
|
||||
- [Instalar Node.js](#instalar-nodejs)
|
||||
- [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)
|
||||
- [Variables del Entorno](#variables-del-entorno)
|
||||
- [Ejecución](#ejecucion)
|
||||
- [Compilación](#compilacion)
|
||||
- [Compilar el cliente de bittorrent](#compilar-el-cliente-de-bittorrent)
|
||||
- [Compilar la aplicación Electron](#compilar-la-aplicacion-electron)
|
||||
- [Colaboradores](#colaboradores)
|
||||
|
||||
## Acerca de
|
||||
|
||||
**Hydra** es un **Launcher de Juegos** con su propio **Cliente Bittorrent** y **autogestor de Repacks**.
|
||||
<br>
|
||||
El launcher está escrito en TypeScript (Electron) y Python, el cuál se encarga del sistema de torrent usando libtorrent.
|
||||
|
||||
## Caracteristicas
|
||||
|
||||
- Buscador e instalador autogestionado de repacks a través de las páginas más confiables en él [Megahilo](https://www.reddit.com/r/Piracy/wiki/megathread/)
|
||||
- Cliente propio de bittorrent integrado
|
||||
- Integración de How Long To Beat (HLTB) en la página del juego
|
||||
- Customización de rutas de descargas
|
||||
- Notificaciones en actualizaciones a listas de repacks
|
||||
- Soporte a Windows y Linux
|
||||
- En constante actualización
|
||||
- Y mucho más ...
|
||||
|
||||
## Instalacion
|
||||
|
||||
Sigue los pasos de abajo para instalar:
|
||||
|
||||
1. Descarga la última versión de Hydra desde la página de [Releases](https://github.com/hydralauncher/hydra/releases/latest).
|
||||
- Descarga solo el .exe si quieres instalar Hydra en Windows.
|
||||
- Descarga el .deb o .rpm o .zip si quieres instalar Hydra en Linux. (Depende de tu distro de Linux)
|
||||
2. Ejecuta el archivo descargado.
|
||||
3. ¡Disfruta de Hydra!
|
||||
|
||||
## <a name="contribuir"> Contribuir
|
||||
|
||||
### <a name="unete-a-nuestro-telegram"></a> Unete a nuestro Telegram
|
||||
|
||||
Puedes unirte a nuestra conversación y discusiones en nuestro canal de [Telegram](https://t.me/hydralauncher).
|
||||
|
||||
### Haz un fork y clona tu repositorio
|
||||
|
||||
1. Rea;iza un fork del repositorio [(Haz click acá para hacer un fork ahora)](https://github.com/hydralauncher/hydra/fork)
|
||||
2. Clona el código forkeado `git clone https://github.com/tu_nombredeusuario/hydra`
|
||||
3. Crea una nueva rama
|
||||
4. Sube tus commits
|
||||
5. Envía nuevas solicitudes de pull
|
||||
|
||||
### Maneras en las que puedes contribuir
|
||||
|
||||
- Traducción: Queremos que Hydra esté disponible para todas las personas que sean posible. Siéntete libre de ayudarnos a traducirlo a nuevos lenguajes o actualizar y mejorar las ya disponibles en Hydra.
|
||||
- Código: Hydra está hecho con Typescript, Electron y un poquito de Python. Si quieres contribuir, ¡únete a nuestro [Telegram](https://t.me/hydralauncher)!
|
||||
|
||||
### Estructura del proyecto
|
||||
|
||||
- torrent-client: Usamos libtorrent, una librería de Python que se encarga de manejar las descargas torrent
|
||||
- src/renderer: El UI de la aplicación
|
||||
- src/main: El resto de la lógica va acá.
|
||||
|
||||
## Compilar desde el código fuente
|
||||
|
||||
### Instalar Node.js
|
||||
|
||||
Asegúrate que tienes Node.js instalado en tú máquina. Si no es así, puedes descargarlo e instalarlo desde [nodejs.org](https://nodejs.org/).
|
||||
|
||||
### Instalar Yarn
|
||||
|
||||
Yarn es un gestor de paquetes para Node.js. Si no tienes aún instalado Yarn todavía, puedes hacerlo siguiendo las instrucciones en [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/).
|
||||
|
||||
### Instalar Dependencias de Node
|
||||
|
||||
Dirígete hasta el directorio del proyecto e instala las dependencias de Node usando Yarn:
|
||||
|
||||
```bash
|
||||
cd hydra
|
||||
yarn
|
||||
```
|
||||
|
||||
### Instalar Python 3.9
|
||||
|
||||
Asegúrate que tienes Python 3.9 instalado en tu máquina. Puedes descargarlo e instalarlo desde [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||
|
||||
### Instalar Dependencias de Python
|
||||
|
||||
Instala las dependencias de Python requeridas usando pip:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Variables del Entorno
|
||||
|
||||
Necesitas una llave API de SteamGridDB para así poder obtener los íconos de los juegos en la instalación.
|
||||
Si quieres también tener los repacks de onlinefix, necesitarás añadir tus credenciales al .env
|
||||
|
||||
Una vez que los tengas, puedes copiar o renombrar el archivo `.env.example` cómo `.env` y colocarlo en `STEAMGRIDDB_API_KEY`, `ONLINEFIX_USERNAME`, `ONLINEFIX_PASSWORD`.
|
||||
|
||||
## Ejecucion
|
||||
|
||||
Una vez que tengas todas las cosas listas, puedes ejecutar el siguiente comando para así iniciar el proceso de Electron y el cliente de bittorrent:
|
||||
|
||||
```bash
|
||||
yarn dev
|
||||
```
|
||||
|
||||
## Compilacion
|
||||
|
||||
### Compilar el cliente de bittorrent
|
||||
|
||||
Crea el cliente bittorrent usando este comando:
|
||||
|
||||
```bash
|
||||
python torrent-client/setup.py build
|
||||
```
|
||||
|
||||
### Compilar la aplicacion Electron
|
||||
|
||||
Crea la aplicación de Electron usando este comando:
|
||||
|
||||
En Windows:
|
||||
|
||||
```bash
|
||||
yarn build:win
|
||||
```
|
||||
|
||||
En Linux:
|
||||
|
||||
```bash
|
||||
yarn build:linux
|
||||
```
|
||||
|
||||
## Colaboradores
|
||||
|
||||
<a href="https://github.com/hydralauncher/hydra/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=hydralauncher/hydra" />
|
||||
</a>
|
||||
|
||||
## Licencia
|
||||
|
||||
Hydra está licenciado bajo la [MIT License](LICENSE).
|
||||
183
README.fr.md
Normal file
183
README.fr.md
Normal 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 est un lanceur de jeux avec son propre client bittorrent intégré et un scraper de repack auto-géré.</strong>
|
||||
</p>
|
||||
|
||||
[](https://github.com/hydralauncher/hydra/actions)
|
||||
[](https://github.com/hydralauncher/hydra/releases)
|
||||
|
||||
[](README.md)
|
||||
[](README.be.md)
|
||||
[](README.pl.md)
|
||||
[](README.pt-BR.md)
|
||||
[](README.ru.md)
|
||||
[](README.uk-UA.md)
|
||||
[](README.es.md)
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
## Table des Matières
|
||||
|
||||
- [À propos](#à-propos)
|
||||
- [Fonctionnalités](#fonctionnalités)
|
||||
- [Installation](#installation)
|
||||
- [Contribuer](#contribuer)
|
||||
- [Rejoindre notre Telegram](#rejoindre-notre-telegram)
|
||||
- [Fork et Cloner votre dépôt](#fork-et-cloner-votre-dépôt)
|
||||
- [Manières de contribuer](#manières-de-contribuer)
|
||||
- [Structure du projet](#structure-du-projet)
|
||||
- [Compiler depuis les sources](#compiler-depuis-les-sources)
|
||||
- [Installer Node.js](#installer-nodejs)
|
||||
- [Installer Yarn](#installer-yarn)
|
||||
- [Installer les dépendances Node](#installer-les-dépendances-node)
|
||||
- [Installer Python 3.9](#installer-python-39)
|
||||
- [Installer les dépendances Python](#installer-les-dépendances-python)
|
||||
- [Variables d'environnement](#variables-denvironnement)
|
||||
- [Lancement](#lancement)
|
||||
- [Compilation](#compilation)
|
||||
- [Compiler le client bittorrent](#compiler-le-client-bittorrent)
|
||||
- [Compiler l'application Electron](#compiler-lapplication-electron)
|
||||
- [Contributeurs](#contributeurs)
|
||||
|
||||
## À propos
|
||||
|
||||
**Hydra** est un **lanceur de jeux** avec son propre **client BitTorrent** intégré et un **scraper de repack auto-géré**.
|
||||
<br>
|
||||
Le lanceur est écrit en TypeScript (Electron) et Python, qui gère le système de torrent en utilisant libtorrent.
|
||||
|
||||
## Fonctionnalités
|
||||
|
||||
- Scraper de repack auto-géré parmi tous les sites les plus fiables sur le [Megathread]("https://www.reddit.com/r/Piracy/wiki/megathread/")
|
||||
- Client bittorrent intégré
|
||||
- Intégration How Long To Beat (HLTB) sur la page du jeu
|
||||
- Personnalisation des chemins de téléchargement
|
||||
- Notifications de mise à jour de la liste de repack
|
||||
- Support pour Windows et Linux
|
||||
- Constamment mis à jour
|
||||
- Et plus encore ...
|
||||
|
||||
## Installation
|
||||
|
||||
Suivez les étapes ci-dessous pour installer :
|
||||
|
||||
1. Téléchargez la dernière version de Hydra depuis la page [Releases](https://github.com/hydralauncher/hydra/releases/latest).
|
||||
- Téléchargez uniquement le .exe si vous voulez installer Hydra sur Windows.
|
||||
- Téléchargez .deb ou .rpm ou .zip si vous voulez installer Hydra sur Linux (cela dépend de votre distribution Linux).
|
||||
2. Exécutez le fichier téléchargé.
|
||||
3. Profitez de Hydra !
|
||||
|
||||
## Contribuer
|
||||
|
||||
### Rejoindre notre Telegram
|
||||
|
||||
Nous concentrons nos discussions sur notre [Telegram](https://t.me/hydralauncher).
|
||||
|
||||
### Fork et Cloner votre dépôt
|
||||
|
||||
1. Forkez le dépôt [(cliquez ici pour forker maintenant)](https://github.com/hydralauncher/hydra/fork)
|
||||
2. Clonez votre code forké `git clone https://github.com/votre_nom_utilisateur/hydra`
|
||||
3. Créez une nouvelle branche
|
||||
4. Pushez vos commits
|
||||
5. Créez une nouvelle Pull Request
|
||||
|
||||
### Manières de contribuer
|
||||
|
||||
- Traduction : Nous voulons que Hydra soit disponible pour le plus grand nombre de personnes possible. N'hésitez pas à aider à traduire dans de nouvelles langues ou à mettre à jour et améliorer celles qui sont déjà disponibles sur Hydra.
|
||||
- Code : Hydra est construit avec Typescript, Electron et un peu de Python. Si vous voulez contribuer, rejoignez notre [Telegram](https://t.me/hydralauncher) !
|
||||
|
||||
### Structure du projet
|
||||
|
||||
- torrent-client : Nous utilisons libtorrent, une bibliothèque Python, pour gérer les téléchargements torrent.
|
||||
- src/renderer : l'interface utilisateur de l'application.
|
||||
- src/main : toute la logique repose ici.
|
||||
|
||||
## Compiler depuis les sources
|
||||
|
||||
### Installer Node.js
|
||||
|
||||
Assurez-vous que Node.js est installé sur votre machine. Sinon, téléchargez et installez-le depuis [nodejs.org](https://nodejs.org/).
|
||||
|
||||
### Installer Yarn
|
||||
|
||||
Yarn est un gestionnaire de paquets pour Node.js. Si vous n'avez pas encore installé Yarn, vous pouvez le faire en suivant les instructions sur [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/).
|
||||
|
||||
### Installer les dépendances Node
|
||||
|
||||
Naviguez vers le répertoire du projet et installez les dépendances Node en utilisant Yarn :
|
||||
|
||||
```bash
|
||||
cd hydra
|
||||
yarn
|
||||
```
|
||||
|
||||
### Installer Python 3.9
|
||||
|
||||
Assurez-vous que Python 3.9 est installé sur votre machine. Vous pouvez le télécharger et l'installer depuis [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||
|
||||
### Installer les dépendances Python
|
||||
|
||||
Installez les dépendances Python requises en utilisant pip :
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Variables d'environnement
|
||||
|
||||
Vous aurez besoin d'une clé API SteamGridDB pour récupérer les icônes de jeux lors de l'installation.
|
||||
Si vous voulez avoir onlinefix comme repacker, vous devrez ajouter vos identifiants au fichier .env.
|
||||
|
||||
Une fois que vous l'avez, vous pouvez copier ou renommer le fichier `.env.example` en `.env` et y mettre `STEAMGRIDDB_API_KEY`, `ONLINEFIX_USERNAME`, `ONLINEFIX_PASSWORD`.
|
||||
|
||||
## Lancement
|
||||
|
||||
Une fois que vous avez tout configuré, vous pouvez exécuter la commande suivante pour démarrer à la fois le processus Electron et le client bittorrent :
|
||||
|
||||
```bash
|
||||
yarn dev
|
||||
```
|
||||
|
||||
## Compilation
|
||||
|
||||
### Compiler le client bittorrent
|
||||
|
||||
Compilez le client bittorrent en utilisant cette commande :
|
||||
|
||||
```bash
|
||||
python torrent-client/setup.py build
|
||||
```
|
||||
|
||||
### Compiler l'application Electron
|
||||
|
||||
Compilez l'application Electron en utilisant cette commande :
|
||||
|
||||
Sur Windows :
|
||||
|
||||
```bash
|
||||
yarn build:win
|
||||
```
|
||||
|
||||
Sur Linux :
|
||||
|
||||
```bash
|
||||
yarn build:linux
|
||||
```
|
||||
|
||||
## Contributeurs
|
||||
|
||||
<a href="https://github.com/hydralauncher/hydra/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=hydralauncher/hydra" />
|
||||
</a>
|
||||
|
||||
## License
|
||||
|
||||
Hydra est sous [License MIT](LICENSE).
|
||||
10
README.md
10
README.md
@@ -13,11 +13,13 @@
|
||||
[](https://github.com/hydralauncher/hydra/actions)
|
||||
[](https://github.com/hydralauncher/hydra/releases)
|
||||
|
||||
[](README.be.md)
|
||||
[](README.pl.md)
|
||||
[](README.pt-BR.md)
|
||||
[](README.md)
|
||||
[](README.ru.md)
|
||||
[](README.uk-UA.md)
|
||||
[](README.be.md)
|
||||
[](README.es.md)
|
||||
[](README.fr.md)
|
||||
|
||||

|
||||
|
||||
@@ -119,7 +121,7 @@ yarn
|
||||
|
||||
### Install Python 3.9
|
||||
|
||||
Ensure you have Python 3.9 installed on your machine. You can download and install it from [python.org](https://www.python.org/downloads/release/python-3919/).
|
||||
Ensure you have Python 3.9 installed on your machine. You can download and install it from [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||
|
||||
### Install Python Dependencies
|
||||
|
||||
@@ -134,7 +136,7 @@ pip install -r requirements.txt
|
||||
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`, `ONLINEFIX_USERNAME`, `ONLINEFIX_PASSWORD`.
|
||||
|
||||
## Running
|
||||
|
||||
|
||||
187
README.pl.md
Normal file
187
README.pl.md
Normal file
@@ -0,0 +1,187 @@
|
||||
<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 - to program uruchamiający gry z własnym wbudowanym klientem bittorrent i samodzielnie zarządzanym repackagerem..</strong>
|
||||
</p>
|
||||
|
||||
[](https://github.com/hydralauncher/hydra/actions)
|
||||
[](https://github.com/hydralauncher/hydra/releases)
|
||||
|
||||
[](README.be.md)
|
||||
[](README.md)
|
||||
[](README.pt-BR.md)
|
||||
[](README.ru.md)
|
||||
[](README.uk-UA.md)
|
||||
[](README.es.md)
|
||||
[](README.fr.md)
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
|
||||
## Zawartość.
|
||||
|
||||
- [O nas](#o-nas)
|
||||
- [Cechy.](#cechy)
|
||||
- [Instalacja](#instalacja)
|
||||
- [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)
|
||||
- [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)
|
||||
- [Zmienne środowiskowe](#zmienne-środowiskowe)
|
||||
- [Uruchomienie](#utwórz-kompilację-z-kodu-źródłowego)
|
||||
- [Tworzenie kompilacji](#tworzenie-kompilacji)
|
||||
- [Tworzenie klienta bittorrent](#zbuduj-klienta-bittorrent)
|
||||
- [Tworzenie kompilacji aplikacji Electron](#tworzenie-aplikacji-electron)
|
||||
- [Współtwórcy](#współtwórcy)
|
||||
|
||||
## O nas
|
||||
|
||||
**Hydra** - jest **programem uruchamiającym gry** z wbudowanym **klientem BitTorrent** i **samozarządzającym się repackagerem**.
|
||||
<br>
|
||||
Ten launcher jest napisany w TypeScript (Electron) i Pythonie, który współpracuje z systemem torrent przy użyciu libtorrent.
|
||||
|
||||
## Cechy
|
||||
|
||||
- Samodzielnie zarządzany repackager wśród wszystkich najbardziej zaufanych stron na [Megathread]("https://www.reddit.com/r/Piracy/wiki/megathread/").
|
||||
- Własny wbudowany klient bittorrent
|
||||
- Integracja funkcji How Long To Beat (HLTB) na stronie gry
|
||||
- Personalizacja folderu pobierania
|
||||
- Powiadomienia o aktualizacjach listy repacków
|
||||
- Wsparcie dla systemów Windows i Linux
|
||||
- Stała aktualizacja
|
||||
- I nie tylko ...
|
||||
|
||||
## Instalacja
|
||||
|
||||
Aby zainstalować, wykonaj poniższe czynności:
|
||||
|
||||
1. Pobierz najnowszą wersję programu Hydra ze strony [Wydania](https://github.com/hydralauncher/hydra/releases/latest).
|
||||
- Pobierz .exe tylko, jeśli chcesz zainstalować Hydrę w systemie Windows.
|
||||
- Pobierz .deb lub .rpm lub .zip, jeśli chcesz zainstalować Hydrę w systemie Linux (zależy od dystrybucji systemu Linux).
|
||||
2. Uruchom pobrany plik.
|
||||
3. Ciesz się Hydrą!
|
||||
|
||||
## <a name="contributing"> Dokonaj wpłaty
|
||||
|
||||
### <a name="join-our-telegram"></a> Dołącz do naszego kanału Telegram
|
||||
|
||||
Skupiamy nasze dyskusje na naszym kanale [Telegram](https://t.me/hydralauncher).
|
||||
|
||||
1. Dołącz do naszego kanału
|
||||
2. Przejdź do kanału ról i wybierz rolę Pracownik.
|
||||
3. Wejdź na kanał dev, komunikuj się z nami i dziel się swoimi pomysłami.
|
||||
|
||||
### Rozwidlenie i sklonowanie repozytorium
|
||||
|
||||
1. Rozwidlenie repozytorium [(kliknij tutaj, aby rozwidlić teraz)](https://github.com/hydralauncher/hydra/fork)
|
||||
2. Sklonuj swój rozwidlony kod `git clone https://github.com/your_username/hydra`.
|
||||
3. Utwórz nowy brunch
|
||||
4. Wypchnij swoje zatwierdzenia
|
||||
5. Wyślij nowy Pull Request
|
||||
|
||||
### Jak możesz pomóc
|
||||
|
||||
- Tłumaczenie: Chcemy, aby Hydra była dostępna dla jak największej liczby osób. Zachęcamy do pomocy w tłumaczeniu na nowe języki lub aktualizowaniu i ulepszaniu tych, które są już dostępne na Hydrze.
|
||||
- Kod: Hydra jest zbudowana przy użyciu Typescript, Electron i odrobiny Pythona. Jeśli chcesz wnieść swój wkład, dołącz do naszego kanału Telegram!
|
||||
|
||||
### Struktura projektu
|
||||
|
||||
- Klient torrent: Używamy libtorrent, biblioteki Pythona, do zarządzania pobieraniem torrentów.
|
||||
- src/renderer: interfejs aplikacji
|
||||
- src/main: cała logika jest tutaj.
|
||||
|
||||
## Utwórz kompilację z kodu źródłowego
|
||||
|
||||
### Zainstaluj Node.js
|
||||
|
||||
Upewnij się, że masz zainstalowany Node.js na swoim komputerze. Jeśli nie, pobierz i zainstaluj go ze strony [nodejs.org](https://nodejs.org/).
|
||||
|
||||
### Zainstaluj Yarn
|
||||
|
||||
Yarn to menedżer pakietów dla Node.js. Jeśli jeszcze nie zainstalowałeś Yarn, możesz to zrobić, postępując zgodnie z instrukcjami na stronie [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/).
|
||||
|
||||
### Zainstaluj zależności Node
|
||||
|
||||
Przejdź do katalogu projektu i zainstaluj zależności Node za pomocą Yarn:
|
||||
|
||||
```bash
|
||||
cd hydra
|
||||
yarn
|
||||
```
|
||||
|
||||
### Zainstaluj Python 3.9
|
||||
|
||||
Upewnij się, że masz zainstalowany Python 3.9 na swoim komputerze. Można go pobrać i zainstalować ze strony [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||
|
||||
### Zainstaluj zależności Pythona
|
||||
|
||||
Zainstaluj niezbędne zależności Pythona za pomocą pip:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Zmienne środowiskowe
|
||||
|
||||
Będziesz potrzebował klucza API SteamGridDB, aby uzyskać ikony gier podczas instalacji.
|
||||
Jeśli chcesz użyć onlinefix jako repackagera, musisz dodać swoje dane uwierzytelniające do .env
|
||||
|
||||
Po jego uzyskaniu można skopiować plik lub zmienić jego nazwę `.env.example` na `.env` i umieść go na`STEAMGRIDDB_API_KEY`, `ONLINEFIX_USERNAME`, `ONLINEFIX_PASSWORD`.
|
||||
|
||||
## Run
|
||||
|
||||
Po skonfigurowaniu wszystkiego można uruchomić następujące polecenie, aby uruchomić zarówno proces Electron, jak i klienta bittorrent:
|
||||
|
||||
```bash
|
||||
yarn dev
|
||||
```
|
||||
|
||||
## Tworzenie kompilacji
|
||||
|
||||
### Zbuduj klienta bittorrent
|
||||
|
||||
Zbuduj klienta bittorrent za pomocą tego poleceniaи:
|
||||
|
||||
```bash
|
||||
python torrent-client/setup.py build
|
||||
```
|
||||
|
||||
### Tworzenie aplikacji Electron
|
||||
|
||||
Zbuduj aplikację Electron za pomocą tego polecenia:
|
||||
|
||||
W systemie Windows:
|
||||
|
||||
```bash
|
||||
yarn build:win
|
||||
```
|
||||
|
||||
W systemie Linux:
|
||||
|
||||
```bash
|
||||
yarn build:linux
|
||||
```
|
||||
|
||||
## Współtwórcy
|
||||
|
||||
<a href="https://github.com/hydralauncher/hydra/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=hydralauncher/hydra" />
|
||||
</a>
|
||||
|
||||
## License
|
||||
|
||||
Hydra posiada licencję [MIT License](LICENSE).
|
||||
@@ -13,11 +13,13 @@
|
||||
[](https://github.com/hydralauncher/hydra/actions)
|
||||
[](https://github.com/hydralauncher/hydra/releases)
|
||||
|
||||
[](README.pt-BR.md)
|
||||
[](README.be.md)
|
||||
[](README.md)
|
||||
[](README.pl.md)
|
||||
[](README.ru.md)
|
||||
[](README.uk-UA.md)
|
||||
[](README.be.md)
|
||||
[](README.es.md)
|
||||
[](README.fr.md)
|
||||
|
||||

|
||||
|
||||
@@ -119,7 +121,7 @@ yarn
|
||||
|
||||
### <a name="install-python-39"></a> Instale Python 3.9
|
||||
|
||||
Certifique-se de ter o Python 3.9 instalado em sua máquina. Você pode baixá-lo e instalá-lo em [python.org](https://www.python.org/downloads/release/python-3919/).
|
||||
Certifique-se de ter o Python 3.9 instalado em sua máquina. Você pode baixá-lo e instalá-lo em [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||
|
||||
### <a name="install-python-dependencies"></a> Instale Python Dependencies
|
||||
|
||||
|
||||
12
README.ru.md
12
README.ru.md
@@ -13,11 +13,13 @@
|
||||
[](https://github.com/hydralauncher/hydra/actions)
|
||||
[](https://github.com/hydralauncher/hydra/releases)
|
||||
|
||||
[](README.pt-BR.md)
|
||||
[](README.md)
|
||||
[](README.ru.md)
|
||||
[](README.uk-UA.md)
|
||||
[](README.be.md)
|
||||
[](README.md)
|
||||
[](README.pl.md)
|
||||
[](README.pt-BR.md)
|
||||
[](README.uk-UA.md)
|
||||
[](README.es.md)
|
||||
[](README.fr.md)
|
||||
|
||||

|
||||
|
||||
@@ -119,7 +121,7 @@ yarn
|
||||
|
||||
### Установка Python 3.9
|
||||
|
||||
Убедитесь, что у вас установлен Python 3.9 на вашем компьютере. Вы можете загрузить и установить его с [python.org](https://www.python.org/downloads/release/python-3919/).
|
||||
Убедитесь, что у вас установлен Python 3.9 на вашем компьютере. Вы можете загрузить и установить его с [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||
|
||||
### Установка зависимостей Python
|
||||
|
||||
|
||||
@@ -13,11 +13,13 @@
|
||||
[](https://github.com/hydralauncher/hydra/actions)
|
||||
[](https://github.com/hydralauncher/hydra/releases)
|
||||
|
||||
[](README.pt-BR.md)
|
||||
[](README.md)
|
||||
[](README.ru.md)
|
||||
[](README.uk-UA.md)
|
||||
[](README.be.md)
|
||||
[](README.md)
|
||||
[](README.pl.md)
|
||||
[](README.pt-BR.md)
|
||||
[](README.ru.md)
|
||||
[](README.es.md)
|
||||
[](README.fr.md)
|
||||
|
||||

|
||||
|
||||
@@ -123,7 +125,7 @@ yarn
|
||||
|
||||
### Встановіть Python 3.9
|
||||
|
||||
Переконайтеся, що на вашому комп'ютері встановлено Python 3.9. Ви можете завантажити та встановити його з [python.org](https://www.python.org/downloads/release/python-3919/).
|
||||
Переконайтеся, що на вашому комп'ютері встановлено Python 3.9. Ви можете завантажити та встановити його з [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||
|
||||
### Встановіть Python залежності
|
||||
|
||||
|
||||
BIN
build/icon.icns
BIN
build/icon.icns
Binary file not shown.
BIN
build/icons/512x512.png
Normal file
BIN
build/icons/512x512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 188 KiB |
@@ -3,9 +3,11 @@ productName: Hydra
|
||||
directories:
|
||||
buildResources: build
|
||||
extraResources:
|
||||
- hydra-download-manager
|
||||
- hydra.db
|
||||
- fastlist.exe
|
||||
- aria2
|
||||
- seeds
|
||||
- from: node_modules/ps-list/vendor/fastlist-0.3.0-x64.exe
|
||||
to: fastlist.exe
|
||||
- from: node_modules/create-desktop-shortcuts/src/windows.vbs
|
||||
files:
|
||||
- "!**/.vscode/*"
|
||||
- "!src/*"
|
||||
@@ -18,12 +20,19 @@ asarUnpack:
|
||||
win:
|
||||
executableName: Hydra
|
||||
requestedExecutionLevel: requireAdministrator
|
||||
target:
|
||||
- nsis
|
||||
- portable
|
||||
nsis:
|
||||
artifactName: ${name}-${version}-setup.${ext}
|
||||
shortcutName: ${productName}
|
||||
uninstallDisplayName: ${productName}
|
||||
createDesktopShortcut: always
|
||||
oneClick: false
|
||||
allowToChangeInstallationDirectory: true
|
||||
portable:
|
||||
artifactName: ${name}-${version}-portable.${ext}
|
||||
requestExecutionLevel: admin
|
||||
mac:
|
||||
entitlementsInherit: build/entitlements.mac.plist
|
||||
extendInfo:
|
||||
@@ -39,8 +48,11 @@ linux:
|
||||
- AppImage
|
||||
- snap
|
||||
- deb
|
||||
- rpm
|
||||
maintainer: electronjs.org
|
||||
category: Utility
|
||||
category: Game
|
||||
mimeTypes:
|
||||
- x-scheme-handler/hydralauncher
|
||||
appImage:
|
||||
artifactName: ${name}-${version}.${ext}
|
||||
npmRebuild: false
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
|
||||
import svgr from "vite-plugin-svgr";
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
loadEnv(mode);
|
||||
|
||||
|
||||
31
package.json
31
package.json
@@ -1,15 +1,18 @@
|
||||
{
|
||||
"name": "hydra",
|
||||
"version": "1.2.1",
|
||||
"name": "hydralauncher",
|
||||
"version": "2.0.1",
|
||||
"description": "Hydra",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "Los Broxas",
|
||||
"homepage": "https://hydralauncher.site",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hydralauncher/hydra.git"
|
||||
},
|
||||
"type": "module",
|
||||
"engines": {
|
||||
"npm": "please-use-yarn",
|
||||
"yarn": ">= 1.19.1"
|
||||
},
|
||||
"scripts": {
|
||||
"format": "prettier --write .",
|
||||
"format-check": "prettier --check .",
|
||||
@@ -25,7 +28,8 @@
|
||||
"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"
|
||||
"prepare": "husky",
|
||||
"typeorm:migration-create": "yarn typeorm migration:create"
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron-toolkit/preload": "^3.0.0",
|
||||
@@ -36,6 +40,7 @@
|
||||
"@reduxjs/toolkit": "^2.2.3",
|
||||
"@vanilla-extract/css": "^1.14.2",
|
||||
"@vanilla-extract/recipes": "^0.5.2",
|
||||
"aria2": "^4.1.2",
|
||||
"auto-launch": "^5.0.6",
|
||||
"axios": "^1.6.8",
|
||||
"better-sqlite3": "^9.5.0",
|
||||
@@ -43,18 +48,23 @@
|
||||
"classnames": "^2.5.1",
|
||||
"color": "^4.2.3",
|
||||
"color.js": "^1.2.0",
|
||||
"create-desktop-shortcuts": "^1.11.0",
|
||||
"date-fns": "^3.6.0",
|
||||
"easydl": "^1.1.1",
|
||||
"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",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lottie-react": "^2.4.0",
|
||||
"node-7z-archive": "^1.1.7",
|
||||
"parse-torrent": "^11.0.16",
|
||||
"piscina": "^4.5.1",
|
||||
"ps-list": "^8.1.1",
|
||||
"react-i18next": "^14.1.0",
|
||||
"react-loading-skeleton": "^3.4.0",
|
||||
@@ -62,8 +72,8 @@
|
||||
"react-router-dom": "^6.22.3",
|
||||
"typeorm": "^0.3.20",
|
||||
"user-agents": "^1.1.193",
|
||||
"winston": "^3.13.0",
|
||||
"yaml": "^2.4.1"
|
||||
"yaml": "^2.4.1",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.3.0",
|
||||
@@ -73,15 +83,18 @@
|
||||
"@electron-toolkit/tsconfig": "^1.0.1",
|
||||
"@swc/core": "^1.4.16",
|
||||
"@types/auto-launch": "^5.0.5",
|
||||
"@types/color": "^3.0.6",
|
||||
"@types/jsdom": "^21.1.6",
|
||||
"@types/jsonwebtoken": "^9.0.6",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^20.12.7",
|
||||
"@types/parse-torrent": "^5.8.7",
|
||||
"@types/react": "^18.2.48",
|
||||
"@types/react-dom": "^18.2.18",
|
||||
"@types/user-agents": "^1.0.4",
|
||||
"@vanilla-extract/vite-plugin": "^4.0.7",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"electron": "^28.2.0",
|
||||
"electron": "^30.0.9",
|
||||
"electron-builder": "^24.9.1",
|
||||
"electron-vite": "^2.0.0",
|
||||
"eslint": "^8.56.0",
|
||||
|
||||
@@ -1,8 +1,50 @@
|
||||
const fs = require("fs");
|
||||
const { default: axios } = require("axios");
|
||||
const util = require("node:util");
|
||||
const fs = require("node:fs");
|
||||
|
||||
if (process.platform === "win32") {
|
||||
fs.copyFileSync(
|
||||
"node_modules/ps-list/vendor/fastlist-0.3.0-x64.exe",
|
||||
"fastlist.exe"
|
||||
);
|
||||
}
|
||||
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();
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
libtorrent
|
||||
cx_Freeze
|
||||
cx_Logging; sys_platform == 'win32'
|
||||
lief; sys_platform == 'win32'
|
||||
pywin32; sys_platform == 'win32'
|
||||
1
seeds/steam-games.json
Normal file
1
seeds/steam-games.json
Normal file
File diff suppressed because one or more lines are too long
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "مميّز",
|
||||
"recently_added": "مضاف مؤخراً",
|
||||
"trending": "شائع",
|
||||
"surprise_me": "فاجئني",
|
||||
"no_results": "لم يتم العثور على نتائج"
|
||||
@@ -12,16 +11,10 @@
|
||||
"settings": "إعدادات",
|
||||
"my_library": "مكتبتي",
|
||||
"downloading_metadata": "{{title}} (جارٍ تنزيل البيانات الوصفية...)",
|
||||
"checking_files": "{{title}} ({{percentage}} - جارٍ التحقق من الملفات...)",
|
||||
"paused": "{{title}} (متوقف)",
|
||||
"downloading": "{{title}} ({{percentage}} - جارٍ التنزيل...)",
|
||||
"filter": "بحث في المكتبة",
|
||||
"follow_us": "تابعنا",
|
||||
"home": "الرئيسية",
|
||||
"discord": "انضم إلى الـDiscord الخاص بنا",
|
||||
"telegram": "انضم إلى قناة Telegram الخاصة بنا",
|
||||
"x": "تابعنا على X",
|
||||
"github": "ساهم في مشروعنا على GitHub"
|
||||
"home": "الرئيسية"
|
||||
},
|
||||
"header": {
|
||||
"search": "ابحث عن الألعاب",
|
||||
@@ -34,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "لا يوجد تنزيلات جارية",
|
||||
"downloading_metadata": "جارٍ تنزيل بيانات وصف {{title}}",
|
||||
"checking_files": "جارٍ التحقق من ملفات {{title}}… ({{percentage}} مكتملة)",
|
||||
"downloading": "جارٍ تنزيل {{title}}… ({{percentage}} مكتملة) - الانتهاء {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -52,22 +44,15 @@
|
||||
"pause": "إيقاف",
|
||||
"cancel": "إلغاء",
|
||||
"remove": "إزالة",
|
||||
"remove_from_list": "إزالة",
|
||||
"space_left_on_disk": "{{space}} متبقية على القرص",
|
||||
"eta": "الوقت المتبقي {{eta}}",
|
||||
"downloading_metadata": "جاري تنزيل البيانات الوصفية...",
|
||||
"checking_files": "جاري التحقق من الملفات...",
|
||||
"filter": "تصفية حزم إعادة التجميع",
|
||||
"requirements": "متطلبات النظام",
|
||||
"minimum": "الحد الأدنى",
|
||||
"recommended": "موصى به",
|
||||
"no_minimum_requirements": "{{title}} لا تتوفر معلومات عن الحد الأدنى للمتطلبات",
|
||||
"no_recommended_requirements": "{{title}} لا تتوفر معلومات عن المتطلبات الموصى بها",
|
||||
"paused_progress": "{{progress}} (متوقف)",
|
||||
"release_date": "تم الإصدار في {{date}}",
|
||||
"publisher": "نشر بواسطة {{publisher}}",
|
||||
"copy_link_to_clipboard": "نسخ الرابط",
|
||||
"copied_link_to_clipboard": "تم نسخ الرابط",
|
||||
"hours": "ساعات",
|
||||
"minutes": "دقائق",
|
||||
"amount_hours": "{{amount}} ساعات",
|
||||
@@ -88,14 +73,6 @@
|
||||
"repacks_modal_description": "اختر الحزمة التي تريد تنزيلها",
|
||||
"select_folder_hint": "لتغيير المجلد الافتراضي، انتقل إلى الإعدادات",
|
||||
"download_now": "تنزيل الآن",
|
||||
"installation_instructions": "إرشادات التثبيت",
|
||||
"installation_instructions_description": "هناك خطوات إضافية مطلوبة لتثبيت هذه اللعبة",
|
||||
"online_fix_instruction": "تتطلب ألعاب OnlineFix كلمة مرور لاستخراجها. عند الحاجة، استخدم كلمة المرور التالية:",
|
||||
"dodi_installation_instruction": "عند فتح مثبت DODI، اضغط على مفتاح التشغيل لأعلى <0 /> لبدء عملية التثبيت:",
|
||||
"dont_show_it_again": "لا تعرضها مرة أخرى",
|
||||
"copy_to_clipboard": "نسخ",
|
||||
"copied_to_clipboard": "تم النسخ",
|
||||
"got_it": "حسنأ",
|
||||
"no_shop_details": "لم يتم استرداد تفاصيل المتجر.",
|
||||
"download_options": "خيارات التنزيل",
|
||||
"download_path": "مسار التنزيل",
|
||||
@@ -118,24 +95,16 @@
|
||||
"eta": "الوقت المتبقي {{eta}}",
|
||||
"paused": "متوقفة مؤقتًا",
|
||||
"verifying": "جار التحقق…",
|
||||
"completed_at": "اكتمل في {{date}}",
|
||||
"completed": "اكتمل",
|
||||
"cancelled": "ملغي",
|
||||
"download_again": "تحميل مرة أخرى",
|
||||
"cancel": "إلغاء",
|
||||
"filter": "تصفية الألعاب التي تم تنزيلها",
|
||||
"remove": "إزالة",
|
||||
"downloading_metadata": "جار تنزيل البيانات الوصفية…",
|
||||
"checking_files": "جار التحقق من الملفات…",
|
||||
"starting_download": "يبدأ التنزيل…",
|
||||
"deleting": "جار حذف المثبت…",
|
||||
"delete": "إزالة المثبت",
|
||||
"remove_from_list": "إزالة",
|
||||
"delete_modal_title": "هل أنت متأكد؟",
|
||||
"delete_modal_description": "سيؤدي هذا إلى إزالة جميع ملفات التثبيت من جهاز الكمبيوتر الخاص بك",
|
||||
"install": "تثبيت",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "تورنت"
|
||||
"install": "تثبيت"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "مسار التنزيلات",
|
||||
@@ -143,16 +112,13 @@
|
||||
"notifications": "الإشعارات",
|
||||
"enable_download_notifications": "عند اكتمال التنزيل",
|
||||
"enable_repack_list_notifications": "عند إضافة حزمة جديدة",
|
||||
"telemetry": "القياس عن بعد",
|
||||
"telemetry_description": "تفعيل إحصائيات الاستخدام مجهولة المصدر",
|
||||
"real_debrid_api_token_label": "رمز واجهة برمجة التطبيقات (API) لـReal Debrid ",
|
||||
"real_debrid_api_token_label": "رمز واجهة برمجة التطبيقات (API) لـReal-Debrid ",
|
||||
"quit_app_instead_hiding": "إنهاء هايدرا بدلاً من التصغير الى شريط الحالة",
|
||||
"launch_with_system": "تشغيل هايدرا عند بدء تشغيل النظام",
|
||||
"general": "عام",
|
||||
"behavior": "السلوك",
|
||||
"enable_real_debrid": "تفعيل Real Debrid ",
|
||||
"real_debrid": "Real Debrid",
|
||||
"real_debrid_api_token_hint": "يمكنك الحصول على مفتاح API الخاص بك هنا.",
|
||||
"enable_real_debrid": "تفعيل Real-Debrid ",
|
||||
"real_debrid_api_token_hint": "يمكنك الحصول على مفتاح API الخاص بك هنا",
|
||||
"save_changes": "حفظ التغييرات"
|
||||
},
|
||||
"notifications": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "Рэкамэндаванае",
|
||||
"recently_added": "Нядаўна дададзенае",
|
||||
"trending": "Актуальнае",
|
||||
"surprise_me": "Здзіві мяне",
|
||||
"no_results": "Няма вынікаў"
|
||||
@@ -12,16 +11,10 @@
|
||||
"settings": "Налады",
|
||||
"my_library": "Мая бібліятэка",
|
||||
"downloading_metadata": "{{title}} (Сцягванне мэтаданых…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Праверка файлаў…)",
|
||||
"paused": "{{title}} (Спынена)",
|
||||
"downloading": "{{title}} ({{percentage}} - Сцягванне…)",
|
||||
"filter": "Фільтар бібліятэкі",
|
||||
"follow_us": "Падпісвайцеся на нас",
|
||||
"home": "Галоўная",
|
||||
"discord": "Далучайцеся да Discord",
|
||||
"telegram": "Далучайцеся да Telegram",
|
||||
"x": "Падпісвайцеся на X",
|
||||
"github": "Зрабіць свой унёсак на GitHub"
|
||||
"home": "Галоўная"
|
||||
},
|
||||
"header": {
|
||||
"search": "Пошук",
|
||||
@@ -34,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Няма актыўных сцягванняў",
|
||||
"downloading_metadata": "Сцягванне мэтаданых {{title}}…",
|
||||
"checking_files": "Праверка файлаў {{title}}… ({{percentage}} скончана)",
|
||||
"downloading": "Сцягванне {{title}}… ({{percentage}} скончана) - Канчатак {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -52,22 +44,15 @@
|
||||
"pause": "Спыніць",
|
||||
"cancel": "Скасаваць",
|
||||
"remove": "Выдаліць",
|
||||
"remove_from_list": "Выдаліць",
|
||||
"space_left_on_disk": "{{space}} засталося на дыску",
|
||||
"eta": "Канчатак {{eta}}",
|
||||
"downloading_metadata": "Сцягванне мэтаданых…",
|
||||
"checking_files": "Праверка файлаў…",
|
||||
"filter": "Фільтар рэпакаў",
|
||||
"requirements": "Сістэмныя патрэбаванни",
|
||||
"minimum": "Мінімальныя",
|
||||
"recommended": "Рэкамендуемыя",
|
||||
"no_minimum_requirements": "{{title}} ня ўтрымлівае інфармацыі пра мінімальныя патрабаванні",
|
||||
"no_recommended_requirements": "{{title}} ня ўтрымлівае інфармацыі пра рэкамендуемыя патрабаванні",
|
||||
"paused_progress": "{{progress}} (Спынена)",
|
||||
"release_date": "Выпушчана {{date}}",
|
||||
"publisher": "Выдана {{publisher}}",
|
||||
"copy_link_to_clipboard": "Скапіяваць спасылку",
|
||||
"copied_link_to_clipboard": "Спасылка скапіявана",
|
||||
"hours": "гадзін",
|
||||
"minutes": "хвілін",
|
||||
"amount_hours": "{{amount}} гадзін",
|
||||
@@ -86,17 +71,8 @@
|
||||
"playing_now": "Зараз гуляе",
|
||||
"change": "Змяніць",
|
||||
"repacks_modal_description": "Абярыце рэпак, які хочаце сцягнуць",
|
||||
"downloads_path": "Шлях сцягвання",
|
||||
"select_folder_hint": "Каб змяніць папку па змоўчанні, адкрыйце",
|
||||
"download_now": "Сцягнуць зараз",
|
||||
"installation_instructions": "Інструкцыя ўсталёўкі",
|
||||
"installation_instructions_description": "Усталёўка гэтай гульні патрабуе дадатковых крокаў",
|
||||
"online_fix_instruction": "Гульні з OnlineFix патрабуюць пароль для вымання. Калі неабходна, выкарыстоўвайце наступны пароль:",
|
||||
"dodi_installation_instruction": "Калі вы адкрыеце ўсталёўшчык DODI, націсніце на клявіятуры клявішу 'уверх' <0 />, каб пачаць працэс усталёўкі:",
|
||||
"dont_show_it_again": "Не паказваць зноў",
|
||||
"copy_to_clipboard": "Капіяваць",
|
||||
"copied_to_clipboard": "Скапіявана",
|
||||
"got_it": "Зразумела"
|
||||
"download_now": "Сцягнуць зараз"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Актываваць Hydra",
|
||||
@@ -112,19 +88,13 @@
|
||||
"eta": "Канчатак {{eta}}",
|
||||
"paused": "Спынена",
|
||||
"verifying": "Праверка…",
|
||||
"completed_at": "Скончана а {{date}}",
|
||||
"completed": "Скончана",
|
||||
"cancelled": "Скасавана",
|
||||
"download_again": "Сцягнуць зноў",
|
||||
"cancel": "Скасаваць",
|
||||
"filter": "Фільтар сцягнутых гульняў",
|
||||
"remove": "Выдаліць",
|
||||
"downloading_metadata": "Сцягванне мэтаданых…",
|
||||
"checking_files": "Праверка файлаў…",
|
||||
"starting_download": "Пачатак сцягвання…",
|
||||
"deleting": "Выдаленне ўсталёўшчыка…",
|
||||
"delete": "Выдаліць усталёўшчык",
|
||||
"remove_from_list": "Выдаліць",
|
||||
"delete_modal_title": "Вы ўпэўнены?",
|
||||
"delete_modal_description": "Гэта выдаліць усе файлы ўсталёвак з вашага кампутара",
|
||||
"install": "Усталяваць"
|
||||
@@ -135,8 +105,6 @@
|
||||
"notifications": "Апавяшчэнні",
|
||||
"enable_download_notifications": "Па сканчэнні сцягванні",
|
||||
"enable_repack_list_notifications": "Пры даданні новага рэпака",
|
||||
"telemetry": "Тэлеметрыя",
|
||||
"telemetry_description": "Уключыць ананімную статыстыку выкарыстання",
|
||||
"behavior": "Паводзіны",
|
||||
"quit_app_instead_hiding": "Закрываць праграму замест таго, каб хаваць яе ў трэй",
|
||||
"launch_with_system": "Запускаць праграму пры запуску сыстэмы"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "Anbefalet",
|
||||
"recently_added": "Nyligt tilføjet",
|
||||
"trending": "Trender",
|
||||
"surprise_me": "Overrask mig",
|
||||
"no_results": "Ingen resultater fundet"
|
||||
@@ -12,16 +11,10 @@
|
||||
"settings": "Indstillinger",
|
||||
"my_library": "Mit bibliotek",
|
||||
"downloading_metadata": "{{title}} (Downloader metadata…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Tjekker filer…)",
|
||||
"paused": "{{title}} (Paused)",
|
||||
"downloading": "{{title}} ({{percentage}} - Downloading…)",
|
||||
"filter": "Filtrer bibliotek",
|
||||
"follow_us": "Følg os",
|
||||
"home": "Hjem",
|
||||
"discord": "Tilslut dig vores Discord",
|
||||
"telegram": "Tilslut dig vores Telegram",
|
||||
"x": "Følg på X",
|
||||
"github": "Bidrag på GitHub"
|
||||
"home": "Hjem"
|
||||
},
|
||||
"header": {
|
||||
"search": "Søg spil",
|
||||
@@ -34,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Ingen downloads igang",
|
||||
"downloading_metadata": "Downloader {{title}} metadata…",
|
||||
"checking_files": "Tjekker {{title}} filer… ({{percentage}} færdig)",
|
||||
"downloading": "Downloader {{title}}… ({{percentage}} færdig) - Konklusion {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -52,22 +44,15 @@
|
||||
"pause": "Pause",
|
||||
"cancel": "Annullér",
|
||||
"remove": "Fjern",
|
||||
"remove_from_list": "Fjern",
|
||||
"space_left_on_disk": "{{space}} tilbage på harddisken",
|
||||
"eta": "Konklusion {{eta}}",
|
||||
"downloading_metadata": "Downloader metadata…",
|
||||
"checking_files": "Tjekker filer…",
|
||||
"filter": "Filtrer repacks",
|
||||
"requirements": "System behov",
|
||||
"minimum": "Mindste",
|
||||
"recommended": "Anbefalet",
|
||||
"no_minimum_requirements": "{{title}} angiver ikke mindste behov informationer",
|
||||
"no_recommended_requirements": "{{title}} angiver ikke anbefalet behov informationer",
|
||||
"paused_progress": "{{progress}} (Pauset)",
|
||||
"release_date": "Offentliggjort den {{date}}",
|
||||
"publisher": "Udgivet af {{publisher}}",
|
||||
"copy_link_to_clipboard": "Kopier link",
|
||||
"copied_link_to_clipboard": "Link kopieret",
|
||||
"hours": "timer",
|
||||
"minutes": "minutter",
|
||||
"amount_hours": "{{amount}} timer",
|
||||
@@ -86,17 +71,8 @@
|
||||
"playing_now": "Spiller nu",
|
||||
"change": "Ændré",
|
||||
"repacks_modal_description": "Vælg den repack du vil downloade",
|
||||
"downloads_path": "Downloads sti",
|
||||
"select_folder_hint": "For at ændre standard mappen, gå til <0>Instillingerne</0>",
|
||||
"download_now": "Download nu",
|
||||
"installation_instructions": "Installations Instrukser",
|
||||
"installation_instructions_description": "Yderligere skridt er krævet for at installere dette spil",
|
||||
"online_fix_instruction": "OnlineFix spil kræver et kodeord for at kunne blive udpakket. Når krævet, brug det følgende kodeord:",
|
||||
"dodi_installation_instruction": "Når du åbner DODI installatør, tryk på op-knappen på dit tastatur <0 /> for at starte installations processen:",
|
||||
"dont_show_it_again": "Vis ikke igen",
|
||||
"copy_to_clipboard": "Kopier",
|
||||
"copied_to_clipboard": "Kopieret",
|
||||
"got_it": "Forstået"
|
||||
"download_now": "Download nu"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Aktivér Hydra",
|
||||
@@ -112,24 +88,16 @@
|
||||
"eta": "Konklusion {{eta}}",
|
||||
"paused": "Pauset",
|
||||
"verifying": "Verificerer…",
|
||||
"completed_at": "Færdiggjort på {{date}}",
|
||||
"completed": "Færdigt",
|
||||
"cancelled": "Annulleret",
|
||||
"download_again": "Download igen",
|
||||
"cancel": "Annullér",
|
||||
"filter": "Filtrer downloadet spil",
|
||||
"remove": "Fjern",
|
||||
"downloading_metadata": "Downloader metadata…",
|
||||
"checking_files": "Tjekker filer…",
|
||||
"starting_download": "Starter download…",
|
||||
"deleting": "Sletter installatør…",
|
||||
"delete": "Fjern installatør",
|
||||
"remove_from_list": "Fjern",
|
||||
"delete_modal_title": "Er du sikker?",
|
||||
"delete_modal_description": "Dette vil fjerne alle installations filerne fra din computer",
|
||||
"install": "Installér",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "Torrent"
|
||||
"install": "Installér"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Downloads sti",
|
||||
@@ -137,16 +105,12 @@
|
||||
"notifications": "Notifikationer",
|
||||
"enable_download_notifications": "Når et download bliver færdigt",
|
||||
"enable_repack_list_notifications": "Når en ny repack bliver tilføjet",
|
||||
"telemetry": "Telemetri",
|
||||
"telemetry_description": "Slå anonymt brugs statistik til",
|
||||
"real_debrid_api_token_description": "Real Debrid API token",
|
||||
"quit_app_instead_hiding": "Afslut Hydra instedet for at minimere til processlinjen",
|
||||
"launch_with_system": "Åben Hydra ved start af systemet",
|
||||
"general": "Generelt",
|
||||
"behavior": "Opførsel",
|
||||
"enable_real_debrid": "Slå Real Debrid til",
|
||||
"real_debrid": "Real Debrid",
|
||||
"real_debrid_api_token_hint": "Du kan få din API nøgle <0>her</0>.",
|
||||
"enable_real_debrid": "Slå Real-Debrid til",
|
||||
"real_debrid_api_token_hint": "Du kan få din API nøgle <0>her</0>",
|
||||
"save_changes": "Gem ændringer"
|
||||
},
|
||||
"notifications": {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"app": {
|
||||
"successfully_signed_in": "Successfully signed in"
|
||||
},
|
||||
"home": {
|
||||
"featured": "Featured",
|
||||
"recently_added": "Recently added",
|
||||
"trending": "Trending",
|
||||
"surprise_me": "Surprise me",
|
||||
"no_results": "No results found"
|
||||
@@ -12,16 +14,13 @@
|
||||
"settings": "Settings",
|
||||
"my_library": "My library",
|
||||
"downloading_metadata": "{{title}} (Downloading metadata…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Checking files…)",
|
||||
"paused": "{{title}} (Paused)",
|
||||
"downloading": "{{title}} ({{percentage}} - Downloading…)",
|
||||
"filter": "Filter library",
|
||||
"follow_us": "Follow us",
|
||||
"home": "Home",
|
||||
"discord": "Join our Discord",
|
||||
"telegram": "Join our Telegram",
|
||||
"x": "Follow on X",
|
||||
"github": "Contribute on GitHub"
|
||||
"queued": "{{title}} (Queued)",
|
||||
"game_has_no_executable": "Game has no executable selected",
|
||||
"sign_in": "Sign in"
|
||||
},
|
||||
"header": {
|
||||
"search": "Search games",
|
||||
@@ -29,13 +28,15 @@
|
||||
"catalogue": "Catalogue",
|
||||
"downloads": "Downloads",
|
||||
"search_results": "Search results",
|
||||
"settings": "Settings"
|
||||
"settings": "Settings",
|
||||
"version_available_install": "Version {{version}} available. Click here to restart and install.",
|
||||
"version_available_download": "Version {{version}} available. Click here to download."
|
||||
},
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "No downloads in progress",
|
||||
"downloading_metadata": "Downloading {{title}} metadata…",
|
||||
"checking_files": "Checking {{title}} files… ({{percentage}} complete)",
|
||||
"downloading": "Downloading {{title}}… ({{percentage}} complete) - Conclusion {{eta}} - {{speed}}"
|
||||
"downloading": "Downloading {{title}}… ({{percentage}} complete) - Conclusion {{eta}} - {{speed}}",
|
||||
"calculating_eta": "Downloading {{title}}… ({{percentage}} complete) - Calculating remaining time…"
|
||||
},
|
||||
"catalogue": {
|
||||
"next_page": "Next page",
|
||||
@@ -52,22 +53,17 @@
|
||||
"pause": "Pause",
|
||||
"cancel": "Cancel",
|
||||
"remove": "Remove",
|
||||
"remove_from_list": "Remove",
|
||||
"space_left_on_disk": "{{space}} left on disk",
|
||||
"eta": "Conclusion {{eta}}",
|
||||
"calculating_eta": "Calculating remaining time…",
|
||||
"downloading_metadata": "Downloading metadata…",
|
||||
"checking_files": "Checking files…",
|
||||
"filter": "Filter repacks",
|
||||
"requirements": "System requirements",
|
||||
"minimum": "Minimum",
|
||||
"recommended": "Recommended",
|
||||
"no_minimum_requirements": "{{title}} doesn't provide minimum requirements information",
|
||||
"no_recommended_requirements": "{{title}} doesn't provide recommended requirements information",
|
||||
"paused_progress": "{{progress}} (Paused)",
|
||||
"paused": "Paused",
|
||||
"release_date": "Released on {{date}}",
|
||||
"publisher": "Published by {{publisher}}",
|
||||
"copy_link_to_clipboard": "Copy link",
|
||||
"copied_link_to_clipboard": "Link copied",
|
||||
"hours": "hours",
|
||||
"minutes": "minutes",
|
||||
"amount_hours": "{{amount}} hours",
|
||||
@@ -88,21 +84,35 @@
|
||||
"repacks_modal_description": "Choose the repack you want to download",
|
||||
"select_folder_hint": "To change the default folder, go to the <0>Settings</0>",
|
||||
"download_now": "Download now",
|
||||
"installation_instructions": "Installation Instructions",
|
||||
"installation_instructions_description": "Additional steps are required to install this game",
|
||||
"online_fix_instruction": "OnlineFix games requires a password to be extracted. When required, use the following password:",
|
||||
"dodi_installation_instruction": "When you open DODI installer, press your keyboard up key <0 /> to start the installation process:",
|
||||
"dont_show_it_again": "Don't show it again",
|
||||
"copy_to_clipboard": "Copy",
|
||||
"copied_to_clipboard": "Copied",
|
||||
"got_it": "Got it",
|
||||
"no_shop_details": "Could not retrieve shop details.",
|
||||
"download_options": "Download options",
|
||||
"download_path": "Download path",
|
||||
"previous_screenshot": "Previous screenshot",
|
||||
"next_screenshot": "Next screenshot",
|
||||
"screenshot": "Screenshot {{number}}",
|
||||
"open_screenshot": "Open screenshot {{number}}"
|
||||
"open_screenshot": "Open screenshot {{number}}",
|
||||
"download_settings": "Download settings",
|
||||
"downloader": "Downloader",
|
||||
"select_executable": "Select",
|
||||
"no_executable_selected": "No executable selected",
|
||||
"open_folder": "Open folder",
|
||||
"open_download_location": "See downloaded files",
|
||||
"create_shortcut": "Create desktop shortcut",
|
||||
"remove_files": "Remove files",
|
||||
"remove_from_library_title": "Are you sure?",
|
||||
"remove_from_library_description": "This will remove {{game}} from your library",
|
||||
"options": "Options",
|
||||
"executable_section_title": "Executable",
|
||||
"executable_section_description": "Path of the file that will be executed when \"Play\" is clicked",
|
||||
"downloads_secion_title": "Downloads",
|
||||
"downloads_section_description": "Check out updates or other versions of this game",
|
||||
"danger_zone_section_title": "Danger zone",
|
||||
"danger_zone_section_description": "Remove this game from your library or the files downloaded by Hydra",
|
||||
"download_in_progress": "Download in progress",
|
||||
"download_paused": "Download paused",
|
||||
"last_downloaded_option": "Last downloaded option",
|
||||
"create_shortcut_success": "Shortcut created successfully",
|
||||
"create_shortcut_error": "Error creating shortcut"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Activate Hydra",
|
||||
@@ -118,24 +128,23 @@
|
||||
"eta": "Conclusion {{eta}}",
|
||||
"paused": "Paused",
|
||||
"verifying": "Verifying…",
|
||||
"completed_at": "Completed in {{date}}",
|
||||
"completed": "Completed",
|
||||
"cancelled": "Cancelled",
|
||||
"download_again": "Download again",
|
||||
"removed": "Not downloaded",
|
||||
"cancel": "Cancel",
|
||||
"filter": "Filter downloaded games",
|
||||
"remove": "Remove",
|
||||
"downloading_metadata": "Downloading metadata…",
|
||||
"checking_files": "Checking files…",
|
||||
"starting_download": "Starting download…",
|
||||
"deleting": "Deleting installer…",
|
||||
"delete": "Remove installer",
|
||||
"remove_from_list": "Remove",
|
||||
"delete_modal_title": "Are you sure?",
|
||||
"delete_modal_description": "This will remove all the installation files from your computer",
|
||||
"install": "Install",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "Torrent"
|
||||
"download_in_progress": "In progress",
|
||||
"queued_downloads": "Queued downloads",
|
||||
"downloads_completed": "Completed",
|
||||
"queued": "Queued",
|
||||
"no_downloads_title": "Such empty",
|
||||
"no_downloads_description": "You haven't downloaded anything with Hydra yet, but it's never too late to start."
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Downloads path",
|
||||
@@ -143,17 +152,45 @@
|
||||
"notifications": "Notifications",
|
||||
"enable_download_notifications": "When a download is complete",
|
||||
"enable_repack_list_notifications": "When a new repack is added",
|
||||
"telemetry": "Telemetry",
|
||||
"telemetry_description": "Enable anonymous usage statistics",
|
||||
"real_debrid_api_token_label": "Real Debrid API token",
|
||||
"quit_app_instead_hiding": "Quit Hydra instead of minimizing to tray",
|
||||
"real_debrid_api_token_label": "Real-Debrid API token",
|
||||
"quit_app_instead_hiding": "Don't hide Hydra when closing",
|
||||
"launch_with_system": "Launch Hydra on system start-up",
|
||||
"general": "General",
|
||||
"behavior": "Behavior",
|
||||
"enable_real_debrid": "Enable Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"real_debrid_api_token_hint": "You can get your API key <0>here</0>.",
|
||||
"save_changes": "Save changes"
|
||||
"download_sources": "Download sources",
|
||||
"language": "Language",
|
||||
"real_debrid_api_token": "API Token",
|
||||
"enable_real_debrid": "Enable Real-Debrid",
|
||||
"real_debrid_description": "Real-Debrid is an unrestricted downloader that allows you to download files instantly and at the best of your Internet speed.",
|
||||
"real_debrid_invalid_token": "Invalid API token",
|
||||
"real_debrid_api_token_hint": "You can get your API token <0>here</0>",
|
||||
"real_debrid_free_account_error": "The account \"{{username}}\" is a free account. Please subscribe to Real-Debrid",
|
||||
"real_debrid_linked_message": "Account \"{{username}}\" linked",
|
||||
"save_changes": "Save changes",
|
||||
"changes_saved": "Changes successfully saved",
|
||||
"download_sources_description": "Hydra will fetch the download links from these sources. The source URL must be a direct link to a .json file containing the download links.",
|
||||
"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_source_url": "Download source URL",
|
||||
"add_download_source_description": "Insert the URL containing the .json file",
|
||||
"download_source_up_to_date": "Up-to-date",
|
||||
"download_source_errored": "Errored",
|
||||
"sync_download_sources": "Sync sources",
|
||||
"removed_download_source": "Download source removed",
|
||||
"added_download_source": "Added download source",
|
||||
"download_sources_synced": "All download sources are synced",
|
||||
"insert_valid_json_url": "Insert a valid JSON url",
|
||||
"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"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download complete",
|
||||
@@ -176,5 +213,30 @@
|
||||
},
|
||||
"modal": {
|
||||
"close": "Close button"
|
||||
},
|
||||
"forms": {
|
||||
"toggle_password_visibility": "Toggle password visibility"
|
||||
},
|
||||
"user_profile": {
|
||||
"amount_hours": "{{amount}} hours",
|
||||
"amount_minutes": "{{amount}} minutes",
|
||||
"last_time_played": "Last played {{period}}",
|
||||
"activity": "Recent activity",
|
||||
"library": "Library",
|
||||
"total_play_time": "Total playtime: {{amount}}",
|
||||
"no_recent_activity_title": "Hmmm… nothing here",
|
||||
"no_recent_activity_description": "You haven't played any games recently. It's time to change that!",
|
||||
"display_name": "Display name",
|
||||
"saving": "Saving",
|
||||
"save": "Save",
|
||||
"edit_profile": "Edit Profile",
|
||||
"saved_successfully": "Saved successfully",
|
||||
"try_again": "Please, try again",
|
||||
"sign_out_modal_title": "Are you sure?",
|
||||
"cancel": "Cancel",
|
||||
"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?"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"app": {
|
||||
"successfully_signed_in": "Successfully signed in (TRANSLATE ME)"
|
||||
},
|
||||
"home": {
|
||||
"featured": "Destacado",
|
||||
"recently_added": "Recién Añadidos",
|
||||
"trending": "Tendencias",
|
||||
"surprise_me": "¡Sorpréndeme!",
|
||||
"no_results": "No se encontraron resultados"
|
||||
@@ -12,16 +14,13 @@
|
||||
"settings": "Ajustes",
|
||||
"my_library": "Mi biblioteca",
|
||||
"downloading_metadata": "{{title}} (Descargando metadatos…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Analizando archivos…)",
|
||||
"paused": "{{title}} (Pausado)",
|
||||
"downloading": "{{title}} ({{percentage}} - Descargando…)",
|
||||
"filter": "Buscar en la biblioteca",
|
||||
"follow_us": "Síguenos",
|
||||
"home": "Inicio",
|
||||
"discord": "Únete a nuestro Discord",
|
||||
"telegram": "Únete a nuestro Telegram",
|
||||
"x": "Síguenos en X",
|
||||
"github": "Contribuye en GitHub"
|
||||
"queued": "{{title}} (En Cola)",
|
||||
"game_has_no_executable": "El juego no tiene un ejecutable",
|
||||
"sign_in": "Sign in (TRANSLATE ME)"
|
||||
},
|
||||
"header": {
|
||||
"search": "Buscar juegos",
|
||||
@@ -29,13 +28,15 @@
|
||||
"catalogue": "Catálogo",
|
||||
"downloads": "Descargas",
|
||||
"search_results": "Resultados de búsqueda",
|
||||
"settings": "Ajustes"
|
||||
"settings": "Ajustes",
|
||||
"version_available_install": "Version {{version}} disponible. Haz clic aquí para reiniciar e instalar.",
|
||||
"version_available_download": "Version {{version}} disponible. Haz clic aquí para descargar."
|
||||
},
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Sin descargas en progreso",
|
||||
"downloading_metadata": "Descargando metadatos de {{title}}…",
|
||||
"checking_files": "Analizando archivos de {{title}} - ({{percentage}} completado)",
|
||||
"downloading": "Descargando {{title}}… ({{percentage}} completado) - Finalizando {{eta}} - {{speed}}"
|
||||
"downloading": "Descargando {{title}}… ({{percentage}} completado) - Finalizando {{eta}} - {{speed}}",
|
||||
"calculating_eta": "Descargando {{title}}… ({{percentage}} completado) - Calculando tiempo restante…"
|
||||
},
|
||||
"catalogue": {
|
||||
"next_page": "Siguiente página",
|
||||
@@ -52,22 +53,17 @@
|
||||
"pause": "Pausa",
|
||||
"cancel": "Cancelar",
|
||||
"remove": "Eliminar",
|
||||
"remove_from_list": "Quitar",
|
||||
"space_left_on_disk": "{{space}} restantes en el disco",
|
||||
"eta": "Finalizando en {{eta}}",
|
||||
"eta": "Tiempo restante: {{eta}}",
|
||||
"calculating_eta": "Calculando tiempo restante…",
|
||||
"downloading_metadata": "Descargando metadatos…",
|
||||
"checking_files": "Analizando archivos…",
|
||||
"filter": "Buscar repacks",
|
||||
"requirements": "Requisitos del Sistema",
|
||||
"minimum": "Mínimos",
|
||||
"recommended": "Recomendados",
|
||||
"no_minimum_requirements": "Sin requisitos mínimos para {{title}}",
|
||||
"no_recommended_requirements": "{{title}} no tiene requisitos recomendados",
|
||||
"paused_progress": "{{progress}} (Pausado)",
|
||||
"paused": "Pausado",
|
||||
"release_date": "Fecha de lanzamiento: {{date}}",
|
||||
"publisher": "Publicado por: {{publisher}}",
|
||||
"copy_link_to_clipboard": "Copiar enlace",
|
||||
"copied_link_to_clipboard": "Enlace copiado",
|
||||
"hours": "horas",
|
||||
"minutes": "minutos",
|
||||
"amount_hours": "{{amount}} horas",
|
||||
@@ -88,21 +84,33 @@
|
||||
"repacks_modal_description": "Selecciona el repack que quieres descargar",
|
||||
"select_folder_hint": "Para cambiar la carpeta predeterminada, ve a <0>Ajustes</0>",
|
||||
"download_now": "Descargar ahora",
|
||||
"installation_instructions": "Instrucciones de instalación",
|
||||
"installation_instructions_description": "Se requieren de pasos adicionales para instalar este juego",
|
||||
"online_fix_instruction": "Los juegos de OnlineFix requieren una contraseña para ser extraídos. Cuando se requiera, usa la siguiente contraseña:",
|
||||
"dodi_installation_instruction": "Cuando abras el instalador de DODI, presiona la tecla hacia arriba del teclado <0 /> para iniciar el proceso de instalación:",
|
||||
"dont_show_it_again": "No mostrar de nuevo",
|
||||
"copy_to_clipboard": "Copiar",
|
||||
"copied_to_clipboard": "Copiado",
|
||||
"got_it": "Entendido",
|
||||
"no_shop_details": "No se pudieron obtener detalles de la tienda.",
|
||||
"download_options": "Opciones de descarga",
|
||||
"download_path": "Ruta de descarga",
|
||||
"previous_screenshot": "Anterior captura",
|
||||
"next_screenshot": "Siguiente captura",
|
||||
"screenshot": "Captura {{number}}",
|
||||
"open_screenshot": "Abrir captura {{number}}"
|
||||
"open_screenshot": "Abrir captura {{number}}",
|
||||
"download_settings": "Ajustes de descarga",
|
||||
"downloader": "Descargador",
|
||||
"select_executable": "Seleccionar",
|
||||
"no_executable_selected": "No se seleccionó un ejecutable",
|
||||
"open_folder": "Abrir carpeta",
|
||||
"open_download_location": "Ver archivos descargados",
|
||||
"create_shortcut": "Crear acceso directo en el escritorio",
|
||||
"remove_files": "Eliminar archivos",
|
||||
"remove_from_library_title": "¿Estás seguro?",
|
||||
"remove_from_library_description": "Esto eliminará {{game}} de tu biblioteca",
|
||||
"options": "Opciones",
|
||||
"executable_section_title": "Ejecutable",
|
||||
"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",
|
||||
"download_in_progress": "Descarga en progreso",
|
||||
"download_paused": "Descarga pausada",
|
||||
"last_downloaded_option": "Última opción descargada"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Activar Hydra",
|
||||
@@ -118,24 +126,23 @@
|
||||
"eta": "Finalizando en {{eta}}",
|
||||
"paused": "En Pausa",
|
||||
"verifying": "Verificando…",
|
||||
"completed_at": "Completado el {{date}}",
|
||||
"completed": "Completado",
|
||||
"cancelled": "Cancelado",
|
||||
"download_again": "Descargar de nuevo",
|
||||
"removed": "No descargado",
|
||||
"cancel": "Cancelar",
|
||||
"filter": "Buscar juegos descargados",
|
||||
"remove": "Eliminar",
|
||||
"downloading_metadata": "Descargando metadatos…",
|
||||
"checking_files": "Verificando archivos…",
|
||||
"starting_download": "Iniciando descarga…",
|
||||
"deleting": "Eliminando instalador…",
|
||||
"delete": "Eliminar instalador",
|
||||
"remove_from_list": "Eliminar",
|
||||
"delete_modal_title": "¿Estás seguro?",
|
||||
"delete_modal_description": "Esto eliminará todos los archivos de instalación de tu computadora.",
|
||||
"install": "Instalar",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "Torrent"
|
||||
"download_in_progress": "En progreso",
|
||||
"queued_downloads": "Descargas en cola",
|
||||
"downloads_completed": "Completado",
|
||||
"queued": "En cola",
|
||||
"no_downloads_title": "Esto está tan... vacío",
|
||||
"no_downloads_description": "No has descargado nada con Hydra... aún, ¡pero nunca es tarde para comenzar!."
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Ruta de descarga",
|
||||
@@ -143,17 +150,45 @@
|
||||
"notifications": "Notificaciones",
|
||||
"enable_download_notifications": "Cuando se completa una descarga",
|
||||
"enable_repack_list_notifications": "Cuando se añade un repack nuevo",
|
||||
"telemetry": "Telemetría",
|
||||
"telemetry_description": "Habilitar recopilación de datos de manera anónima",
|
||||
"real_debrid_api_token_label": "Token API de Real Debrid",
|
||||
"real_debrid_api_token_label": "Token API de Real-Debrid",
|
||||
"quit_app_instead_hiding": "Salir de Hydra en vez de minimizar en la bandeja del sistema",
|
||||
"launch_with_system": "Iniciar Hydra al inicio del sistema",
|
||||
"general": "General",
|
||||
"behavior": "Otros",
|
||||
"enable_real_debrid": "Activar Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"real_debrid_api_token_hint": "Puedes obtener tu clave de API <0>aquí</0>.",
|
||||
"save_changes": "Guardar cambios"
|
||||
"download_sources": "Fuentes de descarga",
|
||||
"language": "Idioma",
|
||||
"real_debrid_api_token": "Token API",
|
||||
"enable_real_debrid": "Activar Real-Debrid",
|
||||
"real_debrid_description": "Real-Debrid es un descargador sin restricciones que te permite descargar archivos instantáneamente con la máxima velocidad de tu internet.",
|
||||
"real_debrid_invalid_token": "Token de API inválido",
|
||||
"real_debrid_api_token_hint": "Puedes obtener tu clave de API <0>aquí</0>",
|
||||
"real_debrid_free_account_error": "La cuenta \"{{username}}\" es una cuenta gratuita. Por favor, suscríbete a Real-Debrid",
|
||||
"real_debrid_linked_message": "Cuenta \"{{username}}\" vinculada",
|
||||
"save_changes": "Guardar cambios",
|
||||
"changes_saved": "Ajustes guardados exitosamente",
|
||||
"download_sources_description": "Hydra buscará los enlaces de descarga de estas fuentes. La URL de origen debe ser un enlace directo a un archivo .json que contenga los enlaces de descarga",
|
||||
"validate_download_source": "Validar",
|
||||
"remove_download_source": "Eliminar",
|
||||
"add_download_source": "Añadir fuente de descarga",
|
||||
"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",
|
||||
"download_source_errored": "Error",
|
||||
"sync_download_sources": "Sincronizar fuentes",
|
||||
"removed_download_source": "Fuente de descarga eliminada",
|
||||
"added_download_source": "Fuente de descarga añadida",
|
||||
"download_sources_synced": "Todas las fuentes de descarga estánn actualizadas (TRANSLATE ME)",
|
||||
"insert_valid_json_url": "Insert a valid JSON url (TRANSLATE ME)",
|
||||
"found_download_option_zero": "No download option found (TRANSLATE ME)",
|
||||
"found_download_option_one": "Found {{countFormatted}} download option (TRANSLATE ME)",
|
||||
"found_download_option_other": "Found {{countFormatted}} download options (TRANSLATE ME)",
|
||||
"import": "Import (TRANSLATE ME)"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Descarga completada",
|
||||
@@ -176,5 +211,30 @@
|
||||
},
|
||||
"modal": {
|
||||
"close": "Botón de cierre"
|
||||
},
|
||||
"forms": {
|
||||
"toggle_password_visibility": "Cambiar visibilidad de contraseña"
|
||||
},
|
||||
"user_profile": {
|
||||
"amount_hours": "{{amount}} hours (TRANSLATE ME)",
|
||||
"amount_minutes": "{{amount}} minutes (TRANSLATE ME)",
|
||||
"last_time_played": "Last played {{period}} (TRANSLATE ME)",
|
||||
"activity": "Recent activity (TRANSLATE ME)",
|
||||
"library": "Library (TRANSLATE ME)",
|
||||
"total_play_time": "Total playtime: {{amount}} (TRANSLATE ME)",
|
||||
"no_recent_activity_title": "Hmmm… nothing here (TRANSLATE ME)",
|
||||
"no_recent_activity_description": "You haven't played any games recently. It's time to change that! (TRANSLATE ME)",
|
||||
"display_name": "Display name (TRANSLATE ME)",
|
||||
"saving": "Saving (TRANSLATE ME)",
|
||||
"save": "Save (TRANSLATE ME)",
|
||||
"edit_profile": "Edit Profile (TRANSLATE ME)",
|
||||
"saved_successfully": "Saved successfully (TRANSLATE ME)",
|
||||
"try_again": "Please, try again (TRANSLATE ME)",
|
||||
"sign_out_modal_title": "Are you sure? (TRANSLATE ME)",
|
||||
"cancel": "Cancel (TRANSLATE ME)",
|
||||
"successfully_signed_out": "Successfully signed out (TRANSLATE ME)",
|
||||
"sign_out": "Sign out (TRANSLATE ME)",
|
||||
"playing_for": "Playing for {{amount}} (TRANSLATE ME)",
|
||||
"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? (TRANSLATE ME)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "پیشنهادی",
|
||||
"recently_added": "تازه اضافه شده",
|
||||
"trending": "پرطرفدار",
|
||||
"surprise_me": "سوپرایزم کن",
|
||||
"no_results": "اتمامای پیدا نشد"
|
||||
@@ -12,16 +11,10 @@
|
||||
"settings": "تنظیمات",
|
||||
"my_library": "کتابخانهی من",
|
||||
"downloading_metadata": "{{title}} (در حال دانلود متادیتا...)",
|
||||
"checking_files": "{{title}} ({{percentage}} - در حال بررسی فایلها...)",
|
||||
"paused": "{{title}} (متوقف شده)",
|
||||
"downloading": "{{title}} ({{percentage}} - در حال دانلود…)",
|
||||
"filter": "فیلتر کردن کتابخانه",
|
||||
"follow_us": "دنبال کردن ما",
|
||||
"home": "خانه",
|
||||
"discord": "عضویت در دیسکورد ما",
|
||||
"telegram": "عضویت در تلگرام ما",
|
||||
"x": "دنبال کرد در ایکس",
|
||||
"github": "مشارکت در گیتهاب"
|
||||
"home": "خانه"
|
||||
},
|
||||
"header": {
|
||||
"search": "جستجوی بازیها",
|
||||
@@ -34,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "دانلودی در حال انجام نیست",
|
||||
"downloading_metadata": "درحال دانلود متادیتاهای {{title}}…",
|
||||
"checking_files": "در حال چک کردن فایلهای {{title}}…. ({{percentage}} تکمیل شده)",
|
||||
"downloading": "در حال دانلود {{title}}… ({{percentage}} تکمیل شده) - اتمام {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -52,22 +44,15 @@
|
||||
"pause": "توقف",
|
||||
"cancel": "بیخیال",
|
||||
"remove": "حذف",
|
||||
"remove_from_list": "حذف",
|
||||
"space_left_on_disk": "{{space}} فضا در دیسک باقیمانده",
|
||||
"eta": "اتمام {{eta}}",
|
||||
"downloading_metadata": "در حال دانلود متادیتاها…",
|
||||
"checking_files": "در حال چک کردن فایلها",
|
||||
"filter": "فیلترکردن ریپکها",
|
||||
"requirements": "سیستم مورد نیاز",
|
||||
"minimum": "حداقل",
|
||||
"recommended": "پیشنهادی",
|
||||
"no_minimum_requirements": "{{title}} اطلاعات حداقل سیستم مورد نیاز را فراهم نکرده",
|
||||
"no_recommended_requirements": "{{title}} اطلاعات پیشنهادی سیستم مورد نیاز را فراهم نکرده",
|
||||
"paused_progress": "{{progress}} (متوقف شده)",
|
||||
"release_date": "منتشر شده در {{date}}",
|
||||
"publisher": "منتشر شده توسط {{publisher}}",
|
||||
"copy_link_to_clipboard": "کپی لینک",
|
||||
"copied_link_to_clipboard": "لینک کپی شد",
|
||||
"hours": "ساعت",
|
||||
"minutes": "دقیقه",
|
||||
"amount_hours": "{{amount}} ساعت",
|
||||
@@ -86,17 +71,8 @@
|
||||
"playing_now": "در حال بازی",
|
||||
"change": "تغییر",
|
||||
"repacks_modal_description": "ریپک مورد نظر برای دانلود را انتخاب کنید",
|
||||
"downloads_path": "آدرس دانلودها",
|
||||
"select_folder_hint": "برای تغییر پوشهی پیشفرض به <0>Settings</0> بروید",
|
||||
"download_now": "الان دانلود کن",
|
||||
"installation_instructions": "دستورات نصب",
|
||||
"installation_instructions_description": "قدمهای دیگری برای نصب این بازی نیاز است",
|
||||
"online_fix_instruction": "بازیهای OnlineFix برای اکسترکت شدن به پسوورد نیاز دارند. در صورت نیاز، از این پسوورد استفاده کنید:",
|
||||
"dodi_installation_instruction": "زمانی که اینستالر DODI را باز کردید، دکمهی <0 /> را فشار دهید تا فرایند نصب شروع شود:",
|
||||
"dont_show_it_again": "دیگر نمایش نده",
|
||||
"copy_to_clipboard": "کپی",
|
||||
"copied_to_clipboard": "کپی شد",
|
||||
"got_it": "فهمیدم"
|
||||
"download_now": "الان دانلود کن"
|
||||
},
|
||||
"activation": {
|
||||
"title": "فعال کردن هایدرا",
|
||||
@@ -112,24 +88,16 @@
|
||||
"eta": "اتمام {{eta}}",
|
||||
"paused": "متوقف شده",
|
||||
"verifying": "در حال اعتبارسنجی…",
|
||||
"completed_at": "پایان یافته در {{date}}",
|
||||
"completed": "پایان یافته",
|
||||
"cancelled": "لغو شده",
|
||||
"download_again": "دانلود مجدد",
|
||||
"cancel": "لغو",
|
||||
"filter": "فیلتر بازیهای دانلود شده",
|
||||
"remove": "حذف",
|
||||
"downloading_metadata": "در حال دانلود متادیتاها…",
|
||||
"checking_files": "در حال چک کردن فایلها…",
|
||||
"starting_download": "در حال آغار دانلود…",
|
||||
"deleting": "در حال پاک کردن اینستالر…",
|
||||
"delete": "پاک کردن",
|
||||
"remove_from_list": "حذف",
|
||||
"delete_modal_title": "مطمئنی؟",
|
||||
"delete_modal_description": "این کار تمام فایلهای اینستالر را از کامپیوتر شما حذف میکند",
|
||||
"install": "نصف",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "تورنت"
|
||||
"install": "نصف"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "مسیر دانلودها",
|
||||
@@ -137,15 +105,11 @@
|
||||
"notifications": "نوتیفیکشنها",
|
||||
"enable_download_notifications": "زمانی که یک دانلود تمام شد",
|
||||
"enable_repack_list_notifications": "زمانی که یک ریپک جدید اضافه شد",
|
||||
"telemetry": "تلمتری",
|
||||
"telemetry_description": "فعال کردن آمارگیری استفاده ناشناس",
|
||||
"real_debrid_api_token_description": "توکن Real Debrid",
|
||||
"quit_app_instead_hiding": "به جای کوچک کردن، از هایدرا خارج شو",
|
||||
"launch_with_system": "زمانی که سیستم روشن میشود، هایدرا را باز کن",
|
||||
"general": "کلی",
|
||||
"behavior": "رفتار",
|
||||
"enable_real_debrid": "فعالسازی Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"enable_real_debrid": "فعالسازی Real-Debrid",
|
||||
"real_debrid_api_token_hint": "کلید API خود را از <ب0>اینجا</0> بگیرید.",
|
||||
"save_changes": "ذخیره تغییرات"
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "En vedette",
|
||||
"recently_added": "Récemment ajouté",
|
||||
"trending": "Tendance",
|
||||
"surprise_me": "Surprenez-moi",
|
||||
"no_results": "Aucun résultat trouvé"
|
||||
@@ -12,12 +11,10 @@
|
||||
"settings": "Paramètres",
|
||||
"my_library": "Ma bibliothèque",
|
||||
"downloading_metadata": "{{title}} (Téléchargement des métadonnées…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Vérification des fichiers…)",
|
||||
"paused": "{{title}} (En pause)",
|
||||
"downloading": "{{title}} ({{percentage}} - Téléchargement en cours…)",
|
||||
"filter": "Filtrer la bibliothèque",
|
||||
"home": "Page d’accueil",
|
||||
"follow_us": "Suivez-nous"
|
||||
"home": "Page d’accueil"
|
||||
},
|
||||
"header": {
|
||||
"search": "Recherche",
|
||||
@@ -30,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Aucun téléchargement en cours",
|
||||
"downloading_metadata": "Téléchargement des métadonnées de {{title}}…",
|
||||
"checking_files": "Vérification des fichiers de {{title}}… ({{percentage}} terminé)",
|
||||
"downloading": "Téléchargement de {{title}}… ({{percentage}} terminé) - Fin dans {{eta}} - {{speed}}"
|
||||
},
|
||||
"game_details": {
|
||||
@@ -43,22 +39,15 @@
|
||||
"pause": "Pause",
|
||||
"cancel": "Annuler",
|
||||
"remove": "Supprimer",
|
||||
"remove_from_list": "Retirer",
|
||||
"space_left_on_disk": "{{space}} restant sur le disque",
|
||||
"eta": "Fin dans {{eta}}",
|
||||
"downloading_metadata": "Téléchargement des métadonnées en cours…",
|
||||
"checking_files": "Vérification des fichiers…",
|
||||
"filter": "Filtrer les repacks",
|
||||
"requirements": "Configuration requise",
|
||||
"minimum": "Minimum",
|
||||
"recommended": "Recommandée",
|
||||
"no_minimum_requirements": "{{title}} ne fournit pas d'informations sur les configurations minimales",
|
||||
"no_recommended_requirements": "{{title}} ne fournit pas d'informations sur les configurations recommandées",
|
||||
"paused_progress": "{{progress}} (En pause)",
|
||||
"release_date": "Sorti le {{date}}",
|
||||
"publisher": "Édité par {{publisher}}",
|
||||
"copy_link_to_clipboard": "Copier le lien",
|
||||
"copied_link_to_clipboard": "Lien copié",
|
||||
"hours": "heures",
|
||||
"minutes": "minutes",
|
||||
"amount_hours": "{{amount}} heures",
|
||||
@@ -91,17 +80,11 @@
|
||||
"eta": "Fin dans {{eta}}",
|
||||
"paused": "En pause",
|
||||
"verifying": "Vérification en cours…",
|
||||
"completed_at": "Terminé en {{date}}",
|
||||
"completed": "Terminé",
|
||||
"cancelled": "Annulé",
|
||||
"download_again": "Télécharger à nouveau",
|
||||
"cancel": "Annuler",
|
||||
"filter": "Filtrer les jeux téléchargés",
|
||||
"remove": "Supprimer",
|
||||
"downloading_metadata": "Téléchargement des métadonnées en cours…",
|
||||
"checking_files": "Vérification des fichiers…",
|
||||
"starting_download": "Démarrage du téléchargement…",
|
||||
"remove_from_list": "Retirer",
|
||||
"delete": "Supprimer le programme d'installation",
|
||||
"delete_modal_description": "Cela supprimera tous les fichiers d'installation de votre ordinateur",
|
||||
"delete_modal_title": "Es-tu sûr?",
|
||||
@@ -114,8 +97,7 @@
|
||||
"notifications": "Notifications",
|
||||
"enable_download_notifications": "Quand un téléchargement est terminé",
|
||||
"enable_repack_list_notifications": "Quand un nouveau repack est ajouté",
|
||||
"telemetry": "Télémétrie",
|
||||
"telemetry_description": "Activer les statistiques d'utilisation anonymes"
|
||||
"language": "Langue"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Téléchargement terminé",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "Featured",
|
||||
"recently_added": "Nemrég hozzáadott",
|
||||
"trending": "Népszerű",
|
||||
"surprise_me": "Lepj meg",
|
||||
"no_results": "Nem található"
|
||||
@@ -12,11 +11,9 @@
|
||||
"settings": "Beállítások",
|
||||
"my_library": "Könyvtáram",
|
||||
"downloading_metadata": "{{title}} (Metadata letöltése…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Fájlok ellenőrzése…)",
|
||||
"paused": "{{title}} (Szünet)",
|
||||
"downloading": "{{title}} ({{percentage}} - Letöltés…)",
|
||||
"filter": "Könyvtár szűrése",
|
||||
"follow_us": "Kövess minket",
|
||||
"home": "Főoldal"
|
||||
},
|
||||
"header": {
|
||||
@@ -30,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Nincsenek folyamatban lévő letöltések",
|
||||
"downloading_metadata": "{{title}} metaadatainak letöltése…",
|
||||
"checking_files": "{{title}} fájlok ellenőrzése… ({{percentage}} kész)",
|
||||
"downloading": "{{title}} letöltése… ({{percentage}} kész) - Befejezés {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -48,22 +44,15 @@
|
||||
"pause": "Szüneteltetés",
|
||||
"cancel": "Mégse",
|
||||
"remove": "Eltávolítás",
|
||||
"remove_from_list": "Eltávolítás",
|
||||
"space_left_on_disk": "{{space}} szabad hely a lemezen",
|
||||
"eta": "Befejezés {{eta}}",
|
||||
"downloading_metadata": "Metaadatok letöltése…",
|
||||
"checking_files": "Fájlok ellenőrzése…",
|
||||
"filter": "Repackek szűrése",
|
||||
"requirements": "Rendszerkövetelmények",
|
||||
"minimum": "Minimális",
|
||||
"recommended": "Ajánlott",
|
||||
"no_minimum_requirements": "{{title}} nem tartalmaz információt a minimális követelményekről",
|
||||
"no_recommended_requirements": "{{title}} nem tartalmaz információt az ajánlott követelményekről",
|
||||
"paused_progress": "{{progress}} (Szünetel)",
|
||||
"release_date": "Megjelenés: {{date}}",
|
||||
"publisher": "Kiadta: {{publisher}}",
|
||||
"copy_link_to_clipboard": "Link másolása",
|
||||
"copied_link_to_clipboard": "Link másolva",
|
||||
"hours": "óra",
|
||||
"minutes": "perc",
|
||||
"amount_hours": "{{amount}} óra",
|
||||
@@ -82,7 +71,6 @@
|
||||
"playing_now": "Jelenleg játszva",
|
||||
"change": "Változtatás",
|
||||
"repacks_modal_description": "Choose the repack you want to download",
|
||||
"downloads_path": "Letöltések helye",
|
||||
"select_folder_hint": "Ahhoz, hogy megváltoztasd a helyet, hozzákell férned a",
|
||||
"download_now": "Töltsd le most"
|
||||
},
|
||||
@@ -100,19 +88,13 @@
|
||||
"eta": "Befejezés {{eta}}",
|
||||
"paused": "Szüneteltetve",
|
||||
"verifying": "Ellenőrzés…",
|
||||
"completed_at": "Befejezve {{date}}-kor",
|
||||
"completed": "Befejezve",
|
||||
"cancelled": "Megszakítva",
|
||||
"download_again": "Újra letöltés",
|
||||
"cancel": "Mégse",
|
||||
"filter": "Letöltött játékok szűrése",
|
||||
"remove": "Eltávolítás",
|
||||
"downloading_metadata": "Metaadatok letöltése…",
|
||||
"checking_files": "Fájlok ellenőrzése…",
|
||||
"starting_download": "Letöltés indítása…",
|
||||
"deleting": "Telepítő törlése…",
|
||||
"delete": "Telepítő eltávolítása",
|
||||
"remove_from_list": "Eltávolítás",
|
||||
"delete_modal_title": "Biztos vagy benne?",
|
||||
"delete_modal_description": "Ez eltávolít minden telepítési fájlt a számítógépedről",
|
||||
"install": "Telepítés"
|
||||
@@ -122,9 +104,7 @@
|
||||
"change": "Frissítés",
|
||||
"notifications": "Értesítések",
|
||||
"enable_download_notifications": "Amikor egy letöltés befejeződik",
|
||||
"enable_repack_list_notifications": "Amikor egy új repack hozzáadásra kerül",
|
||||
"telemetry": "Telemetria",
|
||||
"telemetry_description": "Névtelen felhasználási statisztikák engedélyezése"
|
||||
"enable_repack_list_notifications": "Amikor egy új repack hozzáadásra kerül"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Letöltés befejeződött",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "Unggulan",
|
||||
"recently_added": "Terbaru",
|
||||
"trending": "Trending",
|
||||
"surprise_me": "Kejutkan Saya",
|
||||
"no_results": "Tidak ada hasil"
|
||||
@@ -12,16 +11,10 @@
|
||||
"settings": "Pengaturan",
|
||||
"my_library": "Koleksi saya",
|
||||
"downloading_metadata": "{{title}} (Mengunduh metadata…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Memeriksa file…)",
|
||||
"paused": "{{title}} (Terhenti)",
|
||||
"downloading": "{{title}} ({{percentage}} - Mengunduh…)",
|
||||
"filter": "Filter koleksi",
|
||||
"follow_us": "Ikuti kami",
|
||||
"home": "Beranda",
|
||||
"discord": "Gabung Discord kami",
|
||||
"telegram": "Gabung Telegram kami",
|
||||
"x": "Ikuti akun X kami",
|
||||
"github": "Kontribusi di GitHub"
|
||||
"home": "Beranda"
|
||||
},
|
||||
"header": {
|
||||
"search": "Pencarian",
|
||||
@@ -34,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Tidak ada unduhan berjalan",
|
||||
"downloading_metadata": "Mengunduh metadata {{title}}...",
|
||||
"checking_files": "Memeriksa file {{title}}… ({{percentage}} selesai)",
|
||||
"downloading": "Mengunduh {{title}}… ({{percentage}} selesai) - Perkiraan {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -52,22 +44,15 @@
|
||||
"pause": "Hentikan sementara",
|
||||
"cancel": "Batalkan",
|
||||
"remove": "Hapus",
|
||||
"remove_from_list": "Hapus",
|
||||
"space_left_on_disk": "{{space}} tersisa pada disk",
|
||||
"eta": "Perkiraan {{eta}}",
|
||||
"downloading_metadata": "Mengunduh metadata…",
|
||||
"checking_files": "Memeriksa file…",
|
||||
"filter": "Saring repacks",
|
||||
"requirements": "Keperluan sistem",
|
||||
"minimum": "Minimum",
|
||||
"recommended": "Rekomendasi",
|
||||
"no_minimum_requirements": "{{title}} Tidak ada informasi kebutuhan sistem",
|
||||
"no_recommended_requirements": "{{title}} Tidak ada informasi rekomendasi kebutuhan sistem",
|
||||
"paused_progress": "{{progress}} (Terhenti)",
|
||||
"release_date": "Dirilis pada {{date}}",
|
||||
"publisher": "Dipublikasikan oleh {{publisher}}",
|
||||
"copy_link_to_clipboard": "Salin tautan",
|
||||
"copied_link_to_clipboard": "Tautan tersalin",
|
||||
"hours": "jam",
|
||||
"minutes": "menit",
|
||||
"amount_hours": "{{amount}} jam",
|
||||
@@ -86,17 +71,8 @@
|
||||
"playing_now": "Memainkan sekarang",
|
||||
"change": "Ubah",
|
||||
"repacks_modal_description": "Pilih repack yang kamu ingin unduh",
|
||||
"downloads_path": "Lokasi Unduhan",
|
||||
"select_folder_hint": "Untuk merubah folder bawaan, akses melalui",
|
||||
"download_now": "Unduh sekarang",
|
||||
"installation_instructions": "Instruksi Instalasi",
|
||||
"installation_instructions_description": "Langkah tambahan dibutuhkan untuk meng-instal game ini",
|
||||
"online_fix_instruction": "OnlineFix games mebutuhkan kata sandi untuk ekstraksi. Saat diperlukan, gunakan kata sandi ini:",
|
||||
"dodi_installation_instruction": "Saat menjalankan DODI installer, tekan tombol atas pada keyboard <0 /> untuk melanjutkan proses instalasi:",
|
||||
"dont_show_it_again": "Jangan tunjukkan lagi",
|
||||
"copy_to_clipboard": "Salin",
|
||||
"copied_to_clipboard": "Tersalin",
|
||||
"got_it": "Paham"
|
||||
"download_now": "Unduh sekarang"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Aktivasi Hydra",
|
||||
@@ -112,19 +88,13 @@
|
||||
"eta": "Perkiraan {{eta}}",
|
||||
"paused": "Terhenti sementara",
|
||||
"verifying": "Memeriksa…",
|
||||
"completed_at": "Selesai pada {{date}}",
|
||||
"completed": "Selesai",
|
||||
"cancelled": "Dibatalkan",
|
||||
"download_again": "Unduh lagi",
|
||||
"cancel": "Batalkan",
|
||||
"filter": "Saring game yang diunduh",
|
||||
"remove": "Hapus",
|
||||
"downloading_metadata": "Mengunduh metadata…",
|
||||
"checking_files": "Memeriksa file…",
|
||||
"starting_download": "Memulai unduhan…",
|
||||
"deleting": "Menghapus file instalasi…",
|
||||
"delete": "Hapus file instalasi",
|
||||
"remove_from_list": "Hapus",
|
||||
"delete_modal_title": "Kamu yakin?",
|
||||
"delete_modal_description": "Proses ini akan menghapus semua file instalasi dari komputer kamu",
|
||||
"install": "Install"
|
||||
@@ -135,8 +105,6 @@
|
||||
"notifications": "Pengingat",
|
||||
"enable_download_notifications": "Saat unduhan selesai",
|
||||
"enable_repack_list_notifications": "Saat repack terbaru ditambahkan",
|
||||
"telemetry": "Telemetri",
|
||||
"telemetry_description": "Izinkan statistik penggunaan data anonim",
|
||||
"behavior": "Perilaku",
|
||||
"quit_app_instead_hiding": "Tutup aplikasi alih-alih menyembunyikan aplikasi",
|
||||
"launch_with_system": "Jalankan saat memulai sistem"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "In primo piano",
|
||||
"recently_added": "Aggiunti di recente",
|
||||
"trending": "Di tendenza",
|
||||
"surprise_me": "Sorprendimi",
|
||||
"no_results": "Nessun risultato trovato"
|
||||
@@ -12,16 +11,10 @@
|
||||
"settings": "Impostazioni",
|
||||
"my_library": "La mia libreria",
|
||||
"downloading_metadata": "{{title}} (Scaricamento metadati…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Verifica file…)",
|
||||
"paused": "{{title}} (In pausa)",
|
||||
"downloading": "{{title}} ({{percentage}} - Download…)",
|
||||
"filter": "Filtra libreria",
|
||||
"follow_us": "Seguici",
|
||||
"home": "Home",
|
||||
"discord": "Unisciti al nostro Discord",
|
||||
"telegram": "Unisciti al nostro Telegram",
|
||||
"x": "Segui su X",
|
||||
"github": "Contribuisci su GitHub"
|
||||
"home": "Home"
|
||||
},
|
||||
"header": {
|
||||
"search": "Cerca",
|
||||
@@ -34,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Nessun download in corso",
|
||||
"downloading_metadata": "Scaricamento metadati di {{title}}…",
|
||||
"checking_files": "Verifica file di {{title}}… ({{percentage}} completato)",
|
||||
"downloading": "Download di {{title}}… ({{percentage}} completato) - Conclusione {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -52,27 +44,20 @@
|
||||
"pause": "Metti in pausa",
|
||||
"cancel": "Annulla",
|
||||
"remove": "Rimuovi",
|
||||
"remove_from_list": "Rimuovi",
|
||||
"space_left_on_disk": "{{space}} rimasto sul disco",
|
||||
"eta": "Conclusione {{eta}}",
|
||||
"downloading_metadata": "Scaricamento metadati…",
|
||||
"checking_files": "Verifica file…",
|
||||
"filter": "Filtra repack",
|
||||
"requirements": "Requisiti di sistema",
|
||||
"minimum": "Minimi",
|
||||
"recommended": "Consigliati",
|
||||
"no_minimum_requirements": "{{title}} non fornisce informazioni sui requisiti minimi",
|
||||
"no_recommended_requirements": "{{title}} non fornisce informazioni sui requisiti consigliati",
|
||||
"paused_progress": "{{progress}} (In pausa)",
|
||||
"release_date": "Rilasciato il {{date}}",
|
||||
"publisher": "Pubblicato da {{publisher}}",
|
||||
"copy_link_to_clipboard": "Copia link",
|
||||
"copied_link_to_clipboard": "Link copiato",
|
||||
"hours": "ore",
|
||||
"minutes": "minuti",
|
||||
"amount_hours": "{{amount}} ore",
|
||||
"amount_minutes": "{{amount}} minuti",
|
||||
"accuracy": "{{accuratezza}}% di accuratezza",
|
||||
"accuracy": "{{accuracy}}% di accuratezza",
|
||||
"add_to_library": "Aggiungi alla libreria",
|
||||
"remove_from_library": "Rimuovi dalla libreria",
|
||||
"no_downloads": "Nessun download disponibile",
|
||||
@@ -86,17 +71,15 @@
|
||||
"playing_now": "Stai giocando adesso",
|
||||
"change": "Aggiorna",
|
||||
"repacks_modal_description": "Scegli il repack che vuoi scaricare",
|
||||
"downloads_path": "Percorso dei download",
|
||||
"select_folder_hint": "Per cambiare la cartella predefinita, accedi alle",
|
||||
"download_now": "Scarica ora",
|
||||
"installation_instructions": "Istruzioni di installazione",
|
||||
"installation_instructions_description": "Sono necessari passaggi aggiuntivi per installare questo gioco",
|
||||
"online_fix_instruction": "I giochi OnlineFix richiedono una password per essere estratti. Quando richiesto, utilizza la seguente password:",
|
||||
"dodi_installation_instruction": "Quando apri l'installatore di DODI, premi il tasto su della tua tastiera <0 /> per avviare il processo di installazione:",
|
||||
"dont_show_it_again": "Non mostrarlo più",
|
||||
"copy_to_clipboard": "Copia",
|
||||
"copied_to_clipboard": "Copiato",
|
||||
"got_it": "Capito"
|
||||
"no_shop_details": "Impossibile recuperare i dettagli del negozio.",
|
||||
"download_options": "Opzioni di download",
|
||||
"download_path": "Percorso di download",
|
||||
"previous_screenshot": "Screenshot precedente",
|
||||
"next_screenshot": "Screenshot successivo",
|
||||
"screenshot": "Screenshot {{number}}",
|
||||
"open_screenshot": "Apri screenshot {{number}}"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Attiva Hydra",
|
||||
@@ -112,19 +95,13 @@
|
||||
"eta": "Conclusione {{eta}}",
|
||||
"paused": "In pausa",
|
||||
"verifying": "Verifica…",
|
||||
"completed_at": "Completato in {{date}}",
|
||||
"completed": "Completato",
|
||||
"cancelled": "Annullato",
|
||||
"download_again": "Scarica di nuovo",
|
||||
"cancel": "Annulla",
|
||||
"filter": "Filtra giochi scaricati",
|
||||
"remove": "Rimuovi",
|
||||
"downloading_metadata": "Scaricamento metadati…",
|
||||
"checking_files": "Verifica file…",
|
||||
"starting_download": "Avvio download…",
|
||||
"deleting": "Eliminazione dell'installer…",
|
||||
"delete": "Rimuovi installer",
|
||||
"remove_from_list": "Rimuovi",
|
||||
"delete_modal_title": "Sei sicuro?",
|
||||
"delete_modal_description": "Questo rimuoverà tutti i file di installazione dal tuo computer",
|
||||
"install": "Installa"
|
||||
@@ -135,8 +112,14 @@
|
||||
"notifications": "Notifiche",
|
||||
"enable_download_notifications": "Quando un download è completo",
|
||||
"enable_repack_list_notifications": "Quando viene aggiunto un nuovo repack",
|
||||
"telemetry": "Telemetria",
|
||||
"telemetry_description": "Abilita statistiche di utilizzo anonime"
|
||||
"real_debrid_api_token_label": "Token API Real Debrid",
|
||||
"quit_app_instead_hiding": "Esci da Hydra invece di nascondere nell'area di notifica",
|
||||
"launch_with_system": "Apri Hydra all'avvio",
|
||||
"general": "Generale",
|
||||
"behavior": "Comportamento",
|
||||
"enable_real_debrid": "Abilita Real Debrid",
|
||||
"real_debrid_api_token_hint": "Puoi trovare la tua chiave API <0>here</0>",
|
||||
"save_changes": "Salva modifiche"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download completato",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "추천",
|
||||
"recently_added": "최근 추가됨",
|
||||
"trending": "인기",
|
||||
"surprise_me": "무작위 추천",
|
||||
"no_results": "결과 없음"
|
||||
@@ -12,16 +11,10 @@
|
||||
"settings": "설정",
|
||||
"my_library": "내 라이브러리",
|
||||
"downloading_metadata": "{{title}} (메타데이터 다운로드 중…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - 파일 검사 중…)",
|
||||
"paused": "{{title}} (일시 정지됨)",
|
||||
"downloading": "{{title}} ({{percentage}} - 다운로드 중…)",
|
||||
"filter": "라이브러리 정렬",
|
||||
"follow_us": "공식 SNS",
|
||||
"home": "홈",
|
||||
"discord": "공식 디스코드",
|
||||
"telegram": "공식 텔레그램",
|
||||
"x": "공식 X (구 트위터)",
|
||||
"github": "GitHub에서 기여하기"
|
||||
"home": "홈"
|
||||
},
|
||||
"header": {
|
||||
"search": "게임 검색하기",
|
||||
@@ -34,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "진행중인 다운로드 없음",
|
||||
"downloading_metadata": "{{title}}의 메타데이터를 다운로드 중…",
|
||||
"checking_files": "{{title}}의 파일들을 검사 중… ({{percentage}} 완료)",
|
||||
"downloading": "{{title}}의 파일들을 다운로드 중… ({{percentage}} 완료) - 완료까지 {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -52,22 +44,15 @@
|
||||
"pause": "일시 정지",
|
||||
"cancel": "취소",
|
||||
"remove": "제거",
|
||||
"remove_from_list": "목록에서 제거",
|
||||
"space_left_on_disk": "여유 저장 용량 {{space}} 남음",
|
||||
"eta": "완료까지 {{eta}}",
|
||||
"downloading_metadata": "메타데이터 다운로드 중…",
|
||||
"checking_files": "파일 검사 중…",
|
||||
"filter": "리팩들을 다음과 같이 정렬하기",
|
||||
"requirements": "시스템 사양",
|
||||
"minimum": "최저 사양",
|
||||
"recommended": "권장 사양",
|
||||
"no_minimum_requirements": "{{title}}의 최저 사양을 제공받지 못 함",
|
||||
"no_recommended_requirements": "{{title}}의 권장 사양을 제공받지 못 함",
|
||||
"paused_progress": "{{progress}} (일시 정지)",
|
||||
"release_date": "{{date}}에 발매됨",
|
||||
"publisher": "{{publisher}} 배급",
|
||||
"copy_link_to_clipboard": "링크 복사하기",
|
||||
"copied_link_to_clipboard": "링크 복사됨",
|
||||
"hours": "시",
|
||||
"minutes": "분",
|
||||
"amount_hours": "{{amount}} 시간",
|
||||
@@ -86,17 +71,8 @@
|
||||
"playing_now": "현재 플레이 중",
|
||||
"change": "바꾸기",
|
||||
"repacks_modal_description": "다운로드 할 리팩을 선택해 주세요",
|
||||
"downloads_path": "다운로드 경로",
|
||||
"select_folder_hint": "기본 폴더를 바꾸려면 <0>설정</0>으로 가세요",
|
||||
"download_now": "지금 다운로드",
|
||||
"installation_instructions": "설치 방법",
|
||||
"installation_instructions_description": "이 게임을 설치하기 위해서는 추가적인 단계가 필요합니다",
|
||||
"online_fix_instruction": "OnlineFix 게임들은 압축 해제 시 암호가 필요합니다. 비밀번호를 물을 때 다음을 암호로 사용하기:",
|
||||
"dodi_installation_instruction": "DODI 인스톨러를 실행했다면 키보드의 위 방향키를 눌러 설치를 시작하세요:",
|
||||
"dont_show_it_again": "다시 보지 않기",
|
||||
"copy_to_clipboard": "복사하기",
|
||||
"copied_to_clipboard": "복사됨",
|
||||
"got_it": "알았습니다"
|
||||
"download_now": "지금 다운로드"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Hydra 실행",
|
||||
@@ -112,24 +88,16 @@
|
||||
"eta": "완료까지 {{eta}}",
|
||||
"paused": "일시 정지됨",
|
||||
"verifying": "검증중…",
|
||||
"completed_at": "{{date}}에 완료됨",
|
||||
"completed": "완료됨",
|
||||
"cancelled": "취소됨",
|
||||
"download_again": "다시 다운로드 하기",
|
||||
"cancel": "취소",
|
||||
"filter": "다운로드 된 게임들을 정렬하기",
|
||||
"remove": "제거하기",
|
||||
"downloading_metadata": "메타데이터 다운로드 중…",
|
||||
"checking_files": "파일 검사 중…",
|
||||
"starting_download": "다운로드 개시 중…",
|
||||
"deleting": "인스톨러 삭제 중…",
|
||||
"delete": "인스톨러 삭제하기",
|
||||
"remove_from_list": "제거하기",
|
||||
"delete_modal_title": "정말로 하시겠습니까?",
|
||||
"delete_modal_description": "이 기기의 모든 설치 파일들이 제거될 것입니다",
|
||||
"install": "설치",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "Torrent"
|
||||
"install": "설치"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "다운로드 경로",
|
||||
@@ -137,15 +105,11 @@
|
||||
"notifications": "알림",
|
||||
"enable_download_notifications": "다운로드가 완료되었을 때",
|
||||
"enable_repack_list_notifications": "새 리팩이 추가되었을 때",
|
||||
"telemetry": "자동 데이터 수집",
|
||||
"telemetry_description": "익명 사용 통계를 활성화",
|
||||
"real_debrid_api_token_description": "Real Debrid API 토큰",
|
||||
"quit_app_instead_hiding": "작업 표시줄 트레이로 최소화하는 대신 Hydra를 종료",
|
||||
"launch_with_system": "컴퓨터가 시작되었을 때 Hydra 실행",
|
||||
"general": "일반",
|
||||
"behavior": "행동",
|
||||
"enable_real_debrid": "Real Debrid 활성화",
|
||||
"real_debrid": "Real Debrid",
|
||||
"enable_real_debrid": "Real-Debrid 활성화",
|
||||
"real_debrid_api_token_hint": "API 키를 <0>이곳</0>에서 얻으세요.",
|
||||
"save_changes": "변경 사항 저장"
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "Uitgelicht",
|
||||
"recently_added": "Recent Toegevoegd",
|
||||
"trending": "Trending",
|
||||
"surprise_me": "Verrasing",
|
||||
"no_results": "Geen resultaten gevonden"
|
||||
@@ -12,16 +11,10 @@
|
||||
"settings": "Instellingen",
|
||||
"my_library": "Mijn Bibliotheek",
|
||||
"downloading_metadata": "{{title}} (Downloading metadata…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Folders checken…)",
|
||||
"paused": "{{title}} (Gepauzeerd)",
|
||||
"downloading": "{{title}} ({{percentage}} - Downloading…)",
|
||||
"filter": "Filter Bibliotheek",
|
||||
"follow_us": "volg ons",
|
||||
"home": "Home",
|
||||
"discord": "Volg onze Discord",
|
||||
"telegram": "Volg onze Telegram",
|
||||
"x": "Volg ons op X",
|
||||
"github": "Contribute op GitHub"
|
||||
"home": "Home"
|
||||
},
|
||||
"header": {
|
||||
"search": "Zoek spellen",
|
||||
@@ -34,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Geen Downloads bezig",
|
||||
"downloading_metadata": "Downloading {{title}} metadata…",
|
||||
"checking_files": "Checking {{title}} files… ({{percentage}} complete)",
|
||||
"downloading": "Downloading {{title}}… ({{percentage}} complete) - Conclusion {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -52,22 +44,15 @@
|
||||
"pause": "Pauze",
|
||||
"cancel": "Stoppen",
|
||||
"remove": "Verwijderen",
|
||||
"remove_from_list": "Verwijdere van lijst",
|
||||
"space_left_on_disk": "{{space}} Over op schijf",
|
||||
"eta": "Conclusie {{eta}}",
|
||||
"downloading_metadata": "Downloading metadata…",
|
||||
"checking_files": "Files nakijken…",
|
||||
"filter": "Filter repacks",
|
||||
"requirements": "Systeem vereisten",
|
||||
"minimum": "Minimaal",
|
||||
"recommended": "Aanbevolen",
|
||||
"no_minimum_requirements": "{{title}} biedt geen informatie over de minimale vereisten",
|
||||
"no_recommended_requirements": "{{title}} biedt geen informatie over aanbevolen vereisten",
|
||||
"paused_progress": "{{progress}} (Paused)",
|
||||
"release_date": "Uitgebracht op {{date}}",
|
||||
"publisher": "Gepubliceerd door {{publisher}}",
|
||||
"copy_link_to_clipboard": "Kopieer link",
|
||||
"copied_link_to_clipboard": "Link Gekopieerd",
|
||||
"hours": "uren",
|
||||
"minutes": "minuten",
|
||||
"amount_hours": "{{amount}} uren",
|
||||
@@ -86,17 +71,8 @@
|
||||
"playing_now": "Speel nu",
|
||||
"change": "Verander",
|
||||
"repacks_modal_description": "Kies de herverpakking die u wilt downloaden",
|
||||
"downloads_path": "Downloads path",
|
||||
"select_folder_hint": "Om de standaardmap te wijzigen, gaat u naar <0>instellingen</0>",
|
||||
"download_now": "Download nu",
|
||||
"installation_instructions": "Installatie instructies",
|
||||
"installation_instructions_description": "Er zijn extra stappen vereist om deze game te installeren",
|
||||
"online_fix_instruction": "OnlineFix-spellen vereisen dat een wachtwoord wordt uitgepakt. Gebruik indien nodig het volgende wachtwoord:",
|
||||
"dodi_installation_instruction": "Wanneer u het DODI-installatieprogramma opent, drukt u op de toets omhoog <0 /> op uw toetsenbord om het installatieproces te starten:",
|
||||
"dont_show_it_again": "Laat het niet meer zien",
|
||||
"copy_to_clipboard": "Kopiëren",
|
||||
"copied_to_clipboard": "Gekopieerd",
|
||||
"got_it": "Begrepen"
|
||||
"download_now": "Download nu"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Activeer Hydra",
|
||||
@@ -112,24 +88,16 @@
|
||||
"eta": "Conclusie{{eta}}",
|
||||
"paused": "Gepauzeerd",
|
||||
"verifying": "Verifiëren…",
|
||||
"completed_at": "Voltooid binnen {{date}}",
|
||||
"completed": "Voltooid",
|
||||
"cancelled": "Geannuleerd",
|
||||
"download_again": "Opnieuw downloaden",
|
||||
"cancel": "Annuleren",
|
||||
"filter": "Filter gedownloade games",
|
||||
"remove": "Verwijderen",
|
||||
"downloading_metadata": "Metagegevens downloaden",
|
||||
"checking_files": "Bestanden controleren",
|
||||
"starting_download": "download starten",
|
||||
"deleting": "Installatieprogramma verwijderen…",
|
||||
"delete": "Installatieprogramma verwijderen",
|
||||
"remove_from_list": "Verwijderen",
|
||||
"delete_modal_title": "Weet je het zeker?",
|
||||
"delete_modal_description": "Hiermee worden alle installatiebestanden van uw computer verwijderd",
|
||||
"install": "Installeren",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "Torrent"
|
||||
"install": "Installeren"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Downloadpad",
|
||||
@@ -137,15 +105,12 @@
|
||||
"notifications": "Meldingen",
|
||||
"enable_download_notifications": "Wanneer een download voltooid is",
|
||||
"enable_repack_list_notifications": "Wanneer een nieuwe herverpakking wordt toegevoegd",
|
||||
"telemetry": "Telemetrie",
|
||||
"telemetry_description": "Schakel anonieme gebruiksstatistieken in",
|
||||
"real_debrid_api_token_label": "Real Debrid API token",
|
||||
"real_debrid_api_token_label": "Real-Debrid API token",
|
||||
"quit_app_instead_hiding": "Sluit Hydra af in plaats van te minimaliseren naar de lade",
|
||||
"launch_with_system": "Start Hydra bij het opstarten van het systeem",
|
||||
"general": "Algemeen",
|
||||
"behavior": "Gedrag",
|
||||
"enable_real_debrid": "Enable Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"enable_real_debrid": "Enable Real-Debrid",
|
||||
"real_debrid_api_token_hint": "U kunt uw API-sleutel <0>hier</0> verkrijgen.",
|
||||
"save_changes": "Wijzigingen opslaan"
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "Wyróżnione",
|
||||
"recently_added": "Ostatnio dodane",
|
||||
"trending": "Trendujące",
|
||||
"surprise_me": "Zaskocz mnie",
|
||||
"no_results": "Nie znaleziono wyników"
|
||||
@@ -12,11 +11,9 @@
|
||||
"settings": "Ustawienia",
|
||||
"my_library": "Moja biblioteka",
|
||||
"downloading_metadata": "{{title}} (Pobieranie metadata…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Sprawdzanie plików…)",
|
||||
"paused": "{{title}} (Zatrzymano)",
|
||||
"downloading": "{{title}} ({{percentage}} - Pobieranie…)",
|
||||
"filter": "Filtruj biblioteke",
|
||||
"follow_us": "Śledź nas",
|
||||
"home": "Główna"
|
||||
},
|
||||
"header": {
|
||||
@@ -30,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Brak pobierań w toku",
|
||||
"downloading_metadata": "Pobieranie {{title}} metadata…",
|
||||
"checking_files": "Sprawdzanie {{title}} plików… (ukończone w {{percentage}})",
|
||||
"downloading": "Pobieranie {{title}}… (ukończone w {{percentage}}) - Podsumowanie {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -48,24 +44,19 @@
|
||||
"pause": "Zatrzymaj",
|
||||
"cancel": "Anuluj",
|
||||
"remove": "Usuń",
|
||||
"remove_from_list": "Usuń",
|
||||
"space_left_on_disk": "{{space}} wolnego na dysku",
|
||||
"eta": "Podsumowanie {{eta}}",
|
||||
"downloading_metadata": "Pobieranie metadata…",
|
||||
"checking_files": "Sprawdzanie plików…",
|
||||
"filter": "Filtruj repacki",
|
||||
"requirements": "Wymagania systemowe",
|
||||
"minimum": "Minimalne",
|
||||
"recommended": "Zalecane",
|
||||
"no_minimum_requirements": "{{title}} nie zawiera informacji o minimalnych wymaganiach",
|
||||
"no_recommended_requirements": "{{title}} nie zawiera informacji o zalecanych wymaganiach",
|
||||
"paused_progress": "{{progress}} (Zatrzymano)",
|
||||
"release_date": "Wydano w {{date}}",
|
||||
"publisher": "Opublikowany przez {{publisher}}",
|
||||
"copy_link_to_clipboard": "Kopiuj łącze",
|
||||
"copied_link_to_clipboard": "Skopiowano łącze",
|
||||
"hours": "godzin",
|
||||
"minutes": "minut",
|
||||
"amount_hours": "{{amount}} godzin",
|
||||
"amount_minutes": "{{amount}} minut",
|
||||
"accuracy": "{{accuracy}}% dokładność",
|
||||
"add_to_library": "Dodaj do biblioteki",
|
||||
"remove_from_library": "Usuń z biblioteki",
|
||||
@@ -80,9 +71,15 @@
|
||||
"playing_now": "Granie teraz",
|
||||
"change": "Zmień",
|
||||
"repacks_modal_description": "Wybierz repack, który chcesz pobrać",
|
||||
"downloads_path": "Ścieżka pobierania",
|
||||
"select_folder_hint": "Aby zmienić domyślny folder, przejdź do",
|
||||
"download_now": "Pobierz teraz"
|
||||
"download_now": "Pobierz teraz",
|
||||
"no_shop_details": "Nie udało się pobrać danych sklepu.",
|
||||
"download_options": "Opcje pobierania",
|
||||
"download_path": "Ścieżka pobierania",
|
||||
"previous_screenshot": "Poprzedni zrzut ekranu",
|
||||
"next_screenshot": "Następny zrzut ekranu",
|
||||
"screenshot": "Zrzut ekranu {{number}}",
|
||||
"open_screenshot": "Otwórz zrzut ekranu {{number}}"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Aktywuj Hydra",
|
||||
@@ -98,19 +95,13 @@
|
||||
"eta": "Podsumowanie {{eta}}",
|
||||
"paused": "Zatrzymano",
|
||||
"verifying": "Weryfikowanie…",
|
||||
"completed_at": "Zakończono w {{date}}",
|
||||
"completed": "Zakończono",
|
||||
"cancelled": "Anulowano",
|
||||
"download_again": "Pobierz ponownie",
|
||||
"cancel": "Anuluj",
|
||||
"filter": "Filtruj pobrane gry",
|
||||
"remove": "Usuń",
|
||||
"downloading_metadata": "Pobieranie metadata…",
|
||||
"checking_files": "Sprawdzanie plików…",
|
||||
"starting_download": "Rozpoczęto pobieranie…",
|
||||
"deleting": "Usuwanie instalatora…",
|
||||
"delete": "Usuń instalator",
|
||||
"remove_from_list": "Usuń",
|
||||
"delete_modal_title": "Czy na pewno?",
|
||||
"delete_modal_description": "Spowoduje to usunięcie wszystkich plików instalacyjnych z komputera",
|
||||
"install": "Instaluj"
|
||||
@@ -121,8 +112,15 @@
|
||||
"notifications": "Powiadomienia",
|
||||
"enable_download_notifications": "Gdy pobieranie zostanie zakończone",
|
||||
"enable_repack_list_notifications": "Gdy dodawany jest nowy repack",
|
||||
"telemetry": "Telemetria",
|
||||
"telemetry_description": "Włącz anonimowe statystyki użycia"
|
||||
"real_debrid_api_token_label": "Real-Debrid API token",
|
||||
"quit_app_instead_hiding": "Zamknij Hydr zamiast minimalizować do zasobnika",
|
||||
"launch_with_system": "Uruchom Hydra przy starcie systemu",
|
||||
"general": "Ogólne",
|
||||
"behavior": "Zachowania",
|
||||
"language": "Język",
|
||||
"enable_real_debrid": "Włącz Real-Debrid",
|
||||
"real_debrid_api_token_hint": "Możesz uzyskać swój klucz API <0>tutaj</0>",
|
||||
"save_changes": "Zapisz zmiany"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Pobieranie zakończone",
|
||||
@@ -142,5 +140,8 @@
|
||||
"title": "Programy nie są zainstalowane",
|
||||
"description": "Pliki wykonywalne Wine lub Lutris nie zostały znalezione na twoim systemie",
|
||||
"instructions": "Sprawdź prawidłowy sposób instalacji dowolnego z nich w swojej dystrybucji Linuksa, aby gra działała normalnie"
|
||||
},
|
||||
"modal": {
|
||||
"close": "Zamknij"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"app": {
|
||||
"successfully_signed_in": "Logado com sucesso"
|
||||
},
|
||||
"home": {
|
||||
"featured": "Destaque",
|
||||
"recently_added": "Recém adicionados",
|
||||
"trending": "Populares",
|
||||
"surprise_me": "Surpreenda-me",
|
||||
"no_results": "Nenhum resultado encontrado"
|
||||
@@ -9,33 +11,32 @@
|
||||
"sidebar": {
|
||||
"catalogue": "Catálogo",
|
||||
"downloads": "Downloads",
|
||||
"settings": "Configurações",
|
||||
"settings": "Ajustes",
|
||||
"my_library": "Minha biblioteca",
|
||||
"downloading_metadata": "{{title}} (Baixando metadados…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Verificando arquivos…)",
|
||||
"paused": "{{title}} (Pausado)",
|
||||
"downloading": "{{title}} ({{percentage}} - Baixando…)",
|
||||
"filter": "Filtrar biblioteca",
|
||||
"home": "Início",
|
||||
"follow_us": "Acompanhe-nos",
|
||||
"discord": "Entre no nosso Discord",
|
||||
"telegram": "Entre no nosso Telegram",
|
||||
"x": "Siga-nos no X",
|
||||
"github": "Contribua no GitHub"
|
||||
"queued": "{{title}} (Na fila)",
|
||||
"game_has_no_executable": "Jogo não possui executável selecionado",
|
||||
"sign_in": "Login"
|
||||
},
|
||||
"header": {
|
||||
"search": "Buscar jogos",
|
||||
"catalogue": "Catálogo",
|
||||
"downloads": "Downloads",
|
||||
"search_results": "Resultados da busca",
|
||||
"settings": "Configurações",
|
||||
"home": "Início"
|
||||
"settings": "Ajustes",
|
||||
"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 downloads em andamento",
|
||||
"downloading_metadata": "Baixando metadados de {{title}}…",
|
||||
"checking_files": "Verificando arquivos de {{title}}… ({{percentage}} completo)",
|
||||
"downloading": "Baixando {{title}}… ({{percentage}} completo) - Conclusão {{eta}} - {{speed}}"
|
||||
"downloading": "Baixando {{title}}… ({{percentage}} concluído) - Conclusão {{eta}} - {{speed}}",
|
||||
"calculating_eta": "Baixando {{title}}… ({{percentage}} concluído) - Calculando tempo restante…"
|
||||
},
|
||||
"game_details": {
|
||||
"open_download_options": "Ver opções de download",
|
||||
@@ -47,22 +48,17 @@
|
||||
"pause": "Pausar",
|
||||
"cancel": "Cancelar",
|
||||
"remove": "Remover",
|
||||
"remove_from_list": "Remover",
|
||||
"space_left_on_disk": "{{space}} livres em disco",
|
||||
"eta": "Conclusão {{eta}}",
|
||||
"calculating_eta": "Calculando tempo restante…",
|
||||
"downloading_metadata": "Baixando metadados…",
|
||||
"checking_files": "Verificando arquivos…",
|
||||
"filter": "Filtrar repacks",
|
||||
"requirements": "Requisitos do sistema",
|
||||
"minimum": "Mínimos",
|
||||
"recommended": "Recomendados",
|
||||
"no_minimum_requirements": "{{title}} não possui informações de requisitos mínimos",
|
||||
"no_recommended_requirements": "{{title}} não possui informações de requisitos recomendados",
|
||||
"paused_progress": "{{progress}} (Pausado)",
|
||||
"paused": "Pausado",
|
||||
"release_date": "Lançado em {{date}}",
|
||||
"publisher": "Publicado por {{publisher}}",
|
||||
"copy_link_to_clipboard": "Copiar link",
|
||||
"copied_link_to_clipboard": "Link copiado",
|
||||
"hours": "horas",
|
||||
"minutes": "minutos",
|
||||
"amount_hours": "{{amount}} horas",
|
||||
@@ -82,23 +78,37 @@
|
||||
"playing_now": "Jogando agora",
|
||||
"change": "Mudar",
|
||||
"repacks_modal_description": "Escolha o repack do jogo que deseja baixar",
|
||||
"select_folder_hint": "Para trocar a pasta padrão, acesse a <0>Tela de Configurações</0>",
|
||||
"download_now": "Baixe agora",
|
||||
"installation_instructions": "Instruções de Instalação",
|
||||
"installation_instructions_description": "Passos adicionais são necessários para instalar esse jogo",
|
||||
"online_fix_instruction": "Jogos OnlineFix precisam de uma senha para serem extraídos. Quando solicitado, utilize a seguinte senha:",
|
||||
"dodi_installation_instruction": "Quando o instalador do DODI for aberto, pressione a seta para cima <0 /> do teclado para iniciar o processo de instalação:",
|
||||
"dont_show_it_again": "Não mostrar novamente",
|
||||
"copy_to_clipboard": "Copiar",
|
||||
"copied_to_clipboard": "Copiado",
|
||||
"got_it": "Entendi",
|
||||
"select_folder_hint": "Para trocar o diretório padrão, acesse a <0>Tela de Ajustes</0>",
|
||||
"download_now": "Iniciar download",
|
||||
"no_shop_details": "Não foi possível obter os detalhes da loja.",
|
||||
"download_options": "Opções de download",
|
||||
"download_path": "Diretório de download",
|
||||
"previous_screenshot": "Captura de tela anterior",
|
||||
"next_screenshot": "Próxima captura de tela",
|
||||
"screenshot": "Captura de tela {{number}}",
|
||||
"open_screenshot": "Ver captura de tela {{number}}"
|
||||
"open_screenshot": "Ver captura de tela {{number}}",
|
||||
"download_settings": "Ajustes do download",
|
||||
"downloader": "Downloader",
|
||||
"select_executable": "Selecionar",
|
||||
"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",
|
||||
"remove_from_library_description": "Isso irá remover {{game}} da sua biblioteca",
|
||||
"remove_from_library_title": "Tem certeza?",
|
||||
"executable_section_title": "Executável",
|
||||
"executable_section_description": "O caminho do arquivo que será executado ao clicar em \"Jogar\"",
|
||||
"downloads_secion_title": "Downloads",
|
||||
"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 arquivos que foram baixados pelo Hydra",
|
||||
"download_in_progress": "Download em andamento",
|
||||
"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"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Ativação",
|
||||
@@ -114,24 +124,23 @@
|
||||
"eta": "Conclusão {{eta}}",
|
||||
"paused": "Pausado",
|
||||
"verifying": "Verificando…",
|
||||
"completed_at": "Concluído em {{date}}",
|
||||
"completed": "Concluído",
|
||||
"cancelled": "Cancelado",
|
||||
"download_again": "Baixar novamente",
|
||||
"removed": "Cancelado",
|
||||
"cancel": "Cancelar",
|
||||
"filter": "Filtrar jogos baixados",
|
||||
"remove": "Remover",
|
||||
"downloading_metadata": "Baixando metadados…",
|
||||
"checking_files": "Verificando arquivos…",
|
||||
"starting_download": "Iniciando download…",
|
||||
"remove_from_list": "Remover",
|
||||
"delete": "Remover instalador",
|
||||
"delete_modal_description": "Isso removerá todos os arquivos de instalação do seu computador",
|
||||
"delete_modal_title": "Tem certeza?",
|
||||
"deleting": "Excluindo instalador…",
|
||||
"install": "Instalar",
|
||||
"torrent": "Torrent",
|
||||
"real_debrid": "Real Debrid"
|
||||
"download_in_progress": "Baixando agora",
|
||||
"queued_downloads": "Na fila",
|
||||
"downloads_completed": "Completo",
|
||||
"queued": "Na fila",
|
||||
"no_downloads_title": "Nada por aqui…",
|
||||
"no_downloads_description": "Você ainda não baixou nada pelo Hydra, mas nunca é tarde para começar."
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Diretório dos downloads",
|
||||
@@ -139,17 +148,45 @@
|
||||
"notifications": "Notificações",
|
||||
"enable_download_notifications": "Quando um download for concluído",
|
||||
"enable_repack_list_notifications": "Quando a lista de repacks for atualizada",
|
||||
"telemetry": "Telemetria",
|
||||
"telemetry_description": "Habilitar estatísticas de uso anônimas",
|
||||
"real_debrid_api_token_label": "Token de API do Real Debrid",
|
||||
"quit_app_instead_hiding": "Fechar o aplicativo em vez de minimizá-lo",
|
||||
"launch_with_system": "Iniciar aplicativo na inicialização do sistema",
|
||||
"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",
|
||||
"launch_with_system": "Iniciar o Hydra junto com o sistema",
|
||||
"general": "Geral",
|
||||
"behavior": "Comportamento",
|
||||
"enable_real_debrid": "Habilitar Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"real_debrid_api_token_hint": "Você pode obter sua chave de API <0>aqui</0>.",
|
||||
"save_changes": "Salvar mudanças"
|
||||
"download_sources": "Fontes de download",
|
||||
"language": "Idioma",
|
||||
"real_debrid_api_token": "Token de API",
|
||||
"enable_real_debrid": "Habilitar Real-Debrid",
|
||||
"real_debrid_api_token_hint": "Você pode obter seu token de API <0>aqui</0>",
|
||||
"real_debrid_description": "O Real-Debrid é um downloader sem restrições que permite baixar arquivos 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, assine a Real-Debrid",
|
||||
"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.",
|
||||
"validate_download_source": "Validar",
|
||||
"remove_download_source": "Remover",
|
||||
"add_download_source": "Adicionar fonte",
|
||||
"download_count_zero": "Sem downloads na lista",
|
||||
"download_count_one": "{{countFormatted}} download na lista",
|
||||
"download_count_other": "{{countFormatted}} downloads na lista",
|
||||
"download_options_zero": "Sem downloads disponíveis",
|
||||
"download_options_one": "{{countFormatted}} download disponível",
|
||||
"download_options_other": "{{countFormatted}} downloads disponíveis",
|
||||
"download_source_url": "URL da fonte",
|
||||
"add_download_source_description": "Insira a 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 a url de um JSON válido",
|
||||
"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"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download concluído",
|
||||
@@ -176,5 +213,30 @@
|
||||
},
|
||||
"modal": {
|
||||
"close": "Botão de fechar"
|
||||
},
|
||||
"forms": {
|
||||
"toggle_password_visibility": "Alternar visibilidade da senha"
|
||||
},
|
||||
"user_profile": {
|
||||
"amount_hours": "{{amount}} horas",
|
||||
"amount_minutes": "{{amount}} minutos",
|
||||
"last_time_played": "Jogou {{period}}",
|
||||
"activity": "Atividade recente",
|
||||
"library": "Biblioteca",
|
||||
"total_play_time": "Tempo total de jogo: {{amount}}",
|
||||
"no_recent_activity_title": "Hmmm… nada por aqui",
|
||||
"no_recent_activity_description": "Parece que você não jogou nada recentemente. Que tal começar agora?",
|
||||
"display_name": "Nome de exibição",
|
||||
"saving": "Salvando…",
|
||||
"save": "Salvar",
|
||||
"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?",
|
||||
"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?"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"app": {
|
||||
"successfully_signed_in": "Успешный вход"
|
||||
},
|
||||
"home": {
|
||||
"featured": "Рекомендованное",
|
||||
"recently_added": "Новинки",
|
||||
"trending": "В тренде",
|
||||
"surprise_me": "Удиви меня",
|
||||
"no_results": "Ничего не найдено"
|
||||
@@ -12,16 +14,13 @@
|
||||
"settings": "Настройки",
|
||||
"my_library": "Библиотека",
|
||||
"downloading_metadata": "{{title}} (Загрузка метаданных…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Проверка файлов…)",
|
||||
"paused": "{{title}} (Приостановлено)",
|
||||
"downloading": "{{title}} ({{percentage}} - Загрузка…)",
|
||||
"filter": "Фильтр библиотеки",
|
||||
"follow_us": "Подписывайтесь на нас",
|
||||
"home": "Главная",
|
||||
"discord": "Присоединяйтесь к Discord",
|
||||
"telegram": "Присоединяйтесь к Telegram",
|
||||
"x": "Подписывайтесь на X",
|
||||
"github": "Внести свой вклад на GitHub"
|
||||
"queued": "{{title}} (В очереди)",
|
||||
"game_has_no_executable": "Файл запуска игры не выбран",
|
||||
"sign_in": "Войти"
|
||||
},
|
||||
"header": {
|
||||
"search": "Поиск",
|
||||
@@ -29,13 +28,15 @@
|
||||
"catalogue": "Каталог",
|
||||
"downloads": "Загрузки",
|
||||
"search_results": "Результаты поиска",
|
||||
"settings": "Настройки"
|
||||
"settings": "Настройки",
|
||||
"version_available_install": "Доступна версия {{version}}. Нажмите здесь для перезапуска и установки.",
|
||||
"version_available_download": "Доступна версия {{version}}. Нажмите здесь для загрузки."
|
||||
},
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Нет активных загрузок",
|
||||
"downloading_metadata": "Загрузка метаданных {{title}}…",
|
||||
"checking_files": "Проверка файлов {{title}}… ({{percentage}} завершено)",
|
||||
"downloading": "Загрузка {{title}}… ({{percentage}} завершено) - Окончание {{eta}} - {{speed}}"
|
||||
"downloading": "Загрузка {{title}}… ({{percentage}} завершено) - Окончание {{eta}} - {{speed}}",
|
||||
"calculating_eta": "Загрузка {{title}}… ({{percentage}} завершено) - Подсчёт оставшегося времени…"
|
||||
},
|
||||
"catalogue": {
|
||||
"next_page": "Следующая страница",
|
||||
@@ -52,22 +53,17 @@
|
||||
"pause": "Приостановить",
|
||||
"cancel": "Отменить",
|
||||
"remove": "Удалить",
|
||||
"remove_from_list": "Удалить",
|
||||
"space_left_on_disk": "{{space}} свободно на диске",
|
||||
"eta": "Окончание {{eta}}",
|
||||
"calculating_eta": "Подсчёт оставшегося времени…",
|
||||
"downloading_metadata": "Загрузка метаданных…",
|
||||
"checking_files": "Проверка файлов…",
|
||||
"filter": "Фильтр репаков",
|
||||
"requirements": "Системные требования",
|
||||
"minimum": "Минимальные",
|
||||
"recommended": "Рекомендуемые",
|
||||
"no_minimum_requirements": "Для {{title}} не указаны минимальные требования",
|
||||
"no_recommended_requirements": "Для {{title}} не указаны рекомендуемые требования",
|
||||
"paused_progress": "{{progress}} (Приостановлено)",
|
||||
"paused": "Приостановлено",
|
||||
"release_date": "Выпущено {{date}}",
|
||||
"publisher": "Издатель {{publisher}}",
|
||||
"copy_link_to_clipboard": "Копировать ссылку",
|
||||
"copied_link_to_clipboard": "Ссылка скопирована",
|
||||
"hours": "часов",
|
||||
"minutes": "минут",
|
||||
"amount_hours": "{{amount}} часов",
|
||||
@@ -88,21 +84,35 @@
|
||||
"repacks_modal_description": "Выберите репак для загрузки",
|
||||
"select_folder_hint": "Чтобы изменить папку загрузок по умолчанию, откройте <0>Настройки</0>",
|
||||
"download_now": "Загрузить сейчас",
|
||||
"installation_instructions": "Инструкция по установке",
|
||||
"installation_instructions_description": "Для установки этой игры требуются дополнительные шаги",
|
||||
"online_fix_instruction": "В играх с OnlineFix требуется ввести пароль для извлечения. При необходимости используйте следующий пароль:",
|
||||
"dodi_installation_instruction": "Когда вы откроете установщик DODI, нажмите на клавиатуре клавишу 'вверх' <0 />, чтобы начать процесс установки:",
|
||||
"dont_show_it_again": "Не показывать снова",
|
||||
"copy_to_clipboard": "Копировать",
|
||||
"copied_to_clipboard": "Скопировано",
|
||||
"got_it": "Понятно",
|
||||
"no_shop_details": "Не удалось получить описание",
|
||||
"download_options": "Вариантов загрузки",
|
||||
"download_path": "Путь для загрузок",
|
||||
"previous_screenshot": "Предыдущий скриншот",
|
||||
"next_screenshot": "Следующий скриншот",
|
||||
"screenshot": "Скриншот {{number}}",
|
||||
"open_screenshot": "Открыть скриншот {{number}}"
|
||||
"open_screenshot": "Открыть скриншот {{number}}",
|
||||
"download_settings": "Параметры загрузки",
|
||||
"downloader": "Загрузчик",
|
||||
"select_executable": "Выбрать",
|
||||
"no_executable_selected": "Файл не выбран",
|
||||
"open_folder": "Открыть папку",
|
||||
"open_download_location": "Просмотреть папку загрузок",
|
||||
"create_shortcut": "Создать ярлык на рабочем столе",
|
||||
"remove_files": "Удалить файлы",
|
||||
"remove_from_library_title": "Вы уверены?",
|
||||
"remove_from_library_description": "{{game}} будет удалена из вашей библиотеки.",
|
||||
"options": "Настройки",
|
||||
"executable_section_title": "Файл",
|
||||
"executable_section_description": "Путь к файлу, который будет запущен при нажатии на \"Play\"",
|
||||
"downloads_secion_title": "Загрузки",
|
||||
"downloads_section_description": "Проверить наличие обновлений или других версий игры",
|
||||
"danger_zone_section_title": "Опасная зона",
|
||||
"danger_zone_section_description": "Удалить эту игру из вашей библиотеки или файлы скачанные Hydra",
|
||||
"download_in_progress": "Идёт загрузка",
|
||||
"download_paused": "Загрузка приостановлена",
|
||||
"last_downloaded_option": "Последний вариант загрузки",
|
||||
"create_shortcut_success": "Ярлык создан",
|
||||
"create_shortcut_error": "Не удалось создать ярлык"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Активировать Hydra",
|
||||
@@ -118,24 +128,23 @@
|
||||
"eta": "Окончание {{eta}}",
|
||||
"paused": "Приостановлено",
|
||||
"verifying": "Проверка…",
|
||||
"completed_at": "Завершено в {{date}}",
|
||||
"completed": "Завершено",
|
||||
"cancelled": "Отменено",
|
||||
"download_again": "Загрузить снова",
|
||||
"cancel": "Отменить",
|
||||
"removed": "Не скачано",
|
||||
"cancel": "Отмена",
|
||||
"filter": "Фильтр загруженных игр",
|
||||
"remove": "Удалить",
|
||||
"downloading_metadata": "Загрузка метаданных…",
|
||||
"checking_files": "Проверка файлов…",
|
||||
"starting_download": "Начало загрузки…",
|
||||
"deleting": "Удаление установщика…",
|
||||
"delete": "Удалить установщик",
|
||||
"remove_from_list": "Удалить",
|
||||
"delete_modal_title": "Вы уверены?",
|
||||
"delete_modal_description": "Это удалит все установщики с вашего компьютера",
|
||||
"install": "Установить",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "Torrent"
|
||||
"download_in_progress": "В процессе",
|
||||
"queued_downloads": "Загрузки в очереди",
|
||||
"downloads_completed": "Завершено",
|
||||
"queued": "В очереди",
|
||||
"no_downloads_title": "Здесь так пусто...",
|
||||
"no_downloads_description": "Вы ещё ничего не скачали через Hydra, но никогда не поздно начать."
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Путь загрузок",
|
||||
@@ -143,17 +152,45 @@
|
||||
"notifications": "Уведомления",
|
||||
"enable_download_notifications": "По завершении загрузки",
|
||||
"enable_repack_list_notifications": "При добавлении нового репака",
|
||||
"telemetry": "Телеметрия",
|
||||
"telemetry_description": "Отправлять анонимную статистику использования",
|
||||
"real_debrid_api_token_label": "Real Debrid API-токен",
|
||||
"real_debrid_api_token_label": "Real-Debrid API-токен",
|
||||
"quit_app_instead_hiding": "Закрывать Hydra вместо того, чтобы сворачивать его в трей",
|
||||
"launch_with_system": "Запуск Hydra вместе с системой",
|
||||
"general": "Основные",
|
||||
"behavior": "Поведение",
|
||||
"enable_real_debrid": "Включить Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"real_debrid_api_token_hint": "API ключ можно получить <0>здесь</0>.",
|
||||
"save_changes": "Сохранить изменения"
|
||||
"download_sources": "Скачать исходный код",
|
||||
"language": "Язык",
|
||||
"real_debrid_api_token": "API Ключ",
|
||||
"enable_real_debrid": "Включить Real-Debrid",
|
||||
"real_debrid_description": "Real-Debrid - это неограниченный загрузчик, который позволяет быстро скачивать файлы, размещенные в Интернете, или мгновенно передавать их в плеер через частную сеть, позволяющую обходить любые блокировки.",
|
||||
"real_debrid_invalid_token": "Неверный API ключ",
|
||||
"real_debrid_api_token_hint": "API ключ можно получить <0>здесь</0>",
|
||||
"real_debrid_free_account_error": "Аккаунт \"{{username}}\" - не имеет подписки. Пожалуйста, оформите подписку на Real-Debrid",
|
||||
"real_debrid_linked_message": "Привязан аккаунт \"{{username}}\"",
|
||||
"save_changes": "Сохранить изменения",
|
||||
"changes_saved": "Изменения успешно сохранены",
|
||||
"download_sources_description": "Hydra будет получать ссылки на загрузки из этих источников. URL должна содержать прямую ссылку на .json-файл с ссылками для загрузок.",
|
||||
"validate_download_source": "Проверить",
|
||||
"remove_download_source": "Удалить",
|
||||
"add_download_source": "Добавить источник",
|
||||
"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": "Обновлён",
|
||||
"download_source_errored": "Ошибка",
|
||||
"sync_download_sources": "Синхронизировать источники",
|
||||
"removed_download_source": "Источник загрузок удален",
|
||||
"added_download_source": "Источник загрузок добавлен",
|
||||
"download_sources_synced": "Все источники загрузок синхронизированы",
|
||||
"insert_valid_json_url": "Вставьте действительный URL JSON-файла",
|
||||
"found_download_option_zero": "Не найдено вариантов загрузки",
|
||||
"found_download_option_one": "Найден {{countFormatted}} вариант загрузки",
|
||||
"found_download_option_other": "Найдено {{countFormatted}} вариантов загрузки",
|
||||
"import": "Импортировать"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Загрузка завершена",
|
||||
@@ -176,5 +213,30 @@
|
||||
},
|
||||
"modal": {
|
||||
"close": "Закрыть"
|
||||
},
|
||||
"forms": {
|
||||
"toggle_password_visibility": "Показывать пароль"
|
||||
},
|
||||
"user_profile": {
|
||||
"amount_hours": "{{amount}} часов",
|
||||
"amount_minutes": "{{amount}} минут",
|
||||
"last_time_played": "Последняя игра {{period}}",
|
||||
"activity": "Недавняя активность",
|
||||
"library": "Библиотека",
|
||||
"total_play_time": "Всего сыграно: {{amount}}",
|
||||
"no_recent_activity_title": "Хммм... Тут ничего нет",
|
||||
"no_recent_activity_description": "Вы давно ни во что не играли. Пора это изменить!",
|
||||
"display_name": "Отображаемое имя",
|
||||
"saving": "Сохранение",
|
||||
"save": "Сохранено",
|
||||
"edit_profile": "Редактировать Профиль",
|
||||
"saved_successfully": "Успешно сохранено",
|
||||
"try_again": "Пожалуйста, попробуйте ещё раз",
|
||||
"sign_out_modal_title": "Вы уверены?",
|
||||
"cancel": "Отменить",
|
||||
"successfully_signed_out": "Успешный выход из аккаунта",
|
||||
"sign_out": "Выйти",
|
||||
"playing_for": "Сыграно {{amount}}",
|
||||
"sign_out_modal_text": "Ваша библиотека связана с текущей учетной записью. При выходе из системы ваша библиотека станет недоступна, и прогресс не будет сохранен. Выйти?"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "Öne çıkan",
|
||||
"recently_added": "Son eklenen",
|
||||
"trending": "Popüler",
|
||||
"surprise_me": "Şaşırt beni",
|
||||
"no_results": "Sonuç bulunamadı"
|
||||
@@ -12,16 +11,10 @@
|
||||
"settings": "Ayarlar",
|
||||
"my_library": "Kütüphane",
|
||||
"downloading_metadata": "{{title}} (Metadata indiriliyor…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Dosyalar kontrol ediliyor…)",
|
||||
"paused": "{{title}} (Duraklatıldı)",
|
||||
"downloading": "{{title}} ({{percentage}} - İndiriliyor…)",
|
||||
"filter": "Kütüphaneyi filtrele",
|
||||
"follow_us": "Bizi takip et",
|
||||
"home": "Ana menü",
|
||||
"discord": "Discord'umuza katıl",
|
||||
"telegram": "Telegram'umuza katıl",
|
||||
"x": "X'te bizi takip et",
|
||||
"github": "GitHub'da bize katkı yap"
|
||||
"home": "Ana menü"
|
||||
},
|
||||
"header": {
|
||||
"search": "Ara",
|
||||
@@ -34,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "İndirilen bir şey yok",
|
||||
"downloading_metadata": "{{title}} metadatası indiriliyor…",
|
||||
"checking_files": "{{title}} dosyaları kontrol ediliyor… ({{percentage}} tamamlandı)",
|
||||
"downloading": "{{title}} indiriliyor… ({{percentage}} tamamlandı) - Bitiş {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -52,22 +44,15 @@
|
||||
"pause": "Duraklat",
|
||||
"cancel": "İptal et",
|
||||
"remove": "Sil",
|
||||
"remove_from_list": "Sil",
|
||||
"space_left_on_disk": "Diskte {{space}} yer kaldı",
|
||||
"eta": "Bitiş {{eta}}",
|
||||
"downloading_metadata": "Metadata indiriliyor…",
|
||||
"checking_files": "Dosyalar kontrol ediliyor…",
|
||||
"filter": "Repackleri filtrele",
|
||||
"requirements": "Sistem gereksinimleri",
|
||||
"minimum": "Minimum",
|
||||
"recommended": "Önerilen",
|
||||
"no_minimum_requirements": "{{title}} minimum sistem gereksinim bilgilerini karşılamıyor",
|
||||
"no_recommended_requirements": "{{title}} önerilen sistem gereksinim bilgilerini karşılamıyor",
|
||||
"paused_progress": "{{progress}} (Duraklatıldı)",
|
||||
"release_date": "{{date}} tarihinde çıktı",
|
||||
"publisher": "{{publisher}} tarihinde yayınlandı",
|
||||
"copy_link_to_clipboard": "Link'i kopyala",
|
||||
"copied_link_to_clipboard": "Link kopyalandı",
|
||||
"hours": "saatler",
|
||||
"minutes": "dakikalar",
|
||||
"amount_hours": "{{amount}} saat",
|
||||
@@ -86,17 +71,8 @@
|
||||
"playing_now": "Şimdi oynanıyor",
|
||||
"change": "Değiştir",
|
||||
"repacks_modal_description": "İndirmek istediğiiniz repacki seçin",
|
||||
"downloads_path": "İndirme yolu",
|
||||
"select_folder_hint": "Varsayılan klasörü değiştirmek için ulaşmanız gereken ayar",
|
||||
"download_now": "Şimdi",
|
||||
"installation_instructions": "Kurulum",
|
||||
"installation_instructions_description": "Bu oyunu kurmak için ek adımlar gerekiyor",
|
||||
"online_fix_instruction": "OnlineFix oyunlarını ayıklamak için parola gerekiyor. Gerekli olduğunda bu parolayı kullanın:",
|
||||
"dodi_installation_instruction": "Dodi installerını açtığınızda, kurulumu başlatmak için bu tuşa basın <0 />:",
|
||||
"dont_show_it_again": "Tekrar gösterme",
|
||||
"copy_to_clipboard": "Kopyala",
|
||||
"copied_to_clipboard": "Kopyalandı",
|
||||
"got_it": "Tamam"
|
||||
"download_now": "Şimdi"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Hydra'yı aktif et",
|
||||
@@ -112,19 +88,13 @@
|
||||
"eta": "Bitiş {{eta}}",
|
||||
"paused": "Duraklatıldı",
|
||||
"verifying": "Doğrulanıyor…",
|
||||
"completed_at": "{{date}} tarihinde tamamlanacak",
|
||||
"completed": "Tamamlandı",
|
||||
"cancelled": "İptal edildi",
|
||||
"download_again": "Tekrar indir",
|
||||
"cancel": "İptal et",
|
||||
"filter": "Yüklü oyunları filtrele",
|
||||
"remove": "Kaldır",
|
||||
"downloading_metadata": "Metadata indiriliyor…",
|
||||
"checking_files": "Dosyalar kontrol ediliyor…",
|
||||
"starting_download": "İndirme başlatılıyor…",
|
||||
"deleting": "Installer siliniyor…",
|
||||
"delete": "Installer'ı sil",
|
||||
"remove_from_list": "Kaldır",
|
||||
"delete_modal_title": "Emin misiniz?",
|
||||
"delete_modal_description": "Bu bilgisayarınızdan tüm kurulum dosyalarını silecek",
|
||||
"install": "Kur"
|
||||
@@ -134,9 +104,7 @@
|
||||
"change": "Güncelle",
|
||||
"notifications": "Bildirimler",
|
||||
"enable_download_notifications": "Bir indirme bittiğinde",
|
||||
"enable_repack_list_notifications": "Yeni bir repack eklendiğinde",
|
||||
"telemetry": "Telemetri",
|
||||
"telemetry_description": "Anonim kullanım istatistiklerini aktifleştir"
|
||||
"enable_repack_list_notifications": "Yeni bir repack eklendiğinde"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "İndirme tamamlandı",
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"app": {
|
||||
"successfully_signed_in": "Успішний вхід в систему"
|
||||
},
|
||||
"home": {
|
||||
"featured": "Рекомендоване",
|
||||
"recently_added": "Нове",
|
||||
"trending": "У тренді",
|
||||
"surprise_me": "Здивуй мене",
|
||||
"no_results": "Результатів не знайдено"
|
||||
@@ -12,16 +14,13 @@
|
||||
"settings": "Налаштування",
|
||||
"my_library": "Бібліотека",
|
||||
"downloading_metadata": "{{title}} (Завантаження метаданих…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Перевірка файлів…)",
|
||||
"paused": "{{title}} (Призупинено)",
|
||||
"downloading": "{{title}} ({{percentage}} - Завантаження…)",
|
||||
"filter": "Фільтр бібліотеки",
|
||||
"follow_us": "Підписуйтесь на нас",
|
||||
"home": "Головна",
|
||||
"discord": "Приєднуйтесь до Discord",
|
||||
"telegram": "Приєднуйтесь до Telegram",
|
||||
"x": "Підписуйтесь на X",
|
||||
"github": "Зробіть свій внесок на GitHub"
|
||||
"game_has_no_executable": "Не було вибрано файл для запуску гри",
|
||||
"queued": "{{title}} в черзі",
|
||||
"sign_in": "Увійти"
|
||||
},
|
||||
"header": {
|
||||
"search": "Пошук",
|
||||
@@ -29,13 +28,15 @@
|
||||
"catalogue": "Каталог",
|
||||
"downloads": "Завантаження",
|
||||
"search_results": "Результати пошуку",
|
||||
"settings": "Налаштування"
|
||||
"settings": "Налаштування",
|
||||
"version_available_download": "Доступна версія {{version}}. Натисніть тут, щоб перезапустити та встановити.",
|
||||
"version_available_install": "Доступна версія {{version}}. Натисніть тут для завантаження."
|
||||
},
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Немає активних завантажень",
|
||||
"downloading_metadata": "Завантаження метаданих {{title}}…",
|
||||
"checking_files": "Перевірка файлів {{title}}… ({{percentage}} завершено)",
|
||||
"downloading": "Завантаження {{title}}… ({{percentage}} завершено) - Закінчення {{eta}} - {{speed}}"
|
||||
"downloading": "Завантаження {{title}}… ({{percentage}} завершено) - Закінчення {{eta}} - {{speed}}",
|
||||
"calculating_eta": "Завантаження {{title}}… ({{percentage}} завершено) - Обчислення залишкового часу…"
|
||||
},
|
||||
"catalogue": {
|
||||
"next_page": "Наступна сторінка",
|
||||
@@ -52,22 +53,15 @@
|
||||
"pause": "Призупинити",
|
||||
"cancel": "Скасувати",
|
||||
"remove": "Видалити",
|
||||
"remove_from_list": "Видалити",
|
||||
"space_left_on_disk": "{{space}} вільно на диску",
|
||||
"eta": "Закінчення {{eta}}",
|
||||
"downloading_metadata": "Завантаження метаданих…",
|
||||
"checking_files": "Перевірка файлів…",
|
||||
"filter": "Фільтр репаків",
|
||||
"requirements": "Системні вимоги",
|
||||
"minimum": "Мінімальні",
|
||||
"recommended": "Рекомендовані",
|
||||
"no_minimum_requirements": "Для {{title}} не вказані мінімальні вимоги",
|
||||
"no_recommended_requirements": "Для {{title}} не вказані рекомендовані вимоги",
|
||||
"paused_progress": "{{progress}} (Призупинено)",
|
||||
"release_date": "Випущено {{date}}",
|
||||
"publisher": "Видавець {{publisher}}",
|
||||
"copy_link_to_clipboard": "Скопіювати посилання",
|
||||
"copied_link_to_clipboard": "Посилання скопійовано",
|
||||
"hours": "годин",
|
||||
"minutes": "хвилин",
|
||||
"amount_hours": "{{amount}} годин",
|
||||
@@ -86,23 +80,43 @@
|
||||
"playing_now": "Поточна гра",
|
||||
"change": "Змінити",
|
||||
"repacks_modal_description": "Виберіть репак, який хочете завантажити",
|
||||
"downloads_path": "Шлях завантажень",
|
||||
"select_folder_hint": "Щоб змінити теку за замовчуванням, відкрийте",
|
||||
"download_now": "Завантажити зараз",
|
||||
"installation_instructions": "Інструкція зі встановлення",
|
||||
"installation_instructions_description": "Для встановлення цієї гри потрібні додаткові кроки",
|
||||
"online_fix_instruction": "В іграх з OnlineFix потрібно ввести пароль для вилучення. За необхідності використовуйте наступний пароль:",
|
||||
"dodi_installation_instruction": "Коли ви відкриєте інсталятор DODI, натисніть на клавіатурі клавішу 'вгору' <0 />, щоб почати процес встановлення:",
|
||||
"dont_show_it_again": "Не показувати це знову",
|
||||
"copy_to_clipboard": "Копіювати",
|
||||
"copied_to_clipboard": "Скопійовано",
|
||||
"got_it": "Зрозуміло"
|
||||
"calculating_eta": "Обчислення залишкового часу…",
|
||||
"create_shortcut": "Створити ярлик на робочому столі",
|
||||
"danger_zone_section_description": "Видалити цю гру з вашої бібліотеки або файли скачані Hydra",
|
||||
"danger_zone_section_title": "Небезпечна зона",
|
||||
"download_in_progress": "Триває завантаження.",
|
||||
"download_options": "Варіантів завантаження",
|
||||
"download_path": "Тека для завантажень",
|
||||
"download_paused": "Завантаження призупинено",
|
||||
"download_settings": "Налаштування завантаження",
|
||||
"downloader": "Завантажувач",
|
||||
"downloads_secion_title": "Завантаження",
|
||||
"downloads_section_description": "Перевірити наявність оновлень або інших версій гри",
|
||||
"executable_section_description": "Шлях до файлу, який буде запущений при натисканні на кнопку \"Play\"",
|
||||
"executable_section_title": "Файл",
|
||||
"last_downloaded_option": "Останній варіант завантаження",
|
||||
"next_screenshot": "Наступний скрішнот",
|
||||
"no_executable_selected": "Файл не вибрано",
|
||||
"no_shop_details": "Не вдалося отримати опис",
|
||||
"open_download_location": "Переглянути папку завантажень",
|
||||
"open_folder": "Відкрити папку",
|
||||
"open_screenshot": "Відкрити скріншот",
|
||||
"options": "Налаштування",
|
||||
"paused": "Призупинено",
|
||||
"previous_screenshot": "Попередній скріншот",
|
||||
"remove_files": "Видалити файли",
|
||||
"remove_from_library_description": "{{game}} буде видалено з вашої бібліотеки",
|
||||
"remove_from_library_title": "Ви впевнені?",
|
||||
"screenshot": "Скріншот",
|
||||
"select_executable": "Обрати"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Активувати Hydra",
|
||||
"installation_id": "ID установки:",
|
||||
"enter_activation_code": "Введіть ваш активаційний код",
|
||||
"message": "Якщо ви не знаєте, де його запросити, то не повинні мати цього.",
|
||||
"message": "Якщо ви не знаєте, де його запросити, то не повинні мати його.",
|
||||
"activate": "Активувати",
|
||||
"loading": "Завантаження…"
|
||||
},
|
||||
@@ -112,22 +126,23 @@
|
||||
"eta": "Закінчення {{eta}}",
|
||||
"paused": "Призупинено",
|
||||
"verifying": "Перевірка…",
|
||||
"completed_at": "Завершено в {{date}}",
|
||||
"completed": "Завершено",
|
||||
"cancelled": "Скасовано",
|
||||
"download_again": "Завантажити знову",
|
||||
"cancel": "Скасувати",
|
||||
"filter": "Фільтр завантажених ігор",
|
||||
"remove": "Видалити",
|
||||
"downloading_metadata": "Завантаження метаданих…",
|
||||
"checking_files": "Перевірка файлів…",
|
||||
"starting_download": "Початок завантаження…",
|
||||
"deleting": "Видалення інсталятора…",
|
||||
"delete": "Видалити інсталятор",
|
||||
"remove_from_list": "Видалити",
|
||||
"delete_modal_title": "Ви впевнені?",
|
||||
"delete_modal_description": "Це видалить усі інсталяційні файли з вашого комп'ютера",
|
||||
"install": "Встановити"
|
||||
"install": "Встановити",
|
||||
"download_in_progress": "В процесі",
|
||||
"downloads_completed": "Завершено",
|
||||
"no_downloads_description": "Ви ще нічого не завантажили через Hydra, але ніколи не пізно почати.",
|
||||
"no_downloads_title": "Тут так пусто...",
|
||||
"queued": "В черзі",
|
||||
"queued_downloads": "Завантаження в черзі",
|
||||
"removed": "Не завантажено"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Тека завантажень",
|
||||
@@ -135,11 +150,45 @@
|
||||
"notifications": "Повідомлення",
|
||||
"enable_download_notifications": "Після завершення завантаження",
|
||||
"enable_repack_list_notifications": "Коли додається новий репак",
|
||||
"telemetry": "Телеметрія",
|
||||
"telemetry_description": "Відправляти анонімну статистику використання",
|
||||
"behavior": "Поведінка",
|
||||
"quit_app_instead_hiding": "Закривати програму замість того, щоб згортати її в трей",
|
||||
"launch_with_system": "Запускати програми із запуском комп'ютера"
|
||||
"quit_app_instead_hiding": "Закривати Hydra замість того, щоб згортати її в трей",
|
||||
"launch_with_system": "Запускати Hydra із запуском комп'ютера",
|
||||
"add_download_source": "Добавити джерело",
|
||||
"add_download_source_description": "Введіть посилання на .json-файл",
|
||||
"added_download_source": "Джерело для завантаження було додано",
|
||||
"changes_saved": "Зміни успішно збережено",
|
||||
"download_count_one": "{{countFormatted}} завантаження в списку",
|
||||
"download_count_other": "{{countFormatted}} завантажень в списку",
|
||||
"download_count_zero": "В списку немає завантажень",
|
||||
"download_options_one": "{{countFormatted}} доступний варіант завантаження",
|
||||
"download_options_other": "{{countFormatted}} доступних варіантів завантаження",
|
||||
"download_options_zero": "Немає доступних завантажень",
|
||||
"download_source_errored": "Помилка",
|
||||
"download_source_up_to_date": "Оновлено",
|
||||
"download_source_url": "Посилання на джерело",
|
||||
"download_sources": "Джерела для завантаження",
|
||||
"download_sources_description": "Hydra буде отримувати посилання для завантажень із цих джерел. URL має містити пряме посилання на .json-файл із посиланнями для завантажень.",
|
||||
"download_sources_synced": "Всі джерела для завантаження синхронізовано",
|
||||
"enable_real_debrid": "Включити Real-Debrid",
|
||||
"found_download_option_one": "Знайдено {{countFormatted}} варіант завантаження",
|
||||
"found_download_option_other": "Знайдено {{countFormatted}} варіантів завантаження",
|
||||
"found_download_option_zero": "Немає доступних завантажень",
|
||||
"general": "Основні",
|
||||
"import": "Імпортувати",
|
||||
"insert_valid_json_url": "Вставте дійсний URL JSON-файлу",
|
||||
"language": "Мова",
|
||||
"real_debrid_api_token": "API-токен",
|
||||
"real_debrid_api_token_hint": "API токен можливо отримати <0>тут</0>",
|
||||
"real_debrid_api_token_label": "Real-Debrid API-токен",
|
||||
"real_debrid_description": "Real-Debrid — це необмежений завантажувач, який дозволяє швидко завантажувати файли, розміщені в Інтернеті, або миттєво передавати їх у плеєр через приватну мережу, що дозволяє обходити будь-які блокування.",
|
||||
"real_debrid_free_account_error": "Акаунт \"{{username}}\" - не має наявної підписки. Будь ласка, оформіть підписку на Real-Debrid",
|
||||
"real_debrid_invalid_token": "Невірний API-токен",
|
||||
"real_debrid_linked_message": "Акаунт \"{{username}}\" привязаний",
|
||||
"remove_download_source": "Видалити",
|
||||
"removed_download_source": "Джерело завантажень було видалено",
|
||||
"save_changes": "Зберегти зміни",
|
||||
"sync_download_sources": "Синхронізувати джерела",
|
||||
"validate_download_source": "Перевірити"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Завантаження завершено",
|
||||
@@ -162,5 +211,30 @@
|
||||
},
|
||||
"modal": {
|
||||
"close": "Закрити"
|
||||
},
|
||||
"forms": {
|
||||
"toggle_password_visibility": "Показувати пароль"
|
||||
},
|
||||
"user_profile": {
|
||||
"activity": "Остання активність",
|
||||
"amount_hours": "{{amount}} годин",
|
||||
"amount_minutes": "{{amount}} хвилин",
|
||||
"cancel": "Скасувати",
|
||||
"display_name": "Відображуване ім'я",
|
||||
"edit_profile": "Редагувати профіль",
|
||||
"last_time_played": "Остання гра {{period}}",
|
||||
"library": "Бібліотека",
|
||||
"no_recent_activity_description": "Ви давно не грали в ігри. Пора це змінити!",
|
||||
"no_recent_activity_title": "Хммм... Тут нічого немає",
|
||||
"playing_for": "Зіграно {{amount}}",
|
||||
"save": "Збережено",
|
||||
"saved_successfully": "Успішно збережено",
|
||||
"saving": "Збереження",
|
||||
"sign_out": "Вийти",
|
||||
"sign_out_modal_text": "Ваша бібліотека пов'язана з поточним обліковим записом. При виході з системи ваша бібліотека буде недоступною, і прогрес не буде збережено. Продовжити вихід?",
|
||||
"sign_out_modal_title": "Ви впевнені?",
|
||||
"successfully_signed_out": "Успішний вихід з акаунту",
|
||||
"total_play_time": "Всього зіграно: {{amount}}",
|
||||
"try_again": "Будь ласка, попробуйте ще раз"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "特色推荐",
|
||||
"recently_added": "最近添加",
|
||||
"trending": "最近热门",
|
||||
"surprise_me": "向我推荐",
|
||||
"no_results": "没有找到结果"
|
||||
@@ -12,16 +11,10 @@
|
||||
"settings": "设置",
|
||||
"my_library": "我的游戏库",
|
||||
"downloading_metadata": "{{title}} (正在下载元数据…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - 正在检查文件…)",
|
||||
"paused": "{{title}} (已暂停)",
|
||||
"downloading": "{{title}} ({{percentage}} - 正在下载…)",
|
||||
"filter": "筛选游戏库",
|
||||
"follow_us": "关注我们",
|
||||
"home": "主页",
|
||||
"discord": "加入我们的Discord",
|
||||
"telegram": "加入我们的Telegram",
|
||||
"x": "在X上关注我们",
|
||||
"github": "在GitHub上贡献"
|
||||
"home": "主页"
|
||||
},
|
||||
"header": {
|
||||
"search": "搜索",
|
||||
@@ -34,7 +27,6 @@
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "没有正在进行的下载",
|
||||
"downloading_metadata": "正在下载{{title}}的元数据…",
|
||||
"checking_files": "正在检查{{title}}的文件… ({{percentage}}完成)",
|
||||
"downloading": "正在下载{{title}}… ({{percentage}}完成) - 剩余时间{{eta}} - 速度{{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
@@ -52,22 +44,15 @@
|
||||
"pause": "暂停",
|
||||
"cancel": "取消",
|
||||
"remove": "移除",
|
||||
"remove_from_list": "从列表中移除",
|
||||
"space_left_on_disk": "磁盘剩余空间{{space}}",
|
||||
"eta": "预计完成时间{{eta}}",
|
||||
"downloading_metadata": "正在下载元数据…",
|
||||
"checking_files": "正在检查文件…",
|
||||
"filter": "筛选重打包",
|
||||
"requirements": "配置要求",
|
||||
"minimum": "最低要求",
|
||||
"recommended": "推荐要求",
|
||||
"no_minimum_requirements": "{{title}}没有提供最低要求信息",
|
||||
"no_recommended_requirements": "{{title}}没有提供推荐要求信息",
|
||||
"paused_progress": "{{progress}} (已暂停)",
|
||||
"release_date": "发布于{{date}}",
|
||||
"publisher": "发行商{{publisher}}",
|
||||
"copy_link_to_clipboard": "复制链接",
|
||||
"copied_link_to_clipboard": "链接已复制",
|
||||
"hours": "小时",
|
||||
"minutes": "分钟",
|
||||
"amount_hours": "{{amount}}小时",
|
||||
@@ -86,17 +71,8 @@
|
||||
"playing_now": "正在游戏中",
|
||||
"change": "更改",
|
||||
"repacks_modal_description": "选择您想要下载的重打包",
|
||||
"downloads_path": "下载路径",
|
||||
"select_folder_hint": "要更改默认文件夹,请访问",
|
||||
"settings": "设置",
|
||||
"download_now": "立即下载",
|
||||
"installation_instructions": "安装说明",
|
||||
"installation_instructions_description": "安装这个游戏需要额外的步骤",
|
||||
"online_fix_instruction": "OnlineFix游戏需要密码才能解压。需要时,使用以下密码:",
|
||||
"dodi_installation_instruction": "打开DODI安装程序时,按键盘上的键<0 />开始安装过程:",
|
||||
"dont_show_it_again": "不再显示",
|
||||
"copied_to_clipboard": "已复制到剪贴板",
|
||||
"got_it": "我已知晓",
|
||||
"previous_screenshot": "上一张截图",
|
||||
"next_screenshot": "下一张截图",
|
||||
"screenshot": "截图 {{number}}",
|
||||
@@ -116,24 +92,16 @@
|
||||
"eta": "预计完成时间{{eta}}",
|
||||
"paused": "已暂停",
|
||||
"verifying": "正在验证…",
|
||||
"completed_at": "完成于{{date}}",
|
||||
"completed": "已完成",
|
||||
"cancelled": "已取消",
|
||||
"download_again": "再次下载",
|
||||
"cancel": "取消",
|
||||
"filter": "筛选已下载游戏",
|
||||
"remove": "移除",
|
||||
"downloading_metadata": "正在下载元数据…",
|
||||
"checking_files": "正在检查文件…",
|
||||
"starting_download": "开始下载…",
|
||||
"deleting": "正在删除安装程序…",
|
||||
"delete": "移除安装程序",
|
||||
"remove_from_list": "移除",
|
||||
"delete_modal_title": "您确定吗?",
|
||||
"delete_modal_description": "这将从您的电脑上移除所有的安装文件",
|
||||
"install": "安装",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "种子"
|
||||
"install": "安装"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "下载路径",
|
||||
@@ -141,15 +109,11 @@
|
||||
"notifications": "通知",
|
||||
"enable_download_notifications": "下载完成时",
|
||||
"enable_repack_list_notifications": "添加新重打包时",
|
||||
"telemetry": "遥测",
|
||||
"telemetry_description": "启用匿名使用统计",
|
||||
"real_debrid_api_token_description": "Real Debrid API密钥",
|
||||
"behavior": "行为",
|
||||
"general": "常规",
|
||||
"quit_app_instead_hiding": "关闭应用程序而不是最小化到托盘",
|
||||
"launch_with_system": "随系统启动时运行应用程序",
|
||||
"enable_real_debrid": "启用 Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"enable_real_debrid": "启用 Real-Debrid",
|
||||
"real_debrid_api_token_hint": "您可以从<0>这里</0>获取API密钥.",
|
||||
"save_changes": "保存更改"
|
||||
},
|
||||
|
||||
@@ -1,45 +1,16 @@
|
||||
import { app } from "electron";
|
||||
import path from "node:path";
|
||||
|
||||
export const repackersOn1337x = [
|
||||
"DODI",
|
||||
"FitGirl",
|
||||
"0xEMPRESS",
|
||||
"KaOsKrew",
|
||||
"TinyRepacks",
|
||||
] as const;
|
||||
|
||||
export const repackers = [
|
||||
...repackersOn1337x,
|
||||
"Xatab",
|
||||
"TinyRepacks",
|
||||
"CPG",
|
||||
"GOG",
|
||||
"onlinefix",
|
||||
] as const;
|
||||
|
||||
export const months = [
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mar",
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec",
|
||||
];
|
||||
|
||||
export const defaultDownloadsPath = app.getPath("downloads");
|
||||
|
||||
export const databasePath = path.join(
|
||||
app.getPath("appData"),
|
||||
app.getName(),
|
||||
"hydra",
|
||||
"hydra.db"
|
||||
);
|
||||
|
||||
export const INSTALLATION_ID_LENGTH = 6;
|
||||
export const ACTIVATION_KEY_MULTIPLIER = 7;
|
||||
export const logsPath = path.join(app.getPath("appData"), "hydra", "logs");
|
||||
|
||||
export const seedsPath = app.isPackaged
|
||||
? path.join(process.resourcesPath, "seeds")
|
||||
: path.join(__dirname, "..", "..", "seeds");
|
||||
|
||||
@@ -1,22 +1,37 @@
|
||||
import { DataSource } from "typeorm";
|
||||
import {
|
||||
DownloadQueue,
|
||||
DownloadSource,
|
||||
Game,
|
||||
GameShopCache,
|
||||
Repack,
|
||||
UserPreferences,
|
||||
SteamGame,
|
||||
} from "@main/entity";
|
||||
import type { SqliteConnectionOptions } from "typeorm/driver/sqlite/SqliteConnectionOptions";
|
||||
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<SqliteConnectionOptions>) =>
|
||||
export const createDataSource = (
|
||||
options: Partial<BetterSqlite3ConnectionOptions>
|
||||
) =>
|
||||
new DataSource({
|
||||
type: "better-sqlite3",
|
||||
database: databasePath,
|
||||
entities: [Game, Repack, UserPreferences, GameShopCache, SteamGame],
|
||||
entities: [
|
||||
Game,
|
||||
Repack,
|
||||
UserPreferences,
|
||||
GameShopCache,
|
||||
DownloadSource,
|
||||
DownloadQueue,
|
||||
UserAuth,
|
||||
],
|
||||
synchronize: true,
|
||||
database: databasePath,
|
||||
...options,
|
||||
});
|
||||
|
||||
export const dataSource = createDataSource({});
|
||||
export const dataSource = createDataSource({
|
||||
migrations,
|
||||
});
|
||||
|
||||
80
src/main/declaration.d.ts
vendored
Normal file
80
src/main/declaration.d.ts
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
25
src/main/entity/download-queue.entity.ts
Normal file
25
src/main/entity/download-queue.entity.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
OneToOne,
|
||||
JoinColumn,
|
||||
} from "typeorm";
|
||||
import type { Game } from "./game.entity";
|
||||
|
||||
@Entity("download_queue")
|
||||
export class DownloadQueue {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@OneToOne("Game", "downloadQueue")
|
||||
@JoinColumn()
|
||||
game: Game;
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updatedAt: Date;
|
||||
}
|
||||
41
src/main/entity/download-source.entity.ts
Normal file
41
src/main/entity/download-source.entity.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
OneToMany,
|
||||
} from "typeorm";
|
||||
import type { Repack } from "./repack.entity";
|
||||
|
||||
import { DownloadSourceStatus } from "@shared";
|
||||
|
||||
@Entity("download_source")
|
||||
export class DownloadSource {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column("text", { nullable: true, unique: true })
|
||||
url: string;
|
||||
|
||||
@Column("text")
|
||||
name: string;
|
||||
|
||||
@Column("text", { nullable: true })
|
||||
etag: string | null;
|
||||
|
||||
@Column("int", { default: 0 })
|
||||
downloadCount: number;
|
||||
|
||||
@Column("text", { default: DownloadSourceStatus.UpToDate })
|
||||
status: DownloadSourceStatus;
|
||||
|
||||
@OneToMany("Repack", "downloadSource", { cascade: true })
|
||||
repacks: Repack[];
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updatedAt: Date;
|
||||
}
|
||||
@@ -10,7 +10,9 @@ import {
|
||||
import { Repack } from "./repack.entity";
|
||||
|
||||
import type { GameShop } from "@types";
|
||||
import { Downloader, GameStatus } from "@shared";
|
||||
import { Downloader } from "@shared";
|
||||
import type { Aria2Status } from "aria2";
|
||||
import type { DownloadQueue } from "./download-queue.entity";
|
||||
|
||||
@Entity("game")
|
||||
export class Game {
|
||||
@@ -20,11 +22,14 @@ export class Game {
|
||||
@Column("text", { unique: true })
|
||||
objectID: string;
|
||||
|
||||
@Column("text", { unique: true, nullable: true })
|
||||
remoteId: string | null;
|
||||
|
||||
@Column("text")
|
||||
title: string;
|
||||
|
||||
@Column("text")
|
||||
iconUrl: string;
|
||||
@Column("text", { nullable: true })
|
||||
iconUrl: string | null;
|
||||
|
||||
@Column("text", { nullable: true })
|
||||
folderName: string | null;
|
||||
@@ -42,7 +47,7 @@ export class Game {
|
||||
shop: GameShop;
|
||||
|
||||
@Column("text", { nullable: true })
|
||||
status: GameStatus | null;
|
||||
status: Aria2Status | null;
|
||||
|
||||
@Column("int", { default: Downloader.Torrent })
|
||||
downloader: Downloader;
|
||||
@@ -53,22 +58,28 @@ export class Game {
|
||||
@Column("float", { default: 0 })
|
||||
progress: number;
|
||||
|
||||
@Column("float", { default: 0 })
|
||||
fileVerificationProgress: number;
|
||||
|
||||
@Column("int", { default: 0 })
|
||||
bytesDownloaded: number;
|
||||
|
||||
@Column("text", { nullable: true })
|
||||
@Column("datetime", { nullable: true })
|
||||
lastTimePlayed: Date | null;
|
||||
|
||||
@Column("float", { default: 0 })
|
||||
fileSize: number;
|
||||
|
||||
@OneToOne(() => Repack, { nullable: true })
|
||||
@Column("text", { nullable: true })
|
||||
uri: string | null;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@OneToOne("Repack", "game", { nullable: true })
|
||||
@JoinColumn()
|
||||
repack: Repack;
|
||||
|
||||
@OneToOne("DownloadQueue", "game")
|
||||
downloadQueue: DownloadQueue;
|
||||
|
||||
@Column("boolean", { default: false })
|
||||
isDeleted: boolean;
|
||||
|
||||
|
||||
@@ -2,4 +2,6 @@ export * from "./game.entity";
|
||||
export * from "./repack.entity";
|
||||
export * from "./user-preferences.entity";
|
||||
export * from "./game-shop-cache.entity";
|
||||
export * from "./steam-game.entity";
|
||||
export * from "./download-source.entity";
|
||||
export * from "./download-queue.entity";
|
||||
export * from "./user-auth";
|
||||
|
||||
@@ -4,7 +4,9 @@ import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
ManyToOne,
|
||||
} from "typeorm";
|
||||
import { DownloadSource } from "./download-source.entity";
|
||||
|
||||
@Entity("repack")
|
||||
export class Repack {
|
||||
@@ -17,7 +19,10 @@ export class Repack {
|
||||
@Column("text", { unique: true })
|
||||
magnet: string;
|
||||
|
||||
@Column("int")
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
@Column("int", { nullable: true })
|
||||
page: number;
|
||||
|
||||
@Column("text")
|
||||
@@ -29,6 +34,9 @@ export class Repack {
|
||||
@Column("datetime")
|
||||
uploadDate: Date | string;
|
||||
|
||||
@ManyToOne(() => DownloadSource, { nullable: true, onDelete: "CASCADE" })
|
||||
downloadSource: DownloadSource;
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Column, Entity, PrimaryColumn } from "typeorm";
|
||||
|
||||
@Entity("steam_game")
|
||||
export class SteamGame {
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@Column()
|
||||
name: string;
|
||||
}
|
||||
37
src/main/entity/user-auth.ts
Normal file
37
src/main/entity/user-auth.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
} from "typeorm";
|
||||
|
||||
@Entity("user_auth")
|
||||
export class UserAuth {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column("text", { default: "" })
|
||||
userId: string;
|
||||
|
||||
@Column("text", { default: "" })
|
||||
displayName: string;
|
||||
|
||||
@Column("text", { nullable: true })
|
||||
profileImageUrl: string | null;
|
||||
|
||||
@Column("text", { default: "" })
|
||||
accessToken: string;
|
||||
|
||||
@Column("text", { default: "" })
|
||||
refreshToken: string;
|
||||
|
||||
@Column("int", { default: 0 })
|
||||
tokenExpirationTimestamp: number;
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updatedAt: Date;
|
||||
}
|
||||
14
src/main/events/auth/get-session-hash.ts
Normal file
14
src/main/events/auth/get-session-hash.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
import { userAuthRepository } from "@main/repository";
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
const getSessionHash = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
const auth = await userAuthRepository.findOne({ where: { id: 1 } });
|
||||
|
||||
if (!auth) return null;
|
||||
const payload = jwt.decode(auth.accessToken) as jwt.JwtPayload;
|
||||
return payload.sessionId;
|
||||
};
|
||||
|
||||
registerEvent("getSessionHash", getSessionHash);
|
||||
7
src/main/events/auth/open-auth-window.ts
Normal file
7
src/main/events/auth/open-auth-window.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { WindowManager } from "@main/services";
|
||||
|
||||
const openAuthWindow = async (_event: Electron.IpcMainInvokeEvent) =>
|
||||
WindowManager.openAuthWindow();
|
||||
|
||||
registerEvent("openAuthWindow", openAuthWindow);
|
||||
31
src/main/events/auth/sign-out.ts
Normal file
31
src/main/events/auth/sign-out.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { DownloadManager, HydraApi, gamesPlaytime } from "@main/services";
|
||||
import { dataSource } from "@main/data-source";
|
||||
import { DownloadQueue, Game, UserAuth } from "@main/entity";
|
||||
|
||||
const signOut = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
const databaseOperations = dataSource
|
||||
.transaction(async (transactionalEntityManager) => {
|
||||
await transactionalEntityManager.getRepository(DownloadQueue).delete({});
|
||||
|
||||
await transactionalEntityManager.getRepository(Game).delete({});
|
||||
|
||||
await transactionalEntityManager
|
||||
.getRepository(UserAuth)
|
||||
.delete({ id: 1 });
|
||||
})
|
||||
.then(() => {
|
||||
/* Removes all games being played */
|
||||
gamesPlaytime.clear();
|
||||
});
|
||||
|
||||
/* Disconnects aria2 */
|
||||
DownloadManager.disconnect();
|
||||
|
||||
await Promise.all([
|
||||
databaseOperations,
|
||||
HydraApi.post("/auth/logout").catch(),
|
||||
]);
|
||||
};
|
||||
|
||||
registerEvent("signOut", signOut);
|
||||
42
src/main/events/autoupdater/check-for-updates.ts
Normal file
42
src/main/events/autoupdater/check-for-updates.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { AppUpdaterEvent } from "@types";
|
||||
import { registerEvent } from "../register-event";
|
||||
import updater, { UpdateInfo } from "electron-updater";
|
||||
import { WindowManager } from "@main/services";
|
||||
import { app } from "electron";
|
||||
|
||||
const { autoUpdater } = updater;
|
||||
|
||||
const sendEvent = (event: AppUpdaterEvent) => {
|
||||
WindowManager.mainWindow?.webContents.send("autoUpdaterEvent", event);
|
||||
};
|
||||
|
||||
const sendEventsForDebug = false;
|
||||
|
||||
const isAutoInstallAvailable =
|
||||
process.platform !== "darwin" && process.env.PORTABLE_EXECUTABLE_FILE == null;
|
||||
|
||||
const mockValuesForDebug = () => {
|
||||
sendEvent({ type: "update-available", info: { version: "1.3.0" } });
|
||||
sendEvent({ type: "update-downloaded" });
|
||||
};
|
||||
|
||||
const checkForUpdates = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
autoUpdater
|
||||
.once("update-available", (info: UpdateInfo) => {
|
||||
sendEvent({ type: "update-available", info });
|
||||
})
|
||||
.once("update-downloaded", () => {
|
||||
sendEvent({ type: "update-downloaded" });
|
||||
});
|
||||
|
||||
if (app.isPackaged) {
|
||||
autoUpdater.autoDownload = isAutoInstallAvailable;
|
||||
autoUpdater.checkForUpdates();
|
||||
} else if (sendEventsForDebug) {
|
||||
mockValuesForDebug();
|
||||
}
|
||||
|
||||
return isAutoInstallAvailable;
|
||||
};
|
||||
|
||||
registerEvent("checkForUpdates", checkForUpdates);
|
||||
14
src/main/events/autoupdater/restart-and-install-update.ts
Normal file
14
src/main/events/autoupdater/restart-and-install-update.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { app } from "electron";
|
||||
import { registerEvent } from "../register-event";
|
||||
import updater from "electron-updater";
|
||||
|
||||
const { autoUpdater } = updater;
|
||||
|
||||
const restartAndInstallUpdate = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
autoUpdater.removeAllListeners();
|
||||
if (app.isPackaged) {
|
||||
autoUpdater.quitAndInstall(true, true);
|
||||
}
|
||||
};
|
||||
|
||||
registerEvent("restartAndInstallUpdate", restartAndInstallUpdate);
|
||||
@@ -1,95 +1,36 @@
|
||||
import { formatName, getSteamAppAsset, repackerFormatter } from "@main/helpers";
|
||||
import type { CatalogueCategory, CatalogueEntry, GameShop } from "@types";
|
||||
import { getSteamAppAsset } from "@main/helpers";
|
||||
import type { CatalogueEntry, GameShop } from "@types";
|
||||
|
||||
import { stateManager } from "@main/state-manager";
|
||||
import { searchGames, searchRepacks } from "../helpers/search-games";
|
||||
import { registerEvent } from "../register-event";
|
||||
import { requestSteam250 } from "@main/services";
|
||||
|
||||
const repacks = stateManager.getValue("repacks");
|
||||
|
||||
const getStringForLookup = (index: number): string => {
|
||||
const repack = repacks[index];
|
||||
const formatter =
|
||||
repackerFormatter[repack.repacker as keyof typeof repackerFormatter];
|
||||
|
||||
return formatName(formatter(repack.title));
|
||||
};
|
||||
import { RepacksManager, requestSteam250 } from "@main/services";
|
||||
import { formatName } from "@shared";
|
||||
|
||||
const resultSize = 12;
|
||||
|
||||
const getCatalogue = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
category: CatalogueCategory
|
||||
) => {
|
||||
if (!repacks.length) return [];
|
||||
|
||||
if (category === "trending") {
|
||||
return getTrendingCatalogue(resultSize);
|
||||
}
|
||||
|
||||
return getRecentlyAddedCatalogue(resultSize);
|
||||
};
|
||||
|
||||
const getTrendingCatalogue = async (
|
||||
resultSize: number
|
||||
): Promise<CatalogueEntry[]> => {
|
||||
const results: CatalogueEntry[] = [];
|
||||
const getCatalogue = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
const trendingGames = await requestSteam250("/90day");
|
||||
|
||||
for (
|
||||
let i = 0;
|
||||
i < trendingGames.length && results.length < resultSize;
|
||||
i++
|
||||
) {
|
||||
if (!trendingGames[i]) continue;
|
||||
|
||||
const { title, objectID } = trendingGames[i]!;
|
||||
const repacks = searchRepacks(title);
|
||||
|
||||
if (title && repacks.length) {
|
||||
const catalogueEntry = {
|
||||
objectID,
|
||||
title,
|
||||
shop: "steam" as GameShop,
|
||||
cover: getSteamAppAsset("library", objectID),
|
||||
};
|
||||
|
||||
results.push({ ...catalogueEntry, repacks });
|
||||
}
|
||||
}
|
||||
return results;
|
||||
};
|
||||
|
||||
const getRecentlyAddedCatalogue = async (
|
||||
resultSize: number
|
||||
): Promise<CatalogueEntry[]> => {
|
||||
const results: CatalogueEntry[] = [];
|
||||
|
||||
for (let i = 0; results.length < resultSize; i++) {
|
||||
const stringForLookup = getStringForLookup(i);
|
||||
|
||||
if (!stringForLookup) {
|
||||
for (let i = 0; i < resultSize; i++) {
|
||||
if (!trendingGames[i]) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const games = searchGames({ query: stringForLookup });
|
||||
const { title, objectID } = trendingGames[i]!;
|
||||
const repacks = RepacksManager.search({ query: formatName(title) });
|
||||
|
||||
for (const game of games) {
|
||||
const isAlreadyIncluded = results.some(
|
||||
(result) => result.objectID === game?.objectID
|
||||
);
|
||||
const catalogueEntry = {
|
||||
objectID,
|
||||
title,
|
||||
shop: "steam" as GameShop,
|
||||
cover: getSteamAppAsset("library", objectID),
|
||||
};
|
||||
|
||||
if (!game || !game.repacks.length || isAlreadyIncluded) {
|
||||
continue;
|
||||
}
|
||||
|
||||
results.push(game);
|
||||
}
|
||||
results.push({ ...catalogueEntry, repacks });
|
||||
}
|
||||
|
||||
return results.slice(0, resultSize);
|
||||
return results;
|
||||
};
|
||||
|
||||
registerEvent("getCatalogue", getCatalogue);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { gameShopCacheRepository, steamGameRepository } from "@main/repository";
|
||||
import { gameShopCacheRepository } from "@main/repository";
|
||||
import { getSteamAppDetails } from "@main/services";
|
||||
|
||||
import type { ShopDetails, GameShop, SteamAppDetails } from "@types";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
import { steamGamesWorker } from "@main/workers";
|
||||
|
||||
const getLocalizedSteamAppDetails = (
|
||||
const getLocalizedSteamAppDetails = async (
|
||||
objectID: string,
|
||||
language: string
|
||||
): Promise<ShopDetails | null> => {
|
||||
@@ -13,19 +14,22 @@ const getLocalizedSteamAppDetails = (
|
||||
return getSteamAppDetails(objectID, language);
|
||||
}
|
||||
|
||||
return Promise.all([
|
||||
steamGameRepository.findOne({ where: { id: Number(objectID) } }),
|
||||
getSteamAppDetails(objectID, language),
|
||||
]).then(([steamGame, localizedAppDetails]) => {
|
||||
if (steamGame && localizedAppDetails) {
|
||||
return {
|
||||
...localizedAppDetails,
|
||||
name: steamGame.name,
|
||||
};
|
||||
}
|
||||
return getSteamAppDetails(objectID, language).then(
|
||||
async (localizedAppDetails) => {
|
||||
const steamGame = await steamGamesWorker.run(Number(objectID), {
|
||||
name: "getById",
|
||||
});
|
||||
|
||||
return null;
|
||||
});
|
||||
if (steamGame && localizedAppDetails) {
|
||||
return {
|
||||
...localizedAppDetails,
|
||||
name: steamGame.name,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const getGameShopDetails = async (
|
||||
|
||||
@@ -1,39 +1,28 @@
|
||||
import type { CatalogueEntry, GameShop } from "@types";
|
||||
import type { CatalogueEntry } from "@types";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
import { searchRepacks } from "../helpers/search-games";
|
||||
import { stateManager } from "@main/state-manager";
|
||||
import { getSteamAppAsset } from "@main/helpers";
|
||||
|
||||
const steamGames = stateManager.getValue("steamGames");
|
||||
import { steamGamesWorker } from "@main/workers";
|
||||
import { convertSteamGameToCatalogueEntry } from "../helpers/search-games";
|
||||
import { RepacksManager } from "@main/services";
|
||||
|
||||
const getGames = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
take = 12,
|
||||
cursor = 0
|
||||
): Promise<{ results: CatalogueEntry[]; cursor: number }> => {
|
||||
const results: CatalogueEntry[] = [];
|
||||
const steamGames = await steamGamesWorker.run(
|
||||
{ limit: take, offset: cursor },
|
||||
{ name: "list" }
|
||||
);
|
||||
|
||||
let i = 0 + cursor;
|
||||
const entries = RepacksManager.findRepacksForCatalogueEntries(
|
||||
steamGames.map((game) => convertSteamGameToCatalogueEntry(game))
|
||||
);
|
||||
|
||||
while (results.length < take) {
|
||||
const game = steamGames[i];
|
||||
const repacks = searchRepacks(game.name);
|
||||
|
||||
if (repacks.length) {
|
||||
results.push({
|
||||
objectID: String(game.id),
|
||||
title: game.name,
|
||||
shop: "steam" as GameShop,
|
||||
cover: getSteamAppAsset("library", String(game.id)),
|
||||
repacks,
|
||||
});
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return { results, cursor: i };
|
||||
return {
|
||||
results: entries,
|
||||
cursor: cursor + entries.length,
|
||||
};
|
||||
};
|
||||
|
||||
registerEvent("getGames", getGames);
|
||||
|
||||
@@ -3,21 +3,34 @@ import { shuffle } from "lodash-es";
|
||||
import { getSteam250List } from "@main/services";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
import { searchGames, searchRepacks } from "../helpers/search-games";
|
||||
import { searchSteamGames } from "../helpers/search-games";
|
||||
import type { Steam250Game } from "@types";
|
||||
|
||||
const state = { games: Array<Steam250Game>(), index: 0 };
|
||||
|
||||
const filterGames = async (games: Steam250Game[]) => {
|
||||
const results: Steam250Game[] = [];
|
||||
|
||||
for (const game of games) {
|
||||
const catalogue = await searchSteamGames({ query: game.title });
|
||||
|
||||
if (catalogue.length) {
|
||||
const [steamGame] = catalogue;
|
||||
|
||||
if (steamGame.repacks.length) {
|
||||
results.push(game);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
const getRandomGame = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
if (state.games.length == 0) {
|
||||
const steam250List = await getSteam250List();
|
||||
|
||||
const filteredSteam250List = steam250List.filter((game) => {
|
||||
const repacks = searchRepacks(game.title);
|
||||
const catalogue = searchGames({ query: game.title });
|
||||
|
||||
return repacks.length && catalogue.length;
|
||||
});
|
||||
const filteredSteam250List = await filterGames(steam250List);
|
||||
|
||||
state.games = shuffle(filteredSteam250List);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { searchRepacks } from "../helpers/search-games";
|
||||
import { RepacksManager } from "@main/services";
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
const searchGameRepacks = (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
query: string
|
||||
) => {
|
||||
return searchRepacks(query);
|
||||
};
|
||||
) => RepacksManager.search({ query });
|
||||
|
||||
registerEvent("searchGameRepacks", searchGameRepacks);
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { searchGames } from "../helpers/search-games";
|
||||
import { searchSteamGames } from "../helpers/search-games";
|
||||
import { CatalogueEntry } from "@types";
|
||||
|
||||
const searchGamesEvent = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
query: string
|
||||
): Promise<CatalogueEntry[]> => {
|
||||
return searchGames({ query, take: 12 });
|
||||
};
|
||||
): Promise<CatalogueEntry[]> => searchSteamGames({ query, limit: 12 });
|
||||
|
||||
registerEvent("searchGames", searchGamesEvent);
|
||||
|
||||
42
src/main/events/download-sources/add-download-source.ts
Normal file
42
src/main/events/download-sources/add-download-source.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { dataSource } from "@main/data-source";
|
||||
import { DownloadSource } from "@main/entity";
|
||||
import axios from "axios";
|
||||
import { downloadSourceSchema } from "../helpers/validators";
|
||||
import { insertDownloadsFromSource } from "@main/helpers";
|
||||
import { RepacksManager } from "@main/services";
|
||||
|
||||
const addDownloadSource = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
url: string
|
||||
) => {
|
||||
const response = await axios.get(url);
|
||||
|
||||
const source = downloadSourceSchema.parse(response.data);
|
||||
|
||||
const downloadSource = await dataSource.transaction(
|
||||
async (transactionalEntityManager) => {
|
||||
const downloadSource = await transactionalEntityManager
|
||||
.getRepository(DownloadSource)
|
||||
.save({
|
||||
url,
|
||||
name: source.name,
|
||||
downloadCount: source.downloads.length,
|
||||
});
|
||||
|
||||
await insertDownloadsFromSource(
|
||||
transactionalEntityManager,
|
||||
downloadSource,
|
||||
source.downloads
|
||||
);
|
||||
|
||||
return downloadSource;
|
||||
}
|
||||
);
|
||||
|
||||
await RepacksManager.updateRepacks();
|
||||
|
||||
return downloadSource;
|
||||
};
|
||||
|
||||
registerEvent("addDownloadSource", addDownloadSource);
|
||||
16
src/main/events/download-sources/get-download-sources.ts
Normal file
16
src/main/events/download-sources/get-download-sources.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
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();
|
||||
};
|
||||
|
||||
registerEvent("getDownloadSources", getDownloadSources);
|
||||
13
src/main/events/download-sources/remove-download-source.ts
Normal file
13
src/main/events/download-sources/remove-download-source.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { downloadSourceRepository } from "@main/repository";
|
||||
import { registerEvent } from "../register-event";
|
||||
import { RepacksManager } from "@main/services";
|
||||
|
||||
const removeDownloadSource = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
id: number
|
||||
) => {
|
||||
await downloadSourceRepository.delete(id);
|
||||
await RepacksManager.updateRepacks();
|
||||
};
|
||||
|
||||
registerEvent("removeDownloadSource", removeDownloadSource);
|
||||
@@ -0,0 +1,7 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { fetchDownloadSourcesAndUpdate } from "@main/helpers";
|
||||
|
||||
const syncDownloadSources = async (_event: Electron.IpcMainInvokeEvent) =>
|
||||
fetchDownloadSourcesAndUpdate();
|
||||
|
||||
registerEvent("syncDownloadSources", syncDownloadSources);
|
||||
34
src/main/events/download-sources/validate-download-source.ts
Normal file
34
src/main/events/download-sources/validate-download-source.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import axios from "axios";
|
||||
import { downloadSourceRepository } from "@main/repository";
|
||||
import { downloadSourceSchema } from "../helpers/validators";
|
||||
import { RepacksManager } from "@main/services";
|
||||
|
||||
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 },
|
||||
});
|
||||
|
||||
if (existingSource)
|
||||
throw new Error("Source with the same url already exists");
|
||||
|
||||
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,
|
||||
};
|
||||
};
|
||||
|
||||
registerEvent("validateDownloadSource", validateDownloadSource);
|
||||
@@ -1,40 +1,11 @@
|
||||
import flexSearch from "flexsearch";
|
||||
import { orderBy } from "lodash-es";
|
||||
import flexSearch from "flexsearch";
|
||||
|
||||
import type { GameRepack, GameShop, CatalogueEntry } from "@types";
|
||||
import type { GameShop, CatalogueEntry, SteamGame } from "@types";
|
||||
|
||||
import { formatName, getSteamAppAsset, repackerFormatter } from "@main/helpers";
|
||||
import { stateManager } from "@main/state-manager";
|
||||
|
||||
const { Index } = flexSearch;
|
||||
const repacksIndex = new Index();
|
||||
const steamGamesIndex = new Index({ tokenize: "forward" });
|
||||
|
||||
const repacks = stateManager.getValue("repacks");
|
||||
const steamGames = stateManager.getValue("steamGames");
|
||||
|
||||
for (let i = 0; i < repacks.length; i++) {
|
||||
const repack = repacks[i];
|
||||
const formatter =
|
||||
repackerFormatter[repack.repacker as keyof typeof repackerFormatter];
|
||||
|
||||
repacksIndex.add(i, formatName(formatter(repack.title)));
|
||||
}
|
||||
|
||||
for (let i = 0; i < steamGames.length; i++) {
|
||||
const steamGame = steamGames[i];
|
||||
steamGamesIndex.add(i, formatName(steamGame.name));
|
||||
}
|
||||
|
||||
export const searchRepacks = (title: string): GameRepack[] => {
|
||||
return orderBy(
|
||||
repacksIndex
|
||||
.search(formatName(title))
|
||||
.map((index) => repacks.at(index as number)!),
|
||||
["uploadDate"],
|
||||
"desc"
|
||||
);
|
||||
};
|
||||
import { getSteamAppAsset } from "@main/helpers";
|
||||
import { steamGamesWorker } from "@main/workers";
|
||||
import { RepacksManager } from "@main/services";
|
||||
|
||||
export interface SearchGamesArgs {
|
||||
query?: string;
|
||||
@@ -42,27 +13,29 @@ export interface SearchGamesArgs {
|
||||
skip?: number;
|
||||
}
|
||||
|
||||
export const searchGames = ({
|
||||
query,
|
||||
take,
|
||||
skip,
|
||||
}: SearchGamesArgs): CatalogueEntry[] => {
|
||||
const results = steamGamesIndex
|
||||
.search(formatName(query || ""), { limit: take, offset: skip })
|
||||
.map((index) => {
|
||||
const result = steamGames.at(index as number)!;
|
||||
export const convertSteamGameToCatalogueEntry = (
|
||||
game: SteamGame
|
||||
): CatalogueEntry => ({
|
||||
objectID: String(game.id),
|
||||
title: game.name,
|
||||
shop: "steam" as GameShop,
|
||||
cover: getSteamAppAsset("library", String(game.id)),
|
||||
repacks: [],
|
||||
});
|
||||
|
||||
return {
|
||||
objectID: String(result.id),
|
||||
title: result.name,
|
||||
shop: "steam" as GameShop,
|
||||
cover: getSteamAppAsset("library", String(result.id)),
|
||||
repacks: searchRepacks(result.name),
|
||||
};
|
||||
});
|
||||
export const searchSteamGames = async (
|
||||
options: flexSearch.SearchOptions
|
||||
): Promise<CatalogueEntry[]> => {
|
||||
const steamGames = (await steamGamesWorker.run(options, {
|
||||
name: "search",
|
||||
})) as SteamGame[];
|
||||
|
||||
const result = RepacksManager.findRepacksForCatalogueEntries(
|
||||
steamGames.map((game) => convertSteamGameToCatalogueEntry(game))
|
||||
);
|
||||
|
||||
return orderBy(
|
||||
results,
|
||||
result,
|
||||
[({ repacks }) => repacks.length, "repacks"],
|
||||
["desc"]
|
||||
);
|
||||
|
||||
13
src/main/events/helpers/validators.ts
Normal file
13
src/main/events/helpers/validators.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const downloadSourceSchema = z.object({
|
||||
name: z.string().max(255),
|
||||
downloads: z.array(
|
||||
z.object({
|
||||
title: z.string().max(255),
|
||||
uris: z.array(z.string()),
|
||||
uploadDate: z.string().max(255),
|
||||
fileSize: z.string().max(255),
|
||||
})
|
||||
),
|
||||
});
|
||||
@@ -10,14 +10,19 @@ import "./catalogue/search-games";
|
||||
import "./catalogue/search-game-repacks";
|
||||
import "./hardware/get-disk-free-space";
|
||||
import "./library/add-game-to-library";
|
||||
import "./library/create-game-shortcut";
|
||||
import "./library/close-game";
|
||||
import "./library/delete-game-folder";
|
||||
import "./library/get-game-by-object-id";
|
||||
import "./library/get-library";
|
||||
import "./library/open-game";
|
||||
import "./library/open-game-executable-path";
|
||||
import "./library/open-game-installer";
|
||||
import "./library/open-game-installer-path";
|
||||
import "./library/update-executable-path";
|
||||
import "./library/remove-game";
|
||||
import "./library/remove-game-from-library";
|
||||
import "./misc/is-user-logged-in";
|
||||
import "./misc/open-external";
|
||||
import "./misc/show-open-dialog";
|
||||
import "./torrenting/cancel-game-download";
|
||||
@@ -27,6 +32,20 @@ import "./torrenting/start-game-download";
|
||||
import "./user-preferences/get-user-preferences";
|
||||
import "./user-preferences/update-user-preferences";
|
||||
import "./user-preferences/auto-launch";
|
||||
import "./autoupdater/check-for-updates";
|
||||
import "./autoupdater/restart-and-install-update";
|
||||
import "./user-preferences/authenticate-real-debrid";
|
||||
import "./download-sources/get-download-sources";
|
||||
import "./download-sources/validate-download-source";
|
||||
import "./download-sources/add-download-source";
|
||||
import "./download-sources/remove-download-source";
|
||||
import "./download-sources/sync-download-sources";
|
||||
import "./auth/sign-out";
|
||||
import "./auth/open-auth-window";
|
||||
import "./auth/get-session-hash";
|
||||
import "./user/get-user";
|
||||
import "./profile/get-me";
|
||||
import "./profile/update-profile";
|
||||
|
||||
ipcMain.handle("ping", () => "pong");
|
||||
ipcMain.handle("getVersion", () => app.getVersion());
|
||||
|
||||
@@ -3,15 +3,16 @@ import { gameRepository } from "@main/repository";
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
import type { GameShop } from "@types";
|
||||
import { getFileBase64 } from "@main/helpers";
|
||||
import { getSteamGameIconUrl } from "@main/services";
|
||||
import { getFileBase64, getSteamAppAsset } from "@main/helpers";
|
||||
|
||||
import { steamGamesWorker } from "@main/workers";
|
||||
import { createGame } from "@main/services/library-sync";
|
||||
|
||||
const addGameToLibrary = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
objectID: string,
|
||||
title: string,
|
||||
gameShop: GameShop,
|
||||
executablePath: string | null
|
||||
shop: GameShop
|
||||
) => {
|
||||
return gameRepository
|
||||
.update(
|
||||
@@ -19,26 +20,51 @@ const addGameToLibrary = async (
|
||||
objectID,
|
||||
},
|
||||
{
|
||||
shop: gameShop,
|
||||
shop,
|
||||
status: null,
|
||||
executablePath,
|
||||
isDeleted: false,
|
||||
}
|
||||
)
|
||||
.then(async ({ affected }) => {
|
||||
if (!affected) {
|
||||
const iconUrl = await getFileBase64(
|
||||
await getSteamGameIconUrl(objectID)
|
||||
);
|
||||
|
||||
await gameRepository.insert({
|
||||
title,
|
||||
iconUrl,
|
||||
objectID,
|
||||
shop: gameShop,
|
||||
executablePath,
|
||||
const steamGame = await steamGamesWorker.run(Number(objectID), {
|
||||
name: "getById",
|
||||
});
|
||||
|
||||
const iconUrl = steamGame?.clientIcon
|
||||
? getSteamAppAsset("icon", objectID, steamGame.clientIcon)
|
||||
: null;
|
||||
|
||||
await gameRepository
|
||||
.insert({
|
||||
title,
|
||||
iconUrl,
|
||||
objectID,
|
||||
shop,
|
||||
})
|
||||
.then(() => {
|
||||
if (iconUrl) {
|
||||
getFileBase64(iconUrl).then((base64) =>
|
||||
gameRepository.update({ objectID }, { iconUrl: base64 })
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const game = await gameRepository.findOne({ where: { objectID } });
|
||||
|
||||
createGame(game!).then((response) => {
|
||||
const {
|
||||
id: remoteId,
|
||||
playTimeInMilliseconds,
|
||||
lastTimePlayed,
|
||||
} = response.data;
|
||||
|
||||
gameRepository.update(
|
||||
{ objectID },
|
||||
{ remoteId, playTimeInMilliseconds, lastTimePlayed }
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
38
src/main/events/library/create-game-shortcut.ts
Normal file
38
src/main/events/library/create-game-shortcut.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { gameRepository } from "@main/repository";
|
||||
import { registerEvent } from "../register-event";
|
||||
import { IsNull, Not } from "typeorm";
|
||||
import createDesktopShortcut from "create-desktop-shortcuts";
|
||||
import path from "node:path";
|
||||
import { app } from "electron";
|
||||
|
||||
const createGameShortcut = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
id: number
|
||||
): Promise<boolean> => {
|
||||
const game = await gameRepository.findOne({
|
||||
where: { id, executablePath: Not(IsNull()) },
|
||||
});
|
||||
|
||||
if (game) {
|
||||
const filePath = game.executablePath;
|
||||
|
||||
const windowVbsPath = app.isPackaged
|
||||
? path.join(process.resourcesPath, "windows.vbs")
|
||||
: undefined;
|
||||
|
||||
const options = {
|
||||
filePath,
|
||||
name: game.title,
|
||||
};
|
||||
|
||||
return createDesktopShortcut({
|
||||
windows: { ...options, VBScriptPath: windowVbsPath },
|
||||
linux: options,
|
||||
osx: options,
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
registerEvent("createGameShortcut", createGameShortcut);
|
||||
@@ -1,7 +1,6 @@
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
|
||||
import { GameStatus } from "@shared";
|
||||
import { gameRepository } from "@main/repository";
|
||||
|
||||
import { getDownloadsPath } from "../helpers/get-downloads-path";
|
||||
@@ -13,11 +12,18 @@ const deleteGameFolder = async (
|
||||
gameId: number
|
||||
): Promise<void> => {
|
||||
const game = await gameRepository.findOne({
|
||||
where: {
|
||||
id: gameId,
|
||||
status: GameStatus.Cancelled,
|
||||
isDeleted: false,
|
||||
},
|
||||
where: [
|
||||
{
|
||||
id: gameId,
|
||||
isDeleted: false,
|
||||
status: "removed",
|
||||
},
|
||||
{
|
||||
id: gameId,
|
||||
progress: 1,
|
||||
isDeleted: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (!game) return;
|
||||
@@ -29,7 +35,7 @@ const deleteGameFolder = async (
|
||||
);
|
||||
|
||||
if (fs.existsSync(folderPath)) {
|
||||
return new Promise((resolve, reject) => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
fs.rm(
|
||||
folderPath,
|
||||
{ recursive: true, force: true, maxRetries: 5, retryDelay: 200 },
|
||||
@@ -39,12 +45,21 @@ const deleteGameFolder = async (
|
||||
reject();
|
||||
}
|
||||
|
||||
const aria2ControlFilePath = `${folderPath}.aria2`;
|
||||
if (fs.existsSync(aria2ControlFilePath))
|
||||
fs.rmSync(aria2ControlFilePath);
|
||||
|
||||
resolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await gameRepository.update(
|
||||
{ id: gameId },
|
||||
{ downloadPath: null, folderName: null, status: null, progress: 0 }
|
||||
);
|
||||
};
|
||||
|
||||
registerEvent("deleteGameFolder", deleteGameFolder);
|
||||
|
||||
@@ -11,9 +11,6 @@ const getGameByObjectID = async (
|
||||
objectID,
|
||||
isDeleted: false,
|
||||
},
|
||||
relations: {
|
||||
repack: true,
|
||||
},
|
||||
});
|
||||
|
||||
registerEvent("getGameByObjectID", getGameByObjectID);
|
||||
|
||||
@@ -1,31 +1,17 @@
|
||||
import { gameRepository } from "@main/repository";
|
||||
|
||||
import { searchRepacks } from "../helpers/search-games";
|
||||
import { registerEvent } from "../register-event";
|
||||
import { GameStatus } from "@shared";
|
||||
import { sortBy } from "lodash-es";
|
||||
|
||||
const getLibrary = async () =>
|
||||
gameRepository
|
||||
.find({
|
||||
where: {
|
||||
isDeleted: false,
|
||||
},
|
||||
order: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
relations: {
|
||||
repack: true,
|
||||
},
|
||||
})
|
||||
.then((games) =>
|
||||
sortBy(
|
||||
games.map((game) => ({
|
||||
...game,
|
||||
repacks: searchRepacks(game.title),
|
||||
})),
|
||||
(game) => (game.status !== GameStatus.Cancelled ? 0 : 1)
|
||||
)
|
||||
);
|
||||
gameRepository.find({
|
||||
where: {
|
||||
isDeleted: false,
|
||||
},
|
||||
relations: {
|
||||
downloadQueue: true,
|
||||
},
|
||||
order: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
});
|
||||
|
||||
registerEvent("getLibrary", getLibrary);
|
||||
|
||||
18
src/main/events/library/open-game-executable-path.ts
Normal file
18
src/main/events/library/open-game-executable-path.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { shell } from "electron";
|
||||
import { gameRepository } from "@main/repository";
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
const openGameExecutablePath = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
gameId: number
|
||||
) => {
|
||||
const game = await gameRepository.findOne({
|
||||
where: { id: gameId, isDeleted: false },
|
||||
});
|
||||
|
||||
if (!game || !game.executablePath) return;
|
||||
|
||||
shell.showItemInFolder(game.executablePath);
|
||||
};
|
||||
|
||||
registerEvent("openGameExecutablePath", openGameExecutablePath);
|
||||
27
src/main/events/library/open-game-installer-path.ts
Normal file
27
src/main/events/library/open-game-installer-path.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { shell } from "electron";
|
||||
import path from "node:path";
|
||||
import { gameRepository } from "@main/repository";
|
||||
import { getDownloadsPath } from "../helpers/get-downloads-path";
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
const openGameInstallerPath = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
gameId: number
|
||||
) => {
|
||||
const game = await gameRepository.findOne({
|
||||
where: { id: gameId, isDeleted: false },
|
||||
});
|
||||
|
||||
if (!game || !game.folderName || !game.downloadPath) return true;
|
||||
|
||||
const gamePath = path.join(
|
||||
game.downloadPath ?? (await getDownloadsPath()),
|
||||
game.folderName!
|
||||
);
|
||||
|
||||
shell.showItemInFolder(gamePath);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
registerEvent("openGameInstallerPath", openGameInstallerPath);
|
||||
@@ -1,13 +1,28 @@
|
||||
import { gameRepository } from "@main/repository";
|
||||
import { generateYML } from "../helpers/generate-lutris-yaml";
|
||||
import { shell } from "electron";
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { spawnSync, exec } from "node:child_process";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
import { shell } from "electron";
|
||||
import { gameRepository } from "@main/repository";
|
||||
|
||||
import { generateYML } from "../helpers/generate-lutris-yaml";
|
||||
import { getDownloadsPath } from "../helpers/get-downloads-path";
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
const executeGameInstaller = (filePath: string) => {
|
||||
if (process.platform === "win32") {
|
||||
shell.openPath(filePath);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (spawnSync("which", ["wine"]).status === 0) {
|
||||
exec(`wine "${filePath}"`);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const openGameInstaller = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
@@ -17,7 +32,7 @@ const openGameInstaller = async (
|
||||
where: { id: gameId, isDeleted: false },
|
||||
});
|
||||
|
||||
if (!game) return true;
|
||||
if (!game || !game.folderName) return true;
|
||||
|
||||
const gamePath = path.join(
|
||||
game.downloadPath ?? (await getDownloadsPath()),
|
||||
@@ -29,15 +44,29 @@ const openGameInstaller = async (
|
||||
return true;
|
||||
}
|
||||
|
||||
const setupPath = path.join(gamePath, "setup.exe");
|
||||
if (!fs.existsSync(setupPath)) {
|
||||
if (process.platform === "darwin") {
|
||||
shell.openPath(gamePath);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (process.platform === "win32") {
|
||||
shell.openPath(setupPath);
|
||||
return true;
|
||||
if (fs.lstatSync(gamePath).isFile()) {
|
||||
return executeGameInstaller(gamePath);
|
||||
}
|
||||
|
||||
const setupPath = path.join(gamePath, "setup.exe");
|
||||
if (fs.existsSync(setupPath)) {
|
||||
return executeGameInstaller(setupPath);
|
||||
}
|
||||
|
||||
const gamePathFileNames = fs.readdirSync(gamePath);
|
||||
const gamePathExecutableFiles = gamePathFileNames.filter(
|
||||
(fileName: string) => path.extname(fileName).toLowerCase() === ".exe"
|
||||
);
|
||||
|
||||
if (gamePathExecutableFiles.length === 1) {
|
||||
return executeGameInstaller(
|
||||
path.join(gamePath, gamePathExecutableFiles[0])
|
||||
);
|
||||
}
|
||||
|
||||
if (spawnSync("which", ["lutris"]).status === 0) {
|
||||
@@ -47,12 +76,8 @@ const openGameInstaller = async (
|
||||
return true;
|
||||
}
|
||||
|
||||
if (spawnSync("which", ["wine"]).status === 0) {
|
||||
exec(`wine "${setupPath}"`);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
shell.openPath(gamePath);
|
||||
return true;
|
||||
};
|
||||
|
||||
registerEvent("openGameInstaller", openGameInstaller);
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { gameRepository } from "../../repository";
|
||||
import { HydraApi, logger } from "@main/services";
|
||||
|
||||
const removeGameFromLibrary = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
gameId: number
|
||||
) => {
|
||||
gameRepository.update({ id: gameId }, { isDeleted: true });
|
||||
gameRepository.update(
|
||||
{ id: gameId },
|
||||
{ isDeleted: true, executablePath: null }
|
||||
);
|
||||
|
||||
removeRemoveGameFromLibrary(gameId).catch((err) => {
|
||||
logger.error("removeRemoveGameFromLibrary", err);
|
||||
});
|
||||
};
|
||||
|
||||
const removeRemoveGameFromLibrary = async (gameId: number) => {
|
||||
const game = await gameRepository.findOne({ where: { id: gameId } });
|
||||
|
||||
if (game?.remoteId) {
|
||||
HydraApi.delete(`/games/${game.remoteId}`);
|
||||
}
|
||||
};
|
||||
|
||||
registerEvent("removeGameFromLibrary", removeGameFromLibrary);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { gameRepository } from "../../repository";
|
||||
import { GameStatus } from "@shared";
|
||||
|
||||
const removeGame = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
@@ -9,10 +8,9 @@ const removeGame = async (
|
||||
await gameRepository.update(
|
||||
{
|
||||
id: gameId,
|
||||
status: GameStatus.Cancelled,
|
||||
},
|
||||
{
|
||||
status: null,
|
||||
status: "removed",
|
||||
downloadPath: null,
|
||||
bytesDownloaded: 0,
|
||||
progress: 0,
|
||||
|
||||
20
src/main/events/library/update-executable-path.ts
Normal file
20
src/main/events/library/update-executable-path.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { gameRepository } from "@main/repository";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
const updateExecutablePath = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
id: number,
|
||||
executablePath: string
|
||||
) => {
|
||||
return gameRepository.update(
|
||||
{
|
||||
id,
|
||||
},
|
||||
{
|
||||
executablePath,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
registerEvent("updateExecutablePath", updateExecutablePath);
|
||||
8
src/main/events/misc/is-user-logged-in.ts
Normal file
8
src/main/events/misc/is-user-logged-in.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { HydraApi } from "@main/services";
|
||||
|
||||
const isUserLoggedIn = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||
return HydraApi.isLoggedIn();
|
||||
};
|
||||
|
||||
registerEvent("isUserLoggedIn", isUserLoggedIn);
|
||||
32
src/main/events/profile/get-me.ts
Normal file
32
src/main/events/profile/get-me.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { HydraApi } from "@main/services";
|
||||
import { UserProfile } from "@types";
|
||||
import { userAuthRepository } from "@main/repository";
|
||||
import { logger } from "@main/services";
|
||||
|
||||
const getMe = async (
|
||||
_event: Electron.IpcMainInvokeEvent
|
||||
): Promise<UserProfile | null> => {
|
||||
return HydraApi.get(`/profile/me`)
|
||||
.then((response) => {
|
||||
const me = response.data;
|
||||
|
||||
userAuthRepository.upsert(
|
||||
{
|
||||
id: 1,
|
||||
displayName: me.displayName,
|
||||
profileImageUrl: me.profileImageUrl,
|
||||
userId: me.id,
|
||||
},
|
||||
["id"]
|
||||
);
|
||||
|
||||
return me;
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error("getMe", err);
|
||||
return userAuthRepository.findOne({ where: { id: 1 } });
|
||||
});
|
||||
};
|
||||
|
||||
registerEvent("getMe", getMe);
|
||||
61
src/main/events/profile/update-profile.ts
Normal file
61
src/main/events/profile/update-profile.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { HydraApi } from "@main/services";
|
||||
import axios from "axios";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileTypeFromFile } from "file-type";
|
||||
import { UserProfile } from "@types";
|
||||
|
||||
const patchUserProfile = async (
|
||||
displayName: string,
|
||||
profileImageUrl?: string
|
||||
) => {
|
||||
if (profileImageUrl) {
|
||||
return HydraApi.patch("/profile", {
|
||||
displayName,
|
||||
profileImageUrl,
|
||||
});
|
||||
} else {
|
||||
return HydraApi.patch("/profile", {
|
||||
displayName,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const updateProfile = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
displayName: string,
|
||||
newProfileImagePath: string | null
|
||||
): Promise<UserProfile> => {
|
||||
if (!newProfileImagePath) {
|
||||
return (await patchUserProfile(displayName)).data;
|
||||
}
|
||||
|
||||
const stats = fs.statSync(newProfileImagePath);
|
||||
const fileBuffer = fs.readFileSync(newProfileImagePath);
|
||||
const fileSizeInBytes = stats.size;
|
||||
|
||||
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(() => {
|
||||
return undefined;
|
||||
});
|
||||
|
||||
return (await patchUserProfile(displayName, profileImageUrl)).data;
|
||||
};
|
||||
|
||||
registerEvent("updateProfile", updateProfile);
|
||||
@@ -1,53 +1,31 @@
|
||||
import { gameRepository } from "@main/repository";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
import { WindowManager } from "@main/services";
|
||||
|
||||
import { In } from "typeorm";
|
||||
import { DownloadManager } from "@main/services";
|
||||
import { GameStatus } from "@shared";
|
||||
import { dataSource } from "@main/data-source";
|
||||
import { DownloadQueue, Game } from "@main/entity";
|
||||
|
||||
const cancelGameDownload = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
gameId: number
|
||||
) => {
|
||||
const game = await gameRepository.findOne({
|
||||
where: {
|
||||
id: gameId,
|
||||
isDeleted: false,
|
||||
status: In([
|
||||
GameStatus.Downloading,
|
||||
GameStatus.DownloadingMetadata,
|
||||
GameStatus.CheckingFiles,
|
||||
GameStatus.Paused,
|
||||
GameStatus.Seeding,
|
||||
GameStatus.Finished,
|
||||
]),
|
||||
},
|
||||
});
|
||||
await dataSource.transaction(async (transactionalEntityManager) => {
|
||||
await DownloadManager.cancelDownload(gameId);
|
||||
|
||||
if (!game) return;
|
||||
DownloadManager.cancelDownload();
|
||||
await transactionalEntityManager.getRepository(DownloadQueue).delete({
|
||||
game: { id: gameId },
|
||||
});
|
||||
|
||||
await gameRepository
|
||||
.update(
|
||||
await transactionalEntityManager.getRepository(Game).update(
|
||||
{
|
||||
id: game.id,
|
||||
id: gameId,
|
||||
},
|
||||
{
|
||||
status: GameStatus.Cancelled,
|
||||
status: "removed",
|
||||
bytesDownloaded: 0,
|
||||
progress: 0,
|
||||
}
|
||||
)
|
||||
.then((result) => {
|
||||
if (
|
||||
game.status !== GameStatus.Paused &&
|
||||
game.status !== GameStatus.Seeding
|
||||
) {
|
||||
if (result.affected) WindowManager.mainWindow?.setProgressBar(-1);
|
||||
}
|
||||
});
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
registerEvent("cancelGameDownload", cancelGameDownload);
|
||||
|
||||
@@ -1,30 +1,24 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { gameRepository } from "../../repository";
|
||||
import { In } from "typeorm";
|
||||
import { DownloadManager, WindowManager } from "@main/services";
|
||||
import { GameStatus } from "@shared";
|
||||
|
||||
import { DownloadManager } from "@main/services";
|
||||
import { dataSource } from "@main/data-source";
|
||||
import { DownloadQueue, Game } from "@main/entity";
|
||||
|
||||
const pauseGameDownload = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
gameId: number
|
||||
) => {
|
||||
DownloadManager.pauseDownload();
|
||||
await dataSource.transaction(async (transactionalEntityManager) => {
|
||||
await DownloadManager.pauseDownload();
|
||||
|
||||
await gameRepository
|
||||
.update(
|
||||
{
|
||||
id: gameId,
|
||||
status: In([
|
||||
GameStatus.Downloading,
|
||||
GameStatus.DownloadingMetadata,
|
||||
GameStatus.CheckingFiles,
|
||||
]),
|
||||
},
|
||||
{ status: GameStatus.Paused }
|
||||
)
|
||||
.then((result) => {
|
||||
if (result.affected) WindowManager.mainWindow?.setProgressBar(-1);
|
||||
await transactionalEntityManager.getRepository(DownloadQueue).delete({
|
||||
game: { id: gameId },
|
||||
});
|
||||
|
||||
await transactionalEntityManager
|
||||
.getRepository(Game)
|
||||
.update({ id: gameId }, { status: "paused" });
|
||||
});
|
||||
};
|
||||
|
||||
registerEvent("pauseGameDownload", pauseGameDownload);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { Not } from "typeorm";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
import { gameRepository } from "../../repository";
|
||||
import { getDownloadsPath } from "../helpers/get-downloads-path";
|
||||
import { In } from "typeorm";
|
||||
|
||||
import { DownloadManager } from "@main/services";
|
||||
import { GameStatus } from "@shared";
|
||||
import { dataSource } from "@main/data-source";
|
||||
import { DownloadQueue, Game } from "@main/entity";
|
||||
|
||||
const resumeGameDownload = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
@@ -14,35 +16,32 @@ const resumeGameDownload = async (
|
||||
id: gameId,
|
||||
isDeleted: false,
|
||||
},
|
||||
relations: { repack: true },
|
||||
});
|
||||
|
||||
if (!game) return;
|
||||
DownloadManager.pauseDownload();
|
||||
|
||||
if (game.status === GameStatus.Paused) {
|
||||
const downloadsPath = game.downloadPath ?? (await getDownloadsPath());
|
||||
if (game.status === "paused") {
|
||||
await dataSource.transaction(async (transactionalEntityManager) => {
|
||||
await DownloadManager.pauseDownload();
|
||||
|
||||
DownloadManager.resumeDownload(gameId);
|
||||
await transactionalEntityManager
|
||||
.getRepository(Game)
|
||||
.update({ status: "active", progress: Not(1) }, { status: "paused" });
|
||||
|
||||
await gameRepository.update(
|
||||
{
|
||||
status: In([
|
||||
GameStatus.Downloading,
|
||||
GameStatus.DownloadingMetadata,
|
||||
GameStatus.CheckingFiles,
|
||||
]),
|
||||
},
|
||||
{ status: GameStatus.Paused }
|
||||
);
|
||||
await DownloadManager.resumeDownload(game);
|
||||
|
||||
await gameRepository.update(
|
||||
{ id: game.id },
|
||||
{
|
||||
status: GameStatus.Downloading,
|
||||
downloadPath: downloadsPath,
|
||||
}
|
||||
);
|
||||
await transactionalEntityManager
|
||||
.getRepository(DownloadQueue)
|
||||
.delete({ game: { id: gameId } });
|
||||
|
||||
await transactionalEntityManager
|
||||
.getRepository(DownloadQueue)
|
||||
.insert({ game: { id: gameId } });
|
||||
|
||||
await transactionalEntityManager
|
||||
.getRepository(Game)
|
||||
.update({ id: gameId }, { status: "active" });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,38 +1,30 @@
|
||||
import { getSteamGameIconUrl } from "@main/services";
|
||||
import {
|
||||
downloadQueueRepository,
|
||||
gameRepository,
|
||||
repackRepository,
|
||||
userPreferencesRepository,
|
||||
} from "@main/repository";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
import type { GameShop } from "@types";
|
||||
import { getFileBase64 } from "@main/helpers";
|
||||
import { In } from "typeorm";
|
||||
import type { StartGameDownloadPayload } from "@types";
|
||||
import { getFileBase64, getSteamAppAsset } from "@main/helpers";
|
||||
import { DownloadManager } from "@main/services";
|
||||
import { Downloader, GameStatus } from "@shared";
|
||||
|
||||
import { Not } from "typeorm";
|
||||
import { steamGamesWorker } from "@main/workers";
|
||||
import { createGame } from "@main/services/library-sync";
|
||||
|
||||
const startGameDownload = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
repackId: number,
|
||||
objectID: string,
|
||||
title: string,
|
||||
gameShop: GameShop,
|
||||
downloadPath: string
|
||||
payload: StartGameDownloadPayload
|
||||
) => {
|
||||
const userPreferences = await userPreferencesRepository.findOne({
|
||||
where: { id: 1 },
|
||||
});
|
||||
|
||||
const downloader = userPreferences?.realDebridApiToken
|
||||
? Downloader.RealDebrid
|
||||
: Downloader.Torrent;
|
||||
const { repackId, objectID, title, shop, downloadPath, downloader } = payload;
|
||||
|
||||
const [game, repack] = await Promise.all([
|
||||
gameRepository.findOne({
|
||||
where: {
|
||||
objectID,
|
||||
shop,
|
||||
},
|
||||
}),
|
||||
repackRepository.findOne({
|
||||
@@ -42,18 +34,13 @@ const startGameDownload = async (
|
||||
}),
|
||||
]);
|
||||
|
||||
if (!repack || game?.status === GameStatus.Downloading) return;
|
||||
DownloadManager.pauseDownload();
|
||||
if (!repack) return;
|
||||
|
||||
await DownloadManager.pauseDownload();
|
||||
|
||||
await gameRepository.update(
|
||||
{
|
||||
status: In([
|
||||
GameStatus.Downloading,
|
||||
GameStatus.DownloadingMetadata,
|
||||
GameStatus.CheckingFiles,
|
||||
]),
|
||||
},
|
||||
{ status: GameStatus.Paused }
|
||||
{ status: "active", progress: Not(1) },
|
||||
{ status: "paused" }
|
||||
);
|
||||
|
||||
if (game) {
|
||||
@@ -62,39 +49,69 @@ const startGameDownload = async (
|
||||
id: game.id,
|
||||
},
|
||||
{
|
||||
status: GameStatus.DownloadingMetadata,
|
||||
downloadPath: downloadPath,
|
||||
status: "active",
|
||||
progress: 0,
|
||||
bytesDownloaded: 0,
|
||||
downloadPath,
|
||||
downloader,
|
||||
repack: { id: repackId },
|
||||
uri: repack.magnet,
|
||||
isDeleted: false,
|
||||
}
|
||||
);
|
||||
|
||||
DownloadManager.downloadGame(game.id);
|
||||
|
||||
game.status = GameStatus.DownloadingMetadata;
|
||||
|
||||
return game;
|
||||
} else {
|
||||
const iconUrl = await getFileBase64(await getSteamGameIconUrl(objectID));
|
||||
|
||||
const createdGame = await gameRepository.save({
|
||||
title,
|
||||
iconUrl,
|
||||
objectID,
|
||||
downloader,
|
||||
shop: gameShop,
|
||||
status: GameStatus.Downloading,
|
||||
downloadPath,
|
||||
repack: { id: repackId },
|
||||
const steamGame = await steamGamesWorker.run(Number(objectID), {
|
||||
name: "getById",
|
||||
});
|
||||
|
||||
DownloadManager.downloadGame(createdGame.id);
|
||||
const iconUrl = steamGame?.clientIcon
|
||||
? getSteamAppAsset("icon", objectID, steamGame.clientIcon)
|
||||
: null;
|
||||
|
||||
const { repack: _, ...rest } = createdGame;
|
||||
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 })
|
||||
);
|
||||
}
|
||||
|
||||
return rest;
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
const updatedGame = await gameRepository.findOne({
|
||||
where: {
|
||||
objectID,
|
||||
},
|
||||
});
|
||||
|
||||
createGame(updatedGame!).then((response) => {
|
||||
const {
|
||||
id: remoteId,
|
||||
playTimeInMilliseconds,
|
||||
lastTimePlayed,
|
||||
} = response.data;
|
||||
|
||||
gameRepository.update(
|
||||
{ objectID },
|
||||
{ remoteId, playTimeInMilliseconds, lastTimePlayed }
|
||||
);
|
||||
});
|
||||
|
||||
await downloadQueueRepository.delete({ game: { id: updatedGame!.id } });
|
||||
await downloadQueueRepository.insert({ game: { id: updatedGame!.id } });
|
||||
|
||||
await DownloadManager.startDownload(updatedGame!);
|
||||
};
|
||||
|
||||
registerEvent("startGameDownload", startGameDownload);
|
||||
|
||||
14
src/main/events/user-preferences/authenticate-real-debrid.ts
Normal file
14
src/main/events/user-preferences/authenticate-real-debrid.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { RealDebridClient } from "@main/services/real-debrid";
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
const authenticateRealDebrid = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
apiToken: string
|
||||
) => {
|
||||
RealDebridClient.authorize(apiToken);
|
||||
|
||||
const user = await RealDebridClient.getUser();
|
||||
return user;
|
||||
};
|
||||
|
||||
registerEvent("authenticateRealDebrid", authenticateRealDebrid);
|
||||
@@ -2,23 +2,17 @@ import { userPreferencesRepository } from "@main/repository";
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
import type { UserPreferences } from "@types";
|
||||
import { RealDebridClient } from "@main/services/real-debrid";
|
||||
|
||||
const updateUserPreferences = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
preferences: Partial<UserPreferences>
|
||||
) => {
|
||||
if (preferences.realDebridApiToken) {
|
||||
RealDebridClient.authorize(preferences.realDebridApiToken);
|
||||
}
|
||||
|
||||
await userPreferencesRepository.upsert(
|
||||
) =>
|
||||
userPreferencesRepository.upsert(
|
||||
{
|
||||
id: 1,
|
||||
...preferences,
|
||||
},
|
||||
["id"]
|
||||
);
|
||||
};
|
||||
|
||||
registerEvent("updateUserPreferences", updateUserPreferences);
|
||||
|
||||
56
src/main/events/user/get-user.ts
Normal file
56
src/main/events/user/get-user.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import { HydraApi } from "@main/services";
|
||||
import { steamGamesWorker } from "@main/workers";
|
||||
import { UserProfile } from "@types";
|
||||
import { convertSteamGameToCatalogueEntry } from "../helpers/search-games";
|
||||
import { getSteamAppAsset } from "@main/helpers";
|
||||
|
||||
const getUser = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
userId: string
|
||||
): Promise<UserProfile | null> => {
|
||||
try {
|
||||
const response = await HydraApi.get(`/user/${userId}`);
|
||||
const profile = response.data;
|
||||
|
||||
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;
|
||||
|
||||
return {
|
||||
...game,
|
||||
...convertSteamGameToCatalogueEntry(steamGame),
|
||||
iconUrl,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
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;
|
||||
|
||||
return {
|
||||
...game,
|
||||
...convertSteamGameToCatalogueEntry(steamGame),
|
||||
iconUrl,
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
return { ...profile, libraryGames, recentGames };
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
registerEvent("getUser", getUser);
|
||||
75
src/main/helpers/download-source.ts
Normal file
75
src/main/helpers/download-source.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { dataSource } from "@main/data-source";
|
||||
import { DownloadSource, Repack } from "@main/entity";
|
||||
import { downloadSourceSchema } from "@main/events/helpers/validators";
|
||||
import { downloadSourceRepository } from "@main/repository";
|
||||
import { RepacksManager } from "@main/services";
|
||||
import { downloadSourceWorker } from "@main/workers";
|
||||
import { chunk } from "lodash-es";
|
||||
import type { EntityManager } from "typeorm";
|
||||
import type { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
|
||||
import { z } from "zod";
|
||||
|
||||
export const insertDownloadsFromSource = async (
|
||||
trx: EntityManager,
|
||||
downloadSource: DownloadSource,
|
||||
downloads: z.infer<typeof downloadSourceSchema>["downloads"]
|
||||
) => {
|
||||
const repacks: QueryDeepPartialEntity<Repack>[] = downloads.map(
|
||||
(download) => ({
|
||||
title: download.title,
|
||||
magnet: download.uris[0],
|
||||
fileSize: download.fileSize,
|
||||
repacker: downloadSource.name,
|
||||
uploadDate: download.uploadDate,
|
||||
downloadSource: { id: downloadSource.id },
|
||||
})
|
||||
);
|
||||
|
||||
const downloadsChunks = chunk(repacks, 800);
|
||||
|
||||
for (const chunk of downloadsChunks) {
|
||||
await trx
|
||||
.getRepository(Repack)
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.values(chunk)
|
||||
.updateEntity(false)
|
||||
.orIgnore()
|
||||
.execute();
|
||||
}
|
||||
};
|
||||
|
||||
export const fetchDownloadSourcesAndUpdate = async () => {
|
||||
const downloadSources = await downloadSourceRepository.find({
|
||||
order: {
|
||||
id: "desc",
|
||||
},
|
||||
});
|
||||
|
||||
const results = await downloadSourceWorker.run(downloadSources, {
|
||||
name: "getUpdatedRepacks",
|
||||
});
|
||||
|
||||
await dataSource.transaction(async (transactionalEntityManager) => {
|
||||
for (const result of results) {
|
||||
if (result.etag !== null) {
|
||||
await transactionalEntityManager.getRepository(DownloadSource).update(
|
||||
{ id: result.id },
|
||||
{
|
||||
etag: result.etag,
|
||||
status: result.status,
|
||||
downloadCount: result.downloads.length,
|
||||
}
|
||||
);
|
||||
|
||||
await insertDownloadsFromSource(
|
||||
transactionalEntityManager,
|
||||
result,
|
||||
result.downloads
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await RepacksManager.updateRepacks();
|
||||
});
|
||||
};
|
||||
@@ -1,98 +0,0 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { describe, test } from "node:test";
|
||||
import {
|
||||
dodiFormatter,
|
||||
empressFormatter,
|
||||
fitGirlFormatter,
|
||||
kaosKrewFormatter,
|
||||
} from "./formatters";
|
||||
|
||||
describe("testing formatters", () => {
|
||||
describe("testing fitgirl formatter", () => {
|
||||
const fitGirlGames = [
|
||||
"REVEIL (v1.0.3f4 + 0.5 DLC, MULTi14) [FitGirl Repack]",
|
||||
"Dune: Spice Wars - The Ixian Edition (v2.0.0.31558 + DLC, MULTi9) [FitGirl Repack]",
|
||||
"HUMANKIND: Premium Edition (v1.0.22.3819 + 17 DLCs/Bonus Content, MULTi12) [FitGirl Repack, Selective Download - from 7.3 GB]",
|
||||
"Call to Arms: Gates of Hell - Ostfront: WW2 Bundle (v1.034 Hotfix 3 + 3 DLCs, MULTi9) [FitGirl Repack, Selective Download - from 21.8 GB]",
|
||||
"SUPER BOMBERMAN R 2 (v1.2.0, MULTi12) [FitGirl Repack]",
|
||||
"God of Rock (v3110, MULTi11) [FitGirl Repack]",
|
||||
];
|
||||
|
||||
test("should format games correctly", () => {
|
||||
assert.equal(fitGirlGames.map(fitGirlFormatter), [
|
||||
"REVEIL",
|
||||
"Dune: Spice Wars - The Ixian Edition",
|
||||
"HUMANKIND: Premium Edition",
|
||||
"Call to Arms: Gates of Hell - Ostfront: WW2 Bundle",
|
||||
"SUPER BOMBERMAN R 2",
|
||||
"God of Rock",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("testing kaoskrew formatter", () => {
|
||||
const kaosKrewGames = [
|
||||
"Song.Of.Horror.Complete.Edition.v1.25.MULTi4.REPACK-KaOs",
|
||||
"Remoteness.REPACK-KaOs",
|
||||
"Persona.5.Royal.v1.0.0.MULTi5.NSW.For.PC.REPACK-KaOs",
|
||||
"The.Wreck.MULTi5.REPACK-KaOs",
|
||||
"Nemezis.Mysterious.Journey.III.v1.04.Deluxe.Edition.REPACK-KaOs",
|
||||
"The.World.Of.Others.v1.05.REPACK-KaOs",
|
||||
];
|
||||
|
||||
test("should format games correctly", () => {
|
||||
assert.equal(kaosKrewGames.map(kaosKrewFormatter), [
|
||||
"Song Of Horror Complete Edition",
|
||||
"Remoteness",
|
||||
"Persona 5 Royal NSW For PC",
|
||||
"The Wreck",
|
||||
"Nemezis Mysterious Journey III Deluxe Edition",
|
||||
"The World Of Others",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("testing empress formatter", () => {
|
||||
const empressGames = [
|
||||
"Resident.Evil.4-EMPRESS",
|
||||
"Marvels.Guardians.of.the.Galaxy.Crackfix-EMPRESS",
|
||||
"Life.is.Strange.2.Complete.Edition-EMPRESS",
|
||||
"Forza.Horizon.4.PROPER-EMPRESS",
|
||||
"Just.Cause.4.Complete.Edition.READNFO-EMPRESS",
|
||||
"Immortals.Fenyx.Rising.Crackfix.V2-EMPRESS",
|
||||
];
|
||||
|
||||
test("should format games correctly", () => {
|
||||
assert.equal(empressGames.map(empressFormatter), [
|
||||
"Resident Evil 4",
|
||||
"Marvels Guardians of the Galaxy",
|
||||
"Life is Strange 2 Complete Edition",
|
||||
"Forza Horizon 4 PROPER",
|
||||
"Just Cause 4 Complete Edition",
|
||||
"Immortals Fenyx Rising",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("testing kodi formatter", () => {
|
||||
const dodiGames = [
|
||||
"Tomb Raider I-III Remastered Starring Lara Croft (MULTi20) (From 2.5 GB) [DODI Repack]",
|
||||
"Trail Out: Complete Edition (v2.9st + All DLCs + MULTi11) [DODI Repack]",
|
||||
"Call to Arms - Gates of Hell: Ostfront (v1.034.0 + All DLCs + MULTi9) (From 22.4 GB) [DODI Repack]",
|
||||
"Metal Gear Solid 2: Sons of Liberty - HD Master Collection Edition (Digital book + MULTi6) [DODI Repack]",
|
||||
"DREDGE: Digital Deluxe Edition (v1.2.0.1922 + All DLCs + Bonus Content + MULTi11) (From 413 MB) [DODI Repack]",
|
||||
"Outliver: Tribulation [DODI Repack]",
|
||||
];
|
||||
|
||||
test("should format games correctly", () => {
|
||||
assert.equal(dodiGames.map(dodiFormatter), [
|
||||
"Tomb Raider I-III Remastered Starring Lara Croft",
|
||||
"Trail Out: Complete Edition",
|
||||
"Call to Arms - Gates of Hell: Ostfront",
|
||||
"Metal Gear Solid 2: Sons of Liberty - HD Master Collection Edition",
|
||||
"DREDGE: Digital Deluxe Edition",
|
||||
"Outliver: Tribulation",
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,56 +0,0 @@
|
||||
/* String formatting */
|
||||
|
||||
export const removeReleaseYearFromName = (name: string) =>
|
||||
name.replace(/\([0-9]{4}\)/g, "");
|
||||
|
||||
export const removeSymbolsFromName = (name: string) =>
|
||||
name.replace(/[^A-Za-z 0-9]/g, "");
|
||||
|
||||
export const removeSpecialEditionFromName = (name: string) =>
|
||||
name.replace(
|
||||
/(The |Digital )?(GOTY|Deluxe|Standard|Ultimate|Definitive|Enhanced|Collector's|Premium|Digital|Limited|Game of the Year|Reloaded|[0-9]{4}) Edition/g,
|
||||
""
|
||||
);
|
||||
|
||||
export const removeDuplicateSpaces = (name: string) =>
|
||||
name.replace(/\s{2,}/g, " ");
|
||||
|
||||
export const removeTrash = (title: string) =>
|
||||
title.replace(/\(.*\)|\[.*]/g, "").replace(/:/g, "");
|
||||
|
||||
/* Formatters per repacker */
|
||||
|
||||
export const fitGirlFormatter = (title: string) =>
|
||||
title.replace(/\(.*\)/g, "").trim();
|
||||
|
||||
export const kaosKrewFormatter = (title: string) =>
|
||||
title
|
||||
.replace(/(v\.?[0-9])+([0-9]|\.)+/, "")
|
||||
.replace(
|
||||
/(\.Build\.[0-9]*)?(\.MULTi[0-9]{1,2})?(\.REPACK-KaOs|\.UPDATE-KaOs)?/g,
|
||||
""
|
||||
)
|
||||
.replace(/\./g, " ")
|
||||
.trim();
|
||||
|
||||
export const empressFormatter = (title: string) =>
|
||||
title
|
||||
.replace(/-EMPRESS/, "")
|
||||
.replace(/\./g, " ")
|
||||
.trim();
|
||||
|
||||
export const dodiFormatter = (title: string) =>
|
||||
title.replace(/\(.*?\)/g, "").trim();
|
||||
|
||||
export const xatabFormatter = (title: string) =>
|
||||
title
|
||||
.replace(/RePack от xatab|RePack от Decepticon|R.G. GOGFAN/, "")
|
||||
.replace(/[\u0400-\u04FF]/g, "")
|
||||
.replace(/(v\.?([0-9]| )+)+([0-9]|\.|-|_|\/|[a-zA-Z]| )+/, "");
|
||||
|
||||
export const tinyRepacksFormatter = (title: string) => title;
|
||||
export const onlinefixFormatter = (title: string) =>
|
||||
title.replace("по сети", "").trim();
|
||||
|
||||
export const gogFormatter = (title: string) =>
|
||||
title.replace(/(v\.[0-9]+|v[0-9]+\.|v[0-9]{4})+.+/, "");
|
||||
@@ -1,61 +1,5 @@
|
||||
import {
|
||||
removeReleaseYearFromName,
|
||||
removeSymbolsFromName,
|
||||
removeSpecialEditionFromName,
|
||||
empressFormatter,
|
||||
kaosKrewFormatter,
|
||||
fitGirlFormatter,
|
||||
removeDuplicateSpaces,
|
||||
dodiFormatter,
|
||||
removeTrash,
|
||||
xatabFormatter,
|
||||
tinyRepacksFormatter,
|
||||
gogFormatter,
|
||||
onlinefixFormatter,
|
||||
} from "./formatters";
|
||||
import { months, repackers } from "../constants";
|
||||
|
||||
export const pipe =
|
||||
<T>(...fns: ((arg: T) => any)[]) =>
|
||||
(arg: T) =>
|
||||
fns.reduce((prev, fn) => fn(prev), arg);
|
||||
|
||||
export const formatName = pipe<string>(
|
||||
removeTrash,
|
||||
removeReleaseYearFromName,
|
||||
removeSymbolsFromName,
|
||||
removeSpecialEditionFromName,
|
||||
removeDuplicateSpaces,
|
||||
(str) => str.trim()
|
||||
);
|
||||
|
||||
export const repackerFormatter: Record<
|
||||
(typeof repackers)[number],
|
||||
(title: string) => string
|
||||
> = {
|
||||
DODI: dodiFormatter,
|
||||
"0xEMPRESS": empressFormatter,
|
||||
KaOsKrew: kaosKrewFormatter,
|
||||
FitGirl: fitGirlFormatter,
|
||||
Xatab: xatabFormatter,
|
||||
CPG: (title: string) => title,
|
||||
TinyRepacks: tinyRepacksFormatter,
|
||||
GOG: gogFormatter,
|
||||
onlinefix: onlinefixFormatter,
|
||||
};
|
||||
|
||||
export const formatUploadDate = (str: string) => {
|
||||
const date = new Date();
|
||||
|
||||
const [month, day, year] = str.split(" ");
|
||||
|
||||
date.setMonth(months.indexOf(month.replace(".", "")));
|
||||
date.setDate(Number(day.substring(0, 2)));
|
||||
date.setFullYear(Number("20" + year.replace("'", "")));
|
||||
date.setHours(0, 0, 0, 0);
|
||||
|
||||
return date;
|
||||
};
|
||||
import axios from "axios";
|
||||
import UserAgent from "user-agents";
|
||||
|
||||
export const getSteamAppAsset = (
|
||||
category: "library" | "hero" | "logo" | "icon",
|
||||
@@ -98,5 +42,20 @@ export const steamUrlBuilder = {
|
||||
`https://cdn.cloudflare.steamstatic.com/steam/apps/${objectID}/logo.png`,
|
||||
};
|
||||
|
||||
export * from "./formatters";
|
||||
export const sleep = (ms: number) =>
|
||||
new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
export const requestWebPage = async (url: string) => {
|
||||
const userAgent = new UserAgent();
|
||||
|
||||
return axios
|
||||
.get(url, {
|
||||
headers: {
|
||||
"User-Agent": userAgent.toString(),
|
||||
},
|
||||
})
|
||||
.then((response) => response.data);
|
||||
};
|
||||
|
||||
export * from "./ps";
|
||||
export * from "./download-source";
|
||||
|
||||
@@ -2,8 +2,9 @@ import { app, BrowserWindow, net, protocol } from "electron";
|
||||
import updater from "electron-updater";
|
||||
import i18n from "i18next";
|
||||
import path from "node:path";
|
||||
import url from "node:url";
|
||||
import { electronApp, optimizer } from "@electron-toolkit/utils";
|
||||
import { resolveDatabaseUpdates, WindowManager } from "@main/services";
|
||||
import { DownloadManager, logger, WindowManager } from "@main/services";
|
||||
import { dataSource } from "@main/data-source";
|
||||
import * as resources from "@locales";
|
||||
import { userPreferencesRepository } from "@main/repository";
|
||||
@@ -16,10 +17,12 @@ autoUpdater.setFeedURL({
|
||||
repo: "hydra",
|
||||
});
|
||||
|
||||
autoUpdater.logger = logger;
|
||||
|
||||
const gotTheLock = app.requestSingleInstanceLock();
|
||||
if (!gotTheLock) app.quit();
|
||||
|
||||
app.disableHardwareAcceleration();
|
||||
app.commandLine.appendSwitch("--no-sandbox");
|
||||
|
||||
i18n.init({
|
||||
resources,
|
||||
@@ -45,35 +48,40 @@ if (process.defaultApp) {
|
||||
// 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.
|
||||
app.whenReady().then(() => {
|
||||
app.whenReady().then(async () => {
|
||||
electronApp.setAppUserModelId("site.hydralauncher.hydra");
|
||||
|
||||
protocol.handle("hydra", (request) =>
|
||||
net.fetch("file://" + request.url.slice("hydra://".length))
|
||||
);
|
||||
|
||||
dataSource.initialize().then(async () => {
|
||||
await resolveDatabaseUpdates();
|
||||
|
||||
await import("./main");
|
||||
|
||||
const userPreferences = await userPreferencesRepository.findOne({
|
||||
where: { id: 1 },
|
||||
});
|
||||
|
||||
WindowManager.createMainWindow();
|
||||
WindowManager.createSystemTray(userPreferences?.language || "en");
|
||||
|
||||
WindowManager.mainWindow?.on("ready-to-show", () => {
|
||||
autoUpdater.checkForUpdatesAndNotify();
|
||||
});
|
||||
protocol.handle("local", (request) => {
|
||||
const filePath = request.url.slice("local:".length);
|
||||
return net.fetch(url.pathToFileURL(decodeURI(filePath)).toString());
|
||||
});
|
||||
|
||||
await dataSource.initialize();
|
||||
await dataSource.runMigrations();
|
||||
|
||||
await import("./main");
|
||||
|
||||
const userPreferences = await userPreferencesRepository.findOne({
|
||||
where: { id: 1 },
|
||||
});
|
||||
|
||||
WindowManager.createMainWindow();
|
||||
WindowManager.createSystemTray(userPreferences?.language || "en");
|
||||
});
|
||||
|
||||
app.on("browser-window-created", (_, window) => {
|
||||
optimizer.watchWindowShortcuts(window);
|
||||
});
|
||||
|
||||
const handleDeepLinkPath = (uri?: string) => {
|
||||
if (!uri) return;
|
||||
const url = new URL(uri);
|
||||
|
||||
if (url.host === "install-source") {
|
||||
WindowManager.redirect(`settings${url.search}`);
|
||||
}
|
||||
};
|
||||
|
||||
app.on("second-instance", (_event, commandLine) => {
|
||||
// Someone tried to run a second instance, we should focus our window.
|
||||
if (WindowManager.mainWindow) {
|
||||
@@ -85,13 +93,11 @@ app.on("second-instance", (_event, commandLine) => {
|
||||
WindowManager.createMainWindow();
|
||||
}
|
||||
|
||||
const [, path] = commandLine.pop()?.split("://") ?? [];
|
||||
if (path) WindowManager.redirect(path);
|
||||
handleDeepLinkPath(commandLine.pop());
|
||||
});
|
||||
|
||||
app.on("open-url", (_event, url) => {
|
||||
const [, path] = url.split("://");
|
||||
WindowManager.redirect(path);
|
||||
handleDeepLinkPath(url);
|
||||
});
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
@@ -101,6 +107,10 @@ app.on("window-all-closed", () => {
|
||||
WindowManager.mainWindow = null;
|
||||
});
|
||||
|
||||
app.on("before-quit", () => {
|
||||
DownloadManager.disconnect();
|
||||
});
|
||||
|
||||
app.on("activate", () => {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
|
||||
130
src/main/main.ts
130
src/main/main.ts
@@ -1,112 +1,54 @@
|
||||
import { stateManager } from "./state-manager";
|
||||
import { repackersOn1337x } from "./constants";
|
||||
import { DownloadManager, RepacksManager, startMainLoop } from "./services";
|
||||
import {
|
||||
getNewGOGGames,
|
||||
getNewRepacksFromUser,
|
||||
getNewRepacksFromXatab,
|
||||
getNewRepacksFromOnlineFix,
|
||||
startProcessWatcher,
|
||||
DownloadManager,
|
||||
} from "./services";
|
||||
import {
|
||||
gameRepository,
|
||||
downloadQueueRepository,
|
||||
repackRepository,
|
||||
steamGameRepository,
|
||||
userPreferencesRepository,
|
||||
} from "./repository";
|
||||
import { TorrentDownloader } from "./services";
|
||||
import { Repack, UserPreferences } from "./entity";
|
||||
import { Notification } from "electron";
|
||||
import { t } from "i18next";
|
||||
import { GameStatus } from "@shared";
|
||||
import { In } from "typeorm";
|
||||
import { UserPreferences } from "./entity";
|
||||
import { RealDebridClient } from "./services/real-debrid";
|
||||
import { fetchDownloadSourcesAndUpdate } from "./helpers";
|
||||
import { publishNewRepacksNotifications } from "./services/notifications";
|
||||
import { MoreThan } from "typeorm";
|
||||
import { HydraApi } from "./services/hydra-api";
|
||||
import { uploadGamesBatch } from "./services/library-sync";
|
||||
|
||||
startProcessWatcher();
|
||||
|
||||
const track1337xUsers = async (existingRepacks: Repack[]) => {
|
||||
for (const repacker of repackersOn1337x) {
|
||||
await getNewRepacksFromUser(
|
||||
repacker,
|
||||
existingRepacks.filter((repack) => repack.repacker === repacker)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const checkForNewRepacks = async (userPreferences: UserPreferences | null) => {
|
||||
const existingRepacks = stateManager.getValue("repacks");
|
||||
|
||||
Promise.allSettled([
|
||||
track1337xUsers(existingRepacks),
|
||||
getNewRepacksFromXatab(
|
||||
existingRepacks.filter((repack) => repack.repacker === "Xatab")
|
||||
),
|
||||
getNewGOGGames(
|
||||
existingRepacks.filter((repack) => repack.repacker === "GOG")
|
||||
),
|
||||
getNewRepacksFromOnlineFix(
|
||||
existingRepacks.filter((repack) => repack.repacker === "onlinefix")
|
||||
),
|
||||
]).then(() => {
|
||||
repackRepository.count().then((count) => {
|
||||
const total = count - stateManager.getValue("repacks").length;
|
||||
|
||||
if (total > 0 && userPreferences?.repackUpdatesNotificationsEnabled) {
|
||||
new Notification({
|
||||
title: t("repack_list_updated", {
|
||||
ns: "notifications",
|
||||
lng: userPreferences?.language || "en",
|
||||
}),
|
||||
body: t("repack_count", {
|
||||
ns: "notifications",
|
||||
lng: userPreferences?.language || "en",
|
||||
count: total,
|
||||
}),
|
||||
}).show();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
startMainLoop();
|
||||
|
||||
const loadState = async (userPreferences: UserPreferences | null) => {
|
||||
const [repacks, steamGames] = await Promise.all([
|
||||
repackRepository.find({
|
||||
order: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
}),
|
||||
steamGameRepository.find({
|
||||
order: {
|
||||
name: "asc",
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
stateManager.setValue("repacks", repacks);
|
||||
stateManager.setValue("steamGames", steamGames);
|
||||
await RepacksManager.updateRepacks();
|
||||
|
||||
import("./events");
|
||||
|
||||
if (userPreferences?.realDebridApiToken)
|
||||
await RealDebridClient.authorize(userPreferences?.realDebridApiToken);
|
||||
RealDebridClient.authorize(userPreferences?.realDebridApiToken);
|
||||
|
||||
const game = await gameRepository.findOne({
|
||||
where: {
|
||||
status: In([
|
||||
GameStatus.Downloading,
|
||||
GameStatus.DownloadingMetadata,
|
||||
GameStatus.CheckingFiles,
|
||||
]),
|
||||
isDeleted: false,
|
||||
},
|
||||
relations: { repack: true },
|
||||
HydraApi.setupApi().then(async () => {
|
||||
if (HydraApi.isLoggedIn()) uploadGamesBatch();
|
||||
});
|
||||
|
||||
await TorrentDownloader.startClient();
|
||||
const [nextQueueItem] = await downloadQueueRepository.find({
|
||||
order: {
|
||||
id: "DESC",
|
||||
},
|
||||
relations: {
|
||||
game: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (game) {
|
||||
DownloadManager.resumeDownload(game.id);
|
||||
}
|
||||
if (nextQueueItem?.game.status === "active")
|
||||
DownloadManager.startDownload(nextQueueItem.game);
|
||||
|
||||
const now = new Date();
|
||||
|
||||
fetchDownloadSourcesAndUpdate().then(async () => {
|
||||
const newRepacksCount = await repackRepository.count({
|
||||
where: {
|
||||
createdAt: MoreThan(now),
|
||||
},
|
||||
});
|
||||
|
||||
if (newRepacksCount > 0) publishNewRepacksNotifications(newRepacksCount);
|
||||
});
|
||||
};
|
||||
|
||||
userPreferencesRepository
|
||||
@@ -114,5 +56,5 @@ userPreferencesRepository
|
||||
where: { id: 1 },
|
||||
})
|
||||
.then((userPreferences) => {
|
||||
loadState(userPreferences).then(() => checkForNewRepacks(userPreferences));
|
||||
loadState(userPreferences);
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user