Compare commits

...

525 Commits

Author SHA1 Message Date
OMGeeky
a4fbe20871 refactor window insets handling for fullscreen and touch area
Signed-off-by: OMGeeky <aalaalgmx@gmail.com>
2025-08-03 18:57:39 +02:00
OMGeeky
0d73ee10fa set usable padding for title logo in StartScreenActivity 2025-07-29 05:52:29 +02:00
OMGeeky
f20529df62 setSystemBarsBehavior so it disappears automatically when in fullscreen
also don't run code, that is deprecated when on higher version
2025-07-29 05:38:01 +02:00
OMGeeky
ffef76b28b continue implementing edge-to-edge behaviour and insets 2025-07-29 05:05:40 +02:00
OMGeeky
cd49473e86 continue implementing edge-to-edge behaviour and insets (Start-Screen) 2025-07-29 04:06:06 +02:00
OMGeeky
363a395169 start implementing edge-to-edge behaviour and insets 2025-07-29 03:33:10 +02:00
OMGeeky
a09176d344 Refactor activity view setup to use app.setView for consistency 2025-07-29 03:05:50 +02:00
OMGeeky
f884af20b8 Replace custom Pair implementation with android.util.Pair 2025-07-29 00:08:02 +02:00
OMGeeky
a2859fbc56 Remove unnecessary @TargetApi annotations and remove unnecessary SDK-Version check 2025-07-28 23:33:23 +02:00
OMGeeky
11d5966a51 Sort summary output of errors and warnings by file path 2025-07-28 22:00:24 +02:00
OMGeeky
fd169e9f40 Add total error and warning summary to format specifier check output 2025-07-28 21:59:19 +02:00
OMGeeky
149ad3ae1c Differentiate between missing and extra format specifiers
Missing format specifiers in translated strings are now reported as warnings,
while extra format specifiers are reported as errors.
This change allows the script to pass if only warnings (missing specifiers)
are present, but still fail if there are errors (extra specifiers).

