Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61597cb83d | ||
|
|
2f17552b2c | ||
|
|
f2d3d24338 | ||
|
|
e8a64f52f0 | ||
|
|
f55fe0fc45 | ||
|
|
1e3a5f9515 | ||
|
|
a9c7eb0954 | ||
|
|
289472d8ba | ||
|
|
f191e80100 | ||
|
|
607248e8b3 | ||
|
|
cecabe5bc4 | ||
|
|
947a2e3d91 | ||
|
|
382e0f3b1d | ||
|
|
6e440783dc | ||
|
|
fcd7d8ba83 | ||
|
|
a53d2a1370 | ||
|
|
20148d0b02 | ||
|
|
3114e33067 | ||
|
|
e137d72b76 | ||
|
|
cc087dee81 | ||
|
|
eed475cb28 | ||
|
|
d07c45f0b5 | ||
|
|
0aa0fa1b78 | ||
|
|
e91ec13dbd | ||
|
|
e36105d937 | ||
|
|
07d4df312d | ||
|
|
b521c5b76a | ||
|
|
c1596443f5 | ||
|
|
cadeb1f59c | ||
|
|
2d4223f7ed | ||
|
|
c453bbc7cd | ||
|
|
2184961e3c | ||
|
|
8afd8bde8b | ||
|
|
65952a5d81 | ||
|
|
ac1f2ec1ed | ||
|
|
454cc1e702 | ||
|
|
e3fa7428bf | ||
|
|
7ece35e28a | ||
|
|
d22dae9834 | ||
|
|
63bd707741 | ||
|
|
734c1e14f0 | ||
|
|
46869ad5f7 | ||
|
|
13fa713d58 | ||
|
|
94cd33af5c | ||
|
|
7efd9607e5 | ||
|
|
94539ad77b | ||
|
|
f2a86857bc | ||
|
|
3f2be63d08 | ||
|
|
2d7c1393d6 | ||
|
|
3d33230e25 | ||
|
|
dd4683e693 | ||
|
|
8bc5d2112f | ||
|
|
a828896989 | ||
|
|
5e8734aa95 | ||
|
|
1ac844f398 | ||
|
|
3f85ac208c | ||
|
|
c191186023 | ||
|
|
4715a95a54 | ||
|
|
8108f11c45 | ||
|
|
f4f1850271 | ||
|
|
5a81972f68 | ||
|
|
674dfca34d | ||
|
|
cafcb74e22 | ||
|
|
88c595dab2 | ||
|
|
48e2fcc601 | ||
|
|
2f10948239 | ||
|
|
7f674f237b | ||
|
|
c3f19d2c4a | ||
|
|
94b2cafa7a | ||
|
|
1d66ebef58 | ||
|
|
66459a124c | ||
|
|
5bbb565bd4 | ||
|
|
58819b6361 | ||
|
|
2de6a45ca1 | ||
|
|
c60261d917 | ||
|
|
94b6d7596e | ||
|
|
ae63b9712e | ||
|
|
00b945f6e3 | ||
|
|
37c47fc2dc | ||
|
|
51325d2423 | ||
|
|
469a7df4d4 | ||
|
|
ec56e24b7e | ||
|
|
00c350cd82 | ||
|
|
55d78aeba7 | ||
|
|
85c01cde00 | ||
|
|
4ce0a83845 | ||
|
|
d6859d1956 | ||
|
|
61447f0964 | ||
|
|
22a02faced | ||
|
|
a60c288335 | ||
|
|
3c224198e7 | ||
|
|
dc03f28d56 | ||
|
|
bd18355a1a | ||
|
|
1208d6dabc | ||
|
|
63082f5a5e | ||
|
|
c24ef2a200 | ||
|
|
891b64ee0f | ||
|
|
82763f3c32 | ||
|
|
3119b4d88d | ||
|
|
6532dc72db | ||
|
|
fd24fcc0f2 | ||
|
|
0d3e204f0d | ||
|
|
64d9fa7c6b | ||
|
|
53ff657106 | ||
|
|
6eb0c16fcc | ||
|
|
0984c23253 | ||
|
|
5805914ebb | ||
|
|
bfb55a3813 | ||
|
|
476c41b29b | ||
|
|
a2ef477ae0 | ||
|
|
42d42e9750 | ||
|
|
182e8ba2e8 | ||
|
|
e6d11fe9a3 | ||
|
|
7c510f9fb8 | ||
|
|
b53a3ebcc2 | ||
|
|
8e9f706d37 | ||
|
|
8997895a82 | ||
|
|
94db91b7c1 | ||
|
|
4f70465395 | ||
|
|
b2693cd3f9 | ||
|
|
3ae1c3467b | ||
|
|
1bba1b427c | ||
|
|
63e2fdf56d | ||
|
|
cf1b91ec55 | ||
|
|
4bac9380d1 | ||
|
|
fec5c9a5ce | ||
|
|
810ea9ace9 | ||
|
|
b933938f1b | ||
|
|
c408cccd35 | ||
|
|
bc842437fa | ||
|
|
9bda50f66e | ||
|
|
886ebe6885 | ||
|
|
d574d8d78b | ||
|
|
a3b74e0c75 | ||
|
|
eb9d123176 | ||
|
|
383de6cb2e | ||
|
|
43de254a98 | ||
|
|
02cb2a3fb1 | ||
|
|
62b6c07401 | ||
|
|
e630c6dff7 | ||
|
|
0639d82914 | ||
|
|
2701a84b94 | ||
|
|
859da37d71 | ||
|
|
5893eae87f | ||
|
|
99f42db370 | ||
|
|
32e9076198 | ||
|
|
e1cacad6b8 | ||
|
|
02ce950020 | ||
|
|
1eeba344f7 | ||
|
|
f84c4310f9 | ||
|
|
97e8ff91ea | ||
|
|
1c865e3d8d | ||
|
|
6ca7a86189 | ||
|
|
3c716ea170 | ||
|
|
3a7800db61 | ||
|
|
b04430528e | ||
|
|
4382326dec | ||
|
|
5adbac3cc9 | ||
|
|
d8b84a2574 | ||
|
|
0d59e52ff9 | ||
|
|
feb30a7349 | ||
|
|
3082e4cd16 | ||
|
|
c28dfd0ae0 | ||
|
|
986a430e92 | ||
|
|
80f27f5ea4 | ||
|
|
4c44a3c410 | ||
|
|
14cfd6abeb | ||
|
|
b957ca1931 | ||
|
|
9372d818a5 | ||
|
|
aee9c9bb32 | ||
|
|
5ed42d1654 | ||
|
|
dd94d2254f | ||
|
|
bf4c831047 | ||
|
|
33df069803 | ||
|
|
c360a4abb0 | ||
|
|
d29a198f7f | ||
|
|
8df651c5a8 | ||
|
|
191b88ab2a | ||
|
|
d00b269786 | ||
|
|
cbc85dd99e | ||
|
|
cf25e6c27b | ||
|
|
76807e1cd2 | ||
|
|
d84877dfcc | ||
|
|
f38d3b0026 | ||
|
|
511b555255 | ||
|
|
e79206bcb6 | ||
|
|
d8fa97e8c7 | ||
|
|
be2b55cc67 | ||
|
|
e68a3c7cd4 | ||
|
|
b3bf9d5c94 | ||
|
|
e166651fe7 | ||
|
|
516c73ee15 | ||
|
|
ac532c9400 | ||
|
|
b2f6ef72c3 | ||
|
|
3e2bb9678d | ||
|
|
0074f12a14 | ||
|
|
6a982b2a5c | ||
|
|
bde76707f3 | ||
|
|
2bc7bdba8a | ||
|
|
2e4f6ce076 | ||
|
|
5d3a382d26 | ||
|
|
ee8be3166f | ||
|
|
8fd500e931 | ||
|
|
2b9f070279 | ||
|
|
a53603dbbf | ||
|
|
4332bc124e | ||
|
|
20d0a2ae62 | ||
|
|
646bfa5be7 | ||
|
|
16d92454f4 | ||
|
|
129ce9a545 | ||
|
|
7b6a96b4b6 | ||
|
|
7260ae9b5e | ||
|
|
d333f54430 | ||
|
|
3efec78732 | ||
|
|
4f51ab00a1 | ||
|
|
6857200d75 | ||
|
|
1c3b3bf050 | ||
|
|
e11a5389c6 | ||
|
|
120238b234 | ||
|
|
c093c6e23d | ||
|
|
11d47bf9b1 | ||
|
|
fa13b1fc0d | ||
|
|
334e93196b | ||
|
|
de6cdeab52 | ||
|
|
24a6c2d3ba | ||
|
|
58cdc68b6e | ||
|
|
7389e210a7 | ||
|
|
b117769711 | ||
|
|
1ca4045a2f | ||
|
|
fb4a499fe9 | ||
|
|
4aac45f3b4 | ||
|
|
506786e932 | ||
|
|
1726cc7ec7 | ||
|
|
5b1c72ad5c | ||
|
|
0fa324452f | ||
|
|
6ad5ba3736 | ||
|
|
5707e1d57e | ||
|
|
f3424e0796 | ||
|
|
0b0118446f | ||
|
|
5c19dcd208 | ||
|
|
0a68e52fca | ||
|
|
5c25ab3eda | ||
|
|
91682aeafa | ||
|
|
cd9180c69a | ||
|
|
3269841207 | ||
|
|
b4ec71d65f | ||
|
|
1a0be11ae3 | ||
|
|
b72d42a09a | ||
|
|
ed5e225cdc | ||
|
|
c26579bebd | ||
|
|
1ea9170b2e | ||
|
|
a144a5eee0 | ||
|
|
1b1f532988 | ||
|
|
ca577475fc | ||
|
|
bc4b41e8cd | ||
|
|
a1226012ff | ||
|
|
cfd51915d3 | ||
|
|
030d54bc5c | ||
|
|
97a5d7e71a | ||
|
|
8b16e8be4d | ||
|
|
89dbc1be4a | ||
|
|
25bc8f5cb3 | ||
|
|
37d62b665e | ||
|
|
aa2838d219 | ||
|
|
979e58edf1 | ||
|
|
0f72d98067 | ||
|
|
eea401f99d | ||
|
|
b1301dcdec | ||
|
|
bdb6784a9b | ||
|
|
0d906e0adf | ||
|
|
4923370897 | ||
|
|
bdee33456b | ||
|
|
5a8446524a | ||
|
|
7c75e3d4a0 | ||
|
|
e67a1d16f5 | ||
|
|
b864ea89d7 | ||
|
|
04aa257b48 | ||
|
|
1b466eb33f | ||
|
|
a162828f0a | ||
|
|
b154871207 | ||
|
|
c7e3639155 | ||
|
|
9c1905bb51 | ||
|
|
31e39900b6 | ||
|
|
2b604bfd93 | ||
|
|
29f138ab94 | ||
|
|
8325021f9d | ||
|
|
25e4fa3834 | ||
|
|
9849b5659b | ||
|
|
43428c054a | ||
|
|
1d579c52eb | ||
|
|
214ff9de94 | ||
|
|
bb2e74009e | ||
|
|
53366ee284 | ||
|
|
8ec9a7a218 | ||
|
|
f3434fe2a8 | ||
|
|
acda1952ca | ||
|
|
084b15e113 | ||
|
|
d6d8c60e5b | ||
|
|
d3f24f0147 | ||
|
|
30499aa623 | ||
|
|
20d5957331 | ||
|
|
d859eeeb19 | ||
|
|
076733e6ce | ||
|
|
8fab4349bf | ||
|
|
829d92c8bb | ||
|
|
71131dadb7 | ||
|
|
61abed04f3 | ||
|
|
6e79d287f3 | ||
|
|
30f8657174 | ||
|
|
f516854226 | ||
|
|
0cee859e15 | ||
|
|
7b987c9b95 | ||
|
|
8cdd8b3f70 | ||
|
|
956b4e4a6a | ||
|
|
4e0ffc8d1e | ||
|
|
177935241f | ||
|
|
f133fcf66c | ||
|
|
869f57cbf1 | ||
|
|
de7c2e4f07 | ||
|
|
8bc2650f7b | ||
|
|
cef9f0b2bb | ||
|
|
e36b28c957 | ||
|
|
a770a7ee5c | ||
|
|
e3e9a19f6f | ||
|
|
4772a144ae | ||
|
|
d32ba75d5f | ||
|
|
96f869278b | ||
|
|
df1f9c76ad | ||
|
|
0b934bf6b5 | ||
|
|
f5319fa94c | ||
|
|
28229471f4 | ||
|
|
d00c61b89f | ||
|
|
1f7d3591b9 | ||
|
|
4e537de894 | ||
|
|
e130a14ebe | ||
|
|
31aa2f3a27 | ||
|
|
1f9c94dbc4 | ||
|
|
a2540c2e9b | ||
|
|
4737240c91 | ||
|
|
944d88b8af | ||
|
|
529c4ed420 | ||
|
|
e0ebb02530 | ||
|
|
be22d55cec | ||
|
|
993ce660aa | ||
|
|
79e120dd74 | ||
|
|
d4155bc14d | ||
|
|
ba699c4ed5 | ||
|
|
bc96afd0cd | ||
|
|
cf1a66e858 | ||
|
|
5eba896e6d | ||
|
|
e69d149c34 | ||
|
|
2f9955febd | ||
|
|
df39be708f | ||
|
|
ce3b9e3b1f | ||
|
|
a9feb65fc8 | ||
|
|
93837a28fa | ||
|
|
678f3b8eb7 | ||
|
|
0833fa9e7d | ||
|
|
369b9bb6cf | ||
|
|
c9b6f2f62f | ||
|
|
e2787af044 | ||
|
|
30c27bbb67 | ||
|
|
7aee7e33d0 | ||
|
|
a26061c388 | ||
|
|
11e66ac13c | ||
|
|
a2ac3c1f18 | ||
|
|
e7142e4032 | ||
|
|
0dd9dc6c17 | ||
|
|
a53bfed060 | ||
|
|
c5919f2719 | ||
|
|
fb24516b90 | ||
|
|
60fa4eb0a1 | ||
|
|
536576084d | ||
|
|
c62cc499c5 | ||
|
|
c11bbf8836 | ||
|
|
71c0cede24 | ||
|
|
ad16bbc96d | ||
|
|
520ffe4c09 | ||
|
|
e3f603c145 | ||
|
|
880b8cb072 | ||
|
|
86bf3d473a | ||
|
|
eb6baa8ad1 | ||
|
|
d53d56d93a | ||
|
|
d143ff48fa | ||
|
|
b11acb7762 | ||
|
|
51aa0dd851 | ||
|
|
861b0a1c62 | ||
|
|
27a33f567f | ||
|
|
e862a4b46b | ||
|
|
2b3e8ebfc0 | ||
|
|
6118877ad6 | ||
|
|
0454ff9bf7 | ||
|
|
4faad50d99 | ||
|
|
272599b448 | ||
|
|
c12d76e2fa | ||
|
|
55550f1773 | ||
|
|
e8992d5ad7 | ||
|
|
a8bd589b18 | ||
|
|
602cf7b110 | ||
|
|
1e7b731485 | ||
|
|
824b8e410c | ||
|
|
ba47953485 | ||
|
|
c7e666261f | ||
|
|
0c4c98d2c9 | ||
|
|
0c63be37bb | ||
|
|
9623a311a0 | ||
|
|
13da61d895 | ||
|
|
a7c02e2dea | ||
|
|
cfb9610afc | ||
|
|
a141c6b137 | ||
|
|
300efb99d2 | ||
|
|
6fb3610bcc | ||
|
|
43fb3ca10a | ||
|
|
adc360eaaa | ||
|
|
5e659352d7 | ||
|
|
6595e0a3cf | ||
|
|
c43b2b3bb9 | ||
|
|
ea19e6efd8 | ||
|
|
55d38f2b36 | ||
|
|
e0abf3e0c1 | ||
|
|
974cba8dee | ||
|
|
019cf5fc8f | ||
|
|
1956ba7a73 | ||
|
|
c209617ee7 | ||
|
|
f4b5e061a4 | ||
|
|
06b67a4b9a | ||
|
|
a385265956 | ||
|
|
6ac32a40c7 | ||
|
|
20c612c660 | ||
|
|
7e8cc5fe6c | ||
|
|
9ed14b227b | ||
|
|
ee466d0f4c | ||
|
|
b198eea9e4 | ||
|
|
8c7580488e | ||
|
|
3f4364c67c | ||
|
|
23e2df5e58 | ||
|
|
79136db162 | ||
|
|
3d008dcab5 | ||
|
|
5953cc6411 | ||
|
|
2dce675fe2 | ||
|
|
aa013a86dd | ||
|
|
f866f692e2 | ||
|
|
68a2514cef | ||
|
|
32562d7435 | ||
|
|
78be1aaa7c | ||
|
|
1eb4b1ca9e | ||
|
|
bf37db2cbe | ||
|
|
5b30617a6b | ||
|
|
266c686a3a | ||
|
|
32d0d6a7ee | ||
|
|
d9a336e50b | ||
|
|
3c958d06c8 | ||
|
|
15a75a69b3 | ||
|
|
cae32cff4c | ||
|
|
eeef76594f | ||
|
|
8f2a1030bc | ||
|
|
dc1df98277 | ||
|
|
def45cc3e4 | ||
|
|
8007f1958e | ||
|
|
b22e724a3f | ||
|
|
ed66b016db | ||
|
|
34890f21b3 | ||
|
|
9f85e4a63b | ||
|
|
7fcd4d94a6 | ||
|
|
84fbca7905 | ||
|
|
9add2387b9 | ||
|
|
a388450f94 | ||
|
|
fff7abc2ac | ||
|
|
e5587418c7 | ||
|
|
7c89fac1e9 | ||
|
|
bc9a9ffb72 | ||
|
|
46d27a04a2 | ||
|
|
0f33981c96 | ||
|
|
b396e0b208 | ||
|
|
1bf2f17538 | ||
|
|
608a531655 | ||
|
|
e57180eb15 | ||
|
|
3ae826d9ca | ||
|
|
e940845c60 | ||
|
|
d8aa989cc4 | ||
|
|
31ed4268b6 | ||
|
|
c698eaac6f | ||
|
|
d0dd23fa14 | ||
|
|
c6f1aa21c5 | ||
|
|
a3dc7798e7 | ||
|
|
88f6fd1965 | ||
|
|
9062c2e447 | ||
|
|
e3d2a4bf9d | ||
|
|
c2d609cdb4 | ||
|
|
b3721e29c6 | ||
|
|
eab4463c2d | ||
|
|
394873864f | ||
|
|
758216245f | ||
|
|
6edfd112a2 | ||
|
|
625215b068 | ||
|
|
4759e4957c | ||
|
|
b62f9494ae | ||
|
|
12b47e7d51 | ||
|
|
9ced29aa93 | ||
|
|
5095640ba2 | ||
|
|
c889d7cb3f | ||
|
|
84636f3f50 | ||
|
|
9a6f07d7c9 | ||
|
|
e8f5088049 | ||
|
|
0bee306d67 | ||
|
|
8d75b2d413 | ||
|
|
426ea607e8 | ||
|
|
507cade50d | ||
|
|
f0c7f54cc6 | ||
|
|
62c38482f6 | ||
|
|
0ff6ca18ed | ||
|
|
bbe6c388a3 | ||
|
|
639bc58e84 | ||
|
|
c0bcafd747 | ||
|
|
bcaa019551 | ||
|
|
38725abc48 | ||
|
|
00f1173bac | ||
|
|
68a02966d0 | ||
|
|
4721fcea66 | ||
|
|
5ea63273be | ||
|
|
7cee25aab2 | ||
|
|
9298f5e030 | ||
|
|
93f943d40c | ||
|
|
f20c11a4e2 | ||
|
|
0c25f31493 | ||
|
|
8d774e267f | ||
|
|
6c1de5d485 | ||
|
|
77c86ed3bc | ||
|
|
d75c3bbf96 | ||
|
|
8bb6cb714c | ||
|
|
28d002f6d3 | ||
|
|
78fcc69d29 | ||
|
|
cdfae54ab9 | ||
|
|
0813211c20 | ||
|
|
056a4eead2 | ||
|
|
2635d31425 | ||
|
|
76d35af5b9 | ||
|
|
bcff1695d3 | ||
|
|
3d04447c2f | ||
|
|
2736b88a10 | ||
|
|
0804a2fbf8 | ||
|
|
7224ed6a7d | ||
|
|
c41737364c | ||
|
|
320e579844 | ||
|
|
fc3f2e045b | ||
|
|
481b47bf10 | ||
|
|
0fb87f0b1d | ||
|
|
1252d7700f | ||
|
|
30c2d88f62 | ||
|
|
718a98d7ec | ||
|
|
fb3ba220b6 | ||
|
|
d655c9ec6b | ||
|
|
8a67f33cf6 | ||
|
|
2e53688c52 | ||
|
|
11ce04fba4 | ||
|
|
8b191e4a3b | ||
|
|
6405263616 | ||
|
|
a2119ab008 | ||
|
|
b21d8f094a | ||
|
|
90c41a83b1 | ||
|
|
a1ec774089 | ||
|
|
631056064a | ||
|
|
97e90de71e | ||
|
|
bbaed35160 | ||
|
|
778f26d55f | ||
|
|
fab5bdc2e1 | ||
|
|
b7723a88c3 | ||
|
|
1d2b59d5a2 | ||
|
|
7d42c0f581 | ||
|
|
bfe7398e17 | ||
|
|
c4f0a6a197 | ||
|
|
1ca9d0fa2c | ||
|
|
a015585bd1 | ||
|
|
bc34427793 | ||
|
|
0fe867cd93 | ||
|
|
70f0393bde | ||
|
|
9f060be3fd | ||
|
|
176968d883 | ||
|
|
e6bd55aa69 | ||
|
|
f5ffa875b8 | ||
|
|
2cb23cbfcb | ||
|
|
31dc9b0925 | ||
|
|
af7cd9a821 | ||
|
|
b34a64f425 | ||
|
|
11820e31a8 | ||
|
|
672b6054a6 | ||
|
|
d2486732d2 | ||
|
|
924067e4dd | ||
|
|
7820f748a0 | ||
|
|
e8757deb0d | ||
|
|
c371924dc0 | ||
|
|
cf28b27d50 | ||
|
|
b78f9c8cd5 | ||
|
|
91bd67dc26 | ||
|
|
0671b49c98 | ||
|
|
900f483a03 | ||
|
|
4d7af2e68b | ||
|
|
db59dcea65 | ||
|
|
ef6cfa785f | ||
|
|
2b792e73c9 | ||
|
|
0f2922dab4 | ||
|
|
45b55e2853 | ||
|
|
9c7795687f | ||
|
|
b273c80a02 | ||
|
|
8cdab4710b | ||
|
|
ea5b31d537 | ||
|
|
bb0c11fa12 | ||
|
|
37186439cb | ||
|
|
ab9f93d68e | ||
|
|
ca6920e82a | ||
|
|
d9db108a31 | ||
|
|
34b7e1d582 | ||
|
|
4d73187376 | ||
|
|
dcd0a42705 | ||
|
|
1b40916046 | ||
|
|
a4e4782f2f | ||
|
|
875b0c27ef | ||
|
|
a38a1775a0 | ||
|
|
fd6ae986c3 | ||
|
|
74a87e65c8 | ||
|
|
a285d2c27d | ||
|
|
44ac3bc900 | ||
|
|
1c346c97a8 | ||
|
|
d890b41380 | ||
|
|
cbcc89b48f | ||
|
|
521bd00a70 | ||
|
|
b4693423ef | ||
|
|
594a2741d7 | ||
|
|
a1d9b52b9d | ||
|
|
c9d825b6c1 | ||
|
|
7dcd0eb616 | ||
|
|
e79a95b885 | ||
|
|
5d232c3f5e | ||
|
|
ee1c0d362d | ||
|
|
aafcd57c82 | ||
|
|
66a4566dc5 | ||
|
|
4c317f5b03 | ||
|
|
12d706a812 | ||
|
|
c006068580 | ||
|
|
f8a838506d | ||
|
|
270844bbb1 | ||
|
|
c9466cf8ef | ||
|
|
7d6f1f98f1 | ||
|
|
fb9418dead | ||
|
|
4a1b06b80c | ||
|
|
8905f2e855 | ||
|
|
6c74364fa5 | ||
|
|
f0720c1755 | ||
|
|
f1acc1d2c1 | ||
|
|
82bddbfa6e | ||
|
|
841755fe56 | ||
|
|
340ee751e8 | ||
|
|
cf70f72f9c | ||
|
|
16ea88a659 | ||
|
|
eaa6790013 | ||
|
|
af571d533d | ||
|
|
004c3c588a | ||
|
|
2a44167c22 | ||
|
|
cf6b735026 | ||
|
|
5918b04b48 | ||
|
|
8004cb3a64 | ||
|
|
9981423927 | ||
|
|
0e5250dfb3 | ||
|
|
2dc956b357 | ||
|
|
b8bd0a08e0 | ||
|
|
fb31eebcf2 | ||
|
|
3c8689a3f1 | ||
|
|
2957d66dd6 | ||
|
|
6f6efe0874 | ||
|
|
355fc04069 | ||
|
|
b4738f383b | ||
|
|
b12711969c | ||
|
|
94727353c4 | ||
|
|
5eb7449b74 | ||
|
|
dae41dfb30 | ||
|
|
07a701e572 | ||
|
|
5323aaed6d | ||
|
|
daf659373f | ||
|
|
0eb81c29df | ||
|
|
8aea89c103 | ||
|
|
f1d97454c2 | ||
|
|
ffb6a45e28 | ||
|
|
f0d1c9b361 | ||
|
|
aedd4c290e | ||
|
|
749ecfe37f | ||
|
|
c51da28e31 | ||
|
|
f3dca75a10 | ||
|
|
c3dcb0292c | ||
|
|
2a42ecda78 | ||
|
|
08be1896ee | ||
|
|
6b3152c4b5 | ||
|
|
19ea27dece | ||
|
|
b9e26a4112 | ||
|
|
a71aea8e43 | ||
|
|
1b1f22b9fa | ||
|
|
705a5659b6 | ||
|
|
4121921aca | ||
|
|
8cb4ca0e8b | ||
|
|
6205937a10 | ||
|
|
2f522b744f | ||
|
|
b8a84f831a | ||
|
|
5f9490d780 | ||
|
|
a1c5b87b55 | ||
|
|
641e308c53 | ||
|
|
64bc70a15d | ||
|
|
acadbdb5c9 | ||
|
|
3323ea2be0 | ||
|
|
45f55b2075 | ||
|
|
372005dae1 | ||
|
|
2c7ca6d354 | ||
|
|
e21f315239 | ||
|
|
223c2bc7c7 | ||
|
|
3facbba4ee | ||
|
|
b8bf56c8c3 | ||
|
|
2fa08e0a70 | ||
|
|
8e1e13058b | ||
|
|
92520e46a3 | ||
|
|
6ae6c9c971 | ||
|
|
caf85d2a92 | ||
|
|
030b577dee | ||
|
|
83516ba679 | ||
|
|
c8f74ee8e3 | ||
|
|
c50e41ab91 | ||
|
|
c03a0feb75 | ||
|
|
7da5b8fbc8 | ||
|
|
83f7e61d37 | ||
|
|
86765275c8 | ||
|
|
a01e15d841 | ||
|
|
5e5db332d0 | ||
|
|
2de2f45124 | ||
|
|
b1b3eb9369 | ||
|
|
507665cd91 | ||
|
|
c779172cc2 | ||
|
|
684813e131 | ||
|
|
76ef47efc4 | ||
|
|
71a8fa0e66 | ||
|
|
48d98b2424 | ||
|
|
5a0e17b121 | ||
|
|
5f686f7205 | ||
|
|
518969d2f2 | ||
|
|
01ff1327f7 | ||
|
|
4d366397a8 | ||
|
|
80f79d20a5 | ||
|
|
1611d11544 | ||
|
|
c8e8b25c85 | ||
|
|
92cfc3c1d3 | ||
|
|
c4cebe72b4 | ||
|
|
6d346a3ad6 | ||
|
|
6e2696dea3 | ||
|
|
ba67c968cf | ||
|
|
332719f49a | ||
|
|
fb18975c5c | ||
|
|
08a7c27353 | ||
|
|
4c9cb99a94 | ||
|
|
cbecca5f55 | ||
|
|
4a0831a155 | ||
|
|
fa38c53915 | ||
|
|
e7c2170ce3 | ||
|
|
9b69fe8c56 | ||
|
|
ed91771594 | ||
|
|
b33e014f71 | ||
|
|
19632ac162 | ||
|
|
74e3a9e2d1 | ||
|
|
b15291dc57 | ||
|
|
1b5d4c1b42 | ||
|
|
923924638e | ||
|
|
8b52c46664 | ||
|
|
aa8c386cdd | ||
|
|
bafe17107c | ||
|
|
9c169fb560 | ||
|
|
61ab8a6769 | ||
|
|
b1cd7057db | ||
|
|
d426952d47 | ||
|
|
67b6a60382 | ||
|
|
9d5da5a39d | ||
|
|
efb14572d6 | ||
|
|
bc3ae5cc7d | ||
|
|
9752dea0e1 | ||
|
|
9afdc99157 | ||
|
|
07febc18d4 | ||
|
|
68fdfb36fd | ||
|
|
09287f9c72 | ||
|
|
4a5ac1b899 | ||
|
|
afad520669 | ||
|
|
9950bef260 | ||
|
|
1753b4d27e | ||
|
|
2bfc85b18f | ||
|
|
24f3dec453 | ||
|
|
4e6237c062 | ||
|
|
5cbde9cc33 | ||
|
|
25d79a94f8 | ||
|
|
a5997be9c4 | ||
|
|
c679667079 | ||
|
|
6b311c679d | ||
|
|
0f1f881367 | ||
|
|
090665528f | ||
|
|
387beb8484 | ||
|
|
daa1a38a63 | ||
|
|
d8a34aac1c | ||
|
|
ce9d882c9f | ||
|
|
84c18c8693 | ||
|
|
9360854150 | ||
|
|
ada63f1452 | ||
|
|
c3cd0dd8a0 | ||
|
|
60143d5299 | ||
|
|
1019c891e2 | ||
|
|
1392ad413a | ||
|
|
61aee90c8d | ||
|
|
19725012fb | ||
|
|
94a71dc88f | ||
|
|
d8cb93c36a | ||
|
|
151097a884 | ||
|
|
e97bad88c6 | ||
|
|
9f494a35ec | ||
|
|
d9d20c969a | ||
|
|
7e08cfedd6 | ||
|
|
1145e31162 | ||
|
|
e4e521c2ef | ||
|
|
d01c9a425a | ||
|
|
a9be348ddf | ||
|
|
07079ee295 | ||
|
|
eb1bab453b | ||
|
|
fd3c496a3d | ||
|
|
35e1e0bdd4 | ||
|
|
28aa137dc1 | ||
|
|
16ee0a040a | ||
|
|
437391a860 | ||
|
|
f61181438f | ||
|
|
d74ab35279 | ||
|
|
bbc2b251dd | ||
|
|
222e39dc48 | ||
|
|
f5b310d959 | ||
|
|
5fb0035b2f | ||
|
|
b8793f7575 | ||
|
|
5c5f091769 | ||
|
|
cf6485aea8 | ||
|
|
f2f0c96e62 | ||
|
|
64e7cc74b2 | ||
|
|
531fd87ff3 | ||
|
|
efa280b839 | ||
|
|
b3d84c4f99 | ||
|
|
015a1e3482 | ||
|
|
5efc8d6fa9 | ||
|
|
bb1654828f | ||
|
|
93cabde9f4 | ||
|
|
aeb5eb9129 | ||
|
|
e9e8b8a1ad | ||
|
|
08564e5ea2 | ||
|
|
1695619ef5 | ||
|
|
8f2f57c543 | ||
|
|
60454c6af3 | ||
|
|
40c7c72973 | ||
|
|
f9127272b1 | ||
|
|
ec295664d9 | ||
|
|
ec2b9b19be | ||
|
|
1566e069ed | ||
|
|
9c149f3529 | ||
|
|
2f35baef39 | ||
|
|
7c77c317df | ||
|
|
ed3a04d531 | ||
|
|
c3ec7741dc | ||
|
|
f4f89fac1f | ||
|
|
5262150d3c | ||
|
|
b5f56eb2b5 | ||
|
|
9a375fd0d1 | ||
|
|
6ca4aeb5a2 | ||
|
|
8ed4a9a5f2 | ||
|
|
a4578405cf | ||
|
|
73f147b7e2 | ||
|
|
5c3d735315 | ||
|
|
200621996d | ||
|
|
a912a0a07e | ||
|
|
4146ceb048 | ||
|
|
ad568d2b9f | ||
|
|
c7bfb9a11d | ||
|
|
c9391181bd | ||
|
|
b08eb519bf | ||
|
|
47c4fc2f7e | ||
|
|
dfd177433a | ||
|
|
27381e9696 | ||
|
|
1c7827c53c | ||
|
|
9512bdb5d6 | ||
|
|
33d1f1d692 | ||
|
|
c6b49545ff | ||
|
|
a4a833bfdb | ||
|
|
2e1b6e4630 | ||
|
|
6911cfa387 | ||
|
|
aa29f890de | ||
|
|
0f4e6a01bc | ||
|
|
1d3d8d6710 | ||
|
|
005e06c56f | ||
|
|
0a7c32b3cb | ||
|
|
82916a04ea | ||
|
|
ba2e419894 | ||
|
|
0812c9025d | ||
|
|
4c59ed3ccf | ||
|
|
43d8d96608 | ||
|
|
26a6a7d883 | ||
|
|
2e9c237367 | ||
|
|
99d2816ea7 | ||
|
|
7c3853b0e6 | ||
|
|
53aecf38e0 | ||
|
|
41fab0a781 | ||
|
|
3df35aa373 | ||
|
|
543eaa4f66 | ||
|
|
3a851b7f1a | ||
|
|
089ae1e313 | ||
|
|
bfe5802d02 | ||
|
|
3ec6c97380 | ||
|
|
e376da208d | ||
|
|
3b02c5e4e0 | ||
|
|
1bcc79c415 | ||
|
|
9e2cb25d01 | ||
|
|
7e820ba2a5 | ||
|
|
b079940cd9 | ||
|
|
593ee24429 | ||
|
|
f7a91bf10c | ||
|
|
dad7ac706f | ||
|
|
13c48ce78c | ||
|
|
8ecbba1003 | ||
|
|
8bf6a9ec9d | ||
|
|
64092a4bd4 | ||
|
|
8e6bcd969e | ||
|
|
6777dd7ea7 | ||
|
|
f16885568e | ||
|
|
ab109bcfcc | ||
|
|
17f71eaa21 | ||
|
|
3a294e354a | ||
|
|
54814181b9 | ||
|
|
935c2bd6e5 | ||
|
|
a2b74b8e78 | ||
|
|
09730d74e0 | ||
|
|
2bf03291ce | ||
|
|
93e5851167 | ||
|
|
61fd581ef5 | ||
|
|
51afcf2dee | ||
|
|
cadafe13e1 | ||
|
|
47031cb70e | ||
|
|
b3e776b4bc | ||
|
|
e57a1a8da6 | ||
|
|
7f2a392a33 | ||
|
|
055379f569 | ||
|
|
2b8843ca19 | ||
|
|
ace830bced | ||
|
|
3c2f232acb | ||
|
|
86030e64ca | ||
|
|
b1ce3c31f5 | ||
|
|
04553c2c56 | ||
|
|
bdb7afa860 | ||
|
|
7096135cdf | ||
|
|
be37014206 | ||
|
|
b78beb3305 | ||
|
|
38f27d134d | ||
|
|
3b42ba9375 | ||
|
|
4f52bb2ffe | ||
|
|
dd45e1b3db | ||
|
|
e38bfdfc73 | ||
|
|
73caebff00 | ||
|
|
e0608cdf3e | ||
|
|
c815fa80e8 | ||
|
|
e91e1cab47 | ||
|
|
b791878651 | ||
|
|
8192ffec03 | ||
|
|
afa6eb3bad | ||
|
|
6f7d22518e | ||
|
|
2663312dfb | ||
|
|
1332517a9f | ||
|
|
13e227851f | ||
|
|
e1b6c18017 | ||
|
|
a88c8ed85f | ||
|
|
25a90fc481 | ||
|
|
1371206323 | ||
|
|
129f6bb5cc | ||
|
|
545c17d052 | ||
|
|
add00ddba1 | ||
|
|
d9aeb0cc2b | ||
|
|
49e70e7195 | ||
|
|
f8abebf110 | ||
|
|
8e2dfc7341 | ||
|
|
e650ffffce | ||
|
|
d549a300ab | ||
|
|
82a62e73c1 | ||
|
|
45c7e0c231 | ||
|
|
b98a4b11a3 | ||
|
|
484a103f27 | ||
|
|
e31120be21 | ||
|
|
247f02d423 | ||
|
|
3da0c1d8e3 | ||
|
|
c830bbc703 | ||
|
|
7b619fef1d | ||
|
|
bac265a077 | ||
|
|
39df0f8d43 | ||
|
|
6af7f916ee | ||
|
|
ae64097edf | ||
|
|
cb6d8a88f1 | ||
|
|
12838994ad | ||
|
|
d30758a2a8 | ||
|
|
b820aad358 | ||
|
|
170189c344 | ||
|
|
f9e9c9d38b | ||
|
|
088af981df | ||
|
|
357fef8672 | ||
|
|
c38848ea0e | ||
|
|
be8cd13b08 | ||
|
|
487816ab74 | ||
|
|
bcd9f8240c | ||
|
|
1b62972f06 | ||
|
|
1117c3bfab | ||
|
|
748d195db5 | ||
|
|
3a9017adb8 | ||
|
|
eff3186ab5 | ||
|
|
e5f5fe878e | ||
|
|
a47f0f6ecf | ||
|
|
9896165b68 | ||
|
|
5e3adcee93 | ||
|
|
b252266a46 | ||
|
|
1d5adea114 | ||
|
|
a64a51c7df | ||
|
|
ec41c13b45 | ||
|
|
486ca434ff | ||
|
|
fe87a899c8 | ||
|
|
06806bd383 | ||
|
|
2f6c7e1ce2 | ||
|
|
141cda13f1 | ||
|
|
3e8c8afcd1 | ||
|
|
8236f613e0 | ||
|
|
ea6108dca7 | ||
|
|
985a4f07e0 | ||
|
|
5642c579a4 | ||
|
|
8e0559fb3b | ||
|
|
a6a1755fee | ||
|
|
846f383f7b | ||
|
|
bbbe3726f2 | ||
|
|
6d83fd9903 | ||
|
|
fac62a8d24 | ||
|
|
b0d71a5511 | ||
|
|
124ba34d48 | ||
|
|
75270b8ad6 | ||
|
|
5cf6ef88a6 | ||
|
|
b5f72af513 | ||
|
|
1532893c5f | ||
|
|
a3fbc9595a | ||
|
|
f789343b6e | ||
|
|
ff74417352 | ||
|
|
a0ff843d0c | ||
|
|
da93cb0dbb | ||
|
|
0de446c608 | ||
|
|
03bccf16d4 | ||
|
|
635ae8c11e | ||
|
|
dfd5a82112 | ||
|
|
7dad8d452f | ||
|
|
07f8294876 | ||
|
|
7185cc410b | ||
|
|
2d985af60d | ||
|
|
bee2e64482 | ||
|
|
d5dd43c0c1 | ||
|
|
09470eeb8a | ||
|
|
094249a6fa | ||
|
|
6b5302907a | ||
|
|
adc5b08765 | ||
|
|
0150e2a8d7 | ||
|
|
45eaa0c60f | ||
|
|
66ed683196 | ||
|
|
aa4239721e | ||
|
|
5b0b926cbd | ||
|
|
929ce398eb | ||
|
|
b3fdbe021d | ||
|
|
423bd68ce8 | ||
|
|
9bffc68c70 | ||
|
|
b7a5a60091 | ||
|
|
333b11c19f | ||
|
|
fbd4d1b772 | ||
|
|
06a58514b3 | ||
|
|
80815fc3a0 | ||
|
|
b97c277a3f | ||
|
|
310d693e2b | ||
|
|
c1596f6a11 | ||
|
|
76a04343d9 | ||
|
|
25261c99f1 | ||
|
|
d0b994fa9d | ||
|
|
f259601397 | ||
|
|
87904109ca | ||
|
|
785790ccc4 | ||
|
|
759921d00e | ||
|
|
e9db183d54 | ||
|
|
a853374a88 | ||
|
|
3fb5048f10 | ||
|
|
0dd2e758e8 | ||
|
|
d1a562452a | ||
|
|
9205a6cbf4 | ||
|
|
4c8961f39a | ||
|
|
22bdc23a09 | ||
|
|
764cd16e21 | ||
|
|
7583f4651d | ||
|
|
13e931cda4 | ||
|
|
9743cf8351 | ||
|
|
e5ee5702f8 | ||
|
|
5bd5b25b77 | ||
|
|
55d59f3779 | ||
|
|
7d2ea0b77e | ||
|
|
1f30c299a5 | ||
|
|
c887d7e649 | ||
|
|
3fc7743a14 | ||
|
|
2a232f70db | ||
|
|
6fae131287 | ||
|
|
7ee7ef25f9 | ||
|
|
2bd4bc1472 | ||
|
|
aa170b647e | ||
|
|
4fa01216b1 | ||
|
|
a82eb996a4 | ||
|
|
9315684ee3 | ||
|
|
34f7774ce9 | ||
|
|
75031a04cc | ||
|
|
cfb0526cbb | ||
|
|
9fa56a9cd4 | ||
|
|
c4db9c9e12 | ||
|
|
71272371e4 | ||
|
|
91c6c4d233 | ||
|
|
8a6653a926 | ||
|
|
76caf84e39 | ||
|
|
0fee286b84 | ||
|
|
4af18a1575 | ||
|
|
d9293f4da8 | ||
|
|
db29f97397 | ||
|
|
573f41611d | ||
|
|
28ed103ec0 | ||
|
|
5e37750f00 | ||
|
|
5fe3cd9406 | ||
|
|
b00cc99408 | ||
|
|
9a66c3bba9 | ||
|
|
546921b445 | ||
|
|
8b698d3a4c | ||
|
|
c4608a949b | ||
|
|
bba1c559a3 | ||
|
|
bdee9ea72f | ||
|
|
520923ba08 | ||
|
|
936a74597f | ||
|
|
97132745cc | ||
|
|
2bb30f65f3 | ||
|
|
ec04d55793 | ||
|
|
88671db566 | ||
|
|
538f501bc0 | ||
|
|
3b75d41a2f | ||
|
|
110149d0e6 | ||
|
|
89b68781fa | ||
|
|
4cdc54b9c1 | ||
|
|
7673595a43 | ||
|
|
76a259c107 | ||
|
|
5f40d01fb4 | ||
|
|
df29d47c0a | ||
|
|
10d4084dde | ||
|
|
ba8cdb1b42 | ||
|
|
22732fee6a | ||
|
|
bfbc4613b9 | ||
|
|
92e5eecaf2 | ||
|
|
593159f4a6 | ||
|
|
53cad0e56a | ||
|
|
d61006dd67 | ||
|
|
eb565285b2 | ||
|
|
630f164877 | ||
|
|
38c6bce2c0 | ||
|
|
034734ec66 | ||
|
|
d875eeb22a | ||
|
|
61db6b8fb2 | ||
|
|
945d4cf20d | ||
|
|
631337c451 | ||
|
|
4f51e377ae | ||
|
|
e71c06a0d0 | ||
|
|
13aabde5d9 | ||
|
|
e3f371f457 | ||
|
|
6ee99b5736 | ||
|
|
895188b25f | ||
|
|
9fba923a51 | ||
|
|
37a39098f8 | ||
|
|
6fb548e6c3 | ||
|
|
110b7cb06f | ||
|
|
e9070a77c3 | ||
|
|
475e6e5511 | ||
|
|
eed4c7c11a | ||
|
|
d986d7ac03 | ||
|
|
f640922a50 | ||
|
|
118a6cf0d1 | ||
|
|
72871e6d9a | ||
|
|
61acbcec0d | ||
|
|
06af79e2b4 | ||
|
|
6782602141 | ||
|
|
8df17ae38a | ||
|
|
1645a93adf | ||
|
|
6a04ab37d7 | ||
|
|
27c9abd9ed | ||
|
|
a08be2e11d | ||
|
|
17615b1791 | ||
|
|
d75c3b584a | ||
|
|
20f919b93e | ||
|
|
20244fe5cc | ||
|
|
6a89f0a661 | ||
|
|
3a9efdb03e | ||
|
|
2ae00db94b | ||
|
|
a9261b759b | ||
|
|
6b02dc3cd5 | ||
|
|
afa37c0d2f | ||
|
|
2575f10497 | ||
|
|
27c4a68a13 | ||
|
|
f09cb54894 | ||
|
|
5431cfef79 | ||
|
|
35c0f3cddc | ||
|
|
efe22ca613 | ||
|
|
3408a8ffcf | ||
|
|
60a140efb3 | ||
|
|
bbe584bd91 | ||
|
|
3866377a28 | ||
|
|
ebc0b4b2b0 | ||
|
|
d6c65a320d | ||
|
|
2e46d76165 | ||
|
|
23037da406 | ||
|
|
617261c74d | ||
|
|
6c0d6ee0cf | ||
|
|
663e1ef7ab | ||
|
|
1a47d355f0 | ||
|
|
e407994103 | ||
|
|
bda2149c02 | ||
|
|
b925423d61 | ||
|
|
f3906a37bf | ||
|
|
a1e115ea6b | ||
|
|
03383510ef | ||
|
|
e8cf9644eb | ||
|
|
dbfcf1facc | ||
|
|
44aff94937 | ||
|
|
fb1fc92b7c | ||
|
|
71cfa64b16 | ||
|
|
b200105a85 | ||
|
|
ce83f3c5e1 | ||
|
|
57d3275856 | ||
|
|
eb1a109afc | ||
|
|
a03e3fea12 | ||
|
|
c60ae111ef | ||
|
|
5eb46395ae | ||
|
|
db08b61cfa | ||
|
|
41d313baff | ||
|
|
58c3ed9254 | ||
|
|
affe36a568 | ||
|
|
9ba6cddde7 | ||
|
|
5656c9f351 | ||
|
|
ecf24a746e | ||
|
|
5b5a58a867 | ||
|
|
c6ab7878e7 | ||
|
|
99e85eba37 | ||
|
|
3bf92e6f12 | ||
|
|
ba359305f6 | ||
|
|
f826eb224c | ||
|
|
a675f4cb68 | ||
|
|
5e1e2c6047 | ||
|
|
eba0990538 | ||
|
|
1bcef2bab0 | ||
|
|
f83777e1d2 | ||
|
|
9fa48090ce | ||
|
|
7c8ac4fee8 | ||
|
|
76c254ee98 | ||
|
|
e75ad64483 | ||
|
|
17d1af181d | ||
|
|
a72d27a431 | ||
|
|
4e9fc57aa4 | ||
|
|
494b27cc22 | ||
|
|
3606186975 | ||
|
|
41dbdfc016 | ||
|
|
655e5ca7e0 | ||
|
|
3067d323de | ||
|
|
1404a080ad | ||
|
|
cbb2a1b575 | ||
|
|
30b276ec1a | ||
|
|
13a24d5b00 | ||
|
|
40360cf18a | ||
|
|
139e2ee78d | ||
|
|
3ff466462c | ||
|
|
9ff2442789 | ||
|
|
b11e4ab1db | ||
|
|
a52cc8c093 | ||
|
|
506c409303 | ||
|
|
53a8446f4a | ||
|
|
ab5bb8ea6c | ||
|
|
d097b84c82 | ||
|
|
f285635e76 | ||
|
|
0f7b5299e9 | ||
|
|
7a788d1e6e | ||
|
|
6c4231a6b2 | ||
|
|
6e202341ad | ||
|
|
95a509b86c | ||
|
|
602114af55 | ||
|
|
e5ccc40358 | ||
|
|
2310f6e1c0 | ||
|
|
9ae952bb78 | ||
|
|
57a7eaccf5 | ||
|
|
1934bfa962 | ||
|
|
a5f3ec7b9b | ||
|
|
3cfcf1e772 | ||
|
|
b45907a9f6 | ||
|
|
8fd9395e23 | ||
|
|
126b2a19e7 | ||
|
|
bde01af89d | ||
|
|
65491ef18e | ||
|
|
44a9470613 | ||
|
|
470045f228 | ||
|
|
d081a6ee92 | ||
|
|
95f404bb64 | ||
|
|
dcea76bcd3 | ||
|
|
e9b816fb87 | ||
|
|
20a7039f59 | ||
|
|
4ad172dda4 | ||
|
|
adf6c19996 | ||
|
|
24ec0adacf | ||
|
|
83bc6748a3 | ||
|
|
bfed651263 | ||
|
|
8bd4f2b5b5 | ||
|
|
3d7bc0b593 | ||
|
|
473c6f2b3c | ||
|
|
484ce6c895 | ||
|
|
eeccdbca72 | ||
|
|
552238676c | ||
|
|
c9e7bf7ca5 | ||
|
|
8d1e335abf | ||
|
|
c76bcb5d15 | ||
|
|
7732b21ca2 | ||
|
|
123d9b791c | ||
|
|
a237ca799f | ||
|
|
f850c2461a | ||
|
|
0fb248e6be | ||
|
|
7fca697234 | ||
|
|
4004525d3a | ||
|
|
4f67788d4a | ||
|
|
69ea41056d | ||
|
|
6443770670 | ||
|
|
46917af37c | ||
|
|
47a4a0eaf5 | ||
|
|
03dbecd5ae | ||
|
|
f6c95e3095 | ||
|
|
6823291eb0 | ||
|
|
98b43945ed | ||
|
|
8792c423d5 | ||
|
|
5607298898 | ||
|
|
35047477fe | ||
|
|
08a31a92f2 | ||
|
|
6e2fc7ff97 | ||
|
|
44d1f9cf7d | ||
|
|
826a6bf868 | ||
|
|
3abb96e5b9 | ||
|
|
228fddf902 | ||
|
|
1516802a8d | ||
|
|
c7589e4e3c | ||
|
|
a502785209 | ||
|
|
c923ed69a0 | ||
|
|
e4bd1c758f | ||
|
|
ad175fd2f2 | ||
|
|
190cc18b11 | ||
|
|
55e7b8901a | ||
|
|
2efb5d7f8f | ||
|
|
f144dd888d | ||
|
|
0a4944f120 | ||
|
|
7675347889 | ||
|
|
7ea2b57ece | ||
|
|
cec8249b24 | ||
|
|
31c05c9b20 | ||
|
|
f7aeef3ffc | ||
|
|
ccb1ff7f0e | ||
|
|
b707388134 | ||
|
|
538cc2b75e | ||
|
|
b783f3bae9 | ||
|
|
b776015b36 | ||
|
|
be4ea59984 | ||
|
|
2f92b65400 | ||
|
|
2c7510fe5f | ||
|
|
1ff36552e0 | ||
|
|
418be689f2 | ||
|
|
1a572be52e | ||
|
|
e8316de160 | ||
|
|
12fa94627d | ||
|
|
056c0901f2 | ||
|
|
6db41431ed | ||
|
|
b90d6b7b8c | ||
|
|
4b39c046a7 | ||
|
|
8edfe7bc9c | ||
|
|
9e21e02791 | ||
|
|
8e6b56b2d6 | ||
|
|
4b65d4da06 | ||
|
|
a40c5fdd40 | ||
|
|
d8be9abcc5 | ||
|
|
d2529cfc23 | ||
|
|
b81b38f7e4 | ||
|
|
d9225b9529 | ||
|
|
4bde509708 | ||
|
|
22877e96c7 | ||
|
|
ae473a0d1a | ||
|
|
807f42ad65 | ||
|
|
026986c956 | ||
|
|
621562a17e | ||
|
|
5f7f885d99 | ||
|
|
41337f66a8 | ||
|
|
8c61bc1a5e | ||
|
|
b07144278b | ||
|
|
c775e8368e | ||
|
|
008f07cacc | ||
|
|
ff1a566bf4 | ||
|
|
3b4359f7eb | ||
|
|
e70226afba | ||
|
|
cc2c186e7f | ||
|
|
833247d133 | ||
|
|
f532df20e6 | ||
|
|
0fa601ad5e | ||
|
|
6da1dc5372 | ||
|
|
2e3d9c22e3 | ||
|
|
86cef86fc9 | ||
|
|
d83291eac0 | ||
|
|
0cc7d621bc | ||
|
|
b40b0ec47c | ||
|
|
a67bfabea4 | ||
|
|
be202a6e1a | ||
|
|
f92275fa50 | ||
|
|
563ea993c6 | ||
|
|
cbf2a4e7a8 | ||
|
|
bc53e944af | ||
|
|
432fd287c9 | ||
|
|
383453f9af | ||
|
|
27939c6b61 | ||
|
|
dc468f1a76 | ||
|
|
99f60ea6e5 | ||
|
|
1394034160 | ||
|
|
45ac758b52 | ||
|
|
bf13c5ff40 | ||
|
|
6179bcdf5b | ||
|
|
6121a0cade | ||
|
|
a9b044b4d2 | ||
|
|
54c4ca4180 | ||
|
|
301130bc0c | ||
|
|
36b23d072c | ||
|
|
66ad048053 | ||
|
|
9bd7071297 | ||
|
|
da66102bc0 | ||
|
|
f1ffa5ca03 | ||
|
|
736a8c1b30 | ||
|
|
41498b5d93 | ||
|
|
3c32ef39c7 | ||
|
|
726f92a9c9 | ||
|
|
f6adbe435e | ||
|
|
1410b3b5b1 | ||
|
|
6dc2b36d14 | ||
|
|
34d560b75e | ||
|
|
caa77387df | ||
|
|
a0b19cfd1b | ||
|
|
6afcf8d0d7 | ||
|
|
b8591007cf | ||
|
|
7fe3e28a2d | ||
|
|
72a1d4f186 | ||
|
|
472658293f | ||
|
|
4ecdefc14e | ||
|
|
38eff7e59c | ||
|
|
7d8a66b71a | ||
|
|
29f53d574c | ||
|
|
979a1a9810 | ||
|
|
2f3c8285c8 | ||
|
|
cfa7b4832a | ||
|
|
091898551e | ||
|
|
fbeabfcad2 | ||
|
|
5a6c64377a | ||
|
|
faa806fc9f | ||
|
|
4fdafecf77 | ||
|
|
a8bc4eb352 | ||
|
|
532ff88ea4 | ||
|
|
30ee33cd66 | ||
|
|
3462123877 | ||
|
|
0d8bd2569f | ||
|
|
a68aa84e2f | ||
|
|
ebadbb0f18 | ||
|
|
4f03ec503f | ||
|
|
fd2a5a07a1 | ||
|
|
0f390e63d3 | ||
|
|
57c6ae5e04 | ||
|
|
f4303a0480 | ||
|
|
61afad30c8 | ||
|
|
d8086b7337 | ||
|
|
ea7eb72cce | ||
|
|
0fc7eb6316 | ||
|
|
926e276167 | ||
|
|
a34875e804 | ||
|
|
7436736040 | ||
|
|
0dfd8af7d5 | ||
|
|
b4658463e1 | ||
|
|
99c7fb997b | ||
|
|
dc78eead09 | ||
|
|
63d483d4ec | ||
|
|
6e685a2aa1 | ||
|
|
4b435d4ac3 | ||
|
|
17eca9dd2f | ||
|
|
0a853ca8a5 | ||
|
|
c67caafdb4 | ||
|
|
0bda79c0d5 | ||
|
|
44735b3d4e | ||
|
|
a6768c361f | ||
|
|
d1c4dee7f7 | ||
|
|
f4d148b042 | ||
|
|
184bcc2e40 | ||
|
|
445367532a | ||
|
|
fa5ff14ff1 | ||
|
|
f4c5fbf9dd | ||
|
|
9df351a2f0 | ||
|
|
00143de42b | ||
|
|
65e5677788 | ||
|
|
0bd1b404aa | ||
|
|
5f65496500 | ||
|
|
413854d1f1 | ||
|
|
f836afa2ea | ||
|
|
55b36e734d | ||
|
|
0a2129aeab | ||
|
|
c1208563cd | ||
|
|
5a6e1ffcd9 | ||
|
|
33ef03ef71 | ||
|
|
1b81c1e221 | ||
|
|
7418ef21ac | ||
|
|
20be2f76c6 | ||
|
|
eb311abe83 | ||
|
|
80599013f2 | ||
|
|
f756f32bda | ||
|
|
273744bb7e | ||
|
|
bbfd8db190 | ||
|
|
b415a2c2fa | ||
|
|
a11ca8b720 | ||
|
|
4f88b26c0b | ||
|
|
2fa0a182ff | ||
|
|
25fb73809e | ||
|
|
b8a7b489cc | ||
|
|
92219189a9 | ||
|
|
afe3f84c4a | ||
|
|
a29a5b0bbf | ||
|
|
2553ce82ec | ||
|
|
f6bdb986dd | ||
|
|
6fe451c247 | ||
|
|
2ece71aae3 | ||
|
|
ac66dfe476 | ||
|
|
b5f8c4fb6d | ||
|
|
9ab853d0ea | ||
|
|
02d3bd36fe | ||
|
|
899c825813 | ||
|
|
89efa71ced | ||
|
|
88c46ba9ee | ||
|
|
972c4758b1 | ||
|
|
809d7378e2 | ||
|
|
68cfa3a5da | ||
|
|
6e79450558 | ||
|
|
0fd29ac223 | ||
|
|
627e632120 | ||
|
|
574532f10c | ||
|
|
74ad750d1d | ||
|
|
67a61493dd | ||
|
|
0d03e965d2 | ||
|
|
db4615a2d3 | ||
|
|
da2f0b234f | ||
|
|
3896b2511c | ||
|
|
7c316f8c88 | ||
|
|
ed7c52f09f | ||
|
|
130b950878 | ||
|
|
c0b935e3f1 | ||
|
|
90451e6da9 | ||
|
|
6db34fcdc7 | ||
|
|
5bb53622ca | ||
|
|
b9308f060f | ||
|
|
f715367849 | ||
|
|
07b757b3c1 | ||
|
|
3325e393bc | ||
|
|
48a8c99c83 | ||
|
|
8d687158f6 | ||
|
|
f966793490 | ||
|
|
d824122219 | ||
|
|
65900b5881 | ||
|
|
e6ed1eab71 | ||
|
|
1a3c31a141 | ||
|
|
c0ef592f72 | ||
|
|
5d2b4d435f | ||
|
|
fd5b5ebd8d | ||
|
|
2f42873793 | ||
|
|
3b4b63e57b | ||
|
|
c33a99d9ed | ||
|
|
b6be41e5c5 | ||
|
|
bd4c07a013 | ||
|
|
ba763b2d2a | ||
|
|
c15ec71be9 | ||
|
|
93273d555d | ||
|
|
793f81e287 | ||
|
|
d87b768fc0 | ||
|
|
c07d2dc6d3 | ||
|
|
95af0222f3 | ||
|
|
3f15eddb0c | ||
|
|
c39f1ad75f | ||
|
|
f27b60e031 | ||
|
|
5f1d0a5936 | ||
|
|
4fdadd5474 | ||
|
|
b2ea6d449e | ||
|
|
3afff687b2 | ||
|
|
37ddecf629 | ||
|
|
27e58edb1f | ||
|
|
3dd421a2bf | ||
|
|
4537f9e48f | ||
|
|
94b6cda86e | ||
|
|
9ae010a391 | ||
|
|
13c105472e | ||
|
|
88194e479e | ||
|
|
b36c194f67 | ||
|
|
7c7b6e0fd9 | ||
|
|
01b77f1f5f | ||
|
|
840a0ad840 | ||
|
|
ab1ca18488 | ||
|
|
75e0fa2def | ||
|
|
ca3ed47d21 | ||
|
|
61a8ab5199 | ||
|
|
ce721c2e09 | ||
|
|
2862e3a6ee | ||
|
|
75c4a24cbd | ||
|
|
1cf7d791cc | ||
|
|
62fecc08ac | ||
|
|
491ca63342 | ||
|
|
b232a255e7 | ||
|
|
0870f42557 | ||
|
|
85237eac7e | ||
|
|
8d5088d2e4 | ||
|
|
47f5bf1ea5 | ||
|
|
deebadef3a | ||
|
|
ce24ae4fae | ||
|
|
16152de39d | ||
|
|
4a2ac63d25 | ||
|
|
5437968c83 | ||
|
|
8022252452 | ||
|
|
ea6571fdb6 | ||
|
|
2f7f692b84 | ||
|
|
721df1d17c | ||
|
|
7a2e43f949 | ||
|
|
4e5cc3dadb | ||
|
|
f6d5dd5a82 | ||
|
|
cafcf458b8 | ||
|
|
e7d0624b96 | ||
|
|
156de2457d | ||
|
|
c839d045cc | ||
|
|
2eaf32b23d | ||
|
|
5899c73ab8 | ||
|
|
6c0a446692 | ||
|
|
7c2cfc171e | ||
|
|
5d4a3c1df6 | ||
|
|
587df1f5bb | ||
|
|
019fcf314b | ||
|
|
1818b3575c | ||
|
|
afde41135a | ||
|
|
5dc812072f | ||
|
|
3ba75d2de3 | ||
|
|
dfc6e91321 | ||
|
|
a5504a4b74 | ||
|
|
d10a7fad20 | ||
|
|
f811d4c89f | ||
|
|
dcaa6241ec | ||
|
|
9527783cdb | ||
|
|
db2b0cb159 | ||
|
|
09dbade477 | ||
|
|
0817b9aebb | ||
|
|
e3c923e268 | ||
|
|
761e671ecf | ||
|
|
fe019b8f0f | ||
|
|
55af958792 | ||
|
|
da1bdb1322 | ||
|
|
892d8fe09c | ||
|
|
89fcf4526c | ||
|
|
5d037b5f0e | ||
|
|
1bb7f8ac60 | ||
|
|
52f761095a | ||
|
|
770ec3ab97 | ||
|
|
7c3159fc23 | ||
|
|
d5924fa6ab | ||
|
|
295f44b947 | ||
|
|
115bc85c58 | ||
|
|
6aaad71126 | ||
|
|
24b4004fd9 | ||
|
|
dd0cdb5c83 | ||
|
|
48f14e193a | ||
|
|
7076272768 | ||
|
|
bef6a2d61b | ||
|
|
84c6723adc | ||
|
|
61a179ba67 | ||
|
|
afecb87c6d | ||
|
|
cb125b83cb | ||
|
|
cb337fc22f | ||
|
|
781c7369fb | ||
|
|
5281fc6a69 | ||
|
|
814d137084 | ||
|
|
a567ab1984 | ||
|
|
69eaa04ff6 | ||
|
|
d0c8a95f57 | ||
|
|
d09607766b | ||
|
|
8f90d56e0f | ||
|
|
d20d06ace7 | ||
|
|
98282fd319 | ||
|
|
8e8584656e | ||
|
|
2f97cd8104 | ||
|
|
8b1ff94c5f | ||
|
|
c67e7c0d3a | ||
|
|
21dcb477dc | ||
|
|
cb5391ed28 | ||
|
|
fdc2570945 | ||
|
|
c60b04caf6 | ||
|
|
fc0c99b436 | ||
|
|
0e4c38d99e | ||
|
|
b0845c700f | ||
|
|
27a013450e | ||
|
|
d4dccd1391 | ||
|
|
cd972f5945 | ||
|
|
ed876fa607 | ||
|
|
06d15b045e | ||
|
|
0821b67019 | ||
|
|
0f18e7c1a1 | ||
|
|
ac7f025952 | ||
|
|
05382a0354 | ||
|
|
55b200dec4 | ||
|
|
587abda389 | ||
|
|
da0cc62f16 |
No files matched your search
@@ -0,0 +1 @@
|
||||
*.exe filter=lfs diff=lfs merge=lfs -text
|
||||
@@ -0,0 +1,28 @@
|
||||
# 公告
|
||||
|
||||
提交前请确保你的启动器版本是**最新的开发版**,可以在启动器设置中更换更新通道至开发版获取更新。
|
||||
|
||||
**如果你在阅读完本公告后仍然希望在此处发布 issue,请将公告内容删去,并按照下面的模板填入相关信息。**
|
||||
|
||||
|
||||
|
||||
我们发现,对于不经常检查邮箱的人来说,GitHub Issues 的反馈效率太低,时隔几个小时甚至一天的情况很多。为了改善反馈效率,并将积极为 HMCL 提供问题反馈和建议的人聚集起来,我们希望在这里反馈的人可以在 HMCL 3 用户 QQ 群:219177735 中反馈信息,**而不在 GitHub Issues 中反馈问题**。
|
||||
|
||||
如果你希望在 QQ 群中反馈问题,也请将下面的信息表填好直接发在群中,加快我们的沟通速度。
|
||||
|
||||
|
||||
|
||||
# 问题提交
|
||||
|
||||
*完整地填下面的问题提交表对我们很重要,这可以加快我们分析问题原因的速度。*
|
||||
|
||||
* 启动器版本:
|
||||
* 操作系统:
|
||||
* Java 版本:
|
||||
* 错误截图(最好请将整个电脑屏幕的截图发上来):
|
||||
* 游戏版本(如果是启动通过启动器自带的自动安装功能安装的游戏):
|
||||
* 对游戏做的修改(是否自行通过安装器安装 Rift 等 API,以及 mod):
|
||||
* 游戏崩溃报告(如果有):
|
||||
* 启动器崩溃报告(如果有):
|
||||
* 启动器日志文件(出现问题后点击启动器设置中的【导出启动器日志】按钮):
|
||||
* 问题描述(如何触发问题):
|
||||
@@ -0,0 +1,18 @@
|
||||
name: Java CI
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
java-package: jdk+fx
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
Executable → Regular
+30
-16
@@ -1,27 +1,41 @@
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
.gradle
|
||||
.nb-gradle
|
||||
|
||||
*.bat
|
||||
*.lck
|
||||
*.1
|
||||
*.2
|
||||
*.log
|
||||
.mine*
|
||||
NVIDIA
|
||||
*.json
|
||||
*.hmd
|
||||
|
||||
HMCLAPI/build/
|
||||
HMCL/build/
|
||||
HMCLServer/
|
||||
HMCSM/build/
|
||||
MetroLookAndFeel/build/
|
||||
# gradle build
|
||||
/build/
|
||||
/HMCL/build/
|
||||
/HMCLCore/build/
|
||||
/HMCLTransformerDiscoveryService/build/
|
||||
|
||||
# idea
|
||||
.idea
|
||||
/out/
|
||||
/HMCL/out/
|
||||
/HMCLCore/out/
|
||||
/HMCLTransformerDiscoveryService/out/
|
||||
|
||||
# eclipse
|
||||
/bin/
|
||||
/HMCL/bin/
|
||||
/HMCLCore/bin/
|
||||
/HMCLTransformerDiscoveryService/bin/
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
|
||||
# netbeans
|
||||
.nb-gradle
|
||||
|
||||
*.exe
|
||||
@@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<gradle-project-properties>
|
||||
<!--DO NOT EDIT THIS FILE! - Used by the Gradle plugin of NetBeans.-->
|
||||
<target-platform-name>j2se</target-platform-name>
|
||||
<target-platform>1.8</target-platform>
|
||||
<source-level>1.8</source-level>
|
||||
<common-tasks>
|
||||
<task>
|
||||
<display-name>launch4j</display-name>
|
||||
<non-blocking>no</non-blocking>
|
||||
<task-names>
|
||||
<name must-exist="yes">launch4j</name>
|
||||
</task-names>
|
||||
<task-args/>
|
||||
<task-jvm-args/>
|
||||
</task>
|
||||
</common-tasks>
|
||||
<script-platform>
|
||||
<spec-name>j2se</spec-name>
|
||||
<spec-version>1.8</spec-version>
|
||||
</script-platform>
|
||||
<license-header>
|
||||
<name>GNU General Public License</name>
|
||||
<template>license-header.txt</template>
|
||||
<property name="organization">huangyuhui</property>
|
||||
</license-header>
|
||||
</gradle-project-properties>
|
||||
@@ -0,0 +1,14 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
before_install:
|
||||
- chmod +x gradlew
|
||||
script: "bash ./gradlew clean build --stacktrace"
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
cache:
|
||||
directories:
|
||||
- "$HOME/.gradle/caches/"
|
||||
Binary file not shown.
Executable → Regular
+187
-82
@@ -1,105 +1,210 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
import java.util.jar.JarOutputStream
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
apply plugin: 'launch4j'
|
||||
apply plugin: 'me.tatarka.retrolambda'
|
||||
|
||||
if (!hasProperty('mainClass')) {
|
||||
ext.mainClass = 'org.jackhuang.hellominecraft.launcher.Main'
|
||||
}
|
||||
|
||||
def buildnumber = System.getenv("BUILD_NUMBER") == null ? ".8" : "."+System.getenv("BUILD_NUMBER")
|
||||
|
||||
String mavenGroupId = 'HMCL'
|
||||
String mavenVersion = '2.3.5' + buildnumber
|
||||
String bundleName = "Hello Minecraft! Launcher"
|
||||
|
||||
group = mavenGroupId
|
||||
version = mavenVersion
|
||||
|
||||
String mavenArtifactId = name
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral();
|
||||
|
||||
maven {
|
||||
url "https://libraries.minecraft.net"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'net.sf.proguard:proguard-gradle:4.10'
|
||||
classpath 'edu.sc.seis.gradle:launch4j:1.0.6'
|
||||
classpath 'me.tatarka:gradle-retrolambda:3.1.0'
|
||||
}
|
||||
gradlePluginPortal()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'org.tukaani:xz:1.8'
|
||||
}
|
||||
}
|
||||
|
||||
configure(install.repositories.mavenInstaller) {
|
||||
pom.project {
|
||||
groupId = mavenGroupId
|
||||
artifactId = mavenArtifactId
|
||||
version = mavenVersion
|
||||
}
|
||||
plugins {
|
||||
id 'application'
|
||||
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
||||
}
|
||||
|
||||
import java.nio.file.FileSystems
|
||||
import java.security.KeyFactory
|
||||
import java.security.MessageDigest
|
||||
import java.security.Signature
|
||||
import java.security.spec.PKCS8EncodedKeySpec
|
||||
import java.util.jar.JarFile
|
||||
import java.util.jar.JarOutputStream
|
||||
import java.util.jar.Pack200
|
||||
import java.util.zip.GZIPOutputStream
|
||||
import java.util.zip.ZipFile
|
||||
import java.nio.file.Files
|
||||
|
||||
import org.tukaani.xz.LZMA2Options
|
||||
import org.tukaani.xz.XZOutputStream
|
||||
|
||||
def buildnumber = System.getenv("BUILD_NUMBER") ?: "SNAPSHOT"
|
||||
if (System.getenv("BUILD_NUMBER") != null && System.getenv("BUILD_NUMBER_OFFSET") != null)
|
||||
buildnumber = (Integer.parseInt(System.getenv("BUILD_NUMBER")) - Integer.parseInt(System.getenv("BUILD_NUMBER_OFFSET"))).toString()
|
||||
def versionroot = System.getenv("VERSION_ROOT") ?: "3.2"
|
||||
version = versionroot + '.' + buildnumber
|
||||
|
||||
mainClassName = 'org.jackhuang.hmcl.Main'
|
||||
|
||||
dependencies {
|
||||
compile project(":MetroLookAndFeel")
|
||||
compile project(":HMCLAPI")
|
||||
implementation project(":HMCLCore")
|
||||
implementation rootProject.files("lib/JFoenix.jar")
|
||||
}
|
||||
|
||||
retrolambda {
|
||||
javaVersion = JavaVersion.VERSION_1_6
|
||||
def digest(String algorithm, byte[] bytes) {
|
||||
return MessageDigest.getInstance(algorithm).digest(bytes)
|
||||
}
|
||||
|
||||
def createChecksum(File file) {
|
||||
def algorithm = "SHA-1"
|
||||
def suffix = "sha1"
|
||||
new File(file.parentFile, file.name + "." + suffix).text = digest(algorithm, file.bytes).encodeHex().toString() + "\n"
|
||||
}
|
||||
|
||||
def attachSignature(File jar) {
|
||||
def keyLocation = System.getenv("HMCL_SIGNATURE_KEY");
|
||||
if (keyLocation == null)
|
||||
return
|
||||
def privatekey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(new File(keyLocation).bytes))
|
||||
|
||||
def signer = Signature.getInstance("SHA512withRSA")
|
||||
signer.initSign(privatekey)
|
||||
new ZipFile(jar).withCloseable { zip ->
|
||||
zip.stream()
|
||||
.sorted(Comparator.comparing { it.name })
|
||||
.filter { it.name != "META-INF/hmcl_signature" }
|
||||
.forEach {
|
||||
signer.update(digest("SHA-512", it.name.getBytes("UTF-8")))
|
||||
signer.update(digest("SHA-512", zip.getInputStream(it).bytes))
|
||||
}
|
||||
}
|
||||
def signature = signer.sign()
|
||||
|
||||
FileSystems.newFileSystem(URI.create("jar:" + jar.toURI()), [:]).withCloseable { zipfs ->
|
||||
Files.newOutputStream(zipfs.getPath("META-INF/hmcl_signature")).withCloseable { it << signature }
|
||||
}
|
||||
}
|
||||
|
||||
ext.packer = Pack200.newPacker()
|
||||
packer.properties()["pack.effort"] = "9"
|
||||
ext.unpacker = Pack200.newUnpacker()
|
||||
|
||||
// Pack200 does not guarantee that unpacked .class file is bit-wise same as the .class file before packing
|
||||
// because of shrinking. So we should pack .class files and unpack it to make sure that after unpacking
|
||||
// .class files remain the same.
|
||||
def repack(File file) {
|
||||
def packed = new ByteArrayOutputStream()
|
||||
new JarFile(file).withCloseable { packer.pack(it, packed) }
|
||||
new JarOutputStream(file.newOutputStream()).withCloseable { unpacker.unpack(new ByteArrayInputStream(packed.toByteArray()), it) }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
java11 {
|
||||
java {
|
||||
srcDirs = ['src/main/java11']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compileJava11Java {
|
||||
javaCompiler = javaToolchains.compilerFor {
|
||||
languageVersion = JavaLanguageVersion.of(11)
|
||||
}
|
||||
options.compilerArgs.add('--add-exports=java.base/jdk.internal.loader=ALL-UNNAMED')
|
||||
sourceCompatibility = 11
|
||||
targetCompatibility = 11
|
||||
}
|
||||
|
||||
jar {
|
||||
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
|
||||
enabled = false
|
||||
dependsOn shadowJar
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
classifier = null
|
||||
|
||||
manifest {
|
||||
attributes 'Created-By' : 'Copyright(c) 2013-2016 huangyuhui.',
|
||||
'Main-Class' : mainClass
|
||||
attributes 'Created-By': 'Copyright(c) 2013-2020 huangyuhui.',
|
||||
'Main-Class': mainClassName,
|
||||
'Multi-Release': 'true',
|
||||
'Implementation-Version': version,
|
||||
'Add-Opens': [
|
||||
'java.base/java.lang',
|
||||
'java.base/java.lang.reflect',
|
||||
'javafx.graphics/javafx.css',
|
||||
'javafx.base/com.sun.javafx.runtime',
|
||||
'javafx.controls/com.sun.javafx.scene.control.behavior',
|
||||
'javafx.controls/javafx.scene.control.skin',
|
||||
'javafx.controls/com.sun.javafx.scene.control',
|
||||
'javafx.base/com.sun.javafx.binding',
|
||||
'javafx.base/com.sun.javafx.event',
|
||||
'javafx.graphics/com.sun.javafx.stage'
|
||||
].join(" "),
|
||||
'Add-Exports': [
|
||||
'java.base/jdk.internal.loader',
|
||||
'javafx.controls/com.sun.javafx.scene.control.behavior',
|
||||
'javafx.controls/javafx.scene.control.skin',
|
||||
'javafx.controls/com.sun.javafx.scene.control',
|
||||
'javafx.base/com.sun.javafx.binding',
|
||||
'javafx.graphics/com.sun.javafx.stage',
|
||||
'javafx.base/com.sun.javafx.event'
|
||||
].join(" ")
|
||||
}
|
||||
|
||||
doLast {
|
||||
repack(jar.archivePath) // see repack()
|
||||
attachSignature(jar.archivePath)
|
||||
createChecksum(jar.archivePath)
|
||||
}
|
||||
}
|
||||
|
||||
launch4j {
|
||||
launch4jCmd = 'D:\\Develop\\Java\\Launch4j\\launch4j.exe'
|
||||
//launch4jCmd = '/home/huangyuhui/softwares/launch4j/launch4j'
|
||||
supportUrl = 'http://www.mcbbs.net/thread-142335-1-1.html'
|
||||
jreMinVersion = '1.6.0'
|
||||
|
||||
mainClassName = mainClass
|
||||
icon = new File(project.buildDir, '../icon.ico').absolutePath
|
||||
version = mavenVersion
|
||||
downloadUrl = 'http://java.com/download'
|
||||
copyright = "Copyright(c) 2013-2015 huangyuhui."
|
||||
|
||||
jar = new File(project.buildDir, 'libs/' + mavenGroupId + '-' + mavenVersion + '.jar').absolutePath
|
||||
outfile = mavenGroupId + '-' + mavenVersion + '.exe'
|
||||
messagesJreVersionError = 'This application requires a Java Runtime Environment installation, or the runtime is corrupted.\n\u6ca1\u6709\u627e\u5230\u004a\u0061\u0076\u0061\u8fd0\u884c\u65f6\uff0c\u8bf7\u4e0d\u8981\u4f7f\u7528\u7eff\u8272\u004a\u0061\u0076\u0061\uff0c\u8bf7\u4f7f\u7528\u5b89\u88c5\u7248\u7684\u004a\u0061\u0076\u0061\uff0c\u70b9\u51fb\u786e\u5b9a\u8fdb\u5165\u004a\u0061\u0076\u0061\u5b89\u88c5\u9875\u9762\u3002'
|
||||
def createExecutable(String suffix, String header) {
|
||||
def output = new File(jar.archivePath.parentFile, jar.archivePath.name[0..-4] + suffix)
|
||||
output.bytes = new File(project.projectDir, header).bytes
|
||||
output << jar.archivePath.bytes
|
||||
createChecksum(output)
|
||||
}
|
||||
|
||||
processResources {
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'icon.icns'
|
||||
ext.convertToBSS = { String resource ->
|
||||
// exclude resource
|
||||
doFirst {
|
||||
def cssFile = new File(this.projectDir, "src/main/resources/" + resource)
|
||||
def bssFile = new File(this.projectDir, "build/compiled-resources/" + resource[0..-4] + "bss")
|
||||
bssFile.parentFile.mkdirs()
|
||||
exec {
|
||||
commandLine 'javapackager', '-createbss', '-outdir', bssFile.parent, '-srcfiles', cssFile.path
|
||||
}
|
||||
}
|
||||
}
|
||||
from "build/compiled-resources"
|
||||
|
||||
convertToBSS "assets/css/root.css"
|
||||
convertToBSS "assets/css/blue.css"
|
||||
|
||||
into('META-INF/versions/11') {
|
||||
from sourceSets.java11.output
|
||||
}
|
||||
dependsOn java11Classes
|
||||
}
|
||||
|
||||
task makePack(dependsOn: jar) {
|
||||
ext.outputPath = new File(jar.archivePath.parentFile, jar.archivePath.name[0..-4] + "pack")
|
||||
doLast {
|
||||
outputPath.newOutputStream().withCloseable { out ->
|
||||
new JarFile(jar.archivePath).withCloseable { jarFile -> packer.pack(jarFile, out) }
|
||||
}
|
||||
createChecksum(outputPath)
|
||||
}
|
||||
}
|
||||
|
||||
build.dependsOn makeExecutable
|
||||
task makePackXz(dependsOn: makePack) doLast {
|
||||
def packXz = new File(makePack.outputPath.parentFile, makePack.outputPath.name + ".xz")
|
||||
// Our CI server does not have enough memory space to compress file at highest level.
|
||||
new XZOutputStream(packXz.newOutputStream(), new LZMA2Options(5)).withCloseable { it << makePack.outputPath.bytes }
|
||||
createChecksum(packXz)
|
||||
}
|
||||
|
||||
task makePackGz(dependsOn: makePack) doLast {
|
||||
def packGz = new File(makePack.outputPath.parentFile, makePack.outputPath.name + ".gz")
|
||||
new GZIPOutputStream(packGz.newOutputStream()).withCloseable { it << makePack.outputPath.bytes }
|
||||
createChecksum(packGz)
|
||||
}
|
||||
|
||||
|
||||
task makeExecutables(dependsOn: jar) doLast {
|
||||
createExecutable("exe", "src/main/resources/assets/HMCLauncher.exe")
|
||||
}
|
||||
|
||||
build.dependsOn makePackXz
|
||||
build.dependsOn makePackGz
|
||||
build.dependsOn makeExecutables
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
Vendored
-81
@@ -1,81 +0,0 @@
|
||||
-libraryjars <java.home>/lib/rt.jar
|
||||
-libraryjars <java.home>/lib/jce.jar
|
||||
-libraryjars <java.home>/lib/jsse.jar
|
||||
|
||||
-dontoptimize
|
||||
-dontshrink
|
||||
-dontwarn java.lang.invoke.*
|
||||
|
||||
-overloadaggressively
|
||||
-repackageclasses 'org.jackhuang.hellominecraft.launcher'
|
||||
-allowaccessmodification
|
||||
|
||||
-renamesourcefileattribute SourceFile
|
||||
|
||||
-keepattributes *Annotation*,SourceFile,LineNumberTable,Signature
|
||||
|
||||
-keep class com.** { *; }
|
||||
-keep class org.jackhuang.hellominecraft.lookandfeel.* { *; }
|
||||
-keep class org.jackhuang.hellominecraft.lookandfeel.painters.* { *; }
|
||||
-keep class org.jackhuang.hellominecraft.lookandfeel.ui.* { *; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.Agent { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.UserType { *; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.properties.Property { *; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.minecraft.MinecraftProfileTexture$Type { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.minecraft.MinecraftProfileTexture { *; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.request.AuthenticationRequest { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.request.InvalidateRequest { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.request.JoinMinecraftServerRequest { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.request.RefreshRequest { *; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.AuthenticationResponse { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.HasJoinedMinecraftServerResponse { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.ProfileSearchResultsResponse { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.RefreshResponse { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.Response { *; }
|
||||
-keepclassmembers class org.jackhuang.mojang.authlib.yggdrasil.response.User { *; }
|
||||
|
||||
-keep class org.jackhuang.hellominecraft.launcher.Main { public static void main(java.lang.String[]); }
|
||||
-keep class org.jackhuang.hellominecraft.launcher.Launcher { public static void main(java.lang.String[]); }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.settings.Profile { private <fields>; public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.settings.Config { private <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.version.MinecraftLibrary { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.version.IMinecraftLibrary { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.version.Natives { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.version.OS { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.version.Rules { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.version.MinecraftVersion { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.assets.AssetsObject { <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.assets.AssetsIndex { <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.ModInfo { <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.InstallProfile { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.Install { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.vanilla.MinecraftForgeVersionRoot { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.vanilla.MinecraftForgeVersion { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.bmcl.ForgeVersion { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.forge.bmcl.Downloads { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.optifine.OptiFineVersion { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderVersionsRoot { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderMCVersions { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderVersion { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.launcher.utils.installers.liteloader.LiteLoaderVersionsMeta { public <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.utils.system.JdkVersion { private <fields>; }
|
||||
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.version.MinecraftRemoteLatestVersion { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.version.MinecraftRemoteVersion { public <fields>; }
|
||||
-keepclassmembers class org.jackhuang.hellominecraft.version.MinecraftRemoteVersions { public <fields>; }
|
||||
@@ -0,0 +1,2 @@
|
||||
rootProject.name = 'HMCL'
|
||||
|
||||
Binary file not shown.
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.Authenticator;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.views.LogWindow;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.MinecraftCrashAdvicer;
|
||||
import org.jackhuang.hellominecraft.utils.DoubleOutputStream;
|
||||
import org.jackhuang.hellominecraft.utils.LauncherPrintStream;
|
||||
import org.jackhuang.hellominecraft.utils.MathUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Launcher {
|
||||
|
||||
public static void println(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
static String classPath = "", proxyHost = "", proxyPort = "", proxyUsername = "", proxyPassword = "";
|
||||
|
||||
public static void main(String[] args) {
|
||||
println("*** " + Main.makeTitle() + " ***");
|
||||
|
||||
boolean showInfo = false;
|
||||
String mainClass = "net.minecraft.client.Minecraft";
|
||||
|
||||
ArrayList<String> cmdList = new ArrayList<>();
|
||||
|
||||
for (String s : args)
|
||||
if (s.startsWith("-cp="))
|
||||
classPath = classPath.concat(s.substring("-cp=".length()));
|
||||
else if (s.startsWith("-mainClass="))
|
||||
mainClass = s.substring("-mainClass=".length());
|
||||
else if (s.startsWith("-proxyHost="))
|
||||
proxyHost = s.substring("-proxyHost=".length());
|
||||
else if (s.startsWith("-proxyPort="))
|
||||
proxyPort = s.substring("-proxyPort=".length());
|
||||
else if (s.startsWith("-proxyUsername="))
|
||||
proxyUsername = s.substring("-proxyUsername=".length());
|
||||
else if (s.startsWith("-proxyPassword="))
|
||||
proxyPassword = s.substring("-proxyPassword=".length());
|
||||
else if (s.equals("-debug"))
|
||||
showInfo = true;
|
||||
else
|
||||
cmdList.add(s);
|
||||
|
||||
String[] tokenized = StrUtils.tokenize(classPath, File.pathSeparator);
|
||||
int len = tokenized.length;
|
||||
|
||||
if (showInfo) {
|
||||
LogWindow.INSTANCE.setTerminateGame(() -> {
|
||||
try {
|
||||
Utils.shutdownForcely(1);
|
||||
} catch (Exception e) {
|
||||
MessageBox.Show(C.i18n("launcher.exit_failed"));
|
||||
HMCLog.err("Failed to shutdown forcely", e);
|
||||
}
|
||||
});
|
||||
try {
|
||||
File logFile = new File("hmclmc.log");
|
||||
if (!logFile.exists())
|
||||
logFile.createNewFile();
|
||||
FileOutputStream tc = new FileOutputStream(logFile);
|
||||
DoubleOutputStream out = new DoubleOutputStream(tc, System.out);
|
||||
System.setOut(new LauncherPrintStream(out));
|
||||
DoubleOutputStream err = new DoubleOutputStream(tc, System.err);
|
||||
System.setErr(new LauncherPrintStream(err));
|
||||
} catch (Exception e) {
|
||||
println("Failed to add log file appender.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
println("Arguments: {\n" + StrUtils.parseParams(" ", args, "\n") + "\n}");
|
||||
println("Main Class: " + mainClass);
|
||||
println("Class Path: {\n" + StrUtils.parseParams(" ", tokenized, "\n") + "\n}");
|
||||
SwingUtilities.invokeLater(() -> LogWindow.INSTANCE.setVisible(true));
|
||||
}
|
||||
|
||||
if (StrUtils.isNotBlank(proxyHost) && StrUtils.isNotBlank(proxyPort) && MathUtils.canParseInt(proxyPort)) {
|
||||
HMCLog.log("Initializing customized proxy");
|
||||
System.setProperty("http.proxyHost", proxyHost);
|
||||
System.setProperty("http.proxyPort", proxyPort);
|
||||
if (StrUtils.isNotBlank(proxyUsername) && StrUtils.isNotBlank(proxyPassword))
|
||||
Authenticator.setDefault(new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(proxyUsername, proxyPassword.toCharArray());
|
||||
}
|
||||
});
|
||||
//PROXY = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(Settings.getInstance().getProxyHost(), Integer.parseInt(Settings.getInstance().getProxyPort())));
|
||||
} else {
|
||||
//PROXY = Proxy.NO_PROXY;
|
||||
}
|
||||
|
||||
URL[] urls = new URL[len];
|
||||
|
||||
try {
|
||||
for (int j = 0; j < len; j++)
|
||||
urls[j] = new File(tokenized[j]).toURI().toURL();
|
||||
} catch (Throwable e) {
|
||||
MessageBox.Show(C.i18n("crash.main_class_not_found"));
|
||||
println("Failed to get classpath.");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
Method minecraftMain;
|
||||
URLClassLoader ucl = new URLClassLoader(urls, URLClassLoader.getSystemClassLoader().getParent());
|
||||
Thread.currentThread().setContextClassLoader(ucl);
|
||||
try {
|
||||
minecraftMain = ucl.loadClass(mainClass).getMethod("main", String[].class);
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException t) {
|
||||
MessageBox.Show(C.i18n("crash.main_class_not_found"));
|
||||
println("Minecraft main class not found.");
|
||||
t.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
println("*** Launching Game ***");
|
||||
|
||||
int flag = 0;
|
||||
try {
|
||||
minecraftMain.invoke(null, new Object[] { (String[]) cmdList.toArray(new String[cmdList.size()]) });
|
||||
} catch (Throwable throwable) {
|
||||
String trace = StrUtils.getStackTrace(throwable);
|
||||
final String advice = MinecraftCrashAdvicer.getAdvice(trace);
|
||||
MessageBox.Show(C.i18n("crash.minecraft") + ": " + advice);
|
||||
|
||||
System.err.println(C.i18n("crash.minecraft"));
|
||||
System.err.println(advice);
|
||||
System.err.println(trace);
|
||||
LogWindow.INSTANCE.setExit(() -> true);
|
||||
LogWindow.INSTANCE.setVisible(true);
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
println("*** Game Exited ***");
|
||||
try {
|
||||
Utils.shutdownForcely(flag);
|
||||
} catch (Exception e) {
|
||||
MessageBox.Show(C.i18n("launcher.exit_failed"));
|
||||
HMCLog.err("Failed to shutdown forcely", e);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* static Object getShutdownHaltLock() {
|
||||
* try {
|
||||
* Class z = Class.forName("java.lang.Shutdown");
|
||||
* Field haltLock = z.getDeclaredField("haltLock");
|
||||
* haltLock.setAccessible(true);
|
||||
* return haltLock.get(null);
|
||||
* } catch (Throwable ex) {
|
||||
* ex.printStackTrace();
|
||||
* return new Object();
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
}
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Authenticator;
|
||||
import java.net.PasswordAuthentication;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.text.ParseException;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
|
||||
import org.jackhuang.hellominecraft.launcher.core.launch.GameLauncher;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.CrashReporter;
|
||||
import org.jackhuang.hellominecraft.utils.logging.Configuration;
|
||||
import org.jackhuang.hellominecraft.utils.logging.appender.ConsoleAppender;
|
||||
import org.jackhuang.hellominecraft.utils.logging.layout.DefaultLayout;
|
||||
import org.jackhuang.hellominecraft.utils.views.LogWindow;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.launcher.utils.upgrade.IUpgrader;
|
||||
import org.jackhuang.hellominecraft.launcher.views.MainFrame;
|
||||
import org.jackhuang.hellominecraft.lookandfeel.HelloMinecraftLookAndFeel;
|
||||
import org.jackhuang.hellominecraft.utils.MathUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Main implements Runnable {
|
||||
|
||||
private static final X509TrustManager XTM = new X509TrustManager() {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
private static final HostnameVerifier HNV = (hostname, session) -> true;
|
||||
|
||||
static {
|
||||
SSLContext sslContext = null;
|
||||
|
||||
try {
|
||||
sslContext = SSLContext.getInstance("TLS");
|
||||
X509TrustManager[] xtmArray = new X509TrustManager[] { XTM };
|
||||
sslContext.init(null, xtmArray, new java.security.SecureRandom());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
}
|
||||
if (sslContext != null)
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
|
||||
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(HNV);
|
||||
}
|
||||
|
||||
public static final String LAUNCHER_NAME = "Hello Minecraft! Launcher";
|
||||
public static final byte VERSION_FIRST = 2, VERSION_SECOND = 3, VERSION_THIRD = 5, VERSION_FORTH = 9;
|
||||
public static final int MINIMUM_LAUNCHER_VERSION = 16;
|
||||
//public static Proxy PROXY;
|
||||
|
||||
/**
|
||||
* Make the version of HMCL.
|
||||
*
|
||||
* @return the version: firstVer.secondVer.thirdVer
|
||||
*/
|
||||
public static String makeVersion() {
|
||||
return "" + VERSION_FIRST + '.' + VERSION_SECOND + '.' + VERSION_THIRD + '.' + VERSION_FORTH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the main window title.
|
||||
*
|
||||
* @return the MainWindow title.
|
||||
*/
|
||||
public static String makeTitle() {
|
||||
return LAUNCHER_NAME + ' ' + makeVersion();
|
||||
}
|
||||
|
||||
public static final Main INSTANCE = new Main();
|
||||
public static HelloMinecraftLookAndFeel LOOK_AND_FEEL;
|
||||
|
||||
@SuppressWarnings({ "CallToPrintStackTrace", "UseSpecificCatch" })
|
||||
public static void main(String[] args) throws IOException {
|
||||
{
|
||||
//PluginManager.getServerPlugin();
|
||||
|
||||
if (IUpgrader.NOW_UPGRADER.parseArguments(new VersionNumber(VERSION_FIRST, VERSION_SECOND, VERSION_THIRD), args))
|
||||
return;
|
||||
|
||||
System.setProperty("sun.java2d.noddraw", "true");
|
||||
Thread.setDefaultUncaughtExceptionHandler(new CrashReporter(true));
|
||||
|
||||
try {
|
||||
File file = new File("hmcl.log");
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
Configuration.DEFAULT.appenders.add(new ConsoleAppender("File", new DefaultLayout(), true, new FileOutputStream(file), true));
|
||||
} catch (IOException ex) {
|
||||
System.err.println("Failed to add log appender File because an error occurred while creating or opening hmcl.log");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
HMCLog.log("*** " + Main.makeTitle() + " ***");
|
||||
|
||||
LogWindow.INSTANCE.clean();
|
||||
LogWindow.INSTANCE.setTerminateGame(GameLauncher.PROCESS_MANAGER::stopAllProcesses);
|
||||
|
||||
try {
|
||||
LOOK_AND_FEEL = new HelloMinecraftLookAndFeel(Settings.getInstance().getTheme().settings);
|
||||
UIManager.setLookAndFeel(LOOK_AND_FEEL);
|
||||
} catch (ParseException | UnsupportedLookAndFeelException ex) {
|
||||
HMCLog.warn("Failed to set look and feel...", ex);
|
||||
}
|
||||
|
||||
Settings.UPDATE_CHECKER.outdated.register(IUpgrader.NOW_UPGRADER);
|
||||
Settings.UPDATE_CHECKER.process(false).reg(t -> Main.invokeUpdate()).execute();
|
||||
|
||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyHost()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPort()) && MathUtils.canParseInt(Settings.getInstance().getProxyPort())) {
|
||||
HMCLog.log("Initializing customized proxy");
|
||||
System.setProperty("http.proxyHost", Settings.getInstance().getProxyHost());
|
||||
System.setProperty("http.proxyPort", Settings.getInstance().getProxyPort());
|
||||
if (StrUtils.isNotBlank(Settings.getInstance().getProxyUserName()) && StrUtils.isNotBlank(Settings.getInstance().getProxyPassword()))
|
||||
Authenticator.setDefault(new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(Settings.getInstance().getProxyUserName(), Settings.getInstance().getProxyPassword().toCharArray());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
PluginManager.NOW_PLUGIN.showUI();
|
||||
} catch (Throwable t) {
|
||||
new CrashReporter(false).uncaughtException(Thread.currentThread(), t);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
GameLauncher.PROCESS_MANAGER.stopAllProcesses();
|
||||
}
|
||||
|
||||
public static void invokeUpdate() {
|
||||
MainFrame.INSTANCE.invokeUpdate();
|
||||
}
|
||||
|
||||
public static ImageIcon getIcon(String path) {
|
||||
try {
|
||||
return new ImageIcon(Main.class.getResource("/org/jackhuang/hellominecraft/launcher/" + path));
|
||||
} catch (Exception e) {
|
||||
HMCLog.err("Failed to load icon", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.api;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.Profile;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface IPlugin {
|
||||
|
||||
/**
|
||||
* You can modify the application actions by this method.
|
||||
*
|
||||
* @param profile info to the Minecraft Loader
|
||||
*
|
||||
* @return For example, you can implement IMinecraftProvider to support
|
||||
* MultiMC
|
||||
*/
|
||||
IMinecraftService provideMinecraftService(Profile profile);
|
||||
|
||||
/**
|
||||
* Register authenticators by calling IAuthenticator.LOGINS.add.
|
||||
*
|
||||
* @param apply call apply.accept(your authenticator)
|
||||
*/
|
||||
void onRegisterAuthenticators(Consumer<IAuthenticator> apply);
|
||||
|
||||
/**
|
||||
* Open your customized UI.
|
||||
*/
|
||||
void showUI();
|
||||
|
||||
/**
|
||||
* Add your server ip or modify the access token.
|
||||
*
|
||||
* @param result What you want.
|
||||
*/
|
||||
void onProcessingLoginResult(UserProfileProvider result) throws AuthenticationException;
|
||||
|
||||
void onInitializingProfile(Profile p);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.api;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.DefaultPlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class PluginManager {
|
||||
|
||||
public static IPlugin NOW_PLUGIN = new DefaultPlugin();
|
||||
|
||||
public static void getServerPlugin() {
|
||||
try {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
Class c = cl.loadClass("org.jackhuang.hellominecraft.launcher.servers.ServerPlugin");
|
||||
IPlugin p = (IPlugin) c.newInstance();
|
||||
NOW_PLUGIN = p;
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
} catch (Exception e) {
|
||||
HMCLog.err("Failed to new instance");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huang
|
||||
*/
|
||||
public final class MCUtils {
|
||||
|
||||
public static File getWorkingDirectory(String baseName) {
|
||||
String userhome = System.getProperty("user.home", ".");
|
||||
File file;
|
||||
switch (OS.os()) {
|
||||
case LINUX:
|
||||
file = new File(userhome, '.' + baseName + '/');
|
||||
break;
|
||||
case WINDOWS:
|
||||
String appdata = System.getenv("APPDATA");
|
||||
if (appdata != null)
|
||||
file = new File(appdata, "." + baseName + '/');
|
||||
else
|
||||
file = new File(userhome, '.' + baseName + '/');
|
||||
break;
|
||||
case OSX:
|
||||
file = new File(userhome, "Library/Application Support/" + baseName);
|
||||
break;
|
||||
default:
|
||||
file = new File(userhome, baseName + '/');
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
public static File getLocation() {
|
||||
return getWorkingDirectory("minecraft");
|
||||
}
|
||||
|
||||
public static boolean is16Folder(String path) {
|
||||
path = IOUtils.addSeparator(path);
|
||||
return new File(path, "versions").exists();
|
||||
}
|
||||
|
||||
public static String minecraft() {
|
||||
if (OS.os() == OS.OSX)
|
||||
return "minecraft";
|
||||
return ".minecraft";
|
||||
}
|
||||
|
||||
public static File getInitGameDir() {
|
||||
File gameDir = IOUtils.currentDir();
|
||||
if (gameDir.exists()) {
|
||||
gameDir = new File(gameDir, MCUtils.minecraft());
|
||||
if (!gameDir.exists()) {
|
||||
File newFile = MCUtils.getLocation();
|
||||
if (newFile.exists())
|
||||
gameDir = newFile;
|
||||
}
|
||||
}
|
||||
return gameDir;
|
||||
}
|
||||
|
||||
public static String profile = "{\"selectedProfile\": \"(Default)\",\"profiles\": {\"(Default)\": {\"name\": \"(Default)\"}},\"clientToken\": \"88888888-8888-8888-8888-888888888888\"}";
|
||||
|
||||
public static void tryWriteProfile(File gameDir) throws IOException {
|
||||
File file = new File(gameDir, "launcher_profiles.json");
|
||||
if (!file.exists())
|
||||
FileUtils.writeStringToFile(file, profile);
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ModInfo implements Comparable<ModInfo> {
|
||||
|
||||
public File location;
|
||||
public String modid, name, description, author, version, mcversion, url, updateUrl, credits;
|
||||
public String[] authorList;
|
||||
|
||||
public boolean isActive() {
|
||||
return !location.getName().endsWith(".disabled");
|
||||
}
|
||||
|
||||
public void reverseModState() {
|
||||
File f = location, newf;
|
||||
if (f.getName().endsWith(".disabled"))
|
||||
newf = new File(f.getParentFile(), f.getName().substring(0, f.getName().length() - ".disabled".length()));
|
||||
else
|
||||
newf = new File(f.getParentFile(), f.getName() + ".disabled");
|
||||
if (f.renameTo(newf))
|
||||
location = newf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ModInfo o) {
|
||||
return getFileName().toLowerCase().compareTo(o.getFileName().toLowerCase());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name == null ? FileUtils.removeExtension(location.getName()) : name;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
if (authorList != null && authorList.length > 0)
|
||||
return StrUtils.parseParams("", authorList, ", ");
|
||||
else if (StrUtils.isNotBlank(author))
|
||||
return author;
|
||||
else
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj != null && obj instanceof ModInfo && (((ModInfo) obj).location == location || ((ModInfo) obj).location.equals(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return location.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getFileName();
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
String n = location.getName();
|
||||
return FileUtils.removeExtension(isActive() ? n : n.substring(0, n.length() - ".disabled".length()));
|
||||
}
|
||||
|
||||
public static boolean isFileMod(File file) {
|
||||
if (file == null)
|
||||
return false;
|
||||
String name = file.getName();
|
||||
boolean disabled = name.endsWith(".disabled");
|
||||
if (disabled)
|
||||
name = name.substring(0, name.length() - ".disabled".length());
|
||||
return name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith("litemod");
|
||||
}
|
||||
|
||||
private static ModInfo getForgeModInfo(File f, ZipFile jar, ZipEntry entry) throws IOException {
|
||||
ModInfo i = new ModInfo();
|
||||
i.location = f;
|
||||
List<ModInfo> m = C.gson.fromJson(new InputStreamReader(jar.getInputStream(entry)),
|
||||
new TypeToken<List<ModInfo>>() {
|
||||
}.getType());
|
||||
if (m != null && m.size() > 0) {
|
||||
i = m.get(0);
|
||||
i.location = f;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
private static ModInfo getLiteLoaderModInfo(File f, ZipFile jar, ZipEntry entry) throws IOException {
|
||||
ModInfo m = C.gson.fromJson(new InputStreamReader(jar.getInputStream(entry)),
|
||||
ModInfo.class);
|
||||
if (m == null)
|
||||
m = new ModInfo();
|
||||
m.location = f;
|
||||
return m;
|
||||
}
|
||||
|
||||
public static ModInfo readModInfo(File f) {
|
||||
ModInfo i = new ModInfo();
|
||||
i.location = f;
|
||||
try {
|
||||
try (ZipFile jar = new ZipFile(f)) {
|
||||
ZipEntry entry = jar.getEntry("mcmod.info");
|
||||
if (entry != null)
|
||||
return getForgeModInfo(f, jar, entry);
|
||||
entry = jar.getEntry("litemod.json");
|
||||
if (entry != null)
|
||||
return getLiteLoaderModInfo(f, jar, entry);
|
||||
return i;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
HMCLog.warn("File " + f + " is not a jar.", ex);
|
||||
} catch (JsonSyntaxException ignore) {
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.assets;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AssetsIndex {
|
||||
|
||||
public static final String DEFAULT_ASSET_NAME = "legacy";
|
||||
private Map<String, AssetsObject> objects;
|
||||
private boolean virtual;
|
||||
|
||||
public AssetsIndex() {
|
||||
this.objects = new LinkedHashMap();
|
||||
}
|
||||
|
||||
public Map<String, AssetsObject> getFileMap() {
|
||||
return this.objects;
|
||||
}
|
||||
|
||||
public Set<AssetsObject> getUniqueObjects() {
|
||||
return new HashSet(this.objects.values());
|
||||
}
|
||||
|
||||
public boolean isVirtual() {
|
||||
return this.virtual;
|
||||
}
|
||||
}
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.assets;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.OverridableSwingWorker;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AssetsMojangLoader extends IAssetsHandler {
|
||||
|
||||
public AssetsMojangLoader(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OverridableSwingWorker<String[]> getList(final MinecraftVersion mv, final IMinecraftAssetService mp) {
|
||||
return new OverridableSwingWorker<String[]>() {
|
||||
@Override
|
||||
protected void work() throws Exception {
|
||||
if (mv == null)
|
||||
throw new IllegalArgumentException("AssetsMojangLoader: null argument: MinecraftVersion");
|
||||
String assetsId = mv.assets == null ? "legacy" : mv.assets;
|
||||
File assets = mp.getAssets();
|
||||
HMCLog.log("Gathering asset index: " + assetsId);
|
||||
File f = IOUtils.tryGetCanonicalFile(new File(assets, "indexes/" + assetsId + ".json"));
|
||||
if (!f.exists() && !mp.downloadMinecraftAssetsIndex(assetsId))
|
||||
throw new IllegalStateException("Failed to get index json");
|
||||
|
||||
String result = FileUtils.readFileToString(f);
|
||||
if (StrUtils.isBlank(result))
|
||||
throw new IllegalStateException("Index json is empty, please redownload it!");
|
||||
AssetsIndex o = C.gson.fromJson(result, AssetsIndex.class);
|
||||
assetsDownloadURLs = new ArrayList<>();
|
||||
assetsLocalNames = new ArrayList<>();
|
||||
ArrayList<String> al = new ArrayList<>();
|
||||
contents = new ArrayList<>();
|
||||
if (o != null && o.getFileMap() != null)
|
||||
for (Map.Entry<String, AssetsObject> e : o.getFileMap().entrySet()) {
|
||||
Contents c = new Contents();
|
||||
c.eTag = e.getValue().getHash();
|
||||
c.key = c.eTag.substring(0, 2) + "/" + e.getValue().getHash();
|
||||
c.size = e.getValue().getSize();
|
||||
contents.add(c);
|
||||
assetsDownloadURLs.add(c.key);
|
||||
assetsLocalNames.add(new File(assets, "objects" + File.separator + c.key.replace("/", File.separator)));
|
||||
al.add(e.getKey());
|
||||
}
|
||||
|
||||
publish(al.toArray(new String[1]));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task getDownloadTask(IDownloadProvider sourceType) {
|
||||
return new AssetsTask(sourceType.getAssetsDownloadURL());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVersionAllowed(String formattedVersion) {
|
||||
VersionNumber ur = VersionNumber.check(formattedVersion);
|
||||
if (ur == null)
|
||||
return false;
|
||||
return VersionNumber.check("1.6.0").compareTo(ur) <= 0;
|
||||
}
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.assets;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AssetsObject {
|
||||
|
||||
private String hash;
|
||||
private long size;
|
||||
|
||||
public AssetsObject() {
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
AssetsObject that = (AssetsObject) o;
|
||||
if (this.size != that.size)
|
||||
return false;
|
||||
return this.hash.equals(that.hash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = this.hash.hashCode();
|
||||
result = 31 * result + (int) (this.size ^ this.size >>> 32);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.assets;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.IDownloadProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.code.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.OverridableSwingWorker;
|
||||
|
||||
/**
|
||||
* Assets
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IAssetsHandler {
|
||||
|
||||
protected ArrayList<String> assetsDownloadURLs;
|
||||
protected ArrayList<File> assetsLocalNames;
|
||||
protected final String name;
|
||||
protected List<Contents> contents;
|
||||
|
||||
public IAssetsHandler(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static final IAssetsHandler ASSETS_HANDLER;
|
||||
|
||||
static {
|
||||
ASSETS_HANDLER = new AssetsMojangLoader(C.i18n("assets.list.1_7_3_after"));
|
||||
}
|
||||
|
||||
/**
|
||||
* interface name
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* All the files assets needed
|
||||
*
|
||||
* @param mv The version that needs assets
|
||||
* @param mp Asset Service
|
||||
* @param x finished event
|
||||
*/
|
||||
public abstract OverridableSwingWorker<String[]> getList(MinecraftVersion mv, IMinecraftAssetService mp);
|
||||
|
||||
/**
|
||||
* Will be invoked when the user invoked "Download all assets".
|
||||
*
|
||||
* @param sourceType Download Source
|
||||
*
|
||||
* @return Download File Task
|
||||
*/
|
||||
public abstract Task getDownloadTask(IDownloadProvider sourceType);
|
||||
|
||||
public abstract boolean isVersionAllowed(String formattedVersion);
|
||||
|
||||
protected class AssetsTask extends Task {
|
||||
|
||||
ArrayList<Task> al;
|
||||
String u;
|
||||
|
||||
public AssetsTask(String url) {
|
||||
this.u = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() {
|
||||
if (assetsDownloadURLs == null)
|
||||
throw new IllegalStateException(C.i18n("assets.not_refreshed"));
|
||||
int max = assetsDownloadURLs.size();
|
||||
al = new ArrayList<>();
|
||||
int hasDownloaded = 0;
|
||||
for (int i = 0; i < max; i++) {
|
||||
String mark = assetsDownloadURLs.get(i);
|
||||
String url = u + mark;
|
||||
File location = assetsLocalNames.get(i);
|
||||
if (!location.getParentFile().exists())
|
||||
location.getParentFile().mkdirs();
|
||||
if (location.isDirectory())
|
||||
continue;
|
||||
boolean need = true;
|
||||
try {
|
||||
if (location.exists()) {
|
||||
FileInputStream fis = new FileInputStream(location);
|
||||
String sha = DigestUtils.sha1Hex(NetUtils.getBytesFromStream(fis));
|
||||
IOUtils.closeQuietly(fis);
|
||||
if (contents.get(i).eTag.equals(sha)) {
|
||||
hasDownloaded++;
|
||||
HMCLog.log("File " + assetsLocalNames.get(i) + " has downloaded successfully, skipped downloading.");
|
||||
if (ppl != null)
|
||||
ppl.setProgress(this, hasDownloaded, max);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
HMCLog.warn("Failed to get hash: " + location, e);
|
||||
need = !location.exists();
|
||||
}
|
||||
if (need)
|
||||
al.add(new FileDownloadTask(url, location).setTag(mark));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task> getAfterTasks() {
|
||||
return al;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("assets.download");
|
||||
}
|
||||
}
|
||||
}
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.assets;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftAssetService extends IMinecraftAssetService {
|
||||
|
||||
public MinecraftAssetService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task downloadAssets(final String mcVersion) {
|
||||
return new Task() {
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
IAssetsHandler type = IAssetsHandler.ASSETS_HANDLER;
|
||||
type.getList(service.version().getVersionById(mcVersion), service.asset())
|
||||
.reg((t) -> TaskWindow.getInstance().addTask(type.getDownloadTask(service.getDownloadType().getProvider())).start()).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "Download Assets";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean refreshAssetsIndex(String id) {
|
||||
MinecraftVersion mv = service.version().getVersionById(id);
|
||||
if (mv == null)
|
||||
return false;
|
||||
return downloadMinecraftAssetsIndex(mv.assets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean downloadMinecraftAssetsIndex(String assetsId) {
|
||||
String aurl = service.getDownloadType().getProvider().getIndexesDownloadURL();
|
||||
|
||||
File assetsLocation = getAssets();
|
||||
assetsLocation.mkdirs();
|
||||
File assetsIndex = new File(assetsLocation, "indexes/" + assetsId + ".json");
|
||||
File renamed = null;
|
||||
if (assetsIndex.exists()) {
|
||||
renamed = new File(assetsLocation, "indexes/" + assetsId + "-renamed.json");
|
||||
assetsIndex.renameTo(renamed);
|
||||
}
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(aurl + assetsId + ".json", IOUtils.tryGetCanonicalFile(assetsIndex)).setTag(assetsId + ".json"))
|
||||
.start()) {
|
||||
if (renamed != null)
|
||||
renamed.delete();
|
||||
return true;
|
||||
}
|
||||
if (renamed != null)
|
||||
renamed.renameTo(assetsIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getAssets() {
|
||||
return new File(service.baseDirectory(), "assets");
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getAssetObject(String assetVersion, String name) throws IOException {
|
||||
File assetsDir = getAssets();
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectsDir = new File(assetsDir, "objects");
|
||||
File indexFile = new File(indexDir, assetVersion + ".json");
|
||||
try {
|
||||
AssetsIndex index = (AssetsIndex) C.gson.fromJson(FileUtils.readFileToString(indexFile, "UTF-8"), AssetsIndex.class);
|
||||
|
||||
String hash = ((AssetsObject) index.getFileMap().get(name)).getHash();
|
||||
return new File(objectsDir, hash.substring(0, 2) + "/" + hash);
|
||||
} catch (JsonSyntaxException e) {
|
||||
throw new IOException("Assets file format malformed.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import org.jackhuang.hellominecraft.utils.code.DigestUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class BestLogin extends IAuthenticator {
|
||||
|
||||
public BestLogin(String clientToken) {
|
||||
super(clientToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider login(LoginInfo info) throws AuthenticationException {
|
||||
try {
|
||||
String request = "bl:l:" + info.username + ":" + DigestUtils.sha1Hex(info.password);
|
||||
|
||||
Socket socket = new Socket("auth.zhh0000zhh.com", 8);
|
||||
OutputStream os = socket.getOutputStream();
|
||||
os.write(request.length());
|
||||
os.write(request.getBytes());
|
||||
|
||||
UserProfileProvider lr = new UserProfileProvider();
|
||||
|
||||
InputStream is = socket.getInputStream();
|
||||
int code = is.read();
|
||||
switch (code) {
|
||||
case -1:
|
||||
throw new AuthenticationException("internet error.");
|
||||
case 200:
|
||||
throw new AuthenticationException("server restarting.");
|
||||
case 255:
|
||||
throw new AuthenticationException("unknown error");
|
||||
case 3:
|
||||
throw new AuthenticationException("unregistered.");
|
||||
case 50:
|
||||
throw new AuthenticationException("please update your launcher and act your account.");
|
||||
case 2:
|
||||
throw new AuthenticationException("wrong password.");
|
||||
case 100:
|
||||
throw new AuthenticationException("server reloading.");
|
||||
case 0:
|
||||
byte[] b = new byte[64];
|
||||
is.read(b, 0, b.length);
|
||||
String[] ss = new String(b).split(":");
|
||||
lr.setUserName(info.username);
|
||||
lr.setUserId(ss[1]);
|
||||
lr.setSession(ss[0]);
|
||||
lr.setAccessToken(ss[0]);
|
||||
break;
|
||||
}
|
||||
lr.setUserType("Legacy");
|
||||
return lr;
|
||||
} catch (IOException t) {
|
||||
throw new AuthenticationException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return "best";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "BestLogin";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider loginBySettings() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
}
|
||||
|
||||
}
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
|
||||
|
||||
/**
|
||||
* Login interface
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IAuthenticator {
|
||||
|
||||
public static final List<IAuthenticator> LOGINS = new ArrayList<>();
|
||||
|
||||
static {
|
||||
PluginManager.NOW_PLUGIN.onRegisterAuthenticators(LOGINS::add);
|
||||
}
|
||||
|
||||
protected String clientToken, username;
|
||||
|
||||
public IAuthenticator(String clientToken) {
|
||||
this.clientToken = clientToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login Method
|
||||
*
|
||||
* @param info username & password
|
||||
*
|
||||
* @return login result
|
||||
*
|
||||
* @throws
|
||||
* org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException
|
||||
*/
|
||||
public abstract UserProfileProvider login(LoginInfo info) throws AuthenticationException;
|
||||
|
||||
public abstract String id();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return the name of login method.
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* Has password?
|
||||
*
|
||||
* @return has password?
|
||||
*/
|
||||
public boolean hasPassword() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isLoggedIn() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setRememberMe(boolean is) {
|
||||
|
||||
}
|
||||
|
||||
public abstract UserProfileProvider loginBySettings() throws AuthenticationException;
|
||||
|
||||
public abstract void logout();
|
||||
|
||||
public Map onSaveSettings() {
|
||||
HashMap m = new HashMap();
|
||||
m.put("IAuthenticator_UserName", username);
|
||||
return m;
|
||||
}
|
||||
|
||||
public void onLoadSettings(Map m) {
|
||||
if (m == null)
|
||||
return;
|
||||
username = (String) m.get("IAuthenticator_UserName");
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String s) {
|
||||
username = s;
|
||||
}
|
||||
}
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.code.DigestUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class OfflineAuthenticator extends IAuthenticator {
|
||||
|
||||
Map<String, String> uuidMap = new HashMap<>();
|
||||
|
||||
public OfflineAuthenticator(String clientToken) {
|
||||
super(clientToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadSettings(Map m) {
|
||||
super.onLoadSettings(m);
|
||||
if (m == null)
|
||||
return;
|
||||
Object o = m.get("uuidMap");
|
||||
if (o != null && o instanceof Map)
|
||||
uuidMap = (Map<String, String>) o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map onSaveSettings() {
|
||||
Map m = super.onSaveSettings();
|
||||
m.put("uuidMap", m);
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider login(LoginInfo info) throws AuthenticationException {
|
||||
if (StrUtils.isBlank(info.username))
|
||||
throw new AuthenticationException(C.i18n("login.no_Player007"));
|
||||
UserProfileProvider result = new UserProfileProvider();
|
||||
result.setUserName(info.username);
|
||||
String uuid = getUUIDFromUserName(info.username);
|
||||
if (uuidMap != null && uuidMap.containsKey(uuid))
|
||||
uuid = uuidMap.get(info.username);
|
||||
else {
|
||||
if (uuidMap == null)
|
||||
uuidMap = new HashMap<>();
|
||||
uuidMap.put(info.username, uuid);
|
||||
}
|
||||
result.setSession(uuid);
|
||||
result.setUserId(uuid);
|
||||
result.setAccessToken(uuid);
|
||||
result.setUserType("Legacy");
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String getUUIDFromUserName(String str) {
|
||||
return DigestUtils.md5Hex(str);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return "offline";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return C.i18n("login.methods.offline");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassword() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider loginBySettings() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
}
|
||||
|
||||
}
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.code.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.views.Selector;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class SkinmeAuthenticator extends IAuthenticator {
|
||||
|
||||
public SkinmeAuthenticator(String clientToken) {
|
||||
super(clientToken);
|
||||
}
|
||||
|
||||
public String[] parseType1(String s) {
|
||||
return s.split(",");
|
||||
}
|
||||
|
||||
public String getCharacter(String user, String hash, String $char) throws Exception {
|
||||
return NetUtils.get(
|
||||
"http://www.skinme.cc/api/login.php?user=" + user + "&hash=" + hash + (($char == null) ? "" : ("&char=" + $char)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider login(LoginInfo info) throws AuthenticationException {
|
||||
UserProfileProvider req = new UserProfileProvider();
|
||||
if (info.username == null || !info.username.contains("@"))
|
||||
throw new AuthenticationException(C.i18n("login.not_email"));
|
||||
try {
|
||||
String usr = info.username.toLowerCase();
|
||||
String pwd = info.password;
|
||||
|
||||
String str = DigestUtils.sha1Hex(usr);
|
||||
String hashCode = DigestUtils.sha1Hex(DigestUtils.md5Hex(DigestUtils.sha1Hex(pwd) + pwd) + str);
|
||||
String data = getCharacter(usr, hashCode, null);
|
||||
String[] sl = data.split(":");
|
||||
if (null != sl[0])
|
||||
switch (sl[0]) {
|
||||
case "0":
|
||||
if (sl[1].contains("No Valid Character"))
|
||||
sl[1] = C.i18n("login.no_valid_character");
|
||||
throw new AuthenticationException(sl[1]);
|
||||
case "1": {
|
||||
String[] s = parseType1(sl[1]);
|
||||
req.setUserName(s[0]);
|
||||
req.setSession(s[1]);
|
||||
req.setUserId(s[1]);
|
||||
req.setAccessToken(s[1]);
|
||||
break;
|
||||
}
|
||||
case "2": {
|
||||
String[] charators = sl[1].split(";");
|
||||
int len = charators.length;
|
||||
String[] $char = new String[len];
|
||||
String[] user = new String[len];
|
||||
System.out.println(sl[1]);
|
||||
for (int i = 0; i < len; i++) {
|
||||
String[] charator = charators[i].split(",");
|
||||
$char[i] = charator[0];
|
||||
user[i] = charator[1];
|
||||
}
|
||||
Selector s = new Selector(null, user, C.i18n("login.choose_charactor"));
|
||||
s.setVisible(true);
|
||||
if (s.sel == Selector.FAILED_TO_SELECT)
|
||||
throw new AuthenticationException(C.i18n("message.cancelled"));
|
||||
else {
|
||||
int index = s.sel;
|
||||
String character = $char[index];
|
||||
sl = getCharacter(usr, hashCode, character).split(":");
|
||||
String[] s2 = parseType1(sl[1]);
|
||||
req.setUserName(s2[0]);
|
||||
req.setSession(s2[1]);
|
||||
req.setUserId(s2[1]);
|
||||
req.setAccessToken(s2[1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
req.setUserType("Legacy");
|
||||
return req;
|
||||
} catch (Exception e) {
|
||||
throw new AuthenticationException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return "skinme";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Skinme";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider loginBySettings() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
|
||||
}
|
||||
}
|
||||
-120
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.ServerInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class UserProfileProvider {
|
||||
|
||||
public String getUserName() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUserName(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public void setSession(String session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
if (accessToken == null)
|
||||
accessToken = "0";
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public String getUserProperties() {
|
||||
return userProperties;
|
||||
}
|
||||
|
||||
public void setUserProperties(String userProperties) {
|
||||
this.userProperties = userProperties;
|
||||
}
|
||||
|
||||
public String getUserPropertyMap() {
|
||||
return userPropertyMap;
|
||||
}
|
||||
|
||||
public void setUserPropertyMap(String userPropertyMap) {
|
||||
this.userPropertyMap = userPropertyMap;
|
||||
}
|
||||
|
||||
public String getOtherInfo() {
|
||||
return otherInfo;
|
||||
}
|
||||
|
||||
public void setOtherInfo(String otherInfo) {
|
||||
this.otherInfo = otherInfo;
|
||||
}
|
||||
|
||||
public String getClientIdentifier() {
|
||||
return clientIdentifier;
|
||||
}
|
||||
|
||||
public void setClientIdentifier(String clientIdentifier) {
|
||||
this.clientIdentifier = clientIdentifier;
|
||||
}
|
||||
|
||||
public String getUserType() {
|
||||
return userType;
|
||||
}
|
||||
|
||||
public void setUserType(String userType) {
|
||||
this.userType = userType;
|
||||
}
|
||||
|
||||
private String username = "";
|
||||
private String userId = "";
|
||||
private String session = "";
|
||||
private String accessToken = "";
|
||||
private String userProperties = "{}";
|
||||
private String userPropertyMap = "{}";
|
||||
private String otherInfo = "";
|
||||
private String clientIdentifier = "";
|
||||
private String userType = "Offline";
|
||||
private ServerInfo server = null;
|
||||
|
||||
public ServerInfo getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
public void setServer(ServerInfo server) {
|
||||
this.server = server;
|
||||
}
|
||||
}
|
||||
-140
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.net.Proxy;
|
||||
import java.util.Map;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.utils.views.Selector;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.GameProfile;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.PropertyMap;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.YggdrasilAuthentication;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil.UUIDTypeAdapter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class YggdrasilAuthenticator extends IAuthenticator {
|
||||
|
||||
YggdrasilAuthentication ua;
|
||||
|
||||
public YggdrasilAuthenticator(String clientToken) {
|
||||
super(clientToken);
|
||||
ua = new YggdrasilAuthentication(Proxy.NO_PROXY, clientToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider login(LoginInfo info) throws AuthenticationException {
|
||||
UserProfileProvider result = new UserProfileProvider();
|
||||
result.setUserType("mojang");
|
||||
if (ua.canPlayOnline()) {
|
||||
result.setUserName(info.username);
|
||||
result.setUserId(UUIDTypeAdapter.fromUUID(ua.getSelectedProfile().id));
|
||||
} else {
|
||||
String usr = info.username;
|
||||
if (info.username == null || !info.username.contains("@"))
|
||||
throw new AuthenticationException(C.i18n("login.not_email"));
|
||||
String pwd = info.password;
|
||||
|
||||
if (!ua.isLoggedIn())
|
||||
ua.setPassword(pwd);
|
||||
ua.setUsername(usr);
|
||||
ua.logIn();
|
||||
if (!ua.isLoggedIn())
|
||||
throw new AuthenticationException(C.i18n("login.wrong_password"));
|
||||
GameProfile selectedProfile = ua.getSelectedProfile();
|
||||
GameProfile[] profiles = ua.getAvailableProfiles();
|
||||
String username;
|
||||
if (selectedProfile == null)
|
||||
if (ArrayUtils.isNotEmpty(profiles)) {
|
||||
String[] names = new String[profiles.length];
|
||||
for (int i = 0; i < profiles.length; i++)
|
||||
names[i] = profiles[i].name;
|
||||
Selector s = new Selector(null, names, C.i18n("login.choose_charactor"));
|
||||
s.setVisible(true);
|
||||
selectedProfile = profiles[s.sel];
|
||||
username = names[s.sel];
|
||||
} else
|
||||
username = JOptionPane.showInputDialog(C.i18n("login.no_charactor"));
|
||||
else
|
||||
username = selectedProfile.name;
|
||||
result.setUserName(username);
|
||||
result.setUserId(selectedProfile == null ? OfflineAuthenticator.getUUIDFromUserName(username) : UUIDTypeAdapter.fromUUID(selectedProfile.id));
|
||||
}
|
||||
result.setUserProperties(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new PropertyMap.LegacySerializer()).create().toJson(ua.getUserProperties()));
|
||||
result.setUserPropertyMap(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create().toJson(ua.getUserProperties()));
|
||||
result.setAccessToken(ua.getAuthenticatedToken());
|
||||
result.setSession(ua.getAuthenticatedToken());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggedIn() {
|
||||
return ua.isLoggedIn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return "yggdrasil";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return C.i18n("login.methods.yggdrasil");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map onSaveSettings() {
|
||||
Map m = ua.saveForStorage();
|
||||
m.putAll(super.onSaveSettings());
|
||||
return m;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadSettings(Map settings) {
|
||||
super.onLoadSettings(settings);
|
||||
if (settings == null)
|
||||
return;
|
||||
ua.loadFromStorage(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProfileProvider loginBySettings() throws AuthenticationException {
|
||||
UserProfileProvider result = new UserProfileProvider();
|
||||
ua.logIn();
|
||||
if (!ua.isLoggedIn())
|
||||
throw new AuthenticationException(C.i18n("login.wrong_password"));
|
||||
GameProfile profile = ua.getSelectedProfile();
|
||||
result.setUserName(profile.name);
|
||||
result.setUserId(profile.id.toString());
|
||||
result.setUserProperties(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new PropertyMap.LegacySerializer()).create().toJson(ua.getUserProperties()));
|
||||
result.setUserPropertyMap(new GsonBuilder().registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create().toJson(ua.getUserProperties()));
|
||||
result.setAccessToken(ua.getAuthenticatedToken());
|
||||
result.setSession(ua.getAuthenticatedToken());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout() {
|
||||
ua.logOut();
|
||||
}
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class AuthenticationRequest {
|
||||
|
||||
public HashMap<String, Object> agent;
|
||||
public String username, password, clientToken;
|
||||
public boolean requestUser = true;
|
||||
|
||||
public AuthenticationRequest(String username, String password, String clientToken) {
|
||||
agent = new HashMap<>();
|
||||
agent.put("name", "Minecraft");
|
||||
agent.put("version", 1);
|
||||
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.clientToken = clientToken;
|
||||
}
|
||||
}
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.UUID;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
public class GameProfile {
|
||||
|
||||
public final UUID id;
|
||||
public final String name;
|
||||
public final PropertyMap properties = new PropertyMap();
|
||||
|
||||
public GameProfile(UUID id, String name) {
|
||||
if (id == null && StrUtils.isBlank(name))
|
||||
throw new IllegalArgumentException("Name and ID cannot both be blank");
|
||||
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return id != null && StrUtils.isNotBlank(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
System.out.println("hello?");
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
GameProfile that = (GameProfile) o;
|
||||
|
||||
if (id != null ? !id.equals(that.id) : that.id != null)
|
||||
return false;
|
||||
return name != null ? name.equals(that.name) : that.name == null;
|
||||
}
|
||||
|
||||
public static class GameProfileSerializer implements JsonSerializer<GameProfile>, JsonDeserializer<GameProfile> {
|
||||
|
||||
@Override
|
||||
public GameProfile deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
JsonObject object = (JsonObject) json;
|
||||
UUID id = object.has("id") ? (UUID) context.deserialize(object.get("id"), UUID.class) : null;
|
||||
String name = object.has("name") ? object.getAsJsonPrimitive("name").getAsString() : null;
|
||||
return new GameProfile(id, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(GameProfile src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject result = new JsonObject();
|
||||
if (src.id != null)
|
||||
result.add("id", context.serialize(src.id));
|
||||
if (src.name != null)
|
||||
result.addProperty("name", src.name);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
|
||||
public class PropertyMap extends HashMap<String, Property> {
|
||||
|
||||
public List<Map<String, String>> list() {
|
||||
List<Map<String, String>> properties = new ArrayList<>();
|
||||
for (Property profileProperty : values()) {
|
||||
Map<String, String> property = new HashMap<>();
|
||||
property.put("name", profileProperty.name);
|
||||
property.put("value", profileProperty.value);
|
||||
properties.add(property);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void fromList(List<Map<String, String>> list) {
|
||||
try {
|
||||
for (Map<String, String> propertyMap : list) {
|
||||
String name = propertyMap.get("name");
|
||||
String value = propertyMap.get("value");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
HMCLog.warn("Failed to deserialize properties", t);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Serializer implements JsonSerializer<PropertyMap>, JsonDeserializer<PropertyMap> {
|
||||
|
||||
@Override
|
||||
public PropertyMap deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
PropertyMap result = new PropertyMap();
|
||||
if ((json instanceof JsonObject)) {
|
||||
JsonObject object = (JsonObject) json;
|
||||
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet())
|
||||
if (entry.getValue() instanceof JsonArray)
|
||||
for (JsonElement element : (JsonArray) entry.getValue())
|
||||
result.put(entry.getKey(),
|
||||
new Property((String) entry.getKey(), element.getAsString()));
|
||||
} else if ((json instanceof JsonArray))
|
||||
for (JsonElement element : (JsonArray) json)
|
||||
if ((element instanceof JsonObject)) {
|
||||
JsonObject object = (JsonObject) element;
|
||||
String name = object.getAsJsonPrimitive("name").getAsString();
|
||||
String value = object.getAsJsonPrimitive("value").getAsString();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(PropertyMap src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonArray result = new JsonArray();
|
||||
for (Property property : src.values()) {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("name", property.name);
|
||||
object.addProperty("value", property.value);
|
||||
result.add(object);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static class LegacySerializer
|
||||
implements JsonSerializer<PropertyMap> {
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(PropertyMap src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject result = new JsonObject();
|
||||
for (String key : src.keySet()) {
|
||||
JsonArray values = new JsonArray();
|
||||
values.add(new JsonPrimitive(src.get(key).value));
|
||||
result.add(key, values);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil;
|
||||
|
||||
public class Response {
|
||||
|
||||
public String accessToken, clientToken;
|
||||
public GameProfile selectedProfile;
|
||||
public GameProfile[] availableProfiles;
|
||||
public User user;
|
||||
|
||||
public String error;
|
||||
public String errorMessage;
|
||||
public String cause;
|
||||
}
|
||||
-231
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.auth.yggdrasil;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.io.IOException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
public class YggdrasilAuthentication {
|
||||
|
||||
public static final Gson GSON = new GsonBuilder()
|
||||
.registerTypeAdapter(GameProfile.class, new GameProfile.GameProfileSerializer())
|
||||
.registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer())
|
||||
.registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).create();
|
||||
|
||||
protected static final String BASE_URL = "https://authserver.mojang.com/";
|
||||
protected static final URL ROUTE_AUTHENTICATE = NetUtils.constantURL(BASE_URL + "authenticate");
|
||||
protected static final URL ROUTE_REFRESH = NetUtils.constantURL(BASE_URL + "refresh");
|
||||
|
||||
protected static final String STORAGE_KEY_ACCESS_TOKEN = "accessToken";
|
||||
protected static final String STORAGE_KEY_PROFILE_NAME = "displayName";
|
||||
protected static final String STORAGE_KEY_PROFILE_ID = "uuid";
|
||||
protected static final String STORAGE_KEY_PROFILE_PROPERTIES = "profileProperties";
|
||||
protected static final String STORAGE_KEY_USER_NAME = "username";
|
||||
protected static final String STORAGE_KEY_USER_ID = "userid";
|
||||
protected static final String STORAGE_KEY_USER_PROPERTIES = "userProperties";
|
||||
|
||||
private final Proxy proxy;
|
||||
private final String clientToken;
|
||||
private final PropertyMap userProperties = new PropertyMap();
|
||||
|
||||
private String userid, username, password, accessToken;
|
||||
private GameProfile selectedProfile;
|
||||
private GameProfile[] profiles;
|
||||
private boolean isOnline;
|
||||
|
||||
public YggdrasilAuthentication(Proxy proxy, String clientToken) {
|
||||
this.proxy = proxy;
|
||||
this.clientToken = clientToken;
|
||||
}
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Get/Set">
|
||||
public void setUsername(String username) {
|
||||
if ((isLoggedIn()) && (canPlayOnline()))
|
||||
throw new IllegalStateException("Cannot change username while logged in & online");
|
||||
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
if ((isLoggedIn()) && (canPlayOnline()) && (StrUtils.isNotBlank(password)))
|
||||
throw new IllegalStateException("Cannot set password while logged in & online");
|
||||
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public GameProfile getSelectedProfile() {
|
||||
return this.selectedProfile;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return this.userid;
|
||||
}
|
||||
|
||||
public PropertyMap getUserProperties() {
|
||||
if (isLoggedIn())
|
||||
return (PropertyMap) userProperties.clone();
|
||||
return new PropertyMap();
|
||||
}
|
||||
|
||||
public GameProfile[] getAvailableProfiles() {
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public String getAuthenticatedToken() {
|
||||
return this.accessToken;
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
// <editor-fold defaultstate="collapsed" desc="Log In/Out">
|
||||
public boolean canPlayOnline() {
|
||||
return isLoggedIn() && getSelectedProfile() != null && this.isOnline;
|
||||
}
|
||||
|
||||
public boolean canLogIn() {
|
||||
return !canPlayOnline() && StrUtils.isNotBlank(username) && (StrUtils.isNotBlank(password) || StrUtils.isNotBlank(getAuthenticatedToken()));
|
||||
}
|
||||
|
||||
public boolean isLoggedIn() {
|
||||
return StrUtils.isNotBlank(this.accessToken);
|
||||
}
|
||||
|
||||
public void logIn() throws AuthenticationException {
|
||||
if (StrUtils.isBlank(username))
|
||||
throw new AuthenticationException(C.i18n("login.invalid_username"));
|
||||
|
||||
if (StrUtils.isNotBlank(getAuthenticatedToken())) {
|
||||
if (StrUtils.isBlank(getUserId()))
|
||||
if (StrUtils.isBlank(username))
|
||||
userid = username;
|
||||
else
|
||||
throw new AuthenticationException(C.i18n("login.invalid_uuid_and_username"));
|
||||
|
||||
loggedIn(ROUTE_REFRESH, new RefreshRequest(getAuthenticatedToken(), clientToken));
|
||||
} else if (StrUtils.isNotBlank(password))
|
||||
loggedIn(ROUTE_AUTHENTICATE, new AuthenticationRequest(username, password, clientToken));
|
||||
else
|
||||
throw new AuthenticationException(C.i18n("login.invalid_password"));
|
||||
}
|
||||
|
||||
private void loggedIn(URL url, Object input) throws AuthenticationException {
|
||||
try {
|
||||
String jsonResult = input == null ? NetUtils.get(url) : NetUtils.post(url, GSON.toJson(input), "application/json", proxy);
|
||||
Response response = (Response) GSON.fromJson(jsonResult, Response.class);
|
||||
|
||||
if (StrUtils.isNotBlank(response.error)) {
|
||||
HMCLog.err("Failed to log in, the auth server returned an error: " + response.error + ", message: " + response.errorMessage + ", cause: " + response.cause);
|
||||
if (response.errorMessage.contains("Invalid token"))
|
||||
response.errorMessage = C.i18n("login.invalid_token");
|
||||
throw new AuthenticationException("Request error: " + response.errorMessage);
|
||||
}
|
||||
|
||||
if (!clientToken.equals(response.clientToken))
|
||||
throw new AuthenticationException(C.i18n("login.changed_client_token"));
|
||||
|
||||
User user = response.user;
|
||||
userid = user != null && user.id != null ? user.id : username;
|
||||
|
||||
isOnline = true;
|
||||
profiles = response.availableProfiles;
|
||||
selectedProfile = response.selectedProfile;
|
||||
userProperties.clear();
|
||||
this.accessToken = response.accessToken;
|
||||
|
||||
if (user != null && user.properties != null)
|
||||
userProperties.putAll(user.properties);
|
||||
} catch (IOException | IllegalStateException | JsonParseException e) {
|
||||
throw new AuthenticationException(C.i18n("login.failed.connect_authentication_server"), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void logOut() {
|
||||
password = null;
|
||||
userid = null;
|
||||
selectedProfile = null;
|
||||
userProperties.clear();
|
||||
|
||||
accessToken = null;
|
||||
profiles = null;
|
||||
isOnline = false;
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
// <editor-fold defaultstate="collapsed" desc="Settings Storage">
|
||||
public void loadFromStorage(Map<String, Object> credentials) {
|
||||
logOut();
|
||||
|
||||
setUsername((String) credentials.get(STORAGE_KEY_USER_NAME));
|
||||
|
||||
if (credentials.containsKey(STORAGE_KEY_USER_ID))
|
||||
userid = (String) credentials.get(STORAGE_KEY_USER_ID);
|
||||
else
|
||||
userid = username;
|
||||
|
||||
if (credentials.containsKey(STORAGE_KEY_USER_PROPERTIES))
|
||||
userProperties.fromList((List<Map<String, String>>) credentials.get(STORAGE_KEY_USER_PROPERTIES));
|
||||
|
||||
if ((credentials.containsKey(STORAGE_KEY_PROFILE_NAME)) && (credentials.containsKey(STORAGE_KEY_PROFILE_ID))) {
|
||||
GameProfile profile = new GameProfile(UUIDTypeAdapter.fromString((String) credentials.get(STORAGE_KEY_PROFILE_ID)), (String) credentials.get(STORAGE_KEY_PROFILE_NAME));
|
||||
if (credentials.containsKey(STORAGE_KEY_PROFILE_PROPERTIES))
|
||||
profile.properties.fromList((List<Map<String, String>>) credentials.get(STORAGE_KEY_PROFILE_PROPERTIES));
|
||||
selectedProfile = profile;
|
||||
}
|
||||
|
||||
this.accessToken = (String) credentials.get(STORAGE_KEY_ACCESS_TOKEN);
|
||||
}
|
||||
|
||||
public Map<String, Object> saveForStorage() {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
if (username != null)
|
||||
result.put(STORAGE_KEY_USER_NAME, username);
|
||||
if (getUserId() != null)
|
||||
result.put(STORAGE_KEY_USER_ID, getUserId());
|
||||
|
||||
if (!getUserProperties().isEmpty())
|
||||
result.put(STORAGE_KEY_USER_PROPERTIES, getUserProperties().list());
|
||||
|
||||
GameProfile sel = getSelectedProfile();
|
||||
if (sel != null) {
|
||||
result.put(STORAGE_KEY_PROFILE_NAME, sel.name);
|
||||
result.put(STORAGE_KEY_PROFILE_ID, sel.id);
|
||||
if (!sel.properties.isEmpty())
|
||||
result.put(STORAGE_KEY_PROFILE_PROPERTIES, sel.properties.list());
|
||||
}
|
||||
|
||||
if (StrUtils.isNotBlank(getAuthenticatedToken()))
|
||||
result.put(STORAGE_KEY_ACCESS_TOKEN, getAuthenticatedToken());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// </editor-fold>
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class BMCLAPIDownloadProvider extends IDownloadProvider {
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getForgeInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.forge.MinecraftForgeVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getLiteLoaderInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.liteloader.LiteLoaderVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getOptiFineInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.optifine.bmcl.OptiFineBMCLVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLibraryDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/libraries";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/versions/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIndexesDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/indexes/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsListDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/versions/versions.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssetsDownloadURL() {
|
||||
return "http://bmclapi2.bangbang93.com/assets/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParsedLibraryDownloadURL(String str) {
|
||||
return str == null ? null : str.replace("http://files.minecraftforge.net/maven", "http://bmclapi2.bangbang93.com/maven");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToUseSelfURL() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public enum DownloadType {
|
||||
|
||||
Mojang(C.i18n("download.mojang"), new MojangDownloadProvider()),
|
||||
BMCL(C.i18n("download.BMCL"), new BMCLAPIDownloadProvider()),
|
||||
RapidData(C.i18n("download.rapid_data"), new RapidDataDownloadProvider()),
|
||||
Curse("Curse CDN", new CurseDownloadProvider());
|
||||
|
||||
private final String name;
|
||||
private final IDownloadProvider provider;
|
||||
|
||||
DownloadType(String a, IDownloadProvider provider) {
|
||||
name = a;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public IDownloadProvider getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private static DownloadType suggestedDownloadType = Mojang;
|
||||
|
||||
public static DownloadType getSuggestedDownloadType() {
|
||||
return suggestedDownloadType;
|
||||
}
|
||||
|
||||
public static void setSuggestedDownloadType(DownloadType suggestedDownloadType) {
|
||||
if (suggestedDownloadType == null)
|
||||
throw new IllegalArgumentException("download type should not be null.");
|
||||
DownloadType.suggestedDownloadType = suggestedDownloadType;
|
||||
}
|
||||
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerType;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IDownloadProvider {
|
||||
|
||||
public InstallerVersionList getInstallerByType(InstallerType type) {
|
||||
switch (type) {
|
||||
case Forge:
|
||||
return getForgeInstaller();
|
||||
case LiteLoader:
|
||||
return getLiteLoaderInstaller();
|
||||
case Optifine:
|
||||
return getOptiFineInstaller();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract InstallerVersionList getForgeInstaller();
|
||||
|
||||
public abstract InstallerVersionList getLiteLoaderInstaller();
|
||||
|
||||
public abstract InstallerVersionList getOptiFineInstaller();
|
||||
|
||||
public abstract String getLibraryDownloadURL();
|
||||
|
||||
public abstract String getVersionsDownloadURL();
|
||||
|
||||
public abstract String getIndexesDownloadURL();
|
||||
|
||||
public abstract String getVersionsListDownloadURL();
|
||||
|
||||
public abstract String getAssetsDownloadURL();
|
||||
|
||||
public abstract String getParsedLibraryDownloadURL(String str);
|
||||
|
||||
public abstract boolean isAllowedToUseSelfURL();
|
||||
}
|
||||
-164
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftDownloadService;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.IMinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.OverridableSwingWorker;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftRemoteVersion;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftRemoteVersions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftDownloadService extends IMinecraftDownloadService {
|
||||
|
||||
public MinecraftDownloadService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DownloadLibraryJob> getDownloadLibraries(MinecraftVersion mv) throws GameException {
|
||||
ArrayList<DownloadLibraryJob> downloadLibraries = new ArrayList<>();
|
||||
if (mv == null)
|
||||
return downloadLibraries;
|
||||
MinecraftVersion v = mv.resolve(service.version());
|
||||
if (v.libraries != null)
|
||||
for (IMinecraftLibrary l : v.libraries) {
|
||||
l.init();
|
||||
if (l.allow()) {
|
||||
File ff = l.getFilePath(service.baseDirectory());
|
||||
if (!ff.exists()) {
|
||||
String libURL = service.getDownloadType().getProvider().getLibraryDownloadURL() + "/";
|
||||
libURL = service.getDownloadType().getProvider().getParsedLibraryDownloadURL(l.getDownloadURL(libURL, service.getDownloadType()));
|
||||
if (libURL != null)
|
||||
downloadLibraries.add(new DownloadLibraryJob(l.name, libURL, ff));
|
||||
}
|
||||
}
|
||||
}
|
||||
return downloadLibraries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion downloadMinecraft(String id) {
|
||||
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
|
||||
File vpath = new File(service.baseDirectory(), "versions/" + id);
|
||||
File mvt = new File(vpath, id + ".json");
|
||||
File mvj = new File(vpath, id + ".jar");
|
||||
vpath.mkdirs();
|
||||
mvt.delete();
|
||||
mvj.delete();
|
||||
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(vurl + id + ".json", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".json"))
|
||||
.addTask(new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvj)).setTag(id + ".jar"))
|
||||
.start())
|
||||
try {
|
||||
return C.gson.fromJson(FileUtils.readFileToStringQuietly(mvt), MinecraftVersion.class);
|
||||
} catch (JsonSyntaxException ex) {
|
||||
HMCLog.err("Failed to parse minecraft version json.", ex);
|
||||
}
|
||||
else
|
||||
FileUtils.deleteDirectoryQuietly(vpath);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean downloadMinecraftJar(String id) {
|
||||
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
|
||||
File vpath = new File(service.baseDirectory(), "versions/" + id);
|
||||
File mvv = new File(vpath, id + ".jar"), moved = null;
|
||||
if (mvv.exists()) {
|
||||
moved = new File(vpath, id + "-renamed.jar");
|
||||
mvv.renameTo(moved);
|
||||
}
|
||||
File mvt = new File(vpath, id + ".jar");
|
||||
vpath.mkdirs();
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".jar"))
|
||||
.start()) {
|
||||
if (moved != null)
|
||||
moved.delete();
|
||||
return true;
|
||||
} else {
|
||||
mvt.delete();
|
||||
if (moved != null)
|
||||
moved.renameTo(mvt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task downloadMinecraftJarTo(String id, File mvt) {
|
||||
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
|
||||
return new FileDownloadTask(vurl + id + ".jar", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean downloadMinecraftVersionJson(String id) {
|
||||
String vurl = service.getDownloadType().getProvider().getVersionsDownloadURL() + id + "/";
|
||||
File vpath = new File(service.baseDirectory(), "versions/" + id);
|
||||
File mvv = new File(vpath, id + ".json"), moved = null;
|
||||
if (mvv.exists()) {
|
||||
moved = new File(vpath, id + "-renamed.json");
|
||||
mvv.renameTo(moved);
|
||||
}
|
||||
File mvt = new File(vpath, id + ".json");
|
||||
vpath.mkdirs();
|
||||
if (TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(vurl + id + ".json", IOUtils.tryGetCanonicalFile(mvt)).setTag(id + ".json"))
|
||||
.start()) {
|
||||
if (moved != null)
|
||||
moved.delete();
|
||||
return true;
|
||||
} else {
|
||||
mvt.delete();
|
||||
if (moved != null)
|
||||
moved.renameTo(mvt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OverridableSwingWorker<MinecraftRemoteVersion> getRemoteVersions() {
|
||||
return new OverridableSwingWorker<MinecraftRemoteVersion>() {
|
||||
@Override
|
||||
protected void work() throws Exception {
|
||||
MinecraftRemoteVersions r = C.gson.fromJson(NetUtils.get(service.getDownloadType().getProvider().getVersionsListDownloadURL()), MinecraftRemoteVersions.class);
|
||||
if (r != null && r.versions != null)
|
||||
publish(r.versions.toArray(new MinecraftRemoteVersion[0]));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MojangDownloadProvider extends IDownloadProvider {
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getForgeInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.forge.MinecraftForgeVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getLiteLoaderInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.liteloader.LiteLoaderVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallerVersionList getOptiFineInstaller() {
|
||||
return org.jackhuang.hellominecraft.launcher.core.installers.optifine.vanilla.OptiFineVersionList.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLibraryDownloadURL() {
|
||||
return "https://libraries.minecraft.net";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsDownloadURL() {
|
||||
return "http://s3.amazonaws.com/Minecraft.Download/versions/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIndexesDownloadURL() {
|
||||
return "http://s3.amazonaws.com/Minecraft.Download/indexes/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsListDownloadURL() {
|
||||
return "http://s3.amazonaws.com/Minecraft.Download/versions/versions.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAssetsDownloadURL() {
|
||||
return "http://resources.download.minecraft.net/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToUseSelfURL() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParsedLibraryDownloadURL(String str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.download;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class RapidDataDownloadProvider extends MojangDownloadProvider {
|
||||
|
||||
@Override
|
||||
public String getAssetsDownloadURL() {
|
||||
return "http://mirrors.rapiddata.org/resources.download.minecraft.net/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLibraryDownloadURL() {
|
||||
return "http://mirrors.rapiddata.org/libraries.minecraft.net";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIndexesDownloadURL() {
|
||||
return "http://mirrors.rapiddata.org/Minecraft.Download/indexes/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsDownloadURL() {
|
||||
return "http://mirrors.rapiddata.org/Minecraft.Download/versions/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionsListDownloadURL() {
|
||||
return "http://mirrors.rapiddata.org/Minecraft.Download/versions/versions.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParsedLibraryDownloadURL(String str) {
|
||||
return str == null ? null : str.replace("http://files.minecraftforge.net/maven", "http://mirrors.rapiddata.org/forge/maven");
|
||||
}
|
||||
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.forge.Install;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class InstallProfile {
|
||||
|
||||
@SerializedName("install")
|
||||
public Install install;
|
||||
@SerializedName("versionInfo")
|
||||
public MinecraftVersion versionInfo;
|
||||
}
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class InstallerVersionList implements Consumer<String[]> {
|
||||
|
||||
/**
|
||||
* Refresh installer versions list from the downloaded content.
|
||||
*
|
||||
* @param versions Minecraft versions you need to refresh
|
||||
*
|
||||
* @throws java.lang.Exception including network exceptions, IO exceptions.
|
||||
*/
|
||||
public abstract void refreshList(String[] versions) throws Exception;
|
||||
|
||||
/**
|
||||
* Installer name.
|
||||
*
|
||||
* @return installer name.
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* Get installers you want.
|
||||
*
|
||||
* @param mcVersion the installers to this Minecraft version.
|
||||
*
|
||||
* @return cached result.
|
||||
*/
|
||||
protected abstract List<InstallerVersion> getVersionsImpl(String mcVersion);
|
||||
|
||||
/**
|
||||
* Get installers you want, please cache this method's result to save time.
|
||||
*
|
||||
* @param mcVersion the installers to this Minecraft version.
|
||||
*
|
||||
* @return a copy of the cached data to prevent
|
||||
* ConcurrentModificationException.
|
||||
*/
|
||||
public List<InstallerVersion> getVersions(String mcVersion) {
|
||||
List<InstallerVersion> a = getVersionsImpl(mcVersion);
|
||||
if (a == null)
|
||||
return null;
|
||||
else
|
||||
return new ArrayList<>(a);
|
||||
}
|
||||
|
||||
public static class InstallerVersion implements Comparable<InstallerVersion> {
|
||||
|
||||
public String selfVersion, mcVersion;
|
||||
public String installer, universal;
|
||||
public String changelog;
|
||||
|
||||
public InstallerVersion(String selfVersion, String mcVersion) {
|
||||
this.selfVersion = selfVersion;
|
||||
this.mcVersion = mcVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(InstallerVersion o) {
|
||||
return selfVersion.compareTo(o.selfVersion);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InstallerVersionComparator implements Comparator<InstallerVersion> {
|
||||
|
||||
public static final InstallerVersionComparator INSTANCE = new InstallerVersionComparator();
|
||||
|
||||
@Override
|
||||
public int compare(InstallerVersion o1, InstallerVersion o2) {
|
||||
return o2.compareTo(o1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(String[] v) {
|
||||
try {
|
||||
refreshList(v);
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers;
|
||||
|
||||
import java.util.Comparator;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList.InstallerVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class InstallerVersionNewerComparator implements Comparator<InstallerVersion> {
|
||||
|
||||
@Override
|
||||
public int compare(InstallerVersion o1, InstallerVersion o2) {
|
||||
return -o1.compareTo(o2);
|
||||
}
|
||||
}
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftInstallerService;
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList.InstallerVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.forge.ForgeInstaller;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.liteloader.LiteLoaderInstaller;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.liteloader.LiteLoaderVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.optifine.OptiFineInstaller;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.optifine.vanilla.OptiFineDownloadFormatter;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskInfo;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class MinecraftInstallerService extends IMinecraftInstallerService {
|
||||
|
||||
public MinecraftInstallerService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task download(String installId, InstallerVersion v, InstallerType type) {
|
||||
switch (type) {
|
||||
case Forge:
|
||||
return downloadForge(installId, v);
|
||||
case Optifine:
|
||||
return downloadOptifine(installId, v);
|
||||
case LiteLoader:
|
||||
return downloadLiteLoader(installId, v);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task downloadForge(String installId, InstallerVersion v) {
|
||||
return new TaskInfo("Forge Downloader") {
|
||||
@Override
|
||||
public void executeTask() {
|
||||
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "forge-installer.jar");
|
||||
if (v.installer != null)
|
||||
TaskWindow.getInstance()
|
||||
.addTask(new FileDownloadTask(service.getDownloadType().getProvider().getParsedLibraryDownloadURL(v.installer), filepath).setTag("forge"))
|
||||
.addTask(new ForgeInstaller(service, filepath, v))
|
||||
.start();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task downloadOptifine(String installId, InstallerVersion v) {
|
||||
return new TaskInfo("OptiFine Downloader") {
|
||||
@Override
|
||||
public void executeTask() {
|
||||
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "optifine-installer.jar");
|
||||
if (v.installer != null) {
|
||||
OptiFineDownloadFormatter task = new OptiFineDownloadFormatter(v.installer);
|
||||
TaskWindow.getInstance().addTask(task)
|
||||
.addTask(new FileDownloadTask(filepath).registerPreviousResult(task).setTag("optifine"))
|
||||
.addTask(new OptiFineInstaller(service, installId, v, filepath))
|
||||
.start();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Task downloadLiteLoader(String installId, InstallerVersion v) {
|
||||
return new TaskInfo("LiteLoader Downloader") {
|
||||
@Override
|
||||
public void executeTask() {
|
||||
File filepath = IOUtils.tryGetCanonicalFile(IOUtils.currentDirWithSeparator() + "liteloader-universal.jar");
|
||||
FileDownloadTask task = (FileDownloadTask) new FileDownloadTask(v.universal, filepath).setTag("LiteLoader");
|
||||
TaskWindow.getInstance()
|
||||
.addTask(task).addTask(new LiteLoaderInstaller(service, installId, (LiteLoaderVersionList.LiteLoaderInstallerVersion) v).registerPreviousResult(task))
|
||||
.start();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.utils.system.Compressor;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class PackMinecraftInstaller {
|
||||
|
||||
File dest;
|
||||
ArrayList<String> src;
|
||||
|
||||
public PackMinecraftInstaller(ArrayList<String> src, File dest) {
|
||||
this.dest = dest;
|
||||
this.src = src;
|
||||
}
|
||||
|
||||
public void install() throws IOException {
|
||||
File file = new File(IOUtils.currentDir(), "HMCL-MERGE-TEMP");
|
||||
file.mkdirs();
|
||||
for (String src1 : src)
|
||||
Compressor.unzip(new File(src1), file);
|
||||
Compressor.zip(file.getAbsolutePath(), dest.getAbsolutePath());
|
||||
FileUtils.deleteDirectory(file);
|
||||
}
|
||||
}
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.forge;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallProfile;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList.InstallerVersion;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ForgeInstaller extends Task {
|
||||
|
||||
public File gameDir;
|
||||
public File forgeInstaller;
|
||||
public IMinecraftService mp;
|
||||
public InstallerVersion installerVersion;
|
||||
|
||||
public ForgeInstaller(IMinecraftService mp, File forgeInstaller, InstallerVersion installerVersion) {
|
||||
this.gameDir = mp.baseDirectory();
|
||||
this.forgeInstaller = forgeInstaller;
|
||||
this.mp = mp;
|
||||
this.installerVersion = installerVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Exception {
|
||||
HMCLog.log("Extracting install profiles...");
|
||||
|
||||
ZipFile zipFile = new ZipFile(forgeInstaller);
|
||||
ZipEntry entry = zipFile.getEntry("install_profile.json");
|
||||
String content = NetUtils.getStreamContent(zipFile.getInputStream(entry));
|
||||
InstallProfile profile = C.gsonPrettyPrinting.fromJson(content, InstallProfile.class);
|
||||
|
||||
File from = new File(gameDir, "versions" + File.separator + profile.install.minecraft);
|
||||
if (!from.exists())
|
||||
if (MessageBox.Show(C.i18n("install.no_version_if_intall")) == MessageBox.YES_OPTION) {
|
||||
if (!mp.version().install(profile.install.minecraft, null))
|
||||
throw new IllegalStateException(C.i18n("install.no_version"));
|
||||
} else
|
||||
throw new IllegalStateException(C.i18n("install.no_version"));
|
||||
|
||||
File to = new File(gameDir, "versions" + File.separator + profile.install.target);
|
||||
to.mkdirs();
|
||||
|
||||
HMCLog.log("Copying jar..." + profile.install.minecraft + ".jar to " + profile.install.target + ".jar");
|
||||
FileUtils.copyFile(new File(from, profile.install.minecraft + ".jar"),
|
||||
new File(to, profile.install.target + ".jar"));
|
||||
HMCLog.log("Creating new version profile..." + profile.install.target + ".json");
|
||||
/*
|
||||
* for (MinecraftLibrary library : profile.versionInfo.libraries)
|
||||
* if (library.name.startsWith("net.minecraftforge:forge:"))
|
||||
* library.url = installerVersion.universal;
|
||||
*/
|
||||
FileUtils.write(new File(to, profile.install.target + ".json"), C.gsonPrettyPrinting.toJson(profile.versionInfo));
|
||||
|
||||
HMCLog.log("Extracting universal forge pack..." + profile.install.filePath);
|
||||
|
||||
entry = zipFile.getEntry(profile.install.filePath);
|
||||
InputStream is = zipFile.getInputStream(entry);
|
||||
|
||||
MinecraftLibrary forge = new MinecraftLibrary(profile.install.path);
|
||||
forge.init();
|
||||
File file = new File(gameDir, "libraries/" + forge.formatted);
|
||||
file.getParentFile().mkdirs();
|
||||
try (FileOutputStream fos = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
|
||||
int c;
|
||||
while ((c = is.read()) != -1)
|
||||
bos.write((byte) c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("install.forge.install");
|
||||
}
|
||||
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.forge;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.PackMinecraftInstaller;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ForgeOldInstaller {
|
||||
|
||||
public static void install(String destMinecraftJar, String srcMinecraftJar, String forgeUniversal) throws IOException {
|
||||
ArrayList<String> al = new ArrayList<>();
|
||||
al.add(srcMinecraftJar);
|
||||
al.add(forgeUniversal);
|
||||
new PackMinecraftInstaller(al, new File(destMinecraftJar)).install();
|
||||
}
|
||||
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.forge;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Install {
|
||||
|
||||
public String profileName;
|
||||
public String target;
|
||||
public String path;
|
||||
public String version;
|
||||
public String filePath;
|
||||
public String welcome;
|
||||
public String minecraft;
|
||||
public String mirrorList;
|
||||
public String logo;
|
||||
}
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.forge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionNewerComparator;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftForgeVersionList extends InstallerVersionList {
|
||||
|
||||
private static MinecraftForgeVersionList instance;
|
||||
|
||||
public static MinecraftForgeVersionList getInstance() {
|
||||
if (instance == null)
|
||||
instance = new MinecraftForgeVersionList();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public MinecraftForgeVersionRoot root;
|
||||
public Map<String, List<InstallerVersion>> versionMap;
|
||||
public List<InstallerVersion> versions;
|
||||
|
||||
@Override
|
||||
public void refreshList(String[] needed) throws Exception {
|
||||
if (root != null)
|
||||
return;
|
||||
String s = NetUtils.get(DownloadType.getSuggestedDownloadType().getProvider().getParsedLibraryDownloadURL(C.URL_FORGE_LIST));
|
||||
|
||||
root = C.gson.fromJson(s, MinecraftForgeVersionRoot.class);
|
||||
|
||||
versionMap = new HashMap<>();
|
||||
versions = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, int[]> arr : root.mcversion.entrySet()) {
|
||||
String mcver = StrUtils.formatVersion(arr.getKey());
|
||||
ArrayList<InstallerVersion> al = new ArrayList<>();
|
||||
for (int num : arr.getValue()) {
|
||||
MinecraftForgeVersion v = root.number.get(num);
|
||||
InstallerVersion iv = new InstallerVersion(v.version, StrUtils.formatVersion(v.mcversion));
|
||||
for (String[] f : v.files) {
|
||||
|
||||
String ver = v.mcversion + "-" + v.version;
|
||||
if (!StrUtils.isBlank(v.branch))
|
||||
ver = ver + "-" + v.branch;
|
||||
String filename = root.artifact + "-" + ver + "-" + f[1] + "." + f[0];
|
||||
String url = DownloadType.getSuggestedDownloadType().getProvider().getParsedLibraryDownloadURL(root.webpath + ver + "/" + filename);
|
||||
switch (f[1]) {
|
||||
case "installer":
|
||||
iv.installer = url;
|
||||
break;
|
||||
case "universal":
|
||||
iv.universal = url;
|
||||
break;
|
||||
case "changelog":
|
||||
iv.changelog = url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (StrUtils.isBlank(iv.installer) || StrUtils.isBlank(iv.universal))
|
||||
continue;
|
||||
Collections.sort(al, new InstallerVersionNewerComparator());
|
||||
al.add(iv);
|
||||
versions.add(iv);
|
||||
}
|
||||
|
||||
versionMap.put(StrUtils.formatVersion(mcver), al);
|
||||
}
|
||||
|
||||
Collections.sort(versions, new InstallerVersionComparator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstallerVersion> getVersionsImpl(String mcVersion) {
|
||||
if (versions == null || versionMap == null)
|
||||
return null;
|
||||
if (StrUtils.isBlank(mcVersion))
|
||||
return versions;
|
||||
List c = versionMap.get(mcVersion);
|
||||
if (c == null)
|
||||
return versions;
|
||||
Collections.sort(c, InstallerVersionComparator.INSTANCE);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Forge - MinecraftForge Offical Site";
|
||||
}
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.forge;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftForgeVersionRoot {
|
||||
|
||||
public String artifact, webpath, adfly, homepage, name;
|
||||
public Map<String, int[]> branches, mcversion;
|
||||
public Map<String, Integer> promos;
|
||||
public Map<Integer, MinecraftForgeVersion> number;
|
||||
}
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.liteloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.communication.PreviousResultRegistrar;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LiteLoaderInstaller extends Task implements PreviousResultRegistrar<File> {
|
||||
|
||||
public LiteLoaderVersionList.LiteLoaderInstallerVersion version;
|
||||
public File installer;
|
||||
public String installId;
|
||||
public IMinecraftService service;
|
||||
|
||||
public LiteLoaderInstaller(IMinecraftService service, String installId, LiteLoaderVersionList.LiteLoaderInstallerVersion v) {
|
||||
this(service, installId, v, null);
|
||||
}
|
||||
|
||||
public LiteLoaderInstaller(IMinecraftService service, String installId, LiteLoaderVersionList.LiteLoaderInstallerVersion v, File installer) {
|
||||
this.service = service;
|
||||
this.installId = installId;
|
||||
this.version = v;
|
||||
this.installer = installer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Exception {
|
||||
if (installId == null)
|
||||
throw new IllegalStateException(C.i18n("install.no_version"));
|
||||
if (pre.size() != 1 && installer == null)
|
||||
throw new IllegalStateException("No registered previous task.");
|
||||
if (installer == null)
|
||||
installer = pre.get(pre.size() - 1).getResult();
|
||||
MinecraftVersion mv = (MinecraftVersion) service.version().getVersionById(installId).clone();
|
||||
mv.inheritsFrom = mv.id;
|
||||
mv.jar = mv.jar == null ? mv.id : mv.jar;
|
||||
mv.libraries = new ArrayList(Arrays.asList(version.libraries));
|
||||
|
||||
MinecraftLibrary ml = new MinecraftLibrary("com.mumfrey:liteloader:" + version.selfVersion);
|
||||
//ml.url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + version.mcVersion + "/liteloader-" + version.selfVersion + ".jar";
|
||||
mv.libraries.add(0, ml);
|
||||
FileUtils.copyFile(installer, new File(service.baseDirectory(), "libraries/com/mumfrey/liteloader/" + version.selfVersion + "/liteloader-" + version.selfVersion + ".jar"));
|
||||
|
||||
mv.id += "-LiteLoader" + version.selfVersion;
|
||||
|
||||
mv.mainClass = "net.minecraft.launchwrapper.Launch";
|
||||
mv.minecraftArguments += " --tweakClass " + version.tweakClass;
|
||||
File folder = new File(service.baseDirectory(), "versions/" + mv.id);
|
||||
folder.mkdirs();
|
||||
File json = new File(folder, mv.id + ".json");
|
||||
HMCLog.log("Creating new version profile..." + mv.id + ".json");
|
||||
FileUtils.write(json, C.gsonPrettyPrinting.toJson(mv));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("install.liteloader.install");
|
||||
}
|
||||
|
||||
ArrayList<PreviousResult<File>> pre = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public Task registerPreviousResult(PreviousResult pr) {
|
||||
pre.add(pr);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.liteloader;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LiteLoaderVersion {
|
||||
|
||||
public String tweakClass, file, version, md5, timestamp;
|
||||
public MinecraftLibrary[] libraries;
|
||||
}
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.liteloader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList.InstallerVersion;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionNewerComparator;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LiteLoaderVersionList extends InstallerVersionList {
|
||||
|
||||
private static LiteLoaderVersionList instance;
|
||||
|
||||
public static LiteLoaderVersionList getInstance() {
|
||||
if (instance == null)
|
||||
instance = new LiteLoaderVersionList();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public LiteLoaderVersionsRoot root;
|
||||
public Map<String, List<InstallerVersion>> versionMap;
|
||||
public List<InstallerVersion> versions;
|
||||
|
||||
@Override
|
||||
public void refreshList(String[] needed) throws Exception {
|
||||
String s = NetUtils.get(C.URL_LITELOADER_LIST);
|
||||
if (root != null)
|
||||
return;
|
||||
|
||||
root = C.gson.fromJson(s, LiteLoaderVersionsRoot.class);
|
||||
|
||||
versionMap = new HashMap<>();
|
||||
versions = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, LiteLoaderMCVersions> arr : root.versions.entrySet()) {
|
||||
ArrayList<InstallerVersion> al = new ArrayList<>();
|
||||
LiteLoaderMCVersions mcv = arr.getValue();
|
||||
for (Map.Entry<String, LiteLoaderVersion> entry : mcv.artefacts.get("com.mumfrey:liteloader").entrySet()) {
|
||||
if ("latest".equals(entry.getKey()))
|
||||
continue;
|
||||
LiteLoaderVersion v = entry.getValue();
|
||||
LiteLoaderInstallerVersion iv = new LiteLoaderInstallerVersion(v.version, StrUtils.formatVersion(arr.getKey()));
|
||||
iv.universal = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + arr.getKey() + "/" + v.file;
|
||||
iv.tweakClass = v.tweakClass;
|
||||
iv.libraries = Arrays.copyOf(v.libraries, v.libraries.length);
|
||||
iv.installer = "http://dl.liteloader.com/redist/" + iv.mcVersion + "/liteloader-installer-" + iv.selfVersion.replace("_", "-") + ".jar";
|
||||
al.add(iv);
|
||||
versions.add(iv);
|
||||
}
|
||||
Collections.sort(al, new InstallerVersionNewerComparator());
|
||||
versionMap.put(StrUtils.formatVersion(arr.getKey()), al);
|
||||
}
|
||||
|
||||
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstallerVersion> getVersionsImpl(String mcVersion) {
|
||||
if (versions == null || versionMap == null)
|
||||
return null;
|
||||
if (StrUtils.isBlank(mcVersion))
|
||||
return versions;
|
||||
List c = versionMap.get(mcVersion);
|
||||
if (c == null)
|
||||
return versions;
|
||||
Collections.sort(c, InstallerVersionComparator.INSTANCE);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "LiteLoader - LiteLoader Official Site(By: Mumfrey)";
|
||||
}
|
||||
|
||||
public static class LiteLoaderInstallerVersion extends InstallerVersion {
|
||||
|
||||
public MinecraftLibrary[] libraries;
|
||||
public String tweakClass;
|
||||
|
||||
public LiteLoaderInstallerVersion(String selfVersion, String mcVersion) {
|
||||
super(selfVersion, mcVersion);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-94
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.optifine;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.communication.PreviousResultRegistrar;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class OptiFineInstaller extends Task implements PreviousResultRegistrar<File> {
|
||||
|
||||
public File installer;
|
||||
public IMinecraftService service;
|
||||
public InstallerVersionList.InstallerVersion version;
|
||||
public String installId;
|
||||
|
||||
public OptiFineInstaller(IMinecraftService service, String installId, InstallerVersionList.InstallerVersion version) {
|
||||
this(service, installId, version, null);
|
||||
}
|
||||
|
||||
public OptiFineInstaller(IMinecraftService service, String installId, InstallerVersionList.InstallerVersion version, File installer) {
|
||||
this.service = service;
|
||||
this.installId = installId;
|
||||
this.installer = installer;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Exception {
|
||||
if (installId == null)
|
||||
throw new Exception(C.i18n("install.no_version"));
|
||||
String selfId = version.selfVersion;
|
||||
MinecraftVersion mv = (MinecraftVersion) service.version().getVersionById(installId).clone();
|
||||
mv.inheritsFrom = mv.id;
|
||||
mv.jar = mv.jar == null ? mv.id : mv.jar;
|
||||
mv.libraries.clear();
|
||||
mv.libraries.add(0, new MinecraftLibrary("optifine:OptiFine:" + selfId));
|
||||
FileUtils.copyFile(installer, new File(service.baseDirectory(), "libraries/optifine/OptiFine/" + selfId + "/OptiFine-" + selfId + ".jar"));
|
||||
|
||||
mv.id += "-" + selfId;
|
||||
if (new ZipFile(installer).getEntry("optifine/OptiFineTweaker.class") != null) {
|
||||
if (!mv.mainClass.startsWith("net.minecraft.launchwrapper.")) {
|
||||
mv.mainClass = "net.minecraft.launchwrapper.Launch";
|
||||
mv.libraries.add(1, new MinecraftLibrary("net.minecraft:launchwrapper:1.7"));
|
||||
}
|
||||
mv.minecraftArguments += " --tweakClass optifine.OptiFineTweaker";
|
||||
}
|
||||
File loc = new File(service.baseDirectory(), "versions/" + mv.id);
|
||||
loc.mkdirs();
|
||||
File json = new File(loc, mv.id + ".json");
|
||||
FileUtils.writeStringToFile(json, C.gsonPrettyPrinting.toJson(mv, MinecraftVersion.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "Optifine Installer";
|
||||
}
|
||||
|
||||
ArrayList<PreviousResult<File>> pre = new ArrayList();
|
||||
|
||||
@Override
|
||||
public Task registerPreviousResult(PreviousResult pr) {
|
||||
pre.add(pr);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.optifine.bmcl;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.optifine.OptiFineVersion;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class OptiFineBMCLVersionList extends InstallerVersionList {
|
||||
|
||||
private static OptiFineBMCLVersionList instance;
|
||||
|
||||
public static OptiFineBMCLVersionList getInstance() {
|
||||
if (null == instance)
|
||||
instance = new OptiFineBMCLVersionList();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public ArrayList<OptiFineVersion> root;
|
||||
public Map<String, List<InstallerVersion>> versionMap;
|
||||
public List<InstallerVersion> versions;
|
||||
|
||||
@Override
|
||||
public void refreshList(String[] needed) throws Exception {
|
||||
String s = NetUtils.get("http://bmclapi.bangbang93.com/optifine/versionlist");
|
||||
|
||||
versionMap = new HashMap<>();
|
||||
versions = new ArrayList<>();
|
||||
|
||||
if (s == null)
|
||||
return;
|
||||
root = C.gson.fromJson(s, new TypeToken<ArrayList<OptiFineVersion>>() {
|
||||
}.getType());
|
||||
for (OptiFineVersion v : root) {
|
||||
v.mirror = v.mirror.replace("http://optifine.net/http://optifine.net/", "http://optifine.net/");
|
||||
|
||||
if (StrUtils.isBlank(v.mcver)) {
|
||||
Pattern p = Pattern.compile("OptiFine (.*) HD");
|
||||
Matcher m = p.matcher(v.ver);
|
||||
while (m.find())
|
||||
v.mcver = m.group(1);
|
||||
}
|
||||
InstallerVersion iv = new InstallerVersion(v.ver, StrUtils.formatVersion(v.mcver));
|
||||
|
||||
List<InstallerVersion> al = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.mcver));
|
||||
String url = "http://bmclapi.bangbang93.com/optifine/" + iv.selfVersion.replace(" ", "%20");
|
||||
iv.installer = iv.universal = v.mirror;
|
||||
al.add(iv);
|
||||
versions.add(iv);
|
||||
}
|
||||
|
||||
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstallerVersion> getVersionsImpl(String mcVersion) {
|
||||
if (versions == null || versionMap == null)
|
||||
return null;
|
||||
if (StrUtils.isBlank(mcVersion))
|
||||
return versions;
|
||||
List c = versionMap.get(mcVersion);
|
||||
if (c == null)
|
||||
return versions;
|
||||
Collections.sort(c, InstallerVersionComparator.INSTANCE);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "OptiFine - BMCLAPI(By: bangbang93)";
|
||||
}
|
||||
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.optifine.vanilla;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.communication.PreviousResult;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class OptiFineDownloadFormatter extends Task implements PreviousResult<String> {
|
||||
|
||||
String url, result;
|
||||
|
||||
public OptiFineDownloadFormatter(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Exception {
|
||||
String content = NetUtils.get(url);
|
||||
Pattern p = Pattern.compile("\"downloadx\\?f=OptiFine(.*)\"");
|
||||
Matcher m = p.matcher(content);
|
||||
while (m.find())
|
||||
result = m.group(1);
|
||||
result = "http://optifine.net/downloadx?f=OptiFine" + result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("install.optifine.get_download_link");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
-136
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.installers.optifine.vanilla;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.optifine.OptiFineVersion;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class OptiFineVersionList extends InstallerVersionList {
|
||||
|
||||
private static OptiFineVersionList instance;
|
||||
|
||||
public static OptiFineVersionList getInstance() {
|
||||
if (null == instance)
|
||||
instance = new OptiFineVersionList();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public ArrayList<OptiFineVersion> root = new ArrayList();
|
||||
public Map<String, List<InstallerVersion>> versionMap;
|
||||
public List<InstallerVersion> versions;
|
||||
|
||||
@Override
|
||||
public void refreshList(String[] sss) throws Exception {
|
||||
String content = NetUtils.get("http://optifine.net/downloads");
|
||||
if (versions != null)
|
||||
return;
|
||||
versionMap = new HashMap<>();
|
||||
versions = new ArrayList<>();
|
||||
|
||||
content = content.replace(" ", " ").replace(">", ">").replace("<", "<");
|
||||
|
||||
try {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder db = factory.newDocumentBuilder();
|
||||
Document doc = db.parse(new ByteArrayInputStream(content.getBytes()));
|
||||
Element r = doc.getDocumentElement();
|
||||
NodeList tables = r.getElementsByTagName("table");
|
||||
for (int i = 0; i < tables.getLength(); i++) {
|
||||
Element e = (Element) tables.item(i);
|
||||
if ("downloadTable".equals(e.getAttribute("class"))) {
|
||||
NodeList tr = e.getElementsByTagName("tr");
|
||||
for (int k = 0; k < tr.getLength(); k++) {
|
||||
NodeList downloadLine = ((Element) tr.item(k)).getElementsByTagName("td");
|
||||
OptiFineVersion v = new OptiFineVersion();
|
||||
for (int j = 0; j < downloadLine.getLength(); j++) {
|
||||
Element td = (Element) downloadLine.item(j);
|
||||
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineMirror"))
|
||||
v.mirror = ((Element) td.getElementsByTagName("a").item(0)).getAttribute("href");
|
||||
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineDownload"))
|
||||
v.dl = ((Element) td.getElementsByTagName("a").item(0)).getAttribute("href");
|
||||
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineDate"))
|
||||
v.date = td.getTextContent();
|
||||
if (StrUtils.startsWith(td.getAttribute("class"), "downloadLineFile"))
|
||||
v.ver = td.getTextContent();
|
||||
}
|
||||
if (StrUtils.isBlank(v.mcver)) {
|
||||
Pattern p = Pattern.compile("OptiFine (.*?) ");
|
||||
Matcher m = p.matcher(v.ver);
|
||||
while (m.find())
|
||||
v.mcver = StrUtils.formatVersion(m.group(1));
|
||||
}
|
||||
InstallerVersion iv = new InstallerVersion(v.ver, StrUtils.formatVersion(v.mcver));
|
||||
iv.installer = iv.universal = v.mirror;
|
||||
root.add(v);
|
||||
versions.add(iv);
|
||||
|
||||
List<InstallerVersion> ivl = ArrayUtils.tryGetMapWithList(versionMap, StrUtils.formatVersion(v.mcver));
|
||||
ivl.add(iv);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ParserConfigurationException | SAXException | IOException | DOMException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
Collections.sort(versions, InstallerVersionComparator.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "OptiFine - OptiFine Official Site";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InstallerVersion> getVersionsImpl(String mcVersion) {
|
||||
if (versions == null || versionMap == null)
|
||||
return null;
|
||||
if (StrUtils.isBlank(mcVersion))
|
||||
return versions;
|
||||
List c = versionMap.get(mcVersion);
|
||||
if (c == null)
|
||||
return versions;
|
||||
Collections.sort(c, InstallerVersionComparator.INSTANCE);
|
||||
return c;
|
||||
}
|
||||
|
||||
}
|
||||
-198
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Launcher;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.system.JdkVersion;
|
||||
import org.jackhuang.hellominecraft.utils.MathUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.utils.system.Platform;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class AbstractMinecraftLoader implements IMinecraftLoader {
|
||||
|
||||
protected LaunchOptions options;
|
||||
protected UserProfileProvider lr;
|
||||
protected File gameDir;
|
||||
protected IMinecraftService service;
|
||||
protected final MinecraftVersion version;
|
||||
|
||||
public AbstractMinecraftLoader(LaunchOptions options, IMinecraftService service, String versionId, UserProfileProvider lr) throws GameException {
|
||||
this.lr = lr;
|
||||
|
||||
this.options = options;
|
||||
this.service = service;
|
||||
this.gameDir = service.baseDirectory();
|
||||
this.version = service.version().getVersionById(versionId).resolve(service.version());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion getMinecraftVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void makeHeadCommand(List<String> res) {
|
||||
HMCLog.log("On making head command.");
|
||||
|
||||
JdkVersion jv = options.getJava();
|
||||
res.add(options.getJavaDir());
|
||||
|
||||
if (options.hasJavaArgs())
|
||||
res.addAll(Arrays.asList(StrUtils.tokenize(options.getJavaArgs())));
|
||||
|
||||
if (!options.isNoJVMArgs()) {
|
||||
appendJVMArgs(res);
|
||||
|
||||
if (jv == null || !jv.isEarlyAccess()) {
|
||||
if (OS.os() == OS.WINDOWS)
|
||||
res.add("-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump");
|
||||
res.add("-XX:+UseConcMarkSweepGC");
|
||||
res.add("-XX:+CMSIncrementalMode");
|
||||
res.add("-XX:-UseAdaptiveSizePolicy");
|
||||
res.add("-XX:-OmitStackTraceInFastThrow");
|
||||
|
||||
res.add("-Xmn128m");
|
||||
}
|
||||
if (!StrUtils.isBlank(options.getPermSize()))
|
||||
if (jv == null || jv.getParsedVersion() < JdkVersion.JAVA_18)
|
||||
res.add("-XX:PermSize=" + options.getPermSize() + "m");
|
||||
else if (jv.getParsedVersion() >= JdkVersion.JAVA_18)
|
||||
res.add("-XX:MetaspaceSize=" + options.getPermSize() + "m");
|
||||
}
|
||||
|
||||
if (jv != null) {
|
||||
HMCLog.log("Java Version: " + jv.getVersion());
|
||||
HMCLog.log("Java Platform: " + jv.getPlatform().getBit());
|
||||
}
|
||||
HMCLog.log("System Platform: " + Platform.getPlatform().getBit());
|
||||
|
||||
if (jv != null && jv.getPlatform() == Platform.BIT_32 && Platform.getPlatform() == Platform.BIT_64)
|
||||
MessageBox.Show(C.i18n("advice.os64butjdk32"));
|
||||
|
||||
if (!StrUtils.isBlank(options.getMaxMemory())) {
|
||||
int mem = MathUtils.parseMemory(options.getMaxMemory(), 2147483647);
|
||||
if (jv != null && jv.getPlatform() == Platform.BIT_32 && mem > 1024)
|
||||
MessageBox.Show(C.i18n("launch.too_big_memory_alloc_64bit"));
|
||||
else {
|
||||
long a = OS.getTotalPhysicalMemory() / 1024 / 1024;
|
||||
HMCLog.log("System Physical Memory: " + a);
|
||||
if (a > 0 && a < mem)
|
||||
MessageBox.Show(C.i18n("launch.too_big_memory_alloc_free_space_too_low", a));
|
||||
}
|
||||
String a = "-Xmx" + options.getMaxMemory();
|
||||
if (MathUtils.canParseInt(options.getMaxMemory()))
|
||||
a += "m";
|
||||
res.add(a);
|
||||
}
|
||||
|
||||
res.add("-Djava.library.path=" + service.version().getDecompressNativesToLocation(version).getPath());
|
||||
res.add("-Dfml.ignoreInvalidMinecraftCertificates=true");
|
||||
res.add("-Dfml.ignorePatchDiscrepancies=true");
|
||||
|
||||
if (OS.os() != OS.WINDOWS)
|
||||
res.add("-Duser.home=" + gameDir.getParent());
|
||||
|
||||
if (!options.isCanceledWrapper()) {
|
||||
res.add("-cp");
|
||||
res.add(StrUtils.parseParams("", Utils.getURL(), File.pathSeparator));
|
||||
res.add(Launcher.class.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> makeLaunchingCommand() throws GameException {
|
||||
HMCLog.log("*** Make shell command ***");
|
||||
|
||||
ArrayList<String> res = new ArrayList<>();
|
||||
|
||||
makeHeadCommand(res);
|
||||
makeSelf(res);
|
||||
|
||||
HMCLog.log("On making launcher args.");
|
||||
|
||||
if (StrUtils.isNotBlank(options.getHeight()) && StrUtils.isNotBlank(options.getWidth())) {
|
||||
res.add("--height");
|
||||
res.add(options.getHeight());
|
||||
res.add("--width");
|
||||
res.add(options.getWidth());
|
||||
}
|
||||
|
||||
String serverIp = options.getServerIp();
|
||||
if (lr.getServer() != null)
|
||||
serverIp = lr.getServer().addr;
|
||||
if (StrUtils.isNotBlank(serverIp)) {
|
||||
String[] args = serverIp.split(":");
|
||||
res.add("--server");
|
||||
res.add(args[0]);
|
||||
res.add("--port");
|
||||
res.add(args.length > 1 ? args[1] : "25565");
|
||||
}
|
||||
|
||||
if (options.isFullscreen())
|
||||
res.add("--fullscreen");
|
||||
|
||||
if (options.isDebug() && !options.isCanceledWrapper())
|
||||
res.add("-debug");
|
||||
|
||||
if (StrUtils.isNotBlank(options.getProxyHost()) && StrUtils.isNotBlank(options.getProxyPort()) && MathUtils.canParseInt(options.getProxyPort())) {
|
||||
res.add("-proxyHost=" + options.getProxyHost());
|
||||
res.add("-proxyPort=" + options.getProxyPort());
|
||||
if (StrUtils.isNotBlank(options.getProxyUser()) && StrUtils.isNotBlank(options.getProxyPass())) {
|
||||
res.add("-proxyUsername=" + options.getProxyUser());
|
||||
res.add("-proxyPassword=" + options.getProxyPass());
|
||||
}
|
||||
}
|
||||
|
||||
if (StrUtils.isNotBlank(options.getMinecraftArgs()))
|
||||
res.addAll(Arrays.asList(options.getMinecraftArgs().split(" ")));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* You must do these things:
|
||||
* <ul>
|
||||
* <li>minecraft class path</li>
|
||||
* <li>main class</li>
|
||||
* <li>minecraft arguments</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param list the command list you shoud edit.
|
||||
*/
|
||||
protected abstract void makeSelf(List<String> list) throws GameException;
|
||||
|
||||
protected void appendJVMArgs(List<String> list) {
|
||||
}
|
||||
}
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.LoginInfo;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.ParallelTask;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.system.Compressor;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
public class DefaultGameLauncher extends GameLauncher {
|
||||
|
||||
public DefaultGameLauncher(LaunchOptions options, IMinecraftService service, LoginInfo info, IAuthenticator lg) {
|
||||
super(options, service, info, lg);
|
||||
register();
|
||||
}
|
||||
|
||||
private void register() {
|
||||
downloadLibrariesEvent.register((sender, t) -> {
|
||||
final TaskWindow.TaskWindowFactory dw = TaskWindow.getInstance();
|
||||
ParallelTask parallelTask = new ParallelTask();
|
||||
for (DownloadLibraryJob s : t)
|
||||
parallelTask.addDependsTask(new LibraryDownloadTask(s));
|
||||
dw.addTask(parallelTask);
|
||||
boolean flag = true;
|
||||
if (t.size() > 0)
|
||||
flag = dw.start();
|
||||
if (!flag && MessageBox.Show(C.i18n("launch.not_finished_downloading_libraries"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
flag = true;
|
||||
return flag;
|
||||
});
|
||||
decompressNativesEvent.register((sender, value) -> {
|
||||
if (value == null)
|
||||
return false;
|
||||
for (int i = 0; i < value.decompressFiles.length; i++)
|
||||
try {
|
||||
String[] rules = value.extractRules[i];
|
||||
Compressor.unzip(value.decompressFiles[i], value.decompressTo, t -> !StrUtils.startsWithOne(rules, t), false);
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Unable to decompress library file: " + value.decompressFiles[i] + " to " + value.decompressTo, ex);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
-186
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.LoginInfo;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.AuthenticationException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.DecompressLibraryJob;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.JavaProcess;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
import org.jackhuang.hellominecraft.utils.system.ProcessManager;
|
||||
|
||||
public class GameLauncher {
|
||||
|
||||
public static final ProcessManager PROCESS_MANAGER = new ProcessManager();
|
||||
LaunchOptions options;
|
||||
IMinecraftService service;
|
||||
LoginInfo info;
|
||||
UserProfileProvider result;
|
||||
IAuthenticator login;
|
||||
public final EventHandler<List<DownloadLibraryJob>> downloadLibrariesEvent = new EventHandler(this);
|
||||
public final EventHandler<List<String>> successEvent = new EventHandler(this);
|
||||
public final EventHandler<JavaProcess> launchEvent = new EventHandler(this);
|
||||
public final EventHandler<DecompressLibraryJob> decompressNativesEvent = new EventHandler(this);
|
||||
|
||||
public GameLauncher(LaunchOptions options, IMinecraftService version, LoginInfo info, IAuthenticator lg) {
|
||||
this.options = options;
|
||||
this.service = version;
|
||||
this.info = info;
|
||||
this.login = lg;
|
||||
}
|
||||
|
||||
private Object tag;
|
||||
|
||||
public Object getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(Object tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public IMinecraftLoader makeLaunchCommand() throws AuthenticationException, GameException {
|
||||
HMCLog.log("Logging in...");
|
||||
IMinecraftLoader loader;
|
||||
if (info != null)
|
||||
result = login.login(info);
|
||||
else
|
||||
result = login.loginBySettings();
|
||||
if (result == null)
|
||||
throw new AuthenticationException("Result can not be null.");
|
||||
PluginManager.NOW_PLUGIN.onProcessingLoginResult(result);
|
||||
|
||||
loader = service.launch(options, result);
|
||||
|
||||
File file = service.version().getDecompressNativesToLocation(loader.getMinecraftVersion());
|
||||
if (file != null)
|
||||
FileUtils.cleanDirectoryQuietly(file);
|
||||
|
||||
HMCLog.log("Detecting libraries...");
|
||||
if (!downloadLibrariesEvent.execute(service.download().getDownloadLibraries(loader.getMinecraftVersion())))
|
||||
throw new GameException("Failed to download libraries");
|
||||
|
||||
HMCLog.log("Unpacking natives...");
|
||||
DecompressLibraryJob job = service.version().getDecompressLibraries(loader.getMinecraftVersion());
|
||||
if (!decompressNativesEvent.execute(job))
|
||||
throw new GameException("Failed to decompress natives");
|
||||
|
||||
successEvent.execute(loader.makeLaunchingCommand());
|
||||
return loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the game "as soon as possible".
|
||||
*
|
||||
* @param str launch command
|
||||
*
|
||||
* @throws IOException failed creating process
|
||||
*/
|
||||
public void launch(List str) throws IOException {
|
||||
if (!service.version().onLaunch())
|
||||
return;
|
||||
if (StrUtils.isNotBlank(options.getPrecalledCommand())) {
|
||||
Process p = Runtime.getRuntime().exec(options.getPrecalledCommand());
|
||||
try {
|
||||
if (p != null && p.isAlive())
|
||||
p.waitFor();
|
||||
} catch (InterruptedException ex) {
|
||||
HMCLog.warn("Failed to invoke precalled command", ex);
|
||||
}
|
||||
}
|
||||
HMCLog.log("Starting process");
|
||||
ProcessBuilder builder = new ProcessBuilder(str);
|
||||
if (options.getLaunchVersion() == null || service.baseDirectory() == null)
|
||||
throw new Error("Fucking bug!");
|
||||
builder.directory(service.version().getRunDirectory(options.getLaunchVersion()))
|
||||
.environment().put("APPDATA", service.baseDirectory().getAbsolutePath());
|
||||
JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER);
|
||||
HMCLog.log("The game process have been started");
|
||||
launchEvent.execute(jp);
|
||||
}
|
||||
|
||||
/**
|
||||
* According to the name...
|
||||
*
|
||||
* @param launcherName the name of launch bat/sh
|
||||
* @param str launch command
|
||||
*
|
||||
* @return launcher location
|
||||
*
|
||||
* @throws java.io.IOException write contents failed.
|
||||
*/
|
||||
public File makeLauncher(String launcherName, List str) throws IOException {
|
||||
HMCLog.log("Making shell launcher...");
|
||||
service.version().onLaunch();
|
||||
boolean isWin = OS.os() == OS.WINDOWS;
|
||||
File f = new File(launcherName + (isWin ? ".bat" : ".sh"));
|
||||
if (!f.exists())
|
||||
f.createNewFile();
|
||||
BufferedWriter writer;
|
||||
try {
|
||||
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), System.getProperty("sun.jnu.encoding", "UTF-8")));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
HMCLog.warn("Failed to create writer, will try again.", ex);
|
||||
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f)));
|
||||
}
|
||||
if (isWin) {
|
||||
writer.write("@echo off");
|
||||
writer.newLine();
|
||||
String appdata = IOUtils.tryGetCanonicalFilePath(service.baseDirectory());
|
||||
if (appdata != null) {
|
||||
writer.write("set appdata=" + appdata);
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
if (StrUtils.isNotBlank(options.getPrecalledCommand())) {
|
||||
writer.write(options.getPrecalledCommand());
|
||||
writer.newLine();
|
||||
}
|
||||
writer.write(StrUtils.makeCommand(str));
|
||||
writer.close();
|
||||
if (!f.setExecutable(true)) {
|
||||
HMCLog.warn("Failed to give launcher permission.");
|
||||
MessageBox.Show(C.i18n("launch.failed_sh_permission"));
|
||||
}
|
||||
|
||||
HMCLog.log("Command: " + StrUtils.parseParams("", str, " "));
|
||||
return f;
|
||||
}
|
||||
|
||||
}
|
||||
-230
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.GameDirType;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.JdkVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LaunchOptions {
|
||||
|
||||
private String name, versionName, javaArgs, minecraftArgs, maxMemory, permSize, width, height, serverIp;
|
||||
private String proxyHost, proxyPort, proxyUser, proxyPass, javaDir, launchVersion;
|
||||
private boolean fullscreen, debug, noJVMArgs, canceledWrapper;
|
||||
private JdkVersion java;
|
||||
private File gameDir;
|
||||
private GameDirType gameDirType;
|
||||
|
||||
protected transient IMinecraftService service;
|
||||
|
||||
public String getVersionName() {
|
||||
return versionName;
|
||||
}
|
||||
|
||||
public void setVersionName(String versionName) {
|
||||
this.versionName = versionName;
|
||||
}
|
||||
|
||||
public File getGameDir() {
|
||||
return gameDir;
|
||||
}
|
||||
|
||||
public void setGameDir(File gameDir) {
|
||||
this.gameDir = gameDir;
|
||||
}
|
||||
|
||||
public void setJavaDir(String javaDir) {
|
||||
this.javaDir = javaDir;
|
||||
}
|
||||
|
||||
public String getJavaDir() {
|
||||
return javaDir;
|
||||
}
|
||||
|
||||
public JdkVersion getJava() {
|
||||
return java;
|
||||
}
|
||||
|
||||
public void setJava(JdkVersion java) {
|
||||
this.java = java;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getJavaArgs() {
|
||||
return javaArgs;
|
||||
}
|
||||
|
||||
public void setJavaArgs(String javaArgs) {
|
||||
this.javaArgs = javaArgs;
|
||||
}
|
||||
|
||||
public boolean hasJavaArgs() {
|
||||
return StrUtils.isNotBlank(getJavaArgs().trim());
|
||||
}
|
||||
|
||||
public String getMaxMemory() {
|
||||
return maxMemory;
|
||||
}
|
||||
|
||||
public void setMaxMemory(String maxMemory) {
|
||||
this.maxMemory = maxMemory;
|
||||
}
|
||||
|
||||
public String getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(String width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public String getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(String height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public boolean isFullscreen() {
|
||||
return fullscreen;
|
||||
}
|
||||
|
||||
public void setFullscreen(boolean fullscreen) {
|
||||
this.fullscreen = fullscreen;
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
public GameDirType getGameDirType() {
|
||||
return gameDirType;
|
||||
}
|
||||
|
||||
public void setGameDirType(GameDirType gameDirType) {
|
||||
this.gameDirType = gameDirType;
|
||||
}
|
||||
|
||||
public String getPermSize() {
|
||||
return permSize;
|
||||
}
|
||||
|
||||
public void setPermSize(String permSize) {
|
||||
this.permSize = permSize;
|
||||
}
|
||||
|
||||
public boolean isNoJVMArgs() {
|
||||
return noJVMArgs;
|
||||
}
|
||||
|
||||
public void setNoJVMArgs(boolean noJVMArgs) {
|
||||
this.noJVMArgs = noJVMArgs;
|
||||
}
|
||||
|
||||
public String getMinecraftArgs() {
|
||||
return minecraftArgs;
|
||||
}
|
||||
|
||||
public void setMinecraftArgs(String minecraftArgs) {
|
||||
this.minecraftArgs = minecraftArgs;
|
||||
}
|
||||
|
||||
public boolean isCanceledWrapper() {
|
||||
return canceledWrapper;
|
||||
}
|
||||
|
||||
public void setCanceledWrapper(boolean canceledWrapper) {
|
||||
this.canceledWrapper = canceledWrapper;
|
||||
}
|
||||
|
||||
public String getServerIp() {
|
||||
return serverIp;
|
||||
}
|
||||
|
||||
public void setServerIp(String serverIp) {
|
||||
this.serverIp = serverIp;
|
||||
}
|
||||
|
||||
public String getProxyHost() {
|
||||
return proxyHost;
|
||||
}
|
||||
|
||||
public void setProxyHost(String proxyHost) {
|
||||
this.proxyHost = proxyHost;
|
||||
}
|
||||
|
||||
public String getProxyPort() {
|
||||
return proxyPort;
|
||||
}
|
||||
|
||||
public void setProxyPort(String proxyPort) {
|
||||
this.proxyPort = proxyPort;
|
||||
}
|
||||
|
||||
public String getProxyUser() {
|
||||
return proxyUser;
|
||||
}
|
||||
|
||||
public void setProxyUser(String proxyUser) {
|
||||
this.proxyUser = proxyUser;
|
||||
}
|
||||
|
||||
public String getProxyPass() {
|
||||
return proxyPass;
|
||||
}
|
||||
|
||||
public void setProxyPass(String proxyPass) {
|
||||
this.proxyPass = proxyPass;
|
||||
}
|
||||
|
||||
private String precalledCommand;
|
||||
|
||||
public String getPrecalledCommand() {
|
||||
return precalledCommand;
|
||||
}
|
||||
|
||||
public void setPrecalledCommand(String precalledCommand) {
|
||||
this.precalledCommand = precalledCommand;
|
||||
}
|
||||
|
||||
public String getLaunchVersion() {
|
||||
return launchVersion;
|
||||
}
|
||||
|
||||
public void setLaunchVersion(String launchVersion) {
|
||||
this.launchVersion = launchVersion;
|
||||
}
|
||||
}
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class LibraryDownloadTask extends FileDownloadTask {
|
||||
|
||||
DownloadLibraryJob job;
|
||||
|
||||
public LibraryDownloadTask(DownloadLibraryJob job) {
|
||||
super();
|
||||
this.job = job;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
if (job.name.startsWith("net.minecraftforge:forge:")) {
|
||||
String[] s = job.name.split(":");
|
||||
if (s.length == 3)
|
||||
job.url = "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" + s[2] + "/forge-" + s[2] + "-universal.jar";
|
||||
}
|
||||
if (job.name.startsWith("com.mumfrey:liteloader:")) {
|
||||
String[] s = job.name.split(":");
|
||||
if (s.length == 3 && s[2].length() > 3)
|
||||
job.url = "http://dl.liteloader.com/versions/com/mumfrey/liteloader/" + s[2].substring(0, s[2].length() - 3) + "/liteloader-" + s[2] + ".jar";
|
||||
}
|
||||
download(new URL(job.url), job.path);
|
||||
}
|
||||
|
||||
void download(URL url, File filePath) throws Throwable {
|
||||
this.url = url;
|
||||
this.filePath = filePath;
|
||||
super.executeTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("download") + ": " + job.name;
|
||||
}
|
||||
|
||||
}
|
||||
-185
@@ -1,185 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.launch;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.assets.AssetsIndex;
|
||||
import org.jackhuang.hellominecraft.launcher.core.assets.AssetsObject;
|
||||
import org.jackhuang.hellominecraft.launcher.core.assets.IAssetsHandler;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftLibrary;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftLoader extends AbstractMinecraftLoader {
|
||||
|
||||
DownloadType dt;
|
||||
String text;
|
||||
|
||||
public MinecraftLoader(LaunchOptions p, IMinecraftService provider, UserProfileProvider lr) throws GameException {
|
||||
super(p, provider, p.getLaunchVersion(), lr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void makeSelf(List<String> res) throws GameException {
|
||||
String library = options.isCanceledWrapper() ? "" : "-cp=";
|
||||
for (MinecraftLibrary l : version.libraries) {
|
||||
l.init();
|
||||
if (l.allow() && !l.isRequiredToUnzip())
|
||||
library += l.getFilePath(gameDir).getAbsolutePath() + File.pathSeparator;
|
||||
}
|
||||
File f = version.getJar(service.baseDirectory());
|
||||
if (!f.exists())
|
||||
throw new GameException("Minecraft jar does not exists");
|
||||
library += IOUtils.tryGetCanonicalFilePath(f) + File.pathSeparator;
|
||||
library = library.substring(0, library.length() - File.pathSeparator.length());
|
||||
if (options.isCanceledWrapper())
|
||||
res.add("-cp");
|
||||
res.add(library);
|
||||
String mainClass = version.mainClass;
|
||||
res.add((options.isCanceledWrapper() ? "" : "-mainClass=") + mainClass);
|
||||
|
||||
String[] splitted = StrUtils.tokenize(version.minecraftArguments);
|
||||
|
||||
if (!checkAssetsExist())
|
||||
if (MessageBox.Show(C.i18n("assets.no_assets"), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
||||
IAssetsHandler.ASSETS_HANDLER.getList(version, service.asset()).execute();
|
||||
TaskWindow.getInstance().addTask(IAssetsHandler.ASSETS_HANDLER.getDownloadTask(service.getDownloadType().getProvider())).start();
|
||||
}
|
||||
|
||||
String game_assets = reconstructAssets().getAbsolutePath();
|
||||
|
||||
for (String t : splitted) {
|
||||
t = t.replace("${auth_player_name}", lr.getUserName());
|
||||
t = t.replace("${auth_session}", lr.getSession());
|
||||
t = t.replace("${auth_uuid}", lr.getUserId());
|
||||
t = t.replace("${version_name}", Main.makeTitle());
|
||||
t = t.replace("${profile_name}", options.getName());
|
||||
t = t.replace("${game_directory}", service.version().getRunDirectory(version.id).getAbsolutePath());
|
||||
t = t.replace("${game_assets}", game_assets);
|
||||
t = t.replace("${assets_root}", service.asset().getAssets().getAbsolutePath());
|
||||
t = t.replace("${auth_access_token}", lr.getAccessToken());
|
||||
t = t.replace("${user_type}", lr.getUserType());
|
||||
t = t.replace("${assets_index_name}", version.getAssets());
|
||||
t = t.replace("${user_properties}", lr.getUserProperties());
|
||||
res.add(t);
|
||||
}
|
||||
|
||||
if (res.indexOf("--gameDir") != -1 && res.indexOf("--workDir") != -1) {
|
||||
res.add("--workDir");
|
||||
res.add(gameDir.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void appendJVMArgs(List<String> list) {
|
||||
super.appendJVMArgs(list);
|
||||
|
||||
try {
|
||||
if (OS.os() == OS.OSX) {
|
||||
list.add("-Xdock:icon=" + service.asset().getAssetObject(version.assets, "icons/minecraft.icns").getAbsolutePath());
|
||||
list.add("-Xdock:name=Minecraft");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
HMCLog.err("Failed to append jvm arguments when searching for asset objects.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkAssetsExist() {
|
||||
File assetsDir = new File(service.baseDirectory(), "assets");
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectDir = new File(assetsDir, "objects");
|
||||
File indexFile = new File(indexDir, version.getAssets() + ".json");
|
||||
|
||||
if (!assetsDir.exists() && !indexFile.isFile())
|
||||
return false;
|
||||
|
||||
try {
|
||||
AssetsIndex index = (AssetsIndex) C.gson.fromJson(FileUtils.readFileToString(indexFile, "UTF-8"), AssetsIndex.class);
|
||||
|
||||
if (index == null)
|
||||
return false;
|
||||
for (Map.Entry entry : index.getFileMap().entrySet())
|
||||
if (!new File(new File(objectDir, ((AssetsObject) entry.getValue()).getHash().substring(0, 2)), ((AssetsObject) entry.getValue()).getHash()).exists())
|
||||
return false;
|
||||
return true;
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private File reconstructAssets() {
|
||||
File assetsDir = new File(service.baseDirectory(), "assets");
|
||||
File indexDir = new File(assetsDir, "indexes");
|
||||
File objectDir = new File(assetsDir, "objects");
|
||||
String assetVersion = version.getAssets();
|
||||
File indexFile = new File(indexDir, assetVersion + ".json");
|
||||
File virtualRoot = new File(new File(assetsDir, "virtual"), assetVersion);
|
||||
|
||||
if (!indexFile.isFile()) {
|
||||
HMCLog.warn("No assets index file " + virtualRoot + "; can't reconstruct assets");
|
||||
return assetsDir;
|
||||
}
|
||||
|
||||
try {
|
||||
AssetsIndex index = (AssetsIndex) C.gson.fromJson(FileUtils.readFileToString(indexFile, "UTF-8"), AssetsIndex.class);
|
||||
|
||||
if (index == null)
|
||||
return assetsDir;
|
||||
if (index.isVirtual()) {
|
||||
int cnt = 0;
|
||||
HMCLog.log("Reconstructing virtual assets folder at " + virtualRoot);
|
||||
int tot = index.getFileMap().entrySet().size();
|
||||
for (Map.Entry entry : index.getFileMap().entrySet()) {
|
||||
File target = new File(virtualRoot, (String) entry.getKey());
|
||||
File original = new File(new File(objectDir, ((AssetsObject) entry.getValue()).getHash().substring(0, 2)), ((AssetsObject) entry.getValue()).getHash());
|
||||
if (original.exists()) {
|
||||
cnt++;
|
||||
if (!target.isFile())
|
||||
FileUtils.copyFile(original, target, false);
|
||||
}
|
||||
}
|
||||
// If the scale new format existent file is lower then 0.1, use the old format.
|
||||
if (cnt * 10 < tot)
|
||||
return assetsDir;
|
||||
}
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
HMCLog.warn("Failed to create virutal assets.", e);
|
||||
}
|
||||
|
||||
return virtualRoot;
|
||||
}
|
||||
}
|
||||
-120
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.mod;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftModService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.ModInfo;
|
||||
import org.jackhuang.hellominecraft.utils.code.DigestUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftModService extends IMinecraftModService {
|
||||
|
||||
Map<String, List<ModInfo>> modCache = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
public MinecraftModService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModInfo> getMods(String id) {
|
||||
if (modCache.containsKey(id))
|
||||
return modCache.get(id);
|
||||
else
|
||||
return recacheMods(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ModInfo> recacheMods(String id) {
|
||||
File modsFolder = service.version().getRunDirectory(id, "mods");
|
||||
ArrayList<ModInfo> mods = new ArrayList<>();
|
||||
File[] fs = modsFolder.listFiles();
|
||||
if (fs != null)
|
||||
for (File f : fs)
|
||||
if (ModInfo.isFileMod(f)) {
|
||||
ModInfo m = ModInfo.readModInfo(f);
|
||||
if (m != null)
|
||||
mods.add(m);
|
||||
} else if (f.isDirectory()) {
|
||||
File[] ss = f.listFiles();
|
||||
if (ss != null)
|
||||
for (File ff : ss)
|
||||
if (ModInfo.isFileMod(ff)) {
|
||||
ModInfo m = ModInfo.readModInfo(ff);
|
||||
if (m != null)
|
||||
mods.add(m);
|
||||
}
|
||||
}
|
||||
Collections.sort(mods);
|
||||
modCache.put(id, mods);
|
||||
return mods;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addMod(String id, File f) {
|
||||
try {
|
||||
if (!ModInfo.isFileMod(f))
|
||||
return false;
|
||||
File modsFolder = service.version().getRunDirectory(id, "mods");
|
||||
if (modsFolder == null)
|
||||
return false;
|
||||
modsFolder.mkdirs();
|
||||
File newf = new File(modsFolder, f.getName());
|
||||
FileUtils.copyFile(f, newf);
|
||||
ModInfo i = ModInfo.readModInfo(f);
|
||||
modCache.get(id).add(i);
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
HMCLog.warn("Failed to copy mod", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMod(String id, Object[] rows) {
|
||||
if (rows.length == 0)
|
||||
return;
|
||||
for (Object r : rows)
|
||||
if (r instanceof ModInfo)
|
||||
((ModInfo) r).location.delete();
|
||||
else if (r instanceof Number)
|
||||
getMods(id).get(((Number) r).intValue()).location.delete();
|
||||
recacheMods(id);
|
||||
}
|
||||
|
||||
public String[] checkMd5s(String id) throws IOException {
|
||||
String[] res = new String[getMods(id).size()];
|
||||
for (int i = 0; i < res.length; i++)
|
||||
res[i] = DigestUtils.md5Hex(new FileInputStream(getMods(id).get(i).location));
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
-226
@@ -1,226 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.mod;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.functions.BiFunction;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Predicate;
|
||||
import org.jackhuang.hellominecraft.utils.system.Compressor;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.ZipEngine;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftVersionRequest;
|
||||
|
||||
/**
|
||||
* A mod pack(*.zip) includes these things:
|
||||
* <ul>
|
||||
* <li>sth created by the game automatically, including "mods", "scripts",
|
||||
* "config", etc..
|
||||
* <li>pack.json, the same as Minecraft version configuration file:
|
||||
* "gameDir/versions/{MCVER}/{MCVER}.json", will be renamed to that one.
|
||||
* <li>all things should be included in "minecraft" folder under the root
|
||||
* folder.
|
||||
* </ul>
|
||||
*
|
||||
* This class can manage mod packs, for example, importing and exporting, the
|
||||
* format of game is the offical one.
|
||||
* Not compatible with MultiMC(no instance.cfg processor) & FTB(not leaving
|
||||
* mcversion(jar) in pack.json).
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class ModpackManager {
|
||||
|
||||
public static Task install(final File input, final IMinecraftService service, final String id) {
|
||||
return new Task() {
|
||||
Collection<Task> c = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Throwable {
|
||||
File versions = new File(service.baseDirectory(), "versions");
|
||||
File oldFile = new File(versions, "minecraft"), newFile = null;
|
||||
if (oldFile.exists()) {
|
||||
newFile = new File(versions, "minecraft-" + System.currentTimeMillis());
|
||||
if (newFile.isDirectory())
|
||||
FileUtils.deleteDirectory(newFile);
|
||||
else if (newFile.isFile())
|
||||
newFile.delete();
|
||||
oldFile.renameTo(newFile);
|
||||
}
|
||||
|
||||
File preVersion = new File(versions, id), preVersionRenamed = null;
|
||||
if (preVersion.exists()) {
|
||||
HMCLog.log("Backing up the game");
|
||||
String preId = id + "-" + System.currentTimeMillis();
|
||||
preVersion.renameTo(preVersionRenamed = new File(versions, preId));
|
||||
new File(preVersionRenamed, id + ".json").renameTo(new File(preVersionRenamed, preId + ".json"));
|
||||
new File(preVersionRenamed, id + ".jar").renameTo(new File(preVersionRenamed, preId + ".jar"));
|
||||
}
|
||||
|
||||
try {
|
||||
final AtomicInteger b = new AtomicInteger(0);
|
||||
HMCLog.log("Decompressing modpack");
|
||||
Compressor.unzip(input, versions, new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String t) {
|
||||
if (t.equals("minecraft/pack.json"))
|
||||
b.incrementAndGet();
|
||||
return true;
|
||||
}
|
||||
}, true);
|
||||
if (b.get() < 1)
|
||||
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_json"));
|
||||
File nowFile = new File(versions, id);
|
||||
oldFile.renameTo(nowFile);
|
||||
|
||||
File json = new File(nowFile, "pack.json");
|
||||
MinecraftVersion mv = C.gson.fromJson(FileUtils.readFileToString(json), MinecraftVersion.class);
|
||||
if (mv.jar == null)
|
||||
throw new FileNotFoundException(C.i18n("modpack.incorrect_format.no_jar"));
|
||||
|
||||
c.add(service.download().downloadMinecraftJarTo(mv.jar, new File(nowFile, id + ".jar")));
|
||||
mv.jar = null;
|
||||
FileUtils.writeStringToFile(json, C.gsonPrettyPrinting.toJson(mv));
|
||||
json.renameTo(new File(nowFile, id + ".json"));
|
||||
|
||||
if (preVersionRenamed != null) {
|
||||
HMCLog.log("Restoring saves");
|
||||
File presaves = new File(preVersionRenamed, "saves");
|
||||
File saves = new File(nowFile, "saves");
|
||||
if (presaves.exists()) {
|
||||
FileUtils.deleteDirectory(saves);
|
||||
FileUtils.copyDirectory(presaves, saves);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
FileUtils.deleteDirectoryQuietly(oldFile);
|
||||
if (newFile != null)
|
||||
newFile.renameTo(oldFile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return C.i18n("modpack.install.task");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Task> getAfterTasks() {
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public static final List<String> MODPACK_BLACK_LIST = Arrays.asList(new String[] { "usernamecache.json", "asm", "logs", "backups", "versions", "assets", "usercache.json", "libraries", "crash-reports", "launcher_profiles.json", "NVIDIA", "TCNodeTracker", "screenshots", "natives", "native", "hmclversion.cfg", "pack.json" });
|
||||
public static final List<String> MODPACK_SUGGESTED_BLACK_LIST = Arrays.asList(new String[] { "saves", "servers.dat", "options.txt", "optionsshaders.txt", "mods/VoxelMods" });
|
||||
|
||||
/**
|
||||
* < String, Boolean, Boolean >: Folder/File name, Is Directory,
|
||||
* Return 0: non blocked, 1: non shown, 2: suggested, checked.
|
||||
*/
|
||||
public static final BiFunction<String, Boolean, Integer> MODPACK_PREDICATE = new BiFunction<String, Boolean, Integer>() {
|
||||
@Override
|
||||
public Integer apply(String x, Boolean y) {
|
||||
if (ModpackManager.MODPACK_BLACK_LIST_PREDICATE.apply(x, y))
|
||||
return 1;
|
||||
if (ModpackManager.MODPACK_SUGGESTED_BLACK_LIST_PREDICATE.apply(x, y))
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
public static final BiFunction<String, Boolean, Boolean> MODPACK_BLACK_LIST_PREDICATE = modpackPredicateMaker(MODPACK_BLACK_LIST);
|
||||
public static final BiFunction<String, Boolean, Boolean> MODPACK_SUGGESTED_BLACK_LIST_PREDICATE = modpackPredicateMaker(MODPACK_SUGGESTED_BLACK_LIST);
|
||||
|
||||
private static BiFunction<String, Boolean, Boolean> modpackPredicateMaker(final List<String> l) {
|
||||
return new BiFunction<String, Boolean, Boolean>() {
|
||||
@Override
|
||||
public Boolean apply(String x, Boolean y) {
|
||||
for (String s : l)
|
||||
if (y) {
|
||||
if (x.startsWith(s + "/"))
|
||||
return true;
|
||||
} else if (x.equals(s))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the game to a mod pack file.
|
||||
*
|
||||
* @param output mod pack file.
|
||||
* @param baseFolder if the game dir type is ROOT_FOLDER, use ".minecraft",
|
||||
* or use ".minecraft/versions/{MCVER}/"
|
||||
* @param version to locate version.json
|
||||
*
|
||||
* @throws IOException if create tmp directory failed
|
||||
*/
|
||||
public static void export(File output, IMinecraftProvider provider, String version, List<String> blacklist) throws IOException, GameException {
|
||||
final ArrayList<String> b = new ArrayList<>(MODPACK_BLACK_LIST);
|
||||
if (blacklist != null)
|
||||
b.addAll(blacklist);
|
||||
b.add(version + ".jar");
|
||||
b.add(version + ".json");
|
||||
HMCLog.log("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker");
|
||||
ZipEngine zip = null;
|
||||
try {
|
||||
zip = new ZipEngine(output);
|
||||
zip.putDirectory(provider.getRunDirectory(version), new BiFunction<String, Boolean, String>() {
|
||||
@Override
|
||||
public String apply(String x, Boolean y) {
|
||||
for (String s : b)
|
||||
if (y) {
|
||||
if (x.startsWith(s + "/"))
|
||||
return null;
|
||||
} else if (x.equals(s))
|
||||
return null;
|
||||
return "minecraft/" + x;
|
||||
}
|
||||
});
|
||||
|
||||
MinecraftVersion mv = provider.getVersionById(version).resolve(provider);
|
||||
MinecraftVersionRequest r = MinecraftVersionRequest.minecraftVersion(provider.getMinecraftJar(version));
|
||||
if (r.type != MinecraftVersionRequest.OK)
|
||||
throw new FileSystemException(C.i18n("modpack.cannot_read_version") + ": " + MinecraftVersionRequest.getResponse(r));
|
||||
mv.jar = r.version;
|
||||
mv.runDir = "version";
|
||||
zip.putTextFile(C.gsonPrettyPrinting.toJson(mv), "minecraft/pack.json");
|
||||
} finally {
|
||||
if (zip != null)
|
||||
zip.closeFile();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IMinecraftAssetService extends IMinecraftBasicService {
|
||||
|
||||
public IMinecraftAssetService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
public abstract Task downloadAssets(String mcVersion);
|
||||
|
||||
public abstract File getAssets();
|
||||
|
||||
/**
|
||||
* Redownload the Asset index json of the given version.
|
||||
*
|
||||
* @param a the given version name
|
||||
*
|
||||
* @return Is the action successful?
|
||||
*/
|
||||
public abstract boolean refreshAssetsIndex(String a);
|
||||
|
||||
public abstract boolean downloadMinecraftAssetsIndex(String assetsId);
|
||||
|
||||
public abstract File getAssetObject(String assetVersion, String name) throws IOException;
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.OverridableSwingWorker;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.version.MinecraftRemoteVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IMinecraftDownloadService extends IMinecraftBasicService {
|
||||
|
||||
public IMinecraftDownloadService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
public abstract MinecraftVersion downloadMinecraft(String id);
|
||||
|
||||
public abstract boolean downloadMinecraftJar(String id);
|
||||
|
||||
public abstract Task downloadMinecraftJarTo(String id, File f);
|
||||
|
||||
public abstract boolean downloadMinecraftVersionJson(String id);
|
||||
|
||||
/**
|
||||
* Get the libraries that need to download.
|
||||
*
|
||||
* @return the library collection
|
||||
*/
|
||||
public abstract List<DownloadLibraryJob> getDownloadLibraries(MinecraftVersion mv) throws GameException;
|
||||
|
||||
public abstract OverridableSwingWorker<MinecraftRemoteVersion> getRemoteVersions();
|
||||
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.service;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerType;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.InstallerVersionList;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IMinecraftInstallerService extends IMinecraftBasicService {
|
||||
|
||||
public IMinecraftInstallerService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
public abstract Task download(String installId, InstallerVersionList.InstallerVersion v, InstallerType type);
|
||||
|
||||
public abstract Task downloadForge(String installId, InstallerVersionList.InstallerVersion v);
|
||||
|
||||
public abstract Task downloadOptifine(String installId, InstallerVersionList.InstallerVersion v);
|
||||
|
||||
public abstract Task downloadLiteLoader(String installId, InstallerVersionList.InstallerVersion v);
|
||||
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.service;
|
||||
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public interface IMinecraftLoader {
|
||||
|
||||
MinecraftVersion getMinecraftVersion();
|
||||
|
||||
List<String> makeLaunchingCommand() throws GameException;
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import org.jackhuang.hellominecraft.launcher.core.ModInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IMinecraftModService extends IMinecraftBasicService {
|
||||
|
||||
public IMinecraftModService(IMinecraftService service) {
|
||||
super(service);
|
||||
}
|
||||
|
||||
public abstract List<ModInfo> getMods(String id);
|
||||
|
||||
public abstract List<ModInfo> recacheMods(String id);
|
||||
|
||||
public abstract boolean addMod(String id, File f);
|
||||
|
||||
public abstract void removeMod(String id, Object[] mods);
|
||||
}
|
||||
-172
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.DecompressLibraryJob;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersion;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
|
||||
/**
|
||||
* Provide everything of the Minecraft of a Profile.
|
||||
*
|
||||
* @see
|
||||
* org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersionManager
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IMinecraftProvider {
|
||||
|
||||
protected IMinecraftService service;
|
||||
|
||||
public IMinecraftProvider(IMinecraftService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* To download mod packs.
|
||||
*/
|
||||
public abstract void initializeMiencraft();
|
||||
|
||||
/**
|
||||
* Get the run directory of given version.
|
||||
*
|
||||
* @param id the given version name
|
||||
*
|
||||
* @return the run directory
|
||||
*/
|
||||
public abstract File getRunDirectory(String id);
|
||||
|
||||
public abstract File versionRoot(String id);
|
||||
|
||||
public File getRunDirectory(String id, String subFolder) {
|
||||
return new File(getRunDirectory(id), subFolder);
|
||||
}
|
||||
|
||||
public abstract void open(String version, String folder);
|
||||
|
||||
/**
|
||||
* Install a new version to this profile.
|
||||
*
|
||||
* @param version the new version name
|
||||
*
|
||||
* @return Is the action successful?
|
||||
*/
|
||||
public abstract boolean install(String version, Consumer<MinecraftVersion> callback);
|
||||
|
||||
/**
|
||||
* Returns the thing like ".minecraft/resourcepacks".
|
||||
*
|
||||
* @return the thing
|
||||
*/
|
||||
public abstract File getResourcePacks();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param v should be resolved
|
||||
*
|
||||
* @return libraries of resolved minecraft version v.
|
||||
*/
|
||||
public abstract DecompressLibraryJob getDecompressLibraries(MinecraftVersion v) throws GameException;
|
||||
|
||||
public abstract File getDecompressNativesToLocation(MinecraftVersion v);
|
||||
|
||||
/**
|
||||
* @return the Minecraft jar of selected version.
|
||||
*/
|
||||
public abstract File getMinecraftJar(String id);
|
||||
|
||||
/**
|
||||
* Rename version
|
||||
*
|
||||
* @param from The old name
|
||||
* @param to The new name
|
||||
*
|
||||
* @return Is the action successful?
|
||||
*/
|
||||
public abstract boolean renameVersion(String from, String to);
|
||||
|
||||
/**
|
||||
* Remove the given version from disk.
|
||||
*
|
||||
* @param a the version name
|
||||
*
|
||||
* @return Is the action successful?
|
||||
*/
|
||||
public abstract boolean removeVersionFromDisk(String a);
|
||||
|
||||
/**
|
||||
* Choose a version randomly.
|
||||
*
|
||||
* @return the version
|
||||
*/
|
||||
public abstract MinecraftVersion getOneVersion();
|
||||
|
||||
/**
|
||||
* All Minecraft version in this profile.
|
||||
*
|
||||
* @return the collection of all Minecraft version
|
||||
*/
|
||||
public abstract Collection<MinecraftVersion> getVersions();
|
||||
|
||||
/**
|
||||
* Get the Minecraft json instance of given version.
|
||||
*
|
||||
* @param id the given version name
|
||||
*
|
||||
* @return the Minecraft json instance
|
||||
*/
|
||||
public abstract MinecraftVersion getVersionById(String id);
|
||||
|
||||
/**
|
||||
* getVersions().size()
|
||||
*
|
||||
* @return getVersions().size()
|
||||
*/
|
||||
public abstract int getVersionCount();
|
||||
|
||||
/**
|
||||
* Refind the versions in this profile.
|
||||
* Must call onRefreshingVersions, onRefreshedVersions, onLoadedVersion
|
||||
* Events.
|
||||
*/
|
||||
public abstract void refreshVersions();
|
||||
|
||||
public final EventHandler<Void> onRefreshingVersions = new EventHandler<>(this),
|
||||
onRefreshedVersions = new EventHandler<>(this);
|
||||
public final EventHandler<String> onLoadedVersion = new EventHandler<>(this);
|
||||
|
||||
/**
|
||||
* Clean redundant files.
|
||||
*/
|
||||
public abstract void cleanFolder();
|
||||
|
||||
/**
|
||||
* When GameLauncher launches the game, this function will be called.
|
||||
*
|
||||
* @return if false, will break the launch process.
|
||||
*/
|
||||
public abstract boolean onLaunch();
|
||||
|
||||
public File baseDirectory() {
|
||||
return service.baseDirectory();
|
||||
}
|
||||
|
||||
}
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.service;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IMinecraftService {
|
||||
|
||||
public abstract File baseDirectory();
|
||||
|
||||
public DownloadType getDownloadType() {
|
||||
return DownloadType.getSuggestedDownloadType();
|
||||
}
|
||||
|
||||
public abstract IMinecraftAssetService asset();
|
||||
|
||||
public abstract IMinecraftDownloadService download();
|
||||
|
||||
public abstract IMinecraftModService mod();
|
||||
|
||||
public abstract IMinecraftProvider version();
|
||||
|
||||
public abstract IMinecraftInstallerService install();
|
||||
|
||||
/**
|
||||
* Provide the Minecraft Loader to generate the launching command.
|
||||
*
|
||||
* @see org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader
|
||||
* @param p player informations, including username & auth_token
|
||||
*
|
||||
* @return what you want
|
||||
*
|
||||
* @throws GameException circular denpendency versions
|
||||
*/
|
||||
public abstract IMinecraftLoader launch(LaunchOptions options, UserProfileProvider p) throws GameException;
|
||||
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class DecompressLibraryJob {
|
||||
|
||||
public File[] decompressFiles;
|
||||
public String[][] extractRules;
|
||||
public File decompressTo;
|
||||
|
||||
public DecompressLibraryJob(File[] decompressFiles, String[][] extractRules, File decompressTo) {
|
||||
this.decompressFiles = decompressFiles;
|
||||
this.extractRules = extractRules;
|
||||
this.decompressTo = decompressTo;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Extract extends Object implements Cloneable {
|
||||
|
||||
String[] exclude;
|
||||
|
||||
@Override
|
||||
protected Object clone() {
|
||||
Extract e = new Extract();
|
||||
e.exclude = exclude == null ? null : Arrays.copyOf(exclude, exclude.length);
|
||||
return e;
|
||||
}
|
||||
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public enum GameDirType {
|
||||
|
||||
ROOT_FOLDER,
|
||||
VERSION_FOLDER;
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IMinecraftLibrary implements Cloneable {
|
||||
|
||||
public String name;
|
||||
|
||||
public IMinecraftLibrary(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public abstract boolean isRequiredToUnzip();
|
||||
|
||||
public abstract String[] getDecompressExtractRules();
|
||||
|
||||
public abstract void init();
|
||||
|
||||
public abstract boolean allow();
|
||||
|
||||
public abstract File getFilePath(File gameDir);
|
||||
|
||||
public abstract String getDownloadURL(String urlBase, DownloadType downloadType);
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof MinecraftLibrary)
|
||||
return ((MinecraftLibrary) obj).name.equals(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Object clone();
|
||||
}
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftClassicVersion extends MinecraftVersion {
|
||||
|
||||
public MinecraftClassicVersion() {
|
||||
super();
|
||||
|
||||
mainClass = "net.minecraft.client.Minecraft";
|
||||
id = "Classic";
|
||||
type = "release";
|
||||
processArguments = assets = releaseTime = time = null;
|
||||
minecraftArguments = "${auth_player_name} ${auth_session} --workDir ${game_directory}";
|
||||
libraries = new ArrayList<>();
|
||||
libraries.add(new MinecraftOldLibrary("lwjgl"));
|
||||
libraries.add(new MinecraftOldLibrary("jinput"));
|
||||
libraries.add(new MinecraftOldLibrary("lwjgl_util"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion resolve(IMinecraftProvider manager, Set<String> resolvedSoFar) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getJar(File gameDir) {
|
||||
return new File(gameDir, "bin/minecraft.jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getJar(File gameDir, String suffix) {
|
||||
return new File(gameDir, "bin/minecraft" + suffix + ".jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getNatives(File gameDir) {
|
||||
return new File(gameDir, "bin/natives");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToUnpackNatives() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-136
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.utils.system.Platform;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftLibrary extends IMinecraftLibrary {
|
||||
|
||||
public ArrayList<Rules> rules;
|
||||
public String url, formatted = null;
|
||||
//public boolean serverreq=true, clientreq=true;
|
||||
public String[] checksums;
|
||||
public Natives natives;
|
||||
public Extract extract;
|
||||
|
||||
public MinecraftLibrary(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public MinecraftLibrary(ArrayList<Rules> rules, String url, String[] checksums, Natives natives, String name, Extract extract) {
|
||||
super(name);
|
||||
this.rules = rules == null ? null : (ArrayList<Rules>) rules.clone();
|
||||
this.url = url;
|
||||
this.checksums = checksums == null ? null : Arrays.copyOf(checksums, checksums.length);
|
||||
this.natives = natives == null ? null : (Natives) natives.clone();
|
||||
this.extract = extract == null ? null : (Extract) extract.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new MinecraftLibrary(rules, url, checksums, natives, name, extract);
|
||||
}
|
||||
|
||||
/**
|
||||
* is the library allowed to load.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean allow() {
|
||||
boolean flag = false;
|
||||
if (rules == null || rules.isEmpty())
|
||||
flag = true;
|
||||
else
|
||||
for (Rules r : rules)
|
||||
if (r.action.equals("disallow")) {
|
||||
if (r.os != null && (StrUtils.isBlank(r.os.name) || r.os.name.equalsIgnoreCase(OS.os().toString()))) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if (r.os == null || (r.os != null && (StrUtils.isBlank(r.os.name) || r.os.name.equalsIgnoreCase(OS.os().toString()))))
|
||||
flag = true;
|
||||
return flag;
|
||||
}
|
||||
|
||||
private String formatArch(String nati) {
|
||||
return nati == null ? "" : nati.replace("${arch}", Platform.getPlatform().getBit());
|
||||
}
|
||||
|
||||
private String getNative() {
|
||||
OS os = OS.os();
|
||||
if (os == OS.WINDOWS)
|
||||
return formatArch(natives.windows);
|
||||
else if (os == OS.OSX)
|
||||
return formatArch(natives.osx);
|
||||
else
|
||||
return formatArch(natives.linux);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequiredToUnzip() {
|
||||
return natives != null && allow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
String str = name;
|
||||
String[] s = str.split(":");
|
||||
str = s[0];
|
||||
str = str.replace('.', File.separatorChar);
|
||||
if (natives == null)
|
||||
str += File.separator + s[1] + File.separator + s[2]
|
||||
+ File.separator + s[1] + '-' + s[2] + ".jar";
|
||||
else {
|
||||
str += File.separator + s[1] + File.separator + s[2]
|
||||
+ File.separator + s[1] + '-' + s[2] + '-';
|
||||
str += getNative();
|
||||
str += ".jar";
|
||||
}
|
||||
formatted = str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getFilePath(File gameDir) {
|
||||
return new File(gameDir, "libraries" + File.separatorChar + formatted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadURL(String urlBase, DownloadType downloadType) {
|
||||
if (StrUtils.isNotBlank(url) && downloadType.getProvider().isAllowedToUseSelfURL())
|
||||
urlBase = this.url;
|
||||
if (urlBase.endsWith(".jar"))
|
||||
return urlBase;
|
||||
return urlBase + formatted.replace('\\', '/');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDecompressExtractRules() {
|
||||
return extract == null || extract.exclude == null ? new String[0] : extract.exclude;
|
||||
}
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftOldLibrary extends MinecraftLibrary {
|
||||
|
||||
public MinecraftOldLibrary(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRequiredToUnzip() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allow() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getFilePath(File gameDir) {
|
||||
return new File(gameDir, "bin/" + name + ".jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new MinecraftOldLibrary(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDownloadURL(String urlBase, DownloadType downloadType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.assets.AssetsIndex;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftVersion implements Cloneable, Comparable<MinecraftVersion> {
|
||||
|
||||
public String minecraftArguments, mainClass, time, id, type, processArguments,
|
||||
releaseTime, assets, jar, inheritsFrom, runDir;
|
||||
public int minimumLauncherVersion;
|
||||
public boolean hidden;
|
||||
|
||||
public List<MinecraftLibrary> libraries;
|
||||
|
||||
public MinecraftVersion() {
|
||||
}
|
||||
|
||||
public MinecraftVersion(String minecraftArguments, String mainClass, String time, String id, String type, String processArguments, String releaseTime, String assets, String jar, String inheritsFrom, String runDir, int minimumLauncherVersion, List<MinecraftLibrary> libraries, boolean hidden) {
|
||||
this();
|
||||
this.minecraftArguments = minecraftArguments;
|
||||
this.mainClass = mainClass;
|
||||
this.time = time;
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.processArguments = processArguments;
|
||||
this.releaseTime = releaseTime;
|
||||
this.assets = assets;
|
||||
this.jar = jar;
|
||||
this.inheritsFrom = inheritsFrom;
|
||||
this.minimumLauncherVersion = minimumLauncherVersion;
|
||||
this.hidden = hidden;
|
||||
this.runDir = runDir;
|
||||
if (libraries == null)
|
||||
this.libraries = new ArrayList<>();
|
||||
else {
|
||||
this.libraries = new ArrayList<>(libraries.size());
|
||||
for (IMinecraftLibrary library : libraries)
|
||||
this.libraries.add((MinecraftLibrary) library.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new MinecraftVersion(minecraftArguments, mainClass, time, id, type, processArguments, releaseTime, assets, jar, inheritsFrom, runDir, minimumLauncherVersion, libraries, hidden);
|
||||
}
|
||||
|
||||
public MinecraftVersion resolve(IMinecraftProvider provider) throws GameException {
|
||||
return resolve(provider, new HashSet<>());
|
||||
}
|
||||
|
||||
protected MinecraftVersion resolve(IMinecraftProvider provider, Set<String> resolvedSoFar) throws GameException {
|
||||
if (inheritsFrom == null)
|
||||
return this;
|
||||
if (!resolvedSoFar.add(id))
|
||||
throw new GameException(C.i18n("launch.circular_dependency_versions"));
|
||||
|
||||
MinecraftVersion parent = provider.getVersionById(inheritsFrom);
|
||||
if (parent == null) {
|
||||
if (!provider.install(inheritsFrom, t -> t.hidden = true))
|
||||
return this;
|
||||
parent = provider.getVersionById(inheritsFrom);
|
||||
}
|
||||
parent = parent.resolve(provider, resolvedSoFar);
|
||||
MinecraftVersion result = new MinecraftVersion(
|
||||
this.minecraftArguments != null ? this.minecraftArguments : parent.minecraftArguments,
|
||||
this.mainClass != null ? this.mainClass : parent.mainClass,
|
||||
this.time, this.id, this.type, parent.processArguments, this.releaseTime,
|
||||
this.assets != null ? this.assets : parent.assets,
|
||||
this.jar != null ? this.jar : parent.jar,
|
||||
null, this.runDir, parent.minimumLauncherVersion,
|
||||
this.libraries != null ? ArrayUtils.merge(this.libraries, parent.libraries) : parent.libraries, this.hidden);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public File getJar(File gameDir) {
|
||||
String jarId = this.jar == null ? this.id : this.jar;
|
||||
return new File(gameDir, "versions/" + jarId + "/" + jarId + ".jar");
|
||||
}
|
||||
|
||||
public File getJar(File gameDir, String suffix) {
|
||||
String jarId = this.jar == null ? this.id : this.jar;
|
||||
return new File(gameDir, "versions/" + jarId + "/" + jarId + suffix + ".jar");
|
||||
}
|
||||
|
||||
public File getNatives(File gameDir) {
|
||||
return new File(gameDir, "versions/" + id + "/" + id
|
||||
+ "-natives");
|
||||
}
|
||||
|
||||
public boolean isAllowedToUnpackNatives() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getAssets() {
|
||||
return assets == null ? AssetsIndex.DEFAULT_ASSET_NAME : assets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MinecraftVersion o) {
|
||||
return id.compareTo(((MinecraftVersion) o).id);
|
||||
}
|
||||
}
|
||||
-292
@@ -1,292 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.MCUtils;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.DecompressTask;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import org.jackhuang.hellominecraft.utils.views.SwingUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class MinecraftVersionManager extends IMinecraftProvider {
|
||||
|
||||
final Map<String, MinecraftVersion> versions = new TreeMap();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param p
|
||||
*/
|
||||
public MinecraftVersionManager(IMinecraftService p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MinecraftVersion> getVersions() {
|
||||
return versions.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVersionCount() {
|
||||
return versions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshVersions() {
|
||||
onRefreshingVersions.execute(null);
|
||||
|
||||
try {
|
||||
MCUtils.tryWriteProfile(service.baseDirectory());
|
||||
} catch (IOException ex) {
|
||||
HMCLog.warn("Failed to create launcher_profiles.json, Forge/LiteLoader installer will not work.", ex);
|
||||
}
|
||||
|
||||
versions.clear();
|
||||
File oldDir = new File(service.baseDirectory(), "bin");
|
||||
if (oldDir.exists()) {
|
||||
MinecraftClassicVersion v = new MinecraftClassicVersion();
|
||||
versions.put(v.id, v);
|
||||
}
|
||||
|
||||
File version = new File(service.baseDirectory(), "versions");
|
||||
File[] files = version.listFiles();
|
||||
if (files == null || files.length == 0)
|
||||
return;
|
||||
|
||||
for (File dir : files) {
|
||||
String id = dir.getName();
|
||||
File jsonFile = new File(dir, id + ".json");
|
||||
|
||||
if (!dir.isDirectory())
|
||||
continue;
|
||||
boolean ask = false;
|
||||
File[] jsons = null;
|
||||
if (!jsonFile.exists()) {
|
||||
jsons = FileUtils.searchSuffix(dir, "json");
|
||||
if (jsons.length == 1)
|
||||
ask = true;
|
||||
}
|
||||
if (ask) {
|
||||
HMCLog.warn("Found not matched filenames version: " + id + ", json: " + jsons[0].getName());
|
||||
if (MessageBox.Show(String.format(C.i18n("launcher.versions_json_not_matched"), id, jsons[0].getName()), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
jsons[0].renameTo(new File(jsons[0].getParent(), id + ".json"));
|
||||
}
|
||||
if (!jsonFile.exists()) {
|
||||
if (MessageBox.Show(C.i18n("launcher.versions_json_not_matched_cannot_auto_completion", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION)
|
||||
FileUtils.deleteDirectoryQuietly(dir);
|
||||
continue;
|
||||
}
|
||||
MinecraftVersion mcVersion;
|
||||
try {
|
||||
mcVersion = C.gson.fromJson(FileUtils.readFileToString(jsonFile), MinecraftVersion.class);
|
||||
if (mcVersion == null)
|
||||
throw new GameException("Wrong json format, got null.");
|
||||
} catch (IOException | GameException e) {
|
||||
HMCLog.warn("Found wrong format json, try to fix it.", e);
|
||||
if (MessageBox.Show(C.i18n("launcher.versions_json_not_formatted", id), MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
||||
service.download().downloadMinecraftVersionJson(id);
|
||||
try {
|
||||
mcVersion = C.gson.fromJson(FileUtils.readFileToString(jsonFile), MinecraftVersion.class);
|
||||
if (mcVersion == null)
|
||||
throw new GameException("Wrong json format, got null.");
|
||||
} catch (IOException | GameException ex) {
|
||||
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", ex);
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
if (!id.equals(mcVersion.id)) {
|
||||
HMCLog.warn("Found: " + dir + ", it contains id: " + mcVersion.id + ", expected: " + id + ", this app will fix this problem.");
|
||||
mcVersion.id = id;
|
||||
FileUtils.writeQuietly(jsonFile, C.gsonPrettyPrinting.toJson(mcVersion));
|
||||
}
|
||||
|
||||
if (mcVersion.libraries != null)
|
||||
for (MinecraftLibrary ml : mcVersion.libraries)
|
||||
ml.init();
|
||||
versions.put(id, mcVersion);
|
||||
onLoadedVersion.execute(id);
|
||||
} catch (Exception e) {
|
||||
HMCLog.warn("Ignoring: " + dir + ", the json of this Minecraft is malformed.", e);
|
||||
}
|
||||
}
|
||||
onRefreshedVersions.execute(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File versionRoot(String id) {
|
||||
return new File(service.baseDirectory(), "versions/" + id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVersionFromDisk(String name) {
|
||||
File version = versionRoot(name);
|
||||
if (!version.exists())
|
||||
return true;
|
||||
|
||||
versions.remove(name);
|
||||
return FileUtils.deleteDirectoryQuietly(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renameVersion(String from, String to) {
|
||||
try {
|
||||
File fromJson = new File(versionRoot(from), from + ".json");
|
||||
MinecraftVersion mcVersion = C.gson.fromJson(FileUtils.readFileToString(fromJson), MinecraftVersion.class);
|
||||
mcVersion.id = to;
|
||||
FileUtils.writeQuietly(fromJson, C.gsonPrettyPrinting.toJson(mcVersion));
|
||||
File toDir = versionRoot(to);
|
||||
versionRoot(from).renameTo(toDir);
|
||||
File toJson = new File(toDir, to + ".json");
|
||||
File toJar = new File(toDir, to + ".jar");
|
||||
new File(toDir, from + ".json").renameTo(toJson);
|
||||
File newJar = new File(toDir, from + ".jar");
|
||||
if (newJar.exists())
|
||||
newJar.renameTo(toJar);
|
||||
return true;
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
HMCLog.warn("Failed to rename " + from + " to " + to + ", the json of this Minecraft is malformed.", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getRunDirectory(String id) {
|
||||
if ("version".equals(getVersionById(id).runDir))
|
||||
return versionRoot(id);
|
||||
return baseDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean install(String id, Consumer<MinecraftVersion> callback) {
|
||||
MinecraftVersion v = service.download().downloadMinecraft(id);
|
||||
if (callback != null) {
|
||||
callback.accept(v);
|
||||
File mvt = new File(versionRoot(id), id + ".json");
|
||||
FileUtils.writeQuietly(mvt, C.gsonPrettyPrinting.toJson(v));
|
||||
}
|
||||
if (v != null) {
|
||||
refreshVersions();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(String mv, String name) {
|
||||
SwingUtils.openFolder((name == null) ? getRunDirectory(mv) : new File(getRunDirectory(mv), name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DecompressLibraryJob getDecompressLibraries(MinecraftVersion v) throws GameException {
|
||||
if (v.libraries == null)
|
||||
throw new GameException("Wrong format: minecraft.json");
|
||||
ArrayList<File> unzippings = new ArrayList<>();
|
||||
ArrayList<String[]> extractRules = new ArrayList<>();
|
||||
for (IMinecraftLibrary l : v.libraries) {
|
||||
l.init();
|
||||
if (l.isRequiredToUnzip() && v.isAllowedToUnpackNatives()) {
|
||||
unzippings.add(IOUtils.tryGetCanonicalFile(l.getFilePath(service.baseDirectory())));
|
||||
extractRules.add(l.getDecompressExtractRules());
|
||||
}
|
||||
}
|
||||
return new DecompressLibraryJob(unzippings.toArray(new File[0]), extractRules.toArray(new String[0][]), getDecompressNativesToLocation(v));
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getDecompressNativesToLocation(MinecraftVersion v) {
|
||||
return v == null ? null : v.getNatives(service.baseDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getMinecraftJar(String id) {
|
||||
if (versions.containsKey(id))
|
||||
return versions.get(id).getJar(service.baseDirectory());
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion getOneVersion() {
|
||||
return versions.isEmpty() ? null : versions.values().iterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftVersion getVersionById(String id) {
|
||||
return StrUtils.isBlank(id) ? null : versions.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getResourcePacks() {
|
||||
return new File(service.baseDirectory(), "resourcepacks");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLaunch() {
|
||||
File resourcePacks = getResourcePacks();
|
||||
if (!resourcePacks.exists())
|
||||
resourcePacks.mkdirs();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanFolder() {
|
||||
for (MinecraftVersion s : getVersions()) {
|
||||
FileUtils.deleteDirectoryQuietly(new File(versionRoot(s.id), s.id + "-natives"));
|
||||
File f = getRunDirectory(s.id);
|
||||
String[] dir = { "asm", "NVIDIA", "server-resource-packs", "natives", "native" };
|
||||
for (String str : dir)
|
||||
FileUtils.deleteDirectoryQuietly(new File(f, str));
|
||||
String[] files = { "output-client.log", "usercache.json", "usernamecache.json", "hmclmc.log" };
|
||||
for (String str : files)
|
||||
new File(f, str).delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeMiencraft() {
|
||||
|
||||
}
|
||||
|
||||
private void downloadModpack(String url) throws IOException {
|
||||
File tmp = File.createTempFile("hmcl", ".zip");
|
||||
TaskWindow.getInstance().addTask(new FileDownloadTask(url, tmp)).addTask(new DecompressTask(tmp, service.baseDirectory())).start();
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Natives implements Cloneable {
|
||||
|
||||
public String windows, osx, linux;
|
||||
|
||||
@Override
|
||||
protected Object clone() {
|
||||
Natives n = new Natives();
|
||||
n.windows = windows;
|
||||
n.osx = osx;
|
||||
n.linux = linux;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class Rules {
|
||||
|
||||
public String action;
|
||||
public OS os;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.core.version;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ServerInfo {
|
||||
|
||||
public String name, addr, picurl, type, info, wfjc, tsjs, version, url, depend;
|
||||
public String[] md5;
|
||||
public int port;
|
||||
|
||||
public Icon icon;
|
||||
|
||||
public static final HashMap<String, Icon> CACHE = new HashMap<>();
|
||||
|
||||
public void downloadIcon() {
|
||||
if (icon == null && Utils.isURL(picurl))
|
||||
if (CACHE.containsKey(picurl))
|
||||
icon = CACHE.get(picurl);
|
||||
else
|
||||
try {
|
||||
File tmp = File.createTempFile("HMCLSERVER", ".png");
|
||||
FileDownloadTask.download(picurl, tmp, null);
|
||||
CACHE.put(picurl, icon = new ImageIcon(tmp.getAbsolutePath()));
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException("Failed to download icon", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.settings;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.lookandfeel.Theme;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
import org.jackhuang.hellominecraft.utils.system.JdkVersion;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Config {
|
||||
|
||||
@SerializedName("last")
|
||||
private String last;
|
||||
@SerializedName("bgpath")
|
||||
private String bgpath;
|
||||
@SerializedName("clientToken")
|
||||
private final String clientToken;
|
||||
private String proxyHost, proxyPort, proxyUserName, proxyPassword;
|
||||
@SerializedName("enableShadow")
|
||||
private boolean enableShadow;
|
||||
@SerializedName("decorated")
|
||||
private boolean decorated;
|
||||
@SerializedName("enableAnimation")
|
||||
private boolean enableAnimation;
|
||||
@SerializedName("theme")
|
||||
private int theme;
|
||||
@SerializedName("java")
|
||||
private List<JdkVersion> java;
|
||||
|
||||
public List<JdkVersion> getJava() {
|
||||
return java == null ? java = new ArrayList<>() : java;
|
||||
}
|
||||
|
||||
public transient final EventHandler<Theme> themeChangedEvent = new EventHandler<>(this);
|
||||
public transient final EventHandler<DownloadType> downloadTypeChangedEvent = new EventHandler<>(this);
|
||||
|
||||
public Theme getTheme() {
|
||||
return Theme.values()[theme];
|
||||
}
|
||||
|
||||
public void setTheme(int theme) {
|
||||
this.theme = theme;
|
||||
themeChangedEvent.execute(getTheme());
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public boolean isDecorated() {
|
||||
return decorated;
|
||||
}
|
||||
|
||||
public void setDecorated(boolean decorated) {
|
||||
this.decorated = decorated;
|
||||
}
|
||||
|
||||
public boolean isEnableShadow() {
|
||||
return enableShadow;
|
||||
}
|
||||
|
||||
public void setEnableShadow(boolean enableShadow) {
|
||||
this.enableShadow = enableShadow;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getLast() {
|
||||
return last;
|
||||
}
|
||||
|
||||
public void setLast(String last) {
|
||||
this.last = last;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getBgpath() {
|
||||
return bgpath;
|
||||
}
|
||||
|
||||
public void setBgpath(String bgpath) {
|
||||
this.bgpath = bgpath;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public boolean isEnableAnimation() {
|
||||
return enableAnimation;
|
||||
}
|
||||
|
||||
public void setEnableAnimation(boolean enableAnimation) {
|
||||
this.enableAnimation = enableAnimation;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getClientToken() {
|
||||
return clientToken;
|
||||
}
|
||||
|
||||
public IAuthenticator getAuthenticator() {
|
||||
return IAuthenticator.LOGINS.get(getLoginType());
|
||||
}
|
||||
|
||||
public int getLoginType() {
|
||||
if (logintype < 0 || logintype >= IAuthenticator.LOGINS.size())
|
||||
logintype = 0;
|
||||
return logintype;
|
||||
}
|
||||
|
||||
public void setLoginType(int logintype) {
|
||||
this.logintype = logintype;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public int getDownloadType() {
|
||||
return downloadtype;
|
||||
}
|
||||
|
||||
public void setDownloadType(int downloadtype) {
|
||||
this.downloadtype = downloadtype;
|
||||
downloadTypeChangedEvent.execute(getDownloadSource());
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public TreeMap<String, Profile> getConfigurations() {
|
||||
if (configurations == null)
|
||||
configurations = new TreeMap<>();
|
||||
if (configurations.isEmpty()) {
|
||||
Profile profile = new Profile();
|
||||
configurations.put(profile.getName(), profile);
|
||||
}
|
||||
return configurations;
|
||||
}
|
||||
|
||||
public Map getAuthenticatorConfig(String authId) {
|
||||
return auth.get(authId);
|
||||
}
|
||||
|
||||
public void setAuthenticatorConfig(String authId, Map map) {
|
||||
auth.put(authId, map);
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
@SerializedName("logintype")
|
||||
private int logintype;
|
||||
@SerializedName("downloadtype")
|
||||
private int downloadtype;
|
||||
@SerializedName("configurations")
|
||||
private TreeMap<String, Profile> configurations;
|
||||
@SerializedName("auth")
|
||||
private Map<String, Map> auth;
|
||||
|
||||
public Config() {
|
||||
clientToken = UUID.randomUUID().toString();
|
||||
logintype = downloadtype = 0;
|
||||
enableShadow = false;
|
||||
enableAnimation = true;
|
||||
theme = 4;
|
||||
decorated = OS.os() == OS.LINUX;
|
||||
auth = new HashMap<>();
|
||||
}
|
||||
|
||||
public DownloadType getDownloadSource() {
|
||||
if (downloadtype >= DownloadType.values().length || downloadtype < 0) {
|
||||
downloadtype = 0;
|
||||
Settings.save();
|
||||
}
|
||||
return DownloadType.values()[downloadtype];
|
||||
}
|
||||
|
||||
public String getProxyHost() {
|
||||
return proxyHost == null ? "" : proxyHost;
|
||||
}
|
||||
|
||||
public void setProxyHost(String proxyHost) {
|
||||
this.proxyHost = proxyHost;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getProxyPort() {
|
||||
return proxyPort == null ? "" : proxyPort;
|
||||
}
|
||||
|
||||
public void setProxyPort(String proxyPort) {
|
||||
this.proxyPort = proxyPort;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getProxyUserName() {
|
||||
return proxyUserName == null ? "" : proxyUserName;
|
||||
}
|
||||
|
||||
public void setProxyUserName(String proxyUserName) {
|
||||
this.proxyUserName = proxyUserName;
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
public String getProxyPassword() {
|
||||
return proxyPassword == null ? "" : proxyPassword;
|
||||
}
|
||||
|
||||
public void setProxyPassword(String proxyPassword) {
|
||||
this.proxyPassword = proxyPassword;
|
||||
Settings.save();
|
||||
}
|
||||
}
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.launcher.core.GameException;
|
||||
import org.jackhuang.hellominecraft.launcher.core.installers.MinecraftInstallerService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.assets.MinecraftAssetService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.MinecraftDownloadService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions;
|
||||
import org.jackhuang.hellominecraft.launcher.core.launch.MinecraftLoader;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftAssetService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftDownloadService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftInstallerService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftLoader;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftModService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.core.mod.MinecraftModService;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class DefaultMinecraftService extends IMinecraftService {
|
||||
|
||||
File base;
|
||||
Profile p;
|
||||
final Map<String, VersionSetting> versionSettings = new HashMap<>();
|
||||
|
||||
public DefaultMinecraftService(Profile p) {
|
||||
this.p = p;
|
||||
this.provider = new HMCLGameProvider(this);
|
||||
provider.initializeMiencraft();
|
||||
provider.onRefreshingVersions.register((sender, x) -> {
|
||||
versionSettings.clear();
|
||||
return true;
|
||||
});
|
||||
provider.onLoadedVersion.register((sender, id) -> {
|
||||
VersionSetting vs = new VersionSetting();
|
||||
File f = new File(provider.versionRoot(id), "hmclversion.cfg");
|
||||
if (f.exists()) {
|
||||
String s = FileUtils.readFileToStringQuietly(f);
|
||||
if (s != null)
|
||||
vs = C.gson.fromJson(s, VersionSetting.class);
|
||||
}
|
||||
vs.id = id;
|
||||
versionSettings.put(id, vs);
|
||||
return true;
|
||||
});
|
||||
this.mms = new MinecraftModService(this);
|
||||
this.mds = new MinecraftDownloadService(this);
|
||||
this.mas = new MinecraftAssetService(this);
|
||||
this.mis = new MinecraftInstallerService(this);
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (String key : versionSettings.keySet())
|
||||
saveVersionSetting(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public VersionSetting getVersionSetting(String id) {
|
||||
return versionSettings.get(id);
|
||||
}
|
||||
|
||||
public void saveVersionSetting(String id) {
|
||||
if (!versionSettings.containsKey(id))
|
||||
return;
|
||||
File f = new File(provider.versionRoot(id), "hmclversion.cfg");
|
||||
FileUtils.writeQuietly(f, C.gson.toJson(versionSettings.get(id)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public File baseDirectory() {
|
||||
return p.getCanonicalGameDirFile();
|
||||
}
|
||||
|
||||
protected IMinecraftProvider provider;
|
||||
|
||||
@Override
|
||||
public IMinecraftProvider version() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
protected MinecraftModService mms;
|
||||
|
||||
@Override
|
||||
public IMinecraftModService mod() {
|
||||
return mms;
|
||||
}
|
||||
|
||||
protected MinecraftDownloadService mds;
|
||||
|
||||
@Override
|
||||
public IMinecraftDownloadService download() {
|
||||
return mds;
|
||||
}
|
||||
|
||||
final MinecraftAssetService mas;
|
||||
|
||||
@Override
|
||||
public IMinecraftAssetService asset() {
|
||||
return mas;
|
||||
}
|
||||
|
||||
protected MinecraftInstallerService mis;
|
||||
|
||||
@Override
|
||||
public IMinecraftInstallerService install() {
|
||||
return mis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMinecraftLoader launch(LaunchOptions options, UserProfileProvider p) throws GameException {
|
||||
return new MinecraftLoader(options, this, p);
|
||||
}
|
||||
|
||||
public Profile getProfile() {
|
||||
return p;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.settings;
|
||||
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.launcher.api.IPlugin;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.IAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.OfflineAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.SkinmeAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.UserProfileProvider;
|
||||
import org.jackhuang.hellominecraft.launcher.core.auth.YggdrasilAuthenticator;
|
||||
import org.jackhuang.hellominecraft.launcher.views.MainFrame;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class DefaultPlugin implements IPlugin {
|
||||
|
||||
protected static YggdrasilAuthenticator YGGDRASIL_LOGIN;
|
||||
protected static OfflineAuthenticator OFFLINE_LOGIN;
|
||||
protected static SkinmeAuthenticator SKINME_LOGIN;
|
||||
|
||||
@Override
|
||||
public IMinecraftService provideMinecraftService(Profile profile) {
|
||||
return new DefaultMinecraftService(profile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegisterAuthenticators(Consumer<IAuthenticator> apply) {
|
||||
String clientToken = Settings.getInstance().getClientToken();
|
||||
OFFLINE_LOGIN = new OfflineAuthenticator(clientToken);
|
||||
OFFLINE_LOGIN.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(OFFLINE_LOGIN.id()));
|
||||
YGGDRASIL_LOGIN = new YggdrasilAuthenticator(clientToken);
|
||||
YGGDRASIL_LOGIN.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(YGGDRASIL_LOGIN.id()));
|
||||
SKINME_LOGIN = new SkinmeAuthenticator(clientToken);
|
||||
SKINME_LOGIN.onLoadSettings(Settings.getInstance().getAuthenticatorConfig(SKINME_LOGIN.id()));
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Settings.getInstance().setAuthenticatorConfig(OFFLINE_LOGIN.id(), OFFLINE_LOGIN.onSaveSettings());
|
||||
Settings.getInstance().setAuthenticatorConfig(YGGDRASIL_LOGIN.id(), YGGDRASIL_LOGIN.onSaveSettings());
|
||||
Settings.getInstance().setAuthenticatorConfig(SKINME_LOGIN.id(), SKINME_LOGIN.onSaveSettings());
|
||||
}
|
||||
});
|
||||
apply.accept(OFFLINE_LOGIN);
|
||||
apply.accept(YGGDRASIL_LOGIN);
|
||||
apply.accept(SKINME_LOGIN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showUI() {
|
||||
MainFrame.showMainFrame();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProcessingLoginResult(UserProfileProvider result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializingProfile(Profile p) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.settings;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.GameDirType;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.MinecraftVersionManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class HMCLGameProvider extends MinecraftVersionManager {
|
||||
|
||||
public HMCLGameProvider(DefaultMinecraftService p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getRunDirectory(String id) {
|
||||
return ((DefaultMinecraftService) service).getVersionSetting(id).getGameDirType() == GameDirType.VERSION_FOLDER
|
||||
? service.version().versionRoot(id)
|
||||
: super.getRunDirectory(id);
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.settings;
|
||||
|
||||
import java.io.File;
|
||||
import org.jackhuang.hellominecraft.launcher.api.PluginManager;
|
||||
import org.jackhuang.hellominecraft.launcher.core.MCUtils;
|
||||
import org.jackhuang.hellominecraft.launcher.core.service.IMinecraftService;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Profile {
|
||||
|
||||
private String name, selectedMinecraftVersion = "", gameDir;
|
||||
|
||||
protected transient IMinecraftService service;
|
||||
public transient final EventHandler<String> propertyChanged = new EventHandler<>(this);
|
||||
|
||||
public Profile() {
|
||||
this("Default");
|
||||
}
|
||||
|
||||
public Profile(String name) {
|
||||
this.name = name;
|
||||
gameDir = MCUtils.getInitGameDir().getPath();
|
||||
PluginManager.NOW_PLUGIN.onInitializingProfile(this);
|
||||
}
|
||||
|
||||
public Profile(Profile v) {
|
||||
this();
|
||||
if (v == null)
|
||||
return;
|
||||
name = v.name;
|
||||
gameDir = v.gameDir;
|
||||
}
|
||||
|
||||
public IMinecraftService service() {
|
||||
if (service == null)
|
||||
service = PluginManager.NOW_PLUGIN.provideMinecraftService(this);
|
||||
return service;
|
||||
}
|
||||
|
||||
public VersionSetting getSelectedVersionSetting() {
|
||||
return getVersionSetting(getSelectedVersion());
|
||||
}
|
||||
|
||||
public VersionSetting getVersionSetting(String id) {
|
||||
return ((DefaultMinecraftService) service()).getVersionSetting(id);
|
||||
}
|
||||
|
||||
public String getSettingsSelectedMinecraftVersion() {
|
||||
return selectedMinecraftVersion;
|
||||
}
|
||||
|
||||
public String getSelectedVersion() {
|
||||
String v = selectedMinecraftVersion;
|
||||
if (StrUtils.isBlank(v) || service.version().getVersionById(v) == null) {
|
||||
if (service.version().getVersionCount() > 0)
|
||||
v = service.version().getOneVersion().id;
|
||||
if (StrUtils.isNotBlank(v))
|
||||
setSelectedMinecraftVersion(v);
|
||||
}
|
||||
return StrUtils.isBlank(v) ? null : v;
|
||||
}
|
||||
|
||||
public transient final EventHandler<String> selectedVersionChangedEvent = new EventHandler<>(this);
|
||||
|
||||
public void setSelectedMinecraftVersion(String selectedMinecraftVersion) {
|
||||
this.selectedMinecraftVersion = selectedMinecraftVersion;
|
||||
propertyChanged.execute("selectedMinecraftVersion");
|
||||
selectedVersionChangedEvent.execute(selectedMinecraftVersion);
|
||||
}
|
||||
|
||||
public String getGameDir() {
|
||||
if (StrUtils.isBlank(gameDir))
|
||||
gameDir = MCUtils.getInitGameDir().getPath();
|
||||
return IOUtils.addSeparator(gameDir);
|
||||
}
|
||||
|
||||
public String getCanonicalGameDir() {
|
||||
return IOUtils.tryGetCanonicalFolderPath(getGameDirFile());
|
||||
}
|
||||
|
||||
public File getCanonicalGameDirFile() {
|
||||
return IOUtils.tryGetCanonicalFile(getGameDirFile());
|
||||
}
|
||||
|
||||
public File getGameDirFile() {
|
||||
return new File(getGameDir());
|
||||
}
|
||||
|
||||
public Profile setGameDir(String gameDir) {
|
||||
this.gameDir = gameDir;
|
||||
service().version().refreshVersions();
|
||||
propertyChanged.execute("gameDir");
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
propertyChanged.execute("name");
|
||||
}
|
||||
|
||||
public void checkFormat() {
|
||||
gameDir = gameDir.replace('/', OS.os().fileSeparator).replace('\\', OS.os().fileSeparator);
|
||||
}
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.settings;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.core.download.DownloadType;
|
||||
import org.jackhuang.hellominecraft.utils.CollectionUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Event;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Predicate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class Settings {
|
||||
|
||||
public static final String DEFAULT_PROFILE = "Default";
|
||||
|
||||
public static final File SETTINGS_FILE = new File(IOUtils.currentDir(), "hmcl.json");
|
||||
|
||||
private static final Config SETTINGS;
|
||||
public static final UpdateChecker UPDATE_CHECKER = new UpdateChecker(new VersionNumber(Main.VERSION_FIRST, Main.VERSION_SECOND, Main.VERSION_THIRD),
|
||||
"hmcl");
|
||||
|
||||
public static Config getInstance() {
|
||||
return SETTINGS;
|
||||
}
|
||||
|
||||
static {
|
||||
SETTINGS = initSettings();
|
||||
SETTINGS.downloadTypeChangedEvent.register(new Event<DownloadType>() {
|
||||
@Override
|
||||
public boolean call(Object sender, DownloadType t) {
|
||||
DownloadType.setSuggestedDownloadType(t);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
DownloadType.setSuggestedDownloadType(SETTINGS.getDownloadSource());
|
||||
if (!getProfiles().containsKey(DEFAULT_PROFILE))
|
||||
getProfiles().put(DEFAULT_PROFILE, new Profile());
|
||||
|
||||
for (Profile e : getProfiles().values()) {
|
||||
e.checkFormat();
|
||||
e.propertyChanged.register(new Event<String>() {
|
||||
@Override
|
||||
public boolean call(Object sender, String t) {
|
||||
save();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static Config initSettings() {
|
||||
Config c = new Config();
|
||||
if (SETTINGS_FILE.exists())
|
||||
try {
|
||||
String str = FileUtils.readFileToString(SETTINGS_FILE);
|
||||
if (str == null || str.trim().equals(""))
|
||||
HMCLog.log("Settings file is empty, use the default settings.");
|
||||
else {
|
||||
Config d = C.gsonPrettyPrinting.fromJson(str, Config.class);
|
||||
if (d != null)
|
||||
c = d;
|
||||
}
|
||||
HMCLog.log("Initialized settings.");
|
||||
} catch (IOException | JsonSyntaxException e) {
|
||||
HMCLog.warn("Something happened wrongly when load settings.", e);
|
||||
if (MessageBox.Show(C.i18n("settings.failed_load"), MessageBox.YES_NO_OPTION) == MessageBox.NO_OPTION) {
|
||||
HMCLog.err("Cancelled loading settings.");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
HMCLog.log("No settings file here, may be first loading.");
|
||||
return c;
|
||||
}
|
||||
|
||||
public static void save() {
|
||||
try {
|
||||
FileUtils.write(SETTINGS_FILE, C.gsonPrettyPrinting.toJson(SETTINGS));
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Failed to save config", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static Profile getProfile(String name) {
|
||||
if (name == null)
|
||||
return getProfiles().get("Default");
|
||||
return getProfiles().get(name);
|
||||
}
|
||||
|
||||
public static Map<String, Profile> getProfiles() {
|
||||
return SETTINGS.getConfigurations();
|
||||
}
|
||||
|
||||
public static void setProfile(Profile ver) {
|
||||
getProfiles().put(ver.getName(), ver);
|
||||
}
|
||||
|
||||
public static Collection<Profile> getProfilesFiltered() {
|
||||
return CollectionUtils.map(getProfiles().values(), new Predicate<Profile>() {
|
||||
@Override
|
||||
public boolean apply(Profile t) {
|
||||
return t != null && t.getName() != null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Profile getOneProfile() {
|
||||
return SETTINGS.getConfigurations().firstEntry().getValue();
|
||||
}
|
||||
|
||||
public static boolean trySetProfile(Profile ver) {
|
||||
if (ver == null || ver.getName() == null || getProfiles().containsKey(ver.getName()))
|
||||
return false;
|
||||
getProfiles().put(ver.getName(), ver);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean delProfile(Profile ver) {
|
||||
return delProfile(ver.getName());
|
||||
}
|
||||
|
||||
public static boolean delProfile(String ver) {
|
||||
if (DEFAULT_PROFILE.equals(ver)) {
|
||||
MessageBox.Show(C.i18n("settings.cannot_remove_default_config"));
|
||||
return false;
|
||||
}
|
||||
return getProfiles().remove(ver) != null;
|
||||
}
|
||||
}
|
||||
-323
@@ -1,323 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.core.LauncherVisibility;
|
||||
import org.jackhuang.hellominecraft.launcher.core.launch.LaunchOptions;
|
||||
import org.jackhuang.hellominecraft.launcher.core.version.GameDirType;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.EventHandler;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.system.Java;
|
||||
import org.jackhuang.hellominecraft.utils.system.JdkVersion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class VersionSetting {
|
||||
|
||||
public transient String id;
|
||||
|
||||
private String javaArgs, minecraftArgs, maxMemory, permSize, width, height;
|
||||
private String javaDir, precalledCommand, serverIp, java;
|
||||
private boolean fullscreen, debug, noJVMArgs, canceledWrapper;
|
||||
|
||||
/**
|
||||
* 0 - Close the launcher when the game starts.<br/>
|
||||
* 1 - Hide the launcher when the game starts.<br/>
|
||||
* 2 - Keep the launcher open.<br/>
|
||||
*/
|
||||
private int launcherVisibility;
|
||||
|
||||
/**
|
||||
* 0 - .minecraft<br/>
|
||||
* 1 - .minecraft/versions/<version>/<br/>
|
||||
*/
|
||||
private int gameDirType;
|
||||
|
||||
public transient final EventHandler<String> propertyChanged = new EventHandler<>(this);
|
||||
|
||||
public VersionSetting() {
|
||||
debug = fullscreen = canceledWrapper = false;
|
||||
launcherVisibility = gameDirType = 0;
|
||||
javaDir = java = minecraftArgs = serverIp = precalledCommand = "";
|
||||
}
|
||||
|
||||
public VersionSetting(VersionSetting v) {
|
||||
this();
|
||||
if (v == null)
|
||||
return;
|
||||
maxMemory = v.maxMemory;
|
||||
width = v.width;
|
||||
height = v.height;
|
||||
java = v.java;
|
||||
fullscreen = v.fullscreen;
|
||||
javaArgs = v.javaArgs;
|
||||
javaDir = v.javaDir;
|
||||
debug = v.debug;
|
||||
minecraftArgs = v.minecraftArgs;
|
||||
permSize = v.permSize;
|
||||
gameDirType = v.gameDirType;
|
||||
canceledWrapper = v.canceledWrapper;
|
||||
noJVMArgs = v.noJVMArgs;
|
||||
launcherVisibility = v.launcherVisibility;
|
||||
precalledCommand = v.precalledCommand;
|
||||
serverIp = v.serverIp;
|
||||
}
|
||||
|
||||
public String getJavaDir() {
|
||||
Java j = getJava();
|
||||
if (j.getHome() == null)
|
||||
return javaDir;
|
||||
else
|
||||
return j.getJava();
|
||||
}
|
||||
|
||||
public String getSettingsJavaDir() {
|
||||
return javaDir;
|
||||
}
|
||||
|
||||
public File getJavaDirFile() {
|
||||
return new File(getJavaDir());
|
||||
}
|
||||
|
||||
public void setJavaDir(String javaDir) {
|
||||
this.javaDir = javaDir;
|
||||
propertyChanged.execute("javaDir");
|
||||
}
|
||||
|
||||
public Java getJava() {
|
||||
return Java.JAVA.get(getJavaIndexInAllJavas());
|
||||
}
|
||||
|
||||
public int getJavaIndexInAllJavas() {
|
||||
if (StrUtils.isBlank(java) && StrUtils.isNotBlank(javaDir))
|
||||
java = "Custom";
|
||||
int idx = Java.JAVA.indexOf(new Java(java, null));
|
||||
if (idx == -1) {
|
||||
java = "Default";
|
||||
idx = 0;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
public void setJava(Java java) {
|
||||
if (java == null)
|
||||
this.java = Java.JAVA.get(0).getName();
|
||||
else {
|
||||
int idx = Java.JAVA.indexOf(java);
|
||||
if (idx == -1)
|
||||
return;
|
||||
this.java = java.getName();
|
||||
}
|
||||
propertyChanged.execute("java");
|
||||
}
|
||||
|
||||
public String getJavaArgs() {
|
||||
if (StrUtils.isBlank(javaArgs))
|
||||
return "";
|
||||
return javaArgs;
|
||||
}
|
||||
|
||||
public void setJavaArgs(String javaArgs) {
|
||||
this.javaArgs = javaArgs;
|
||||
propertyChanged.execute("javaArgs");
|
||||
}
|
||||
|
||||
public boolean hasJavaArgs() {
|
||||
return StrUtils.isNotBlank(getJavaArgs().trim());
|
||||
}
|
||||
|
||||
public String getMaxMemory() {
|
||||
if (StrUtils.isBlank(maxMemory))
|
||||
return String.valueOf(Utils.getSuggestedMemorySize());
|
||||
return maxMemory;
|
||||
}
|
||||
|
||||
public void setMaxMemory(String maxMemory) {
|
||||
this.maxMemory = maxMemory;
|
||||
propertyChanged.execute("maxMemory");
|
||||
}
|
||||
|
||||
public String getWidth() {
|
||||
if (StrUtils.isBlank(width))
|
||||
return "854";
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(String width) {
|
||||
this.width = width;
|
||||
propertyChanged.execute("width");
|
||||
}
|
||||
|
||||
public String getHeight() {
|
||||
if (StrUtils.isBlank(height))
|
||||
return "480";
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(String height) {
|
||||
this.height = height;
|
||||
propertyChanged.execute("height");
|
||||
}
|
||||
|
||||
public boolean isFullscreen() {
|
||||
return fullscreen;
|
||||
}
|
||||
|
||||
public void setFullscreen(boolean fullscreen) {
|
||||
this.fullscreen = fullscreen;
|
||||
propertyChanged.execute("fullscreen");
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
propertyChanged.execute("debug");
|
||||
}
|
||||
|
||||
public LauncherVisibility getLauncherVisibility() {
|
||||
return LauncherVisibility.values()[launcherVisibility];
|
||||
}
|
||||
|
||||
public void setLauncherVisibility(LauncherVisibility launcherVisibility) {
|
||||
this.launcherVisibility = launcherVisibility.ordinal();
|
||||
propertyChanged.execute("launcherVisibility");
|
||||
}
|
||||
|
||||
public GameDirType getGameDirType() {
|
||||
if (gameDirType < 0 || gameDirType > 1)
|
||||
setGameDirType(GameDirType.ROOT_FOLDER);
|
||||
return GameDirType.values()[gameDirType];
|
||||
}
|
||||
|
||||
public void setGameDirType(GameDirType gameDirType) {
|
||||
this.gameDirType = gameDirType.ordinal();
|
||||
propertyChanged.execute("gameDirType");
|
||||
}
|
||||
|
||||
public String getPermSize() {
|
||||
return permSize;
|
||||
}
|
||||
|
||||
public void setPermSize(String permSize) {
|
||||
this.permSize = permSize;
|
||||
propertyChanged.execute("permSize");
|
||||
}
|
||||
|
||||
public boolean isNoJVMArgs() {
|
||||
return noJVMArgs;
|
||||
}
|
||||
|
||||
public void setNoJVMArgs(boolean noJVMArgs) {
|
||||
this.noJVMArgs = noJVMArgs;
|
||||
propertyChanged.execute("noJVMArgs");
|
||||
}
|
||||
|
||||
public String getMinecraftArgs() {
|
||||
return minecraftArgs;
|
||||
}
|
||||
|
||||
public void setMinecraftArgs(String minecraftArgs) {
|
||||
this.minecraftArgs = minecraftArgs;
|
||||
propertyChanged.execute("minecraftArgs");
|
||||
}
|
||||
|
||||
public boolean isCanceledWrapper() {
|
||||
return canceledWrapper;
|
||||
}
|
||||
|
||||
public void setCanceledWrapper(boolean canceledWrapper) {
|
||||
this.canceledWrapper = canceledWrapper;
|
||||
propertyChanged.execute("canceledWrapper");
|
||||
}
|
||||
|
||||
public String getPrecalledCommand() {
|
||||
return precalledCommand;
|
||||
}
|
||||
|
||||
public void setPrecalledCommand(String precalledCommand) {
|
||||
this.precalledCommand = precalledCommand;
|
||||
propertyChanged.execute("precalledCommand");
|
||||
}
|
||||
|
||||
public String getServerIp() {
|
||||
return serverIp;
|
||||
}
|
||||
|
||||
public void setServerIp(String serverIp) {
|
||||
this.serverIp = serverIp;
|
||||
propertyChanged.execute("serverIp");
|
||||
}
|
||||
|
||||
public LaunchOptions createLaunchOptions(File gameDir) {
|
||||
LaunchOptions x = new LaunchOptions();
|
||||
x.setCanceledWrapper(isCanceledWrapper());
|
||||
x.setDebug(isDebug());
|
||||
x.setFullscreen(isFullscreen());
|
||||
x.setGameDir(gameDir);
|
||||
x.setGameDirType(getGameDirType());
|
||||
x.setHeight(getHeight());
|
||||
x.setJavaArgs(getJavaArgs());
|
||||
x.setLaunchVersion(id);
|
||||
x.setMaxMemory(getMaxMemory());
|
||||
x.setMinecraftArgs(getMinecraftArgs());
|
||||
x.setName(Main.makeTitle());
|
||||
x.setNoJVMArgs(isNoJVMArgs());
|
||||
x.setPermSize(getPermSize());
|
||||
x.setPrecalledCommand(getPrecalledCommand());
|
||||
x.setProxyHost(Settings.getInstance().getProxyHost());
|
||||
x.setProxyPort(Settings.getInstance().getProxyPort());
|
||||
x.setProxyUser(Settings.getInstance().getProxyUserName());
|
||||
x.setProxyPass(Settings.getInstance().getProxyPassword());
|
||||
x.setServerIp(getServerIp());
|
||||
x.setVersionName(Main.makeTitle());
|
||||
x.setWidth(getWidth());
|
||||
|
||||
String str = getJavaDir();
|
||||
if (!getJavaDirFile().exists()) {
|
||||
HMCLog.err(C.i18n("launch.wrong_javadir"));
|
||||
setJava(null);
|
||||
str = getJavaDir();
|
||||
}
|
||||
JdkVersion jv = new JdkVersion(str);
|
||||
if (Settings.getInstance().getJava().contains(jv))
|
||||
jv = Settings.getInstance().getJava().get(Settings.getInstance().getJava().indexOf(jv));
|
||||
else
|
||||
try {
|
||||
jv = JdkVersion.getJavaVersionFromExecutable(str);
|
||||
Settings.getInstance().getJava().add(jv);
|
||||
Settings.save();
|
||||
} catch (IOException ex) {
|
||||
HMCLog.warn("Failed to get java version", ex);
|
||||
jv = null;
|
||||
}
|
||||
x.setJava(jv);
|
||||
x.setJavaDir(str);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.Main;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
||||
import org.jackhuang.hellominecraft.utils.NetUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.StrUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
import org.jackhuang.hellominecraft.utils.views.LogWindow;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class CrashReporter implements Thread.UncaughtExceptionHandler {
|
||||
|
||||
boolean enableLogger = false;
|
||||
|
||||
public CrashReporter(boolean enableLogger) {
|
||||
this.enableLogger = enableLogger;
|
||||
}
|
||||
|
||||
public boolean checkThrowable(Throwable e) {
|
||||
String s = StrUtils.getStackTrace(e);
|
||||
if (s.contains("MessageBox") || s.contains("AWTError"))
|
||||
return false;
|
||||
else if (s.contains("JFileChooser") || s.contains("JceSecurityManager")) {
|
||||
System.out.println("Is not your operating system installed completely? ");
|
||||
return false;
|
||||
}
|
||||
if (s.contains("sun.awt.shell.Win32ShellFolder2") || s.contains("UnsatisfiedLinkError")) {
|
||||
System.out.println(C.i18n("crash.user_fault"));
|
||||
try {
|
||||
showMessage(C.i18n("crash.user_fault"));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
} else if (s.contains("java.awt.HeadlessException")) {
|
||||
System.out.println(C.i18n("crash.headless"));
|
||||
try {
|
||||
showMessage(C.i18n("crash.headless"));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
} else if (s.contains("java.lang.NoClassDefFoundError") || s.contains("java.lang.VerifyError") || s.contains("java.lang.NoSuchMethodError") || s.contains("java.lang.IncompatibleClassChangeError") || s.contains("java.lang.ClassFormatError")) {
|
||||
System.out.println(C.i18n("crash.NoClassDefFound"));
|
||||
try {
|
||||
showMessage(C.i18n("crash.NoClassDefFound"));
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
} else if (s.contains("java.lang.OutOfMemoryError")) {
|
||||
System.out.println("FUCKING MEMORY LIMIT!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
String s = StrUtils.getStackTrace(e);
|
||||
if (!s.contains("org.jackhuang.hellominecraft"))
|
||||
return;
|
||||
try {
|
||||
String text = "\n---- Hello Minecraft! Crash Report ----\n";
|
||||
text += " Version: " + Main.makeVersion() + "\n";
|
||||
text += " Time: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\n";
|
||||
text += " Thread: " + t.toString() + "\n";
|
||||
text += "\n Content: \n ";
|
||||
text += s + "\n\n";
|
||||
text += "-- System Details --\n";
|
||||
text += " Operating System: " + OS.getSystemVersion() + "\n";
|
||||
text += " Java Version: " + System.getProperty("java.version") + ", " + System.getProperty("java.vendor") + "\n";
|
||||
text += " Java VM Version: " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor") + "\n";
|
||||
if (enableLogger)
|
||||
HMCLog.err(text);
|
||||
else
|
||||
System.out.println(text);
|
||||
|
||||
if (checkThrowable(e) && !System.getProperty("java.vm.name").contains("OpenJDK")) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LogWindow.INSTANCE.showAsCrashWindow(Settings.UPDATE_CHECKER.OUT_DATED);
|
||||
}
|
||||
});
|
||||
if (!Settings.UPDATE_CHECKER.OUT_DATED)
|
||||
reportToServer(text, s);
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
showMessage(e.getMessage() + "\n" + ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
void showMessage(String s) {
|
||||
try {
|
||||
MessageBox.Show(s, "ERROR", MessageBox.ERROR_MESSAGE);
|
||||
} catch (Throwable e) {
|
||||
System.err.println("ERROR: " + s);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static final HashSet<String> THROWABLE_SET = new HashSet<>();
|
||||
|
||||
void reportToServer(final String text, String stacktrace) {
|
||||
if (THROWABLE_SET.contains(stacktrace))
|
||||
return;
|
||||
THROWABLE_SET.add(stacktrace);
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
HashMap<String, String> map = new HashMap<>();
|
||||
map.put("CrashReport", text);
|
||||
try {
|
||||
System.out.println(NetUtils.post(NetUtils.constantURL("http://huangyuhui.duapp.com/crash.php"), map));
|
||||
} catch (IOException ex) {
|
||||
System.out.println("Failed to send post request to HMCL server.");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils;
|
||||
|
||||
import java.io.File;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class FileNameFilter extends FileFilter {
|
||||
|
||||
String acceptedName;
|
||||
|
||||
public FileNameFilter(String acceptedName) {
|
||||
this.acceptedName = acceptedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
return f.isDirectory() || f.getName().equals(acceptedName) && !FileUtils.getExtension(f.getName()).equals("lnk");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return acceptedName;
|
||||
}
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
|
||||
/**
|
||||
* Give the advice to solve the Minecraft crashing.
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public final class MinecraftCrashAdvicer {
|
||||
|
||||
public static String getAdvice(String trace) {
|
||||
return getAdvice(trace, false);
|
||||
}
|
||||
|
||||
public static String getAdvice(String trace, boolean selfCrash) {
|
||||
trace = trace.toLowerCase();
|
||||
if (trace.contains("pixel format not accelerated"))
|
||||
return C.i18n("crash.advice.LWJGLException");
|
||||
else if (trace.contains("unsupportedclassversionrrror"))
|
||||
return C.i18n("crash.advice.UnsupportedClassVersionError");
|
||||
else if (trace.contains("concurrentmodificationexception"))
|
||||
return C.i18n("crash.advice.ConcurrentModificationException");
|
||||
else if (trace.contains("securityexception"))
|
||||
return C.i18n("crash.advice.SecurityException");
|
||||
else if (trace.contains("nosuchfieldexception") || trace.contains("nosuchfielderror"))
|
||||
return C.i18n("crash.advice.NoSuchFieldError");
|
||||
else if (trace.contains("outofmemory") || trace.contains("out of memory"))
|
||||
return C.i18n("crash.advice.OutOfMemoryError");
|
||||
else if (trace.contains("noclassdeffounderror") || trace.contains("classnotfoundexception"))
|
||||
return C.i18n("crash.advice.ClassNotFoundException");
|
||||
else if (trace.contains("no lwjgl in java.library.path"))
|
||||
return C.i18n("crash.advice.no_lwjgl");
|
||||
else if (trace.contains("opengl") || trace.contains("openal"))
|
||||
return C.i18n("crash.advice.OpenGL");
|
||||
return C.i18n(selfCrash ? "crash.advice.no" : "crash.advice.otherwise");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class ModpackUpdater {
|
||||
|
||||
ModpackInfo info;
|
||||
|
||||
public ModpackUpdater(File baseFolder, ModpackInfo info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
void update() {
|
||||
|
||||
}
|
||||
|
||||
public static class ModpackInfo {
|
||||
|
||||
ArrayList<ModpackFolder> folders;
|
||||
ArrayList<ModpackFile> files;
|
||||
|
||||
public static class ModpackFolder {
|
||||
|
||||
String ext, name;
|
||||
}
|
||||
|
||||
public static class ModpackFile {
|
||||
|
||||
String hash, loc;
|
||||
}
|
||||
}
|
||||
}
|
||||
-179
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.upgrade;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Pack200;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import org.jackhuang.hellominecraft.utils.C;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.launcher.core.MCUtils;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.Task;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.utils.MessageBox;
|
||||
import org.jackhuang.hellominecraft.utils.UpdateChecker;
|
||||
import org.jackhuang.hellominecraft.utils.Utils;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
import org.jackhuang.hellominecraft.utils.functions.Consumer;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.OS;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AppDataUpgrader extends IUpgrader {
|
||||
|
||||
@Override
|
||||
public boolean parseArguments(VersionNumber nowVersion, String[] args) {
|
||||
if (!ArrayUtils.contains(args, "nofound"))
|
||||
try {
|
||||
File f = AppDataUpgraderTask.HMCL_VER_FILE;
|
||||
if (f.exists()) {
|
||||
Map<String, String> m = C.gson.fromJson(FileUtils.readFileToString(f), Map.class);
|
||||
String s = m.get("ver");
|
||||
if (s != null && VersionNumber.check(s).compareTo(nowVersion) > 0) {
|
||||
String j = m.get("loc");
|
||||
if (j != null) {
|
||||
File jar = new File(j);
|
||||
if (jar.exists()) {
|
||||
JarFile jarFile = new JarFile(jar);
|
||||
String mainClass = jarFile.getManifest().getMainAttributes().getValue("Main-Class");
|
||||
if (mainClass != null) {
|
||||
ArrayList<String> al = new ArrayList<>(Arrays.asList(args));
|
||||
al.add("notfound");
|
||||
new URLClassLoader(new URL[] { jar.toURI().toURL() },
|
||||
URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass)
|
||||
.getMethod("main", String[].class).invoke(null, new Object[] { al.toArray(new String[0]) });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean call(Object sender, final VersionNumber number) {
|
||||
((UpdateChecker) sender).requestDownloadLink().reg(new Consumer<Map<String, String>>() {
|
||||
@Override
|
||||
public void accept(Map<String, String> map) {
|
||||
if (map != null && map.containsKey("pack"))
|
||||
try {
|
||||
if (TaskWindow.getInstance().addTask(new AppDataUpgraderTask(map.get("pack"), number.version)).start()) {
|
||||
new ProcessBuilder(new String[] { IOUtils.getJavaDir(), "-jar", AppDataUpgraderTask.getSelf(number.version).getAbsolutePath() }).directory(new File(".")).start();
|
||||
System.exit(0);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Failed to create upgrader", ex);
|
||||
}
|
||||
if (MessageBox.Show(C.i18n("update.newest_version") + number.firstVer + "." + number.secondVer + "." + number.thirdVer + "\n"
|
||||
+ C.i18n("update.should_open_link"),
|
||||
MessageBox.YES_NO_OPTION) == MessageBox.YES_OPTION) {
|
||||
String url = C.URL_PUBLISH;
|
||||
if (map != null)
|
||||
if (map.containsKey(OS.os().checked_name))
|
||||
url = map.get(OS.os().checked_name);
|
||||
else if (map.containsKey(OS.UNKOWN.checked_name))
|
||||
url = map.get(OS.UNKOWN.checked_name);
|
||||
if (url == null)
|
||||
url = C.URL_PUBLISH;
|
||||
try {
|
||||
java.awt.Desktop.getDesktop().browse(new URI(url));
|
||||
} catch (URISyntaxException | IOException e) {
|
||||
HMCLog.warn("Failed to browse uri: " + url, e);
|
||||
Utils.setClipborad(url);
|
||||
MessageBox.Show(C.i18n("update.no_browser"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}).execute();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class AppDataUpgraderTask extends Task {
|
||||
|
||||
public static final File BASE_FOLDER = MCUtils.getWorkingDirectory("hmcl");
|
||||
public static final File HMCL_VER_FILE = new File(BASE_FOLDER, "hmclver.json");
|
||||
|
||||
public static File getSelf(String ver) {
|
||||
return new File(BASE_FOLDER, "HMCL-" + ver + ".jar");
|
||||
}
|
||||
|
||||
private final String downloadLink, newestVersion;
|
||||
File tempFile;
|
||||
|
||||
public AppDataUpgraderTask(String downloadLink, String newestVersion) throws IOException {
|
||||
this.downloadLink = downloadLink;
|
||||
this.newestVersion = newestVersion;
|
||||
tempFile = File.createTempFile("hmcl", ".pack.xz");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends Task> getDependTasks() {
|
||||
return Arrays.asList(new FileDownloadTask(downloadLink, tempFile));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeTask() throws Exception {
|
||||
HashMap<String, String> json = new HashMap<>();
|
||||
File f = getSelf(newestVersion);
|
||||
if (!f.getParentFile().exists())
|
||||
f.getParentFile().mkdirs();
|
||||
|
||||
for (int i = 0; f.exists(); i++)
|
||||
f = new File(BASE_FOLDER, "HMCL-" + newestVersion + (i > 0 ? "-" + i : "") + ".jar");
|
||||
f.createNewFile();
|
||||
|
||||
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(f))) {
|
||||
Pack200.newUnpacker().unpack(new GZIPInputStream(new FileInputStream(tempFile)), jos);
|
||||
}
|
||||
json.put("ver", newestVersion);
|
||||
json.put("loc", f.getAbsolutePath());
|
||||
String result = C.gson.toJson(json);
|
||||
FileUtils.write(HMCL_VER_FILE, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return "Upgrade";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.upgrade;
|
||||
|
||||
import org.jackhuang.hellominecraft.utils.Event;
|
||||
import org.jackhuang.hellominecraft.utils.Event;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public abstract class IUpgrader implements Event<VersionNumber> {
|
||||
|
||||
public static final IUpgrader NOW_UPGRADER = new AppDataUpgrader();
|
||||
|
||||
/**
|
||||
* Paring arguments to decide on whether the upgrade is needed.
|
||||
*
|
||||
* @param nowVersion now launcher version
|
||||
* @param args Application CommandLine Arguments
|
||||
*
|
||||
* @return true if it is needed to break the main thread to shutdown this
|
||||
* application.
|
||||
*/
|
||||
public abstract boolean parseArguments(VersionNumber nowVersion, String[] args);
|
||||
|
||||
/**
|
||||
* Just download the new app.
|
||||
*
|
||||
* @param sender Should be VersionChecker
|
||||
* @param number the newest version
|
||||
*
|
||||
* @return should return true
|
||||
*/
|
||||
@Override
|
||||
public abstract boolean call(Object sender, VersionNumber number);
|
||||
}
|
||||
-68
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.utils.upgrade;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.jackhuang.hellominecraft.utils.logging.HMCLog;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.TaskWindow;
|
||||
import org.jackhuang.hellominecraft.utils.tasks.download.FileDownloadTask;
|
||||
import org.jackhuang.hellominecraft.utils.ArrayUtils;
|
||||
import org.jackhuang.hellominecraft.utils.VersionNumber;
|
||||
import org.jackhuang.hellominecraft.utils.system.FileUtils;
|
||||
import org.jackhuang.hellominecraft.utils.system.IOUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class NewFileUpgrader extends IUpgrader {
|
||||
|
||||
@Override
|
||||
public boolean parseArguments(VersionNumber nowVersion, String[] args) {
|
||||
int i = ArrayUtils.indexOf(args, "--removeOldLauncher");
|
||||
if (i != -1 && i < args.length - 1) {
|
||||
File f = new File(args[i + 1]);
|
||||
if (f.exists())
|
||||
f.deleteOnExit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean call(Object sender, VersionNumber number) {
|
||||
String str = requestDownloadLink();
|
||||
File newf = new File(FileUtils.getName(str));
|
||||
if (TaskWindow.getInstance().addTask(new FileDownloadTask(str, newf)).start()) {
|
||||
try {
|
||||
new ProcessBuilder(new String[] { IOUtils.tryGetCanonicalFilePath(newf), "--removeOldLauncher", IOUtils.getRealPath() }).directory(new File(".")).start();
|
||||
} catch (IOException ex) {
|
||||
HMCLog.err("Failed to start new app", ex);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String requestDownloadLink() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher.
|
||||
* Copyright (C) 2013 huangyuhui <huanghongxun2008@126.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
*/
|
||||
package org.jackhuang.hellominecraft.launcher.views;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.Timer;
|
||||
import org.jackhuang.hellominecraft.launcher.settings.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author huangyuhui
|
||||
*/
|
||||
public class AnimatedPanel extends JPanel implements Selectable {
|
||||
|
||||
private static final int ANIMATION_LENGTH = 10;
|
||||
|
||||
public AnimatedPanel() {
|
||||
timer = new Timer(1, (e) -> {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
AnimatedPanel.this.repaint();
|
||||
offsetX += 0.15;
|
||||
if (offsetX >= ANIMATION_LENGTH) {
|
||||
timer.stop();
|
||||
AnimatedPanel.this.repaint();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
double offsetX = ANIMATION_LENGTH;
|
||||
|
||||
Timer timer;
|
||||
|
||||
public void animate() {
|
||||
if (Settings.getInstance().isEnableAnimation()) {
|
||||
offsetX = 0;
|
||||
timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
double pgs = 1 - Math.sin(Math.PI / 2 / ANIMATION_LENGTH * offsetX);
|
||||
if (Math.abs(ANIMATION_LENGTH - offsetX) < 0.1) {
|
||||
super.paint(g);
|
||||
return;
|
||||
}
|
||||
if (pgs > 1)
|
||||
pgs = 1;
|
||||
if (pgs < 0)
|
||||
pgs = 0;
|
||||
Graphics2D gg = (Graphics2D) g;
|
||||
int width = this.getWidth();
|
||||
int height = this.getHeight();
|
||||
if (isOpaque()) {
|
||||
g.setColor(getBackground());
|
||||
g.fillRect(0, 0, width, height);
|
||||
}
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = image.createGraphics();
|
||||
g2d.translate((int) (pgs * 50), 0);
|
||||
super.paint(g2d);
|
||||
g2d.dispose();
|
||||
gg.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (float) (1 - pgs)));
|
||||
g.drawImage(image, 0, 0, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelected() {
|
||||
animate();
|
||||
}
|
||||
}
|
||||
Loaded 100 of 918 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user