Compare commits
2827 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ddc59589c | ||
|
|
1e15d7a33e | ||
|
|
13969bdd29 | ||
|
|
a3f5583326 | ||
|
|
f137c11c6c | ||
|
|
8d6afbd80d | ||
|
|
c46fa206f6 | ||
|
|
e8da206389 | ||
|
|
b2b8cf2357 | ||
|
|
a4fd88a440 | ||
|
|
a1624f61ae | ||
|
|
5ee26fc3f4 | ||
|
|
93ffb66e59 | ||
|
|
4b9bcfb014 | ||
|
|
a161c09441 | ||
|
|
0c396f76b2 | ||
|
|
b2408b1a7c | ||
|
|
eaa2ad4f05 | ||
|
|
88ce7837a6 | ||
|
|
4054c7d12d | ||
|
|
2d3fd513d8 | ||
|
|
404b593ab8 | ||
|
|
b9f1dea914 | ||
|
|
f3385e6453 | ||
|
|
a2e55f7861 | ||
|
|
761e0114a5 | ||
|
|
dcae128d06 | ||
|
|
a891a8badc | ||
|
|
f3ec5b533e | ||
|
|
d50397edf1 | ||
|
|
49986f22c8 | ||
|
|
70f279d978 | ||
|
|
84c5a75b6c | ||
|
|
97663e87a6 | ||
|
|
5956edcb8e | ||
|
|
7e975f2134 | ||
|
|
40de13f9c7 | ||
|
|
70946539e3 | ||
|
|
996c594dfc | ||
|
|
d8eeb79b63 | ||
|
|
cf61dd0704 | ||
|
|
6fd5f1563a | ||
|
|
3c643c917a | ||
|
|
378be0ef86 | ||
|
|
29e90969eb | ||
|
|
fb724514f3 | ||
|
|
1f11da75d2 | ||
|
|
fcc433fe17 | ||
|
|
617bdf9910 | ||
|
|
3b2aa92eb7 | ||
|
|
4c17b56e28 | ||
|
|
ad13c83f93 | ||
|
|
768d67a8ae | ||
|
|
d827cda395 | ||
|
|
106e6c98a3 | ||
|
|
e7ad797d4e | ||
|
|
6e1fb71194 | ||
|
|
9f5dc7f091 | ||
|
|
57b273639c | ||
|
|
278d690a6b | ||
|
|
c91c0f7b47 | ||
|
|
6a406f4d45 | ||
|
|
eecaa850e0 | ||
|
|
f332332eaa | ||
|
|
79b0e76be0 | ||
|
|
30650efd98 | ||
|
|
b7759c8151 | ||
|
|
0382c35ac0 | ||
|
|
819262c93f | ||
|
|
db60f4bb1c | ||
|
|
7785ca55c2 | ||
|
|
75dcceff43 | ||
|
|
af91979d4c | ||
|
|
52cd4a77dd | ||
|
|
8a1da3c0ed | ||
|
|
9d67c36c32 | ||
|
|
f283709e62 | ||
|
|
5035559b08 | ||
|
|
01e1438382 | ||
|
|
4eee472043 | ||
|
|
5f89a1b9ca | ||
|
|
b9db5ad662 | ||
|
|
5b8084e1fa | ||
|
|
ab67b67e4c | ||
|
|
f825931f92 | ||
|
|
6113edf2ce | ||
|
|
8413443c26 | ||
|
|
f67fb31bc5 | ||
|
|
d321ec5ed1 | ||
|
|
084ae184f9 | ||
|
|
d1ec652f7b | ||
|
|
7a2a6586be | ||
|
|
392dcf3092 | ||
|
|
8a983c784d | ||
|
|
a443263439 | ||
|
|
3e766b9f54 | ||
|
|
89b9501f35 | ||
|
|
816ae84005 | ||
|
|
c0e425cf46 | ||
|
|
9ebb4c7d12 | ||
|
|
46c3b35028 | ||
|
|
ef2b8be726 | ||
|
|
df51078858 | ||
|
|
5783b61631 | ||
|
|
98a53381fb | ||
|
|
daccfa5fe3 | ||
|
|
d82c24616f | ||
|
|
905ca3dcfc | ||
|
|
b4fb687c4f | ||
|
|
39fb2ae5ab | ||
|
|
b40beb0d1d | ||
|
|
4a96b9bb00 | ||
|
|
f83a178982 | ||
|
|
986b4276e1 | ||
|
|
6f6f418ec9 | ||
|
|
1463571cd7 | ||
|
|
7dfb0a81e3 | ||
|
|
9699d9467a | ||
|
|
08a2872527 | ||
|
|
7c81a807ea | ||
|
|
3bf7031e6a | ||
|
|
503fc980f4 | ||
|
|
efed11eb97 | ||
|
|
330820062f | ||
|
|
45d157fe3f | ||
|
|
812dea385c | ||
|
|
c582bdea46 | ||
|
|
e6c6a9381b | ||
|
|
4b4c0755c6 | ||
|
|
aeb0539c91 | ||
|
|
9feafa45f5 | ||
|
|
927df391f3 | ||
|
|
cbef6adeb1 | ||
|
|
2dee221861 | ||
|
|
0b175cb25d | ||
|
|
0820338b55 | ||
|
|
a2b46eee6f | ||
|
|
09a435320a | ||
|
|
bf56200c06 | ||
|
|
2d18df2011 | ||
|
|
bab87c0da8 | ||
|
|
148f272500 | ||
|
|
6de4af727b | ||
|
|
75946b9d14 | ||
|
|
1c63ee6743 | ||
|
|
efdaf0d986 | ||
|
|
3f6aeac33d | ||
|
|
d9692004cc | ||
|
|
67a12eecad | ||
|
|
37999e0870 | ||
|
|
66dc1e94f5 | ||
|
|
ebcce194a0 | ||
|
|
95eab94c80 | ||
|
|
41a6dbe06c | ||
|
|
fa22b0ec12 | ||
|
|
be60a367e8 | ||
|
|
608de34205 | ||
|
|
0a8f2edb05 | ||
|
|
41b08f38c5 | ||
|
|
a83c0b2e9a | ||
|
|
8f853c8f18 | ||
|
|
b4071f6dcb | ||
|
|
6b70418861 | ||
|
|
de0235ad94 | ||
|
|
c278c632b3 | ||
|
|
6392330e70 | ||
|
|
160ae4e244 | ||
|
|
a6c9bd3182 | ||
|
|
801eadd8a8 | ||
|
|
211dab1297 | ||
|
|
0c3b39ffdc | ||
|
|
c31f88a318 | ||
|
|
e9eb981782 | ||
|
|
83bde8a781 | ||
|
|
52f352bf94 | ||
|
|
b419a96d69 | ||
|
|
eb3d5b62f5 | ||
|
|
1c5f578d88 | ||
|
|
db3aae1388 | ||
|
|
0b08eb72a6 | ||
|
|
cbc81376be | ||
|
|
27e9901d05 | ||
|
|
532c36677c | ||
|
|
0c20c6ecb7 | ||
|
|
fbb3240ebb | ||
|
|
bffae90022 | ||
|
|
61f6368591 | ||
|
|
1027ca2a85 | ||
|
|
5acc42f739 | ||
|
|
1edeaeb94e | ||
|
|
879acc6077 | ||
|
|
4e5d87104c | ||
|
|
e6a24b8ba1 | ||
|
|
fd190c7770 | ||
|
|
d56869aefa | ||
|
|
c8a15bb7e4 | ||
|
|
07c28c3f6d | ||
|
|
855957b099 | ||
|
|
50959317e9 | ||
|
|
20a681a71f | ||
|
|
4e2d558b36 | ||
|
|
0430b908f4 | ||
|
|
a84e9f2aaa | ||
|
|
7ce571e59c | ||
|
|
545a64f7dc | ||
|
|
10c999a4a2 | ||
|
|
d0e026d597 | ||
|
|
0b1e2bf19b | ||
|
|
71c2c7ad05 | ||
|
|
97f5bf3cc4 | ||
|
|
bb9573b85a | ||
|
|
e1f53dfc67 | ||
|
|
87481e0a4d | ||
|
|
f7aa58e385 | ||
|
|
ea5c78f814 | ||
|
|
c93c016e9c | ||
|
|
4bb6664c7e | ||
|
|
9578068a02 | ||
|
|
30e5f2b17d | ||
|
|
f959760c07 | ||
|
|
e7db2350bc | ||
|
|
0585dabf7a | ||
|
|
a3c6e3f1df | ||
|
|
9f57278644 | ||
|
|
afc35cf623 | ||
|
|
6d8523054b | ||
|
|
fdecd55278 | ||
|
|
7e7f95916b | ||
|
|
ab52c65dcf | ||
|
|
ed4d0eb5d0 | ||
|
|
4bc9143306 | ||
|
|
a4f558c77a | ||
|
|
e4f226a9c5 | ||
|
|
c7d34049fa | ||
|
|
ee06e620c6 | ||
|
|
b48110db3b | ||
|
|
8413046dd8 | ||
|
|
83a5a82e18 | ||
|
|
771c5fbe3d | ||
|
|
74f16d0137 | ||
|
|
5d5d354f7d | ||
|
|
8f5f27755d | ||
|
|
4cb92cdb06 | ||
|
|
9e067ebdd6 | ||
|
|
fd5fcc9928 | ||
|
|
c0b2abb5fd | ||
|
|
2c8620a75c | ||
|
|
62f6ed0878 | ||
|
|
886b62bbad | ||
|
|
4bd58589fc | ||
|
|
0ce4144767 | ||
|
|
cde945f40e | ||
|
|
e2126a2693 | ||
|
|
c9f6d92bef | ||
|
|
fbf4c411c1 | ||
|
|
ce5218db58 | ||
|
|
e2ea7f9b87 | ||
|
|
94d9f04814 | ||
|
|
c86dbac04a | ||
|
|
f36eed32b9 | ||
|
|
cd752209ad | ||
|
|
fe37d619b9 | ||
|
|
043f4688ef | ||
|
|
949f171579 | ||
|
|
87d586a30e | ||
|
|
783f453da3 | ||
|
|
6dcf889ffe | ||
|
|
8d44879cc6 | ||
|
|
e7b813962d | ||
|
|
22fadab3b3 | ||
|
|
91741ec29c | ||
|
|
8269d842ce | ||
|
|
d038bdb6ce | ||
|
|
6cef301b94 | ||
|
|
e7ffbd817c | ||
|
|
97067a6ee2 | ||
|
|
7d1a8f5404 | ||
|
|
43bcf0cf3b | ||
|
|
71751ee18d | ||
|
|
ed105b102d | ||
|
|
f2662045ed | ||
|
|
ecb77b0283 | ||
|
|
4d4869842e | ||
|
|
47300b42b0 | ||
|
|
609565af5f | ||
|
|
0c75f920de | ||
|
|
e7b51f313b | ||
|
|
e8204fc983 | ||
|
|
aa69af64fb | ||
|
|
41f734b04d | ||
|
|
8ad6f3abcc | ||
|
|
e4875903f1 | ||
|
|
0a04de04f1 | ||
|
|
20427fdffa | ||
|
|
0fd0abc6c0 | ||
|
|
70f7fc29d4 | ||
|
|
b0c1aff783 | ||
|
|
4909c28ed9 | ||
|
|
9e6745f691 | ||
|
|
6c3ccb259f | ||
|
|
6c8d80777c | ||
|
|
2db61f93ac | ||
|
|
ad059cbc38 | ||
|
|
87e7e04c5e | ||
|
|
c083d059c9 | ||
|
|
ebd44d3b60 | ||
|
|
51f5d04889 | ||
|
|
0f4d574115 | ||
|
|
1feb4a5e6d | ||
|
|
f861b75c7d | ||
|
|
3530ca8989 | ||
|
|
6b074ed4b2 | ||
|
|
671823b4fa | ||
|
|
8ceebf1546 | ||
|
|
376495836a | ||
|
|
98212df076 | ||
|
|
1316c9235a | ||
|
|
a0905d5695 | ||
|
|
2a35e22dd2 | ||
|
|
f86a07daee | ||
|
|
997628622a | ||
|
|
563e015c92 | ||
|
|
64533de597 | ||
|
|
3776b99c39 | ||
|
|
a5d1350815 | ||
|
|
82e44397ff | ||
|
|
335c880af2 | ||
|
|
966efa0669 | ||
|
|
526a61381d | ||
|
|
d01f68f731 | ||
|
|
1235b41172 | ||
|
|
21f3a053ed | ||
|
|
9e960d461b | ||
|
|
02fad0a9cc | ||
|
|
627b78043b | ||
|
|
89b439c3c8 | ||
|
|
4a4a9f267b | ||
|
|
f605aabaa9 | ||
|
|
d82d0ae923 | ||
|
|
1e111d29d9 | ||
|
|
110def97d9 | ||
|
|
5bacdfa951 | ||
|
|
914f1b38f8 | ||
|
|
2aff73a958 | ||
|
|
13c2eae1f4 | ||
|
|
8f4258b119 | ||
|
|
4eba89603e | ||
|
|
61f75d7331 | ||
|
|
cd387c5c3a | ||
|
|
2fa32e5099 | ||
|
|
f12da57720 | ||
|
|
964d1a0d87 | ||
|
|
0cb14461ba | ||
|
|
d05f9c5540 | ||
|
|
690580c57d | ||
|
|
5039763a52 | ||
|
|
2cc54ffa5b | ||
|
|
0a9b78f013 | ||
|
|
e42fa7ad20 | ||
|
|
9c179e559b | ||
|
|
6dd10b74d5 | ||
|
|
a073b0ab18 | ||
|
|
4f253999ac | ||
|
|
9108a7bae6 | ||
|
|
6ba88323fe | ||
|
|
e112e3f949 | ||
|
|
1ed4e9f5bb | ||
|
|
b6c5f202e4 | ||
|
|
976b39414f | ||
|
|
d74887eaa1 | ||
|
|
7fb72bf0e2 | ||
|
|
b0126206e1 | ||
|
|
9c240850b8 | ||
|
|
5b7b50f555 | ||
|
|
f591403b7d | ||
|
|
4b028b3435 | ||
|
|
cbcf237d80 | ||
|
|
a815c564fb | ||
|
|
cb12501d5b | ||
|
|
86aeabc911 | ||
|
|
5e2a455045 | ||
|
|
86dddd0253 | ||
|
|
4677de80c1 | ||
|
|
fbcbca6f24 | ||
|
|
7024273a02 | ||
|
|
070bb4d2d1 | ||
|
|
f33e924cdf | ||
|
|
18fcc6e596 | ||
|
|
59e909ae3a | ||
|
|
66766b43c7 | ||
|
|
8c6c4c2630 | ||
|
|
ea2ed7d776 | ||
|
|
a708c8b7ea | ||
|
|
12ca4cda91 | ||
|
|
85f73fee02 | ||
|
|
1b5b6d424b | ||
|
|
126a764918 | ||
|
|
f796a24956 | ||
|
|
e815cff291 | ||
|
|
0ad89ebc04 | ||
|
|
a4b9579d25 | ||
|
|
e65b6670ec | ||
|
|
1665e75068 | ||
|
|
6d01d893f7 | ||
|
|
cb9616a381 | ||
|
|
d218fb926a | ||
|
|
39276b4b03 | ||
|
|
51ba999ee1 | ||
|
|
52593252c5 | ||
|
|
718f56172e | ||
|
|
34b7961814 | ||
|
|
897b90f044 | ||
|
|
a9778e6e68 | ||
|
|
ccaf888e8b | ||
|
|
29821003fe | ||
|
|
3f7ba23dff | ||
|
|
6fd243522d | ||
|
|
368bf2258f | ||
|
|
533ddb874e | ||
|
|
baaf126c15 | ||
|
|
5b2bfe10bc | ||
|
|
17b24c3389 | ||
|
|
55b3e8639f | ||
|
|
22dad88ff7 | ||
|
|
ce3b0f2d8f | ||
|
|
a87e2a56d2 | ||
|
|
bb0ee26e4f | ||
|
|
adf5189541 | ||
|
|
82077936bb | ||
|
|
5094a6fc49 | ||
|
|
274ef166ef | ||
|
|
66c27fab13 | ||
|
|
56bcabedf7 | ||
|
|
79a9541394 | ||
|
|
7e35de3c33 | ||
|
|
7b90044544 | ||
|
|
5a7e5450dc | ||
|
|
ec2ec59be0 | ||
|
|
beb25bd595 | ||
|
|
c2919f7e7a | ||
|
|
cee9d86835 | ||
|
|
9dbedc6e5d | ||
|
|
53310ed80a | ||
|
|
9251c55be2 | ||
|
|
25658f2a0a | ||
|
|
4f9e64588f | ||
|
|
afeb4d033b | ||
|
|
2569b2139d | ||
|
|
d88923bb71 | ||
|
|
d0c6d9a489 | ||
|
|
1bdea1b8d8 | ||
|
|
6ea90ea828 | ||
|
|
6217ae78e3 | ||
|
|
20529d3ebc | ||
|
|
c8fa116a24 | ||
|
|
2904bc69d9 | ||
|
|
38b3ad07b7 | ||
|
|
fe765e5a5b | ||
|
|
6e7514491c | ||
|
|
eb5b50b3e9 | ||
|
|
82b908f0ab | ||
|
|
336256fc71 | ||
|
|
49a7da6393 | ||
|
|
a8c645f00d | ||
|
|
62d8cb0b25 | ||
|
|
f5028a4937 | ||
|
|
203612853b | ||
|
|
8e8e95cd2d | ||
|
|
696e6cb84b | ||
|
|
67940476af | ||
|
|
0dd9d2b460 | ||
|
|
6b2f2d0664 | ||
|
|
636bfdb530 | ||
|
|
c0d6618808 | ||
|
|
e21a3347ac | ||
|
|
59a68ee981 | ||
|
|
7a072746d9 | ||
|
|
a6799dd29b | ||
|
|
163ecb160a | ||
|
|
f00d1f9505 | ||
|
|
87b489a541 | ||
|
|
f670ade2ee | ||
|
|
b5508c1152 | ||
|
|
564c258c86 | ||
|
|
745ff1a270 | ||
|
|
e727ee6d4a | ||
|
|
e6a39a8255 | ||
|
|
43bff5c34d | ||
|
|
c046a1b474 | ||
|
|
209e3f03c1 | ||
|
|
dbf05a1419 | ||
|
|
5af35b6771 | ||
|
|
00abba11ae | ||
|
|
d268d94f76 | ||
|
|
76af3e3077 | ||
|
|
54bade668e | ||
|
|
5a3ec8f407 | ||
|
|
c043664ad6 | ||
|
|
7e9ca6fbb6 | ||
|
|
e9a82652a0 | ||
|
|
db2e6b6973 | ||
|
|
da9278ad8d | ||
|
|
5a9307e9a7 | ||
|
|
f31fd622dd | ||
|
|
6723157ca5 | ||
|
|
956448a1a5 | ||
|
|
4be675f977 | ||
|
|
7924051c0d | ||
|
|
83b5f6ef2d | ||
|
|
0f26d62a0a | ||
|
|
a9f11256cd | ||
|
|
ead0547d59 | ||
|
|
89e29bce62 | ||
|
|
058db5d5d0 | ||
|
|
76aa409f89 | ||
|
|
923d0497e6 | ||
|
|
dd4f4b83fc | ||
|
|
c2bed82db5 | ||
|
|
9a444da343 | ||
|
|
9dd6a77c76 | ||
|
|
895725df64 | ||
|
|
6f07576748 | ||
|
|
550a11962e | ||
|
|
c3883cdad0 | ||
|
|
e9e2cd614d | ||
|
|
55e1759b47 | ||
|
|
33f5215e6d | ||
|
|
5459a646b3 | ||
|
|
6229f99a2e | ||
|
|
0e5b95e3aa | ||
|
|
72d7c1ba54 | ||
|
|
ee9a2ee03d | ||
|
|
6bfbcc4aa9 | ||
|
|
a9d7ed50b7 | ||
|
|
bc77ebc10c | ||
|
|
cbdce79d7d | ||
|
|
46dfa064d0 | ||
|
|
0478af2564 | ||
|
|
750388a425 | ||
|
|
ea9155b903 | ||
|
|
d34f228d2f | ||
|
|
093043750b | ||
|
|
4fb0c246db | ||
|
|
5e951f27c9 | ||
|
|
49253964d8 | ||
|
|
4ff1d0c2e1 | ||
|
|
2385011f96 | ||
|
|
7527f9326c | ||
|
|
9c7b80f066 | ||
|
|
48facc0978 | ||
|
|
22a6c4e8af | ||
|
|
bd6cfa6461 | ||
|
|
c63dca1c0d | ||
|
|
c6af151bf3 | ||
|
|
ccc20a9716 | ||
|
|
47605583d1 | ||
|
|
58e83c11f0 | ||
|
|
836a4eb892 | ||
|
|
6d50a747e3 | ||
|
|
4344af1f02 | ||
|
|
6510d83524 | ||
|
|
6d01193e1e | ||
|
|
8c3d6d05ab | ||
|
|
733a064c79 | ||
|
|
8715f6a301 | ||
|
|
b51725633e | ||
|
|
5ec11c61bd | ||
|
|
ab038a4d46 | ||
|
|
a976a7affb | ||
|
|
2f76684113 | ||
|
|
1ad7f12e2d | ||
|
|
017b83d375 | ||
|
|
650b443fd0 | ||
|
|
8aa1509f47 | ||
|
|
b21bf2d544 | ||
|
|
777bd60f88 | ||
|
|
7889db43a8 | ||
|
|
ae3aa20508 | ||
|
|
84e754dd10 | ||
|
|
b9618d66f2 | ||
|
|
daa7b20e4a | ||
|
|
48a7254aa3 | ||
|
|
2bc63b37e4 | ||
|
|
33afab7294 | ||
|
|
8010a82776 | ||
|
|
048b7bd32f | ||
|
|
28fa0b070d | ||
|
|
dc0be93b25 | ||
|
|
5e49d2d8d6 | ||
|
|
1d8efe5f9d | ||
|
|
8b791b68d3 | ||
|
|
521174f911 | ||
|
|
a6f7bd9099 | ||
|
|
fed964e0f7 | ||
|
|
77b4f3e930 | ||
|
|
351b8c2469 | ||
|
|
ee9f65d4a3 | ||
|
|
a1a69f62e1 | ||
|
|
ff52fec663 | ||
|
|
5743d30851 | ||
|
|
de02061b5e | ||
|
|
b64c38809e | ||
|
|
a163db485b | ||
|
|
47f7507af3 | ||
|
|
568e55e373 | ||
|
|
79e722b5ff | ||
|
|
415252a5b2 | ||
|
|
307bb7aeec | ||
|
|
397da91ab4 | ||
|
|
fdd0c25a25 | ||
|
|
d691e9f39d | ||
|
|
a5cbe19d23 | ||
|
|
5661124d86 | ||
|
|
1346e163e9 | ||
|
|
d5626bfe52 | ||
|
|
0900c13fa1 | ||
|
|
5019f200b7 | ||
|
|
3b41ded045 | ||
|
|
9f84b84819 | ||
|
|
f61f3af687 | ||
|
|
0a6f7ac817 | ||
|
|
153e6c5f1b | ||
|
|
e24d96da6f | ||
|
|
59e5099ed6 | ||
|
|
b8e6e5df61 | ||
|
|
16851a457e | ||
|
|
1c5bb605c3 | ||
|
|
dc12d58054 | ||
|
|
120e0f6971 | ||
|
|
b9136e4e98 | ||
|
|
197b97d0db | ||
|
|
912136d174 | ||
|
|
653c85c58d | ||
|
|
638c99981d | ||
|
|
71e61abcd6 | ||
|
|
fa1d440bb0 | ||
|
|
f0064e35bc | ||
|
|
88d208268a | ||
|
|
6aa90a44f7 | ||
|
|
3c9322ee08 | ||
|
|
b2f47e6b70 | ||
|
|
c905a870e0 | ||
|
|
b2360e42c6 | ||
|
|
0da621745a | ||
|
|
d8fc3851a7 | ||
|
|
edd3fb3440 | ||
|
|
a105c017d5 | ||
|
|
dd1034e37b | ||
|
|
41f16a54de | ||
|
|
b91510efb3 | ||
|
|
745d8122f5 | ||
|
|
98e4f7409b | ||
|
|
cdb3971b8d | ||
|
|
d01b8c7ad1 | ||
|
|
7c35b6e95a | ||
|
|
86b35fc43d | ||
|
|
5b2c8ac337 | ||
|
|
734d4a912b | ||
|
|
4386d3169a | ||
|
|
35348f1150 | ||
|
|
36b27458b6 | ||
|
|
bbb2153112 | ||
|
|
9ec1d8f16b | ||
|
|
e1858df645 | ||
|
|
3b1066e16f | ||
|
|
75709a7812 | ||
|
|
81c68e90cb | ||
|
|
bc9110b344 | ||
|
|
89d5618232 | ||
|
|
1e8b844eac | ||
|
|
3fc278c7b7 | ||
|
|
db546412f1 | ||
|
|
3b42b604e1 | ||
|
|
f22caed088 | ||
|
|
1f4e611629 | ||
|
|
8879593381 | ||
|
|
22b7086bea | ||
|
|
c097841d78 | ||
|
|
44e4ffbe62 | ||
|
|
84f60f63b8 | ||
|
|
572f358bda | ||
|
|
46df7726c3 | ||
|
|
3abfaf1bca | ||
|
|
f119afe436 | ||
|
|
94908bc599 | ||
|
|
cabcfc7136 | ||
|
|
d2c6305548 | ||
|
|
414af6a5d5 | ||
|
|
ecab13af57 | ||
|
|
47f9aece38 | ||
|
|
6dc64cf2f6 | ||
|
|
832582caa9 | ||
|
|
828661e9de | ||
|
|
52f78ee4ed | ||
|
|
6029b6d67f | ||
|
|
9d744580a1 | ||
|
|
b295f51c29 | ||
|
|
5c6aea0d50 | ||
|
|
99bf50ee52 | ||
|
|
f48a19a3bc | ||
|
|
fed11db92e | ||
|
|
23fb15fe78 | ||
|
|
7a533f6053 | ||
|
|
a292ff4287 | ||
|
|
29329383e4 | ||
|
|
fefdad5335 | ||
|
|
982f9ce8fb | ||
|
|
5c6d4b9ac2 | ||
|
|
49954f5c07 | ||
|
|
0b837925a2 | ||
|
|
54dd67a435 | ||
|
|
18ddc040d1 | ||
|
|
aeb28f67e4 | ||
|
|
54b892cd29 | ||
|
|
2e28525c4b | ||
|
|
8aa8de570f | ||
|
|
6723479c32 | ||
|
|
e318b6a113 | ||
|
|
df44f82198 | ||
|
|
97d54868e9 | ||
|
|
65e65ba308 | ||
|
|
2056d5e350 | ||
|
|
8b3b72243f | ||
|
|
814146f227 | ||
|
|
511983e1ea | ||
|
|
13e5df62c9 | ||
|
|
8debf8caf8 | ||
|
|
eab90cac05 | ||
|
|
ce401b01b6 | ||
|
|
271dcd46bc | ||
|
|
c1a7b452e0 | ||
|
|
e50ff6b0a5 | ||
|
|
34ddb92e4d | ||
|
|
35b16c7292 | ||
|
|
931fc93b4b | ||
|
|
aacd9dc62c | ||
|
|
061c55614b | ||
|
|
41c6887f33 | ||
|
|
b427185fac | ||
|
|
6fa14accfe | ||
|
|
1b8933cd84 | ||
|
|
e6261a6bf8 | ||
|
|
0a76647175 | ||
|
|
787706b1f7 | ||
|
|
94665e8055 | ||
|
|
b24770629e | ||
|
|
a09bd09a0e | ||
|
|
988df8742c | ||
|
|
10c41bf443 | ||
|
|
bb30876557 | ||
|
|
81c24b3de1 | ||
|
|
4e1f734af7 | ||
|
|
2f726cf7f2 | ||
|
|
e726d16094 | ||
|
|
5bda5124e6 | ||
|
|
1a66b7c4c3 | ||
|
|
da86dee981 | ||
|
|
6caf0fc1cc | ||
|
|
8d28976b0d | ||
|
|
26e972314e | ||
|
|
8a582f8872 | ||
|
|
ca04504573 | ||
|
|
80360214df | ||
|
|
c69eae486e | ||
|
|
57bebd3fb6 | ||
|
|
329dac77ee | ||
|
|
e5dabc63c2 | ||
|
|
f652135e19 | ||
|
|
6bf7d8b111 | ||
|
|
004ad0eb8c | ||
|
|
989034c799 | ||
|
|
c2334ce80a | ||
|
|
6d59fe3080 | ||
|
|
9c01256029 | ||
|
|
e33c863162 | ||
|
|
787a9c0083 | ||
|
|
c75c22955c | ||
|
|
5afb5d24d8 | ||
|
|
134cc34d74 | ||
|
|
3397d6c907 | ||
|
|
f8cf185db9 | ||
|
|
735935c0c4 | ||
|
|
fd3beaf2b9 | ||
|
|
034fab480d | ||
|
|
17432d1f94 | ||
|
|
62c6d8e42d | ||
|
|
14e057cf05 | ||
|
|
982c9bf964 | ||
|
|
b4aba3d263 | ||
|
|
9f9d57b9a9 | ||
|
|
236e3c7e61 | ||
|
|
2160844ad0 | ||
|
|
51475d600c | ||
|
|
149f7a1d9d | ||
|
|
56ef7ae60c | ||
|
|
7ec6586c4a | ||
|
|
074a6bfa87 | ||
|
|
965fec5927 | ||
|
|
58b87aa999 | ||
|
|
b0b16b52ee | ||
|
|
9ab3f7e5aa | ||
|
|
61210955bd | ||
|
|
28f73d0a76 | ||
|
|
99fb1a4c5f | ||
|
|
42cf80106f | ||
|
|
bcb9cfd2fe | ||
|
|
1d57568322 | ||
|
|
d56c041c4a | ||
|
|
be48ed5589 | ||
|
|
897c296fbe | ||
|
|
d25fe028b8 | ||
|
|
d9ade96fad | ||
|
|
7fd05b7ca6 | ||
|
|
0eec5383ed | ||
|
|
f474d2c834 | ||
|
|
e40e5e6a99 | ||
|
|
82d20efa8d | ||
|
|
8c7716428d | ||
|
|
9ac8a4211e | ||
|
|
23750bab55 | ||
|
|
22aeddc655 | ||
|
|
ab69cd8027 | ||
|
|
f3d35e9537 | ||
|
|
4cb72c1998 | ||
|
|
12ccc10e83 | ||
|
|
ec631f3499 | ||
|
|
75d2ea1519 | ||
|
|
14e9a94061 | ||
|
|
d3284ab9f6 | ||
|
|
775df43470 | ||
|
|
e2e6024e8f | ||
|
|
d89b51f17d | ||
|
|
aa626947ed | ||
|
|
630693d64e | ||
|
|
f2be23274e | ||
|
|
2972780bed | ||
|
|
cf3d2c3def | ||
|
|
1f8751054c | ||
|
|
cc90e6d479 | ||
|
|
76dd3c86f2 | ||
|
|
91468fa2f9 | ||
|
|
739219c57b | ||
|
|
f56e1933a6 | ||
|
|
8e4aec9c4d | ||
|
|
e6e29aaf1e | ||
|
|
1ac5f54e9e | ||
|
|
bf983658c8 | ||
|
|
e17286eb9f | ||
|
|
19c17e96de | ||
|
|
b45368342d | ||
|
|
11e071289b | ||
|
|
dcea8ae64f | ||
|
|
c9480ef17d | ||
|
|
a9517096f9 | ||
|
|
fc3f03425e | ||
|
|
8d43046f13 | ||
|
|
cd6880aff4 | ||
|
|
ccefa45fb0 | ||
|
|
b721d7a10f | ||
|
|
ef85d1d83e | ||
|
|
d03ceb2a23 | ||
|
|
90198be1cb | ||
|
|
f640494c1f | ||
|
|
77b9feb765 | ||
|
|
99139dfcca | ||
|
|
a241f63ddc | ||
|
|
70507258ae | ||
|
|
51a8144f49 | ||
|
|
54ad9ba243 | ||
|
|
a7f7a09418 | ||
|
|
44897fb371 | ||
|
|
bb6a748167 | ||
|
|
21f61d46da | ||
|
|
6ac8a9d440 | ||
|
|
c321402414 | ||
|
|
ec80fc9f3f | ||
|
|
6bfd57097f | ||
|
|
6f5df6a671 | ||
|
|
1baf3190cd | ||
|
|
66c29c49e5 | ||
|
|
e5d6740555 | ||
|
|
30b5dd63e4 | ||
|
|
f0aa8d73ea | ||
|
|
8a0761cad8 | ||
|
|
322d76b713 | ||
|
|
4f56bf3c3e | ||
|
|
942eed402a | ||
|
|
24c72650fb | ||
|
|
f5959c8829 | ||
|
|
4a8299d9dc | ||
|
|
560d388df4 | ||
|
|
7621ebed42 | ||
|
|
5447c71790 | ||
|
|
c5241eaaf6 | ||
|
|
9266b55ddf | ||
|
|
1bc1f66613 | ||
|
|
7795a690ed | ||
|
|
d498ac89f2 | ||
|
|
7683e86d8b | ||
|
|
ebb763db03 | ||
|
|
920491ddb2 | ||
|
|
761728ac43 | ||
|
|
d8ddb9dc82 | ||
|
|
405f153439 | ||
|
|
f789a35901 | ||
|
|
2842018c2f | ||
|
|
51641cc704 | ||
|
|
729f5ed5e4 | ||
|
|
46c6b2168c | ||
|
|
1f955904a4 | ||
|
|
03ff33acaf | ||
|
|
46035e76cc | ||
|
|
7c073f76ae | ||
|
|
558c89cc30 | ||
|
|
222d41c84a | ||
|
|
12a62f4607 | ||
|
|
f561768c67 | ||
|
|
5ced5ce253 | ||
|
|
55781e911e | ||
|
|
ee3c4a4124 | ||
|
|
6815e56e57 | ||
|
|
6c744443fb | ||
|
|
3c37047afb | ||
|
|
f31f09d77a | ||
|
|
c1bb05c0a4 | ||
|
|
f5b8d8a60c | ||
|
|
8218cfc72c | ||
|
|
de508ee68f | ||
|
|
a932111040 | ||
|
|
8c437eb815 | ||
|
|
1ad4815983 | ||
|
|
00706daae5 | ||
|
|
c75cdc6d28 | ||
|
|
b9fae7fb7d | ||
|
|
e74a3da5cd | ||
|
|
08cf986cae | ||
|
|
ba01ed0153 | ||
|
|
19ac8bd9b2 | ||
|
|
ab79ccb02b | ||
|
|
6ba8a6a600 | ||
|
|
377fb2329c | ||
|
|
285ee665ee | ||
|
|
d862498516 | ||
|
|
b09b03a427 | ||
|
|
4ef2ede4cf | ||
|
|
0efaa11553 | ||
|
|
ea87b958ef | ||
|
|
ff62f075d0 | ||
|
|
348744086d | ||
|
|
d1d4f79973 | ||
|
|
2a3f7f8cb3 | ||
|
|
7eaef11a84 | ||
|
|
efe93d0117 | ||
|
|
7d12e18b98 | ||
|
|
de6bca424f | ||
|
|
03268a5575 | ||
|
|
1251680a1c | ||
|
|
f8d55ba837 | ||
|
|
cd0e49914b | ||
|
|
700e845727 | ||
|
|
bab8120814 | ||
|
|
c6f1f19866 | ||
|
|
745592f507 | ||
|
|
afec65eb56 | ||
|
|
d6661da0a7 | ||
|
|
dcc4732748 | ||
|
|
6a5bf08d55 | ||
|
|
d52f5e6e03 | ||
|
|
eb62356313 | ||
|
|
919dc248e3 | ||
|
|
ca5db2bff8 | ||
|
|
658698ed2f | ||
|
|
7f391dacbd | ||
|
|
90e0bf95d1 | ||
|
|
930bfb26f4 | ||
|
|
7e788f212a | ||
|
|
8f99530795 | ||
|
|
434af4b998 | ||
|
|
a011728cc9 | ||
|
|
e584139b6d | ||
|
|
a7c8526f3e | ||
|
|
459256e83a | ||
|
|
21f3f52c7b | ||
|
|
568e43cf3d | ||
|
|
e004e540d7 | ||
|
|
cac6172344 | ||
|
|
8dbfb87246 | ||
|
|
d8cbc7ddd8 | ||
|
|
bdf3a2dfe8 | ||
|
|
693b82e47d | ||
|
|
888be0fd5e | ||
|
|
9f97ed331b | ||
|
|
e8ea2af298 | ||
|
|
785c2e36c6 | ||
|
|
ee043e67a4 | ||
|
|
d824b41bbb | ||
|
|
a9df64f861 | ||
|
|
6c3b449f74 | ||
|
|
536c6a7b2c | ||
|
|
e90e0fc615 | ||
|
|
b704121dcb | ||
|
|
5e0886d744 | ||
|
|
f819e4829b | ||
|
|
8873948e9e | ||
|
|
a25ea14436 | ||
|
|
1a922f05c1 | ||
|
|
e8268b1dab | ||
|
|
4cb78f55d1 | ||
|
|
7a516930b1 | ||
|
|
8091bec6bf | ||
|
|
7baf42b138 | ||
|
|
ab9835b896 | ||
|
|
9d142c5607 | ||
|
|
92b68bdb8f | ||
|
|
a86bb9f6e6 | ||
|
|
09db6dc424 | ||
|
|
3b62526267 | ||
|
|
5d80031a40 | ||
|
|
c9777af91c | ||
|
|
656e4d529c | ||
|
|
a894873d6b | ||
|
|
2d1a97e042 | ||
|
|
ece3f96867 | ||
|
|
65a48b324d | ||
|
|
53bf622065 | ||
|
|
075be18123 | ||
|
|
044390b4b4 | ||
|
|
37d03aaebe | ||
|
|
51a51833d4 | ||
|
|
a8cfc1ef7a | ||
|
|
1d238c8315 | ||
|
|
4f96744ff2 | ||
|
|
e9783ecccc | ||
|
|
6342cc41ac | ||
|
|
c554390de5 | ||
|
|
4d8bbe3023 | ||
|
|
969076f1ef | ||
|
|
20032def7e | ||
|
|
94706460c0 | ||
|
|
b7506229f8 | ||
|
|
58c6df3537 | ||
|
|
235a1f36ec | ||
|
|
b53821976e | ||
|
|
4355881fb2 | ||
|
|
cf50d558ba | ||
|
|
7488dc3ebb | ||
|
|
b449847ad1 | ||
|
|
9785745384 | ||
|
|
56ffa7905e | ||
|
|
216433aa2d | ||
|
|
122fbbed22 | ||
|
|
042c671bd4 | ||
|
|
38fdc11917 | ||
|
|
2f4730a9c6 | ||
|
|
3759d32c89 | ||
|
|
93c2ca8df1 | ||
|
|
832aac0e6e | ||
|
|
6967d4e762 | ||
|
|
3c70681537 | ||
|
|
0ce08319e7 | ||
|
|
17e0489164 | ||
|
|
7953cc416b | ||
|
|
a670ac0aea | ||
|
|
ef30018008 | ||
|
|
66810c8b75 | ||
|
|
2bba55ebd5 | ||
|
|
b977ae4d3b | ||
|
|
d4f5e854c5 | ||
|
|
837f621633 | ||
|
|
a781b4a387 | ||
|
|
a73a75a7f8 | ||
|
|
17d1db913f | ||
|
|
a924509e92 | ||
|
|
04b4321ea1 | ||
|
|
1f9ebc7295 | ||
|
|
6d88111dfc | ||
|
|
184e52b4ec | ||
|
|
2a3cc3d88c | ||
|
|
ffa1aae27c | ||
|
|
7cd842df19 | ||
|
|
e399e4960c | ||
|
|
5c193a47eb | ||
|
|
b63c02cb10 | ||
|
|
09418f1a5d | ||
|
|
fa4491340a | ||
|
|
192814650d | ||
|
|
5f1addc54d | ||
|
|
9ffc8c6800 | ||
|
|
64cd8084ea | ||
|
|
2e6c9d408c | ||
|
|
f3bea49f61 | ||
|
|
48fdae754e | ||
|
|
64f2ee67b2 | ||
|
|
19d34779a0 | ||
|
|
76a6a0cf75 | ||
|
|
da47d97cd0 | ||
|
|
f59441005e | ||
|
|
e30347a11f | ||
|
|
8ac079fb72 | ||
|
|
4295f08a84 | ||
|
|
bd8eb97d46 | ||
|
|
329f656c40 | ||
|
|
f2c7a26ce0 | ||
|
|
930e25e64a | ||
|
|
963269a685 | ||
|
|
de23ef5d35 | ||
|
|
208ae6183c | ||
|
|
761ae4b816 | ||
|
|
ff308641e1 | ||
|
|
a2094ddf75 | ||
|
|
0391ed3e63 | ||
|
|
b6b3997498 | ||
|
|
9f77c0c9b7 | ||
|
|
dc4812a86e | ||
|
|
fc83b0d95b | ||
|
|
8e70568e32 | ||
|
|
f0e3a3a30c | ||
|
|
cf44efa02e | ||
|
|
ddc59dfb97 | ||
|
|
ef0a3396d7 | ||
|
|
8bf68aa020 | ||
|
|
02a90856ff | ||
|
|
8716695d4e | ||
|
|
9a1bb69cd8 | ||
|
|
6caad0daf6 | ||
|
|
6508f1541b | ||
|
|
6809b38821 | ||
|
|
7f9a3efa24 | ||
|
|
8ecea9792b | ||
|
|
7c85a03b42 | ||
|
|
d4d71b90eb | ||
|
|
fbf614a8df | ||
|
|
c02329e4b1 | ||
|
|
5aba065413 | ||
|
|
6e65096bb4 | ||
|
|
b39f25ed51 | ||
|
|
3925d5ec27 | ||
|
|
381b59acd4 | ||
|
|
5b01d923d3 | ||
|
|
108e5a2f5e | ||
|
|
e21d17a482 | ||
|
|
d4ea8c56c3 | ||
|
|
783ad64353 | ||
|
|
ac918c1a81 | ||
|
|
0f00074f77 | ||
|
|
eb20ec1556 | ||
|
|
32f9da0724 | ||
|
|
968be8eb8f | ||
|
|
d7e05cde42 | ||
|
|
557b86a7a9 | ||
|
|
f144dda8b5 | ||
|
|
80aed31135 | ||
|
|
2a21e7c2cb | ||
|
|
d281277797 | ||
|
|
fb807bcde4 | ||
|
|
ebf6f6782f | ||
|
|
008df649f0 | ||
|
|
a810e704ad | ||
|
|
d0b3167956 | ||
|
|
a726ecbdd8 | ||
|
|
da6a8f806d | ||
|
|
b47f44cacd | ||
|
|
0cc59adad7 | ||
|
|
6c076863db | ||
|
|
ddb6e74955 | ||
|
|
2094bc3d80 | ||
|
|
c922007d21 | ||
|
|
b1435c1264 | ||
|
|
be5e1648e0 | ||
|
|
a270feb1eb | ||
|
|
103b8cd13a | ||
|
|
e6dd36283d | ||
|
|
aae2d0a5dc | ||
|
|
fda1d4cc2b | ||
|
|
5be92460c1 | ||
|
|
15ce31ea3a | ||
|
|
35e5a669a0 | ||
|
|
8b8c74cf93 | ||
|
|
cc43524b4c | ||
|
|
f87d297155 | ||
|
|
605d50166a | ||
|
|
de6681d00a | ||
|
|
7632e33975 | ||
|
|
5993a596e8 | ||
|
|
2294b6babb | ||
|
|
c38f866363 | ||
|
|
511b112ac7 | ||
|
|
8cd0618e85 | ||
|
|
b4b589bfc2 | ||
|
|
cb69eb7c0f | ||
|
|
7d83cd89f2 | ||
|
|
b2dca0a34f | ||
|
|
3bd73961d7 | ||
|
|
67f574b5d8 | ||
|
|
f9b70a37aa | ||
|
|
d4047e1413 | ||
|
|
80f5b4c3b7 | ||
|
|
4668a6d8c0 | ||
|
|
e6f076306f | ||
|
|
b73dc127a3 | ||
|
|
8c8a2311d6 | ||
|
|
0555fb22ca | ||
|
|
85cde62039 | ||
|
|
46a2648d15 | ||
|
|
e55f6ecd6b | ||
|
|
c71fee3fed | ||
|
|
4d6c25c9d3 | ||
|
|
6ed4e2d946 | ||
|
|
6b4242478f | ||
|
|
ef5478279b | ||
|
|
62bb8bce1c | ||
|
|
83a5c3af8a | ||
|
|
f78abd61d4 | ||
|
|
209c6fa1c1 | ||
|
|
6e3c600a49 | ||
|
|
b1cda57174 | ||
|
|
412d92e782 | ||
|
|
c0703a6a5e | ||
|
|
64bd306c6d | ||
|
|
6be49f898c | ||
|
|
59bc73656f | ||
|
|
bed22f51b4 | ||
|
|
c1362a02f3 | ||
|
|
859a3cbe6e | ||
|
|
a6d82f44b3 | ||
|
|
e66e17a41a | ||
|
|
cfa6d7080c | ||
|
|
01ceedccd5 | ||
|
|
ed28af7c73 | ||
|
|
74cf91f99e | ||
|
|
44479930df | ||
|
|
cb1f54aac4 | ||
|
|
d68d2e9f30 | ||
|
|
948c48ea23 | ||
|
|
a9ccf6ca42 | ||
|
|
fd7b829e70 | ||
|
|
87a7cc6289 | ||
|
|
2f8b5e53bb | ||
|
|
8b7fa3b646 | ||
|
|
dd2c71fe61 | ||
|
|
3b58d57e5c | ||
|
|
cecf32e52e | ||
|
|
91a2dfab36 | ||
|
|
5e5838a8c1 | ||
|
|
0fffbc06dd | ||
|
|
4d360bfb73 | ||
|
|
e3001b614e | ||
|
|
6ecdef02ab | ||
|
|
36903eb749 | ||
|
|
f530c9514f | ||
|
|
fdffa77bc5 | ||
|
|
245dd39a60 | ||
|
|
4614aacc02 | ||
|
|
64ccdab90c | ||
|
|
02286b0c4e | ||
|
|
8e952a550b | ||
|
|
a29f95194d | ||
|
|
0e5db49b93 | ||
|
|
a2c29c0937 | ||
|
|
c318f05cfd | ||
|
|
789d200c24 | ||
|
|
2dc4a9e044 | ||
|
|
82577b91d5 | ||
|
|
8fd08a1574 | ||
|
|
7a41fc8ec8 | ||
|
|
798ca929d6 | ||
|
|
7e4e58fb78 | ||
|
|
28b9975c75 | ||
|
|
5536ade389 | ||
|
|
21bc195213 | ||
|
|
b6beacf053 | ||
|
|
94b6c133f4 | ||
|
|
949d7bed89 | ||
|
|
81ce12a38c | ||
|
|
eba65b2934 | ||
|
|
c7f5b7fca1 | ||
|
|
f670d522bf | ||
|
|
a02f7f46c3 | ||
|
|
4b7f254e17 | ||
|
|
9b42be560d | ||
|
|
31b39231a2 | ||
|
|
4eb2c1f646 | ||
|
|
5f89d8588d | ||
|
|
404cbf9b4a | ||
|
|
0aabc09b82 | ||
|
|
a5ebeadd95 | ||
|
|
9e188aaf03 | ||
|
|
870f5caca9 | ||
|
|
28b4ddfc72 | ||
|
|
13a4a26e97 | ||
|
|
81c7e63994 | ||
|
|
7f234ab5bc | ||
|
|
f8d0682810 | ||
|
|
175d6b1fc5 | ||
|
|
1cd8e8a097 | ||
|
|
ed95e38257 | ||
|
|
cab585225d | ||
|
|
3688dde5e5 | ||
|
|
ae6a5b2512 | ||
|
|
6f87611d67 | ||
|
|
6a5e31c908 | ||
|
|
8bda5e16cd | ||
|
|
d70d3d95f0 | ||
|
|
554b7d2ec4 | ||
|
|
ebc4031922 | ||
|
|
c526997aba | ||
|
|
c0e3a1f3ef | ||
|
|
7dc0a7a5c3 | ||
|
|
2943b6ed04 | ||
|
|
5feb212df7 | ||
|
|
327edcd347 | ||
|
|
94cbf4cddf | ||
|
|
08cc87affb | ||
|
|
18020d64cc | ||
|
|
48b7ceac06 | ||
|
|
dbcce9663c | ||
|
|
6ee7dd56fe | ||
|
|
22328772ca | ||
|
|
99418e6b88 | ||
|
|
52bd079c0a | ||
|
|
67db5e9dfc | ||
|
|
5f1bc6c6c2 | ||
|
|
05201d7012 | ||
|
|
6b4983537e | ||
|
|
87c8293c78 | ||
|
|
54488564f3 | ||
|
|
f2ac9ed385 | ||
|
|
38f2f1e30a | ||
|
|
02004011ec | ||
|
|
60bb982450 | ||
|
|
67389c0bac | ||
|
|
faa1fee1c0 | ||
|
|
0bae421fbc | ||
|
|
b29d81bf0f | ||
|
|
4792828da1 | ||
|
|
6171e887a8 | ||
|
|
f28fa93f40 | ||
|
|
940ad84493 | ||
|
|
0b168376ed | ||
|
|
f7bd376499 | ||
|
|
9566155bdb | ||
|
|
9994ddb31b | ||
|
|
fadfdaa673 | ||
|
|
4ca546f44a | ||
|
|
8af30c9256 | ||
|
|
42adc38720 | ||
|
|
c1d9dee46c | ||
|
|
69a7104286 | ||
|
|
aba5afe32c | ||
|
|
c1ccf4fceb | ||
|
|
916a4cfc73 | ||
|
|
fd107ab5b8 | ||
|
|
5fa6fccf7b | ||
|
|
0ce226d0c9 | ||
|
|
14e0b471d3 | ||
|
|
ed0df64cf9 | ||
|
|
35bc2c9803 | ||
|
|
a771dc8787 | ||
|
|
244eb91dfb | ||
|
|
7488a6d42b | ||
|
|
696a59f1b9 | ||
|
|
ee5a3269f2 | ||
|
|
f89bf027f7 | ||
|
|
4db432b0a9 | ||
|
|
c82fd9ead5 | ||
|
|
34715b1e06 | ||
|
|
f0870b3236 | ||
|
|
9a286800d6 | ||
|
|
59832b1777 | ||
|
|
561f566506 | ||
|
|
f0cacf6bd5 | ||
|
|
ce4031af74 | ||
|
|
dd7f91b8c2 | ||
|
|
8523e5bf6b | ||
|
|
860727d27a | ||
|
|
f175bf2c82 | ||
|
|
40008f44ac | ||
|
|
3f93b5c63b | ||
|
|
d2ce051c4a | ||
|
|
d5d90bde9a | ||
|
|
fc8d9febf6 | ||
|
|
b43c542213 | ||
|
|
e7533232c0 | ||
|
|
5e1aaf11a7 | ||
|
|
d062dffc13 | ||
|
|
4810bbbbd9 | ||
|
|
967998273f | ||
|
|
24decf8abc | ||
|
|
3bc605894e | ||
|
|
b74ae302ec | ||
|
|
db3dac261a | ||
|
|
87b47b3042 | ||
|
|
720e1a038e | ||
|
|
1753c54e88 | ||
|
|
2d42de83de | ||
|
|
c4e6af455d | ||
|
|
51d619449b | ||
|
|
1160a14f56 | ||
|
|
57fce0ddbc | ||
|
|
b9eb8a750b | ||
|
|
3ce16e0ed1 | ||
|
|
554d9b4047 | ||
|
|
02d565ce58 | ||
|
|
795bc1276b | ||
|
|
499b7b2e67 | ||
|
|
b6c0fe8bf7 | ||
|
|
d5bb1b72b9 | ||
|
|
af86564adc | ||
|
|
5354e02b6f | ||
|
|
4ee17a656f | ||
|
|
32c59b66f6 | ||
|
|
20732f04ff | ||
|
|
06763b34c3 | ||
|
|
6bab6c57f2 | ||
|
|
4eab89d73e | ||
|
|
8d20c46228 | ||
|
|
f5c4586bb7 | ||
|
|
bc6bbdbbe0 | ||
|
|
b77caed0ba | ||
|
|
df976f1212 | ||
|
|
999dd5eb6f | ||
|
|
a1a6a3ab81 | ||
|
|
d067bbfa65 | ||
|
|
3bd40eeb27 | ||
|
|
b124d54055 | ||
|
|
90691de457 | ||
|
|
bee83a3a3e | ||
|
|
fd8f2438fa | ||
|
|
7937d99a73 | ||
|
|
569afb5535 | ||
|
|
fc5a45e113 | ||
|
|
950f4a9f1a | ||
|
|
6a6e80b6d8 | ||
|
|
083c9792a6 | ||
|
|
893bfce767 | ||
|
|
f61f3df732 | ||
|
|
a3be5e332e | ||
|
|
33d65a8593 | ||
|
|
ebbf01c6e5 | ||
|
|
acb8496352 | ||
|
|
ecad5772d2 | ||
|
|
6e6f5714dd | ||
|
|
50ae15aa4f | ||
|
|
4e2c3049a0 | ||
|
|
3a785c166e | ||
|
|
5248a4eb9c | ||
|
|
c9a53aed7b | ||
|
|
bafe5dc784 | ||
|
|
5325488099 | ||
|
|
737ad5c8b7 | ||
|
|
17cea4e274 | ||
|
|
af5b579a2f | ||
|
|
c87eaaa928 | ||
|
|
33418397f8 | ||
|
|
8c7258e839 | ||
|
|
98fff9b81d | ||
|
|
0c63b27eea | ||
|
|
0968981aef | ||
|
|
8db4abdf43 | ||
|
|
9aa4219bf0 | ||
|
|
6c32ab4711 | ||
|
|
a80c5a1efa | ||
|
|
4ba46bff69 | ||
|
|
6a7c97277f | ||
|
|
cc70ff9732 | ||
|
|
2d25948c57 | ||
|
|
8946af4831 | ||
|
|
5e7ca0374c | ||
|
|
21f8e89ba4 | ||
|
|
f0aca90de2 | ||
|
|
097228066a | ||
|
|
7d8782f3dc | ||
|
|
e4ea9d561e | ||
|
|
e284d9de8e | ||
|
|
df6382a1ca | ||
|
|
c1c1a3318c | ||
|
|
796df1cec5 | ||
|
|
28980293c5 | ||
|
|
d878ad2e7e | ||
|
|
1290d1e9d4 | ||
|
|
f229f1e9fe | ||
|
|
0776951018 | ||
|
|
6d47b449b9 | ||
|
|
594c975c70 | ||
|
|
bf57318307 | ||
|
|
abd87793e4 | ||
|
|
7b4e6128ce | ||
|
|
2ae65acc28 | ||
|
|
2ee87ad078 | ||
|
|
d65beea179 | ||
|
|
b19f3ff8cf | ||
|
|
75fae9454d | ||
|
|
5d309c39cf | ||
|
|
649fc5a0e6 | ||
|
|
67cfa5d42f | ||
|
|
5dcacdeea1 | ||
|
|
2f7073bbe4 | ||
|
|
e8df6ed3be | ||
|
|
d9eb4c1296 | ||
|
|
4af0fbf553 | ||
|
|
2da0862cb2 | ||
|
|
66fcf84688 | ||
|
|
5740d40d57 | ||
|
|
6ef2256bf2 | ||
|
|
65f911909b | ||
|
|
2cb6e454c8 | ||
|
|
abfaa47db2 | ||
|
|
e06970eebb | ||
|
|
dadc83800b | ||
|
|
62f2c67321 | ||
|
|
1651844b4f | ||
|
|
fb9f42ff93 | ||
|
|
9c29b982dd | ||
|
|
f52c4964b3 | ||
|
|
46a8edb781 | ||
|
|
8dbdbe6d6c | ||
|
|
778069c15d | ||
|
|
e98457c540 | ||
|
|
7a3a76065c | ||
|
|
c73c97dc7b | ||
|
|
1b0dd279ae | ||
|
|
7dd487ccc5 | ||
|
|
d046591512 | ||
|
|
e4ce115abf | ||
|
|
aedcac5820 | ||
|
|
9f4430ad92 | ||
|
|
2ad8f1c112 | ||
|
|
f0d884e114 | ||
|
|
b618f5be80 | ||
|
|
7b63eac3eb | ||
|
|
df3f2ea9c1 | ||
|
|
30c6280ed1 | ||
|
|
1960b59629 | ||
|
|
6e6edf8322 | ||
|
|
f47fb01614 | ||
|
|
ae30bdd599 | ||
|
|
2c8962cf5f | ||
|
|
eb3e507a11 | ||
|
|
be3147465d | ||
|
|
484721fece | ||
|
|
9c36026991 | ||
|
|
bf5055f944 | ||
|
|
389034bf1a | ||
|
|
3f07102f2a | ||
|
|
d4ccfa31b5 | ||
|
|
5814b2a4b8 | ||
|
|
d3f61af493 | ||
|
|
233ea7bb4a | ||
|
|
6893a30ffb | ||
|
|
ae6d2fb363 | ||
|
|
baa7cb3a10 | ||
|
|
7b90544d91 | ||
|
|
9a5495d8b2 | ||
|
|
1fa769b3e7 | ||
|
|
96766ece4e | ||
|
|
add525396f | ||
|
|
26ae4edd63 | ||
|
|
063893adee | ||
|
|
ff37e99d71 | ||
|
|
3d0b02ee23 | ||
|
|
d7cfbfe6c8 | ||
|
|
dc00e22f13 | ||
|
|
bcde481304 | ||
|
|
5b1341e488 | ||
|
|
6ad70ceee3 | ||
|
|
9c4d2f5490 | ||
|
|
6c5eff1143 | ||
|
|
a893767d0f | ||
|
|
a4f240edc8 | ||
|
|
e0a94f694b | ||
|
|
8654f25a4f | ||
|
|
e877310d85 | ||
|
|
bb59f45ba6 | ||
|
|
3d4c2a2c20 | ||
|
|
e36667cd08 | ||
|
|
cebaa6949e | ||
|
|
019e22aff2 | ||
|
|
5129e2ea73 | ||
|
|
3b63f60462 | ||
|
|
5e29115c2e | ||
|
|
0b4b30286d | ||
|
|
a01f64080d | ||
|
|
d031351bc8 | ||
|
|
1d21d36253 | ||
|
|
8d4cd72b41 | ||
|
|
46ab6d3476 | ||
|
|
3fcf3cbf93 | ||
|
|
ada912c69b | ||
|
|
e204b89eaf | ||
|
|
e903798fc2 | ||
|
|
54497c43b6 | ||
|
|
99e54cc214 | ||
|
|
56ae47cd8d | ||
|
|
0fb336cf7b | ||
|
|
469b3c0a94 | ||
|
|
d90d88c68b | ||
|
|
dcc061af3e | ||
|
|
a2960f5c50 | ||
|
|
565f8a2b4d | ||
|
|
5cb50d57ec | ||
|
|
522e19d4bf | ||
|
|
0db7a78889 | ||
|
|
1ce3b40b4e | ||
|
|
e633528a7a | ||
|
|
6570b411d1 | ||
|
|
ac9e774795 | ||
|
|
8791747453 | ||
|
|
dda3afe9fa | ||
|
|
d4435f980c | ||
|
|
f29673a6e3 | ||
|
|
9816bab151 | ||
|
|
5884c0bcb3 | ||
|
|
96dc00beac | ||
|
|
febc1e53b6 | ||
|
|
3e18fb3ca0 | ||
|
|
28b9de2e7a | ||
|
|
9a41399178 | ||
|
|
db47b9a877 | ||
|
|
7cdd7a3487 | ||
|
|
833f646903 | ||
|
|
35a85860b1 | ||
|
|
00f24dfb79 | ||
|
|
8c6ae2576d | ||
|
|
5416ad33bd | ||
|
|
1e25ba2d8e | ||
|
|
8d08d25f5b | ||
|
|
802e7b12d0 | ||
|
|
9b57550f3d | ||
|
|
28c13c8e52 | ||
|
|
d8f9059989 | ||
|
|
ac9d37d038 | ||
|
|
6323c13704 | ||
|
|
2f7f16daff | ||
|
|
9059238aee | ||
|
|
2677c0e752 | ||
|
|
ba80770564 | ||
|
|
06ad35d934 | ||
|
|
864c4f6bc3 | ||
|
|
f5f0f02abe | ||
|
|
19979dec55 | ||
|
|
926e61b7cc | ||
|
|
15378d3267 | ||
|
|
33fcfda1a0 | ||
|
|
74d7b43d0f | ||
|
|
e392c8f0e6 | ||
|
|
f60ba8587f | ||
|
|
86a7f837cd | ||
|
|
9465497481 | ||
|
|
8c3f3ac304 | ||
|
|
88ba8f6f55 | ||
|
|
c64459dbf4 | ||
|
|
8b0bbffe27 | ||
|
|
94805259d7 | ||
|
|
e796d44f92 | ||
|
|
5e8686db77 | ||
|
|
ee835f6514 | ||
|
|
5de61aaed3 | ||
|
|
6613e4ec42 | ||
|
|
206314f4f4 | ||
|
|
8f12c3f1a8 | ||
|
|
4c224d0b9c | ||
|
|
30dd089c8b | ||
|
|
8d9ec206bf | ||
|
|
8319288776 | ||
|
|
60bf36613f | ||
|
|
a75994cbbf | ||
|
|
e1f7c7b03d | ||
|
|
bb7e2c7cee | ||
|
|
69eb6469f9 | ||
|
|
d2eb3be7f8 | ||
|
|
5aa76639d1 | ||
|
|
3bf72a1af6 | ||
|
|
b745d88299 | ||
|
|
3aedc07ad0 | ||
|
|
dbb164f4be | ||
|
|
b0103d1ce3 | ||
|
|
9c532047d3 | ||
|
|
0003a58210 | ||
|
|
34f2704dc7 | ||
|
|
0ddee379ca | ||
|
|
6dcbe4fabb | ||
|
|
5dbb9fdf3f | ||
|
|
914fa3079d | ||
|
|
2e958d8d8f | ||
|
|
7a5e61fd2e | ||
|
|
6a031d8f53 | ||
|
|
dc6f01c0d3 | ||
|
|
1cc8cbe8a8 | ||
|
|
01ae8bec85 | ||
|
|
258ab87f6b | ||
|
|
8ba2db6c58 | ||
|
|
a7599e85dc | ||
|
|
28389d698e | ||
|
|
c47a220721 | ||
|
|
69f7296baa | ||
|
|
855f56bb45 | ||
|
|
a79d072aaf | ||
|
|
467047a011 | ||
|
|
0288daa39d | ||
|
|
3f075068a9 | ||
|
|
278e7027f2 | ||
|
|
9d654c1f18 | ||
|
|
279187d13b | ||
|
|
360494f971 | ||
|
|
81931eb536 | ||
|
|
a2ef11eb0f | ||
|
|
b872252771 | ||
|
|
b2c388276f | ||
|
|
178928f866 | ||
|
|
7e548f9969 | ||
|
|
a60ce3c54c | ||
|
|
0f173bcc5a | ||
|
|
64dbe8312e | ||
|
|
7f443c71ae | ||
|
|
27276c025c | ||
|
|
e9d03c179c | ||
|
|
dec01c23a9 | ||
|
|
e0eb227ce5 | ||
|
|
20021c5b31 | ||
|
|
f8d6797fc2 | ||
|
|
25051980ce | ||
|
|
fb8becca99 | ||
|
|
25bd8a7eaa | ||
|
|
bbd2424a3f | ||
|
|
83eeeed319 | ||
|
|
c92e8161a1 | ||
|
|
258555c990 | ||
|
|
0f7799422e | ||
|
|
177b565d7c | ||
|
|
a62b336b6c | ||
|
|
3ea61c8b3a | ||
|
|
4c57f9f902 | ||
|
|
6d7941fba4 | ||
|
|
020c6388c2 | ||
|
|
53d35e8c77 | ||
|
|
01f205d352 | ||
|
|
a786167b04 | ||
|
|
1699ab48e8 | ||
|
|
b15c04a532 | ||
|
|
20d3740e75 | ||
|
|
80d57f8c0c | ||
|
|
1de367e89c | ||
|
|
8850a89e30 | ||
|
|
4f72011cf7 | ||
|
|
c569232e74 | ||
|
|
14c526d0c4 | ||
|
|
5c4ac6b702 | ||
|
|
d58cc18136 | ||
|
|
36c01fde94 | ||
|
|
d4d9d59fe4 | ||
|
|
8dbd0a6130 | ||
|
|
3746344cba | ||
|
|
d07fd1bbfe | ||
|
|
02f95c0ed4 | ||
|
|
c98fcbd795 | ||
|
|
d071877963 | ||
|
|
0267cb4006 | ||
|
|
bf571e595c | ||
|
|
c0cad70212 | ||
|
|
7bd6dbb4b4 | ||
|
|
6d932e3d04 | ||
|
|
e154b5179d | ||
|
|
52110d6008 | ||
|
|
103b08fd1d | ||
|
|
cb09d10e7f | ||
|
|
a041c1e60d | ||
|
|
586b4cf4bd | ||
|
|
d0ff149cca | ||
|
|
f8ddc8325c | ||
|
|
59ec09e82c | ||
|
|
2ae5c96690 | ||
|
|
fda9e6bb9c | ||
|
|
29bcb8e07c | ||
|
|
b70de81c2d | ||
|
|
5e89b2568f | ||
|
|
ac1d8215ff | ||
|
|
fefc734bfa | ||
|
|
7f8735842c | ||
|
|
a226983470 | ||
|
|
28526d0a12 | ||
|
|
913e005bae | ||
|
|
7bd9fd5bae | ||
|
|
8986b89d67 | ||
|
|
ef936214f0 | ||
|
|
18fce6b3e3 | ||
|
|
ecda4d74ab | ||
|
|
31124037b5 | ||
|
|
aaf95e0756 | ||
|
|
804e311875 | ||
|
|
61ad9bc47d | ||
|
|
2b23b7876a | ||
|
|
547d334f43 | ||
|
|
7432dc115e | ||
|
|
905defe8ce | ||
|
|
0a8ff0cde7 | ||
|
|
bd5f44030e | ||
|
|
79abb86262 | ||
|
|
fe6f98ec5a | ||
|
|
e39a856e54 | ||
|
|
64e5f8155d | ||
|
|
8328b11f6b | ||
|
|
15778b2ca5 | ||
|
|
b7842014c1 | ||
|
|
a804053904 | ||
|
|
2aee72b47b | ||
|
|
0cb8c600b7 | ||
|
|
aa5348f37e | ||
|
|
0736574a57 | ||
|
|
d56365ce63 | ||
|
|
c82d2f856a | ||
|
|
8432677826 | ||
|
|
0c0c6e5470 | ||
|
|
57019b6e20 | ||
|
|
12ab2249b4 | ||
|
|
22d0992d38 | ||
|
|
f8def04653 | ||
|
|
6349530fc5 | ||
|
|
ad83a7dcc3 | ||
|
|
cfc2239733 | ||
|
|
91552a3a2b | ||
|
|
4e3204bc6d | ||
|
|
a94998bd02 | ||
|
|
81c78eafa6 | ||
|
|
273523480f | ||
|
|
b27fefae88 | ||
|
|
aa00a1b8d1 | ||
|
|
ba62e0eefc | ||
|
|
cb16c75e11 | ||
|
|
3efed0ace3 | ||
|
|
879fb8194f | ||
|
|
049dd89470 | ||
|
|
1f59d4354a | ||
|
|
8dea45d9d5 | ||
|
|
21ba6e257c | ||
|
|
18ebda01a4 | ||
|
|
3acb843109 | ||
|
|
1768aea66f | ||
|
|
4b61f273d5 | ||
|
|
a1dbbbdafc | ||
|
|
dcb840f290 | ||
|
|
e6c4c66199 | ||
|
|
b76cd558aa | ||
|
|
85b077b5c5 | ||
|
|
c34d6e6606 | ||
|
|
a5fd0aebe6 | ||
|
|
aaec04d04a | ||
|
|
b4272e0387 | ||
|
|
77f9d6cb1d | ||
|
|
aaa82b34e4 | ||
|
|
7a6b1129d9 | ||
|
|
1f8918c773 | ||
|
|
e9fe724e59 | ||
|
|
80001246ef | ||
|
|
50461bb7c8 | ||
|
|
c7c7cfde74 | ||
|
|
dcc29c0c48 | ||
|
|
635e299464 | ||
|
|
502c4e51ae | ||
|
|
382fdcbb40 | ||
|
|
468e092422 | ||
|
|
6904d4693f | ||
|
|
3ef7ec3be5 | ||
|
|
70257cbbfa | ||
|
|
6ef31d0ec1 | ||
|
|
d3077bec58 | ||
|
|
a1095353fc | ||
|
|
66fab1b3df | ||
|
|
569d6d4272 | ||
|
|
07c19ce085 | ||
|
|
d86dd4f80b | ||
|
|
f0f89f0894 | ||
|
|
47af2e83f7 | ||
|
|
8ec87872c8 | ||
|
|
f30ea80b42 | ||
|
|
1dd6e66167 | ||
|
|
4e681b2dd1 | ||
|
|
58be00b3ce | ||
|
|
5604ac6b6a | ||
|
|
effdaefdf3 | ||
|
|
5775fad030 | ||
|
|
eabc6d79c3 | ||
|
|
5f4ca6e383 | ||
|
|
c05020e28e | ||
|
|
5206079e23 | ||
|
|
9b01140882 | ||
|
|
4dae27da98 | ||
|
|
f0cab65a6d | ||
|
|
699a47351b | ||
|
|
af004da699 | ||
|
|
b5ad885237 | ||
|
|
07bd0fec70 | ||
|
|
318e51d736 | ||
|
|
ae90db50fe | ||
|
|
64772c195e | ||
|
|
05ead63bdc | ||
|
|
6f5c64420d | ||
|
|
d9d9a00a24 | ||
|
|
c1de67032c | ||
|
|
890d49fdd7 | ||
|
|
ba96ea5a0c | ||
|
|
b481b784bb | ||
|
|
53b6e68a85 | ||
|
|
e3d16418a0 | ||
|
|
e41f560ecd | ||
|
|
d394d9a529 | ||
|
|
a73015fa6e | ||
|
|
87846864cc | ||
|
|
f3b976bdd1 | ||
|
|
3a06e319b0 | ||
|
|
fe31c404ff | ||
|
|
cc23378758 | ||
|
|
5cac949ea8 | ||
|
|
a35e897194 | ||
|
|
8e92edeae1 | ||
|
|
f289a0a9a8 | ||
|
|
65a7e89a8c | ||
|
|
43be3259c9 | ||
|
|
54a4c95a1b | ||
|
|
ddac5cbfbc | ||
|
|
22342d01a5 | ||
|
|
7cffaeb193 | ||
|
|
2534496543 | ||
|
|
fe9b11e771 | ||
|
|
032347840f | ||
|
|
2978bc6ac5 | ||
|
|
a3b0bb323f | ||
|
|
a6246d27d9 | ||
|
|
884b649b53 | ||
|
|
92a2f770b4 | ||
|
|
e88ce078df | ||
|
|
77f0dfb9b1 | ||
|
|
78d1accf07 | ||
|
|
2ec68a7f07 | ||
|
|
bbaa2a2c92 | ||
|
|
341bb67ef4 | ||
|
|
e377cb423b | ||
|
|
81e954c258 | ||
|
|
79d41ba7ac | ||
|
|
e740e4da87 | ||
|
|
b476c47194 | ||
|
|
b2d61a93d9 | ||
|
|
a045ec9d46 | ||
|
|
1daf8d2743 | ||
|
|
295824f440 | ||
|
|
22b59e0cf6 | ||
|
|
ecabdb82e6 | ||
|
|
924b1c1a67 | ||
|
|
0454c4c25a | ||
|
|
3a3b81941b | ||
|
|
0875c29da5 | ||
|
|
0d4cf9f6c4 | ||
|
|
6a525dcf59 | ||
|
|
01f6904f82 | ||
|
|
23bd9a989b | ||
|
|
acfa02475b | ||
|
|
9dba304011 | ||
|
|
69b0020d15 | ||
|
|
ce2896cb38 | ||
|
|
68fd09c222 | ||
|
|
c832a7b93f | ||
|
|
49e19ab34d | ||
|
|
c1c82b451d | ||
|
|
ea6f88b7f6 | ||
|
|
2a6ee6d65b | ||
|
|
583342b430 | ||
|
|
7289c1080c | ||
|
|
9ed4f2b7a3 | ||
|
|
7396f91a5e | ||
|
|
ccc926d812 | ||
|
|
bd39255ead | ||
|
|
add7b1a7d9 | ||
|
|
8e471f9939 | ||
|
|
c61568ef98 | ||
|
|
3260e45e71 | ||
|
|
ea61b560b8 | ||
|
|
f8ad7d485b | ||
|
|
229e624434 | ||
|
|
7a3fb9c759 | ||
|
|
9a7ea0d28c | ||
|
|
ee5e655668 | ||
|
|
58be055f57 | ||
|
|
38e1944503 | ||
|
|
992b402e9c | ||
|
|
81bf28e4ed | ||
|
|
f10734b083 | ||
|
|
bf8f565631 | ||
|
|
9bc1ff8fa2 | ||
|
|
56239b6bbf | ||
|
|
cedd2bfe57 | ||
|
|
7e187a57d8 | ||
|
|
572a30a2c5 | ||
|
|
f3235ef7e8 | ||
|
|
7448eb32cc | ||
|
|
33e8cc4711 | ||
|
|
6cdb016c2c | ||
|
|
ababb7f5ab | ||
|
|
9f2b66e09d | ||
|
|
8de267f6a9 | ||
|
|
ecf9a3cbc9 | ||
|
|
01300b97e2 | ||
|
|
787163fb06 | ||
|
|
3701a3c3d9 | ||
|
|
68c51bb1bc | ||
|
|
df147c700c | ||
|
|
f5fc4d99dd | ||
|
|
2a4aa9e550 | ||
|
|
0a489f1117 | ||
|
|
9cc7c061a3 | ||
|
|
a1e7274ec3 | ||
|
|
51d516a39e | ||
|
|
de7c38231c | ||
|
|
c352ef9382 | ||
|
|
e36b5551e9 | ||
|
|
57856c38d6 | ||
|
|
2a8e02339b | ||
|
|
57f94ca6a2 | ||
|
|
0eaca8b80a | ||
|
|
d2dbab57dc | ||
|
|
cb448a3494 | ||
|
|
3fa6eae05b | ||
|
|
52cc7d699a | ||
|
|
ec4eac3a7d | ||
|
|
fbcfb23676 | ||
|
|
dbb2371801 | ||
|
|
4d6dc9546f | ||
|
|
06b9d328f4 | ||
|
|
48c7daa4ab | ||
|
|
3c83b88127 | ||
|
|
3a63fa5475 | ||
|
|
882790d133 | ||
|
|
bcf72b894d | ||
|
|
9f723c39ef | ||
|
|
56fc40a64d | ||
|
|
091f591ffb | ||
|
|
4d88a8206a | ||
|
|
363bf7c552 | ||
|
|
7ff4e5879d | ||
|
|
0b7decbfdd | ||
|
|
be9ea33aa4 | ||
|
|
d4b2cad94e | ||
|
|
ac039ce7cd | ||
|
|
946e60937d | ||
|
|
6f6601d270 | ||
|
|
71016f0d7c | ||
|
|
c2c2551607 | ||
|
|
d7812ec030 | ||
|
|
f184b0700f | ||
|
|
07f0be8d8d | ||
|
|
dd45b43d7f | ||
|
|
9b505106e3 | ||
|
|
d552f37daf | ||
|
|
6a7ff13859 | ||
|
|
9e3af13efc | ||
|
|
92a968217c | ||
|
|
37b9df3202 | ||
|
|
7dc33111fc | ||
|
|
ab2f260a52 | ||
|
|
1aa4b8cb88 | ||
|
|
dfed36748c | ||
|
|
d35f736548 | ||
|
|
cfecdae970 | ||
|
|
59ade6cf09 | ||
|
|
642842888a | ||
|
|
3ae51edf3a | ||
|
|
d8ccb81015 | ||
|
|
0db6020231 | ||
|
|
738c0a5c9c | ||
|
|
a2f7d3e241 | ||
|
|
9b86ded164 | ||
|
|
6cbb645b10 | ||
|
|
066a1d7591 | ||
|
|
5f82d575ee | ||
|
|
302ae0a83c | ||
|
|
82c4c791cc | ||
|
|
3c0310120d | ||
|
|
21c106e9d5 | ||
|
|
2c8cd2f8dc | ||
|
|
380d9908b4 | ||
|
|
6abef7d645 | ||
|
|
98ac25ac29 | ||
|
|
93bec04c92 | ||
|
|
136559cddd | ||
|
|
3f63a6ed70 | ||
|
|
2fcb3c4420 | ||
|
|
baaeb229cf | ||
|
|
a3bda3a941 | ||
|
|
3d536aa28d | ||
|
|
454267455b | ||
|
|
8e9adeb4b4 | ||
|
|
1f18e7beed | ||
|
|
b5e8e54107 | ||
|
|
f41e426b69 | ||
|
|
6375862a71 | ||
|
|
be2a745d78 | ||
|
|
d89feb2c75 | ||
|
|
b4a20c8fcb | ||
|
|
73087a92f4 | ||
|
|
2b58bd5bd8 | ||
|
|
bce0101278 | ||
|
|
bba418c79d | ||
|
|
cb58eb82fc | ||
|
|
3aafffabc1 | ||
|
|
66b9cdf64c | ||
|
|
d31fbf3b6f | ||
|
|
dbee30a412 | ||
|
|
f3cc881930 | ||
|
|
3d9c9e639d | ||
|
|
d6969d2c74 | ||
|
|
b7e28a73ba | ||
|
|
1e8206757d | ||
|
|
a0e94577fc | ||
|
|
a2a0c2f791 | ||
|
|
63a0fde121 | ||
|
|
c06152de07 | ||
|
|
0b3ccbda20 | ||
|
|
97b7eb0768 | ||
|
|
b712301804 | ||
|
|
76ebe3ff41 | ||
|
|
d988bb1821 | ||
|
|
64f1fbe400 | ||
|
|
c2c837329c | ||
|
|
b6531efe08 | ||
|
|
2c97a4aefe | ||
|
|
f0ffebd58c | ||
|
|
05e407f064 | ||
|
|
6dd2eec1b6 | ||
|
|
df13436688 | ||
|
|
fa0d89b6df | ||
|
|
ab0f8defa4 | ||
|
|
6b3329845b | ||
|
|
fc07c5efa6 | ||
|
|
23188df276 | ||
|
|
5e66dfcc36 | ||
|
|
bc36c57f9f | ||
|
|
5efa7d551e | ||
|
|
8c6cda0d97 | ||
|
|
4fa165bc6a | ||
|
|
da6695ceee | ||
|
|
1043a5bb0d | ||
|
|
c7625278b5 | ||
|
|
b9ef88951e | ||
|
|
14fe35bba0 | ||
|
|
4a32706c5a | ||
|
|
cc92edfa58 | ||
|
|
071d0fbbf7 | ||
|
|
6ff44fddd0 | ||
|
|
8760e99c43 | ||
|
|
423f5f16bb | ||
|
|
1c8c702afd | ||
|
|
d2a739262d | ||
|
|
76d0285e3f | ||
|
|
cb9d3414f2 | ||
|
|
12f444750c | ||
|
|
5fdf7e3a12 | ||
|
|
60deb9205b | ||
|
|
677526cb16 | ||
|
|
359a392cca | ||
|
|
4d600f973a | ||
|
|
4a626bc920 | ||
|
|
3597860074 | ||
|
|
68d2c30c38 | ||
|
|
e210d9c08e | ||
|
|
c9b77e4e23 | ||
|
|
e56d865416 | ||
|
|
efc779a8d7 | ||
|
|
7e6807509b | ||
|
|
a683866397 | ||
|
|
7a4f56d943 | ||
|
|
ec127519aa | ||
|
|
5ea3e2006d | ||
|
|
bd914bf42a | ||
|
|
e66c95fc76 | ||
|
|
9130302c93 | ||
|
|
11b979e408 | ||
|
|
44f13ef162 | ||
|
|
17253adcdf | ||
|
|
04dcc262ee | ||
|
|
e3bee43163 | ||
|
|
fb2bb5a4bc | ||
|
|
cf0a25fdfc | ||
|
|
e9436426b7 | ||
|
|
37ba95f8b3 | ||
|
|
deadcd5339 | ||
|
|
95d01f0ef5 | ||
|
|
02b8e34242 | ||
|
|
7177e0a576 | ||
|
|
b2c99fd0fd | ||
|
|
cc5910f997 | ||
|
|
cb6090c773 | ||
|
|
c0a649ffcb | ||
|
|
bebc1a22f3 | ||
|
|
b4151a256b | ||
|
|
3898602f0e | ||
|
|
0216425209 | ||
|
|
499671a637 | ||
|
|
ab82faf7ba | ||
|
|
fdf7173f14 | ||
|
|
4b11511bd1 | ||
|
|
53cbc0fb8b | ||
|
|
b209f3e50d | ||
|
|
5ec495987e | ||
|
|
66c9fd8431 | ||
|
|
576af67587 | ||
|
|
cad44cf379 | ||
|
|
ff07e99e39 | ||
|
|
18b137a1a6 | ||
|
|
2344fb910b | ||
|
|
085d309528 | ||
|
|
c8069dfee7 | ||
|
|
9c90f59c25 | ||
|
|
15cf8fe0be | ||
|
|
4258f53bc8 | ||
|
|
3640f1ba77 | ||
|
|
23bb409639 | ||
|
|
6364b9e06b | ||
|
|
5cefecced8 | ||
|
|
8b17972b11 | ||
|
|
e799187aaf | ||
|
|
c89123b18a | ||
|
|
03277c69af | ||
|
|
20b3bb8f13 | ||
|
|
a6ca84308e | ||
|
|
a71f3f55b0 | ||
|
|
24ac823f06 | ||
|
|
e407ba3ad3 | ||
|
|
7a049d64d8 | ||
|
|
8ec9d95cd2 | ||
|
|
91501d39ee | ||
|
|
5d70b4b95b | ||
|
|
c7bc6e9128 | ||
|
|
b911ef98bb | ||
|
|
f464868934 | ||
|
|
d89c33fbe8 | ||
|
|
f61f8a36f8 | ||
|
|
b9b34eea37 | ||
|
|
d948607039 | ||
|
|
5a135e108a | ||
|
|
ced11c88bc | ||
|
|
92a748a762 | ||
|
|
f4c9645d73 | ||
|
|
89ddbfc83d | ||
|
|
fa53b1be73 | ||
|
|
c7ec7db61a | ||
|
|
27cf4b0218 | ||
|
|
482858e36b | ||
|
|
50372ed9f3 | ||
|
|
d8e8765cec | ||
|
|
6ec28be541 | ||
|
|
6e5aec080a | ||
|
|
c7fb517e6c | ||
|
|
ca10ab0274 | ||
|
|
41e611d7db | ||
|
|
77a63a39ad | ||
|
|
0267ad574f | ||
|
|
8f2aae6065 | ||
|
|
a4edf827c8 | ||
|
|
f9947d2e53 | ||
|
|
0a6614d1b3 | ||
|
|
98cfb4d5ed | ||
|
|
18a780147e | ||
|
|
74878b5cb1 | ||
|
|
57d5628750 | ||
|
|
fc058476ed | ||
|
|
c24eb231ab | ||
|
|
28e44d33c4 | ||
|
|
f7dbe807e4 | ||
|
|
a76e99af86 | ||
|
|
13bb78ffa0 | ||
|
|
8c194398a9 | ||
|
|
21238e7376 | ||
|
|
ca30f49481 | ||
|
|
45da578756 | ||
|
|
1c80314cfd | ||
|
|
23d621e9c7 | ||
|
|
2884e4b847 | ||
|
|
0c7f6432d8 | ||
|
|
56bb23400a | ||
|
|
33a278ccb4 | ||
|
|
e79494b5cb | ||
|
|
3c3147d665 | ||
|
|
23f3f68767 | ||
|
|
08690b9d9e | ||
|
|
6cfd1a1ef6 | ||
|
|
d3eb9c9d99 | ||
|
|
a0ef3a0e44 | ||
|
|
354c6e17c0 | ||
|
|
c31a710aa7 | ||
|
|
0304512b8a | ||
|
|
6bdd960623 | ||
|
|
80d0a1555a | ||
|
|
ee2cba89d5 | ||
|
|
84d80525fa | ||
|
|
4d9fab6cf2 | ||
|
|
77856a3ff7 | ||
|
|
eb99132b8c | ||
|
|
e1cdf80b17 | ||
|
|
9fbeeda1c6 | ||
|
|
1a8cd2e24c | ||
|
|
6c620182ea | ||
|
|
ff542a9946 | ||
|
|
6281826b92 | ||
|
|
eb94a4ee14 | ||
|
|
09ebb7a01c | ||
|
|
11d2ada6b3 | ||
|
|
ffbb6bb40b | ||
|
|
604f315a83 | ||
|
|
ba67c01dd0 | ||
|
|
fab3704dbd | ||
|
|
1436e78305 | ||
|
|
125677f787 | ||
|
|
63d5539427 | ||
|
|
4be101e9fc | ||
|
|
d0302cdbf3 | ||
|
|
c077f6e1e8 | ||
|
|
4ca9a26bdd | ||
|
|
6b713b283a | ||
|
|
9abbd8c158 | ||
|
|
4df0641d67 | ||
|
|
4b093812bc | ||
|
|
d7120af5cb | ||
|
|
e36a666542 | ||
|
|
b609b5909b | ||
|
|
cbd83b5e39 | ||
|
|
2ddd768393 | ||
|
|
c508f30d92 | ||
|
|
9b7750c1f3 | ||
|
|
a9b5949a7b | ||
|
|
f56247df7a | ||
|
|
0ef76aa66d | ||
|
|
5c98283932 | ||
|
|
ce6bd0fd6d | ||
|
|
aca1001f9a | ||
|
|
d5a58be440 | ||
|
|
b33dd7e91c | ||
|
|
30e13259b3 | ||
|
|
be2fa1dfad | ||
|
|
87c5ad79f4 | ||
|
|
2e210e7adc | ||
|
|
c56f4783c0 | ||
|
|
a1d351aa37 | ||
|
|
bc7b584001 | ||
|
|
690571eec0 | ||
|
|
0620c635e5 | ||
|
|
8e00bdcf30 | ||
|
|
0bd0602655 | ||
|
|
2bcbc3294b | ||
|
|
9aa5460688 | ||
|
|
e451cdd519 | ||
|
|
ab9cdf5610 | ||
|
|
c443eee15d | ||
|
|
9e136bad94 | ||
|
|
ccb97e34d5 | ||
|
|
917e2e40fb | ||
|
|
c5ed0afb4e | ||
|
|
b10fa9e5b2 | ||
|
|
210967cfef | ||
|
|
2a5118326a | ||
|
|
a6225962b0 | ||
|
|
01f4a9b23b | ||
|
|
3202d62a92 | ||
|
|
270dc351a1 | ||
|
|
12c746a4e4 | ||
|
|
a116a2a553 | ||
|
|
9555b10b97 | ||
|
|
ae6b4211b9 | ||
|
|
3fe7e4e8da | ||
|
|
ba805739b0 | ||
|
|
89d8aa99ac | ||
|
|
5b65c2e27e | ||
|
|
6f9b712230 | ||
|
|
ca3bfa2239 | ||
|
|
35a3a89d2d | ||
|
|
be8632d94b | ||
|
|
1bc4b16d38 | ||
|
|
863c159fbb | ||
|
|
a647efe3fd | ||
|
|
c79c23899f | ||
|
|
a04e432aea | ||
|
|
5c120e532f | ||
|
|
cfa95eef39 | ||
|
|
a327b9cfa8 | ||
|
|
c4ae6121b4 | ||
|
|
23d07600f7 | ||
|
|
418467e467 | ||
|
|
e60b3880ce | ||
|
|
92acf009b0 | ||
|
|
a141df434c | ||
|
|
32201dda72 | ||
|
|
13b0c8880d | ||
|
|
24e7d755eb | ||
|
|
e534a6b7fc | ||
|
|
277d75016c | ||
|
|
278a10cf61 | ||
|
|
8f283b2226 | ||
|
|
857b76980b | ||
|
|
fae7bfa8c5 | ||
|
|
e9e7d2e289 | ||
|
|
e3cbe118c5 | ||
|
|
9d05cfba36 | ||
|
|
b5966afe25 | ||
|
|
1cf91c0ce3 | ||
|
|
0f09a0b152 | ||
|
|
b434c37f01 | ||
|
|
4655bd5502 | ||
|
|
fcb74d4fba | ||
|
|
2bf7d06a91 | ||
|
|
ce68c2a3e9 | ||
|
|
e58194ac3c | ||
|
|
857f36e01a | ||
|
|
83c3a80766 | ||
|
|
736552f3b1 | ||
|
|
0b28f97d8f | ||
|
|
47b627d669 | ||
|
|
b051a296fc | ||
|
|
908a569413 | ||
|
|
31f83dfb40 | ||
|
|
022b16c8e6 | ||
|
|
d462d9c89b | ||
|
|
86360049c3 | ||
|
|
f524be6738 | ||
|
|
519d2c1714 | ||
|
|
c19fcb831f | ||
|
|
ff6268e616 | ||
|
|
b0f1ad63ee | ||
|
|
a7b017f307 | ||
|
|
29c3df8ba7 | ||
|
|
570226a051 | ||
|
|
96cfb51bd8 | ||
|
|
ba0c7907ca | ||
|
|
4c6ae83d4b | ||
|
|
e4231e012d | ||
|
|
9693de8885 | ||
|
|
d096a7ceb1 | ||
|
|
fd77dfd66d | ||
|
|
3f1389818c | ||
|
|
c920fa6740 | ||
|
|
b4088dcfbc | ||
|
|
b20f026c7b | ||
|
|
f0fa126e7b | ||
|
|
2999694f48 | ||
|
|
fcc60957c1 | ||
|
|
4781351184 | ||
|
|
d97a585eba | ||
|
|
2d65c9734c | ||
|
|
3b5a9c0a10 | ||
|
|
f6184004e5 | ||
|
|
d70dd05221 | ||
|
|
5602cb8920 | ||
|
|
4a250b4e27 | ||
|
|
37afb46957 | ||
|
|
9708d3183f | ||
|
|
433cb99eab | ||
|
|
241b86d704 | ||
|
|
3b0c66429c | ||
|
|
8f137eadf0 | ||
|
|
468a6c1dca | ||
|
|
f9597569ba | ||
|
|
93353ff900 | ||
|
|
ed7e77b2db | ||
|
|
2108aab523 | ||
|
|
75f01099ee | ||
|
|
26e1ad51ff | ||
|
|
c1a5482ad2 | ||
|
|
ed232248a2 | ||
|
|
e215324292 | ||
|
|
a8bc2f10e4 | ||
|
|
b64cbc223f | ||
|
|
de40df7f7b | ||
|
|
94896451ac | ||
|
|
0e35bb4852 | ||
|
|
cd30b1d9b3 | ||
|
|
8d66d43a98 | ||
|
|
8ca861360b | ||
|
|
410db16160 | ||
|
|
1c1df81341 | ||
|
|
66a1cc7b71 | ||
|
|
0543569315 | ||
|
|
e5a94bd140 | ||
|
|
adfebdb3f6 | ||
|
|
dbe06b0a93 | ||
|
|
e8305d1245 | ||
|
|
b2ea733b45 | ||
|
|
fc320fb9ee | ||
|
|
a3268eefbf | ||
|
|
5a77eebb34 | ||
|
|
68af32bc9f | ||
|
|
100e5042de | ||
|
|
b3e188a5f4 | ||
|
|
ae3bcac3b7 | ||
|
|
afed54b217 | ||
|
|
2d768990ec | ||
|
|
10c44d0a4e | ||
|
|
57b0e3e311 | ||
|
|
19e62786c9 | ||
|
|
e45e04a6dc | ||
|
|
97cac33773 | ||
|
|
a889571b98 | ||
|
|
cf1148e7c8 | ||
|
|
e2f74fd4f0 | ||
|
|
57bcea56b5 | ||
|
|
380a955e7a | ||
|
|
cf50f47459 | ||
|
|
eb69dce585 | ||
|
|
b3adf7b331 | ||
|
|
a8900bb50e | ||
|
|
c79f0b76ff | ||
|
|
ca24e64c42 | ||
|
|
d1a3752b2d | ||
|
|
00e70cbb6a | ||
|
|
7f2c2d9d6b | ||
|
|
959f756ff5 | ||
|
|
90b9ba71de | ||
|
|
26025a3018 | ||
|
|
cce35b4a6f | ||
|
|
09bdfd7ac1 | ||
|
|
ce2b73b737 | ||
|
|
61e9611bab | ||
|
|
83d1707b56 | ||
|
|
cbdf252fe6 | ||
|
|
55cd0c2bae | ||
|
|
6cc1cecf5a | ||
|
|
7a94ebcf2a | ||
|
|
84a126253a | ||
|
|
ad3ce3f9fc | ||
|
|
c74ee2150c | ||
|
|
665f0ee03e | ||
|
|
f8a4128c88 | ||
|
|
c931bbf107 | ||
|
|
b020336f8c | ||
|
|
299c2af59b | ||
|
|
37a73eda37 | ||
|
|
3938022002 | ||
|
|
450fc456be | ||
|
|
f7e0dc4818 | ||
|
|
b496f51afc | ||
|
|
c1163a078a | ||
|
|
90c243dec8 | ||
|
|
fab22a152c | ||
|
|
3905da1a62 | ||
|
|
0b02ada315 | ||
|
|
3dd1fc2efe | ||
|
|
c1066e94f2 | ||
|
|
3a3c23d2f1 | ||
|
|
1f439b4b0c | ||
|
|
2af750cfec | ||
|
|
42b3b19a57 | ||
|
|
496498b913 | ||
|
|
b7a7e7dcc0 | ||
|
|
3fcdfbd01a | ||
|
|
72fc673020 | ||
|
|
c3967c79c9 | ||
|
|
3dd07d2f4a | ||
|
|
036f233946 | ||
|
|
16c243d270 | ||
|
|
9776884a91 | ||
|
|
131f646024 | ||
|
|
1bf728359d | ||
|
|
0ee5c1cd86 | ||
|
|
8a83e0fc1a | ||
|
|
0be49002ba | ||
|
|
2b96c820fd | ||
|
|
9641a388e2 | ||
|
|
37fcd81e87 | ||
|
|
b589d8a1df | ||
|
|
d0a44906fe | ||
|
|
5b8ee48600 | ||
|
|
e5f6b7f66c | ||
|
|
941ebd39bf | ||
|
|
52b73b5a9d | ||
|
|
f5b7e6bb60 | ||
|
|
44965a42e4 | ||
|
|
d8aea69c0c | ||
|
|
aa110ec9a6 | ||
|
|
dbfe5196e7 | ||
|
|
13e911eaa1 | ||
|
|
cbbd5ffc62 | ||
|
|
cf40aec9d7 | ||
|
|
cdda421920 | ||
|
|
0db22f2cff | ||
|
|
7a22ca2841 | ||
|
|
4fc8e321af | ||
|
|
59fe8f444f | ||
|
|
8cc3a865e2 | ||
|
|
8a13482c38 | ||
|
|
d8d8552176 | ||
|
|
96475557ae | ||
|
|
bb4c498e5a | ||
|
|
3ba57c3473 | ||
|
|
094aa5a326 | ||
|
|
4b71b30418 | ||
|
|
d960703a5c | ||
|
|
6244551d69 | ||
|
|
3ed6be1d6d | ||
|
|
91c3cb93f0 | ||
|
|
8c369d9874 | ||
|
|
b5008f4ad3 | ||
|
|
deefab8a5b | ||
|
|
ff6dc98bbe | ||
|
|
8581213126 | ||
|
|
19d058a644 | ||
|
|
aa83510fbe | ||
|
|
5aa995b5ef | ||
|
|
1a9d701d32 | ||
|
|
9f4f107b6d | ||
|
|
90716ebaad | ||
|
|
496b4e77e8 | ||
|
|
6e9d833c77 | ||
|
|
48061d3cae | ||
|
|
292ce33e0f | ||
|
|
365fc6af20 | ||
|
|
97360b33f4 | ||
|
|
5012313dc4 | ||
|
|
95f10aeb06 | ||
|
|
8a965e56cd | ||
|
|
fb14a83b9a | ||
|
|
8cef351ed9 | ||
|
|
4261e6242c | ||
|
|
68bfd3017b | ||
|
|
ccd25c7e76 | ||
|
|
7df232c65d | ||
|
|
32fb79478c | ||
|
|
d950396f68 | ||
|
|
7d5f336e36 | ||
|
|
b5cba3abfd | ||
|
|
1d8630dd7d | ||
|
|
bfcce4f7ab | ||
|
|
622f0d9355 | ||
|
|
434256b0a5 | ||
|
|
e7a4ce2e19 | ||
|
|
23dc62dbd2 | ||
|
|
739e636a2c | ||
|
|
b020bf6816 | ||
|
|
47d61c4a0e | ||
|
|
714c5fd784 | ||
|
|
7f2a0a77c7 | ||
|
|
0bebe5008b | ||
|
|
ee24eb8d1b | ||
|
|
d396149521 | ||
|
|
a4962c5225 | ||
|
|
bece87c790 | ||
|
|
e21d92cf4d | ||
|
|
e6f9ce888f | ||
|
|
871b6548ab | ||
|
|
cb569be3b3 | ||
|
|
0e50fbf3f2 | ||
|
|
3adc599278 | ||
|
|
68593acf89 | ||
|
|
6007e511ba | ||
|
|
01fc7108d8 | ||
|
|
494e415bd3 | ||
|
|
c17b34c70d | ||
|
|
02ab945ab8 | ||
|
|
97e5ac4c1e | ||
|
|
458d4378f0 | ||
|
|
b715e0d34e | ||
|
|
cce4113b2d | ||
|
|
89f06506c1 | ||
|
|
cc26e61d7a | ||
|
|
4b6b1b43cd | ||
|
|
913ee34c8d | ||
|
|
4e77f24a06 | ||
|
|
fcf62ada8f | ||
|
|
86b7966027 | ||
|
|
43c9bc51dc | ||
|
|
1ff6a7e423 | ||
|
|
439d2c88ae | ||
|
|
37aced0ad3 | ||
|
|
a3a1e6d3a9 | ||
|
|
2c769cad0b | ||
|
|
b1ad8f917d | ||
|
|
221f7be21b | ||
|
|
bed34c4cad | ||
|
|
f8b0819fb3 | ||
|
|
25778a143c | ||
|
|
5b11875a5a | ||
|
|
6967093689 | ||
|
|
0cafa152bf | ||
|
|
697e288de2 | ||
|
|
aa28c3a45b | ||
|
|
815daccff1 | ||
|
|
f61aa6068b | ||
|
|
21fe0f9246 | ||
|
|
6db1175c95 | ||
|
|
00b78402eb | ||
|
|
30ddd91a34 | ||
|
|
1789fadbf6 | ||
|
|
86d5803b63 | ||
|
|
98ec2dcf44 | ||
|
|
117e2e2cb6 | ||
|
|
4b39e5fab6 | ||
|
|
7ea4a503f7 | ||
|
|
7cf619e620 | ||
|
|
7a65604cc8 | ||
|
|
d67402e6aa | ||
|
|
2191437f39 | ||
|
|
c6efa6ca2e | ||
|
|
5172ae781f | ||
|
|
343a94bf05 | ||
|
|
7cd96e379e | ||
|
|
ddf39461fb | ||
|
|
62608bea6c | ||
|
|
05356776c5 | ||
|
|
1956fccbe9 | ||
|
|
53ca2d0755 | ||
|
|
641a4b87c6 | ||
|
|
0559b43bde | ||
|
|
397220e682 | ||
|
|
636da8f95f | ||
|
|
94f2e880cd | ||
|
|
c03aa6300e | ||
|
|
54d0cae450 | ||
|
|
efd9280f96 | ||
|
|
a1ca9d396c | ||
|
|
c686bf6149 | ||
|
|
20b95fa063 | ||
|
|
ec5f74b753 | ||
|
|
5ee369f26a | ||
|
|
198dff7864 | ||
|
|
af483e93f3 | ||
|
|
0813f00ea1 | ||
|
|
06dcc875bd | ||
|
|
eab226f04d | ||
|
|
dd0ad495f7 | ||
|
|
4ff3517343 | ||
|
|
8a80e82b5d | ||
|
|
c14fb51eb8 | ||
|
|
9302b7c15c | ||
|
|
662283908c | ||
|
|
532eeb7ab0 | ||
|
|
e78579581f | ||
|
|
027e8dc35e | ||
|
|
d83a852681 | ||
|
|
826d5705c9 | ||
|
|
fbf8655ea4 | ||
|
|
737c63da5e | ||
|
|
a98f42012a | ||
|
|
8526c67e4d | ||
|
|
29051d4281 | ||
|
|
1d0063ed39 | ||
|
|
18d81f6daa | ||
|
|
17bc8fd9ed | ||
|
|
707e57e72d | ||
|
|
f049706539 | ||
|
|
203e4bc0a4 | ||
|
|
d6cd197435 | ||
|
|
684b57d139 | ||
|
|
3418979f4d | ||
|
|
59530909d6 | ||
|
|
674d259df1 | ||
|
|
3af18094f7 | ||
|
|
9e309c9592 | ||
|
|
c73286358c | ||
|
|
967dab21bc | ||
|
|
4e9d1d348e | ||
|
|
7b3d60215b | ||
|
|
7d2fd514be | ||
|
|
2981dd857f | ||
|
|
5b075ead9e | ||
|
|
e5656896e7 | ||
|
|
238c589ad6 | ||
|
|
85988a2ff9 | ||
|
|
23e6f89eef | ||
|
|
e330b28e49 | ||
|
|
1984921883 | ||
|
|
68f8ef54ac | ||
|
|
940b8b72f9 | ||
|
|
34f4eda1cf | ||
|
|
1b36325450 | ||
|
|
0f8168324f | ||
|
|
172ac78466 | ||
|
|
713875100b | ||
|
|
ba84bb82b4 | ||
|
|
ed0b796c5a | ||
|
|
4a7c722673 | ||
|
|
714fdc751a | ||
|
|
ad2e2032e6 | ||
|
|
52c0a8e573 | ||
|
|
807c4688c2 | ||
|
|
b4ec2ccb90 | ||
|
|
155f3945a6 | ||
|
|
0b2a933faa | ||
|
|
01ba051c43 | ||
|
|
1cd30e9057 | ||
|
|
a023c4fbac | ||
|
|
99c12595a9 | ||
|
|
3056e9e79c | ||
|
|
b822a02d41 | ||
|
|
539971b5a0 | ||
|
|
2a0d3b05d3 | ||
|
|
d1b51844e4 | ||
|
|
94b815b8ab | ||
|
|
e67ddf9430 | ||
|
|
9674ca5e87 | ||
|
|
5834dc9b2e | ||
|
|
9d49c7d836 | ||
|
|
3ce7284fc5 | ||
|
|
bf6e33791d | ||
|
|
6a11f0dd8d | ||
|
|
83452b1e36 | ||
|
|
d88a908e29 | ||
|
|
9c05ddbd7d | ||
|
|
89ca9ad213 | ||
|
|
c46f1ec590 | ||
|
|
3131e8c7e9 | ||
|
|
7d8b0f9941 | ||
|
|
d3313d6438 | ||
|
|
c611066791 | ||
|
|
1e456d6560 | ||
|
|
6a564f6693 | ||
|
|
45a3be7642 | ||
|
|
a25b6a9952 | ||
|
|
25063ed1f0 | ||
|
|
292dbf101b | ||
|
|
099d88ba7b | ||
|
|
992fcc73b8 | ||
|
|
9b3c9aaea2 | ||
|
|
41e4f87e06 | ||
|
|
6de48b4535 | ||
|
|
70b104c936 | ||
|
|
827f72f595 | ||
|
|
5faff6260e | ||
|
|
59e8a85c7e | ||
|
|
d3ec50825e | ||
|
|
2518564f92 | ||
|
|
81de9875d3 | ||
|
|
eae07c15a7 | ||
|
|
1fdffa8be5 |
23
.gitignore
vendored
@@ -1,7 +1,8 @@
|
|||||||
##Packr, build stuff
|
logs/
|
||||||
|
|
||||||
/core/assets/mindustry-saves/
|
/core/assets/mindustry-saves/
|
||||||
/core/assets/mindustry-maps/
|
/core/assets/mindustry-maps/
|
||||||
|
/core/assets/bundles/output/
|
||||||
|
/core/assets/.gifimages/
|
||||||
/deploy/
|
/deploy/
|
||||||
/desktop/packr-out/
|
/desktop/packr-out/
|
||||||
/desktop/packr-export/
|
/desktop/packr-export/
|
||||||
@@ -9,14 +10,30 @@
|
|||||||
/desktop/mindustry-maps/
|
/desktop/mindustry-maps/
|
||||||
/desktop/gifexport/
|
/desktop/gifexport/
|
||||||
/core/lib/
|
/core/lib/
|
||||||
/kryonet/build/
|
/core/assets-raw/sprites/generated/
|
||||||
|
/core/assets-raw/sprites_out/
|
||||||
|
/annotations/build/
|
||||||
|
/annotations/out/
|
||||||
|
/net/build/
|
||||||
|
/tools/build/
|
||||||
|
/tests/build/
|
||||||
/server/build/
|
/server/build/
|
||||||
|
/test_files/
|
||||||
|
/annotations/build/
|
||||||
/android/assets/mindustry-maps/
|
/android/assets/mindustry-maps/
|
||||||
/android/assets/mindustry-saves/
|
/android/assets/mindustry-saves/
|
||||||
/core/assets/gifexport/
|
/core/assets/gifexport/
|
||||||
/core/assets/version.properties
|
/core/assets/version.properties
|
||||||
|
/core/assets/locales
|
||||||
|
/ios/src/io/anuke/mindustry/gen/
|
||||||
|
/core/src/io/anuke/mindustry/gen/
|
||||||
|
ios/robovm.properties
|
||||||
|
packr-out/
|
||||||
|
config/
|
||||||
*.gif
|
*.gif
|
||||||
|
|
||||||
|
version.properties
|
||||||
|
|
||||||
.attach_*
|
.attach_*
|
||||||
## Java
|
## Java
|
||||||
|
|
||||||
|
|||||||
39
.travis.yml
@@ -1,23 +1,20 @@
|
|||||||
language: android
|
|
||||||
|
|
||||||
jdk:
|
jdk:
|
||||||
- openjdk8
|
- openjdk8
|
||||||
|
script:
|
||||||
android:
|
- "git clone --depth=1 --branch=master https://github.com/Anuken/Arc ../Arc"
|
||||||
components:
|
- "./gradlew test"
|
||||||
- android-26
|
- "./gradlew desktop:dist -Pbuildversion=${TRAVIS_TAG:1}"
|
||||||
|
- "./gradlew server:dist -Pbuildversion=${TRAVIS_TAG:1}"
|
||||||
# Additional components
|
|
||||||
- extra-google-google_play_services
|
|
||||||
- extra-google-m2repository
|
|
||||||
- extra-android-m2repository
|
|
||||||
- addon-google_apis-google-26
|
|
||||||
|
|
||||||
script:
|
|
||||||
- ./gradlew desktop:dist
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
- chmod +x upload-build.sh
|
|
||||||
- chmod +x cleanup_builds.sh
|
|
||||||
- ./upload-build.sh
|
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
provider: releases
|
||||||
|
skip_cleanup: true
|
||||||
|
draft: false
|
||||||
|
api_key:
|
||||||
|
secure: Cv5wFtWt62/A24EvSEQvMow7gKPbZ3oATEFPuSghhB2TQz1dA40Zee3Qvk4LFlpLrhYo4K0ZSczCZRGpR+hCd8+Dpww52bheYEvWuh3ZQfvu/fXtEx2j5PwP1qMpmIgSxETV/gkD7l9FImdh0VzktYiAvQfmi0bEocG9/D4QwjFpNat7iwBdcMiw1MvAygpdIWRsjiw0RKlB2mWarmoHhQ7Gu7qlU3j50uaEvcrtmU0pBUPggNQwQRv32i9NPvNFxrqqlUjDLIS8JFea99zCkp8BwYqbEvBIMzd+Qip1/stLJJA3+cDUClbsDtg8rAVetzpOrdLEEBmqShFe5MDl2yEHcsgpN9CFsyTaUfvB3P3rVjizvycMm42IsUkXQiarm5xTQ/TIA8Rd8AHiSKuweNCg1Fd5SFaRtKy8JVLXuxyfUccmyje6hhz2L4lS2Wfj3mAG7sqZUCXhWP79EKdGkiPOjKv4CwXEKmuH3BMVqPlNUZJr9Eg3sV1FG0h2l+MVOOnR635qdUbb49sYojYxVruMLX0BH1c4ZCu230m8CUoWA1Em1QNI75ya7+9Y5T6AsgWDVpBvdUo9fWNbdp+VQ0GskFQsJD5wtnxbcbHeFiERAgGBm7z6qt9u9LrQpBH+dsW52ADvYsu3L4nQEa+sdMHwTTwmGY+iUvsxu0DqxGg=
|
||||||
|
file:
|
||||||
|
- "desktop/build/libs/desktop-release.jar"
|
||||||
|
- "server/build/libs/server-release.jar"
|
||||||
|
on:
|
||||||
|
repo: Anuken/Mindustry
|
||||||
|
tags: true
|
||||||
|
|||||||
36
README.md
@@ -1,43 +1,45 @@
|
|||||||