The summary now also includes counts for both errors and warnings per file.
2025-07-28 21:57:29 +02:00
OMGeeky
6e74243ea8 Refactor: Improve format specifier regex
The regular expression for identifying format specifiers in XML string resources has been updated. The new regex now correctly identifies specifiers like `%.2f` which include precision for floating point numbers. This change ensures more accurate validation of format specifiers.
2025-07-28 21:51:59 +02:00
OMGeeky
9c4009034f Enhance format specifier check script output
The script now provides a summary of errors per file at the end of its execution.
This makes it easier to identify which translation files have issues with format specifiers or non-escaped percentage signs.
2025-07-28 21:51:31 +02:00
OMGeeky
0422beb855 Update string formatter check script
- Add scanning for used keys in Java files.
- Refactor argument parsing to separate project root and res root.
- If no specific key is provided, check only keys used in Java code.
2025-07-28 21:35:38 +02:00
OMGeeky
2cc12b3530 Improve check_format_specifiers.py to check all keys if none specified 2025-07-28 21:25:28 +02:00
OMGeeky
80997ddc36 Exit with error code on specifier mismatches in format checker 2025-07-28 21:20:17 +02:00
OMGeeky
c244ba1390 Added checks for unescaped percent signs 2025-07-28 21:12:23 +02:00
OMGeeky
8a74ffd2ef Add Python script to check format specifier consistency in Android strings
This script, `check_format_specifiers.py`, helps ensure that format
specifiers (like `%s`, `%d`, `%1$s`) are used consistently across
different language versions of a string resource in an Android project.
2025-07-28 21:01:11 +02:00
OMGeeky
57f7a0dc91 Refactor fullscreen mode setting
Move fullscreen mode setting logic into a static method in AndorsTrailApplication and use it in Preferences and CustomDialogFactory.
2025-07-28 18:06:43 +02:00
OMGeeky
78cf59c90c Updated full screen flag for API 30+ 2025-07-28 18:00:54 +02:00
Nut.andor
c4ac6b1046 whatsnew 2025-07-26 00:18:21 +02:00
Nut.andor
a5ed53a763 added graphic 2025-07-19 01:09:00 +02:00
Nut.andor
d6b11d8242 added graphic 2025-07-17 20:48:09 +02:00
Nut.andor
d9e7509daa whatsnew 2025-07-17 20:48:09 +02:00
Nut.andor
e15583e3c5 settings 2025-07-17 20:48:08 +02:00
Nut.andor
25b70ae818 typos 2025-06-24 00:00:27 +02:00
Nut.andor
1aa98de579 new png 2025-06-24 00:00:27 +02:00
Nut.andor
be027bb303 Item description could have $playername 2025-06-22 22:25:23 +02:00
Nut.andor
d2fe192466 settings 2025-06-22 22:25:23 +02:00
Nut.andor
469d2bfc46 new part of falsly extended map_cavewall_5 moved to new map_cavewall_6 2025-06-19 16:19:40 +02:00
Nut.andor
ce399ffe1f settings 2025-06-19 12:35:13 +02:00
Nut.andor
054c6e5d23 new map_outdoor_2.png 2025-06-17 22:15:54 +02:00
Nut.andor
e4633c0689 exploding star item icon 2025-06-10 21:51:38 +02:00
Nut.andor
9b9d8a7c3a dbg 2025-06-10 21:51:38 +02:00
Nut.andor
0cfa6a97c9 Merge branch 'pulls/1829009049/90' into AT_Source_Next_Release 2025-06-06 22:10:10 +02:00
Nut.andor
9729d5a34f On miss effects 2025-06-06 22:09:19 +02:00
Nut.andor
c024474128 Merge branch 'pulls/1829009049/86' into AT_Source_Next_Release 2025-06-06 22:07:13 +02:00
Nut.andor
3100ffd717 Anti cheat checksum 2025-06-06 21:56:42 +02:00
Nut.andor
e3c8c0ecfb useful links 2025-05-11 18:10:32 +02:00
Nut.andor
cd35ad673f next version v0.8.14dev 2025-05-11 11:12:25 +02:00
Nut.andor
5f000ef210 Merge branch 'master' into AT_Source_Next_Release 2025-05-11 11:10:27 +02:00
Nut.andor
c09f5e3a6e whatsnew 2025-05-04 22:46:39 +02:00
Nut.andor
4d5a765522 translation status 2025-05-04 22:02:14 +02:00
Nut.andor
64500ed2fa Merge branch 'AT_Source_Next_Release' 2025-05-04 20:40:36 +02:00
Nut.andor
77af4079c5 whatsnew 2025-05-04 20:39:29 +02:00
Nut.andor
d885911b32 potc built 2025-05-04 20:20:06 +02:00
Nut.andor
99a0d4f40c potc 2025-05-04 20:18:22 +02:00
Nut.andor
656b95061b v0.8.13 Troubling Times content 2025-05-04 20:08:26 +02:00
Nut.andor
24760824b5 Authors 2025-05-04 19:27:49 +02:00
Nut.andor
8eef67bfe7 Merge branch 'master-hosted.weblate' into AT_Source_Next_Release 2025-05-04 19:12:23 +02:00
Nut.andor
d839604e38 version 2025-05-04 19:03:24 +02:00
Nut.andor
2078eedb94 Pull Request #90: On miss effects 2025-05-02 22:26:37 +02:00
Nut.andor
7d8301fbed dirty fix of French 2025-05-01 18:00:43 +02:00
Lacrom
f07f41d4e5 Translated using Weblate (French)
Currently translated at 100.0% (612 of 612 strings)
2025-04-29 19:01:43 +00:00
Nut.andor
ab540d7707 Merge branch 'master-hosted.weblate' into AT_Source_Next_Release 2025-04-27 22:38:01 +02:00
Максим Горпиніч
1e1b012a72 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (19203 of 19203 strings)
2025-04-27 22:34:16 +02:00
Максим Горпиніч
9a68c014a9 Translated using Weblate (Turkish)
Currently translated at 32.0% (6157 of 19203 strings)
2025-04-24 05:44:11 +02:00
Максим Горпиніч
ea436327d5 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (19203 of 19203 strings)
2025-04-22 20:18:14 +02:00
Максим Горпиніч
7c7b2f85ac Translated using Weblate (Ukrainian)
Currently translated at 95.3% (18303 of 19203 strings)
2025-04-22 15:38:50 +02:00
Максим Горпиніч
7c3f1c4a91 Translated using Weblate (Ukrainian)
Currently translated at 89.5% (17203 of 19203 strings)
2025-04-21 15:02:58 +02:00
Максим Горпиніч
5f88580ba3 Translated using Weblate (Ukrainian)
Currently translated at 84.3% (16203 of 19203 strings)
2025-04-20 20:03:55 +02:00
Максим Горпиніч
b0cc608091 Translated using Weblate (Turkish)
Currently translated at 32.0% (6158 of 19203 strings)
2025-04-20 20:03:42 +02:00
Prashanth Prash
441ecc1b1d Added translation using Weblate (Hindi (Latin script)) 2025-04-20 03:55:04 +02:00
Максим Горпиніч
d18df3c17c Translated using Weblate (Ukrainian)
Currently translated at 79.1% (15203 of 19203 strings)
2025-04-19 19:15:05 +02:00
Максим Горпиніч
7e7974a612 Translated using Weblate (Ukrainian)
Currently translated at 77.0% (14803 of 19203 strings)
2025-04-19 09:03:16 +02:00
Максим Горпиніч
3d7b09c3c5 Translated using Weblate (Ukrainian)
Currently translated at 68.7% (13203 of 19203 strings)
2025-04-17 23:05:55 +02:00
Максим Горпиніч
ce7ad3fdfe Translated using Weblate (Ukrainian)
Currently translated at 63.5% (12203 of 19203 strings)
2025-04-16 22:35:51 +02:00
Максим Горпиніч
85c2cb4c88 Translated using Weblate (Ukrainian)
Currently translated at 58.3% (11203 of 19203 strings)
2025-04-15 19:22:00 +02:00
Максим Горпиніч
43dbbfd984 Translated using Weblate (Ukrainian)
Currently translated at 53.1% (10203 of 19203 strings)
2025-04-14 19:41:34 +02:00
xvy
0286f70a25 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-04-14 19:41:15 +02:00
Максим Горпиніч
9e34fad7d6 Translated using Weblate (Ukrainian)
Currently translated at 47.9% (9203 of 19203 strings)
2025-04-13 18:32:04 +02:00
Максим Горпиніч
d910597f22 Translated using Weblate (Ukrainian)
Currently translated at 42.7% (8203 of 19203 strings)
2025-04-12 19:10:13 +02:00
Andriamihaja Tsiky Miangola Kevin
a8eb6acc3f Translated using Weblate (Malagasy)
Currently translated at 31.3% (192 of 612 strings)
2025-04-11 17:02:18 +02:00
Максим Горпиніч
3075951465 Translated using Weblate (Ukrainian)
Currently translated at 37.5% (7203 of 19203 strings)
2025-04-11 17:02:16 +02:00
ssantos
f2ef2d8ede Translated using Weblate (Portuguese)
Currently translated at 64.7% (12427 of 19203 strings)
2025-04-11 17:01:56 +02:00
Daniel Stasiak
6d4c701335 Translated using Weblate (Polish)
Currently translated at 87.8% (16872 of 19203 strings)
2025-04-11 17:01:42 +02:00
Максим Горпиніч
25d5c20abd Translated using Weblate (Ukrainian)
Currently translated at 28.3% (5448 of 19203 strings)
2025-04-10 14:01:44 +00:00
Andriamihaja Tsiky Miangola Kevin
012bbbb6c9 Translated using Weblate (Malagasy)
Currently translated at 30.8% (189 of 612 strings)
2025-04-09 16:00:03 +02:00
Максим Горпиніч
11ae4a3344 Translated using Weblate (Ukrainian)
Currently translated at 26.4% (5082 of 19203 strings)
2025-04-09 16:00:02 +02:00
Andriamihaja Tsiky Miangola Kevin
ec6227e795 Translated using Weblate (Malagasy)
Currently translated at 22.0% (135 of 612 strings)
2025-04-08 23:13:36 +02:00
Максим Горпиніч
9f6fde7476 Translated using Weblate (Ukrainian)
Currently translated at 21.8% (4203 of 19203 strings)
2025-04-08 23:13:35 +02:00
Andriamihaja Tsiky Miangola Kevin
3c16226999 Added translation using Weblate (Malagasy) 2025-04-08 17:47:11 +02:00
Andriamihaja Tsiky Miangola Kevin
4f839e5fda Translated using Weblate (Malagasy)
Currently translated at 0.1% (1 of 19202 strings)
2025-04-08 17:47:11 +02:00
Максим Горпиніч
53de823d40 Translated using Weblate (Ukrainian)
Currently translated at 19.9% (3838 of 19203 strings)
2025-04-08 17:47:10 +02:00
Andriamihaja Tsiky Miangola Kevin
04143af634 Added translation using Weblate (Malagasy) 2025-04-08 17:14:23 +02:00
Максим Горпиніч
833c824b36 Translated using Weblate (Ukrainian)
Currently translated at 19.8% (3803 of 19203 strings)
2025-04-08 17:14:19 +02:00
Максим Горпиніч
b1505721a8 Translated using Weblate (Ukrainian)
Currently translated at 16.6% (3203 of 19203 strings)
2025-04-07 19:05:38 +02:00
ssantos
70d3de4eb9 Translated using Weblate (Portuguese)
Currently translated at 99.5% (609 of 612 strings)
2025-04-07 19:05:34 +02:00
Nut.andor
f503aafb35 debug teleport #targets 2025-04-06 02:05:46 +02:00
Daniel Stasiak
7bd5d648d8 Translated using Weblate (Polish)
Currently translated at 87.8% (16862 of 19203 strings)
2025-04-03 18:39:51 +02:00
Daniel Stasiak
01ec5b1802 Translated using Weblate (Polish)
Currently translated at 87.7% (16856 of 19203 strings)
2025-04-03 17:16:04 +02:00
xvy
090a39991a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-04-02 19:44:16 +02:00
Daniel Stasiak
2d761123ae Translated using Weblate (Polish)
Currently translated at 87.7% (16852 of 19203 strings)
2025-04-02 19:44:13 +02:00
Daniel Stasiak
4e066b4fc5 Translated using Weblate (Polish)
Currently translated at 87.7% (16847 of 19203 strings)
2025-04-01 22:34:11 +02:00
Daniel Stasiak
835293cdb2 Translated using Weblate (Polish)
Currently translated at 87.7% (16843 of 19203 strings)
2025-04-01 18:39:18 +02:00
xvy
9a1322ee46 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-04-01 17:15:24 +02:00
Daniel Stasiak
03b0cf77cd Translated using Weblate (Polish)
Currently translated at 87.6% (16837 of 19203 strings)
2025-03-27 23:47:51 +01:00
Daniel Stasiak
4744f9ffcc Translated using Weblate (Polish)
Currently translated at 87.6% (16830 of 19203 strings)
2025-03-27 00:06:27 +01:00
Ilian Iliev
37319f768c Translated using Weblate (Bulgarian)
Currently translated at 89.7% (549 of 612 strings)
2025-03-24 22:56:29 +01:00
Daniel Stasiak
8a75b08c2e Translated using Weblate (Polish)
Currently translated at 87.6% (16824 of 19203 strings)
2025-03-24 22:56:28 +01:00
Daniel Stasiak
2e3121008b Translated using Weblate (Polish)
Currently translated at 87.5% (16814 of 19203 strings)
2025-03-23 21:34:13 +01:00
Ilian Iliev
3fbbcdbdf2 Translated using Weblate (Bulgarian)
Currently translated at 79.5% (487 of 612 strings)
2025-03-23 20:34:06 +01:00
Daniel Stasiak
f948b8890a Translated using Weblate (Polish)
Currently translated at 87.4% (16797 of 19203 strings)
2025-03-22 20:39:49 +01:00
Daniel Stasiak
195214a367 Translated using Weblate (Polish)
Currently translated at 87.4% (16789 of 19203 strings)
2025-03-21 22:58:47 +01:00
Максим Горпиніч
7078a6c91a Translated using Weblate (Ukrainian)
Currently translated at 10.9% (2103 of 19203 strings)
2025-03-21 20:45:10 +01:00
Максим Горпиніч
21772ce12e Translated using Weblate (Ukrainian)
Currently translated at 9.9% (1903 of 19203 strings)
2025-03-21 11:07:48 +01:00
Максим Горпиніч
b3514abea2 Translated using Weblate (Ukrainian)
Currently translated at 8.8% (1703 of 19203 strings)
2025-03-20 22:19:04 +01:00
ilya
421a1d7458 Translated using Weblate (Russian)
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-20 21:33:16 +01:00
Daniel Stasiak
cfdd8be9ab Translated using Weblate (Polish)
Currently translated at 87.3% (16783 of 19203 strings)
2025-03-20 17:44:44 +01:00
Максим Горпиніч
0f91d45265 Translated using Weblate (Ukrainian)
Currently translated at 8.1% (1557 of 19203 strings)
2025-03-20 14:30:11 +01:00
Максим Горпиніч
47c3725671 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (612 of 612 strings)
2025-03-20 10:28:55 +01:00
Максим Горпиніч
6166378478 Translated using Weblate (Ukrainian)
Currently translated at 7.8% (1503 of 19203 strings)
2025-03-20 10:28:55 +01:00
xvy
af958bf242 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-20 09:00:35 +01:00
xvy
ec2c7ca98d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-20 03:13:06 +01:00
Daniel Stasiak
7d2da8d21b Translated using Weblate (Polish)
Currently translated at 87.3% (16780 of 19203 strings)
2025-03-19 22:46:38 +01:00
xvy
d305fabac2 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-19 12:07:46 +01:00
xvy
7edc940de1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-19 08:02:33 +01:00
xvy
e5a8cc1f10 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-19 07:43:59 +01:00
xvy
5fe07e25fe Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-19 04:02:09 +01:00
xvy
cf82f7f4a9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-19 02:25:57 +01:00
Daniel Stasiak
fefe9d3618 Translated using Weblate (Polish)
Currently translated at 87.2% (16762 of 19203 strings)
2025-03-19 00:09:17 +01:00
Daniel Stasiak
b5f163f249 Translated using Weblate (Polish)
Currently translated at 87.2% (16748 of 19203 strings)
2025-03-18 18:08:13 +01:00
xvy
988be52a32 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-18 10:38:59 +01:00
xvy
cc2b510f08 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-18 02:26:08 +01:00
Daniel Stasiak
cb95eec05a Translated using Weblate (Polish)
Currently translated at 87.1% (16739 of 19203 strings)
2025-03-17 23:00:09 +01:00
Daniel Stasiak
1d16e47fc2 Translated using Weblate (Polish)
Currently translated at 87.1% (16733 of 19203 strings)
2025-03-17 22:16:03 +01:00
Daniel Stasiak
82a84018ba Translated using Weblate (Polish)
Currently translated at 87.1% (16730 of 19203 strings)
2025-03-17 22:05:40 +01:00
xvy
69373da1a5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-17 02:14:37 +01:00
Daniel Stasiak
a22827993d Translated using Weblate (Polish)
Currently translated at 87.1% (16729 of 19203 strings)
2025-03-17 00:00:57 +01:00
Daniel Stasiak
d8630872ad Translated using Weblate (Polish)
Currently translated at 87.1% (16728 of 19203 strings)
2025-03-16 23:34:02 +01:00
xvy
12be936120 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-16 09:36:05 +01:00
Daniel Stasiak
26f9fbf7a6 Translated using Weblate (Polish)
Currently translated at 87.0% (16719 of 19203 strings)
2025-03-16 00:21:20 +01:00
xvy
ac5168bd7a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-14 12:07:15 +01:00
xvy
2454285f7f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-14 08:45:48 +01:00
xvy
a6c87856c0 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-14 05:41:27 +01:00
xvy
be8e164436 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-14 05:13:47 +01:00
xvy
01127733f5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-14 04:03:07 +01:00
xvy
cdb8af5672 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-14 01:55:31 +01:00
Daniel Stasiak
346fdd7acc Translated using Weblate (Polish)
Currently translated at 87.0% (16714 of 19203 strings)
2025-03-14 00:10:00 +01:00
Daniel Stasiak
98979f5d61 Translated using Weblate (Polish)
Currently translated at 87.0% (16710 of 19203 strings)
2025-03-13 18:04:50 +01:00
Daniel Stasiak
1cf308efa7 Translated using Weblate (Polish)
Currently translated at 86.9% (16695 of 19203 strings)
2025-03-13 03:06:13 +01:00
Daniel Stasiak
fd56b4434e Translated using Weblate (Polish)
Currently translated at 86.9% (16695 of 19203 strings)
2025-03-12 22:00:47 +01:00
Daniel Stasiak
fd15bd78f7 Translated using Weblate (Polish)
Currently translated at 86.8% (16682 of 19203 strings)
2025-03-12 20:33:22 +01:00
xvy
f830445a62 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-12 07:05:08 +01:00
Daniel Stasiak
2af0874c39 Translated using Weblate (Polish)
Currently translated at 86.8% (16678 of 19203 strings)
2025-03-12 04:08:37 +01:00
xvy
eda2755e38 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (612 of 612 strings)
2025-03-11 09:29:46 +01:00
xvy
81f0d701b5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-11 09:29:45 +01:00
Daniel Stasiak
c6f93ffa11 Translated using Weblate (Polish)
Currently translated at 86.7% (16662 of 19203 strings)
2025-03-11 09:29:44 +01:00
xvy
d5d0b56593 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-10 10:45:10 +01:00
xvy
f328da34c1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-10 04:22:49 +01:00
xvy
c6b34c8485 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-10 03:04:00 +01:00
xvy
c6330e23e5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-09 21:43:33 +01:00
Daniel Stasiak
a137247483 Translated using Weblate (Polish)
Currently translated at 86.6% (16647 of 19203 strings)
2025-03-09 21:43:31 +01:00
xvy
99e056b022 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-09 14:08:14 +01:00
xvy
f8314567f2 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-09 12:58:51 +01:00
xvy
cd430eb528 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-09 07:04:00 +01:00
Daniel Stasiak
929cb81ea5 Translated using Weblate (Polish)
Currently translated at 86.5% (16617 of 19203 strings)
2025-03-09 04:07:26 +01:00
xvy
dfc2b9410c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-08 15:14:00 +01:00
Daniel Stasiak
c58095a689 Translated using Weblate (Polish)
Currently translated at 86.4% (16601 of 19203 strings)
2025-03-07 23:27:41 +01:00
Daniel Stasiak
1994ca69f2 Translated using Weblate (Polish)
Currently translated at 86.4% (16596 of 19203 strings)
2025-03-07 22:43:16 +01:00
Daniel Stasiak
34413664a5 Translated using Weblate (Polish)
Currently translated at 86.4% (16593 of 19203 strings)
2025-03-07 22:36:20 +01:00
Daniel Stasiak
af0c316d33 Translated using Weblate (Polish)
Currently translated at 86.3% (16590 of 19203 strings)
2025-03-07 20:05:32 +01:00
Daniel Stasiak
918838b7eb Translated using Weblate (Polish)
Currently translated at 86.3% (16589 of 19203 strings)
2025-03-06 23:09:29 +01:00
Daniel Stasiak
1ada919cf2 Translated using Weblate (Polish)
Currently translated at 86.3% (16579 of 19203 strings)
2025-03-06 19:27:42 +01:00
Daniel Stasiak
871b11ec2f Translated using Weblate (Polish)
Currently translated at 86.2% (16571 of 19203 strings)
2025-03-06 02:33:41 +01:00
xvy
ff9eebec79 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-05 06:58:23 +01:00
xvy
7c62660192 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-05 06:27:22 +01:00
xvy
86c177ddd8 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-05 06:08:33 +01:00
xvy
20a9e0170e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-05 06:01:22 +01:00
xvy
3ee260800d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-05 03:40:48 +01:00
xvy
4168d88f6c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-05 02:49:36 +01:00
xvy
396b08d9c1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-05 02:42:44 +01:00
Daniel Stasiak
1800c36918 Translated using Weblate (Polish)
Currently translated at 86.1% (16552 of 19203 strings)
2025-03-04 22:55:30 +01:00
JohannesBoanerges
dbbe58e780 Translated using Weblate (German)
Currently translated at 91.7% (17625 of 19203 strings)
2025-03-04 19:05:15 +01:00
Raphi
2b0a0e0662 Translated using Weblate (German)
Currently translated at 91.6% (17607 of 19203 strings)
2025-03-04 18:26:39 +01:00
JohannesBoanerges
0a3b6182bb Translated using Weblate (German)
Currently translated at 91.6% (17607 of 19203 strings)
2025-03-04 18:26:39 +01:00
xvy
795d44fe64 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-04 09:36:31 +01:00
xvy
7f41df5932 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-04 02:23:40 +01:00
Daniel Stasiak
012e0d12f7 Translated using Weblate (Polish)
Currently translated at 86.0% (16531 of 19203 strings)
2025-03-03 19:11:01 +01:00
xvy
93e2117b21 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-03 08:32:39 +01:00
Daniel Stasiak
b38ad51811 Translated using Weblate (Polish)
Currently translated at 85.9% (16506 of 19203 strings)
2025-03-03 05:55:04 +01:00
Kevin Rojas Costa Rica
ea14f8fd67 Translated using Weblate (Spanish)
Currently translated at 74.9% (14388 of 19203 strings)
2025-03-02 19:50:52 +01:00
Kevin Rojas Costa Rica
cecbe8aeb3 Translated using Weblate (Spanish)
Currently translated at 74.8% (14374 of 19203 strings)
2025-03-02 05:17:45 +01:00
Kevin Rojas Costa Rica
bde5140d00 Translated using Weblate (Spanish)
Currently translated at 74.8% (14372 of 19203 strings)
2025-03-02 04:11:21 +01:00
Daniel Stasiak
b4fdfb2184 Translated using Weblate (Polish)
Currently translated at 85.8% (16488 of 19203 strings)
2025-03-02 00:24:21 +01:00
Daniel Stasiak
05594baea5 Translated using Weblate (Polish)
Currently translated at 85.8% (16478 of 19203 strings)
2025-03-01 21:24:12 +01:00
xvy
406ee85a32 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-03-01 08:04:38 +01:00
Daniel Stasiak
f7d7aed8ff Translated using Weblate (Polish)
Currently translated at 85.7% (16457 of 19203 strings)
2025-03-01 00:19:26 +01:00
xvy
b3c2c92dbc Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-28 15:08:12 +01:00
xvy
abc9ac8b0a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-28 04:46:53 +01:00
xvy
16ac1c1bc8 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-28 04:44:16 +01:00
xvy
8ed9e39e32 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-28 04:42:57 +01:00
xvy
f72242ed47 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-28 04:41:43 +01:00
xvy
e02bb34c95 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-28 02:59:25 +01:00
xvy
781731bb7d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-28 02:54:23 +01:00
xvy
781cefa5d2 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-28 02:52:03 +01:00
xvy
a6669dff12 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-28 02:47:32 +01:00
xvy
136a867939 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-28 02:42:18 +01:00
Daniel Stasiak
ae22a78fc3 Translated using Weblate (Polish)
Currently translated at 85.6% (16439 of 19203 strings)
2025-02-28 02:42:15 +01:00
Kevin Rojas Costa Rica
53408496e5 Translated using Weblate (Spanish)
Currently translated at 74.8% (14367 of 19203 strings)
2025-02-28 02:42:13 +01:00
xvy
759635947d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-27 15:31:18 +01:00
xvy
b0939becc9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-27 09:21:28 +01:00
xvy
42d3b81f18 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-27 08:43:39 +01:00
xvy
bd5beff711 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-27 07:50:33 +01:00
xvy
4f298d55fc Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-27 04:45:19 +01:00
xvy
cddf1c8a3b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-27 01:55:31 +01:00
Daniel Stasiak
5dbb45e08f Translated using Weblate (Polish)
Currently translated at 85.4% (16404 of 19203 strings)
2025-02-27 01:55:28 +01:00
ilya
dd13229ce4 Translated using Weblate (Russian)
Currently translated at 100.0% (612 of 612 strings)
2025-02-27 01:55:28 +01:00
xvy
4edeb85d97 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-26 09:05:50 +01:00
Burak Hüseyin Ekseli
59fc1a7cf5 Translated using Weblate (Turkish)
Currently translated at 32.0% (6157 of 19203 strings)
2025-02-26 09:05:48 +01:00
xvy
d690d061d2 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-26 06:51:49 +01:00
xvy
0ce85fe6c8 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-26 06:20:14 +01:00
Daniel Stasiak
fab0f57a28 Translated using Weblate (Polish)
Currently translated at 85.3% (16387 of 19203 strings)
2025-02-26 01:21:00 +01:00
Daniel Stasiak
b181555d23 Translated using Weblate (Polish)
Currently translated at 85.3% (16382 of 19203 strings)
2025-02-25 23:03:43 +01:00
Renamed1986
c02a8a37d3 Translated using Weblate (Russian)
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-25 16:39:06 +01:00
Nut.andor
b341d7e6f1 Pull Request #86: Anti cheat checksum 2025-02-25 15:32:58 +01:00
OMGeeky
31f25a963f fix whitespace formatting
Signed-off-by: OMGeeky <aalaalgmx@gmail.com>
2025-02-25 15:28:52 +01:00
Renamed1986
4e7ecb5c85 Translated using Weblate (Russian)
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-25 15:11:52 +01:00
xvy
aafff1dab6 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-25 09:43:21 +01:00
xvy
36c99a861d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-25 08:47:01 +01:00
xvy
27c4de04db Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-25 07:14:41 +01:00
xvy
ae617c94fe Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-25 04:15:34 +01:00
xvy
3f6f76f5cd Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-25 03:15:57 +01:00
Burak Hüseyin Ekseli
adf3215e3a Translated using Weblate (Turkish)
Currently translated at 31.9% (6143 of 19203 strings)
2025-02-25 00:03:11 +01:00
Burak Hüseyin Ekseli
0b9be84c80 Translated using Weblate (Turkish)
Currently translated at 31.6% (6087 of 19203 strings)
2025-02-24 23:01:20 +01:00
Burak Hüseyin Ekseli
e58c0db0f2 Translated using Weblate (Turkish)
Currently translated at 31.6% (6082 of 19203 strings)
2025-02-24 22:56:04 +01:00
Daniel Stasiak
1f33eab415 Translated using Weblate (Polish)
Currently translated at 85.2% (16376 of 19203 strings)
2025-02-24 22:56:02 +01:00
ilya
c389100211 Translated using Weblate (Russian)
Currently translated at 100.0% (612 of 612 strings)
2025-02-24 22:56:00 +01:00
xvy
0544940b9b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-24 21:21:13 +01:00
Daniel Stasiak
70acf9303f Translated using Weblate (Polish)
Currently translated at 85.2% (16372 of 19203 strings)
2025-02-24 21:21:11 +01:00
ilya
159b82a75e Translated using Weblate (Russian)
Currently translated at 100.0% (612 of 612 strings)
2025-02-24 21:21:09 +01:00
OMGeeky
30030031b2 add checksum to savegame to track if the savegame has been modified
Signed-off-by: OMGeeky <aalaalgmx@gmail.com>
2025-02-24 21:04:22 +01:00
xvy
4a33bac877 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-24 06:07:27 +01:00
Daniel Stasiak
6999e08d95 Translated using Weblate (Polish)
Currently translated at 85.1% (16352 of 19203 strings)
2025-02-24 06:07:26 +01:00
Daniel Stasiak
08357c227c Translated using Weblate (Polish)
Currently translated at 85.1% (16350 of 19203 strings)
2025-02-23 21:47:27 +01:00
ilya
c0b156a1e7 Translated using Weblate (Russian)
Currently translated at 100.0% (612 of 612 strings)
2025-02-23 21:47:25 +01:00
xvy
0ffae1e118 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-23 10:37:23 +01:00
Daniel Stasiak
d9af9e8883 Translated using Weblate (Polish)
Currently translated at 84.9% (16319 of 19203 strings)
2025-02-23 10:37:21 +01:00
ilya
57e3e16b89 Translated using Weblate (Russian)
Currently translated at 100.0% (612 of 612 strings)
2025-02-23 10:37:19 +01:00
Daniel Stasiak
806cc59521 Translated using Weblate (Polish)
Currently translated at 84.9% (16311 of 19203 strings)
2025-02-22 19:12:16 +01:00
Daniel Stasiak
0e42043b3d Translated using Weblate (Polish)
Currently translated at 84.8% (16289 of 19203 strings)
2025-02-22 03:16:37 +01:00
Daniel Stasiak
1020c7e0ed Translated using Weblate (Polish)
Currently translated at 84.7% (16279 of 19203 strings)
2025-02-21 22:21:35 +01:00
xvy
c65b99ad86 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-21 10:29:37 +01:00
Burak Hüseyin Ekseli
5bd06db0b0 Translated using Weblate (Turkish)
Currently translated at 31.6% (6081 of 19203 strings)
2025-02-21 10:29:36 +01:00
Daniel Stasiak
a6cd41c170 Translated using Weblate (Polish)
Currently translated at 84.7% (16275 of 19203 strings)
2025-02-20 21:59:18 +01:00
Burak Hüseyin Ekseli
5fb7ffef30 Translated using Weblate (Turkish)
Currently translated at 31.5% (6061 of 19203 strings)
2025-02-20 11:03:14 +01:00
xvy
8230667037 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-20 10:25:25 +01:00
Burak Hüseyin Ekseli
1a9bddfb08 Translated using Weblate (Turkish)
Currently translated at 31.4% (6047 of 19203 strings)
2025-02-20 10:25:24 +01:00
xvy
634ff7afaf Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-20 08:52:00 +01:00
xvy
25260bf8c1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-20 06:58:55 +01:00
Daniel Stasiak
f52e88403c Translated using Weblate (Polish)
Currently translated at 84.6% (16252 of 19203 strings)
2025-02-20 02:36:47 +01:00
Daniel Stasiak
1623228c59 Translated using Weblate (Polish)
Currently translated at 84.5% (16230 of 19203 strings)
2025-02-19 21:31:01 +01:00
Daniel Stasiak
765b76d01c Translated using Weblate (Polish)
Currently translated at 84.5% (16227 of 19203 strings)
2025-02-19 21:10:24 +01:00
Burak Hüseyin Ekseli
3ace8c8163 Translated using Weblate (Turkish)
Currently translated at 30.9% (5939 of 19203 strings)
2025-02-19 18:15:38 +01:00
Burak Hüseyin Ekseli
263ba70577 Translated using Weblate (Turkish)
Currently translated at 30.8% (5922 of 19203 strings)
2025-02-19 18:09:09 +01:00
Burak Hüseyin Ekseli
7787b4fa88 Translated using Weblate (Turkish)
Currently translated at 30.4% (5855 of 19203 strings)
2025-02-19 17:27:24 +01:00
Burak Hüseyin Ekseli
54d358a912 Translated using Weblate (Turkish)
Currently translated at 30.4% (5854 of 19203 strings)
2025-02-19 17:26:37 +01:00
Burak Hüseyin Ekseli
f5a4cc6298 Translated using Weblate (Turkish)
Currently translated at 30.4% (5853 of 19203 strings)
2025-02-19 17:26:10 +01:00
Burak Hüseyin Ekseli
c71db30dc9 Translated using Weblate (Turkish)
Currently translated at 30.4% (5851 of 19203 strings)
2025-02-19 17:25:09 +01:00
Burak Hüseyin Ekseli
522d63a7d5 Translated using Weblate (Turkish)
Currently translated at 30.4% (5850 of 19203 strings)
2025-02-19 17:24:59 +01:00
Burak Hüseyin Ekseli
77e2e64ee8 Translated using Weblate (Turkish)
Currently translated at 30.4% (5848 of 19203 strings)
2025-02-19 11:26:29 +01:00
xvy
19c4ae6180 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-19 09:51:00 +01:00
xvy
51c71c0106 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-19 08:08:45 +01:00
Burak Hüseyin Ekseli
05528f223f Translated using Weblate (Turkish)
Currently translated at 30.3% (5826 of 19203 strings)
2025-02-19 07:31:32 +01:00
Burak Hüseyin Ekseli
9cc5ae0d06 Translated using Weblate (Turkish)
Currently translated at 30.2% (5802 of 19203 strings)
2025-02-19 07:20:44 +01:00
xvy
c535d5339b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-19 06:16:40 +01:00
xvy
530c39bfe7 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-19 05:18:13 +01:00
xvy
ca8330936e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-19 04:40:39 +01:00
xvy
16ab2a9000 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-19 04:11:34 +01:00
xvy
7ee8808930 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-19 03:36:12 +01:00
xvy
25ed3aa460 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-19 02:38:07 +01:00
Daniel Stasiak
e6af5b9ff8 Translated using Weblate (Polish)
Currently translated at 84.4% (16226 of 19203 strings)
2025-02-18 22:25:19 +01:00
Daniel Stasiak
d05f9f1f17 Translated using Weblate (Polish)
Currently translated at 84.4% (16219 of 19203 strings)
2025-02-18 20:29:29 +01:00
xvy
dea3386a8b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-18 11:28:55 +01:00
xvy
dee12529d9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-18 07:51:06 +01:00
xvy
ff83682d4a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-18 01:56:23 +01:00
Daniel Stasiak
b5681143cb Translated using Weblate (Polish)
Currently translated at 84.3% (16201 of 19203 strings)
2025-02-18 00:33:46 +01:00
xvy
2f6b6e115e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-17 20:07:58 +01:00
Burak Hüseyin Ekseli
676e666f78 Translated using Weblate (Turkish)
Currently translated at 30.1% (5785 of 19203 strings)
2025-02-17 20:07:57 +01:00
xvy
d703dc2304 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-17 09:22:05 +01:00
xvy
ace4c2a65a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-17 09:18:13 +01:00
xvy
23189efa79 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-17 07:38:55 +01:00
xvy
bdbacfe74c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-17 04:44:10 +01:00
Daniel Stasiak
3dbc1f82e6 Translated using Weblate (Polish)
Currently translated at 84.3% (16197 of 19203 strings)
2025-02-16 21:47:38 +01:00
Daniel Stasiak
77709bfea2 Translated using Weblate (Polish)
Currently translated at 84.2% (16175 of 19203 strings)
2025-02-16 05:05:23 +01:00
Daniel Stasiak
db46ecf7af Translated using Weblate (Polish)
Currently translated at 84.1% (16160 of 19203 strings)
2025-02-15 20:47:35 +01:00
Daniel Stasiak
0dfbd223eb Translated using Weblate (Polish)
Currently translated at 84.1% (16155 of 19203 strings)
2025-02-14 22:11:38 +01:00
Daniel Stasiak
c166cb5c6d Translated using Weblate (Polish)
Currently translated at 84.0% (16146 of 19203 strings)
2025-02-14 21:09:41 +01:00
Burak Hüseyin Ekseli
49927184a2 Translated using Weblate (Turkish)
Currently translated at 29.8% (5728 of 19203 strings)
2025-02-14 14:04:48 +01:00
xvy
769600aff5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-14 09:18:30 +01:00
Burak Hüseyin Ekseli
1aaa813f80 Translated using Weblate (Turkish)
Currently translated at 29.7% (5719 of 19203 strings)
2025-02-14 09:18:28 +01:00
Daniel Stasiak
e49e54dfb0 Translated using Weblate (Polish)
Currently translated at 84.0% (16143 of 19203 strings)
2025-02-14 09:18:25 +01:00
Arnaud
1c761123ef Translated using Weblate (Finnish)
Currently translated at 1.5% (301 of 19203 strings)
2025-02-13 18:02:01 +01:00
Burak Hüseyin Ekseli
dafd984f4f Translated using Weblate (Turkish)
Currently translated at 29.6% (5697 of 19203 strings)
2025-02-13 18:01:58 +01:00
Daniel Stasiak
dd7dc9e4de Translated using Weblate (Polish)
Currently translated at 83.9% (16123 of 19203 strings)
2025-02-13 18:01:55 +01:00
xvy
8d4b35c929 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-12 09:02:02 +01:00
Daniel Stasiak
f0b94fa560 Translated using Weblate (Polish)
Currently translated at 83.8% (16106 of 19203 strings)
2025-02-12 09:01:59 +01:00
xvy
b13a20de5a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-11 03:01:40 +01:00
Daniel Stasiak
8223afb1b4 Translated using Weblate (Polish)
Currently translated at 83.7% (16092 of 19203 strings)
2025-02-11 03:01:38 +01:00
VeridisQuo
21f049fc49 Translated using Weblate (Esperanto)
Currently translated at 72.0% (441 of 612 strings)
2025-02-10 16:01:57 +01:00
xvy
13ce88d7dd Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-10 16:01:56 +01:00
Daniel Stasiak
5dc7c8d6a1 Translated using Weblate (Polish)
Currently translated at 83.7% (16078 of 19203 strings)
2025-02-10 16:01:53 +01:00
Daniel Stasiak
e989503238 Translated using Weblate (Polish)
Currently translated at 83.6% (16070 of 19203 strings)
2025-02-09 15:15:06 +01:00
xvy
0514f1facd Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-09 11:19:53 +01:00
Daniel Stasiak
6f81dcf97e Translated using Weblate (Polish)
Currently translated at 83.6% (16063 of 19203 strings)
2025-02-09 11:19:52 +01:00
xvy
5bb0290d10 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-08 19:10:15 +01:00
Anderson Nogueira Silva
a5a4d07282 Translated using Weblate (Portuguese (Brazil))
Currently translated at 81.4% (15647 of 19203 strings)
2025-02-08 19:10:13 +01:00
Daniel Stasiak
67a3670641 Translated using Weblate (Polish)
Currently translated at 83.5% (16039 of 19203 strings)
2025-02-08 19:10:12 +01:00
Miroslav Iliev
16bff85b1f Translated using Weblate (Bulgarian)
Currently translated at 75.0% (459 of 612 strings)
2025-02-07 21:02:09 +00:00
xvy
a14bcbf9a5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-07 21:02:08 +00:00
Daniel Stasiak
948a785474 Translated using Weblate (Polish)
Currently translated at 83.4% (16026 of 19203 strings)
2025-02-07 21:02:05 +00:00
VeridisQuo
d41e83dd86 Translated using Weblate (Esperanto)
Currently translated at 0.5% (109 of 19202 strings)
2025-02-06 12:02:17 +00:00
VeridisQuo
dea99e8770 Translated using Weblate (Esperanto)
Currently translated at 63.7% (390 of 612 strings)
2025-02-06 12:02:15 +00:00
xvy
e0d316f953 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-06 12:02:13 +00:00
Daniel Stasiak
b77eba6186 Translated using Weblate (Polish)
Currently translated at 83.2% (15978 of 19203 strings)
2025-02-06 12:02:10 +00:00
xvy
73e93046bc Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-05 07:02:06 +01:00
Daniel Stasiak
fd5568710c Translated using Weblate (Polish)
Currently translated at 83.1% (15966 of 19203 strings)
2025-02-04 04:13:31 +01:00
Ricky Tigg
6caf00b7ab Translated using Weblate (Finnish)
Currently translated at 1.5% (300 of 19203 strings)
2025-02-03 20:02:42 +00:00
xvy
59776a258e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-03 20:02:40 +00:00
Daniel Stasiak
2cd76c4e5f Translated using Weblate (Polish)
Currently translated at 83.0% (15950 of 19203 strings)
2025-02-03 20:02:37 +00:00
xvy
59fdab737f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-02 20:02:10 +01:00
Anderson Nogueira Silva
823959e801 Translated using Weblate (Portuguese (Brazil))
Currently translated at 81.3% (15624 of 19203 strings)
2025-02-02 20:02:08 +01:00
xvy
8c3fe791eb Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-01 19:10:04 +01:00
Anderson Nogueira Silva
2b98e295ed Translated using Weblate (Portuguese (Brazil))
Currently translated at 81.3% (15613 of 19203 strings)
2025-02-01 19:10:02 +01:00
xvy
dd0efabce9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-02-01 05:40:17 +01:00
Daniel Stasiak
a0b5516608 Translated using Weblate (Polish)
Currently translated at 83.0% (15939 of 19203 strings)
2025-01-31 23:02:04 +01:00
Ricky Tigg
401fd815f1 Translated using Weblate (Finnish)
Currently translated at 33.3% (204 of 612 strings)
2025-01-31 19:23:15 +01:00
Ricky Tigg
b83f339052 Translated using Weblate (Finnish)
Currently translated at 1.5% (300 of 19203 strings)
2025-01-31 19:23:14 +01:00
VeridisQuo
f41a104aa2 Translated using Weblate (Esperanto)
Currently translated at 0.5% (101 of 19202 strings)
2025-01-31 05:58:56 +01:00
VeridisQuo
a58db0d7a0 Translated using Weblate (Esperanto)
Currently translated at 61.2% (375 of 612 strings)
2025-01-31 05:58:56 +01:00
xvy
576438c5d6 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-31 05:58:55 +01:00
Daniel Stasiak
20b89ac790 Translated using Weblate (Polish)
Currently translated at 82.9% (15938 of 19203 strings)
2025-01-31 05:58:53 +01:00
Ron McNair
b0e3156592 Translated using Weblate (Esperanto)
Currently translated at 56.2% (344 of 612 strings)
2025-01-30 10:21:44 +01:00
Ron McNair
ad624f42a0 Translated using Weblate (Esperanto)
Currently translated at 0.5% (100 of 19202 strings)
2025-01-30 06:57:47 +01:00
Ron McNair
7c5dc8bfcb Translated using Weblate (Esperanto)
Currently translated at 54.5% (334 of 612 strings)
2025-01-30 06:57:45 +01:00
Daniel Stasiak
c65f503a24 Translated using Weblate (Polish)
Currently translated at 82.9% (15933 of 19203 strings)
2025-01-30 06:57:44 +01:00
xvy
c91b30bdcf Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-29 16:02:58 +01:00
Daniel Stasiak
f7c078b873 Translated using Weblate (Polish)
Currently translated at 82.9% (15924 of 19203 strings)
2025-01-29 16:02:56 +01:00
Daniel Stasiak
eeccddaf9c Translated using Weblate (Polish)
Currently translated at 82.7% (15885 of 19203 strings)
2025-01-28 01:52:47 +01:00
Daniel Stasiak
6ff9098630 Translated using Weblate (Polish)
Currently translated at 82.6% (15864 of 19203 strings)
2025-01-27 20:01:53 +00:00
xvy
bdf8811ea1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-26 20:01:53 +01:00
Daniel Stasiak
0e4ce207ad Translated using Weblate (Polish)
Currently translated at 82.4% (15836 of 19203 strings)
2025-01-26 20:01:51 +01:00
xvy
bb31dec6dd Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-25 19:11:14 +01:00
Daniel Stasiak
e63b684101 Translated using Weblate (Polish)
Currently translated at 82.2% (15804 of 19203 strings)
2025-01-25 00:06:28 +01:00
xvy
cac7ce19a0 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-24 11:23:57 +01:00
Daniel Stasiak
608e27cd92 Translated using Weblate (Polish)
Currently translated at 82.2% (15795 of 19203 strings)
2025-01-24 11:23:55 +01:00
xvy
5b6ef25d2c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-23 13:02:40 +01:00
Daniel Stasiak
2551ef08a0 Translated using Weblate (Polish)
Currently translated at 82.0% (15761 of 19203 strings)
2025-01-23 13:02:36 +01:00
xvy
69ebcb3aff Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-22 11:34:32 +01:00
Daniel Stasiak
4e73ec5560 Translated using Weblate (Polish)
Currently translated at 82.0% (15757 of 19203 strings)
2025-01-22 11:34:30 +01:00
xvy
a50b29c9f0 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-22 05:47:00 +00:00
Daniel Stasiak
770ebc3819 Translated using Weblate (Polish)
Currently translated at 82.0% (15748 of 19203 strings)
2025-01-22 05:46:47 +00:00
Kevin Rojas Costa Rica
1ee2b3615b Translated using Weblate (Spanish)
Currently translated at 74.7% (14360 of 19203 strings)
2025-01-22 05:46:45 +00:00
Kevin Rojas Costa Rica
33b30cddd9 Translated using Weblate (Spanish)
Currently translated at 74.7% (14345 of 19203 strings)
2025-01-21 05:39:09 +01:00
Palkia
f29fa33aa0 Translated using Weblate (Spanish)
Currently translated at 74.7% (14345 of 19203 strings)
2025-01-21 05:39:09 +01:00
Kevin Rojas Costa Rica
37227533ef Translated using Weblate (Spanish)
Currently translated at 100.0% (612 of 612 strings)
2025-01-21 05:35:07 +01:00
Daniel Stasiak
082cd32d4e Translated using Weblate (Polish)
Currently translated at 81.8% (15718 of 19203 strings)
2025-01-21 05:35:07 +01:00
Palkia
322a1f77aa Translated using Weblate (Spanish)
Currently translated at 74.7% (14345 of 19203 strings)
2025-01-21 05:35:06 +01:00
Wladimir Castañeda Sánchez
6015408b76 Translated using Weblate (Spanish)
Currently translated at 74.7% (14345 of 19203 strings)
2025-01-21 05:35:05 +01:00
Alejandro Ruiz Medina
f60c35b2eb Translated using Weblate (Spanish)
Currently translated at 74.7% (14345 of 19203 strings)
2025-01-21 05:35:05 +01:00
Kevin Rojas Costa Rica
1e8e4bdf76 Translated using Weblate (Spanish)
Currently translated at 74.7% (14345 of 19203 strings)
2025-01-21 05:35:05 +01:00
Ricky Tigg
a041dcd4d5 Translated using Weblate (Finnish)
Currently translated at 30.5% (187 of 612 strings)
2025-01-20 10:20:21 +01:00
Ricky Tigg
b463422264 Translated using Weblate (Finnish)
Currently translated at 1.5% (300 of 19203 strings)
2025-01-20 10:20:20 +01:00
Daniel Stasiak
b039e4966e Translated using Weblate (Polish)
Currently translated at 81.7% (15707 of 19203 strings)
2025-01-20 10:20:19 +01:00
Ricky Tigg
fceaf6aa89 Translated using Weblate (Finnish)
Currently translated at 0.3% (69 of 19203 strings)
2025-01-19 12:00:23 +01:00
Ricky Tigg
a6ce31c499 Translated using Weblate (Finnish)
Currently translated at 8.1% (50 of 612 strings)
2025-01-19 11:59:50 +01:00
Ricky Tigg
025d6cb3c6 Translated using Weblate (Finnish)
Currently translated at 0.3% (67 of 19203 strings)
2025-01-19 11:59:50 +01:00
Ricky Tigg
448add9cda Translated using Weblate (Finnish)
Currently translated at 7.8% (48 of 612 strings)
2025-01-19 11:48:35 +01:00
Ricky Tigg
86b521e5ec Translated using Weblate (Finnish)
Currently translated at 0.2% (57 of 19203 strings)
2025-01-19 11:48:35 +01:00
Ricky Tigg
7986e5280d Translated using Weblate (Finnish)
Currently translated at 7.6% (47 of 612 strings)
2025-01-19 11:47:33 +01:00
Ricky Tigg
9aa216ea6d Translated using Weblate (Finnish)
Currently translated at 0.2% (55 of 19203 strings)
2025-01-19 11:47:33 +01:00
Ricky Tigg
e2ea022f69 Translated using Weblate (Finnish)
Currently translated at 7.1% (44 of 612 strings)
2025-01-19 11:43:38 +01:00
Ricky Tigg
01886f1f54 Translated using Weblate (Finnish)
Currently translated at 0.2% (51 of 19203 strings)
2025-01-19 11:43:38 +01:00
Ricky Tigg
fc35dc0d2b Translated using Weblate (Finnish)
Currently translated at 0.2% (41 of 19203 strings)
2025-01-19 11:34:54 +01:00
Ricky Tigg
063cd69354 Translated using Weblate (Finnish)
Currently translated at 0.2% (40 of 19203 strings)
2025-01-19 11:34:36 +01:00
Ricky Tigg
6126d2ebb6 Translated using Weblate (Finnish)
Currently translated at 0.2% (39 of 19203 strings)
2025-01-19 11:34:21 +01:00
Ricky Tigg
a43e8daaf3 Translated using Weblate (Finnish)
Currently translated at 0.1% (38 of 19203 strings)
2025-01-19 11:33:53 +01:00
Ricky Tigg
1b1b33c73f Translated using Weblate (Finnish)
Currently translated at 0.1% (37 of 19203 strings)
2025-01-19 11:32:44 +01:00
Ricky Tigg
4a86673a59 Translated using Weblate (Finnish)
Currently translated at 0.1% (36 of 19203 strings)
2025-01-19 11:32:24 +01:00
Patryck Cardozo
577d1b9d58 Translated using Weblate (Portuguese (Brazil))
Currently translated at 81.1% (15584 of 19203 strings)
2025-01-19 11:32:23 +01:00
Patryck Cardozo
cd008a5629 Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.6% (610 of 612 strings)
2025-01-19 11:32:22 +01:00
n1ck
0a7225ebb2 Translated using Weblate (Spanish)
Currently translated at 99.6% (610 of 612 strings)
2025-01-18 19:12:47 +01:00
xvy
1036c7b659 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-18 19:12:47 +01:00
Patryck Cardozo
7ccadb3acf Translated using Weblate (Portuguese (Brazil))
Currently translated at 80.9% (15542 of 19203 strings)
2025-01-18 19:12:45 +01:00
Patryck Cardozo
ac3f4b1957 Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.6% (610 of 612 strings)
2025-01-18 19:12:43 +01:00
Ricky Tigg
a024440fcc Translated using Weblate (Finnish)
Currently translated at 0.1% (35 of 19203 strings)
2025-01-17 19:00:55 +00:00
xvy
7c064ac9dc Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-17 19:00:53 +00:00
Filip
255fd90757 Translated using Weblate (Polish)
Currently translated at 81.7% (15695 of 19203 strings)
2025-01-17 19:00:50 +00:00
Daniel Stasiak
d81d5470a2 Translated using Weblate (Polish)
Currently translated at 81.7% (15695 of 19203 strings)
2025-01-17 19:00:49 +00:00
Renamed1986
6293f1e3c9 Translated using Weblate (Russian)
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-16 19:00:37 +01:00
Daniel Stasiak
01d47c0ff7 Translated using Weblate (Polish)
Currently translated at 81.3% (15617 of 19203 strings)
2025-01-16 19:00:34 +01:00
xvy
5edeecc6e4 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-15 14:04:12 +01:00
xvy
048433caeb Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-15 07:22:35 +01:00
xvy
7f5e8dbd1f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-15 03:33:39 +01:00
Daniel Stasiak
3d7238e835 Translated using Weblate (Polish)
Currently translated at 81.1% (15586 of 19203 strings)
2025-01-15 03:33:38 +01:00
Bob Idle
300391b97b Translated using Weblate (German)
Currently translated at 91.6% (17597 of 19203 strings)
2025-01-15 03:33:36 +01:00
xvy
7795b12f85 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-14 05:00:47 +00:00
Daniel Stasiak
d94ec642ef Translated using Weblate (Polish)
Currently translated at 80.9% (15542 of 19203 strings)
2025-01-14 05:00:45 +00:00
Bob Idle
3642c425ca Translated using Weblate (Czech)
Currently translated at 99.6% (610 of 612 strings)
2025-01-12 23:24:12 +01:00
xvy
418b1827ab Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-12 23:24:12 +01:00
Daniel Stasiak
2293dc1f6d Translated using Weblate (Polish)
Currently translated at 80.8% (15517 of 19203 strings)
2025-01-12 23:24:09 +01:00
Bob Idle
b57f137334 Translated using Weblate (German)
Currently translated at 91.6% (17597 of 19203 strings)
2025-01-12 23:24:07 +01:00
Bob Idle
df7df92a7a Translated using Weblate (German)
Currently translated at 100.0% (612 of 612 strings)
2025-01-12 23:24:06 +01:00
Daniel Stasiak
6b1e74f2c9 Translated using Weblate (Polish)
Currently translated at 80.6% (15482 of 19203 strings)
2025-01-12 10:17:28 +01:00
Daniel Stasiak
a2c999e5af Translated using Weblate (Polish)
Currently translated at 80.4% (15445 of 19203 strings)
2025-01-11 20:19:36 +01:00
xvy
22426e4f39 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-11 19:14:14 +01:00
Daniel Stasiak
855aeed779 Translated using Weblate (Polish)
Currently translated at 80.3% (15426 of 19203 strings)
2025-01-11 02:04:15 +01:00
Filip
894bdb15c4 Translated using Weblate (Polish)
Currently translated at 80.1% (15390 of 19203 strings)
2025-01-10 20:40:45 +01:00
Lacrom
7208030e79 Translated using Weblate (French)
Currently translated at 84.3% (16207 of 19203 strings)
2025-01-10 20:40:43 +01:00
Lacrom
27dcd1bf5b Translated using Weblate (French)
Currently translated at 99.8% (611 of 612 strings)
2025-01-10 20:40:41 +01:00
A-Nicoladie[FR]
e8a7cd4bf7 Translated using Weblate (French)
Currently translated at 99.8% (611 of 612 strings)
2025-01-10 14:52:15 +01:00
Filip
2c5ec1179e Translated using Weblate (Polish)
Currently translated at 80.1% (15390 of 19203 strings)
2025-01-10 14:41:48 +01:00
Lacrom
e141383873 Translated using Weblate (French)
Currently translated at 99.8% (611 of 612 strings)
2025-01-10 14:41:46 +01:00
Filip
4b8a0d799f Translated using Weblate (Polish)
Currently translated at 80.1% (15390 of 19203 strings)
2025-01-09 23:37:10 +01:00
Daniel Stasiak
50a2f1c9ba Translated using Weblate (Polish)
Currently translated at 80.1% (15390 of 19203 strings)
2025-01-09 23:37:10 +01:00
Miroslav Iliev
67c872397a Translated using Weblate (Bulgarian)
Currently translated at 74.6% (457 of 612 strings)
2025-01-09 11:33:41 +01:00
Ludvík Remešek
9ddb4c9886 Translated using Weblate (Czech)
Currently translated at 76.3% (14653 of 19203 strings)
2025-01-09 11:33:39 +01:00
Filip
db8e186c67 Translated using Weblate (Polish)
Currently translated at 79.9% (15344 of 19203 strings)
2025-01-09 11:33:37 +01:00
Daniel Stasiak
39a428eeef Translated using Weblate (Polish)
Currently translated at 79.9% (15344 of 19203 strings)
2025-01-09 11:33:37 +01:00
Bob Idle
961bb44d0f Translated using Weblate (Arabic)
Currently translated at 99.6% (610 of 612 strings)
2025-01-08 21:40:07 +01:00
Bob Idle
aeca5fd252 Translated using Weblate (Czech)
Currently translated at 99.5% (609 of 612 strings)
2025-01-08 21:40:07 +01:00
Bob Idle
e57bc41353 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 99.6% (610 of 612 strings)
2025-01-08 21:40:07 +01:00
Bob Idle
9a758bd279 Translated using Weblate (Basque)
Currently translated at 60.4% (370 of 612 strings)
2025-01-08 21:40:06 +01:00
Filip
ed08c442ac Translated using Weblate (Polish)
Currently translated at 79.6% (15300 of 19203 strings)
2025-01-08 21:40:06 +01:00
Daniel Stasiak
409867553c Translated using Weblate (Polish)
Currently translated at 79.6% (15300 of 19203 strings)
2025-01-08 21:40:06 +01:00
Bob Idle
d8e73cac6b Translated using Weblate (German)
Currently translated at 91.6% (17591 of 19203 strings)
2025-01-08 21:40:04 +01:00
Raphi
074a3d088c Translated using Weblate (German)
Currently translated at 91.6% (17591 of 19203 strings)
2025-01-08 21:40:03 +01:00
Bob Idle
fb42410d7e Translated using Weblate (German)
Currently translated at 99.6% (610 of 612 strings)
2025-01-08 21:40:02 +01:00
Daniel Stasiak
d3323118e7 Translated using Weblate (Polish)
Currently translated at 79.5% (15283 of 19203 strings)
2025-01-07 22:48:41 +01:00
Bob Idle
5ae8027a18 Translated using Weblate (German)
Currently translated at 91.5% (17587 of 19203 strings)
2025-01-07 22:48:39 +01:00
Raphi
e390fcbdbc Translated using Weblate (German)
Currently translated at 91.5% (17587 of 19203 strings)
2025-01-07 22:48:39 +01:00
Daniel Stasiak
8f87fe8355 Translated using Weblate (Polish)
Currently translated at 79.4% (15257 of 19203 strings)
2025-01-07 02:08:54 +01:00
Daniel Stasiak
5fd930497b Translated using Weblate (Polish)
Currently translated at 100.0% (612 of 612 strings)
2025-01-07 02:08:52 +01:00
xvy
3da566d39c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-05 22:01:23 +00:00
Daniel Stasiak
ea23161d42 Translated using Weblate (Polish)
Currently translated at 79.1% (15195 of 19203 strings)
2025-01-05 22:01:21 +00:00
Ruben Rodriguez Martin
a1e4b55597 Translated using Weblate (Spanish)
Currently translated at 74.5% (14321 of 19203 strings)
2025-01-05 22:01:19 +00:00
xvy
62a54d4ee7 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-04 19:12:37 +01:00
Daniel Stasiak
2714514680 Translated using Weblate (Polish)
Currently translated at 78.8% (15147 of 19203 strings)
2025-01-04 19:12:35 +01:00
Miroslav Iliev
a1cb6b3b35 Translated using Weblate (Bulgarian)
Currently translated at 73.6% (451 of 612 strings)
2025-01-03 21:01:37 +00:00
Daniel Stasiak
cc44cb7027 Translated using Weblate (Polish)
Currently translated at 78.8% (15135 of 19203 strings)
2025-01-03 21:01:35 +00:00
xvy
fc1dedc570 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (612 of 612 strings)
2025-01-02 21:00:43 +01:00
Filip
d64fa699b4 Translated using Weblate (Polish)
Currently translated at 78.6% (15110 of 19203 strings)
2025-01-02 21:00:41 +01:00
Daniel Stasiak
d22bb347fe Translated using Weblate (Polish)
Currently translated at 78.6% (15110 of 19203 strings)
2025-01-02 21:00:40 +01:00
xvy
d6739f3253 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2025-01-01 19:00:42 +00:00
Daniel Stasiak
d810aef5cd Translated using Weblate (Polish)
Currently translated at 78.4% (15072 of 19203 strings)
2025-01-01 19:00:40 +00:00
xvy
a23c4d2165 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2024-12-31 16:09:18 +01:00
Daniel Stasiak
eb2e2ced32 Translated using Weblate (Polish)
Currently translated at 78.1% (15015 of 19203 strings)
2024-12-30 23:17:46 +01:00
Daniel Stasiak
046aa71d6b Translated using Weblate (Polish)
Currently translated at 78.0% (14984 of 19203 strings)
2024-12-30 19:00:58 +00:00
xvy
6b6177e078 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (612 of 612 strings)
2024-12-29 19:05:38 +01:00
xvy
a14df5951e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2024-12-29 19:05:37 +01:00
Daniel Stasiak
f312440541 Translated using Weblate (Polish)
Currently translated at 77.6% (14905 of 19203 strings)
2024-12-29 19:05:34 +01:00
Filip
b97cc203fd Translated using Weblate (Polish)
Currently translated at 100.0% (612 of 612 strings)
2024-12-29 19:05:33 +01:00
Daniel Stasiak
672cbc99db Translated using Weblate (Polish)
Currently translated at 77.5% (14883 of 19203 strings)
2024-12-28 19:11:56 +01:00
Miroslav Iliev
0858ac8f7f Translated using Weblate (Bulgarian)
Currently translated at 1.5% (297 of 19203 strings)
2024-12-27 22:20:56 +01:00
Daniel Stasiak
783bc925df Translated using Weblate (Polish)
Currently translated at 77.4% (14881 of 19203 strings)
2024-12-27 22:20:54 +01:00
Frei Tags
a3cce7f3b3 Translated using Weblate (German)
Currently translated at 91.5% (17580 of 19203 strings)
2024-12-27 22:20:51 +01:00
Miroslav Iliev
ae8c0b6d1e Translated using Weblate (Bulgarian)
Currently translated at 1.3% (252 of 19203 strings)
2024-12-27 13:00:36 +01:00
xvy
129ccfea7b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2024-12-27 13:00:32 +01:00
Daniel Stasiak
a58287e4d7 Translated using Weblate (Polish)
Currently translated at 77.3% (14852 of 19203 strings)
2024-12-27 13:00:29 +01:00
Daniel Stasiak
6bda903fe7 Translated using Weblate (Polish)
Currently translated at 100.0% (612 of 612 strings)
2024-12-27 13:00:26 +01:00
xvy
034a4faef5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2024-12-26 11:48:05 +01:00
Miroslav Iliev
4632ad011d Translated using Weblate (Bulgarian)
Currently translated at 73.2% (448 of 612 strings)
2024-12-26 07:00:47 +01:00
Miroslav Iliev
c9ce488c1b Translated using Weblate (Bulgarian)
Currently translated at 1.0% (206 of 19203 strings)
2024-12-26 07:00:46 +01:00
xvy
fe270d8c17 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2024-12-26 07:00:44 +01:00
Daniel Stasiak
bd971ff792 Translated using Weblate (Polish)
Currently translated at 77.1% (14815 of 19203 strings)
2024-12-26 07:00:41 +01:00
xvy
de7af46fb3 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2024-12-24 09:00:32 +01:00
aircqsj
b08e690150 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (19203 of 19203 strings)
2024-12-24 09:00:30 +01:00
xvy
9b256c1fca Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.3% (18887 of 19203 strings)
2024-12-22 20:03:05 +01:00
aircqsj
597683ed35 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.3% (18887 of 19203 strings)
2024-12-22 20:03:04 +01:00
xvy
a195722f6f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 97.8% (18783 of 19203 strings)
2024-12-22 10:05:34 +01:00
aircqsj
fa85588c48 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 97.8% (18783 of 19203 strings)
2024-12-22 10:05:33 +01:00
xvy
253d9bfd10 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 97.2% (18677 of 19203 strings)
2024-12-22 06:52:04 +01:00
aircqsj
7010321939 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 97.2% (18677 of 19203 strings)
2024-12-22 06:52:04 +01:00
xvy
59d63ad7f9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 97.1% (18649 of 19203 strings)
2024-12-22 05:53:42 +01:00
aircqsj
961d91ae53 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 97.0% (18632 of 19203 strings)
2024-12-22 05:05:52 +01:00
xvy
dd54abe829 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 96.9% (18616 of 19203 strings)
2024-12-21 19:12:38 +01:00
aircqsj
fd33f93baa Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 96.9% (18616 of 19203 strings)
2024-12-21 19:12:38 +01:00
aircqsj
8d4fedd911 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 96.5% (18531 of 19203 strings)
2024-12-21 13:00:34 +01:00
Daniel Stasiak
c28da080da Translated using Weblate (Polish)
Currently translated at 76.9% (14772 of 19203 strings)
2024-12-21 13:00:31 +01:00
aircqsj
bfe41bc7c4 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 96.0% (18447 of 19203 strings)
2024-12-20 09:28:39 +01:00
Daniel Stasiak
ac739622e5 Translated using Weblate (Polish)
Currently translated at 76.9% (14769 of 19203 strings)
2024-12-20 09:28:37 +01:00
Mateusz Mendel
44d4ef7430 Translated using Weblate (Polish)
Currently translated at 76.8% (14765 of 19203 strings)
2024-12-19 20:23:03 +01:00
Daniel Stasiak
9322969adf Translated using Weblate (Polish)
Currently translated at 76.8% (14765 of 19203 strings)
2024-12-19 20:23:02 +01:00
Daniel Stasiak
b038a2b139 Translated using Weblate (Polish)
Currently translated at 76.8% (14764 of 19203 strings)
2024-12-19 20:21:38 +01:00
Mateusz Mendel
bbd1afc0bf Translated using Weblate (Polish)
Currently translated at 76.8% (14764 of 19203 strings)
2024-12-19 20:21:38 +01:00
Mateusz Mendel
c3e23bdc6b Translated using Weblate (Polish)
Currently translated at 76.8% (14763 of 19203 strings)
2024-12-19 20:18:03 +01:00
Daniel Stasiak
1de35e79d3 Translated using Weblate (Polish)
Currently translated at 76.8% (14763 of 19203 strings)
2024-12-19 20:18:03 +01:00
Mateusz Mendel
423b3d5cb6 Translated using Weblate (Polish)
Currently translated at 76.8% (14762 of 19203 strings)
2024-12-19 17:28:40 +01:00
Daniel Stasiak
bb08710f50 Translated using Weblate (Polish)
Currently translated at 76.8% (14762 of 19203 strings)
2024-12-19 17:28:40 +01:00
xvy
5166fb44bf Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.8% (18415 of 19203 strings)
2024-12-19 17:24:14 +01:00
aircqsj
21e237791e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.8% (18415 of 19203 strings)
2024-12-19 17:24:13 +01:00
Mateusz Mendel
74cb3527d2 Translated using Weblate (Polish)
Currently translated at 76.8% (14761 of 19203 strings)
2024-12-19 17:24:12 +01:00
xvy
2ca1e8959c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.8% (18407 of 19203 strings)
2024-12-19 13:35:20 +01:00
aircqsj
26f03e46df Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.8% (18407 of 19203 strings)
2024-12-19 13:35:20 +01:00
aircqsj
eba4eef677 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.6% (18376 of 19203 strings)
2024-12-19 07:58:45 +01:00
xvy
25070675e5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.6% (18376 of 19203 strings)
2024-12-19 07:58:44 +01:00
Daniel Stasiak
8c2870dd2f Translated using Weblate (Polish)
Currently translated at 76.8% (14760 of 19203 strings)
2024-12-19 07:58:43 +01:00
Mateusz Mendel
fb3ccfa95c Translated using Weblate (Polish)
Currently translated at 76.8% (14760 of 19203 strings)
2024-12-18 21:54:00 +01:00
Daniel Stasiak
30ef789bf8 Translated using Weblate (Polish)
Currently translated at 76.8% (14760 of 19203 strings)
2024-12-18 21:53:59 +01:00
Daniel Stasiak
a68721b89d Translated using Weblate (Polish)
Currently translated at 76.8% (14758 of 19203 strings)
2024-12-18 21:27:18 +01:00
Mateusz Mendel
b49dbea3c0 Translated using Weblate (Polish)
Currently translated at 76.8% (14758 of 19203 strings)
2024-12-18 21:27:18 +01:00
Mateusz Mendel
49b2d75d30 Translated using Weblate (Polish)
Currently translated at 76.8% (14757 of 19203 strings)
2024-12-18 21:26:29 +01:00
Daniel Stasiak
fd46024890 Translated using Weblate (Polish)
Currently translated at 76.8% (14757 of 19203 strings)
2024-12-18 21:26:29 +01:00
Mateusz Mendel
a6e1e8c5f3 Translated using Weblate (Polish)
Currently translated at 76.8% (14756 of 19203 strings)
2024-12-18 21:23:47 +01:00
xvy
dd786d561d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (612 of 612 strings)
2024-12-18 21:00:25 +01:00
aircqsj
e4d395ff2f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.6% (18367 of 19203 strings)
2024-12-18 21:00:23 +01:00
Daniel Stasiak
41bfd3186d Translated using Weblate (Polish)
Currently translated at 76.8% (14755 of 19203 strings)
2024-12-18 21:00:21 +01:00
Mateusz Mendel
08992142ae Translated using Weblate (Polish)
Currently translated at 76.8% (14755 of 19203 strings)
2024-12-17 20:47:42 +01:00
Daniel Stasiak
89736c1dd2 Translated using Weblate (Polish)
Currently translated at 76.8% (14755 of 19203 strings)
2024-12-17 20:47:42 +01:00
Mateusz Mendel
469ee9435d Translated using Weblate (Polish)
Currently translated at 76.8% (14750 of 19203 strings)
2024-12-17 19:58:04 +01:00
Daniel Stasiak
8fcdb29078 Translated using Weblate (Polish)
Currently translated at 76.8% (14750 of 19203 strings)
2024-12-17 19:58:04 +01:00
Mateusz Mendel
ac861ff575 Translated using Weblate (Polish)
Currently translated at 76.8% (14749 of 19203 strings)
2024-12-17 17:28:44 +01:00
Daniel Stasiak
5be353d52c Translated using Weblate (Polish)
Currently translated at 76.8% (14749 of 19203 strings)
2024-12-17 17:28:43 +01:00
Daniel Stasiak
3f27b198ed Translated using Weblate (Polish)
Currently translated at 76.8% (14748 of 19203 strings)
2024-12-17 17:27:29 +01:00
Mateusz Mendel
24cbbd1149 Translated using Weblate (Polish)
Currently translated at 76.8% (14748 of 19203 strings)
2024-12-17 17:27:28 +01:00
Mateusz Mendel
68b495b753 Translated using Weblate (Polish)
Currently translated at 76.7% (14747 of 19203 strings)
2024-12-17 17:25:42 +01:00
Daniel Stasiak
47959f28a8 Translated using Weblate (Polish)
Currently translated at 76.7% (14747 of 19203 strings)
2024-12-17 17:25:42 +01:00
Daniel Stasiak
2f0c0cd3f6 Translated using Weblate (Polish)
Currently translated at 76.7% (14746 of 19203 strings)
2024-12-17 17:24:40 +01:00
Mateusz Mendel
da9b758f13 Translated using Weblate (Polish)
Currently translated at 76.7% (14746 of 19203 strings)
2024-12-17 17:24:40 +01:00
xvy
b141bc0ded Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (612 of 612 strings)
2024-12-17 17:19:14 +01:00
Ricky Tigg
5943ef866d Translated using Weblate (Finnish)
Currently translated at 6.8% (42 of 612 strings)
2024-12-17 17:19:14 +01:00
xvy
394f10be06 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 95.4% (18330 of 19203 strings)
2024-12-17 17:19:14 +01:00
Mateusz Mendel
2ee59101ef Translated using Weblate (Polish)
Currently translated at 76.7% (14745 of 19203 strings)
2024-12-17 17:19:12 +01:00
Daniel Stasiak
c1e250d801 Translated using Weblate (Polish)
Currently translated at 76.7% (14745 of 19203 strings)
2024-12-17 17:19:11 +01:00
227 changed files with 212149 additions and 28829 deletions