|

|
||||||
|
|
||||||
[](https://travis-ci.org/Anuken/Mindustry)
|
[](https://travis-ci.org/Anuken/Mindustry)
|
||||||
[](https://waffle.io/Anuken/Mindustry)
|
[](https://discord.gg/mindustry)
|
||||||
|
|
||||||
A pixelated sandbox tower defense game made using [LibGDX](https://libgdx.badlogicgames.com/). Winner of the [GDL Metal Monstrosity Jam](https://itch.io/jam/gdl---metal-monstrosity-jam).
|
A sandbox tower defense game written in Java.
|
||||||
|
|
||||||
_[Issue tracker](https://waffle.io/Anuken/Mindustry)_
|
|
||||||
_[Trello Board](https://trello.com/b/aE2tcUwF/mindustry-40-plans)_
|
_[Trello Board](https://trello.com/b/aE2tcUwF/mindustry-40-plans)_
|
||||||
_[Wiki](http://mindustry.wikia.com/wiki/Mindustry_Wiki)_
|
_[Wiki](http://mindustry.wikia.com/wiki/Mindustry_Wiki)_
|
||||||
_[Discord](https://discord.gg/r8BkXNd)_
|
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
Bleeding-edge live builds are generated automatically for every commit. You can see them [here](https://github.com/Anuken/Mindustry/wiki).
|
Bleeding-edge live builds are generated automatically for every commit. You can see them [here](https://jenkins.hellomouse.net/job/mindustry/).
|
||||||
|
|
||||||
If you'd rather compile on your own, follow these instructions.
|
If you'd rather compile on your own, follow these instructions.
|
||||||
First, make sure you have Java 8 and JDK 8 installed. Open a terminal in the root directory, and run the following commands:
|
First, make sure you have Java 8 and JDK 8 installed. Open a terminal in the root directory, `cd` to the Mindustry folder and run the following commands:
|
||||||
|
|
||||||
|
#### Windows
|
||||||
|
|
||||||
**_Windows_**
|
_Running:_ `gradlew desktop:run`
|
||||||
|
_Building:_ `gradlew desktop:dist`
|
||||||
|
|
||||||
_Running:_ `gradlew.bat desktop:run`
|
#### Linux/Mac OS
|
||||||
_Building:_ `gradlew.bat desktop:dist`
|
|
||||||
|
|
||||||
|
|
||||||
**_Linux_**
|
|
||||||
|
|
||||||
_Running:_ `./gradlew desktop:run`
|
_Running:_ `./gradlew desktop:run`
|
||||||
_Building:_ `./gradlew desktop:dist`
|
_Building:_ `./gradlew desktop:dist`
|
||||||
|
|
||||||
|
#### Server
|
||||||
|
|
||||||
|
Server builds are bundled with each released build (in Releases). If you'd rather compile on your own, replace 'desktop' with 'server', e.g. `gradlew server:dist`.
|
||||||
|
|
||||||
|
##### Troubleshooting
|
||||||
|
|
||||||
|
If the terminal returns `Permission denied` or `Command not found` on Mac/Linux, run `chmod +x ./gradlew` before running `./gradlew`. *This is a one-time procedure.*
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Gradle may take up to several minutes to download files. Be patient. <br>
|
Gradle may take up to several minutes to download files. Be patient. <br>
|
||||||
After building, the output .JAR file should be in the output JAR file should be in `/desktop/build/libs/desktop-release.jar.`
|
After building, the output .JAR file should be in `/desktop/build/libs/desktop-release.jar` for desktop builds, and in `/server/build/libs/server-release.jar` for server builds.
|
||||||
|
|
||||||
### Downloads
|
### Downloads
|
||||||
|
|
||||||
<a href="https://anuke.itch.io/mindustry"><img src="https://i.imgur.com/sk26hTV.png" width="auto" height="75"></a>
|
<a href="https://anuke.itch.io/mindustry"><img src="https://i.imgur.com/sk26hTV.png" width="auto" height="75"></a>
|
||||||
|
|
||||||
<a href="https://anuke.itch.io/mindustry"><img src="https://i.imgur.com/ZSPVQpn.gif" width="auto" height="75"></a>
|
|
||||||
|
|
||||||
<a href="https://play.google.com/store/apps/details?id=io.anuke.mindustry&hl=en"><img src="https://i.imgur.com/8dF6l81.png" width="auto" height="75"></a>
|
<a href="https://play.google.com/store/apps/details?id=io.anuke.mindustry&hl=en"><img src="https://i.imgur.com/8dF6l81.png" width="auto" height="75"></a>
|
||||||
|
|||||||
39
TRANSLATING.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
## Translating for Mindustry
|
||||||
|
|
||||||
|
**DISCLAIMER:** *Currently, 4.0 is far from done, which means that things such as block names, descriptions, and core text will be changing often. If you begin translating now, you might have to re-do large chunks of the bundle before final release.*
|
||||||
|
|
||||||
|
|
||||||
|
To begin, log in to your GitHub account, or if you don't have one yet, create it [here](https://github.com/).
|
||||||
|
|
||||||
|
Consult [this list](https://www.science.co.il/language/Locale-codes.php) to find the locale code for your language. Once you've found it,
|
||||||
|
head over to the translation bundle folder and check the [list of bundles](https://github.com/Anuken/Mindustry/tree/master/core/assets/bundles) that have already been created.
|
||||||
|
You're looking for a file called "`bundle_`(insert locale code here)`.properties`". If you don't find one, create one manually (more info below).
|
||||||
|
|
||||||
|
#### Editing an existing translation
|
||||||
|
|
||||||
|
If a translation bundle already exists, that means someone has already started working on a translation. To edit it or translate text, simply click the file and press the edit (pencil) button in the top right. Once you're done editing, press the green "propose file change" button at the bottom, then "create pull request" (twice).
|
||||||
|
Once this is done, all you need to do is wait for me to approve your changes.
|
||||||
|
|
||||||
|
#### Creating a new translation bundle
|
||||||
|
|
||||||
|
If a translation bundle for your language *doesn't* exist, you need to create one yourself.
|
||||||
|
In the folder with all the bundles in it, click the *'create new file'* button, and name it `bundle_(locale code here).properties`.
|
||||||
|
Then, copy-paste the entire contents of the [English translation bundle](https://raw.githubusercontent.com/Anuken/Mindustry/master/core/assets/bundles/bundle.properties) into the file, and translate all the necessary text to your language.
|
||||||
|
Once you are done, press the *propose new file* button at the bottom, then 'create pull request' twice.
|
||||||
|
|
||||||
|
#### Useful Information
|
||||||
|
|
||||||
|
- When you see text surrounded by square brackets, such as `[RED]`, `[]` or `[accent]`, this indicates a color code. Don't translate it.
|
||||||
|
- `{0}` means an argument that will be replaced when the text is displayed. For example, `Wave: {0}` will replace the `{0}` with whatever wave you are in.
|
||||||
|
- Empty lines are fine, and it doesn't matter in what order you place the text.
|
||||||
|
- `\n` means "new line". If you want to split text into multiple lines, use `\n` to do it.
|
||||||
|
|
||||||
|
#### Testing your translation bundle
|
||||||
|
|
||||||
|
There are two ways to test the translation bundle:
|
||||||
|
1) Assuming you have the PC version downloaded, download your bundle file, name it `bundle.properties`, then place it in the same folder as the Mindustry desktop executable and run it. *You should get a popup message in-game confirming that you have loaded an external translation.*
|
||||||
|
2) For advanced users: simply download your fork of mindustry and compile/run the game.
|
||||||
|
|
||||||
|
**And that's it.**
|
||||||
|
|
||||||
|
*(...of course, that's never really it. Bother me on Discord when something inevitably goes wrong.)*
|
||||||
@@ -1,33 +1,65 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="io.anuke.mindustry">
|
package="io.anuke.mindustry">
|
||||||
|
|
||||||
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
|
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
|
||||||
<uses-permission android:name="com.android.vending.BILLING" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:resizeableActivity="false"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:allowBackup="true"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:theme="@style/GdxTheme" >
|
android:isGame="true"
|
||||||
<activity
|
android:appCategory="game"
|
||||||
android:name="io.anuke.mindustry.AndroidLauncher"
|
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:screenOrientation="sensorLandscape"
|
android:theme="@style/GdxTheme" android:fullBackupContent="@xml/backup_rules">
|
||||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
|
<meta-data android:name="android.max_aspect" android:value="2.1"/>
|
||||||
|
<activity
|
||||||
|
android:name="io.anuke.mindustry.AndroidLauncher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:screenOrientation="user"
|
||||||
|
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
<category android:name="android.intent.category.BROWSABLE"/>
|
||||||
|
<data android:mimeType="application/octet-stream"/>
|
||||||
|
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.mmap"/>
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
<category android:name="android.intent.category.BROWSABLE"/>
|
||||||
|
<data android:mimeType="application/octet-stream"/>
|
||||||
|
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.msav"/>
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
|
||||||
|
<intent-filter android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="Mindustry Map"
|
||||||
|
android:priority="1">
|
||||||
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.mmap" android:mimeType="*/*"/>
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.msav" android:mimeType="*/*"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:name=".DonationsActivity"
|
|
||||||
android:theme="@style/GdxTheme" />
|
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -1,30 +1,59 @@
|
|||||||
|
buildscript{
|
||||||
|
repositories{
|
||||||
|
mavenLocal()
|
||||||
|
mavenCentral()
|
||||||
|
google()
|
||||||
|
maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
repositories {
|
dependencies{
|
||||||
mavenCentral()
|
classpath 'com.android.tools.build:gradle:3.4.0'
|
||||||
jcenter()
|
|
||||||
maven {
|
|
||||||
url "https://maven.google.com"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
apply plugin: "com.android.application"
|
||||||
implementation 'com.android.support:support-v4:22.1.1'
|
|
||||||
implementation 'org.sufficientlysecure:donations:2.5'
|
configurations{ natives }
|
||||||
|
|
||||||
|
repositories{
|
||||||
|
mavenCentral()
|
||||||
|
jcenter()
|
||||||
|
maven{
|
||||||
|
url "https://maven.google.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies{
|
||||||
|
implementation project(":core")
|
||||||
|
implementation project(":net")
|
||||||
|
|
||||||
|
implementation arcModule("backends:backend-android")
|
||||||
|
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi"
|
||||||
|
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
|
||||||
|
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a"
|
||||||
|
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
|
||||||
|
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
|
||||||
|
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi"
|
||||||
|
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a"
|
||||||
|
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a"
|
||||||
|
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86"
|
||||||
|
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86_64"
|
||||||
}
|
}
|
||||||
|
|
||||||
task deploy(type: Copy){
|
task deploy(type: Copy){
|
||||||
dependsOn "assembleRelease"
|
dependsOn "assembleRelease"
|
||||||
|
|
||||||
from "build/outputs/apk/google/release/android-google-release.apk"
|
from "build/outputs/apk/release/android-release.apk"
|
||||||
into "../deploy/";
|
into "../deploy/"
|
||||||
rename ("android-google-release.apk", appName + "-android-" + getVersionString() + ".apk");
|
rename("android-release.apk", appName + "-android-" + getVersionString() + ".apk")
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android{
|
||||||
buildToolsVersion '26.0.2'
|
buildToolsVersion '28.0.3'
|
||||||
compileSdkVersion 26
|
compileSdkVersion 28
|
||||||
sourceSets {
|
sourceSets{
|
||||||
main {
|
main{
|
||||||
manifest.srcFile 'AndroidManifest.xml'
|
manifest.srcFile 'AndroidManifest.xml'
|
||||||
java.srcDirs = ['src']
|
java.srcDirs = ['src']
|
||||||
aidl.srcDirs = ['src']
|
aidl.srcDirs = ['src']
|
||||||
@@ -34,56 +63,58 @@ android {
|
|||||||
jniLibs.srcDirs = ['libs']
|
jniLibs.srcDirs = ['libs']
|
||||||
}
|
}
|
||||||
|
|
||||||
instrumentTest.setRoot('tests')
|
androidTest.setRoot('tests')
|
||||||
}
|
}
|
||||||
packagingOptions {
|
packagingOptions{
|
||||||
exclude 'META-INF/robovm/ios/robovm.xml'
|
exclude 'META-INF/robovm/ios/robovm.xml'
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig{
|
||||||
def vfile = file('../core/assets/version.properties')
|
def vfile = file('../core/assets/version.properties')
|
||||||
def props = new Properties()
|
|
||||||
props.load(new FileInputStream(vfile))
|
|
||||||
|
|
||||||
def code = props['androidBuildCode'].toInteger() + 1
|
def code = 0
|
||||||
props['androidBuildCode'] = code.toString()
|
def versionNameResult = "unknown"
|
||||||
props.store(vfile.newWriter(), "Autogenerated file. Do not modify.")
|
|
||||||
|
if(vfile.exists()){
|
||||||
|
def props = new Properties()
|
||||||
|
props.load(new FileInputStream(vfile))
|
||||||
|
|
||||||
|
code = (props['androidBuildCode'] == null ? 0 : props['androidBuildCode']).toInteger() + 1
|
||||||
|
|
||||||
|
props['androidBuildCode'] = code.toString()
|
||||||
|
props.store(vfile.newWriter(), "Autogenerated file. Do not modify.")
|
||||||
|
versionNameResult = "$versionNumber-$versionType-${props['build'].replace(" ", "-")}"
|
||||||
|
}
|
||||||
|
|
||||||
applicationId "io.anuke.mindustry"
|
applicationId "io.anuke.mindustry"
|
||||||
minSdkVersion 9
|
minSdkVersion 14
|
||||||
targetSdkVersion 26
|
targetSdkVersion 28
|
||||||
versionCode code
|
versionCode code
|
||||||
versionName "$versionNumber-$versionType-${props['build'].replace(" ", "-")}"
|
versionName versionNameResult
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions{
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
flavorDimensions "google"
|
flavorDimensions "google"
|
||||||
|
|
||||||
productFlavors {
|
signingConfigs{
|
||||||
google {
|
release{
|
||||||
buildConfigField "boolean", "DONATIONS_GOOGLE", "true"
|
if(project.hasProperty("RELEASE_STORE_FILE")){
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
signingConfigs {
|
|
||||||
release {
|
|
||||||
if(project.hasProperty("RELEASE_STORE_FILE")) {
|
|
||||||
storeFile file(RELEASE_STORE_FILE)
|
storeFile file(RELEASE_STORE_FILE)
|
||||||
storePassword RELEASE_STORE_PASSWORD
|
storePassword RELEASE_STORE_PASSWORD
|
||||||
keyAlias RELEASE_KEY_ALIAS
|
keyAlias RELEASE_KEY_ALIAS
|
||||||
keyPassword RELEASE_KEY_PASSWORD
|
keyPassword RELEASE_KEY_PASSWORD
|
||||||
}else{
|
}else{
|
||||||
println("No keystore info property found!");
|
println("No keystore info property found!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes{
|
||||||
release {
|
release{
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,22 +122,22 @@ android {
|
|||||||
// called every time gradle gets executed, takes the native dependencies of
|
// called every time gradle gets executed, takes the native dependencies of
|
||||||
// the natives configuration, and extracts them to the proper libs/ folders
|
// the natives configuration, and extracts them to the proper libs/ folders
|
||||||
// so they get packed with the APK.
|
// so they get packed with the APK.
|
||||||
task copyAndroidNatives() {
|
task copyAndroidNatives(){
|
||||||
file("libs/armeabi/").mkdirs();
|
file("libs/armeabi/").mkdirs()
|
||||||
file("libs/armeabi-v7a/").mkdirs();
|
file("libs/armeabi-v7a/").mkdirs()
|
||||||
file("libs/arm64-v8a/").mkdirs();
|
file("libs/arm64-v8a/").mkdirs()
|
||||||
file("libs/x86_64/").mkdirs();
|
file("libs/x86_64/").mkdirs()
|
||||||
file("libs/x86/").mkdirs();
|
file("libs/x86/").mkdirs()
|
||||||
|
|
||||||
configurations.natives.files.each { jar ->
|
configurations.natives.files.each{ jar ->
|
||||||
def outputDir = null
|
def outputDir = null
|
||||||
if (jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a")
|
if(jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a")
|
||||||
if (jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a")
|
if(jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a")
|
||||||
if (jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi")
|
if(jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi")
|
||||||
if (jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64")
|
if(jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64")
|
||||||
if (jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86")
|
if(jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86")
|
||||||
if (outputDir != null) {
|
if(outputDir != null){
|
||||||
copy {
|
copy{
|
||||||
from zipTree(jar)
|
from zipTree(jar)
|
||||||
into outputDir
|
into outputDir
|
||||||
include "*.so"
|
include "*.so"
|
||||||
@@ -114,71 +145,43 @@ task copyAndroidNatives() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
task run(type: Exec) {
|
|
||||||
|
task run(type: Exec){
|
||||||
def path
|
def path
|
||||||
def localProperties = project.file("../local.properties")
|
def localProperties = project.file("../local.properties")
|
||||||
if (localProperties.exists()) {
|
if(localProperties.exists()){
|
||||||
Properties properties = new Properties()
|
Properties properties = new Properties()
|
||||||
localProperties.withInputStream { instr ->
|
localProperties.withInputStream{ instr ->
|
||||||
properties.load(instr)
|
properties.load(instr)
|
||||||
}
|
}
|
||||||
def sdkDir = properties.getProperty('sdk.dir')
|
def sdkDir = properties.getProperty('sdk.dir')
|
||||||
if (sdkDir) {
|
if(sdkDir){
|
||||||
path = sdkDir
|
path = sdkDir
|
||||||
} else {
|
}else{
|
||||||
path = "$System.env.ANDROID_HOME"
|
path = "$System.env.ANDROID_HOME"
|
||||||
}
|
}
|
||||||
} else {
|
}else{
|
||||||
path = "$System.env.ANDROID_HOME"
|
path = "$System.env.ANDROID_HOME"
|
||||||
}
|
}
|
||||||
|
|
||||||
def adb = path + "/platform-tools/adb"
|
def adb = path + "/platform-tools/adb"
|
||||||
commandLine "$adb", 'shell', 'am', 'start', '-n', 'io.anuke.mindustry/io.anuke.mindustry.AndroidLauncher'
|
commandLine "$adb", 'shell', 'am', 'start', '-n', 'io.anuke.mindustry/io.anuke.mindustry.AndroidLauncher'
|
||||||
}
|
}
|
||||||
// sets up the Android Eclipse project, using the old Ant based build.
|
|
||||||
eclipse {
|
|
||||||
// need to specify Java source sets explicitly, SpringSource Gradle Eclipse plugin
|
|
||||||
// ignores any nodes added in classpath.file.withXml
|
|
||||||
sourceSets {
|
|
||||||
main {
|
|
||||||
java.srcDirs "src", 'gen'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jdt {
|
|
||||||
sourceCompatibility = 1.7
|
|
||||||
targetCompatibility = 1.7
|
|
||||||
}
|
|
||||||
|
|
||||||
classpath {
|
|
||||||
plusConfigurations += [project.configurations.compile]
|
|
||||||
containers 'com.android.ide.eclipse.adt.ANDROID_FRAMEWORK', 'com.android.ide.eclipse.adt.LIBRARIES'
|
|
||||||
}
|
|
||||||
|
|
||||||
project {
|
|
||||||
name = appName + "-android"
|
|
||||||
natures 'com.android.ide.eclipse.adt.AndroidNature'
|
|
||||||
buildCommands.clear();
|
|
||||||
buildCommand "com.android.ide.eclipse.adt.ResourceManagerBuilder"
|
|
||||||
buildCommand "com.android.ide.eclipse.adt.PreCompilerBuilder"
|
|
||||||
buildCommand "org.eclipse.jdt.core.javabuilder"
|
|
||||||
buildCommand "com.android.ide.eclipse.adt.ApkBuilder"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sets up the Android Idea project, using the old Ant based build.
|
// sets up the Android Idea project, using the old Ant based build.
|
||||||
idea {
|
idea{
|
||||||
module {
|
module{
|
||||||
sourceDirs += file("src");
|
sourceDirs += file("src")
|
||||||
scopes = [COMPILE: [plus: [project.configurations.compile]]]
|
scopes = [COMPILE: [plus: [project.configurations.compile]]]
|
||||||
|
|
||||||
iml {
|
iml{
|
||||||
withXml {
|
withXml{
|
||||||
def node = it.asNode()
|
def node = it.asNode()
|
||||||
def builder = NodeBuilder.newInstance();
|
def builder = NodeBuilder.newInstance()
|
||||||
builder.current = node;
|
builder.current = node
|
||||||
builder.component(name: "FacetManager") {
|
builder.component(name: "FacetManager"){
|
||||||
facet(type: "android", name: "Android") {
|
facet(type: "android", name: "Android"){
|
||||||
configuration {
|
configuration{
|
||||||
option(name: "UPDATE_PROPERTY_FILES", value: "true")
|
option(name: "UPDATE_PROPERTY_FILES", value: "true")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 76 KiB |
@@ -20,26 +20,10 @@
|
|||||||
#}
|
#}
|
||||||
|
|
||||||
-verbose
|
-verbose
|
||||||
|
-verbose
|
||||||
-dontwarn android.support.**
|
-ignorewarnings
|
||||||
-dontwarn com.badlogic.gdx.backends.android.AndroidFragmentApplication
|
-keep class io.anuke.mindustry.game.Rules
|
||||||
-dontwarn com.badlogic.gdx.utils.GdxBuild
|
-keep class io.anuke.mindustry.desktop.DesktopLauncher
|
||||||
-dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild
|
-keepclasseswithmembers public class * {
|
||||||
-dontwarn com.badlogic.gdx.jnigen.BuildTarget*
|
public static void main(java.lang.String[]);
|
||||||
-dontwarn com.badlogic.gdx.graphics.g2d.freetype.FreetypeBuild
|
|
||||||
|
|
||||||
-keep class com.badlogic.gdx.controllers.android.AndroidControllers
|
|
||||||
|
|
||||||
-keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* {
|
|
||||||
<init>(com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
-keepclassmembers class com.badlogic.gdx.physics.box2d.World {
|
|
||||||
boolean contactFilter(long, long);
|
|
||||||
void beginContact(long);
|
|
||||||
void endContact(long);
|
|
||||||
void preSolve(long, long);
|
|
||||||
void postSolve(long, long);
|
|
||||||
boolean reportFixture(long);
|
|
||||||
float reportRayFixture(long, float, float, float, float, float);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,5 @@
|
|||||||
#
|
#
|
||||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-19
|
target=android-19
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 911 B After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 23 KiB |
@@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/layout_root"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="10dp" >
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/gdxDialogsEditTextInput"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inputType="text"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:maxLength="15"
|
|
||||||
>
|
|
||||||
|
|
||||||
<requestFocus />
|
|
||||||
|
|
||||||
</EditText>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:background="#000">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="top"
|
|
||||||
android:adjustViewBounds="false"
|
|
||||||
android:contentDescription="background"
|
|
||||||
android:cropToPadding="false"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:src="@drawable/background" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/donations_activity_container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/layout_root"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="10dp" >
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/gdxDialogsEnterTitle"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
|
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
|
||||||
|
|
||||||
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/gdxDialogsEnterMessage"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
|
|
||||||
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/gdxDialogsEditTextInput"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inputType="text"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:maxLength="15"
|
|
||||||
>
|
|
||||||
|
|
||||||
<requestFocus />
|
|
||||||
|
|
||||||
</EditText>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 553 B After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 28 KiB |
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<style name="GdxTheme" parent="android:Theme.Material.NoActionBar">
|
<style name="GdxTheme" parent="android:Theme.Material.NoActionBar">
|
||||||
<item name="android:windowBackground">@android:color/transparent</item>
|
<item name="android:windowBackground">@android:color/transparent</item>
|
||||||
<item name="android:colorBackgroundCacheHint">@null</item>
|
<item name="android:colorBackgroundCacheHint">@null</item>
|
||||||
@@ -9,11 +8,4 @@
|
|||||||
<item name="android:windowContentOverlay">@null</item>
|
<item name="android:windowContentOverlay">@null</item>
|
||||||
<item name="android:windowFullscreen">true</item>
|
<item name="android:windowFullscreen">true</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="LightBackground" parent="android:Theme.Material.Light" >
|
|
||||||
<item name="android:colorBackground">@android:color/black</item>
|
|
||||||
<item name="android:textColorPrimary">@android:color/white</item>
|
|
||||||
<item name="android:textColorSecondary">@android:color/white</item>
|
|
||||||
<item name="android:textColorSecondaryInverse">@android:color/white</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -2,14 +2,5 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<string name="app_name">Mindustry</string>
|
<string name="app_name">Mindustry</string>
|
||||||
<string-array name="donation_google_catalog_values">
|
|
||||||
<item>1 Dollar</item>
|
|
||||||
<item>2 Dollars</item>
|
|
||||||
<item>5 Dollars</item>
|
|
||||||
<item>10 Dollars</item>
|
|
||||||
<item>15 Dollars</item>
|
|
||||||
<item>25 Dollars</item>
|
|
||||||
<item>50 Dollars</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
4
android/res/xml/backup_rules.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<full-backup-content>
|
||||||
|
|
||||||
|
</full-backup-content>
|
||||||
@@ -3,164 +3,185 @@ package io.anuke.mindustry;
|
|||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.Settings.Secure;
|
import android.provider.Settings.Secure;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import com.badlogic.gdx.backends.android.AndroidApplication;
|
import io.anuke.arc.Core;
|
||||||
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
|
import io.anuke.arc.backends.android.surfaceview.AndroidApplication;
|
||||||
import com.badlogic.gdx.utils.Base64Coder;
|
import io.anuke.arc.backends.android.surfaceview.AndroidApplicationConfiguration;
|
||||||
import io.anuke.kryonet.DefaultThreadImpl;
|
import io.anuke.arc.files.FileHandle;
|
||||||
import io.anuke.kryonet.KryoClient;
|
import io.anuke.arc.function.Consumer;
|
||||||
import io.anuke.kryonet.KryoServer;
|
import io.anuke.arc.scene.ui.layout.Unit;
|
||||||
import io.anuke.mindustry.core.ThreadHandler.ThreadProvider;
|
import io.anuke.arc.util.Strings;
|
||||||
import io.anuke.mindustry.io.Platform;
|
import io.anuke.arc.util.serialization.Base64Coder;
|
||||||
|
import io.anuke.mindustry.core.Platform;
|
||||||
|
import io.anuke.mindustry.game.Saves.SaveSlot;
|
||||||
|
import io.anuke.mindustry.io.SaveIO;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.mindustry.ui.dialogs.FileChooser;
|
||||||
import io.anuke.ucore.scene.ui.TextField;
|
import io.anuke.mindustry.net.ArcNetClient;
|
||||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
import io.anuke.mindustry.net.ArcNetServer;
|
||||||
|
|
||||||
import java.text.DateFormat;
|
import java.io.*;
|
||||||
import java.text.NumberFormat;
|
import java.util.ArrayList;
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class AndroidLauncher extends AndroidApplication{
|
public class AndroidLauncher extends AndroidApplication{
|
||||||
boolean doubleScaleTablets = true;
|
public static final int PERMISSION_REQUEST_CODE = 1;
|
||||||
int WRITE_REQUEST_CODE = 1;
|
boolean doubleScaleTablets = true;
|
||||||
|
FileChooser chooser;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState){
|
protected void onCreate(Bundle savedInstanceState){
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
|
||||||
|
config.useImmersiveMode = true;
|
||||||
|
config.depth = 0;
|
||||||
|
Platform.instance = new Platform(){
|
||||||
|
|
||||||
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
|
@Override
|
||||||
config.useImmersiveMode = true;
|
public void hide(){
|
||||||
|
moveTaskToBack(true);
|
||||||
|
}
|
||||||
|
|
||||||
Platform.instance = new Platform(){
|
@Override
|
||||||
DateFormat format = SimpleDateFormat.getDateTimeInstance();
|
public String getUUID(){
|
||||||
|
try{
|
||||||
@Override
|
String s = Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
|
||||||
public boolean hasDiscord() {
|
int len = s.length();
|
||||||
return isPackageInstalled("com.discord");
|
byte[] data = new byte[len / 2];
|
||||||
}
|
for(int i = 0; i < len; i += 2){
|
||||||
|
data[i / 2] = (byte)((Character.digit(s.charAt(i), 16) << 4)
|
||||||
@Override
|
+ Character.digit(s.charAt(i + 1), 16));
|
||||||
public String format(Date date){
|
|
||||||
return format.format(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(int number){
|
|
||||||
return NumberFormat.getIntegerInstance().format(number);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addDialog(TextField field, int length){
|
|
||||||
TextFieldDialogListener.add(field, 0, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLocaleName(Locale locale){
|
|
||||||
return locale.getDisplayName(locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void openDonations() {
|
|
||||||
showDonations();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void requestWritePerms() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
||||||
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
|
|
||||||
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
|
||||||
Manifest.permission.READ_EXTERNAL_STORAGE}, WRITE_REQUEST_CODE);
|
|
||||||
}else{
|
|
||||||
|
|
||||||
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_REQUEST_CODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, WRITE_REQUEST_CODE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ThreadProvider getThreadProvider() {
|
|
||||||
return new DefaultThreadImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDebug() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getUUID() {
|
|
||||||
try {
|
|
||||||
String s = Secure.getString(getContext().getContentResolver(),
|
|
||||||
Secure.ANDROID_ID);
|
|
||||||
|
|
||||||
int len = s.length();
|
|
||||||
byte[] data = new byte[len / 2];
|
|
||||||
for (int i = 0; i < len; i += 2) {
|
|
||||||
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
|
||||||
+ Character.digit(s.charAt(i + 1), 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}catch (Exception e){
|
|
||||||
Settings.defaults("uuid", "");
|
|
||||||
|
|
||||||
String uuid = Settings.getString("uuid");
|
|
||||||
if(uuid.isEmpty()){
|
|
||||||
byte[] result = new byte[8];
|
|
||||||
new Random().nextBytes(result);
|
|
||||||
uuid = new String(Base64Coder.encode(result));
|
|
||||||
Settings.putString("uuid", uuid);
|
|
||||||
Settings.save();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return Base64Coder.decode(uuid);
|
String result = new String(Base64Coder.encode(data));
|
||||||
}
|
if(result.equals("AAAAAAAAAOA=")) throw new RuntimeException("Bad UUID.");
|
||||||
}
|
return result;
|
||||||
};
|
}catch(Exception e){
|
||||||
|
return super.getUUID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(doubleScaleTablets && isTablet(this.getContext())){
|
@Override
|
||||||
Unit.dp.addition = 0.5f;
|
public void shareFile(FileHandle file){
|
||||||
}
|
}
|
||||||
|
|
||||||
config.hideStatusBar = true;
|
|
||||||
|
|
||||||
Net.setClientProvider(new KryoClient());
|
@Override
|
||||||
Net.setServerProvider(new KryoServer());
|
public void showFileChooser(String text, String content, Consumer<FileHandle> cons, boolean open, String filetype){
|
||||||
|
chooser = new FileChooser(text, file -> file.extension().equalsIgnoreCase(filetype), open, cons);
|
||||||
|
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.M || (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
|
||||||
|
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){
|
||||||
|
chooser.show();
|
||||||
|
chooser = null;
|
||||||
|
}else{
|
||||||
|
ArrayList<String> perms = new ArrayList<>();
|
||||||
|
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
|
||||||
|
perms.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||||
|
}
|
||||||
|
if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
|
||||||
|
perms.add(Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||||
|
}
|
||||||
|
requestPermissions(perms.toArray(new String[0]), PERMISSION_REQUEST_CODE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginForceLandscape(){
|
||||||
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endForceLandscape(){
|
||||||
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canDonate(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(doubleScaleTablets && isTablet(this.getContext())){
|
||||||
|
Unit.dp.addition = 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.hideStatusBar = true;
|
||||||
|
Net.setClientProvider(new ArcNetClient());
|
||||||
|
Net.setServerProvider(new ArcNetServer());
|
||||||
initialize(new Mindustry(), config);
|
initialize(new Mindustry(), config);
|
||||||
}
|
checkFiles(getIntent());
|
||||||
|
}
|
||||||
private boolean isPackageInstalled(String packagename) {
|
|
||||||
try {
|
@Override
|
||||||
getPackageManager().getPackageInfo(packagename, 0);
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
|
||||||
return true;
|
if(requestCode == PERMISSION_REQUEST_CODE){
|
||||||
} catch (Exception e) {
|
for(int i : grantResults){
|
||||||
return false;
|
if(i != PackageManager.PERMISSION_GRANTED) return;
|
||||||
}
|
}
|
||||||
}
|
if(chooser != null){
|
||||||
|
chooser.show();
|
||||||
private boolean isTablet(Context context) {
|
}
|
||||||
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
|
}
|
||||||
return manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE;
|
}
|
||||||
}
|
|
||||||
|
private void checkFiles(Intent intent){
|
||||||
private void showDonations(){
|
try{
|
||||||
Intent intent = new Intent(this, DonationsActivity.class);
|
Uri uri = intent.getData();
|
||||||
startActivity(intent);
|
if(uri != null){
|
||||||
}
|
File myFile = null;
|
||||||
|
String scheme = uri.getScheme();
|
||||||
|
if(scheme.equals("file")){
|
||||||
|
String fileName = uri.getEncodedPath();
|
||||||
|
myFile = new File(fileName);
|
||||||
|
}else if(!scheme.equals("content")){
|
||||||
|
//error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean save = uri.getPath().endsWith(saveExtension);
|
||||||
|
boolean map = uri.getPath().endsWith(mapExtension);
|
||||||
|
InputStream inStream;
|
||||||
|
if(myFile != null) inStream = new FileInputStream(myFile);
|
||||||
|
else inStream = getContentResolver().openInputStream(uri);
|
||||||
|
Core.app.post(() -> {
|
||||||
|
if(save){ //open save
|
||||||
|
System.out.println("Opening save.");
|
||||||
|
FileHandle file = Core.files.local("temp-save." + saveExtension);
|
||||||
|
file.write(inStream, false);
|
||||||
|
if(SaveIO.isSaveValid(file)){
|
||||||
|
try{
|
||||||
|
SaveSlot slot = control.saves.importSave(file);
|
||||||
|
ui.load.runLoadSave(slot);
|
||||||
|
}catch(IOException e){
|
||||||
|
ui.showError(Core.bundle.format("save.import.fail", Strings.parseException(e, false)));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
ui.showError("$save.import.invalid");
|
||||||
|
}
|
||||||
|
}else if(map){ //open map
|
||||||
|
FileHandle file = Core.files.local("temp-map." + mapExtension);
|
||||||
|
file.write(inStream, false);
|
||||||
|
Core.app.post(() -> {
|
||||||
|
System.out.println("Opening map.");
|
||||||
|
if(!ui.editor.isShown()){
|
||||||
|
ui.editor.show();
|
||||||
|
}
|
||||||
|
ui.editor.beginEditMap(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}catch(IOException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTablet(Context context){
|
||||||
|
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
return manager != null && manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,119 +0,0 @@
|
|||||||
package io.anuke.mindustry;
|
|
||||||
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.text.InputFilter;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager.LayoutParams;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
|
|
||||||
public class AndroidTextFieldDialog{
|
|
||||||
private Activity activity;
|
|
||||||
private EditText userInput;
|
|
||||||
private AlertDialog.Builder builder;
|
|
||||||
private TextPromptListener listener;
|
|
||||||
private boolean isBuild;
|
|
||||||
|
|
||||||
public AndroidTextFieldDialog() {
|
|
||||||
this.activity = (Activity)Gdx.app;
|
|
||||||
load();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidTextFieldDialog show() {
|
|
||||||
|
|
||||||
activity.runOnUiThread(() -> {
|
|
||||||
Gdx.app.error("Android Dialogs", AndroidTextFieldDialog.class.getSimpleName() + " now shown.");
|
|
||||||
AlertDialog dialog = builder.create();
|
|
||||||
|
|
||||||
dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AndroidTextFieldDialog load() {
|
|
||||||
|
|
||||||
activity.runOnUiThread(() -> {
|
|
||||||
|
|
||||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
|
|
||||||
LayoutInflater li = LayoutInflater.from(activity);
|
|
||||||
|
|
||||||
View promptsView = li.inflate(getResourceId("gdxdialogs_inputtext", "layout"), null);
|
|
||||||
|
|
||||||
alertDialogBuilder.setView(promptsView);
|
|
||||||
|
|
||||||
userInput = (EditText) promptsView.findViewById(getResourceId("gdxDialogsEditTextInput", "id"));
|
|
||||||
|
|
||||||
alertDialogBuilder.setCancelable(false);
|
|
||||||
builder = alertDialogBuilder;
|
|
||||||
|
|
||||||
isBuild = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wait till TextPrompt is built.
|
|
||||||
while (!isBuild) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(10);
|
|
||||||
} catch (InterruptedException e) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getResourceId(String pVariableName, String pVariableType) {
|
|
||||||
try {
|
|
||||||
return activity.getResources().getIdentifier(pVariableName, pVariableType, activity.getPackageName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Gdx.app.error("Android Dialogs", "Cannot find resouce with name: " + pVariableName
|
|
||||||
+ " Did you copy the layouts to /res/layouts and /res/layouts_v14 ?");
|
|
||||||
e.printStackTrace();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidTextFieldDialog setText(CharSequence value) {
|
|
||||||
userInput.append(value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label) {
|
|
||||||
builder.setNegativeButton(label, (dialog, id) -> dialog.cancel());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label) {
|
|
||||||
builder.setPositiveButton(label, (dialog, id) -> {
|
|
||||||
if (listener != null && !userInput.getText().toString().isEmpty()) {
|
|
||||||
listener.confirm(userInput.getText().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidTextFieldDialog setTextPromptListener(TextPromptListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidTextFieldDialog setInputType(int type) {
|
|
||||||
userInput.setInputType(type);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidTextFieldDialog setMaxLength(int length) {
|
|
||||||
userInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(length) });
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface TextPromptListener{
|
|
||||||
void confirm(String text);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
package io.anuke.mindustry;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.app.FragmentActivity;
|
|
||||||
import android.support.v4.app.FragmentManager;
|
|
||||||
import android.support.v4.app.FragmentTransaction;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.donations.DonationsFragment;
|
|
||||||
|
|
||||||
public class DonationsActivity extends FragmentActivity {
|
|
||||||
DonationsFragment donationsFragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Google
|
|
||||||
*/
|
|
||||||
private static final String GOOGLE_PUBKEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzG93KhpfBPKTo2jF0yxbWkkmMKwsPNM4SsMj1aDq7vv6n3R+mqJVfprOJxFfJh7JchXTflLIgiaKXFAiU70gJbMTniEWnEaFSxAeF09a7U0RjOwN+7rFwjCG91c2CpYxPanBTQP4zasc1ODPVzq4q6/4ByjhenN71V4WmR08NFIAodcfFPrOkDPil7i8y7cgcd1Ky53U0TS+LLYJttAK3XdTK4s7VE3I5IKoeNa4uwCmIM59R67q2k3cXjLk/nP6MP+y++EzHN/PTiR1sVg4dMP8K31RPw/1QNLPQwJz6Wc872oWwb7xo5gkoXbDc5WPPydsi8F3SyKNaYwzN6CDFQIDAQAB";
|
|
||||||
private static final String[] GOOGLE_CATALOG = new String[]{
|
|
||||||
"mindustry.donation.1", "mindustry.donation.2", "mindustry.donation.5",
|
|
||||||
"mindustry.donation.10", "mindustry.donation.15",
|
|
||||||
"mindustry.donation.25", "mindustry.donation.50" };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the activity is first created.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
setTheme(R.style.GdxTheme);
|
|
||||||
|
|
||||||
setContentView(R.layout.donations_activity);
|
|
||||||
|
|
||||||
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
|
||||||
if (BuildConfig.DONATIONS_GOOGLE) {
|
|
||||||
donationsFragment = DonationsFragment.newInstance(BuildConfig.DEBUG, true, GOOGLE_PUBKEY, GOOGLE_CATALOG,
|
|
||||||
getResources().getStringArray(R.array.donation_google_catalog_values), false, null, null,
|
|
||||||
null, false, null, null, false, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ft.replace(R.id.donations_activity_container, donationsFragment, "donationsFragment");
|
|
||||||
ft.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onStart(){
|
|
||||||
super.onStart();
|
|
||||||
Button b = ((Button)findViewById(org.sufficientlysecure.donations.R.id.donations__google_android_market_donate_button));
|
|
||||||
b.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override public void onClick(View view) {
|
|
||||||
donationsFragment.donateGoogleOnClick(donationsFragment.getView());
|
|
||||||
b.setEnabled(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Needed for Google Play In-app Billing. It uses startIntentSenderForResult(). The result is not propagated to
|
|
||||||
* the Fragment like in startActivityForResult(). Thus we need to propagate manually to our Fragment.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
Button b = ((Button)findViewById(org.sufficientlysecure.donations.R.id.donations__google_android_market_donate_button));
|
|
||||||
b.setEnabled(true);
|
|
||||||
|
|
||||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
|
||||||
Fragment fragment = fragmentManager.findFragmentByTag("donationsFragment");
|
|
||||||
if (fragment != null) {
|
|
||||||
fragment.onActivityResult(requestCode, resultCode, data);
|
|
||||||
//TODO donation event, set settings?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package io.anuke.mindustry;
|
|
||||||
|
|
||||||
|
|
||||||
import android.text.InputType;
|
|
||||||
import com.badlogic.gdx.Application.ApplicationType;
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
import io.anuke.ucore.scene.event.ChangeListener;
|
|
||||||
import io.anuke.ucore.scene.event.ClickListener;
|
|
||||||
import io.anuke.ucore.scene.event.InputEvent;
|
|
||||||
import io.anuke.ucore.scene.event.InputListener;
|
|
||||||
import io.anuke.ucore.scene.ui.TextField;
|
|
||||||
|
|
||||||
public class TextFieldDialogListener extends ClickListener{
|
|
||||||
private TextField field;
|
|
||||||
private int type;
|
|
||||||
private int max;
|
|
||||||
|
|
||||||
public static void add(TextField field, int type, int max){
|
|
||||||
field.addListener(new TextFieldDialogListener(field, type, max));
|
|
||||||
field.addListener(new InputListener(){
|
|
||||||
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
|
|
||||||
Gdx.input.setOnscreenKeyboardVisible(false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void add(TextField field){
|
|
||||||
add(field, 0, 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
//type - 0 is text, 1 is numbers, 2 is decimals
|
|
||||||
public TextFieldDialogListener(TextField field, int type, int max){
|
|
||||||
this.field = field;
|
|
||||||
this.type = type;
|
|
||||||
this.max = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clicked(final InputEvent event, float x, float y){
|
|
||||||
|
|
||||||
if(Gdx.app.getType() == ApplicationType.Desktop) return;
|
|
||||||
|
|
||||||
AndroidTextFieldDialog dialog = new AndroidTextFieldDialog();
|
|
||||||
|
|
||||||
dialog.setTextPromptListener(text -> {
|
|
||||||
field.clearText();
|
|
||||||
field.appendText(text);
|
|
||||||
field.fire(new ChangeListener.ChangeEvent());
|
|
||||||
Gdx.graphics.requestRendering();
|
|
||||||
});
|
|
||||||
|
|
||||||
if(type == 0){
|
|
||||||
dialog.setInputType(InputType.TYPE_CLASS_TEXT);
|
|
||||||
}else if(type == 1){
|
|
||||||
dialog.setInputType(InputType.TYPE_CLASS_NUMBER);
|
|
||||||
}else if(type == 2){
|
|
||||||
dialog.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog.setConfirmButtonLabel("OK").setText(field.getText());
|
|
||||||
dialog.setCancelButtonLabel("Cancel");
|
|
||||||
dialog.setMaxLength(max);
|
|
||||||
dialog.show();
|
|
||||||
event.cancel();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
6
annotations/build.gradle
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
apply plugin: "java"
|
||||||
|
|
||||||
|
sourceCompatibility = 1.8
|
||||||
|
sourceSets.main.java.srcDirs = ["src/main/java/"]
|
||||||
|
sourceSets.main.resources.srcDirs = ["src/main/resources/"]
|
||||||
|
|
||||||
135
annotations/src/main/java/io/anuke/annotations/Annotations.java
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
public class Annotations{
|
||||||
|
|
||||||
|
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface Nullable{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface NonNull{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Marks a class as serializable. */
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface Serialize{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Marks a class as a special value type struct. Class name must end in 'Struct'. */
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface Struct{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Marks a field of a struct. Optional. */
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface StructField{
|
||||||
|
/** Size of a struct field in bits. Not valid on booleans or floating point numbers. */
|
||||||
|
int value();
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PacketPriority{
|
||||||
|
/** Gets put in a queue and processed if not connected. */
|
||||||
|
normal,
|
||||||
|
/** Gets handled immediately, regardless of connection status. */
|
||||||
|
high,
|
||||||
|
/** Does not get handled unless client is connected. */
|
||||||
|
low
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A set of two booleans, one specifying server and one specifying client. */
|
||||||
|
public enum Loc{
|
||||||
|
/** Method can only be invoked on the client from the server. */
|
||||||
|
server(true, false),
|
||||||
|
/** Method can only be invoked on the server from the client. */
|
||||||
|
client(false, true),
|
||||||
|
/** Method can be invoked from anywhere */
|
||||||
|
both(true, true),
|
||||||
|
/** Neither server nor client. */
|
||||||
|
none(false, false);
|
||||||
|
|
||||||
|
/** If true, this method can be invoked ON clients FROM servers. */
|
||||||
|
public final boolean isServer;
|
||||||
|
/** If true, this method can be invoked ON servers FROM clients. */
|
||||||
|
public final boolean isClient;
|
||||||
|
|
||||||
|
Loc(boolean server, boolean client){
|
||||||
|
this.isServer = server;
|
||||||
|
this.isClient = client;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Variant{
|
||||||
|
/** Method can only be invoked targeting one player. */
|
||||||
|
one(true, false),
|
||||||
|
/** Method can only be invoked targeting all players. */
|
||||||
|
all(false, true),
|
||||||
|
/** Method targets both one player and all players. */
|
||||||
|
both(true, true);
|
||||||
|
|
||||||
|
public final boolean isOne, isAll;
|
||||||
|
|
||||||
|
Variant(boolean isOne, boolean isAll){
|
||||||
|
this.isOne = isOne;
|
||||||
|
this.isAll = isAll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Marks a method as invokable remotely across a server/client connection. */
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface Remote{
|
||||||
|
/** Specifies the locations from which this method can be invoked. */
|
||||||
|
Loc targets() default Loc.server;
|
||||||
|
|
||||||
|
/** Specifies which methods are generated. Only affects server-to-client methods. */
|
||||||
|
Variant variants() default Variant.all;
|
||||||
|
|
||||||
|
/** The local locations where this method is called locally, when invoked. */
|
||||||
|
Loc called() default Loc.none;
|
||||||
|
|
||||||
|
/** Whether to forward this packet to all other clients upon recieval. Client only. */
|
||||||
|
boolean forward() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the packet for this method is sent with UDP instead of TCP.
|
||||||
|
* UDP is faster, but is prone to packet loss and duplication.
|
||||||
|
*/
|
||||||
|
boolean unreliable() default false;
|
||||||
|
|
||||||
|
/** Priority of this event. */
|
||||||
|
PacketPriority priority() default PacketPriority.normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies that this method will be used to write classes of the type returned by {@link #value()}.<br>
|
||||||
|
* This method must return void and have two parameters, the first being of type {@link java.nio.ByteBuffer} and the second
|
||||||
|
* being the type returned by {@link #value()}.
|
||||||
|
*/
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface WriteClass{
|
||||||
|
Class<?> value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies that this method will be used to read classes of the type returned by {@link #value()}. <br>
|
||||||
|
* This method must return the type returned by {@link #value()},
|
||||||
|
* and have one parameter, being of type {@link java.nio.ByteBuffer}.
|
||||||
|
*/
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface ReadClass{
|
||||||
|
Class<?> value();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/** Represents a class witha list method entries to include in it. */
|
||||||
|
public class ClassEntry{
|
||||||
|
/** All methods in this generated class. */
|
||||||
|
public final ArrayList<MethodEntry> methods = new ArrayList<>();
|
||||||
|
/** Simple class name. */
|
||||||
|
public final String name;
|
||||||
|
|
||||||
|
public ClassEntry(String name){
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
90
annotations/src/main/java/io/anuke/annotations/IOFinder.java
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import io.anuke.annotations.Annotations.ReadClass;
|
||||||
|
import io.anuke.annotations.Annotations.WriteClass;
|
||||||
|
|
||||||
|
import javax.annotation.processing.RoundEnvironment;
|
||||||
|
import javax.lang.model.element.Element;
|
||||||
|
import javax.lang.model.type.MirroredTypeException;
|
||||||
|
import javax.tools.Diagnostic.Kind;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class finds reader and writer methods annotated by the {@link io.anuke.annotations.Annotations.WriteClass}
|
||||||
|
* and {@link io.anuke.annotations.Annotations.ReadClass} annotations.
|
||||||
|
*/
|
||||||
|
public class IOFinder{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all class serializers for all types and returns them. Logs errors when necessary.
|
||||||
|
* Maps fully qualified class names to their serializers.
|
||||||
|
*/
|
||||||
|
public HashMap<String, ClassSerializer> findSerializers(RoundEnvironment env){
|
||||||
|
HashMap<String, ClassSerializer> result = new HashMap<>();
|
||||||
|
|
||||||
|
//get methods with the types
|
||||||
|
Set<? extends Element> writers = env.getElementsAnnotatedWith(WriteClass.class);
|
||||||
|
Set<? extends Element> readers = env.getElementsAnnotatedWith(ReadClass.class);
|
||||||
|
|
||||||
|
//look for writers first
|
||||||
|
for(Element writer : writers){
|
||||||
|
WriteClass writean = writer.getAnnotation(WriteClass.class);
|
||||||
|
String typeName = getValue(writean);
|
||||||
|
|
||||||
|
//make sure there's only one read method
|
||||||
|
if(readers.stream().filter(elem -> getValue(elem.getAnnotation(ReadClass.class)).equals(typeName)).count() > 1){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "Multiple writer methods for type '" + typeName + "'", writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//make sure there's only one write method
|
||||||
|
long count = readers.stream().filter(elem -> getValue(elem.getAnnotation(ReadClass.class)).equals(typeName)).count();
|
||||||
|
if(count == 0){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "Writer method does not have an accompanying reader: ", writer);
|
||||||
|
}else if(count > 1){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "Writer method has multiple reader for type: ", writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Element reader = readers.stream().filter(elem -> getValue(elem.getAnnotation(ReadClass.class)).equals(typeName)).findFirst().get();
|
||||||
|
|
||||||
|
//add to result list
|
||||||
|
result.put(typeName, new ClassSerializer(Utils.getMethodName(reader), Utils.getMethodName(writer), typeName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getValue(WriteClass write){
|
||||||
|
try{
|
||||||
|
Class<?> type = write.value();
|
||||||
|
return type.getName();
|
||||||
|
}catch(MirroredTypeException e){
|
||||||
|
return e.getTypeMirror().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getValue(ReadClass read){
|
||||||
|
try{
|
||||||
|
Class<?> type = read.value();
|
||||||
|
return type.getName();
|
||||||
|
}catch(MirroredTypeException e){
|
||||||
|
return e.getTypeMirror().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Information about read/write methods for a specific class type. */
|
||||||
|
public static class ClassSerializer{
|
||||||
|
/** Fully qualified method name of the reader. */
|
||||||
|
public final String readMethod;
|
||||||
|
/** Fully qualified method name of the writer. */
|
||||||
|
public final String writeMethod;
|
||||||
|
/** Fully qualified class type name. */
|
||||||
|
public final String classType;
|
||||||
|
|
||||||
|
public ClassSerializer(String readMethod, String writeMethod, String classType){
|
||||||
|
this.readMethod = readMethod;
|
||||||
|
this.writeMethod = writeMethod;
|
||||||
|
this.classType = classType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import io.anuke.annotations.Annotations.*;
|
||||||
|
|
||||||
|
import javax.lang.model.element.ExecutableElement;
|
||||||
|
|
||||||
|
/** Class that repesents a remote method to be constructed and put into a class. */
|
||||||
|
public class MethodEntry{
|
||||||
|
/** Simple target class name. */
|
||||||
|
public final String className;
|
||||||
|
/** Fully qualified target method to call. */
|
||||||
|
public final String targetMethod;
|
||||||
|
/** Whether this method can be called on a client/server. */
|
||||||
|
public final Loc where;
|
||||||
|
/**
|
||||||
|
* Whether an additional 'one' and 'all' method variant is generated. At least one of these must be true.
|
||||||
|
* Only applicable to client (server-invoked) methods.
|
||||||
|
*/
|
||||||
|
public final Variant target;
|
||||||
|
/** Whether this method is called locally as well as remotely. */
|
||||||
|
public final Loc local;
|
||||||
|
/** Whether this method is unreliable and uses UDP. */
|
||||||
|
public final boolean unreliable;
|
||||||
|
/** Whether to forward this method call to all other clients when a client invokes it. Server only. */
|
||||||
|
public final boolean forward;
|
||||||
|
/** Unique method ID. */
|
||||||
|
public final int id;
|
||||||
|
/** The element method associated with this entry. */
|
||||||
|
public final ExecutableElement element;
|
||||||
|
/** The assigned packet priority. Only used in clients. */
|
||||||
|
public final PacketPriority priority;
|
||||||
|
|
||||||
|
public MethodEntry(String className, String targetMethod, Loc where, Variant target,
|
||||||
|
Loc local, boolean unreliable, boolean forward, int id, ExecutableElement element, PacketPriority priority){
|
||||||
|
this.className = className;
|
||||||
|
this.forward = forward;
|
||||||
|
this.targetMethod = targetMethod;
|
||||||
|
this.where = where;
|
||||||
|
this.target = target;
|
||||||
|
this.local = local;
|
||||||
|
this.id = id;
|
||||||
|
this.element = element;
|
||||||
|
this.unreliable = unreliable;
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode(){
|
||||||
|
return targetMethod.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.*;
|
||||||
|
import io.anuke.annotations.Annotations.Loc;
|
||||||
|
import io.anuke.annotations.Annotations.Remote;
|
||||||
|
import io.anuke.annotations.IOFinder.ClassSerializer;
|
||||||
|
|
||||||
|
import javax.annotation.processing.*;
|
||||||
|
import javax.lang.model.SourceVersion;
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import javax.tools.Diagnostic.Kind;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
|
/** The annotation processor for generating remote method call code. */
|
||||||
|
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||||
|
@SupportedAnnotationTypes({
|
||||||
|
"io.anuke.annotations.Annotations.Remote",
|
||||||
|
"io.anuke.annotations.Annotations.WriteClass",
|
||||||
|
"io.anuke.annotations.Annotations.ReadClass",
|
||||||
|
})
|
||||||
|
public class RemoteMethodAnnotationProcessor extends AbstractProcessor{
|
||||||
|
/** Maximum size of each event packet. */
|
||||||
|
public static final int maxPacketSize = 4096;
|
||||||
|
/** Warning on top of each autogenerated file. */
|
||||||
|
public static final String autogenWarning = "Autogenerated file. Do not modify!\n";
|
||||||
|
/** Name of the base package to put all the generated classes. */
|
||||||
|
private static final String packageName = "io.anuke.mindustry.gen";
|
||||||
|
|
||||||
|
/** Name of class that handles reading and invoking packets on the server. */
|
||||||
|
private static final String readServerName = "RemoteReadServer";
|
||||||
|
/** Name of class that handles reading and invoking packets on the client. */
|
||||||
|
private static final String readClientName = "RemoteReadClient";
|
||||||
|
/** Simple class name of generated class name. */
|
||||||
|
private static final String callLocation = "Call";
|
||||||
|
|
||||||
|
/** Processing round number. */
|
||||||
|
private int round;
|
||||||
|
|
||||||
|
//class serializers
|
||||||
|
private HashMap<String, ClassSerializer> serializers;
|
||||||
|
//all elements with the Remote annotation
|
||||||
|
private Set<? extends Element> elements;
|
||||||
|
//map of all classes to generate by name
|
||||||
|
private HashMap<String, ClassEntry> classMap;
|
||||||
|
//list of all method entries
|
||||||
|
private ArrayList<MethodEntry> methods;
|
||||||
|
//list of all method entries
|
||||||
|
private ArrayList<ClassEntry> classes;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void init(ProcessingEnvironment processingEnv){
|
||||||
|
super.init(processingEnv);
|
||||||
|
//put all relevant utils into utils class
|
||||||
|
Utils.typeUtils = processingEnv.getTypeUtils();
|
||||||
|
Utils.elementUtils = processingEnv.getElementUtils();
|
||||||
|
Utils.filer = processingEnv.getFiler();
|
||||||
|
Utils.messager = processingEnv.getMessager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||||
|
if(round > 1) return false; //only process 2 rounds
|
||||||
|
|
||||||
|
round++;
|
||||||
|
|
||||||
|
try{
|
||||||
|
|
||||||
|
//round 1: find all annotations, generate *writers*
|
||||||
|
if(round == 1){
|
||||||
|
//get serializers
|
||||||
|
serializers = new IOFinder().findSerializers(roundEnv);
|
||||||
|
//last method ID used
|
||||||
|
int lastMethodID = 0;
|
||||||
|
//find all elements with the Remote annotation
|
||||||
|
elements = roundEnv.getElementsAnnotatedWith(Remote.class);
|
||||||
|
//map of all classes to generate by name
|
||||||
|
classMap = new HashMap<>();
|
||||||
|
//list of all method entries
|
||||||
|
methods = new ArrayList<>();
|
||||||
|
//list of all method entries
|
||||||
|
classes = new ArrayList<>();
|
||||||
|
|
||||||
|
List<Element> orderedElements = new ArrayList<>(elements);
|
||||||
|
orderedElements.sort(Comparator.comparing(Object::toString));
|
||||||
|
|
||||||
|
//create methods
|
||||||
|
for(Element element : orderedElements){
|
||||||
|
Remote annotation = element.getAnnotation(Remote.class);
|
||||||
|
|
||||||
|
//check for static
|
||||||
|
if(!element.getModifiers().contains(Modifier.STATIC) || !element.getModifiers().contains(Modifier.PUBLIC)){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "All @Remote methods must be public and static: ", element);
|
||||||
|
}
|
||||||
|
|
||||||
|
//can't generate none methods
|
||||||
|
if(annotation.targets() == Loc.none){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "A @Remote method's targets() cannot be equal to 'none':", element);
|
||||||
|
}
|
||||||
|
|
||||||
|
//get and create class entry if needed
|
||||||
|
if(!classMap.containsKey(callLocation)){
|
||||||
|
ClassEntry clas = new ClassEntry(callLocation);
|
||||||
|
classMap.put(callLocation, clas);
|
||||||
|
classes.add(clas);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassEntry entry = classMap.get(callLocation);
|
||||||
|
|
||||||
|
//create and add entry
|
||||||
|
MethodEntry method = new MethodEntry(entry.name, Utils.getMethodName(element), annotation.targets(), annotation.variants(),
|
||||||
|
annotation.called(), annotation.unreliable(), annotation.forward(), lastMethodID++, (ExecutableElement)element, annotation.priority());
|
||||||
|
|
||||||
|
entry.methods.add(method);
|
||||||
|
methods.add(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
//create read/write generators
|
||||||
|
RemoteWriteGenerator writegen = new RemoteWriteGenerator(serializers);
|
||||||
|
|
||||||
|
//generate the methods to invoke (write)
|
||||||
|
writegen.generateFor(classes, packageName);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}else if(round == 2){ //round 2: generate all *readers*
|
||||||
|
RemoteReadGenerator readgen = new RemoteReadGenerator(serializers);
|
||||||
|
|
||||||
|
//generate server readers
|
||||||
|
readgen.generateFor(methods.stream().filter(method -> method.where.isClient).collect(Collectors.toList()), readServerName, packageName, true);
|
||||||
|
//generate client readers
|
||||||
|
readgen.generateFor(methods.stream().filter(method -> method.where.isServer).collect(Collectors.toList()), readClientName, packageName, false);
|
||||||
|
|
||||||
|
//create class for storing unique method hash
|
||||||
|
TypeSpec.Builder hashBuilder = TypeSpec.classBuilder("MethodHash").addModifiers(Modifier.PUBLIC);
|
||||||
|
hashBuilder.addJavadoc(autogenWarning);
|
||||||
|
hashBuilder.addField(FieldSpec.builder(int.class, "HASH", Modifier.STATIC, Modifier.PUBLIC, Modifier.FINAL)
|
||||||
|
.initializer("$1L", Objects.hash(methods)).build());
|
||||||
|
|
||||||
|
//build and write resulting hash class
|
||||||
|
TypeSpec spec = hashBuilder.build();
|
||||||
|
JavaFile.builder(packageName, spec).build().writeTo(Utils.filer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.*;
|
||||||
|
import io.anuke.annotations.IOFinder.ClassSerializer;
|
||||||
|
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import javax.tools.Diagnostic.Kind;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/** Generates code for reading remote invoke packets on the client and server. */
|
||||||
|
public class RemoteReadGenerator{
|
||||||
|
private final HashMap<String, ClassSerializer> serializers;
|
||||||
|
|
||||||
|
/** Creates a read generator that uses the supplied serializer setup. */
|
||||||
|
public RemoteReadGenerator(HashMap<String, ClassSerializer> serializers){
|
||||||
|
this.serializers = serializers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a class for reading remote invoke packets.
|
||||||
|
* @param entries List of methods to use.
|
||||||
|
* @param className Simple target class name.
|
||||||
|
* @param packageName Full target package name.
|
||||||
|
* @param needsPlayer Whether this read method requires a reference to the player sender.
|
||||||
|
*/
|
||||||
|
public void generateFor(List<MethodEntry> entries, String className, String packageName, boolean needsPlayer)
|
||||||
|
throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException, IOException{
|
||||||
|
|
||||||
|
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
|
||||||
|
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning);
|
||||||
|
|
||||||
|
//create main method builder
|
||||||
|
MethodSpec.Builder readMethod = MethodSpec.methodBuilder("readPacket")
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||||
|
.addParameter(ByteBuffer.class, "buffer") //buffer to read form
|
||||||
|
.addParameter(int.class, "id") //ID of method type to read
|
||||||
|
.returns(void.class);
|
||||||
|
|
||||||
|
if(needsPlayer){
|
||||||
|
//since the player type isn't loaded yet, creating a type def is necessary
|
||||||
|
//this requires reflection since the TypeName constructor is private for some reason
|
||||||
|
Constructor<TypeName> cons = TypeName.class.getDeclaredConstructor(String.class);
|
||||||
|
cons.setAccessible(true);
|
||||||
|
|
||||||
|
TypeName playerType = cons.newInstance("io.anuke.mindustry.entities.type.Player");
|
||||||
|
//add player parameter
|
||||||
|
readMethod.addParameter(playerType, "player");
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeBlock.Builder readBlock = CodeBlock.builder(); //start building block of code inside read method
|
||||||
|
boolean started = false; //whether an if() statement has been written yet
|
||||||
|
|
||||||
|
for(MethodEntry entry : entries){
|
||||||
|
//write if check for this entry ID
|
||||||
|
if(!started){
|
||||||
|
started = true;
|
||||||
|
readBlock.beginControlFlow("if(id == " + entry.id + ")");
|
||||||
|
}else{
|
||||||
|
readBlock.nextControlFlow("else if(id == " + entry.id + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
readBlock.beginControlFlow("try");
|
||||||
|
|
||||||
|
//concatenated list of variable names for method invocation
|
||||||
|
StringBuilder varResult = new StringBuilder();
|
||||||
|
|
||||||
|
//go through each parameter
|
||||||
|
for(int i = 0; i < entry.element.getParameters().size(); i++){
|
||||||
|
VariableElement var = entry.element.getParameters().get(i);
|
||||||
|
|
||||||
|
if(!needsPlayer || i != 0){ //if client, skip first parameter since it's always of type player and doesn't need to be read
|
||||||
|
//full type name of parameter
|
||||||
|
String typeName = var.asType().toString();
|
||||||
|
//name of parameter
|
||||||
|
String varName = var.getSimpleName().toString();
|
||||||
|
//captialized version of type name for reading primitives
|
||||||
|
String capName = typeName.equals("byte") ? "" : Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
|
||||||
|
|
||||||
|
//write primitives automatically
|
||||||
|
if(Utils.isPrimitive(typeName)){
|
||||||
|
if(typeName.equals("boolean")){
|
||||||
|
readBlock.addStatement("boolean " + varName + " = buffer.get() == 1");
|
||||||
|
}else{
|
||||||
|
readBlock.addStatement(typeName + " " + varName + " = buffer.get" + capName + "()");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//else, try and find a serializer
|
||||||
|
ClassSerializer ser = serializers.get(typeName);
|
||||||
|
|
||||||
|
if(ser == null){ //make sure a serializer exists!
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "No @ReadClass method to read class type: '" + typeName + "'", var);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//add statement for reading it
|
||||||
|
readBlock.addStatement(typeName + " " + varName + " = " + ser.readMethod + "(buffer)");
|
||||||
|
}
|
||||||
|
|
||||||
|
//append variable name to string builder
|
||||||
|
varResult.append(var.getSimpleName());
|
||||||
|
if(i != entry.element.getParameters().size() - 1) varResult.append(", ");
|
||||||
|
}else{
|
||||||
|
varResult.append("player");
|
||||||
|
if(i != entry.element.getParameters().size() - 1) varResult.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//execute the relevant method before the forward
|
||||||
|
//if it throws a ValidateException, the method won't be forwarded
|
||||||
|
readBlock.addStatement("$N." + entry.element.getSimpleName() + "(" + varResult.toString() + ")", ((TypeElement)entry.element.getEnclosingElement()).getQualifiedName().toString());
|
||||||
|
|
||||||
|
//call forwarded method, don't forward on the client reader
|
||||||
|
if(entry.forward && entry.where.isServer && needsPlayer){
|
||||||
|
//call forwarded method
|
||||||
|
readBlock.addStatement(packageName + "." + entry.className + "." + entry.element.getSimpleName() +
|
||||||
|
"__forward(player.con.id" + (varResult.length() == 0 ? "" : ", ") + varResult.toString() + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
readBlock.nextControlFlow("catch (java.lang.Exception e)");
|
||||||
|
readBlock.addStatement("throw new java.lang.RuntimeException(\"Failed to to read remote method '" + entry.element.getSimpleName() + "'!\", e)");
|
||||||
|
readBlock.endControlFlow();
|
||||||
|
}
|
||||||
|
|
||||||
|
//end control flow if necessary
|
||||||
|
if(started){
|
||||||
|
readBlock.nextControlFlow("else");
|
||||||
|
readBlock.addStatement("throw new $1N(\"Invalid read method ID: \" + id + \"\")", RuntimeException.class.getName()); //handle invalid method IDs
|
||||||
|
readBlock.endControlFlow();
|
||||||
|
}
|
||||||
|
|
||||||
|
//add block and method to class
|
||||||
|
readMethod.addCode(readBlock.build());
|
||||||
|
classBuilder.addMethod(readMethod.build());
|
||||||
|
|
||||||
|
//build and write resulting class
|
||||||
|
TypeSpec spec = classBuilder.build();
|
||||||
|
JavaFile.builder(packageName, spec).build().writeTo(Utils.filer);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.*;
|
||||||
|
import io.anuke.annotations.Annotations.Loc;
|
||||||
|
import io.anuke.annotations.IOFinder.ClassSerializer;
|
||||||
|
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import javax.tools.Diagnostic.Kind;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/** Generates code for writing remote invoke packets on the client and server. */
|
||||||
|
public class RemoteWriteGenerator{
|
||||||
|
private final HashMap<String, ClassSerializer> serializers;
|
||||||
|
|
||||||
|
/** Creates a write generator that uses the supplied serializer setup. */
|
||||||
|
public RemoteWriteGenerator(HashMap<String, ClassSerializer> serializers){
|
||||||
|
this.serializers = serializers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates all classes in this list. */
|
||||||
|
public void generateFor(List<ClassEntry> entries, String packageName) throws IOException{
|
||||||
|
|
||||||
|
for(ClassEntry entry : entries){
|
||||||
|
//create builder
|
||||||
|
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(entry.name).addModifiers(Modifier.PUBLIC);
|
||||||
|
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning);
|
||||||
|
|
||||||
|
//add temporary write buffer
|
||||||
|
classBuilder.addField(FieldSpec.builder(ByteBuffer.class, "TEMP_BUFFER", Modifier.STATIC, Modifier.PRIVATE, Modifier.FINAL)
|
||||||
|
.initializer("ByteBuffer.allocate($1L)", RemoteMethodAnnotationProcessor.maxPacketSize).build());
|
||||||
|
|
||||||
|
//go through each method entry in this class
|
||||||
|
for(MethodEntry methodEntry : entry.methods){
|
||||||
|
//write the 'send event to all players' variant: always happens for clients, but only happens if 'all' is enabled on the server method
|
||||||
|
if(methodEntry.where.isClient || methodEntry.target.isAll){
|
||||||
|
writeMethodVariant(classBuilder, methodEntry, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//write the 'send event to one player' variant, which is only applicable on the server
|
||||||
|
if(methodEntry.where.isServer && methodEntry.target.isOne){
|
||||||
|
writeMethodVariant(classBuilder, methodEntry, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//write the forwarded method version
|
||||||
|
if(methodEntry.where.isServer && methodEntry.forward){
|
||||||
|
writeMethodVariant(classBuilder, methodEntry, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//build and write resulting class
|
||||||
|
TypeSpec spec = classBuilder.build();
|
||||||
|
JavaFile.builder(packageName, spec).build().writeTo(Utils.filer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a specific variant for a method entry. */
|
||||||
|
private void writeMethodVariant(TypeSpec.Builder classBuilder, MethodEntry methodEntry, boolean toAll, boolean forwarded){
|
||||||
|
ExecutableElement elem = methodEntry.element;
|
||||||
|
|
||||||
|
//create builder
|
||||||
|
MethodSpec.Builder method = MethodSpec.methodBuilder(elem.getSimpleName().toString() + (forwarded ? "__forward" : "")) //add except suffix when forwarding
|
||||||
|
.addModifiers(Modifier.STATIC, Modifier.SYNCHRONIZED)
|
||||||
|
.returns(void.class);
|
||||||
|
|
||||||
|
//forwarded methods aren't intended for use, and are not public
|
||||||
|
if(!forwarded){
|
||||||
|
method.addModifiers(Modifier.PUBLIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
//validate client methods to make sure
|
||||||
|
if(methodEntry.where.isClient){
|
||||||
|
if(elem.getParameters().isEmpty()){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "Client invoke methods must have a first parameter of type Player.", elem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!elem.getParameters().get(0).asType().toString().equals("io.anuke.mindustry.entities.type.Player")){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "Client invoke methods should have a first parameter of type Player.", elem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if toAll is false, it's a 'send to one player' variant, so add the player as a parameter
|
||||||
|
if(!toAll){
|
||||||
|
method.addParameter(int.class, "playerClientID");
|
||||||
|
}
|
||||||
|
|
||||||
|
//add sender to ignore
|
||||||
|
if(forwarded){
|
||||||
|
method.addParameter(int.class, "exceptSenderID");
|
||||||
|
}
|
||||||
|
|
||||||
|
//call local method if applicable, shouldn't happen when forwarding method as that already happens by default
|
||||||
|
if(!forwarded && methodEntry.local != Loc.none){
|
||||||
|
//add in local checks
|
||||||
|
if(methodEntry.local != Loc.both){
|
||||||
|
method.beginControlFlow("if(" + getCheckString(methodEntry.local) + " || !io.anuke.mindustry.net.Net.active())");
|
||||||
|
}
|
||||||
|
|
||||||
|
//concatenate parameters
|
||||||
|
int index = 0;
|
||||||
|
StringBuilder results = new StringBuilder();
|
||||||
|
for(VariableElement var : elem.getParameters()){
|
||||||
|
//special case: calling local-only methods uses the local player
|
||||||
|
if(index == 0 && methodEntry.where == Loc.client){
|
||||||
|
results.append("io.anuke.mindustry.Vars.player");
|
||||||
|
}else{
|
||||||
|
results.append(var.getSimpleName());
|
||||||
|
}
|
||||||
|
if(index != elem.getParameters().size() - 1) results.append(", ");
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//add the statement to call it
|
||||||
|
method.addStatement("$N." + elem.getSimpleName() + "(" + results.toString() + ")",
|
||||||
|
((TypeElement)elem.getEnclosingElement()).getQualifiedName().toString());
|
||||||
|
|
||||||
|
if(methodEntry.local != Loc.both){
|
||||||
|
method.endControlFlow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//start control flow to check if it's actually client/server so no netcode is called
|
||||||
|
method.beginControlFlow("if(" + getCheckString(methodEntry.where) + ")");
|
||||||
|
|
||||||
|
//add statement to create packet from pool
|
||||||
|
method.addStatement("$1N packet = $2N.obtain($1N.class, $1N::new)", "io.anuke.mindustry.net.Packets.InvokePacket", "io.anuke.arc.util.pooling.Pools");
|
||||||
|
//assign buffer
|
||||||
|
method.addStatement("packet.writeBuffer = TEMP_BUFFER");
|
||||||
|
//assign priority
|
||||||
|
method.addStatement("packet.priority = (byte)" + methodEntry.priority.ordinal());
|
||||||
|
//assign method ID
|
||||||
|
method.addStatement("packet.type = (byte)" + methodEntry.id);
|
||||||
|
//rewind buffer
|
||||||
|
method.addStatement("TEMP_BUFFER.position(0)");
|
||||||
|
|
||||||
|
for(int i = 0; i < elem.getParameters().size(); i++){
|
||||||
|
//first argument is skipped as it is always the player caller
|
||||||
|
if((!methodEntry.where.isServer/* || methodEntry.mode == Loc.both*/) && i == 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VariableElement var = elem.getParameters().get(i);
|
||||||
|
|
||||||
|
//add parameter to method
|
||||||
|
method.addParameter(TypeName.get(var.asType()), var.getSimpleName().toString());
|
||||||
|
|
||||||
|
//name of parameter
|
||||||
|
String varName = var.getSimpleName().toString();
|
||||||
|
//name of parameter type
|
||||||
|
String typeName = var.asType().toString();
|
||||||
|
//captialized version of type name for writing primitives
|
||||||
|
String capName = typeName.equals("byte") ? "" : Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
|
||||||
|
//special case: method can be called from anywhere to anywhere
|
||||||
|
//thus, only write the player when the SERVER is writing data, since the client is the only one who reads it
|
||||||
|
boolean writePlayerSkipCheck = methodEntry.where == Loc.both && i == 0;
|
||||||
|
|
||||||
|
if(writePlayerSkipCheck){ //write begin check
|
||||||
|
method.beginControlFlow("if(io.anuke.mindustry.net.Net.server())");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Utils.isPrimitive(typeName)){ //check if it's a primitive, and if so write it
|
||||||
|
if(typeName.equals("boolean")){ //booleans are special
|
||||||
|
method.addStatement("TEMP_BUFFER.put(" + varName + " ? (byte)1 : 0)");
|
||||||
|
}else{
|
||||||
|
method.addStatement("TEMP_BUFFER.put" +
|
||||||
|
capName + "(" + varName + ")");
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//else, try and find a serializer
|
||||||
|
ClassSerializer ser = serializers.get(typeName);
|
||||||
|
|
||||||
|
if(ser == null){ //make sure a serializer exists!
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "No @WriteClass method to write class type: '" + typeName + "'", var);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//add statement for writing it
|
||||||
|
method.addStatement(ser.writeMethod + "(TEMP_BUFFER, " + varName + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(writePlayerSkipCheck){ //write end check
|
||||||
|
method.endControlFlow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//assign packet length
|
||||||
|
method.addStatement("packet.writeLength = TEMP_BUFFER.position()");
|
||||||
|
|
||||||
|
String sendString;
|
||||||
|
|
||||||
|
if(forwarded){ //forward packet
|
||||||
|
if(!methodEntry.local.isClient){ //if the client doesn't get it called locally, forward it back after validation
|
||||||
|
sendString = "send(";
|
||||||
|
}else{
|
||||||
|
sendString = "sendExcept(exceptSenderID, ";
|
||||||
|
}
|
||||||
|
}else if(toAll){ //send to all players / to server
|
||||||
|
sendString = "send(";
|
||||||
|
}else{ //send to specific client from server
|
||||||
|
sendString = "sendTo(playerClientID, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
//send the actual packet
|
||||||
|
method.addStatement("io.anuke.mindustry.net.Net." + sendString + "packet, " +
|
||||||
|
(methodEntry.unreliable ? "io.anuke.mindustry.net.Net.SendMode.udp" : "io.anuke.mindustry.net.Net.SendMode.tcp") + ")");
|
||||||
|
|
||||||
|
|
||||||
|
//end check for server/client
|
||||||
|
method.endControlFlow();
|
||||||
|
|
||||||
|
//add method to class, finally
|
||||||
|
classBuilder.addMethod(method.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCheckString(Loc loc){
|
||||||
|
return loc.isClient && loc.isServer ? "io.anuke.mindustry.net.Net.server() || io.anuke.mindustry.net.Net.client()" :
|
||||||
|
loc.isClient ? "io.anuke.mindustry.net.Net.client()" :
|
||||||
|
loc.isServer ? "io.anuke.mindustry.net.Net.server()" : "false";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.*;
|
||||||
|
import io.anuke.annotations.Annotations.Serialize;
|
||||||
|
|
||||||
|
import javax.annotation.processing.*;
|
||||||
|
import javax.lang.model.SourceVersion;
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import javax.lang.model.util.ElementFilter;
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||||
|
@SupportedAnnotationTypes({
|
||||||
|
"io.anuke.annotations.Annotations.Serialize"
|
||||||
|
})
|
||||||
|
public class SerializeAnnotationProcessor extends AbstractProcessor{
|
||||||
|
/** Target class name. */
|
||||||
|
private static final String className = "Serialization";
|
||||||
|
/** Name of the base package to put all the generated classes. */
|
||||||
|
private static final String packageName = "io.anuke.mindustry.gen";
|
||||||
|
|
||||||
|
private int round;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void init(ProcessingEnvironment processingEnv){
|
||||||
|
super.init(processingEnv);
|
||||||
|
//put all relevant utils into utils class
|
||||||
|
Utils.typeUtils = processingEnv.getTypeUtils();
|
||||||
|
Utils.elementUtils = processingEnv.getElementUtils();
|
||||||
|
Utils.filer = processingEnv.getFiler();
|
||||||
|
Utils.messager = processingEnv.getMessager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||||
|
if(round++ != 0) return false; //only process 1 round
|
||||||
|
|
||||||
|
try{
|
||||||
|
Set<TypeElement> elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Serialize.class));
|
||||||
|
|
||||||
|
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className).addModifiers(Modifier.PUBLIC);
|
||||||
|
classBuilder.addAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "\"unchecked\"").build());
|
||||||
|
classBuilder.addJavadoc(RemoteMethodAnnotationProcessor.autogenWarning);
|
||||||
|
MethodSpec.Builder method = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||||
|
|
||||||
|
TypeName jsonType = ClassName.bestGuess("io.anuke.arc.util.serialization.Json");
|
||||||
|
TypeName jsonValueType = ClassName.bestGuess("io.anuke.arc.util.serialization.JsonValue");
|
||||||
|
TypeName ubJsonWriterType = ClassName.bestGuess("io.anuke.arc.util.serialization.UBJsonWriter");
|
||||||
|
TypeName ubJsonReaderType = ClassName.bestGuess("io.anuke.arc.util.serialization.UBJsonReader");
|
||||||
|
|
||||||
|
classBuilder.addField(jsonType, "bjson", Modifier.STATIC, Modifier.PRIVATE);
|
||||||
|
classBuilder.addField(ubJsonReaderType, "bjsonReader", Modifier.STATIC, Modifier.PRIVATE);
|
||||||
|
classBuilder.addStaticBlock(CodeBlock.builder()
|
||||||
|
.addStatement("bjson = new " + jsonType + "()")
|
||||||
|
.addStatement("bjsonReader = new " + ubJsonReaderType + "()")
|
||||||
|
.build());
|
||||||
|
|
||||||
|
for(TypeElement elem : elements){
|
||||||
|
TypeName type = TypeName.get(elem.asType());
|
||||||
|
String simpleTypeName = type.toString().substring(type.toString().lastIndexOf('.') + 1);
|
||||||
|
|
||||||
|
TypeSpec.Builder serializer = TypeSpec.anonymousClassBuilder("")
|
||||||
|
.addSuperinterface(ParameterizedTypeName.get(
|
||||||
|
ClassName.bestGuess("io.anuke.arc.Settings.TypeSerializer"), type));
|
||||||
|
|
||||||
|
MethodSpec.Builder writeMethod = MethodSpec.methodBuilder("write")
|
||||||
|
.returns(void.class)
|
||||||
|
.addParameter(DataOutput.class, "stream")
|
||||||
|
.addParameter(type, "object")
|
||||||
|
.addException(IOException.class)
|
||||||
|
.addModifiers(Modifier.PUBLIC);
|
||||||
|
|
||||||
|
MethodSpec.Builder readMethod = MethodSpec.methodBuilder("read")
|
||||||
|
.returns(type)
|
||||||
|
.addParameter(DataInput.class, "stream")
|
||||||
|
.addException(IOException.class)
|
||||||
|
.addModifiers(Modifier.PUBLIC);
|
||||||
|
|
||||||
|
MethodSpec.Builder jsonWriteMethod = MethodSpec.methodBuilder("write" + simpleTypeName + "Json")
|
||||||
|
.returns(void.class)
|
||||||
|
.addParameter(jsonType, "json")
|
||||||
|
.addParameter(type, "object")
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||||
|
|
||||||
|
MethodSpec.Builder jsonReadMethod = MethodSpec.methodBuilder("read" + simpleTypeName + "Json")
|
||||||
|
.returns(type)
|
||||||
|
.addParameter(jsonValueType, "value")
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||||
|
|
||||||
|
readMethod.addStatement("$L object = new $L()", type, type);
|
||||||
|
jsonReadMethod.addStatement("$L object = new $L()", type, type);
|
||||||
|
|
||||||
|
List<VariableElement> fields = ElementFilter.fieldsIn(Utils.elementUtils.getAllMembers(elem));
|
||||||
|
for(VariableElement field : fields){
|
||||||
|
if(field.getModifiers().contains(Modifier.STATIC) || field.getModifiers().contains(Modifier.TRANSIENT) || field.getModifiers().contains(Modifier.PRIVATE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
String name = field.getSimpleName().toString();
|
||||||
|
String typeName = Utils.typeUtils.erasure(field.asType()).toString().replace('$', '.');
|
||||||
|
String capName = Character.toUpperCase(typeName.charAt(0)) + typeName.substring(1);
|
||||||
|
|
||||||
|
if(field.asType().getKind().isPrimitive()){
|
||||||
|
writeMethod.addStatement("stream.write" + capName + "(object." + name + ")");
|
||||||
|
readMethod.addStatement("object." + name + "= stream.read" + capName + "()");
|
||||||
|
|
||||||
|
jsonWriteMethod.addStatement("json.writeValue(\"" + name + "\", object." + name + ")");
|
||||||
|
jsonReadMethod.addStatement("if(value.has(\"" + name + "\")) object." + name + "= value.get" + capName + "(\"" + name + "\")");
|
||||||
|
}else{
|
||||||
|
writeMethod.addStatement("io.anuke.arc.Core.settings.getSerializer(" + typeName + ".class).write(stream, object." + name + ")");
|
||||||
|
readMethod.addStatement("object." + name + " = (" + typeName + ")io.anuke.arc.Core.settings.getSerializer(" + typeName + ".class).read(stream)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readMethod.addStatement("return object");
|
||||||
|
jsonReadMethod.addStatement("return object");
|
||||||
|
|
||||||
|
serializer.addMethod(writeMethod.build());
|
||||||
|
serializer.addMethod(readMethod.build());
|
||||||
|
|
||||||
|
method.addStatement("io.anuke.arc.Core.settings.setSerializer($N, $L)", Utils.elementUtils.getBinaryName(elem).toString().replace('$', '.') + ".class", serializer.build());
|
||||||
|
|
||||||
|
name(writeMethod, "write" + simpleTypeName);
|
||||||
|
name(readMethod, "read" + simpleTypeName);
|
||||||
|
|
||||||
|
writeMethod.addModifiers(Modifier.STATIC);
|
||||||
|
readMethod.addModifiers(Modifier.STATIC);
|
||||||
|
|
||||||
|
classBuilder.addMethod(writeMethod.build());
|
||||||
|
classBuilder.addMethod(readMethod.build());
|
||||||
|
|
||||||
|
classBuilder.addMethod(jsonWriteMethod.build());
|
||||||
|
classBuilder.addMethod(jsonReadMethod.build());
|
||||||
|
|
||||||
|
MethodSpec.Builder binaryJsonWriteMethod = MethodSpec.methodBuilder("write" + simpleTypeName + "StreamJson")
|
||||||
|
.returns(void.class)
|
||||||
|
.addParameter(DataOutput.class, "stream")
|
||||||
|
.addParameter(type, "object")
|
||||||
|
.addException(IOException.class)
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||||
|
.addStatement("java.io.StringWriter output = new java.io.StringWriter()")
|
||||||
|
.addStatement("bjson.setWriter(output)")
|
||||||
|
.addStatement("bjson.writeObjectStart(" + type + ".class, " + type + ".class)")
|
||||||
|
.addStatement("write" + simpleTypeName + "Json(bjson, object)")
|
||||||
|
.addStatement("bjson.writeObjectEnd()")
|
||||||
|
.addStatement("stream.writeUTF(output.toString())");
|
||||||
|
|
||||||
|
MethodSpec.Builder binaryJsonReadMethod = MethodSpec.methodBuilder("read" + simpleTypeName + "StreamJson")
|
||||||
|
.returns(type)
|
||||||
|
.addParameter(DataInput.class, "stream")
|
||||||
|
.addException(IOException.class)
|
||||||
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||||
|
.addStatement("return read" + simpleTypeName + "Json(bjson.fromJson(null, stream.readUTF()))");
|
||||||
|
|
||||||
|
classBuilder.addMethod(binaryJsonWriteMethod.build());
|
||||||
|
classBuilder.addMethod(binaryJsonReadMethod.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
classBuilder.addMethod(method.build());
|
||||||
|
|
||||||
|
//write result
|
||||||
|
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void name(MethodSpec.Builder builder, String name){
|
||||||
|
try{
|
||||||
|
Field field = builder.getClass().getDeclaredField("name");
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(builder, name);
|
||||||
|
}catch(Exception e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import com.squareup.javapoet.*;
|
||||||
|
import io.anuke.annotations.Annotations.Struct;
|
||||||
|
import io.anuke.annotations.Annotations.StructField;
|
||||||
|
|
||||||
|
import javax.annotation.processing.*;
|
||||||
|
import javax.lang.model.SourceVersion;
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import javax.lang.model.type.TypeKind;
|
||||||
|
import javax.lang.model.util.ElementFilter;
|
||||||
|
import javax.tools.Diagnostic.Kind;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates ""value types"" classes that are packed into integer primitives of the most aproppriate size.
|
||||||
|
* It would be nice if Java didn't make crazy hacks like this necessary.
|
||||||
|
*/
|
||||||
|
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||||
|
@SupportedAnnotationTypes({
|
||||||
|
"io.anuke.annotations.Annotations.Struct"
|
||||||
|
})
|
||||||
|
public class StructAnnotationProcessor extends AbstractProcessor{
|
||||||
|
/** Name of the base package to put all the generated classes. */
|
||||||
|
private static final String packageName = "io.anuke.mindustry.gen";
|
||||||
|
private int round;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void init(ProcessingEnvironment processingEnv){
|
||||||
|
super.init(processingEnv);
|
||||||
|
//put all relevant utils into utils class
|
||||||
|
Utils.typeUtils = processingEnv.getTypeUtils();
|
||||||
|
Utils.elementUtils = processingEnv.getElementUtils();
|
||||||
|
Utils.filer = processingEnv.getFiler();
|
||||||
|
Utils.messager = processingEnv.getMessager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){
|
||||||
|
if(round++ != 0) return false; //only process 1 round
|
||||||
|
|
||||||
|
try{
|
||||||
|
Set<TypeElement> elements = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Struct.class));
|
||||||
|
|
||||||
|
for(TypeElement elem : elements){
|
||||||
|
|
||||||
|
if(!elem.getSimpleName().toString().endsWith("Struct")){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "All classes annotated with @Struct must have their class names end in 'Struct'.", elem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String structName = elem.getSimpleName().toString().substring(0, elem.getSimpleName().toString().length() - "Struct".length());
|
||||||
|
String structParam = structName.toLowerCase();
|
||||||
|
|
||||||
|
TypeSpec.Builder classBuilder = TypeSpec.classBuilder(structName)
|
||||||
|
.addModifiers(Modifier.FINAL, Modifier.PUBLIC);
|
||||||
|
|
||||||
|
try{
|
||||||
|
List<VariableElement> variables = ElementFilter.fieldsIn(elem.getEnclosedElements());
|
||||||
|
int structSize = variables.stream().mapToInt(StructAnnotationProcessor::varSize).sum();
|
||||||
|
int structTotalSize = (structSize <= 8 ? 8 : structSize <= 16 ? 16 : structSize <= 32 ? 32 : 64);
|
||||||
|
|
||||||
|
if(variables.size() == 0){
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, "making a struct with no fields is utterly pointles.", elem);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//obtain type which will be stored
|
||||||
|
Class<?> structType = typeForSize(structSize);
|
||||||
|
|
||||||
|
//[constructor] get(fields...) : structType
|
||||||
|
MethodSpec.Builder constructor = MethodSpec.methodBuilder("get")
|
||||||
|
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||||
|
.returns(structType);
|
||||||
|
|
||||||
|
StringBuilder cons = new StringBuilder();
|
||||||
|
StringBuilder doc = new StringBuilder();
|
||||||
|
doc.append("Bits used: ").append(structSize).append(" / ").append(structTotalSize).append("\n");
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
for(VariableElement var : variables){
|
||||||
|
int size = varSize(var);
|
||||||
|
TypeName varType = TypeName.get(var.asType());
|
||||||
|
String varName = var.getSimpleName().toString();
|
||||||
|
|
||||||
|
//add val param to constructor
|
||||||
|
constructor.addParameter(varType, varName);
|
||||||
|
|
||||||
|
//[get] field(structType) : fieldType
|
||||||
|
MethodSpec.Builder getter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
||||||
|
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||||
|
.returns(varType)
|
||||||
|
.addParameter(structType, structParam);
|
||||||
|
//[set] field(structType, fieldType) : structType
|
||||||
|
MethodSpec.Builder setter = MethodSpec.methodBuilder(var.getSimpleName().toString())
|
||||||
|
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
|
||||||
|
.returns(structType)
|
||||||
|
.addParameter(structType, structParam).addParameter(varType, "value");
|
||||||
|
|
||||||
|
//[getter]
|
||||||
|
if(varType == TypeName.BOOLEAN){
|
||||||
|
//bools: single bit, is simplified
|
||||||
|
getter.addStatement("return ($L & (1L << $L)) != 0", structParam, offset);
|
||||||
|
}else if(varType == TypeName.FLOAT){
|
||||||
|
//floats: need conversion
|
||||||
|
getter.addStatement("return Float.intBitsToFloat((int)(($L >>> $L) & $L))", structParam, offset, bitString(size, structTotalSize));
|
||||||
|
}else{
|
||||||
|
//bytes, shorts, chars, ints
|
||||||
|
getter.addStatement("return ($T)(($L >>> $L) & $L)", varType, structParam, offset, bitString(size, structTotalSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
//[setter] + [constructor building]
|
||||||
|
if(varType == TypeName.BOOLEAN){
|
||||||
|
cons.append(" | (").append(varName).append(" ? ").append("1L << ").append(offset).append("L : 0)");
|
||||||
|
|
||||||
|
//bools: single bit, needs special case to clear things
|
||||||
|
setter.beginControlFlow("if(value)");
|
||||||
|
setter.addStatement("return ($T)(($L & ~(1L << $LL)))", structType, structParam, offset);
|
||||||
|
setter.nextControlFlow("else");
|
||||||
|
setter.addStatement("return ($T)(($L & ~(1L << $LL)) | (1L << $LL))", structType, structParam, offset, offset);
|
||||||
|
setter.endControlFlow();
|
||||||
|
}else if(varType == TypeName.FLOAT){
|
||||||
|
cons.append(" | (").append("(").append(structType).append(")").append("Float.floatToIntBits(").append(varName).append(") << ").append(offset).append("L)");
|
||||||
|
|
||||||
|
//floats: need conversion
|
||||||
|
setter.addStatement("return ($T)(($L & $L) | (($T)Float.floatToIntBits(value) << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
||||||
|
}else{
|
||||||
|
cons.append(" | (((").append(structType).append(")").append(varName).append(" << ").append(offset).append("L)").append(" & ").append(bitString(offset, size, structTotalSize)).append(")");
|
||||||
|
|
||||||
|
//bytes, shorts, chars, ints
|
||||||
|
setter.addStatement("return ($T)(($L & $L) | (($T)value << $LL))", structType, structParam, bitString(offset, size, structTotalSize), structType, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
doc.append("<br> ").append(varName).append(" [").append(offset).append("..").append(size + offset).append("]\n");
|
||||||
|
|
||||||
|
//add finished methods
|
||||||
|
classBuilder.addMethod(getter.build());
|
||||||
|
classBuilder.addMethod(setter.build());
|
||||||
|
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
classBuilder.addJavadoc(doc.toString());
|
||||||
|
|
||||||
|
//add constructor final statement + add to class and build
|
||||||
|
constructor.addStatement("return ($T)($L)", structType, cons.toString().substring(3));
|
||||||
|
classBuilder.addMethod(constructor.build());
|
||||||
|
|
||||||
|
JavaFile.builder(packageName, classBuilder.build()).build().writeTo(Utils.filer);
|
||||||
|
}catch(IllegalArgumentException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
Utils.messager.printMessage(Kind.ERROR, e.getMessage(), elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}catch(Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static String bitString(int offset, int size, int totalSize){
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for(int i = 0; i < offset; i++) builder.append('0');
|
||||||
|
for(int i = 0; i < size; i++) builder.append('1');
|
||||||
|
for(int i = 0; i < totalSize - size - offset; i++) builder.append('0');
|
||||||
|
return "0b" + builder.reverse().toString() + "L";
|
||||||
|
}
|
||||||
|
|
||||||
|
static String bitString(int size, int totalSize){
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for(int i = 0; i < size; i++) builder.append('1');
|
||||||
|
for(int i = 0; i < totalSize - size; i++) builder.append('0');
|
||||||
|
return "0b" + builder.reverse().toString() + "L";
|
||||||
|
}
|
||||||
|
|
||||||
|
static int varSize(VariableElement var) throws IllegalArgumentException{
|
||||||
|
if(!var.asType().getKind().isPrimitive()){
|
||||||
|
throw new IllegalArgumentException("All struct fields must be primitives: " + var);
|
||||||
|
}
|
||||||
|
|
||||||
|
StructField an = var.getAnnotation(StructField.class);
|
||||||
|
if(var.asType().getKind() == TypeKind.BOOLEAN && an != null && an.value() != 1){
|
||||||
|
throw new IllegalArgumentException("Booleans can only be one bit long... why would you do this?");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(var.asType().getKind() == TypeKind.FLOAT && an != null && an.value() != 32){
|
||||||
|
throw new IllegalArgumentException("Float size can't be changed. Very sad.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return an == null ? typeSize(var.asType().getKind()) : an.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Class<?> typeForSize(int size) throws IllegalArgumentException{
|
||||||
|
if(size <= 8){
|
||||||
|
return byte.class;
|
||||||
|
}else if(size <= 16){
|
||||||
|
return short.class;
|
||||||
|
}else if(size <= 32){
|
||||||
|
return int.class;
|
||||||
|
}else if(size <= 64){
|
||||||
|
return long.class;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Too many fields, must fit in 64 bits. Curent size: " + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** returns a type's element size in bits. */
|
||||||
|
static int typeSize(TypeKind kind) throws IllegalArgumentException{
|
||||||
|
switch(kind){
|
||||||
|
case BOOLEAN:
|
||||||
|
return 1;
|
||||||
|
case BYTE:
|
||||||
|
return 8;
|
||||||
|
case SHORT:
|
||||||
|
return 16;
|
||||||
|
case FLOAT:
|
||||||
|
case CHAR:
|
||||||
|
case INT:
|
||||||
|
return 32;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Invalid type kind: " + kind + ". Note that doubles and longs are not supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
annotations/src/main/java/io/anuke/annotations/Utils.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package io.anuke.annotations;
|
||||||
|
|
||||||
|
import javax.annotation.processing.Filer;
|
||||||
|
import javax.annotation.processing.Messager;
|
||||||
|
import javax.lang.model.element.Element;
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
import javax.lang.model.util.Elements;
|
||||||
|
import javax.lang.model.util.Types;
|
||||||
|
|
||||||
|
public class Utils{
|
||||||
|
public static Types typeUtils;
|
||||||
|
public static Elements elementUtils;
|
||||||
|
public static Filer filer;
|
||||||
|
public static Messager messager;
|
||||||
|
|
||||||
|
public static String getMethodName(Element element){
|
||||||
|
return ((TypeElement)element.getEnclosingElement()).getQualifiedName().toString() + "." + element.getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPrimitive(String type){
|
||||||
|
return type.equals("boolean") || type.equals("byte") || type.equals("short") || type.equals("int")
|
||||||
|
|| type.equals("long") || type.equals("float") || type.equals("double") || type.equals("char");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
io.anuke.annotations.RemoteMethodAnnotationProcessor
|
||||||
|
io.anuke.annotations.SerializeAnnotationProcessor
|
||||||
|
io.anuke.annotations.StructAnnotationProcessor
|
||||||
275
build.gradle
@@ -1,35 +1,67 @@
|
|||||||
buildscript {
|
buildscript{
|
||||||
repositories {
|
repositories{
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
google()
|
google()
|
||||||
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
|
||||||
classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
|
dependencies{
|
||||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.6'
|
||||||
classpath "com.badlogicgames.gdx:gdx-tools:1.9.8"
|
classpath "com.badlogicgames.gdx:gdx-tools:1.9.9"
|
||||||
|
classpath "com.badlogicgames.packr:packr:2.1-SNAPSHOT"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects{
|
||||||
apply plugin: "eclipse"
|
|
||||||
apply plugin: "idea"
|
apply plugin: "idea"
|
||||||
|
|
||||||
version = 'release'
|
version = 'release'
|
||||||
|
|
||||||
ext {
|
ext{
|
||||||
versionNumber = '3.5'
|
versionNumber = '4'
|
||||||
versionType = 'release'
|
versionModifier = 'beta'
|
||||||
|
if(!project.hasProperty("versionType")) versionType = 'official'
|
||||||
appName = 'Mindustry'
|
appName = 'Mindustry'
|
||||||
gdxVersion = '1.9.8'
|
gdxVersion = '1.9.9'
|
||||||
aiVersion = '1.8.1'
|
roboVMVersion = '2.3.6'
|
||||||
uCoreVersion = 'c5d47cc'
|
arcHash = null
|
||||||
|
|
||||||
|
debugged = {
|
||||||
|
return new File(projectDir.parent, '../debug').exists() && !project.hasProperty("release")
|
||||||
|
}
|
||||||
|
|
||||||
|
localArc = {
|
||||||
|
return (!project.hasProperty("release")) && new File(projectDir.parent, '../Arc').exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
getArcHash = {
|
||||||
|
//get latest commit hash from gtihub since JITPack's '-snapshot' version doesn't work correctly
|
||||||
|
if(arcHash == null){
|
||||||
|
try{
|
||||||
|
arcHash = 'git ls-remote https://github.com/Anuken/Arc.git'.execute().text.split("\t")[0]
|
||||||
|
}catch(e){
|
||||||
|
e.printStackTrace()
|
||||||
|
arcHash = "-SNAPSHOT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arcHash
|
||||||
|
}
|
||||||
|
|
||||||
|
arcModule = { String name ->
|
||||||
|
if(localArc()){
|
||||||
|
return project(":Arc:$name")
|
||||||
|
}else{
|
||||||
|
//skip to last submodule
|
||||||
|
if(name.contains(':')) name = name.split(':').last()
|
||||||
|
return "com.github.Anuken.Arc:$name:${getArcHash()}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getVersionString = {
|
getVersionString = {
|
||||||
String buildVersion = getBuildVersion()
|
String buildVersion = getBuildVersion()
|
||||||
return "$versionNumber-$versionType-$buildVersion"
|
return "$versionNumber-$versionModifier-$buildVersion"
|
||||||
}
|
}
|
||||||
|
|
||||||
getBuildVersion = {
|
getBuildVersion = {
|
||||||
@@ -40,117 +72,170 @@ allprojects {
|
|||||||
getPackage = {
|
getPackage = {
|
||||||
return project.ext.mainClassName.substring(0, project.ext.mainClassName.indexOf("desktop") - 1)
|
return project.ext.mainClassName.substring(0, project.ext.mainClassName.indexOf("desktop") - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generateLocales = {
|
||||||
|
def output = 'en\n'
|
||||||
|
def bundles = new File(project(':core').projectDir, 'assets/bundles/')
|
||||||
|
bundles.listFiles().each{ other ->
|
||||||
|
if(other.name == "bundle.properties") return
|
||||||
|
output += other.name.substring("bundle".length() + 1, other.name.lastIndexOf('.')) + "\n"
|
||||||
|
}
|
||||||
|
new File(project(':core').projectDir, 'assets/locales').text = output
|
||||||
|
}
|
||||||
|
|
||||||
|
writeVersion = {
|
||||||
|
def pfile = new File(project(':core').projectDir, 'assets/version.properties')
|
||||||
|
def props = new Properties()
|
||||||
|
|
||||||
|
try{
|
||||||
|
pfile.createNewFile()
|
||||||
|
}catch(Exception ignored){
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pfile.exists()){
|
||||||
|
props.load(new FileInputStream(pfile))
|
||||||
|
|
||||||
|
String buildid = getBuildVersion()
|
||||||
|
|
||||||
|
props["type"] = versionType
|
||||||
|
props["number"] = versionNumber
|
||||||
|
props["modifier"] = versionModifier
|
||||||
|
props["build"] = buildid
|
||||||
|
|
||||||
|
props.store(pfile.newWriter(), "Autogenerated file. Do not modify.")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories{
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
maven{ url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||||
maven { url "https://oss.sonatype.org/content/repositories/releases/" }
|
maven{ url "https://oss.sonatype.org/content/repositories/releases/" }
|
||||||
maven { url 'https://jitpack.io' }
|
maven{ url 'https://jitpack.io' }
|
||||||
|
jcenter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project(":desktop") {
|
project(":desktop"){
|
||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
|
|
||||||
dependencies {
|
dependencies{
|
||||||
compile project(":core")
|
compile project(":core")
|
||||||
compile project(":kryonet")
|
compile project(":net")
|
||||||
compile "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion"
|
|
||||||
|
if(debugged()) compile project(":debug")
|
||||||
|
|
||||||
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
|
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
|
||||||
compile "com.badlogicgames.gdx:gdx-controllers-lwjgl3:$gdxVersion"
|
compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"
|
||||||
compile 'com.github.MinnDevelopment:java-discord-rpc:v1.3.2'
|
|
||||||
|
compile arcModule("backends:backend-lwjgl3")
|
||||||
|
compile 'com.github.MinnDevelopment:java-discord-rpc:v2.0.2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project(":html") {
|
project(":ios"){
|
||||||
apply plugin: "gwt"
|
|
||||||
apply plugin: "war"
|
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compile project(":core")
|
|
||||||
compile "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion"
|
|
||||||
compile "com.badlogicgames.gdx:gdx:$gdxVersion:sources"
|
|
||||||
compile "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion:sources"
|
|
||||||
compile "com.badlogicgames.gdx:gdx-ai:$aiVersion:sources"
|
|
||||||
|
|
||||||
compile "com.badlogicgames.gdx:gdx-controllers:$gdxVersion:sources"
|
|
||||||
compile "com.badlogicgames.gdx:gdx-controllers-gwt:$gdxVersion"
|
|
||||||
compile "com.badlogicgames.gdx:gdx-controllers-gwt:$gdxVersion:sources"
|
|
||||||
compile "com.sksamuel.gwt:gwt-websockets:1.0.4"
|
|
||||||
compile "com.sksamuel.gwt:gwt-websockets:1.0.4:sources"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project(":android") {
|
|
||||||
apply plugin: "android"
|
|
||||||
|
|
||||||
configurations { natives }
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation project(":core")
|
|
||||||
implementation project(":kryonet")
|
|
||||||
implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion"
|
|
||||||
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi"
|
|
||||||
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a"
|
|
||||||
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a"
|
|
||||||
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86"
|
|
||||||
natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64"
|
|
||||||
implementation "com.badlogicgames.gdx:gdx-ai:$aiVersion"
|
|
||||||
implementation "com.badlogicgames.gdx:gdx-controllers-android:$gdxVersion"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project(":core") {
|
|
||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
|
apply plugin: "robovm"
|
||||||
|
|
||||||
dependencies {
|
task incrementConfig{
|
||||||
boolean comp = System.properties["release"] == null || System.properties["release"].equals("false")
|
def vfile = file('robovm.properties')
|
||||||
|
|
||||||
if(!comp){
|
def props = new Properties()
|
||||||
println("NOTICE: Compiling release build.")
|
if(vfile.exists()){
|
||||||
}else{
|
props.load(new FileInputStream(vfile))
|
||||||
println("Compiling DEBUG build.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(new File('../uCore').exists() && comp){
|
props['app.id'] = 'io.anuke.mindustry'
|
||||||
compile project(":uCore")
|
props['app.version'] = '4.0'
|
||||||
}else{
|
props['app.mainclass'] = 'io.anuke.mindustry.IOSLauncher'
|
||||||
compile "com.github.anuken:ucore:$uCoreVersion"
|
props['app.executable'] = 'IOSLauncher'
|
||||||
}
|
props['app.name'] = 'Mindustry'
|
||||||
|
props['app.build'] = (!props.containsKey("app.build") ? 40 : props['app.build'].toInteger() + 1) + ""
|
||||||
|
props.store(vfile.newWriter(), null)
|
||||||
|
}
|
||||||
|
|
||||||
if(new File('../GDXGifRecorder').exists() && comp) {
|
dependencies{
|
||||||
compile project(":GDXGifRecorder")
|
compile project(":core")
|
||||||
}
|
compile project(":net")
|
||||||
compile "com.badlogicgames.gdx:gdx:$gdxVersion"
|
compileOnly project(":annotations")
|
||||||
compile "com.badlogicgames.gdx:gdx-ai:$aiVersion"
|
|
||||||
compile "com.badlogicgames.gdx:gdx-controllers:$gdxVersion"
|
compile arcModule("backends:backend-robovm")
|
||||||
|
|
||||||
|
compile "com.mobidevelop.robovm:robovm-rt:$roboVMVersion"
|
||||||
|
compile "com.mobidevelop.robovm:robovm-cocoatouch:$roboVMVersion"
|
||||||
|
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-ios"
|
||||||
|
compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-ios"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project(":server") {
|
project(":core"){
|
||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
|
|
||||||
dependencies {
|
task finish{
|
||||||
compile project(":core")
|
generateLocales()
|
||||||
compile project(":kryonet")
|
}
|
||||||
compile "com.badlogicgames.gdx:gdx-backend-headless:$gdxVersion"
|
|
||||||
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
|
dependencies{
|
||||||
|
compile arcModule("arc-core")
|
||||||
|
compile arcModule("extensions:freetype")
|
||||||
|
compile arcModule("extensions:arcnet")
|
||||||
|
if(localArc() && debugged()) compile arcModule("extensions:recorder")
|
||||||
|
|
||||||
|
compileOnly project(":annotations")
|
||||||
|
annotationProcessor project(":annotations")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project(":kryonet") {
|
project(":server"){
|
||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
|
|
||||||
dependencies {
|
dependencies{
|
||||||
compile project(":core")
|
compile project(":core")
|
||||||
compile 'com.github.crykn:kryonet:2.22.1'
|
compile project(":net")
|
||||||
compile "org.java-websocket:Java-WebSocket:1.3.7"
|
compile arcModule("backends:backend-headless")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.eclipse.doLast {
|
project(":tests"){
|
||||||
delete ".project"
|
apply plugin: "java"
|
||||||
|
|
||||||
|
dependencies{
|
||||||
|
testImplementation project(":core")
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-params:5.3.1"
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.1"
|
||||||
|
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.3.1"
|
||||||
|
compile arcModule("backends:backend-headless")
|
||||||
|
}
|
||||||
|
|
||||||
|
test{
|
||||||
|
useJUnitPlatform()
|
||||||
|
workingDir = new File("../core/assets")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project(":tools"){
|
||||||
|
apply plugin: "java"
|
||||||
|
|
||||||
|
dependencies{
|
||||||
|
compile project(":core")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project(":annotations"){
|
||||||
|
apply plugin: "java"
|
||||||
|
|
||||||
|
dependencies{
|
||||||
|
compile 'com.squareup:javapoet:1.11.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project(":net"){
|
||||||
|
apply plugin: "java"
|
||||||
|
|
||||||
|
dependencies{
|
||||||
|
compile project(":core")
|
||||||
|
compile "org.lz4:lz4-java:1.4.1"
|
||||||
|
compile 'com.github.Anuken:WaifUPnP:05eb46bc577fd7674596946ba288c96c0cedd893'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
core/assets-raw/fonts/Exo2-Regular.ttf
Normal file
BIN
core/assets-raw/fonts/NanumBarunGothic.ttf
Normal file
BIN
core/assets-raw/fonts/OpenSansEmoji.ttf
Normal file
BIN
core/assets-raw/fonts/font_latin.ttf
Normal file
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 128 B |
|
Before Width: | Height: | Size: 223 B |
|
Before Width: | Height: | Size: 248 B |
|
Before Width: | Height: | Size: 186 B |
|
Before Width: | Height: | Size: 196 B |
|
Before Width: | Height: | Size: 194 B |
|
Before Width: | Height: | Size: 207 B |
|
Before Width: | Height: | Size: 208 B |
|
Before Width: | Height: | Size: 206 B |
|
Before Width: | Height: | Size: 224 B |
|
Before Width: | Height: | Size: 315 B |
|
Before Width: | Height: | Size: 378 B |
|
Before Width: | Height: | Size: 172 B |
|
Before Width: | Height: | Size: 182 B |
|
Before Width: | Height: | Size: 281 B |
|
Before Width: | Height: | Size: 514 B |
|
Before Width: | Height: | Size: 258 B |
|
Before Width: | Height: | Size: 237 B |
|
Before Width: | Height: | Size: 256 B |
|
Before Width: | Height: | Size: 253 B |
|
Before Width: | Height: | Size: 304 B |
|
Before Width: | Height: | Size: 300 B |
|
Before Width: | Height: | Size: 274 B |
|
Before Width: | Height: | Size: 254 B |
|
Before Width: | Height: | Size: 290 B |
|
Before Width: | Height: | Size: 222 B |
|
Before Width: | Height: | Size: 199 B |
|
Before Width: | Height: | Size: 171 B |
|
Before Width: | Height: | Size: 191 B |
|
Before Width: | Height: | Size: 195 B |
|
Before Width: | Height: | Size: 195 B |
|
Before Width: | Height: | Size: 246 B |
|
Before Width: | Height: | Size: 575 B |