View File

@@ -2,12 +2,12 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 34
compileSdkVersion 35
defaultConfig {
applicationId "com.gpl.rpg.AndorsTrail"
minSdkVersion 14
targetSdkVersion 34
targetSdkVersion 35
}
buildTypes {

View File

@@ -3,8 +3,8 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gpl.rpg.AndorsTrail"
android:versionCode="80"
android:versionName="0.8.13dev"
android:versionCode="81"
android:versionName="0.8.14dev"
android:installLocation="auto"
>

View File

@@ -8,17 +8,25 @@ import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.util.AndroidStorage;
import com.gpl.rpg.AndorsTrail.util.Pair;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Insets;
import android.os.Build;
import android.os.Environment;
import android.util.Pair;
import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import androidx.annotation.RequiresApi;
public final class AndorsTrailApplication extends Application {
public static final boolean DEVELOPMENT_DEBUGRESOURCES = false;
@@ -26,13 +34,13 @@ public final class AndorsTrailApplication extends Application {
public static final boolean DEVELOPMENT_FORCE_CONTINUEGAME = false;
public static final boolean DEVELOPMENT_DEBUGBUTTONS = true;
public static final boolean DEVELOPMENT_FASTSPEED = false;
public static final boolean DEVELOPMENT_VALIDATEDATA = true;
public static final boolean DEVELOPMENT_VALIDATEDATA = false;
public static final boolean DEVELOPMENT_DEBUGMESSAGES = true;
public static final String CURRENT_VERSION_DISPLAY = "0.8.13dev";
public static final String CURRENT_VERSION_DISPLAY = "0.8.14dev";
public static final boolean IS_RELEASE_VERSION = !CURRENT_VERSION_DISPLAY.matches(".*[a-d].*");
public static final boolean DEVELOPMENT_INCOMPATIBLE_SAVEGAMES = DEVELOPMENT_DEBUGRESOURCES || DEVELOPMENT_DEBUGBUTTONS || DEVELOPMENT_FASTSPEED || !IS_RELEASE_VERSION;
public static final int DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION = 999;
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 80;
public static final int CURRENT_VERSION = DEVELOPMENT_INCOMPATIBLE_SAVEGAMES ? DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION : 81;
private final AndorsTrailPreferences preferences = new AndorsTrailPreferences();
private WorldContext world = new WorldContext();
@@ -57,13 +65,45 @@ public final class AndorsTrailApplication extends Application {
public void setWindowParameters(Activity activity) {
activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
if (preferences.fullscreen) {
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
public void setFullscreenMode(Activity activity) {
setFullscreenMode(preferences.fullscreen, activity.getWindow());
}
public static void setFullscreenMode(boolean fullscreen, Window window) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
final WindowInsetsController insetsController = window.getInsetsController();
if (insetsController != null) {
insetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
int insetType = WindowInsets.Type.statusBars();
if (fullscreen) {
insetsController.hide(insetType);
} else {
insetsController.show(insetType);
}
}
} else {
activity.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
if (fullscreen) {
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
window.setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
}
@RequiresApi(Build.VERSION_CODES.R)
public int getUsableTouchAreaInsetMask(){
int i = 0;
i |= WindowInsets.Type.displayCutout();
i |= WindowInsets.Type.navigationBars();
if (!preferences.fullscreen) {
i |= WindowInsets.Type.statusBars();
}
return i;
}
//Get default locale at startup, as somehow it seems that changing the app's
//configured locale impacts the value returned by Locale.getDefault() nowadays.
private final Locale defaultLocale = Locale.getDefault();
@@ -166,4 +206,18 @@ public final class AndorsTrailApplication extends Application {
controllers = new ControllerContext(this, world);
setup = new WorldSetup(world, controllers, getApplicationContext());
}
public void setUsablePadding(View root) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
root.setOnApplyWindowInsetsListener((v, insets) -> {
Insets bars = insets.getInsets(getUsableTouchAreaInsetMask());
int left = Math.max(bars.left, v.getPaddingLeft());
int top = Math.max(bars.top, v.getPaddingTop());
int right = Math.max(bars.right, v.getPaddingRight());
int bottom = Math.max(bars.bottom, v.getPaddingBottom());
v.setPadding(left, top, right, bottom);
return WindowInsets.CONSUMED;
});
}
}
}

View File

@@ -346,7 +346,6 @@ public final class Dialogs {
CustomDialogFactory.show(d);
}
@TargetApi(23)
private static boolean hasPermissions(final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (activity.getApplicationContext().checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED

View File

@@ -24,9 +24,7 @@ public final class AboutActivity extends AndorsTrailBaseActivity implements Imag
super.onCreate(savedInstanceState);
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
app.setWindowParameters(this);
setContentView(R.layout.about);
initializeView(this, R.layout.about, R.id.about_root);
final Resources res = getResources();
final TextView tv = (TextView) findViewById(R.id.about_contents);

View File

@@ -30,9 +30,7 @@ public final class ActorConditionInfoActivity extends AndorsTrailBaseActivity {
String conditionTypeID = getIntent().getData().getLastPathSegment();
ActorConditionType conditionType = world.actorConditionsTypes.getActorConditionType(conditionTypeID);
setContentView(R.layout.actorconditioninfo);
initializeView(this, R.layout.actorconditioninfo, R.id.actorconditioninfo_root);
TextView tv = (TextView) findViewById(R.id.actorconditioninfo_title);
tv.setText(conditionType.name);

View File

@@ -2,6 +2,10 @@ package com.gpl.rpg.AndorsTrail.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
@@ -19,5 +23,13 @@ public abstract class AndorsTrailBaseActivity extends Activity {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
app.setLocale(this);
}
protected void initializeView(Activity activity, @LayoutRes int layoutId, @IdRes int rootViewId) {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(activity);
app.setWindowParameters(activity);
activity.setContentView(layoutId);
View root = activity.findViewById(rootViewId);
app.setUsablePadding(root);
app.setFullscreenMode(activity);
}
}

View File

@@ -1,6 +1,11 @@
package com.gpl.rpg.AndorsTrail.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.fragment.app.FragmentActivity;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
@@ -19,4 +24,13 @@ public abstract class AndorsTrailBaseFragmentActivity extends FragmentActivity {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
app.setLocale(this);
}
protected void initializeView(Activity activity, @LayoutRes int layoutId, @IdRes int rootViewId) {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(activity);
app.setWindowParameters(activity);
activity.setContentView(layoutId);
View root = activity.findViewById(rootViewId);
app.setUsablePadding(root);
app.setFullscreenMode(activity);
}
}

View File

@@ -89,8 +89,7 @@ public final class BulkSelectionInterface extends AndorsTrailBaseActivity implem
interfaceType = BulkInterfaceType.valueOf(params.getString("interfaceType"));
int intialSelection = 1;
setContentView(R.layout.bulkselection);
initializeView(this, R.layout.bulkselection, R.id.bulkselection_root);
// initialize UI variables
TextView bulkselection_action_type = (TextView)findViewById(R.id.bulkselection_action_type);

View File

@@ -75,13 +75,11 @@ public final class ConversationActivity
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.conversation);
initializeView(this, R.layout.conversation, R.id.conversation_root);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
setFinishOnTouchOutside(false);
}
setFinishOnTouchOutside(false);
replyGroup = new RadioGroup(this);
replyGroup = new RadioGroup(this);
replyGroup.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, ListView.LayoutParams.WRAP_CONTENT));
statementList = (ListView) findViewById(R.id.conversation_statements);
statementList.addFooterView(replyGroup);

View File

@@ -365,7 +365,7 @@ public final class DebugInterface {
,new DebugButton("#2", new OnClickListener() {
@Override
public void onClick(View arg0) {
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "crackshot_hideout3", "South", 0, 0);
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "waytolake12", "tower_door", 0, 0);
}
})
@@ -373,21 +373,21 @@ public final class DebugInterface {
,new DebugButton("#3", new OnClickListener() {
@Override
public void onClick(View arg0) {
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "fallhaven_derelict2", "up", 0, 0);
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "galmore_cavea", "up", 0, 0);
}
})
,new DebugButton("#4", new OnClickListener() {
@Override
public void onClick(View arg0) {
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "loneford4", "south", 0, 0);
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "galmore_35", "south", 11, 0);
}
})
,new DebugButton("#5", new OnClickListener() {
@Override
public void onClick(View arg0) {
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "waytogalmore1", "entrance2", 0, 0);
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "way_to_sullengard_west_5", "east", 0, 5);
}
})
@@ -408,21 +408,42 @@ public final class DebugInterface {
,new DebugButton("#8", new OnClickListener() {
@Override
public void onClick(View arg0) {
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "galmore_86", "west", 0, 5);
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "wayto_feygard_duleian_2", "south", 0, 5);
}
})
,new DebugButton("#9", new OnClickListener() {
@Override
public void onClick(View arg0) {
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "elm_2f_2", "west", 5, 0);
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "galmore_58", "north", 0, 0);
}
})
,new DebugButton("#10", new OnClickListener() {
@Override
public void onClick(View arg0) {
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "laerothprison3", "south", 2, 0);
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "moesforest_03", "north1", 0, 0);
}
})
,new DebugButton("#11", new OnClickListener() {
@Override
public void onClick(View arg0) {
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "galmore_17", "outside", 0, 0);
}
})
,new DebugButton("#12", new OnClickListener() {
@Override
public void onClick(View arg0) {
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "galmore_48", "west", 0, 10);
}
})
,new DebugButton("#13", new OnClickListener() {
@Override
public void onClick(View arg0) {
controllerContext.movementController.placePlayerAsyncAt(MapObject.MapObjectType.newmap, "wild18", "south", 6, 0);
}
})

View File

@@ -38,10 +38,7 @@ public final class DisplayWorldMapActivity extends AndorsTrailBaseActivity {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
if (!app.isInitialized()) { finish(); return; }
this.world = app.getWorld();
app.setWindowParameters(this);
setContentView(R.layout.displayworldmap);
initializeView(this, R.layout.displayworldmap, R.id.worldmap_root);
displayworldmap_webview = (WebView) findViewById(R.id.displayworldmap_webview);
displayworldmap_webview.setBackgroundColor(ThemeHelper.getThemeColor(this, R.attr.ui_theme_displayworldmap_bg_color));

View File

@@ -29,10 +29,7 @@ public final class HeroinfoActivity extends AndorsTrailBaseFragmentActivity {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
if (!app.isInitialized()) { finish(); return; }
this.world = app.getWorld();
app.setWindowParameters(this);
setContentView(R.layout.tabbedlayout);
initializeView(this, R.layout.tabbedlayout, android.R.id.tabhost);
Resources res = getResources();

View File

@@ -14,6 +14,7 @@ import android.widget.TextView;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
import com.gpl.rpg.AndorsTrail.R;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.util.ThemeHelper;
import com.gpl.rpg.AndorsTrail.view.ItemEffectsView;
@@ -45,7 +46,7 @@ public final class ItemInfoActivity extends AndorsTrailBaseActivity {
boolean buttonEnabled = params.getBoolean("buttonEnabled");
boolean moreButtonEnabled = params.getBoolean("moreActions");
setContentView(R.layout.iteminfo);
initializeView(this, R.layout.iteminfo, R.id.iteminfo_root);
TextView tv = (TextView) findViewById(R.id.iteminfo_title);
tv.setText(itemType.getName(world.model.player));
@@ -54,7 +55,7 @@ public final class ItemInfoActivity extends AndorsTrailBaseActivity {
tv = (TextView) findViewById(R.id.iteminfo_description);
String description = itemType.getDescription();
if (description != null) {
tv.setText(description);
tv.setText(description.replace(Constants.PLACEHOLDER_PLAYERNAME, world.model.player.getName()));
tv.setVisibility(View.VISIBLE);
} else {
tv.setVisibility(View.GONE);

View File

@@ -37,7 +37,7 @@ public final class LevelUpActivity extends AndorsTrailBaseActivity {
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.levelup);
initializeView(this, R.layout.levelup, R.id.levelup_root);
levelup_title = (TextView) findViewById(R.id.levelup_title);
levelup_description = (TextView) findViewById(R.id.levelup_description);

View File

@@ -70,7 +70,7 @@ public final class LoadSaveActivity extends AndorsTrailBaseActivity implements O
String loadsave = getIntent().getData().getLastPathSegment();
isLoading = (loadsave.equalsIgnoreCase("load"));
setContentView(R.layout.loadsave);
initializeView(this, R.layout.loadsave, R.id.loadsave_root);
TextView tv = (TextView) findViewById(R.id.loadsave_title);
if (isLoading) {

View File

@@ -36,8 +36,7 @@ public final class LoadingActivity extends AndorsTrailBaseActivity implements On
setTheme(ThemeHelper.getBaseTheme());
super.onCreate(savedInstanceState);
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
app.setWindowParameters(this);
setContentView(R.layout.startscreen);
initializeView(this, R.layout.startscreen, R.id.startscreen_fragment_container);
TextView tv = (TextView) findViewById(R.id.startscreen_version);
tv.setVisibility(View.GONE);

View File

@@ -91,9 +91,9 @@ public final class MainActivity
AndorsTrailPreferences preferences = app.getPreferences();
this.world = app.getWorld();
this.controllers = app.getControllerContext();
app.setWindowParameters(this);
setContentView(R.layout.main);
initializeView(this, R.layout.main, R.id.main_container);
mainview = (MainView) findViewById(R.id.main_mainview);
statusview = (StatusView) findViewById(R.id.main_statusview);
combatview = (CombatView) findViewById(R.id.main_combatview);

View File

@@ -34,7 +34,7 @@ public final class MonsterEncounterActivity extends AndorsTrailBaseActivity {
return;
}
setContentView(R.layout.monsterencounter);
initializeView(this, R.layout.monsterencounter, R.id.monsterencounter_root);
CharSequence difficulty = getText(MonsterInfoActivity.getMonsterDifficultyResource(controllers, monster));

View File

@@ -43,7 +43,7 @@ public final class MonsterInfoActivity extends AndorsTrailBaseActivity {
this.controllers = app.getControllerContext();
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.monsterinfo);
initializeView(this, R.layout.monsterinfo, R.id.monsterinfo_root);
monsterinfo_title = (TextView) findViewById(R.id.monsterinfo_title);
monsterinfo_difficulty = (TextView) findViewById(R.id.monsterinfo_difficulty);

View File

@@ -13,17 +13,16 @@ public final class Preferences extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(ThemeHelper.getBaseTheme());
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
if (app.getPreferences().fullscreen) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
app.setWindowParameters(this);
super.onCreate(savedInstanceState);
app.setFullscreenMode(this);
app.setLocale(this);
addPreferencesFromResource(R.xml.preferences);
}
@Override

View File

@@ -23,9 +23,8 @@ public final class ShopActivity extends AndorsTrailBaseFragmentActivity {
AndorsTrailApplication app = AndorsTrailApplication.getApplicationFromActivity(this);
if (!app.isInitialized()) { finish(); return; }
app.setWindowParameters(this);
setContentView(R.layout.tabbedlayout);
initializeView(this, R.layout.tabbedlayout, android.R.id.tabhost);
final Resources res = getResources();

View File

@@ -31,9 +31,7 @@ public final class SkillInfoActivity extends AndorsTrailBaseActivity {
final WorldContext world = app.getWorld();
final Player player = world.model.player;
app.setWindowParameters(this);
setContentView(R.layout.skill_info_view);
initializeView(this, R.layout.skill_info_view, R.id.skillinfo_root);
final Resources res = getResources();
final Intent intent = getIntent();

View File

@@ -21,6 +21,8 @@ import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
import android.view.KeyEvent;
@@ -49,9 +51,9 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i
final Resources res = getResources();
TileManager tileManager = app.getWorld().tileManager;
tileManager.setDensity(res);
app.setWindowParameters(this);
setContentView(R.layout.startscreen);
initializeView(this, R.layout.startscreen, R.id.startscreen_fragment_container);
app.setFullscreenMode(this);
if (findViewById(R.id.startscreen_fragment_container) != null) {
StartScreenActivity_MainMenu mainMenu = new StartScreenActivity_MainMenu();
@@ -67,9 +69,11 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i
tv = (TextView) findViewById(R.id.startscreen_version);
app.setUsablePadding(tv);
tv.setText('v' + AndorsTrailApplication.CURRENT_VERSION_DISPLAY);
development_version = (TextView) findViewById(R.id.startscreen_dev_version);
app.setUsablePadding((View) development_version.getParent());
if (AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAMES) {
development_version.setText(R.string.startscreen_incompatible_savegames);
development_version.setVisibility(View.VISIBLE);
@@ -96,6 +100,10 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i
}
});
}
View titleLogo = findViewById(R.id.title_logo);
if (titleLogo != null) {
app.setUsablePadding(titleLogo);
}
if (development_version.getVisibility() == View.VISIBLE) {
development_version.setText(development_version.getText()
@@ -112,7 +120,7 @@ public final class StartScreenActivity extends AndorsTrailBaseFragmentActivity i
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, int[] grantResults) {
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
final CustomDialog d = CustomDialogFactory.createDialog(this,

View File

@@ -59,7 +59,6 @@ public class StartScreenActivity_MainMenu extends Fragment {
updatePreferences(false);
super.onCreateView(inflater, container, savedInstanceState);
if (container != null) {
container.removeAllViews();
}
@@ -196,7 +195,6 @@ public class StartScreenActivity_MainMenu extends Fragment {
}
@TargetApi(29)
public void migrateDataOnDemand(final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
@@ -232,7 +230,6 @@ public class StartScreenActivity_MainMenu extends Fragment {
private static final int READ_EXTERNAL_STORAGE_REQUEST=1;
private static final int WRITE_EXTERNAL_STORAGE_REQUEST=2;
@TargetApi(23)
public static void checkAndRequestPermissions(final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
if (activity.getApplicationContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

View File

@@ -3,6 +3,7 @@ package com.gpl.rpg.AndorsTrail.activity.fragment;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
@@ -39,8 +40,7 @@ public class StartScreenActivity_NewGame extends Fragment {
}
View root = inflater.inflate(R.layout.startscreen_newgame, container, false);
startscreen_enterheroname = (TextView) root.findViewById(R.id.startscreen_enterheroname);
new SpinnerEmulator(root, R.id.startscreen_mode_selector_button, R.array.startscreen_mode_selector, R.string.startscreen_game_mode) {

View File

@@ -1,5 +1,6 @@
package com.gpl.rpg.AndorsTrail.context;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import com.gpl.rpg.AndorsTrail.model.ModelContainer;
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionTypeCollection;
import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection;
@@ -13,6 +14,8 @@ import com.gpl.rpg.AndorsTrail.resource.ConversationLoader;
import com.gpl.rpg.AndorsTrail.resource.VisualEffectCollection;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
import java.security.DigestException;
public final class WorldContext {
//Objectcollections
public final ConversationLoader conversationLoader;
@@ -62,4 +65,11 @@ public final class WorldContext {
public void resetForNewGame() {
maps.resetForNewGame();
}
public byte[] getChecksum() throws DigestException {
ChecksumBuilder checksumBuilder = new ChecksumBuilder();
model.addToChecksum(checksumBuilder);
maps.addToChecksum(checksumBuilder, this);
return checksumBuilder.build();
}
}

View File

@@ -0,0 +1,115 @@
package com.gpl.rpg.AndorsTrail.model;
import android.os.Build;
import com.gpl.rpg.AndorsTrail.util.L;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class ChecksumBuilder {
public static final int CHECKSUM_LENGTH = 32;// 256 bits (depends on the hash algorithm)
public static final String CHECKSUM_ALGORITHM = "SHA-256"; //Should be available in all Android versions
private ByteBuffer buffer;
private final MessageDigest digest;
private ChecksumBuilder(int initialCapacity, ByteOrder byteOrder) {
buffer = ByteBuffer.allocate(initialCapacity);
buffer.order(byteOrder);
try {
digest = MessageDigest.getInstance(CHECKSUM_ALGORITHM); // Or SHA-512 for even stronger hash
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Hash algorithm not found", e);
}
}
private ChecksumBuilder(int initialCapacity) {
this(initialCapacity, ByteOrder.BIG_ENDIAN); // Default to big-endian
}
public ChecksumBuilder() {
this(1024*10); // A reasonable default initial capacity
}
// --- Methods for adding different data types ---
public ChecksumBuilder add(String value) {
if (value != null) {
byte[] bytes;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
bytes = value.getBytes(StandardCharsets.UTF_8);
} else {
bytes = value.getBytes();
}
add(bytes);
} else {
add(-1); // Use -1 to represent a null string
}
return this;
}
public ChecksumBuilder add(byte[] bytes) {
add(bytes.length); // Add length prefix
ensureCapacity(bytes.length + 4); // +4 for length prefix (int)
buffer.put(bytes);
return this;
}
public ChecksumBuilder add(boolean value) {
ensureCapacity(1);
buffer.put(value ? (byte) 1 : (byte) 0);
return this;
}
public ChecksumBuilder add(long value) {
ensureCapacity(8);
buffer.putLong(value);
return this;
}
public ChecksumBuilder add(int value) {
ensureCapacity(4);
buffer.putInt(value);
return this;
}
public ChecksumBuilder add(float value) {
ensureCapacity(8);
buffer.putFloat(value);
return this;
}
public ChecksumBuilder add(double value) {
ensureCapacity(4);
buffer.putDouble(value);
return this;
}
// --- Method to finalize and get the checksum ---
public byte[] build() throws DigestException {
buffer.flip(); // Prepare for reading
digest.update(buffer);// Only use the actually used part of the buffer
buffer.flip(); // Prepare for further writing
return digest.digest();
}
// --- Utility method to ensure sufficient capacity ---
private void ensureCapacity(int required) {
if (buffer.remaining() < required) {
int newCapacity = Math.max(buffer.capacity() * 2, buffer.capacity() + required);
ByteBuffer newBuffer = ByteBuffer.allocate(newCapacity);
newBuffer.order(buffer.order());
buffer.flip(); // Prepare for reading
newBuffer.put(buffer); // Copy existing data
buffer = newBuffer; // Assign the new buffer to the field
}
}
}

View File

@@ -3,6 +3,7 @@ package com.gpl.rpg.AndorsTrail.model;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -22,6 +23,8 @@ import com.gpl.rpg.AndorsTrail.model.quest.Quest;
import com.gpl.rpg.AndorsTrail.util.HashMapHelper;
public final class GameStatistics {
private boolean isAlteredSavegame = false;
private byte[] checksum = new byte[ChecksumBuilder.CHECKSUM_LENGTH];
private int deaths = 0;
private final HashMap<String, Integer> killedMonstersByTypeID = new HashMap<String, Integer>();
private final HashMap<String, Integer> killedMonstersByName = new HashMap<String, Integer>();
@@ -67,6 +70,7 @@ public final class GameStatistics {
public boolean hasUnlimitedLives() { return startLives == -1; }
public int getStartLives() { return startLives; }
public boolean getIsAlteredSavegame() { return isAlteredSavegame; }
public int getLivesLeft() { return hasUnlimitedLives() ? -1 : startLives - deaths; }
@@ -158,6 +162,18 @@ public final class GameStatistics {
}
};
public void setChecksum(byte[] checksum) {
if (checksum.length != ChecksumBuilder.CHECKSUM_LENGTH) throw new IllegalArgumentException("Invalid checksum length.");
this.checksum = checksum;
}
public boolean compareChecksum(byte[] checksum) {
return this.checksum.length == checksum.length && MessageDigest.isEqual(this.checksum, checksum);
}
public void markAsAlteredSavegame() {
isAlteredSavegame = true;
}
// ====== PARCELABLE ===================================================================
@@ -194,6 +210,11 @@ public final class GameStatistics {
this.startLives = src.readInt();
this.unlimitedSaves = src.readBoolean();
if (fileversion < 81) return;
this.isAlteredSavegame = src.readBoolean();
final int checksumLength = src.readInt();
this.checksum = new byte[checksumLength];
if( src.read(checksum) != checksumLength) throw new IOException("Failed to read full checksum.");
}
public void writeToParcel(DataOutputStream dest) throws IOException {
@@ -213,5 +234,29 @@ public final class GameStatistics {
dest.writeInt(spentGold);
dest.writeInt(startLives);
dest.writeBoolean(unlimitedSaves);
dest.writeBoolean(isAlteredSavegame);
dest.writeInt(checksum.length);
dest.write(checksum);
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(deaths);
Set<Entry<String, Integer> > set = killedMonstersByTypeID.entrySet();
builder.add(set.size());
for (Entry<String, Integer> e : set) {
builder.add(e.getKey());
builder.add(e.getValue());
}
set = usedItems.entrySet();
builder.add(set.size());
for (Entry<String, Integer> e : set) {
builder.add(e.getKey());
builder.add(e.getValue());
}
builder.add(spentGold);
builder.add(startLives);
builder.add(unlimitedSaves);
builder.add(isAlteredSavegame);
}
}

View File

@@ -51,4 +51,12 @@ public final class InterfaceData {
}
dest.writeUTF(selectedTabHeroInfo);
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(isMainActivityVisible);
builder.add(isInCombat);
builder.add(selectedPosition != null);
if (selectedPosition != null) selectedPosition.addToChecksum(builder);
builder.add(selectedTabHeroInfo);
}
}

View File

@@ -49,4 +49,11 @@ public final class ModelContainer {
statistics.writeToParcel(dest);
worldData.writeToParcel(dest);
}
public void addToChecksum(ChecksumBuilder builder){
player.addToChecksum(builder);
builder.add(currentMaps.map.name);
uiSelections.addToChecksum(builder);
statistics.addToChecksum(builder);
worldData.addToChecksum(builder);
}
}

View File

@@ -114,4 +114,13 @@ public final class WorldData {
dest.writeLong(e.getValue());
}
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(worldTime);
builder.add(timers.size());
for(Map.Entry<String, Long> e : timers.entrySet()) {
builder.add(e.getKey());
builder.add(e.getValue());
}
}
}

View File

@@ -5,6 +5,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
public final class ActorCondition {
public static final int MAGNITUDE_REMOVE_ALL = -99;
@@ -51,4 +52,11 @@ public final class ActorCondition {
dest.writeInt(magnitude);
dest.writeInt(duration);
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(conditionType.conditionTypeID);
builder.add(magnitude);
builder.add(duration);
}
}

View File

@@ -6,6 +6,7 @@ import java.io.IOException;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection;
import com.gpl.rpg.AndorsTrail.model.item.DropList;
@@ -193,4 +194,43 @@ public final class Monster extends Actor {
dest.writeBoolean(false);
}
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(getMonsterTypeID());
if (attackCost == monsterType.attackCost
&& attackChance == monsterType.attackChance
&& criticalSkill == monsterType.criticalSkill
&& criticalMultiplier == monsterType.criticalMultiplier
&& damagePotential.equals(monsterType.damagePotential)
&& blockChance == monsterType.blockChance
&& damageResistance == monsterType.damageResistance
) {
builder.add(false);
} else {
builder.add(true);
builder.add(attackCost);
builder.add(attackChance);
builder.add(criticalSkill);
builder.add(criticalMultiplier);
damagePotential.addToChecksum(builder);
builder.add(blockChance);
builder.add(damageResistance);
}
ap.addToChecksum(builder);
health.addToChecksum(builder);
position.addToChecksum(builder);
builder.add(conditions.size());
for (ActorCondition c : conditions) {
c.addToChecksum(builder);
}
builder.add(moveCost);
builder.add(forceAggressive);
if (shopItems != null) {
builder.add(true);
shopItems.addToChecksum(builder);
} else {
builder.add(false);
}
}
}

View File

@@ -19,6 +19,7 @@ import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
import com.gpl.rpg.AndorsTrail.model.ability.SkillCollection;
import com.gpl.rpg.AndorsTrail.model.item.DropListCollection;
@@ -475,5 +476,62 @@ public final class Player extends Actor {
dest.writeUTF(id);
dest.writeLong(savedVersion);
}
public void addToChecksum(ChecksumBuilder builder) {
//builder.add(baseTraits.iconID);// Do not add to checksum so that it can be changed without invalidating checksums
builder.add(baseTraits.maxAP);
builder.add(baseTraits.maxHP);
//builder.add(name);// Do not add to checksum so that it can be changed without invalidating checksums
builder.add(moveCost); // TODO: Should we really write this?
builder.add(baseTraits.attackCost);
builder.add(baseTraits.attackChance);
builder.add(baseTraits.criticalSkill);
builder.add(baseTraits.criticalMultiplier);
baseTraits.damagePotential.addToChecksum(builder);
builder.add(baseTraits.blockChance);
builder.add(baseTraits.damageResistance);
builder.add(baseTraits.moveCost);
ap.addToChecksum(builder);
health.addToChecksum(builder);
position.addToChecksum(builder);
builder.add(conditions.size());
for (ActorCondition c : conditions) {
c.addToChecksum(builder);
}
builder.add(immunities.size());
for (ActorCondition c : immunities) {
c.addToChecksum(builder);
}
lastPosition.addToChecksum(builder);
nextPosition.addToChecksum(builder);
builder.add(level);
builder.add(totalExperience);
inventory.addToChecksum(builder);
builder.add(baseTraits.useItemCost);
builder.add(baseTraits.reequipCost);
builder.add(skillLevels.size());
for (int i = 0; i < skillLevels.size(); ++i) {
builder.add(skillLevels.keyAt(i));
builder.add(skillLevels.valueAt(i));
}
builder.add(spawnMap);
builder.add(spawnPlace);
builder.add(questProgress.size());
for(Entry<String, LinkedHashSet<Integer> > e : questProgress.entrySet()) {
builder.add(e.getKey());
builder.add(e.getValue().size());
for(int progress : e.getValue()) {
builder.add(progress);
}
}
builder.add(availableSkillIncreases);
builder.add(alignments.size());
for(Entry<String, Integer> e : alignments.entrySet()) {
builder.add(e.getKey());
builder.add(e.getValue());
}
builder.add(id);
builder.add(savedVersion);
}
}

View File

@@ -5,6 +5,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForItemContainer;
public final class Inventory extends ItemContainer {
@@ -208,4 +209,21 @@ public final class Inventory extends ItemContainer {
}
}
}
public void addToChecksum(ChecksumBuilder builder) {
super.addToChecksum(builder);
builder.add(gold);
builder.add(NUM_WORN_SLOTS);
for(int i = 0; i < NUM_WORN_SLOTS; ++i) {
if (wear[i] != null) {
builder.add(wear[i].id);
}
}
builder.add(NUM_QUICK_SLOTS);
for(int i = 0; i < NUM_QUICK_SLOTS; ++i) {
if (quickitem[i] != null) {
builder.add(quickitem[i].id);
}
}
}
}

View File

@@ -8,6 +8,7 @@ import java.util.Collections;
import java.util.Comparator;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
public class ItemContainer {
@@ -42,6 +43,10 @@ public class ItemContainer {
dest.writeUTF(itemType.id);
dest.writeInt(quantity);
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(itemType.id);
builder.add(quantity);
}
}
public void addItem(ItemType itemType, int quantity) {
@@ -280,4 +285,10 @@ public class ItemContainer {
e.writeToParcel(dest);
}
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(items.size());
for (ItemEntry e : items) {
e.addToChecksum(builder);
}
}
}

View File

@@ -5,6 +5,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForItemContainer;
import com.gpl.rpg.AndorsTrail.util.Coord;
@@ -88,4 +89,12 @@ public final class Loot {
position.writeToParcel(dest);
dest.writeBoolean(isVisible);
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(exp);
builder.add(gold);
items.addToChecksum(builder);
position.addToChecksum(builder);
builder.add(isVisible);
}
}

View File

@@ -11,6 +11,7 @@ import java.util.List;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForMap;
import com.gpl.rpg.AndorsTrail.util.L;
@@ -99,4 +100,16 @@ public final class MapCollection {
map.writeToParcel(dest, world);
}
}
public void addToChecksum(ChecksumBuilder checksumBuilder, WorldContext world) {
List<PredefinedMap> mapsToExport = new ArrayList<PredefinedMap>();
for(PredefinedMap map : getAllMaps()) {
if (shouldSaveMap(world, map)) mapsToExport.add(map);
}
checksumBuilder.add(mapsToExport.size());
for(PredefinedMap map : mapsToExport) {
checksumBuilder.add(map.name);
map.addToChecksum(checksumBuilder, world);
}
}
}

View File

@@ -8,6 +8,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.actor.MonsterType;
import com.gpl.rpg.AndorsTrail.util.Coord;
@@ -140,4 +141,12 @@ public final class MonsterSpawnArea {
m.writeToParcel(dest);
}
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(isSpawning);
builder.add(monsters.size());
for (Monster m : monsters) {
m.addToChecksum(builder);
}
}
}

View File

@@ -12,6 +12,7 @@ import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.BloodSplatter;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.item.Loot;
@@ -398,4 +399,30 @@ public final class PredefinedMap {
dest.writeBoolean(visited);
dest.writeUTF(lastSeenLayoutHash);
}
public void addToChecksum(ChecksumBuilder builder, WorldContext world) {
if (shouldSaveMapData(world)) {
builder.add(true);
builder.add(spawnAreas.length);
for(MonsterSpawnArea a : spawnAreas) {
builder.add(a.areaID);
a.addToChecksum(builder);
}
builder.add(activeMapObjectGroups.size());
for(String s : activeMapObjectGroups) {
builder.add(s);
}
builder.add(groundBags.size());
for(Loot l : groundBags) {
l.addToChecksum(builder);
}
builder.add(currentColorFilter != null);
if (currentColorFilter != null) builder.add(currentColorFilter);
builder.add(lastVisitTime);
} else {
builder.add(false);
}
builder.add(visited);
builder.add(lastSeenLayoutHash);
}
}

View File

@@ -385,6 +385,7 @@ public final class ResourceLoader {
loader.prepareTileset(R.drawable.monsters_omi2, "monsters_omi2", sz8x3, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_phoenix01, "monsters_phoenix01", sz16x8, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_cats, "monsters_cats", new Size(10, 2), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.monsters_1x2, "monsters_1x2", new Size(10, 5), sz1x2, mTileSize);
/*INSERT_NPCS_TILESETS_HERE*/
loader.prepareTileset(R.drawable.map_bed_1, "map_bed_1", sz16x10, sz1x1, mTileSize);
@@ -399,6 +400,7 @@ public final class ResourceLoader {
loader.prepareTileset(R.drawable.map_cavewall_3, "map_cavewall_3", new Size(18, 6), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_cavewall_4, "map_cavewall_4", new Size(18, 6), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_cavewall_5, "map_cavewall_5", new Size(6, 6), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_cavewall_6, "map_cavewall_6", new Size(18, 6), sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_chair_table_1, "map_chair_table_1", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_chair_table_2, "map_chair_table_2", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_crate_1, "map_crate_1", mapTileSize, sz1x1, mTileSize);
@@ -427,6 +429,7 @@ public final class ResourceLoader {
loader.prepareTileset(R.drawable.map_indoor_2, "map_indoor_2", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_kitchen_1, "map_kitchen_1", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_outdoor_1, "map_outdoor_1", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_outdoor_2, "map_outdoor_2", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_pillar_1, "map_pillar_1", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_pillar_2, "map_pillar_2", mapTileSize, sz1x1, mTileSize);
loader.prepareTileset(R.drawable.map_pillar_3, "map_pillar_3", new Size(16, 10), sz1x1, mTileSize);

View File

@@ -8,7 +8,7 @@ import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader;
import com.gpl.rpg.AndorsTrail.resource.TranslationLoader;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames;
import com.gpl.rpg.AndorsTrail.util.Pair;
import android.util.Pair;
public final class ActorConditionsTypeParser extends JsonCollectionParserFor<ActorConditionType> {

View File

@@ -13,7 +13,7 @@ import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames;
import com.gpl.rpg.AndorsTrail.util.L;
import com.gpl.rpg.AndorsTrail.util.Pair;
import android.util.Pair;
public final class ConversationListParser extends JsonCollectionParserFor<Phrase> {

View File

@@ -11,7 +11,7 @@ import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames;
import com.gpl.rpg.AndorsTrail.util.L;
import com.gpl.rpg.AndorsTrail.util.Pair;
import android.util.Pair;
public final class DropListParser extends JsonCollectionParserFor<DropList> {

View File

@@ -8,7 +8,7 @@ import com.gpl.rpg.AndorsTrail.model.item.ItemCategory;
import com.gpl.rpg.AndorsTrail.resource.TranslationLoader;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames;
import com.gpl.rpg.AndorsTrail.util.Pair;
import android.util.Pair;
public final class ItemCategoryParser extends JsonCollectionParserFor<ItemCategory> {

View File

@@ -13,7 +13,7 @@ import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader;
import com.gpl.rpg.AndorsTrail.resource.TranslationLoader;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames;
import com.gpl.rpg.AndorsTrail.util.Pair;
import android.util.Pair;
public final class ItemTypeParser extends JsonCollectionParserFor<ItemType> {

View File

@@ -14,7 +14,7 @@ import com.gpl.rpg.AndorsTrail.resource.TranslationLoader;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames;
import com.gpl.rpg.AndorsTrail.util.ConstRange;
import com.gpl.rpg.AndorsTrail.util.Pair;
import android.util.Pair;
import com.gpl.rpg.AndorsTrail.util.Size;
public final class MonsterTypeParser extends JsonCollectionParserFor<MonsterType> {

View File

@@ -12,7 +12,7 @@ import com.gpl.rpg.AndorsTrail.resource.TranslationLoader;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames;
import com.gpl.rpg.AndorsTrail.util.Pair;
import android.util.Pair;
public final class QuestParser extends JsonCollectionParserFor<Quest> {
private final TranslationLoader translationLoader;

View File

@@ -16,7 +16,7 @@ import com.gpl.rpg.AndorsTrail.model.map.WorldMapSegment.WorldMapSegmentMap;
import com.gpl.rpg.AndorsTrail.resource.TranslationLoader;
import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.util.L;
import com.gpl.rpg.AndorsTrail.util.Pair;
import android.util.Pair;
import com.gpl.rpg.AndorsTrail.util.XmlResourceParserUtils;
public final class WorldMapParser {

View File

@@ -11,7 +11,7 @@ import org.json.JSONException;
import com.gpl.rpg.AndorsTrail.AndorsTrailApplication;
import com.gpl.rpg.AndorsTrail.util.L;
import com.gpl.rpg.AndorsTrail.util.Pair;
import android.util.Pair;
public abstract class JsonCollectionParserFor<T> extends JsonParserFor<Pair<String, T>> {
public HashSet<String> parseRows(String input, HashMap<String, T> dest) {

View File

@@ -12,6 +12,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.DigestException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -79,7 +80,7 @@ public final class Savegames {
}
return true;
} catch (IOException e) {
} catch (IOException | DigestException e) {
L.log("Error saving world: " + e.toString());
return false;
}
@@ -87,7 +88,7 @@ public final class Savegames {
private static void writeBackup(Context androidContext, byte[] savegame, String playerId) throws IOException {
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
ensureDirExists(cheatDetectionFolder);
ensureDirExists(cheatDetectionFolder);
File backupFile = new File(cheatDetectionFolder, playerId + "X");
FileOutputStream fileOutputStream = new FileOutputStream(backupFile);
fileOutputStream.write(savegame);
@@ -108,15 +109,15 @@ public final class Savegames {
LoadSavegameResult result = loadWorld(androidContext.getResources(), world, controllers, androidContext, fos, fh);
fos.close();
if (result == LoadSavegameResult.success && slot != SLOT_QUICKSAVE && !world.model.statistics.hasUnlimitedSaves()) {
// save to the quicksave slot before deleting the file
if (!saveWorld(world, androidContext, SLOT_QUICKSAVE)) {
// save to the quicksave slot before deleting the file
if (!saveWorld(world, androidContext, SLOT_QUICKSAVE)) {
return LoadSavegameResult.unknownError;
}
getSlotFile(slot, androidContext).delete();
writeCheatCheck(androidContext, DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED, fh.playerId);
}
return result;
} catch (IOException e) {
} catch (IOException | DigestException e) {
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
L.log("Error loading world: " + e.toString());
StringWriter sw = new StringWriter();
@@ -128,33 +129,33 @@ public final class Savegames {
}
}
private static boolean triedToCheat(Context androidContext, FileHeader fh) throws IOException {
long savedVersionToCheck = 0;
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
ensureDirExists(cheatDetectionFolder);
File cheatDetectionFile = new File(cheatDetectionFolder, fh.playerId);
if (cheatDetectionFile.exists()) {
FileInputStream fileInputStream = new FileInputStream(cheatDetectionFile);
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
savedVersionToCheck = cheatDetection.savedVersion;
dataInputStream.close();
fileInputStream.close();
}
private static boolean triedToCheat(Context androidContext, FileHeader fh) throws IOException {
long savedVersionToCheck = 0;
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
ensureDirExists(cheatDetectionFolder);
File cheatDetectionFile = new File(cheatDetectionFolder, fh.playerId);
if (cheatDetectionFile.exists()) {
FileInputStream fileInputStream = new FileInputStream(cheatDetectionFile);
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
savedVersionToCheck = cheatDetection.savedVersion;
dataInputStream.close();
fileInputStream.close();
}
if (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
return true;
}
if (androidContext.getFileStreamPath(fh.playerId).exists()) {
FileInputStream fileInputStream = androidContext.openFileInput(fh.playerId);
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
if (cheatDetection.savedVersion == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
savedVersionToCheck = DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED;
} else if (cheatDetection.savedVersion > savedVersionToCheck) {
savedVersionToCheck = cheatDetection.savedVersion;
}
if (androidContext.getFileStreamPath(fh.playerId).exists()) {
FileInputStream fileInputStream = androidContext.openFileInput(fh.playerId);
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
final CheatDetection cheatDetection = new CheatDetection(dataInputStream);
if (cheatDetection.savedVersion == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED) {
savedVersionToCheck = DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED;
} else if (cheatDetection.savedVersion > savedVersionToCheck) {
savedVersionToCheck = cheatDetection.savedVersion;
}
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) {
L.log("Internal cheatcheck file savedVersion: " + cheatDetection.savedVersion);
@@ -167,83 +168,98 @@ public final class Savegames {
return (savedVersionToCheck == DENY_LOADING_BECAUSE_GAME_IS_CURRENTLY_PLAYED || fh.savedVersion < savedVersionToCheck);
}
private static FileOutputStream getOutputFile(Context androidContext, int slot) throws IOException {
if (slot == SLOT_QUICKSAVE) {
return androidContext.openFileOutput(Constants.FILENAME_SAVEGAME_QUICKSAVE, Context.MODE_PRIVATE);
} else {
ensureSavegameDirectoryExists(androidContext);
return new FileOutputStream(getSlotFile(slot, androidContext));
}
}
private static FileOutputStream getOutputFile(Context androidContext, int slot) throws IOException {
if (slot == SLOT_QUICKSAVE) {
return androidContext.openFileOutput(Constants.FILENAME_SAVEGAME_QUICKSAVE, Context.MODE_PRIVATE);
} else {
ensureSavegameDirectoryExists(androidContext);
return new FileOutputStream(getSlotFile(slot, androidContext));
}
}
private static void ensureSavegameDirectoryExists(Context context) {
File dir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
ensureDirExists(dir);
}
private static void ensureSavegameDirectoryExists(Context context) {
File dir = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
ensureDirExists(dir);
}
public static boolean ensureDirExists(File dir) {
if (!dir.exists()) {
boolean worked = dir.mkdir();
return worked;
}
return true;
}
public static boolean ensureDirExists(File dir) {
if (!dir.exists()) {
boolean worked = dir.mkdir();
return worked;
}
return true;
}
private static FileInputStream getInputFile(Context androidContext, int slot) throws IOException {
if (slot == SLOT_QUICKSAVE) {
return androidContext.openFileInput(Constants.FILENAME_SAVEGAME_QUICKSAVE);
} else {
return new FileInputStream(getSlotFile(slot, androidContext));
}
}
private static FileInputStream getInputFile(Context androidContext, int slot) throws IOException {
if (slot == SLOT_QUICKSAVE) {
return androidContext.openFileInput(Constants.FILENAME_SAVEGAME_QUICKSAVE);
} else {
return new FileInputStream(getSlotFile(slot, androidContext));
}
}
public static File getSlotFile(int slot, Context context) {
File root = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
return getSlotFile(slot, root);
}
public static File getSlotFile(int slot, Context context) {
File root = AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY);
return getSlotFile(slot, root);
}
public static File getSlotFile(int slot, File directory) {
return new File(directory, getSlotFileName(slot));
}
public static File getSlotFile(int slot, File directory) {
return new File(directory, getSlotFileName(slot));
}
public static String getSlotFileName(int slot) {
return Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + slot;
}
public static String getSlotFileName(int slot) {
return Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + slot;
}
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException {
public static void saveWorld(WorldContext world, OutputStream outStream, String displayInfo) throws IOException, DigestException {
DataOutputStream dest = new DataOutputStream(outStream);
FileHeader.writeToParcel(dest, world.model.player.getName(),
displayInfo, world.model.player.iconID,
world.model.statistics.isDead(),
world.model.statistics.hasUnlimitedSaves(),
world.model.player.id,
world.model.player.savedVersion);
world.model.player.savedVersion,
world.model.statistics.getIsAlteredSavegame());
byte[] checksum = world.getChecksum();
world.model.statistics.setChecksum(checksum);
world.maps.writeToParcel(dest, world);
world.model.writeToParcel(dest);
dest.close();
}
public static LoadSavegameResult loadWorld(Resources res, WorldContext world, ControllerContext controllers, Context androidContext, InputStream inState, FileHeader fh) throws IOException {
DataInputStream src = new DataInputStream(inState);
final FileHeader header = new FileHeader(src, fh.skipIcon);
if (header.fileversion > AndorsTrailApplication.CURRENT_VERSION)
return LoadSavegameResult.savegameIsFromAFutureVersion;
public static LoadSavegameResult loadWorld(Resources res, WorldContext world, ControllerContext controllers, Context androidContext, InputStream inState, FileHeader fh) throws IOException, DigestException {
DataInputStream src = new DataInputStream(inState);
final FileHeader header = new FileHeader(src, fh.skipIcon);
if (header.fileversion > AndorsTrailApplication.CURRENT_VERSION)
return LoadSavegameResult.savegameIsFromAFutureVersion;
world.maps.readFromParcel(src, world, controllers, header.fileversion);
world.model = new ModelContainer(src, world, controllers, header.fileversion);
WorldMapController.populateWorldMap(androidContext, world, controllers.getResources());
src.close();
if (header.fileversion >= 81) {
checkChecksum(world);
}
WorldMapController.populateWorldMap(androidContext, world, controllers.getResources());
if (header.fileversion < 45) {
LegacySavegamesContentAdaptations.adaptToNewContentForVersion45(world, controllers, res);
}
onWorldLoaded(res, world, controllers);
return LoadSavegameResult.success;
}
private static void checkChecksum(WorldContext world) throws DigestException {
byte[] checksum = world.getChecksum();
if (!world.model.statistics.compareChecksum(checksum)) {
world.model.statistics.markAsAlteredSavegame();
}
}
private static void onWorldLoaded(Resources res, WorldContext world, ControllerContext controllers) {
controllers.actorStatsController.recalculatePlayerStats(world.model.player);
controllers.mapController.resetMapsNotRecentlyVisited();
@@ -268,15 +284,15 @@ public final class Savegames {
}
}
private static void writeCheatCheck(Context androidContext, long savedVersion, String playerId) throws IOException {
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
ensureDirExists(cheatDetectionFolder);
File cheatDetectionFile = new File(cheatDetectionFolder, playerId);
FileOutputStream fileOutputStream = new FileOutputStream(cheatDetectionFile);
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
CheatDetection.writeToParcel(dataOutputStream, savedVersion);
dataOutputStream.close();
fileOutputStream.close();
private static void writeCheatCheck(Context androidContext, long savedVersion, String playerId) throws IOException {
File cheatDetectionFolder = AndroidStorage.getStorageDirectory(androidContext, Constants.CHEAT_DETECTION_FOLDER);
ensureDirExists(cheatDetectionFolder);
File cheatDetectionFile = new File(cheatDetectionFolder, playerId);
FileOutputStream fileOutputStream = new FileOutputStream(cheatDetectionFile);
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
CheatDetection.writeToParcel(dataOutputStream, savedVersion);
dataOutputStream.close();
fileOutputStream.close();
fileOutputStream = androidContext.openFileOutput(playerId, Context.MODE_PRIVATE);
dataOutputStream = new DataOutputStream(fileOutputStream);
@@ -287,26 +303,26 @@ public final class Savegames {
private static final Pattern savegameFilenamePattern = Pattern.compile(Constants.FILENAME_SAVEGAME_FILENAME_PREFIX + "(\\d+)");
public static List<Integer> getUsedSavegameSlots(Context context) {
try {
final List<Integer> result = new ArrayList<Integer>();
AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY).listFiles(new FilenameFilter() {
@Override
public boolean accept(File f, String filename) {
Matcher m = savegameFilenamePattern.matcher(filename);
if (m != null && m.matches()) {
result.add(Integer.parseInt(m.group(1)));
return true;
}
return false;
}
});
Collections.sort(result);
return result;
} catch (Exception e) {
return new ArrayList<Integer>();
}
}
public static List<Integer> getUsedSavegameSlots(Context context) {
try {
final List<Integer> result = new ArrayList<Integer>();
AndroidStorage.getStorageDirectory(context, Constants.FILENAME_SAVEGAME_DIRECTORY).listFiles(new FilenameFilter() {
@Override
public boolean accept(File f, String filename) {
Matcher m = savegameFilenamePattern.matcher(filename);
if (m != null && m.matches()) {
result.add(Integer.parseInt(m.group(1)));
return true;
}
return false;
}
});
Collections.sort(result);
return result;
} catch (Exception e) {
return new ArrayList<Integer>();
}
}
private static final class CheatDetection {
public final int fileversion;
@@ -326,16 +342,17 @@ public final class Savegames {
}
public static final class FileHeader {
public final int fileversion;
public final String playerName;
public final String displayInfo;
public final int iconID;
public boolean skipIcon = false;
public final boolean isDead;
public final boolean hasUnlimitedSaves;
public final String playerId;
public final long savedVersion;
public static final class FileHeader {
public final int fileversion;
public final String playerName;
public final String displayInfo;
public final int iconID;
public final boolean isAlteredSavegame;
public boolean skipIcon = false;
public final boolean isDead;
public final boolean hasUnlimitedSaves;
public final String playerId;
public final long savedVersion;
public String describe() {
return (fileversion == AndorsTrailApplication.DEVELOPMENT_INCOMPATIBLE_SAVEGAME_VERSION ? "(D) " : "") + playerName + ", " + displayInfo;
@@ -344,18 +361,18 @@ public final class Savegames {
// ====== PARCELABLE ===================================================================
public FileHeader(DataInputStream src, boolean skipIcon) throws IOException {
int fileversion = src.readInt();
if (fileversion == 11)
fileversion = 5; // Fileversion 5 had no version identifier, but the first byte was 11.
this.fileversion = fileversion;
if (fileversion >= 14) { // Before fileversion 14 (0.6.7), we had no file header.
this.playerName = src.readUTF();
this.displayInfo = src.readUTF();
} else {
this.playerName = null;
this.displayInfo = null;
}
public FileHeader(DataInputStream src, boolean skipIcon) throws IOException {
int fileversion = src.readInt();
if (fileversion == 11)
fileversion = 5; // Fileversion 5 had no version identifier, but the first byte was 11.
this.fileversion = fileversion;
if (fileversion >= 14) { // Before fileversion 14 (0.6.7), we had no file header.
this.playerName = src.readUTF();
this.displayInfo = src.readUTF();
} else {
this.playerName = null;
this.displayInfo = null;
}
if (fileversion >= 43) {
int id = src.readInt();
@@ -380,9 +397,14 @@ public final class Savegames {
this.playerId = "";
this.savedVersion = 0;
}
if(fileversion >= 81){
this.isAlteredSavegame = src.readBoolean();
}else{
this.isAlteredSavegame = false;
}
}
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo, int iconID, boolean isDead, boolean hasUnlimitedSaves, String playerId, long savedVersion) throws IOException {
public static void writeToParcel(DataOutputStream dest, String playerName, String displayInfo, int iconID, boolean isDead, boolean hasUnlimitedSaves, String playerId, long savedVersion, boolean isAlteredSavegame) throws IOException {
dest.writeInt(AndorsTrailApplication.CURRENT_VERSION);
dest.writeUTF(playerName);
dest.writeUTF(displayInfo);
@@ -391,6 +413,7 @@ public final class Savegames {
dest.writeBoolean(hasUnlimitedSaves);
dest.writeUTF(playerId);
dest.writeLong(savedVersion);
dest.writeBoolean(isAlteredSavegame);
}
}
}

View File

@@ -1,5 +1,7 @@
package com.gpl.rpg.AndorsTrail.util;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -47,4 +49,9 @@ public final class Coord {
dest.writeInt(x);
dest.writeInt(y);
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(x);
builder.add(y);
}
}

View File

@@ -1,11 +0,0 @@
package com.gpl.rpg.AndorsTrail.util;
// Should really use android.util.Pair<> instead, but it is not available for API level 4 (Android 1.6).
public final class Pair<T1, T2> {
public final T1 first;
public final T2 second;
public Pair(T1 a, T2 b) {
this.first = a;
this.second = b;
}
}

View File

@@ -1,5 +1,7 @@
package com.gpl.rpg.AndorsTrail.util;
import com.gpl.rpg.AndorsTrail.model.ChecksumBuilder;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -99,4 +101,9 @@ public final class Range {
dest.writeInt(max);
dest.writeInt(current);
}
public void addToChecksum(ChecksumBuilder builder) {
builder.add(max);
builder.add(current);
}
}

View File

@@ -13,7 +13,6 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
@@ -76,11 +75,8 @@ public class CustomDialogFactory {
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.custom_dialog_title_icon);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
if (((AndorsTrailApplication)context.getApplicationContext()).getPreferences().fullscreen) {
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
dialog.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
boolean fullscreen = ((AndorsTrailApplication) context.getApplicationContext()).getPreferences().fullscreen;
AndorsTrailApplication.setFullscreenMode(fullscreen, dialog.getWindow());
setTitle(dialog, title, icon);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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