Compare commits
693 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
573ae10ecc | ||
|
|
ac1e0e7d6b | ||
|
|
838e75f025 | ||
|
|
5f0527be71 | ||
|
|
fd49333db6 | ||
|
|
31b30e3a31 | ||
|
|
0fe8c628c7 | ||
|
|
f86f0ab6cd | ||
|
|
40e83423bc | ||
|
|
0de802e7ba | ||
|
|
249f93877c | ||
|
|
8ac57c8da3 | ||
|
|
db96a5a3ec | ||
|
|
79f1503c8b | ||
|
|
eace2ad161 | ||
|
|
d74420b265 | ||
|
|
7aab08ae0f | ||
|
|
2fc8490c72 | ||
|
|
ddc2820418 | ||
|
|
9e1e89b91f | ||
|
|
7c4036dfb1 | ||
|
|
bbaa602fe9 | ||
|
|
921822acd7 | ||
|
|
f019b81bd9 | ||
|
|
50df7b2026 | ||
|
|
92130f1642 | ||
|
|
fd13d5cbdc | ||
|
|
209b51b253 | ||
|
|
3fa0f34c1e | ||
|
|
bf0c47c85c | ||
|
|
9de3074041 | ||
|
|
37a95aea97 | ||
|
|
3116405953 | ||
|
|
ed4f9cee78 | ||
|
|
b8ac867fb9 | ||
|
|
3f6c87a8ed | ||
|
|
bf08c4fcf4 | ||
|
|
f357eb230b | ||
|
|
f3086c2231 | ||
|
|
002415425a | ||
|
|
c54d878d1c | ||
|
|
590f5d98ee | ||
|
|
849072f8ca | ||
|
|
59157c1ee0 | ||
|
|
3c9f5b2c91 | ||
|
|
cdfa86c977 | ||
|
|
64fdad424f | ||
|
|
a5668532b1 | ||
|
|
bac24af90e | ||
|
|
497fb74829 | ||
|
|
91a1f05ff2 | ||
|
|
1a258b2bec | ||
|
|
93dee4fd19 | ||
|
|
f6657846d3 | ||
|
|
db163867df | ||
|
|
58fcf328b9 | ||
|
|
8e8cfdd2a6 | ||
|
|
991d822557 | ||
|
|
c25b1325da | ||
|
|
ea1de44ca8 | ||
|
|
f22f4aed00 | ||
|
|
d644c5b754 | ||
|
|
1e2ae34dbe | ||
|
|
a690e1eca4 | ||
|
|
d25d6c2611 | ||
|
|
ef72c56833 | ||
|
|
7e8c852528 | ||
|
|
42032890ed | ||
|
|
6b6931c86d | ||
|
|
b915151ae3 | ||
|
|
7609f3082e | ||
|
|
99f9dd1671 | ||
|
|
1a0cca794c | ||
|
|
e71547b9ef | ||
|
|
246a246cb7 | ||
|
|
b87a1fa420 | ||
|
|
b12c4e9f8c | ||
|
|
330089f1e2 | ||
|
|
f6045b7cb4 | ||
|
|
a07d7d0526 | ||
|
|
edb433ea6e | ||
|
|
a02704e097 | ||
|
|
1947459acf | ||
|
|
52aa609ac7 | ||
|
|
92bc067633 | ||
|
|
64639b377f | ||
|
|
42c62a0559 | ||
|
|
b25a6305ce | ||
|
|
98e90e72f7 | ||
|
|
10851ddf14 | ||
|
|
402079d7db | ||
|
|
b184141db2 | ||
|
|
f9a8aa0c2b | ||
|
|
0c09441154 | ||
|
|
69d3bc0c2e | ||
|
|
1018db797e | ||
|
|
b31e0a87cb | ||
|
|
4572b75db7 | ||
|
|
15fdbb2312 | ||
|
|
848b7c6de0 | ||
|
|
2b96a2e463 | ||
|
|
354b26b1da | ||
|
|
62b2f81ba1 | ||
|
|
5826931eea | ||
|
|
a8119366a1 | ||
|
|
b0575fbe0c | ||
|
|
866cf34f50 | ||
|
|
23908ad14f | ||
|
|
6d06713610 | ||
|
|
18d3c4c2bd | ||
|
|
faece77e8c | ||
|
|
413c11a23e | ||
|
|
4c9253fa5e | ||
|
|
d86a34a527 | ||
|
|
92aba1b78e | ||
|
|
28ba97c3de | ||
|
|
24c23e28ec | ||
|
|
2a2842361b | ||
|
|
632e05c4c2 | ||
|
|
980d68536c | ||
|
|
4144344acd | ||
|
|
e962c39506 | ||
|
|
48f309ac05 | ||
|
|
0688a57a38 | ||
|
|
078b3909b3 | ||
|
|
d51b23bd1e | ||
|
|
9378f7e8a0 | ||
|
|
e7e434a95b | ||
|
|
be1203fabb | ||
|
|
340d2a1d54 | ||
|
|
f84b749ff4 | ||
|
|
a223585daa | ||
|
|
8a0f3018bf | ||
|
|
3e7eb87a36 | ||
|
|
c146440cb2 | ||
|
|
4b6652b4cf | ||
|
|
21feeb664e | ||
|
|
3dbcf0102a | ||
|
|
c1b555c289 | ||
|
|
dce35e339f | ||
|
|
163e97aad6 | ||
|
|
f147519a5c | ||
|
|
19accb0d90 | ||
|
|
44bcd4251d | ||
|
|
5795baab1a | ||
|
|
e183dcba17 | ||
|
|
a945cfaa3c | ||
|
|
ea964a976c | ||
|
|
1409c92e69 | ||
|
|
a0914192d0 | ||
|
|
e19fd1161d | ||
|
|
3a3b012199 | ||
|
|
9accb2bfb0 | ||
|
|
20d62c68bf | ||
|
|
0ca81b14bf | ||
|
|
1dd2a334d6 | ||
|
|
3332ec9e1f | ||
|
|
30f27d43e7 | ||
|
|
74457db125 | ||
|
|
91588caf7d | ||
|
|
9bf890a7b6 | ||
|
|
e1e620a0d9 | ||
|
|
f5d15927de | ||
|
|
7902517663 | ||
|
|
4db988dbef | ||
|
|
9ad273a46c | ||
|
|
81932069d9 | ||
|
|
a1ac87f80d | ||
|
|
97067b9078 | ||
|
|
2cd5c6b0af | ||
|
|
920c3aa280 | ||
|
|
f2679bea29 | ||
|
|
e8bcd0535d | ||
|
|
3b30b06313 | ||
|
|
e492e5f830 | ||
|
|
5a4500177d | ||
|
|
c4f33b72c2 | ||
|
|
5f5567f283 | ||
|
|
301ad40350 | ||
|
|
aee36e4d85 | ||
|
|
e063475ebd | ||
|
|
58d6b80f4f | ||
|
|
fa28a56e84 | ||
|
|
c18fa512ef | ||
|
|
3bdd0a81a5 | ||
|
|
7668952ca8 | ||
|
|
b351ceef71 | ||
|
|
4efa2b1272 | ||
|
|
c2308c650a | ||
|
|
b16590d504 | ||
|
|
51843f7074 | ||
|
|
7969988099 | ||
|
|
fc474cfb49 | ||
|
|
bfc813a802 | ||
|
|
fd8ca8576b | ||
|
|
75b8554a11 | ||
|
|
d9cb2d91a0 | ||
|
|
d4b95110f5 | ||
|
|
8a2a20a1b3 | ||
|
|
7daf1022c0 | ||
|
|
60d6791f0c | ||
|
|
ca4385da7a | ||
|
|
661b16af7e | ||
|
|
f36072c8d3 | ||
|
|
b1be4f29ad | ||
|
|
050e3a570d | ||
|
|
7b911aa0a7 | ||
|
|
9ecb416bf3 | ||
|
|
f35e55ef66 | ||
|
|
b0929991b1 | ||
|
|
bd263e1bf8 | ||
|
|
535eccfc24 | ||
|
|
81e004380f | ||
|
|
d67a3d8bbc | ||
|
|
36534eeb2d | ||
|
|
4e3a7abac9 | ||
|
|
f331124895 | ||
|
|
15a38c4871 | ||
|
|
070523511a | ||
|
|
0edcf65044 | ||
|
|
139fd03470 | ||
|
|
3215824a9e | ||
|
|
f5bd737ee9 | ||
|
|
70640246b6 | ||
|
|
8c1ccd6c19 | ||
|
|
7813a9caba | ||
|
|
231d3a376b | ||
|
|
3791569519 | ||
|
|
7aa3eda3f6 | ||
|
|
0ca173f5dc | ||
|
|
c0a1e6540f | ||
|
|
46f38f2ce7 | ||
|
|
64a881f990 | ||
|
|
541b710ea7 | ||
|
|
cc8afe95c5 | ||
|
|
83feddf6be | ||
|
|
7662810405 | ||
|
|
d921d2e367 | ||
|
|
9630224e78 | ||
|
|
134bfb2a16 | ||
|
|
36df7b17f8 | ||
|
|
7e9cf2e1e9 | ||
|
|
54511f13d9 | ||
|
|
27e45b816d | ||
|
|
3a6e5541fb | ||
|
|
a83d275622 | ||
|
|
d6adb52718 | ||
|
|
976f3439eb | ||
|
|
2821a2a0a7 | ||
|
|
2e2c0ecc0b | ||
|
|
31d1656c48 | ||
|
|
4b5a094f30 | ||
|
|
6b611cf4c7 | ||
|
|
90f2b39fba | ||
|
|
2164857408 | ||
|
|
e0308dee49 | ||
|
|
601a781983 | ||
|
|
f14bb282f0 | ||
|
|
1e0dce8f41 | ||
|
|
45400a9685 | ||
|
|
6ffe31b59e | ||
|
|
293b556b56 | ||
|
|
dbf38efd83 | ||
|
|
e63aad7825 | ||
|
|
212ef4d4cc | ||
|
|
31e082b8dc | ||
|
|
75e8035551 | ||
|
|
f7f0521093 | ||
|
|
684fda2d1b | ||
|
|
886091df50 | ||
|
|
9707dd7ce8 | ||
|
|
b81d712a33 | ||
|
|
3ffacbf375 | ||
|
|
eec85b20be | ||
|
|
c0ead0147a | ||
|
|
bafd41837e | ||
|
|
9bfa2025d5 | ||
|
|
bf63ffbc1d | ||
|
|
985148b49a | ||
|
|
9e78443595 | ||
|
|
58723a33ca | ||
|
|
c9aa1658b2 | ||
|
|
7f9e50bbe2 | ||
|
|
664375a678 | ||
|
|
097e30850f | ||
|
|
a63cbab013 | ||
|
|
37f1c30ad0 | ||
|
|
217dca5363 | ||
|
|
15e97268ed | ||
|
|
29301e8a39 | ||
|
|
dfa838a6f9 | ||
|
|
218de1cb98 | ||
|
|
6a9694b03a | ||
|
|
0239a2cad4 | ||
|
|
38553b3324 | ||
|
|
ba78c48a75 | ||
|
|
f4996137a3 | ||
|
|
ccd80dfc8f | ||
|
|
ff1b3e7c5f | ||
|
|
2f0497756b | ||
|
|
afe9359d3e | ||
|
|
4b5d629df6 | ||
|
|
dbc0a46b10 | ||
|
|
9a6241af8a | ||
|
|
1b82bd1f33 | ||
|
|
bf9cb76604 | ||
|
|
90cfd82810 | ||
|
|
108dbdae5d | ||
|
|
32a4c4644e | ||
|
|
edc92753cf | ||
|
|
0e567f2f90 | ||
|
|
41e8c69db9 | ||
|
|
a83d1901f2 | ||
|
|
f3bb5a0cb2 | ||
|
|
76d3a13f58 | ||
|
|
6f99f891dc | ||
|
|
e579bf980d | ||
|
|
716b3ae0d2 | ||
|
|
b468b8eb95 | ||
|
|
b647c0fca0 | ||
|
|
1d109d4b9f | ||
|
|
29bf046aa8 | ||
|
|
4399b7c2fb | ||
|
|
d35571923f | ||
|
|
461f56c4d6 | ||
|
|
0b5d5b8176 | ||
|
|
42771686c6 | ||
|
|
448e454cc8 | ||
|
|
8f5105c454 | ||
|
|
7c696b7055 | ||
|
|
349c951b55 | ||
|
|
5dc403e643 | ||
|
|
a8e1b16dee | ||
|
|
dc53a95bef | ||
|
|
eec4edea05 | ||
|
|
70249e5fa7 | ||
|
|
96a64b454e | ||
|
|
7a935fb2ea | ||
|
|
c0cdfb7781 | ||
|
|
487b3a759a | ||
|
|
fe67489419 | ||
|
|
308b9bbfea | ||
|
|
bfb4ffcafc | ||
|
|
537100a5e5 | ||
|
|
b6bf4427ef | ||
|
|
8de239f468 | ||
|
|
ecfd664f30 | ||
|
|
c4ac23837f | ||
|
|
aeeb001205 | ||
|
|
2552eb8dca | ||
|
|
cbf0d79c9c | ||
|
|
8ceb89d021 | ||
|
|
8e58dd9e64 | ||
|
|
45abbb7fa1 | ||
|
|
1d983d5fdc | ||
|
|
be54b8ee5b | ||
|
|
4c0c263d11 | ||
|
|
c8259d3e90 | ||
|
|
d892ef54f0 | ||
|
|
6654476da4 | ||
|
|
fc209599af | ||
|
|
dee7df1534 | ||
|
|
ccd737d0a1 | ||
|
|
14b5a0cec3 | ||
|
|
2f7dc2397e | ||
|
|
3498082f2b | ||
|
|
83066fc57c | ||
|
|
d32f1b2a16 | ||
|
|
8211ae4af5 | ||
|
|
4590ba3ff8 | ||
|
|
b4578931d3 | ||
|
|
b8ede0a652 | ||
|
|
3eb7610f89 | ||
|
|
5a48f4119e | ||
|
|
974b86aac1 | ||
|
|
f30cb916bd | ||
|
|
494ebfa10d | ||
|
|
222f53b105 | ||
|
|
12898df2f1 | ||
|
|
fbb66a0586 | ||
|
|
48462da473 | ||
|
|
4b689bd946 | ||
|
|
5126ec9c36 | ||
|
|
d640ebb02d | ||
|
|
0bb6f1b094 | ||
|
|
bb39fea415 | ||
|
|
7a61ab8137 | ||
|
|
7861860187 | ||
|
|
70166f385d | ||
|
|
03ee30bca9 | ||
|
|
c48de32860 | ||
|
|
3b31387092 | ||
|
|
ff12832a21 | ||
|
|
4ccaf681c5 | ||
|
|
02fc62f1c4 | ||
|
|
04a5a1a620 | ||
|
|
3e94cac567 | ||
|
|
452b2c278b | ||
|
|
db0bfbe722 | ||
|
|
f0148a625e | ||
|
|
0b5a310f18 | ||
|
|
c18715b8d7 | ||
|
|
d244a39040 | ||
|
|
0981114b78 | ||
|
|
9bd0856445 | ||
|
|
9d1addd114 | ||
|
|
1902e6c1f3 | ||
|
|
a1a3d93dc1 | ||
|
|
32b7c82650 | ||
|
|
615266ed96 | ||
|
|
15f4253b3d | ||
|
|
2ccd464a49 | ||
|
|
f2374edd8b | ||
|
|
24b0bd2edf | ||
|
|
f56e0569a2 | ||
|
|
c10903be69 | ||
|
|
e3a1ac85cc | ||
|
|
1ea071de09 | ||
|
|
c9a18caf49 | ||
|
|
bfae100cb9 | ||
|
|
878a32228a | ||
|
|
bce2c74a8e | ||
|
|
90434b3178 | ||
|
|
9cf5538058 | ||
|
|
f4a99253f4 | ||
|
|
b366b1b1d1 | ||
|
|
a90e720956 | ||
|
|
535fd17a42 | ||
|
|
47dc0f9b94 | ||
|
|
4776fa1876 | ||
|
|
944405e4df | ||
|
|
0dd38ca65a | ||
|
|
b0ebbf4dfb | ||
|
|
9d12a4ba3d | ||
|
|
6dc953631b | ||
|
|
7ef4307ab7 | ||
|
|
0aff31b768 | ||
|
|
0682e63707 | ||
|
|
7e426bd2e8 | ||
|
|
a5ca664a6a | ||
|
|
367ce5fa17 | ||
|
|
877fd25608 | ||
|
|
cfd9a69052 | ||
|
|
d42bfcfa53 | ||
|
|
defa6399e2 | ||
|
|
699e8bdea6 | ||
|
|
2eb912835a | ||
|
|
bd7a57f7aa | ||
|
|
e76f79214e | ||
|
|
141a48a15e | ||
|
|
fa158c6e67 | ||
|
|
7a12ef530c | ||
|
|
1d092a7165 | ||
|
|
57a17e907e | ||
|
|
2a82f6048a | ||
|
|
4076263afa | ||
|
|
e3c8283158 | ||
|
|
0aad3470d9 | ||
|
|
553c85f0f6 | ||
|
|
c057081f07 | ||
|
|
7d22a71507 | ||
|
|
0ecabdd047 | ||
|
|
6c6b44ee65 | ||
|
|
14ff90ccf1 | ||
|
|
5d7655fbdf | ||
|
|
ee0a6c2523 | ||
|
|
753b1cf1c3 | ||
|
|
cd1c07deef | ||
|
|
41d730fb04 | ||
|
|
30278a1c52 | ||
|
|
d87d1ab9b5 | ||
|
|
31c9072970 | ||
|
|
f7a20a3acf | ||
|
|
9d05043fa0 | ||
|
|
5f709eef9c | ||
|
|
b111fd2f3e | ||
|
|
84777c2437 | ||
|
|
13742df877 | ||
|
|
e57a84ded4 | ||
|
|
f55f7f19b4 | ||
|
|
e43200865c | ||
|
|
1de2d55965 | ||
|
|
959b4cddbd | ||
|
|
82156250df | ||
|
|
90f401a067 | ||
|
|
c6a6624045 | ||
|
|
7d17ace15d | ||
|
|
8d3b0c8f07 | ||
|
|
6741dff12b | ||
|
|
9e10faa4c5 | ||
|
|
579e6d6e4c | ||
|
|
a32ac59ec1 | ||
|
|
2b259d6dee | ||
|
|
67efb7a5b6 | ||
|
|
1da7ab2c22 | ||
|
|
1257a0128c | ||
|
|
0886f176b3 | ||
|
|
7a8f8e8d47 | ||
|
|
7046927394 | ||
|
|
d2b1398cea | ||
|
|
6c8f2698d6 | ||
|
|
9808f62fe4 | ||
|
|
1837b66bb5 | ||
|
|
efae476bc0 | ||
|
|
a236031435 | ||
|
|
812be14375 | ||
|
|
1dbfc9abe3 | ||
|
|
411c43d90e | ||
|
|
bac5fd7438 | ||
|
|
4df31a3fbb | ||
|
|
8dc32ae03c | ||
|
|
5fd915ab8a | ||
|
|
68901695ca | ||
|
|
6aeb73b5bd | ||
|
|
aec683d80f | ||
|
|
d4e6a84ec9 | ||
|
|
d66b8f1dd8 | ||
|
|
688bbb83c8 | ||
|
|
da31a643b3 | ||
|
|
76c5c1155f | ||
|
|
94027d17f2 | ||
|
|
fef7ba4701 | ||
|
|
fcf8cd35d2 | ||
|
|
91609f4ebf | ||
|
|
64a5ceabd8 | ||
|
|
4c2984a9a0 | ||
|
|
d1a6de06e2 | ||
|
|
0290b344dc | ||
|
|
395706edc9 | ||
|
|
a67889ab42 | ||
|
|
97e91ed680 | ||
|
|
424f27c798 | ||
|
|
c5475498ca | ||
|
|
157e4db7c5 | ||
|
|
1f303e69b0 | ||
|
|
dc53c79393 | ||
|
|
37167746b5 | ||
|
|
a046708867 | ||
|
|
f798ff26f6 | ||
|
|
a665605a5a | ||
|
|
071e6164fe | ||
|
|
b72bbfce5e | ||
|
|
cb7c2d7171 | ||
|
|
800cb2e747 | ||
|
|
5b39eb5041 | ||
|
|
53a0069704 | ||
|
|
8c12416348 | ||
|
|
e00e0032b4 | ||
|
|
f1bf1e8663 | ||
|
|
ef4cdfd646 | ||
|
|
e01093eb9a | ||
|
|
a9e9cd978d | ||
|
|
fe8ec19b6d | ||
|
|
0e87f350b3 | ||
|
|
c86643874d | ||
|
|
8df6778641 | ||
|
|
26a2945696 | ||
|
|
04b09fbfbd | ||
|
|
f14caa3778 | ||
|
|
06d11c1874 | ||
|
|
91bf7d726b | ||
|
|
bde0c620ad | ||
|
|
9672bd2c6d | ||
|
|
7b6f9b3eb6 | ||
|
|
ea9245ad26 | ||
|
|
8534e1ba55 | ||
|
|
ae66004b80 | ||
|
|
5b39c0dd96 | ||
|
|
2db2d8be59 | ||
|
|
75d47bb110 | ||
|
|
3662b3fdf1 | ||
|
|
b03d31e990 | ||
|
|
54f0a3c14c | ||
|
|
6a80b0d4ff | ||
|
|
5e724c1e3a | ||
|
|
88e604426c | ||
|
|
7487b90d50 | ||
|
|
dd7b492b0c | ||
|
|
c7f4e366e2 | ||
|
|
09554ab39d | ||
|
|
382f82b0e0 | ||
|
|
ab3d9e9c47 | ||
|
|
2ae7bc6a64 | ||
|
|
6979bd6971 | ||
|
|
b2bd025896 | ||
|
|
714ebb2c2d | ||
|
|
1b254a4811 | ||
|
|
92509f07e9 | ||
|
|
44cd5dcd41 | ||
|
|
76fe0d14d3 | ||
|
|
2022d33d03 | ||
|
|
c8b8deb3d6 | ||
|
|
4885d49d20 | ||
|
|
13fc58933d | ||
|
|
c217a34f13 | ||
|
|
15182cb151 | ||
|
|
8a65a1cfc5 | ||
|
|
5bdd5b0c0d | ||
|
|
298256197b | ||
|
|
7da802a238 | ||
|
|
de80527702 | ||
|
|
e334aae608 | ||
|
|
c48a9d98b4 | ||
|
|
ed34ae73c0 | ||
|
|
c8a0ae9e10 | ||
|
|
67a085c95f | ||
|
|
1d5ee079b4 | ||
|
|
410cfcf21a | ||
|
|
4148b98187 | ||
|
|
b9054cdfc9 | ||
|
|
35a996e2b0 | ||
|
|
bb36ebfc0c | ||
|
|
a7d15d1e32 | ||
|
|
4317dca024 | ||
|
|
666a890088 | ||
|
|
c48c2aa45c | ||
|
|
77ca36c794 | ||
|
|
a602863426 | ||
|
|
a09e63d6aa | ||
|
|
fbe28e397e | ||
|
|
364ae87ef8 | ||
|
|
ffd00080f2 | ||
|
|
94d757104b | ||
|
|
705a5a0712 | ||
|
|
9729e63d98 | ||
|
|
b389b573e5 | ||
|
|
f232bbdb15 | ||
|
|
26574b4a9b | ||
|
|
a1b1ef88cf | ||
|
|
b6c52cd8e1 | ||
|
|
eb28298983 | ||
|
|
34abbfb5da | ||
|
|
0d14bde583 | ||
|
|
4b0a8eb166 | ||
|
|
80ec9023ce | ||
|
|
336b2c2798 | ||
|
|
5dd10b6e81 | ||
|
|
415fa048ba | ||
|
|
a1661e94b5 | ||
|
|
63d0064d69 | ||
|
|
43eb4e3581 | ||
|
|
c45a714b77 | ||
|
|
271c2ff636 | ||
|
|
e4cd35ac33 | ||
|
|
e8a4a9fdac | ||
|
|
7bb311687b | ||
|
|
5f2eadbfa6 | ||
|
|
6eeeeb3a1b | ||
|
|
35ab687d5e | ||
|
|
3ff2bd4f17 | ||
|
|
f334b3b765 | ||
|
|
e3c6b312ef | ||
|
|
acce20c573 | ||
|
|
e4d725d9aa | ||
|
|
0cf89e0b2a | ||
|
|
ff1732011e | ||
|
|
c5721fb7e3 | ||
|
|
3200d976d7 | ||
|
|
6698505dd8 | ||
|
|
790a4f6769 | ||
|
|
c9d7a5bea6 | ||
|
|
f1ead19b6e | ||
|
|
9efc512253 | ||
|
|
174bdd2307 | ||
|
|
24e047c12e | ||
|
|
6e5fec576f | ||
|
|
1e7e504650 | ||
|
|
814c17522a | ||
|
|
b622adf300 | ||
|
|
c1b58f8a01 | ||
|
|
c1a9621dfa | ||
|
|
6de266a106 | ||
|
|
334d9c119b | ||
|
|
1a2c30b4e3 | ||
|
|
413cc1469f | ||
|
|
7404414e7a | ||
|
|
49b1f3528b | ||
|
|
26cceede15 | ||
|
|
b71c9e776a | ||
|
|
746faf6df6 | ||
|
|
a367031fe2 | ||
|
|
853dadd906 | ||
|
|
e55db05f20 | ||
|
|
98a748afb3 | ||
|
|
c04eb066cb | ||
|
|
6260c6d3d7 | ||
|
|
ce1fb49252 | ||
|
|
ecdec87e7a | ||
|
|
96f432d2d5 | ||
|
|
0ae59755e3 | ||
|
|
12b596e536 | ||
|
|
0b6088cd2d | ||
|
|
1736f2ffc7 |
10
.github/workflows/gradle_build.yml
vendored
10
.github/workflows/gradle_build.yml
vendored
@@ -13,12 +13,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
@@ -28,16 +28,16 @@ jobs:
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build -Pmod_version="$(git describe --always --tags | cut -c2-)"
|
||||
run: ./gradlew build -Pmod_version="$(git describe --always --tags --first-parent | cut -c2-)"
|
||||
|
||||
- name: Archive Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Artifacts
|
||||
path: dist/
|
||||
|
||||
- name: Archive mapping.txt
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Mappings
|
||||
path: mapping/
|
||||
|
||||
4
.github/workflows/run_tests.yml
vendored
4
.github/workflows/run_tests.yml
vendored
@@ -11,9 +11,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -37,4 +37,10 @@ baritone_Client.launch
|
||||
.vscode/launch.json
|
||||
.architectury-transformer
|
||||
|
||||
mapping
|
||||
|
||||
mapping
|
||||
|
||||
libs/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar
|
||||
libs/java-objc-bridge-1.1.jar
|
||||
|
||||
mapping
|
||||
|
||||
@@ -6,6 +6,7 @@ RUN apt update -y
|
||||
|
||||
RUN apt install \
|
||||
openjdk-17-jdk \
|
||||
git \
|
||||
--assume-yes
|
||||
|
||||
COPY . /code
|
||||
|
||||
55
README.md
55
README.md
@@ -4,13 +4,17 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/cabaletta/baritone/tree/master"><img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.13.2"><img src="https://img.shields.io/badge/MC-1.13.2-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.14.4"><img src="https://img.shields.io/badge/MC-1.14.4-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.15.2"><img src="https://img.shields.io/badge/MC-1.15.2-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.16.5"><img src="https://img.shields.io/badge/MC-1.16.5-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.17.1"><img src="https://img.shields.io/badge/MC-1.17.1-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.18.2"><img src="https://img.shields.io/badge/MC-1.18.2-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.13.2-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.14.4-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.15.2-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.16.5-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.17.1-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.18.2-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.19.2-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.19.4-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.20.1-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.21.3-brightgreen.svg" alt="Minecraft"/></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -28,12 +32,13 @@
|
||||
<a href="https://github.com/cabaletta/baritone/commit/"><img src="https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg" alt="GitHub commits"/></a>
|
||||
<img src="https://img.shields.io/github/languages/code-size/cabaletta/baritone.svg" alt="Code size"/>
|
||||
<img src="https://img.shields.io/github/repo-size/cabaletta/baritone.svg" alt="GitHub repo size"/>
|
||||
<img src="https://tokei.rs/b1/github/cabaletta/baritone?category=code" alt="Lines of Code"/>
|
||||
<img src="https://tokei.rs/b1/github/cabaletta/baritone?category=code&style=flat" alt="Lines of Code"/>
|
||||
<img src="https://img.shields.io/badge/Badges-36-blue.svg" alt="yes"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://impactclient.net/"><img src="https://img.shields.io/badge/Impact%20integration-v1.2.14%20/%20v1.3.8%20/%20v1.4.6%20/%20v1.5.3%20/%20v1.6.3-brightgreen.svg" alt="Impact integration"/></a>
|
||||
<a href="https://github.com/kami-blue/client"><img src="https://img.shields.io/badge/KAMI%20Blue%20integration-v1.2.14--master-green" alt="KAMI Blue integration"/></a>
|
||||
<a href="https://github.com/lambda-client/lambda"><img src="https://img.shields.io/badge/Lambda%20integration-v1.2.17-brightgreen.svg" alt="Lambda integration"/></a>
|
||||
<a href="https://github.com/fr1kin/ForgeHax/"><img src="https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg" alt="ForgeHax integration"/></a>
|
||||
<a href="https://aristois.net/"><img src="https://img.shields.io/badge/Aristois%20add--on%20integration-v1.6.3-green.svg" alt="Aristois add-on integration"/></a>
|
||||
<a href="https://rootnet.dev/"><img src="https://img.shields.io/badge/rootNET%20integration-v1.2.14-green.svg" alt="rootNET integration"/></a>
|
||||
@@ -42,27 +47,37 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="http://forthebadge.com/"><img src="https://forthebadge.com/images/badges/built-with-swag.svg" alt="forthebadge"/></a>
|
||||
<a href="http://forthebadge.com/"><img src="https://forthebadge.com/images/badges/mom-made-pizza-rolls.svg" alt="forthebadge"/></a>
|
||||
<a href="http://forthebadge.com/"><img src="https://web.archive.org/web/20230604002050/https://forthebadge.com/images/badges/built-with-swag.svg" alt="forthebadge"/></a>
|
||||
<a href="http://forthebadge.com/"><img src="https://web.archive.org/web/20230604002050/https://forthebadge.com/images/badges/mom-made-pizza-rolls.svg" alt="forthebadge"/></a>
|
||||
</p>
|
||||
|
||||
A Minecraft pathfinder bot.
|
||||
|
||||
Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do.
|
||||
|
||||
[**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr)
|
||||
|
||||
Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#0730 on Baritone which I recommend. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do.
|
||||
**Quick download links:**
|
||||
|
||||
[Tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa)
|
||||
| Forge | Fabric |
|
||||
|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
|
||||
| [1.12.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.2.19/baritone-api-forge-1.2.19.jar) | |
|
||||
| [1.16.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.6.5/baritone-api-forge-1.6.5.jar) | [1.16.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.6.5/baritone-api-fabric-1.6.5.jar) |
|
||||
| [1.17.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-forge-1.7.3.jar) | [1.17.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-fabric-1.7.3.jar) |
|
||||
| [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.6/baritone-api-forge-1.8.6.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.6/baritone-api-fabric-1.8.6.jar) |
|
||||
| [1.19.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-forge-1.9.4.jar) | [1.19.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-fabric-1.9.4.jar) |
|
||||
| [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) |
|
||||
| [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) |
|
||||
| [1.20.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-forge-1.10.1.jar) | [1.20.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-fabric-1.10.1.jar) |
|
||||
| [1.20.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.2/baritone-api-forge-1.10.2.jar) | [1.20.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.2/baritone-api-fabric-1.10.2.jar) |
|
||||
| [1.20.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.2/baritone-api-forge-1.10.2.jar) | [1.20.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.2/baritone-api-fabric-1.10.2.jar) |
|
||||
| [1.21.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.11.1/baritone-api-forge-1.11.1.jar) | [1.21.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.11.1/baritone-api-fabric-1.11.1.jar) |
|
||||
|
||||
The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to
|
||||
install the v1.2.* `api-forge` jar from [releases](https://github.com/cabaletta/baritone/releases). **For 1.12.2 Forge, just click
|
||||
[here](https://github.com/cabaletta/baritone/releases/download/v1.2.17/baritone-api-forge-1.2.17.jar)**. Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
|
||||
**Message for 2b2t players looking for 1.19/1.20 Baritone** If you like, please try the beta for Baritone Elytra for 2b2t, find it in #announcements of [the Baritone discord](http://discord.gg/s6fRBAUpmr). It supports 1.19.4 and 1.20.1, Forge or Fabric. If you have to see it to believe it, watch [this YouTube video](https://youtu.be/NnSlQi-68eQ).
|
||||
|
||||
For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. If you need Forge or Fabric 1.16.5, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.6.3) and get the `api-forge` or `api-fabric` jar. **For 1.16.5 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.6.3/baritone-api-fabric-1.6.3.jar)**.
|
||||
**How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa). Also try `#elytra` for Elytra flying in the Nether using fireworks.
|
||||
|
||||
If you need Forge or Fabric 1.17.1, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.7.2) and get the `api-forge` or `api-fabric` jar. **For 1.17.1 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.7.2/baritone-api-fabric-1.7.2.jar)**.
|
||||
|
||||
If you need Forge or Fabric 1.18.2, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.8.3) and get the `api-forge` or `api-fabric` jar. **For 1.18.2 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-fabric-1.8.3.jar)**. **For 1.18.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-forge-1.8.3.jar)**.
|
||||
For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). Also consider just installing [Impact](https://impactclient.net/), which comes with Baritone and is easier to install than wrangling with version JSONs and zips. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#6313 on Baritone which I recommend.
|
||||
|
||||
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
||||
the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 onwards. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
||||
|
||||
134
SETUP.md
134
SETUP.md
@@ -1,133 +1,87 @@
|
||||
# Installation
|
||||
|
||||
The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone.
|
||||
|
||||
You can also use a custom version json for Minecraft, with the [1.14.4](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1) version or the [1.15.2](https://www.dropbox.com/s/8rx6f0kts9hvd4f/1.15.2-Baritone.zip?dl=1) version or the [1.16.5](https://www.dropbox.com/s/i6f292o2i7o9acp/1.16.5-Baritone.zip?dl=1) version.
|
||||
The easiest way to install Baritone is to install it as Forge/Neoforge/Fabric mod, but if you know how you can also use with a custom `version.json`
|
||||
(Examples: [1.14.4](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1), [1.15.2](https://www.dropbox.com/s/8rx6f0kts9hvd4f/1.15.2-Baritone.zip?dl=1), [1.16.5](https://www.dropbox.com/s/i6f292o2i7o9acp/1.16.5-Baritone.zip?dl=1)).
|
||||
|
||||
Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
|
||||
|
||||
## Prebuilt official releases
|
||||
These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `backfill-2` branch for example, you'll have to build it yourself)
|
||||
Releases are made rarely and are not always up to date with the latest features and bug fixes.
|
||||
|
||||
Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
|
||||
|
||||
v1.2.* is for 1.12.2, v1.3.* is for 1.13.2, v1.4.* is for 1.14.4, v1.5.* is for 1.15.2, v1.6.* is for 1.16.5, v1.7.* is for 1.17.1, v1.8.* is for 1.18.1
|
||||
The mapping between major Minecraft versions and major Baritone versions is as follows
|
||||
| Minecraft version | 1.12 | 1.13 | 1.14 | 1.15 | 1.16 | 1.17 | 1.18 | 1.19 | 1.20 | 1.21 |
|
||||
|-------------------|------|------|------|------|------|------|------|------|-------|-------|
|
||||
| Baritone version | v1.2 | v1.3 | v1.4 | v1.5 | v1.6 | v1.7 | v1.8 | v1.9 | v1.10 | v1.11 |
|
||||
|
||||
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by that public keys of `checksums.txt`.
|
||||
|
||||
The build is fully deterministic and reproducible, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone .` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too).
|
||||
The build is fully deterministic and reproducible, and you can verify that by running `docker build --no-cache -t cabaletta/baritone .` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too).
|
||||
|
||||
|
||||
## Artifacts
|
||||
|
||||
Building Baritone will result in 5 artifacts created in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases).
|
||||
Building Baritone will create the final artifacts in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases).
|
||||
|
||||
**The Forge and Fabric releases can simply be added as a Forge/Fabric mods.**
|
||||
**The Forge, NeoForge and Fabric releases can simply be added as a Forge/Neoforge/Fabric mods.**
|
||||
|
||||
If another one of your Forge mods has a Baritone integration, you want `baritone-api-forge-VERSION.jar`. Otherwise, you want `baritone-standalone-forge-VERSION.jar`
|
||||
If another one of your other mods has a Baritone integration, you want `baritone-api-*-VERSION.jar`.
|
||||
If you want to report a bug and spare us some effort, you want `baritone-unoptimized-*-VERSION.jar`.
|
||||
Otherwise, you want `baritone-standalone-*-VERSION.jar`
|
||||
|
||||
Here's what the various qualifiers mean
|
||||
- **API**: Only the non-api packages are obfuscated. This should be used in environments where other mods would like to use Baritone's features.
|
||||
- **Forge/Fabric API**: Same as API, but packaged for Forge/Fabric. This should be used where another mod has a Baritone integration.
|
||||
- **Standalone**: Everything is obfuscated. This should be used in environments where there are no other mods present that would like to use Baritone's features.
|
||||
- **Forge/Fabric Standalone**: Same as Standalone, but packaged for Forge/Fabric. This should be used when Baritone is your only Forge/Fabric mod, or none of your other Forge/Fabric mods integrate with Baritone.
|
||||
- **Unoptimized**: Nothing is obfuscated. This shouldn't be used ever in production.
|
||||
- **Forge/Fabric Unoptimized**: Same as Unoptimized, but packaged for Forge/Fabric.
|
||||
- **Standalone**: Everything is obfuscated. Other mods cannot use Baritone, but you get a bit of extra performance.
|
||||
- **Unoptimized**: Nothing is obfuscated. This shouldn't be used in production, but is really helpful for crash reports.
|
||||
|
||||
- **No loader**: Loadable as a launchwrapper tweaker against vanilla Minecraft using a custom `version.json`.
|
||||
- **Forge/Neoforge/Fabric**: Loadable as a standard mod using the respective loader. The fabric build may or may not work on Quilt.
|
||||
|
||||
If you build from source you will also find mapping files in the `dist` directory. These contain the renamings done by ProGuard and are useful if you want to read obfuscated stack traces.
|
||||
|
||||
## Build it yourself
|
||||
- Clone or download Baritone
|
||||
|
||||

|
||||
- If you choose to download, make sure you extract the ZIP archive.
|
||||
- If you choose to download, make sure you download the correct branch and extract the ZIP archive.
|
||||
- Follow one of the instruction sets below, based on your preference
|
||||
|
||||
## Command Line
|
||||
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
|
||||
|
||||
If you have errors with a package missing please make sure you have setup your environment, and are using Oracle JDK 8 for 1.12.2-1.16.5, JDK 16 for 1.17.1, and JDK 17 for 1.18.1.
|
||||
The recommended Java versions by Minecraft version are
|
||||
| Minecraft version | Java version |
|
||||
|-------------------------------|---------------|
|
||||
| 1.12.2 - 1.16.5 | 8 |
|
||||
| 1.17.1 | 16 |
|
||||
| 1.18.2 - 1.20.4 | 17 |
|
||||
| 1.20.5 - 1.21.4 | 21 |
|
||||
|
||||
To check which java you are using do
|
||||
`java -version` in a command prompt or terminal.
|
||||
If you are using anything above OpenJDK 8 for 1.12.2-1.16.5, it might not work because the Java distributions above JDK 8 using may not have the needed javax classes.
|
||||
Download java: https://adoptium.net/
|
||||
|
||||
Open JDK download: https://openjdk.java.net/install/
|
||||
#### macOS guide
|
||||
In order to get JDK 8, Try running the following command:
|
||||
`% /usr/libexec/java_home -V`
|
||||
If it doesn't work try this guide: https://stackoverflow.com/questions/46513639/how-to-downgrade-java-from-9-to-8-on-a-macos-eclipse-is-not-running-with-java-9
|
||||
To check which java version you are using do `java -version` in a command prompt or terminal.
|
||||
|
||||
If you see something like
|
||||
### Building Baritone
|
||||
|
||||
`% 1.8.0_VERSION, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_VERSION.jdk/Contents/Home`
|
||||
These tasks depend on the minecraft version, but are (for the most part) standard for building mods.
|
||||
|
||||
in the list then you've got JDK 8 installed.
|
||||
In order to get JDK 8 running in the **current terminal window** you will have to run this command:
|
||||
For more details, see [the build ci action](/.github/workflows/gradle_build.yml) of the branch you want to build.
|
||||
|
||||
`% export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)`
|
||||
For most branches `gradlew build` should build everything, but there are exceptions and this file might be out of date.
|
||||
|
||||
To add OpenJDK 8 to your PATH add the export line to the end of your `.zshrc / .bashrc` if you want it to apply to each new terminal. If you're using bash change the .bachrc and if you're using zsh change the .zshrc
|
||||
|
||||
Setting up the Environment:
|
||||
|
||||
```
|
||||
$ gradlew setupDecompWorkspace
|
||||
$ gradlew --refresh-dependencies
|
||||
```
|
||||
|
||||
Building Baritone:
|
||||
|
||||
```
|
||||
$ gradlew build
|
||||
```
|
||||
|
||||
For minecraft 1.15.2+, run the following instead to include the Forge jars:
|
||||
|
||||
```
|
||||
$ gradlew build -Pbaritone.forge_build
|
||||
```
|
||||
|
||||
Do this instead for Fabric jars:
|
||||
|
||||
```
|
||||
$ gradlew build -Pbaritone.fabric_build
|
||||
```
|
||||
|
||||
Running Baritone:
|
||||
|
||||
```
|
||||
$ gradlew runClient
|
||||
```
|
||||
|
||||
For information on how to build baritone, see [Building Baritone](#building-baritone)
|
||||
More specifically, on older branches the setup used to be that `gradlew build` builds the tweaker jar
|
||||
and `gradlew build -Pbaritone.forge_build` / `gradlew build -Pbaritone.fabric_build` are needed to build
|
||||
for Forge/Fabric instead. And you might have to run `setupDecompWorkspace` first.
|
||||
|
||||
## IntelliJ
|
||||
- Open the project in IntelliJ as a Gradle project
|
||||
|
||||

|
||||
|
||||
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
|
||||
|
||||

|
||||
|
||||
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
|
||||
|
||||

|
||||
- Depending on the minecraft version, you may need to run `setupDecompWorkspace` or `genIntellijRuns` in order to get everything working
|
||||
|
||||
- Select the "Minecraft Client" launch config
|
||||
|
||||

|
||||
## Github Actions
|
||||
Most branches have a CI workflow at `.github/workflows/gradle_build.yml`. If you fork this repository and enable actions for your fork
|
||||
you can push a dummy commit to trigger it and have GitHub build Baritone for you.
|
||||
|
||||
- Click on ``Edit Configurations...`` from the same dropdown and select the "Minecraft Client" config
|
||||
|
||||

|
||||
|
||||
- In `Edit Configurations...` you need to select `baritone_launch` for `Use classpath of module:`.
|
||||
|
||||

|
||||
|
||||
## IntelliJ
|
||||
|
||||
- Navigate to the gradle tasks on the right tab as follows
|
||||
|
||||

|
||||
|
||||
- Double click on **build** to run it
|
||||
If the commit you want to build is less than 90 days old, you can also find the corresponding workflow run in
|
||||
[this list](https://github.com/cabaletta/baritone/actions/workflows/gradle_build.yml) and download the artifacts from there.
|
||||
|
||||
58
build.gradle
58
build.gradle
@@ -21,17 +21,29 @@ allprojects {
|
||||
apply plugin: "maven-publish"
|
||||
|
||||
archivesBaseName = rootProject.archives_base_name
|
||||
def vers = 'git describe --always --tags --dirty'.execute().text.trim()
|
||||
|
||||
def vers = ""
|
||||
try {
|
||||
vers = 'git describe --always --tags --first-parent --dirty'.execute().text.trim()
|
||||
} catch (Exception e) {
|
||||
println "Version detection failed: " + e
|
||||
}
|
||||
if (!vers.startsWith("v")) {
|
||||
println "git doesn't appear to be installed!"
|
||||
println "using version number: " + rootProject.mod_version
|
||||
version = rootProject.mod_version
|
||||
} else {
|
||||
version = vers.substring(1)
|
||||
println "Detected version " + version
|
||||
}
|
||||
group = rootProject.maven_group
|
||||
|
||||
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
|
||||
sourceCompatibility = targetCompatibility = JavaVersion.toVersion(project.java_version)
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(sourceCompatibility.majorVersion.toInteger()))
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
@@ -59,33 +71,44 @@ allprojects {
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = 'babbaj-repo'
|
||||
url = 'https://babbaj.github.io/maven/'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "net.minecraft:minecraft:${rootProject.minecraft_version}"
|
||||
// The following line declares the mojmap mappings, you may use other mappings as well
|
||||
mappings "net.fabricmc:intermediary:${rootProject.minecraft_version}:v2"
|
||||
mappings "net.minecraft:minecraft:${rootProject.minecraft_version}:client-mappings"
|
||||
mappings "org.parchmentmc.data:parchment-1.19.2:2022.11.27@zip"
|
||||
compileOnly "org.spongepowered:mixin:${project.mixin_version}"
|
||||
compileOnly "org.ow2.asm:asm:${project.asm_version}"
|
||||
|
||||
implementation "org.spongepowered:mixin:0.8.5"
|
||||
implementation "org.ow2.asm:asm:9.3"
|
||||
// The following line declares the yarn mappings you may select this one as well.
|
||||
// mappings "net.fabricmc:yarn:1.17.1+build.32:v2"
|
||||
implementation "dev.babbaj:nether-pathfinder:${project.nether_pathfinder_version}"
|
||||
|
||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
}
|
||||
|
||||
unimined.minecraft(sourceSets.main, true) {
|
||||
version rootProject.minecraft_version
|
||||
|
||||
mappings {
|
||||
intermediary()
|
||||
mojmap()
|
||||
parchment("1.20.2", "2023.10.22")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
it.options.encoding = "UTF-8"
|
||||
|
||||
def targetVersion = 17
|
||||
def targetVersion = project.java_version.toInteger()
|
||||
if (JavaVersion.current().isJava9Compatible()) {
|
||||
it.options.release = targetVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
minecraft {
|
||||
unimined.minecraft {
|
||||
runs.off = true
|
||||
defaultRemapJar = false
|
||||
}
|
||||
|
||||
archivesBaseName = archivesBaseName + "-common"
|
||||
@@ -125,15 +148,10 @@ jar {
|
||||
from sourceSets.main.output, sourceSets.launch.output, sourceSets.api.output
|
||||
}
|
||||
|
||||
remapJar {
|
||||
targetNamespace = "named"
|
||||
fallbackTargetNamespace = "intermediary"
|
||||
}
|
||||
|
||||
javadoc {
|
||||
options.addStringOption('Xwerror', '-quiet') // makes the build fail on travis when there is a javadoc error
|
||||
options.linkSource true
|
||||
options.encoding "UTF-8" // allow emoji in comments :^)
|
||||
source = sourceSets.api.allJava
|
||||
classpath += sourceSets.api.compileClasspath
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,16 @@ repositories {
|
||||
name = 'FabricMaven'
|
||||
url = 'https://maven.fabricmc.net/'
|
||||
}
|
||||
maven {
|
||||
name = 'NeoForgedMaven'
|
||||
url = 'https://maven.neoforged.net/'
|
||||
}
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: '2.9.0'
|
||||
implementation group: 'commons-io', name: 'commons-io', version: '2.6'
|
||||
implementation group: 'commons-io', name: 'commons-io', version: '2.7'
|
||||
|
||||
implementation group: 'xyz.wagyourtail.unimined', name: 'xyz.wagyourtail.unimined.gradle.plugin', version: '0.3.4'
|
||||
implementation group: 'xyz.wagyourtail.unimined', name: 'xyz.wagyourtail.unimined.gradle.plugin', version: '1.2.9'
|
||||
}
|
||||
@@ -36,8 +36,8 @@ import java.nio.file.Paths;
|
||||
class BaritoneGradleTask extends DefaultTask {
|
||||
|
||||
protected static final String
|
||||
PROGUARD_ZIP = "proguard.zip",
|
||||
PROGUARD_JAR = "proguard.jar",
|
||||
PROGUARD_ZIP = "proguard-%s.zip",
|
||||
PROGUARD_JAR = "proguard-%s.jar",
|
||||
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
|
||||
PROGUARD_CONFIG_DEST = "template.pro",
|
||||
PROGUARD_API_CONFIG = "api.pro",
|
||||
|
||||
@@ -18,31 +18,31 @@
|
||||
package baritone.gradle.task;
|
||||
|
||||
import baritone.gradle.util.Determinizer;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.SourceSetContainer;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.api.tasks.TaskCollection;
|
||||
import org.gradle.api.tasks.compile.ForkOptions;
|
||||
import org.gradle.api.tasks.compile.JavaCompile;
|
||||
import org.gradle.internal.jvm.Jvm;
|
||||
import xyz.wagyourtail.unimined.api.Constants;
|
||||
import xyz.wagyourtail.unimined.api.minecraft.EnvType;
|
||||
import xyz.wagyourtail.unimined.api.minecraft.MinecraftProvider;
|
||||
import org.gradle.jvm.toolchain.JavaLanguageVersion;
|
||||
import org.gradle.jvm.toolchain.JavaLauncher;
|
||||
import org.gradle.jvm.toolchain.JavaToolchainService;
|
||||
import xyz.wagyourtail.unimined.api.UniminedExtension;
|
||||
import xyz.wagyourtail.unimined.api.minecraft.MinecraftConfig;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 10/11/2018
|
||||
@@ -50,18 +50,13 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
public class ProguardTask extends BaritoneGradleTask {
|
||||
|
||||
@Input
|
||||
private String url;
|
||||
private String proguardVersion;
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
public String getProguardVersion() {
|
||||
return proguardVersion;
|
||||
}
|
||||
|
||||
@Input
|
||||
private String extract;
|
||||
|
||||
public String getExtract() {
|
||||
return extract;
|
||||
}
|
||||
private List<String> requiredLibraries;
|
||||
|
||||
@TaskAction
|
||||
protected void exec() throws Exception {
|
||||
@@ -69,23 +64,26 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
super.verifyArtifacts();
|
||||
|
||||
// "Haha brady why don't you make separate tasks"
|
||||
processArtifact();
|
||||
downloadProguard();
|
||||
extractProguard();
|
||||
generateConfigs();
|
||||
processArtifact();
|
||||
proguardApi();
|
||||
proguardStandalone();
|
||||
cleanup();
|
||||
}
|
||||
|
||||
MinecraftProvider<?, ?> provider = this.getProject().getExtensions().getByType(MinecraftProvider.class);
|
||||
UniminedExtension ext = getProject().getExtensions().getByType(UniminedExtension.class);
|
||||
SourceSetContainer sourceSets = getProject().getExtensions().getByType(SourceSetContainer.class);
|
||||
|
||||
private File getMcJar() {
|
||||
return provider.getMinecraftWithMapping(EnvType.COMBINED, provider.getMcPatcher().getProdNamespace(), provider.getMcPatcher().getProdFallbackNamespace()).toFile();
|
||||
MinecraftConfig mcc = ext.getMinecrafts().get(sourceSets.getByName("main"));
|
||||
return mcc.getMinecraft(mcc.getMcPatcher().getProdNamespace(), mcc.getMcPatcher().getProdNamespace()).toFile();
|
||||
}
|
||||
|
||||
private boolean isMcJar(File f) {
|
||||
return this.getProject().getConfigurations().getByName(Constants.MINECRAFT_COMBINED_PROVIDER).getFiles().contains(f);
|
||||
MinecraftConfig mcc = ext.getMinecrafts().get(sourceSets.getByName("main"));
|
||||
return mcc.isMinecraftJar(f.toPath());
|
||||
}
|
||||
|
||||
private void processArtifact() throws Exception {
|
||||
@@ -93,124 +91,41 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
Files.delete(this.artifactUnoptimizedPath);
|
||||
}
|
||||
|
||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
|
||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), List.of(), false);
|
||||
}
|
||||
|
||||
private void downloadProguard() throws Exception {
|
||||
Path proguardZip = getTemporaryFile(PROGUARD_ZIP);
|
||||
Path proguardZip = getTemporaryFile(String.format(PROGUARD_ZIP, proguardVersion));
|
||||
if (!Files.exists(proguardZip)) {
|
||||
write(new URL(this.url).openStream(), proguardZip);
|
||||
write(new URL(String.format("https://github.com/Guardsquare/proguard/releases/download/v%s/proguard-%s.zip", proguardVersion, proguardVersion)).openStream(), proguardZip);
|
||||
}
|
||||
}
|
||||
|
||||
private void extractProguard() throws Exception {
|
||||
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
|
||||
Path proguardJar = getTemporaryFile(String.format(PROGUARD_JAR, proguardVersion));
|
||||
if (!Files.exists(proguardJar)) {
|
||||
ZipFile zipFile = new ZipFile(getTemporaryFile(PROGUARD_ZIP).toFile());
|
||||
ZipEntry zipJarEntry = zipFile.getEntry(this.extract);
|
||||
ZipFile zipFile = new ZipFile(getTemporaryFile(String.format(PROGUARD_ZIP, proguardVersion)).toFile());
|
||||
ZipEntry zipJarEntry = zipFile.getEntry(String.format("proguard-%s/lib/proguard.jar", proguardVersion));
|
||||
write(zipFile.getInputStream(zipJarEntry), proguardJar);
|
||||
zipFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
private String getJavaBinPathForProguard() throws Exception {
|
||||
String path;
|
||||
try {
|
||||
path = findJavaPathByGradleConfig();
|
||||
if (path != null) return path;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.err.println("Unable to find java by javaCompile options");
|
||||
ex.printStackTrace();
|
||||
private JavaLauncher getJavaLauncherForProguard() {
|
||||
var toolchains = getProject().getExtensions().getByType(JavaToolchainService.class);
|
||||
var toolchain = toolchains.launcherFor((spec) -> {
|
||||
spec.getLanguageVersion().set(JavaLanguageVersion.of(getProject().findProperty("java_version").toString()));
|
||||
}).getOrNull();
|
||||
|
||||
if (toolchain == null) {
|
||||
throw new IllegalStateException("Java toolchain not found");
|
||||
}
|
||||
|
||||
try {
|
||||
path = findJavaByJavaHome();
|
||||
if (path != null) return path;
|
||||
}
|
||||
catch(Exception ex) {
|
||||
System.err.println("Unable to find java by JAVA_HOME");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
path = findJavaByGradleCurrentRuntime();
|
||||
if (path != null) return path;
|
||||
|
||||
throw new Exception("Unable to find java to determine ProGuard libraryjars. Please specify forkOptions.executable in javaCompile," +
|
||||
" JAVA_HOME environment variable, or make sure to run Gradle with the correct JDK (a v1.8 only)");
|
||||
}
|
||||
|
||||
private String findJavaByGradleCurrentRuntime() {
|
||||
String path = Jvm.current().getJavaExecutable().getAbsolutePath();
|
||||
|
||||
if (this.validateJavaVersion(path)) {
|
||||
System.out.println("Using Gradle's runtime Java for ProGuard");
|
||||
return path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String findJavaByJavaHome() {
|
||||
final String javaHomeEnv = System.getenv("JAVA_HOME");
|
||||
if (javaHomeEnv != null) {
|
||||
|
||||
String path = Jvm.forHome(new File(javaHomeEnv)).getJavaExecutable().getAbsolutePath();
|
||||
if (this.validateJavaVersion(path)) {
|
||||
System.out.println("Detected Java path by JAVA_HOME");
|
||||
return path;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String findJavaPathByGradleConfig() {
|
||||
final TaskCollection<JavaCompile> javaCompiles = super.getProject().getTasks().withType(JavaCompile.class);
|
||||
|
||||
final JavaCompile compileTask = javaCompiles.iterator().next();
|
||||
final ForkOptions forkOptions = compileTask.getOptions().getForkOptions();
|
||||
|
||||
if (forkOptions != null) {
|
||||
String javacPath = forkOptions.getExecutable();
|
||||
if (javacPath != null) {
|
||||
File javacFile = new File(javacPath);
|
||||
if (javacFile.exists()) {
|
||||
File[] maybeJava = javacFile.getParentFile().listFiles(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.equals("java");
|
||||
}
|
||||
});
|
||||
|
||||
if (maybeJava != null && maybeJava.length > 0) {
|
||||
String path = maybeJava[0].getAbsolutePath();
|
||||
if (this.validateJavaVersion(path)) {
|
||||
System.out.println("Detected Java path by forkOptions");
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean validateJavaVersion(String java) {
|
||||
//TODO: fix for j16
|
||||
// final JavaVersion javaVersion = new DefaultJvmVersionDetector(new DefaultExecActionFactory(new IdentityFileResolver())).getJavaVersion(java);
|
||||
//
|
||||
// if (!javaVersion.getMajorVersion().equals("8")) {
|
||||
// System.out.println("Failed to validate Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars");
|
||||
// // throw new RuntimeException("Java version incorrect: " + javaVersion.getMajorVersion() + " for " + java);
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// System.out.println("Validated Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars");
|
||||
return true;
|
||||
return toolchain;
|
||||
}
|
||||
|
||||
private void generateConfigs() throws Exception {
|
||||
Files.copy(getRootRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), REPLACE_EXISTING);
|
||||
Files.copy(getRootRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
// Setup the template that will be used to derive the API and Standalone configs
|
||||
List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST));
|
||||
@@ -233,11 +148,11 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
{
|
||||
// Discover all of the libraries that we will need to acquire from gradle
|
||||
final Stream<File> dependencies = acquireDependencies()
|
||||
// remove MCP mapped jar, and nashorn
|
||||
.filter(f -> !f.toString().endsWith("-recomp.jar") && !f.getName().startsWith("nashorn") && !f.getName().startsWith("coremods"));
|
||||
// remove MCP mapped jar, and nashorn
|
||||
.filter(f -> !f.toString().endsWith("-recomp.jar") && !f.getName().startsWith("nashorn") && !f.getName().startsWith("coremods"));
|
||||
|
||||
libraries = dependencies
|
||||
.map(f -> isMcJar(f) ? mcJar : f);
|
||||
.map(f -> isMcJar(f) ? mcJar : f);
|
||||
}
|
||||
libraries.forEach(f -> {
|
||||
template.add(2, "-libraryjars '" + f + "'");
|
||||
@@ -250,29 +165,48 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
api.add(2, "-printmapping " + new File(this.getRootRelativeFile(PROGUARD_MAPPING_DIR).toFile(), "mappings-" + addCompTypeFirst("api.txt")));
|
||||
|
||||
// API config doesn't require any changes from the changes that we made to the template
|
||||
Files.write(getTemporaryFile(compType+PROGUARD_API_CONFIG), api);
|
||||
Files.write(getTemporaryFile(compType + PROGUARD_API_CONFIG), api);
|
||||
|
||||
// For the Standalone config, don't keep the API package
|
||||
List<String> standalone = new ArrayList<>(template);
|
||||
standalone.removeIf(s -> s.contains("# this is the keep api"));
|
||||
standalone.add(2, "-printmapping " + new File(this.getRootRelativeFile(PROGUARD_MAPPING_DIR).toFile(), "mappings-" + addCompTypeFirst("standalone.txt")));
|
||||
Files.write(getTemporaryFile(compType+PROGUARD_STANDALONE_CONFIG), standalone);
|
||||
Files.write(getTemporaryFile(compType + PROGUARD_STANDALONE_CONFIG), standalone);
|
||||
}
|
||||
|
||||
private Stream<File> acquireDependencies() {
|
||||
return getProject().getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().findByName("main").getCompileClasspath().getFiles()
|
||||
.stream()
|
||||
.filter(File::isFile);
|
||||
.stream()
|
||||
.filter(File::isFile);
|
||||
}
|
||||
|
||||
private void proguardApi() throws Exception {
|
||||
runProguard(getTemporaryFile(compType+PROGUARD_API_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
|
||||
runProguard(getTemporaryFile(compType + PROGUARD_API_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), List.of(), false);
|
||||
}
|
||||
|
||||
private void proguardStandalone() throws Exception {
|
||||
runProguard(getTemporaryFile(compType+PROGUARD_STANDALONE_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
|
||||
runProguard(getTemporaryFile(compType + PROGUARD_STANDALONE_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), List.of(), false);
|
||||
}
|
||||
|
||||
private static final class Pair<A, B> {
|
||||
public final A a;
|
||||
public final B b;
|
||||
|
||||
private Pair(final A a, final B b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Pair{" +
|
||||
"a=" + this.a +
|
||||
", " +
|
||||
"b=" + this.b +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
@@ -281,51 +215,25 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
public void setProguardVersion(String url) {
|
||||
this.proguardVersion = url;
|
||||
}
|
||||
|
||||
public void setExtract(String extract) {
|
||||
this.extract = extract;
|
||||
}
|
||||
private void runProguard(Path config) throws Exception {
|
||||
// Delete the existing proguard output file. Proguard probably handles this already, but why not do it ourselves
|
||||
if (Files.exists(this.proguardOut)) {
|
||||
Files.delete(this.proguardOut);
|
||||
}
|
||||
|
||||
// Make paths relative to work directory; fixes spaces in path to config, @"" doesn't work
|
||||
Path workingDirectory = getTemporaryFile("");
|
||||
Path proguardJar = workingDirectory.relativize(getTemporaryFile(PROGUARD_JAR));
|
||||
config = workingDirectory.relativize(config);
|
||||
|
||||
// Honestly, if you still have spaces in your path at this point, you're SOL.
|
||||
|
||||
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
|
||||
.directory(workingDirectory.toFile()) // Set the working directory to the temporary folder]
|
||||
.start();
|
||||
getProject().javaexec(spec -> {
|
||||
spec.workingDir(workingDirectory.toFile());
|
||||
spec.args("@" + workingDirectory.relativize(config));
|
||||
spec.classpath(getTemporaryFile(String.format(PROGUARD_JAR, proguardVersion)));
|
||||
|
||||
// We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this
|
||||
this.printOutputLog(p.getInputStream(), System.out);
|
||||
this.printOutputLog(p.getErrorStream(), System.err);
|
||||
|
||||
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
|
||||
int exitCode = p.waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new IllegalStateException("Proguard exited with code " + exitCode);
|
||||
}
|
||||
spec.executable(getJavaLauncherForProguard().getExecutablePath().getAsFile());
|
||||
}).assertNormalExitValue().rethrowFailure();
|
||||
}
|
||||
|
||||
private void printOutputLog(InputStream stream, PrintStream outerr) {
|
||||
new Thread(() -> {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
outerr.println(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +39,11 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class Determinizer {
|
||||
|
||||
public static void determinize(String inputPath, String outputPath) throws IOException {
|
||||
public static void determinize(String inputPath, String outputPath, List<File> toInclude, boolean doForgeReplacementOfMetaInf) throws IOException {
|
||||
System.out.println("Running Determinizer");
|
||||
System.out.println(" Input path: " + inputPath);
|
||||
System.out.println(" Output path: " + outputPath);
|
||||
System.out.println(" Shade: " + toInclude);
|
||||
|
||||
try (
|
||||
JarFile jarFile = new JarFile(new File(inputPath));
|
||||
@@ -64,14 +65,35 @@ public class Determinizer {
|
||||
clone.setTime(42069);
|
||||
jos.putNextEntry(clone);
|
||||
if (entry.getName().endsWith(".refmap.json")) {
|
||||
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
|
||||
jos.write(writeSorted(object).getBytes());
|
||||
JsonElement json = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry)));
|
||||
jos.write(writeSorted(json).getBytes());
|
||||
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && doForgeReplacementOfMetaInf) { // only replace for forge jar
|
||||
ByteArrayOutputStream cancer = new ByteArrayOutputStream();
|
||||
copy(jarFile.getInputStream(entry), cancer);
|
||||
String manifest = new String(cancer.toByteArray());
|
||||
if (!manifest.contains("baritone.launch.tweaker.BaritoneTweaker")) {
|
||||
throw new IllegalStateException("unable to replace");
|
||||
}
|
||||
manifest = manifest.replace("baritone.launch.tweaker.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker");
|
||||
jos.write(manifest.getBytes());
|
||||
} else {
|
||||
copy(jarFile.getInputStream(entry), jos);
|
||||
}
|
||||
}
|
||||
for (File file : toInclude) {
|
||||
try (JarFile mixin = new JarFile(file)) {
|
||||
for (JarEntry entry : mixin.stream().sorted(Comparator.comparing(JarEntry::getName)).collect(Collectors.toList())) {
|
||||
if (entry.getName().startsWith("META-INF") && !entry.getName().startsWith("META-INF/services")) {
|
||||
continue;
|
||||
}
|
||||
jos.putNextEntry(entry);
|
||||
copy(mixin.getInputStream(entry), jos);
|
||||
}
|
||||
}
|
||||
}
|
||||
jos.finish();
|
||||
}
|
||||
System.out.println("Done with determinizer");
|
||||
}
|
||||
|
||||
private static void copy(InputStream is, OutputStream os) throws IOException {
|
||||
@@ -82,7 +104,7 @@ public class Determinizer {
|
||||
}
|
||||
}
|
||||
|
||||
private static String writeSorted(JsonObject in) throws IOException {
|
||||
private static String writeSorted(JsonElement in) throws IOException {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonWriter jw = new JsonWriter(writer);
|
||||
ORDERED_JSON_WRITER.write(jw, in);
|
||||
|
||||
@@ -19,13 +19,15 @@ import baritone.gradle.task.CreateDistTask
|
||||
import baritone.gradle.task.ProguardTask
|
||||
|
||||
plugins {
|
||||
id "com.github.johnrengelman.shadow" version "7.0.0"
|
||||
id "com.github.johnrengelman.shadow" version "8.0.0"
|
||||
}
|
||||
|
||||
archivesBaseName = archivesBaseName + "-fabric"
|
||||
|
||||
minecraft {
|
||||
fabric()
|
||||
unimined.minecraft {
|
||||
fabric {
|
||||
loader project.fabric_version
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
@@ -36,8 +38,6 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
fabric "net.fabricmc:fabric-loader:${project.fabric_version}"
|
||||
|
||||
// because of multiple sourcesets `common project(":")` doesn't work
|
||||
for (sourceSet in rootProject.sourceSets) {
|
||||
if (sourceSet == rootProject.sourceSets.test) continue
|
||||
@@ -45,6 +45,7 @@ dependencies {
|
||||
common sourceSet.output
|
||||
shadowCommon sourceSet.output
|
||||
}
|
||||
include "dev.babbaj:nether-pathfinder:${project.nether_pathfinder_version}"
|
||||
}
|
||||
|
||||
processResources {
|
||||
@@ -57,17 +58,17 @@ processResources {
|
||||
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadowCommon]
|
||||
classifier "dev-shadow"
|
||||
archiveClassifier.set "dev-shadow"
|
||||
}
|
||||
|
||||
remapJar {
|
||||
inputFile.set shadowJar.archiveFile
|
||||
dependsOn shadowJar
|
||||
classifier null
|
||||
archiveClassifier.set null
|
||||
}
|
||||
|
||||
jar {
|
||||
classifier "dev"
|
||||
archiveClassifier.set "dev"
|
||||
}
|
||||
|
||||
components.java {
|
||||
@@ -77,8 +78,7 @@ components.java {
|
||||
}
|
||||
|
||||
task proguard(type: ProguardTask) {
|
||||
url 'https://github.com/Guardsquare/proguard/releases/download/v7.2.1/proguard-7.2.1.zip'
|
||||
extract 'proguard-7.2.1/lib/proguard.jar'
|
||||
proguardVersion "7.2.1"
|
||||
compType "fabric"
|
||||
}
|
||||
|
||||
@@ -100,4 +100,4 @@ publishing {
|
||||
repositories {
|
||||
// Add repositories to publish to here.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "baritone",
|
||||
@@ -11,7 +10,8 @@
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "https://github.com/cabaletta/baritone",
|
||||
"sources": "https://github.com/cabaletta/baritone"
|
||||
"sources": "https://github.com/cabaletta/baritone",
|
||||
"issues": "https://github.com/cabaletta/baritone/issues"
|
||||
},
|
||||
|
||||
"license": "LGPL-3.0",
|
||||
@@ -25,7 +25,14 @@
|
||||
],
|
||||
|
||||
"depends": {
|
||||
"fabricloader": ">=0.11.0",
|
||||
"minecraft": "1.19.4"
|
||||
"fabricloader": ">=0.14.22",
|
||||
"minecraft": ["1.20.3", "1.20.4"]
|
||||
},
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"links": {
|
||||
"modmenu.discord": "https://discord.gg/s6fRBAUpmr"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,19 @@ import baritone.gradle.task.CreateDistTask
|
||||
import baritone.gradle.task.ProguardTask
|
||||
|
||||
plugins {
|
||||
id "com.github.johnrengelman.shadow" version "7.0.0"
|
||||
id "com.github.johnrengelman.shadow" version "8.0.0"
|
||||
}
|
||||
|
||||
archivesBaseName = archivesBaseName + "-forge"
|
||||
|
||||
minecraft {
|
||||
unimined.minecraft {
|
||||
mappings {
|
||||
devFallbackNamespace "intermediary"
|
||||
}
|
||||
|
||||
forge {
|
||||
devFallbackNamespace = "intermediary"
|
||||
mixinConfig = ["mixins.baritone.json"]
|
||||
loader project.forge_version
|
||||
mixinConfig ["mixins.baritone.json"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +49,6 @@ configurations {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
forge "net.minecraftforge:forge:${rootProject.forge_version}"
|
||||
|
||||
// because of multiple sourcesets `common project(":")` doesn't work
|
||||
for (sourceSet in rootProject.sourceSets) {
|
||||
if (sourceSet == rootProject.sourceSets.test) continue
|
||||
@@ -54,6 +56,7 @@ dependencies {
|
||||
common sourceSet.output
|
||||
shadowCommon sourceSet.output
|
||||
}
|
||||
shadowCommon "dev.babbaj:nether-pathfinder:${project.nether_pathfinder_version}"
|
||||
}
|
||||
|
||||
processResources {
|
||||
@@ -66,17 +69,17 @@ processResources {
|
||||
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadowCommon]
|
||||
classifier "dev-shadow"
|
||||
archiveClassifier.set "dev-shadow"
|
||||
}
|
||||
|
||||
remapJar {
|
||||
inputFile.set shadowJar.archiveFile
|
||||
dependsOn shadowJar
|
||||
classifier null
|
||||
archiveClassifier.set null
|
||||
}
|
||||
|
||||
jar {
|
||||
classifier "dev"
|
||||
archiveClassifier.set "dev"
|
||||
|
||||
manifest {
|
||||
attributes(
|
||||
@@ -96,8 +99,7 @@ components.java {
|
||||
}
|
||||
|
||||
task proguard(type: ProguardTask) {
|
||||
url 'https://github.com/Guardsquare/proguard/releases/download/v7.2.1/proguard-7.2.1.zip'
|
||||
extract 'proguard-7.2.1/lib/proguard.jar'
|
||||
proguardVersion "7.2.1"
|
||||
compType "forge"
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
|
||||
modLoader="javafml" #mandatory
|
||||
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
|
||||
loaderVersion="[33,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
|
||||
loaderVersion="[48,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
|
||||
license="https://raw.githubusercontent.com/cabaletta/baritone/1.16.2/LICENSE"
|
||||
# A URL to refer people to when problems occur with this mod
|
||||
issueTrackerURL="https://github.com/cabaletta/baritone/issues" #optional
|
||||
@@ -35,6 +35,6 @@ A Minecraft pathfinder bot.
|
||||
modId="minecraft"
|
||||
mandatory=true
|
||||
# This version range declares a minimum of the current minecraft version up to but not including the next major version
|
||||
versionRange="[1.19.3]"
|
||||
versionRange="[1.20.3, 1.20.4]"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
side="BOTH"
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
org.gradle.jvmargs=-Xmx4G
|
||||
|
||||
mod_version=1.9.2
|
||||
available_loaders=fabric,forge,neoforge,tweaker
|
||||
|
||||
mod_version=1.10.4
|
||||
maven_group=baritone
|
||||
archives_base_name=baritone
|
||||
|
||||
minecraft_version=1.19.4
|
||||
forge_version=1.19.3-44.0.1
|
||||
fabric_version=0.14.11
|
||||
java_version=17
|
||||
|
||||
minecraft_version=1.20.4
|
||||
|
||||
forge_version=49.0.3
|
||||
|
||||
neoforge_version=0-beta
|
||||
|
||||
fabric_version=0.14.22
|
||||
|
||||
nether_pathfinder_version=1.4.1
|
||||
|
||||
// These dependencies are used for common and tweaker
|
||||
// while mod loaders usually ship their own version
|
||||
mixin_version=0.8.5
|
||||
asm_version=9.3
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
2
gradlew
vendored
2
gradlew
vendored
@@ -72,7 +72,7 @@ case "`uname`" in
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
MSYS* | MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
|
||||
133
neoforge/build.gradle
Normal file
133
neoforge/build.gradle
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import baritone.gradle.task.CreateDistTask
|
||||
import baritone.gradle.task.ProguardTask
|
||||
|
||||
plugins {
|
||||
id "com.github.johnrengelman.shadow" version "8.0.0"
|
||||
}
|
||||
|
||||
archivesBaseName = archivesBaseName + "-neoforge"
|
||||
|
||||
unimined.minecraft {
|
||||
mappings {
|
||||
devFallbackNamespace "intermediary"
|
||||
}
|
||||
|
||||
neoForged {
|
||||
loader project.neoforge_version
|
||||
mixinConfig ["mixins.baritone.json"]
|
||||
}
|
||||
|
||||
minecraftRemapper.config {
|
||||
// neoforge adds 1 conflict, where 2 interfaces have a method with the same name on yarn/mojmap,
|
||||
// but the method has different names in the intermediary mappings.
|
||||
// this is a conflict because they have a class that extends both interfaces.
|
||||
// this shouldn't be a problem as long as named mappings don't make the name of those 2 methods different.
|
||||
ignoreConflicts(true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//loom {
|
||||
// forge {
|
||||
// mixinConfig 'mixins.baritone.json'
|
||||
// }
|
||||
//}
|
||||
|
||||
configurations {
|
||||
common
|
||||
shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
|
||||
compileClasspath.extendsFrom common
|
||||
runtimeClasspath.extendsFrom common
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// because of multiple sourcesets `common project(":")` doesn't work
|
||||
for (sourceSet in rootProject.sourceSets) {
|
||||
if (sourceSet == rootProject.sourceSets.test) continue
|
||||
if (sourceSet == rootProject.sourceSets.schematica_api) continue
|
||||
common sourceSet.output
|
||||
shadowCommon sourceSet.output
|
||||
}
|
||||
shadowCommon "dev.babbaj:nether-pathfinder:${project.nether_pathfinder_version}"
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
filesMatching("META-INF/mods.toml") {
|
||||
expand "version": project.version
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadowCommon]
|
||||
archiveClassifier.set "dev-shadow"
|
||||
}
|
||||
|
||||
remapJar {
|
||||
inputFile.set shadowJar.archiveFile
|
||||
dependsOn shadowJar
|
||||
archiveClassifier.set null
|
||||
}
|
||||
|
||||
jar {
|
||||
archiveClassifier.set "dev"
|
||||
|
||||
manifest {
|
||||
attributes(
|
||||
'MixinConfigs': 'mixins.baritone.json',
|
||||
"MixinConnector": "baritone.launch.BaritoneMixinConnector",
|
||||
|
||||
'Implementation-Title': 'Baritone',
|
||||
'Implementation-Version': version,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
components.java {
|
||||
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
|
||||
skip()
|
||||
}
|
||||
}
|
||||
|
||||
task proguard(type: ProguardTask) {
|
||||
proguardVersion "7.2.1"
|
||||
compType "neoforge"
|
||||
}
|
||||
|
||||
task createDist(type: CreateDistTask, dependsOn: proguard) {
|
||||
compType "neoforge"
|
||||
}
|
||||
|
||||
build.finalizedBy(createDist)
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenFabric(MavenPublication) {
|
||||
artifactId = rootProject.archives_base_name + "-" + project.name
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
|
||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||
repositories {
|
||||
// Add repositories to publish to here.
|
||||
}
|
||||
}
|
||||
18
neoforge/gradle.properties
Normal file
18
neoforge/gradle.properties
Normal file
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# This file is part of Baritone.
|
||||
#
|
||||
# Baritone is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Baritone 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 Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
loom.platform=forge
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch;
|
||||
|
||||
import net.neoforged.fml.common.Mod;
|
||||
|
||||
@Mod("baritoe")
|
||||
public class BaritoneForgeModXD {
|
||||
}
|
||||
40
neoforge/src/main/resources/META-INF/mods.toml
Normal file
40
neoforge/src/main/resources/META-INF/mods.toml
Normal file
@@ -0,0 +1,40 @@
|
||||
# This is an example mods.toml file. It contains the data relating to the loading mods.
|
||||
# There are several mandatory fields (#mandatory), and many more that are optional (#optional).
|
||||
# The overall format is standard TOML format, v0.5.0.
|
||||
# Note that there are a couple of TOML lists in this file.
|
||||
# Find more information on toml format here: https://github.com/toml-lang/toml
|
||||
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
|
||||
modLoader="javafml" #mandatory
|
||||
# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
|
||||
loaderVersion="[1,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions.
|
||||
license="https://raw.githubusercontent.com/cabaletta/baritone/1.16.2/LICENSE"
|
||||
# A URL to refer people to when problems occur with this mod
|
||||
issueTrackerURL="https://github.com/cabaletta/baritone/issues" #optional
|
||||
# A list of mods - how many allowed here is determined by the individual mod loader
|
||||
[[mods]] #mandatory
|
||||
# The modid of the mod
|
||||
modId="baritoe" #mandatory
|
||||
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
|
||||
version="${version}" #mandatory
|
||||
# A display name for the mod
|
||||
displayName="Baritone" #mandatory
|
||||
# A URL for the "homepage" for this mod, displayed in the mod UI
|
||||
displayURL="https://github.com/cabaletta/baritone" #optional
|
||||
# A file name (in the root of the mod JAR) containing a logo for display
|
||||
#logoFile="examplemod.png" #optional
|
||||
# A text field displayed in the mod UI
|
||||
credits="Hat Gamers" #optional
|
||||
# A text field displayed in the mod UI
|
||||
authors="leijurv, Brady" #optional
|
||||
# The description text for the mod (multi line!) (#mandatory)
|
||||
description='''
|
||||
A Minecraft pathfinder bot.
|
||||
'''
|
||||
|
||||
[[dependencies.baritoe]]
|
||||
modId="minecraft"
|
||||
mandatory=true
|
||||
# This version range declares a minimum of the current minecraft version up to but not including the next major version
|
||||
versionRange="[1.20.3, 1.20.4]"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
6
neoforge/src/main/resources/pack.mcmeta
Normal file
6
neoforge/src/main/resources/pack.mcmeta
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"pack": {
|
||||
"description": "null",
|
||||
"pack_format": 8
|
||||
}
|
||||
}
|
||||
7
scripts/proguard.pro
vendored
7
scripts/proguard.pro
vendored
@@ -19,6 +19,8 @@
|
||||
-dontwarn module-info
|
||||
# we dont have forge
|
||||
-dontwarn baritone.launch.BaritoneForgeModXD
|
||||
# progard doesn't like signature polymorphism
|
||||
-dontwarn java.lang.invoke.MethodHandle
|
||||
|
||||
# please do not change the comment below
|
||||
-keep class baritone.api.** { *; } # this is the keep api
|
||||
@@ -52,6 +54,11 @@
|
||||
-dontwarn baritone.utils.schematic.schematica.**
|
||||
-dontwarn baritone.utils.schematic.litematica.**
|
||||
|
||||
# nether-pathfinder uses JNI to acess its own classes
|
||||
# and some of our builds include it before running proguard
|
||||
# conservatively keep all of it, even though only PathSegment.<init> is needed
|
||||
-keep,allowoptimization class dev.babbaj.pathfinder.** { *; }
|
||||
|
||||
# Keep - Applications. Keep all application classes, along with their 'main'
|
||||
# methods.
|
||||
-keepclasseswithmembers public class * {
|
||||
|
||||
@@ -42,10 +42,6 @@ pluginManagement {
|
||||
rootProject.name = 'baritone'
|
||||
|
||||
include("tweaker")
|
||||
if (System.getProperty("Baritone.enabled_platforms") == null) {
|
||||
// System.setProperty("Baritone.enabled_platforms", "fabric,forge")
|
||||
System.setProperty("Baritone.enabled_platforms", "fabric")
|
||||
}
|
||||
for (platform in System.getProperty("Baritone.enabled_platforms").split(",")) {
|
||||
for (platform in available_loaders.split(",")) {
|
||||
include(platform)
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public final class BaritoneAPI {
|
||||
|
||||
static {
|
||||
settings = new Settings();
|
||||
SettingsUtil.readAndApply(settings);
|
||||
SettingsUtil.readAndApply(settings, SettingsUtil.SETTINGS_DEFAULT_NAME);
|
||||
|
||||
try {
|
||||
provider = (IBaritoneProvider) Class.forName("baritone.BaritoneProvider").newInstance();
|
||||
|
||||
@@ -88,6 +88,12 @@ public interface IBaritone {
|
||||
*/
|
||||
IGetToBlockProcess getGetToBlockProcess();
|
||||
|
||||
/**
|
||||
* @return The {@link IElytraProcess} instance
|
||||
* @see IElytraProcess
|
||||
*/
|
||||
IElytraProcess getElytraProcess();
|
||||
|
||||
/**
|
||||
* @return The {@link IWorldProvider} instance
|
||||
* @see IWorldProvider
|
||||
|
||||
@@ -21,9 +21,12 @@ import baritone.api.cache.IWorldScanner;
|
||||
import baritone.api.command.ICommand;
|
||||
import baritone.api.command.ICommandSystem;
|
||||
import baritone.api.schematic.ISchematicSystem;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
|
||||
/**
|
||||
* Provides the present {@link IBaritone} instances, as well as non-baritone instance related APIs.
|
||||
@@ -51,15 +54,13 @@ public interface IBaritoneProvider {
|
||||
List<IBaritone> getAllBaritones();
|
||||
|
||||
/**
|
||||
* Provides the {@link IBaritone} instance for a given {@link LocalPlayer}. This will likely be
|
||||
* replaced with or be overloaded in addition to {@code #getBaritoneForUser(IBaritoneUser)} when
|
||||
* {@code bot-system} is merged into {@code master}.
|
||||
* Provides the {@link IBaritone} instance for a given {@link LocalPlayer}.
|
||||
*
|
||||
* @param player The player
|
||||
* @return The {@link IBaritone} instance.
|
||||
*/
|
||||
default IBaritone getBaritoneForPlayer(LocalPlayer player) {
|
||||
for (IBaritone baritone : getAllBaritones()) {
|
||||
for (IBaritone baritone : this.getAllBaritones()) {
|
||||
if (Objects.equals(player, baritone.getPlayerContext().player())) {
|
||||
return baritone;
|
||||
}
|
||||
@@ -67,6 +68,55 @@ public interface IBaritoneProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the {@link IBaritone} instance for a given {@link Minecraft}.
|
||||
*
|
||||
* @param minecraft The minecraft
|
||||
* @return The {@link IBaritone} instance.
|
||||
*/
|
||||
default IBaritone getBaritoneForMinecraft(Minecraft minecraft) {
|
||||
for (IBaritone baritone : this.getAllBaritones()) {
|
||||
if (Objects.equals(minecraft, baritone.getPlayerContext().minecraft())) {
|
||||
return baritone;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the {@link IBaritone} instance for the player with the specified connection.
|
||||
*
|
||||
* @param connection The connection
|
||||
* @return The {@link IBaritone} instance.
|
||||
*/
|
||||
default IBaritone getBaritoneForConnection(ClientPacketListener connection) {
|
||||
for (IBaritone baritone : this.getAllBaritones()) {
|
||||
final LocalPlayer player = baritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == connection) {
|
||||
return baritone;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and registers a new {@link IBaritone} instance using the specified {@link Minecraft}. The existing
|
||||
* instance is returned if already registered.
|
||||
*
|
||||
* @param minecraft The minecraft
|
||||
* @return The {@link IBaritone} instance
|
||||
*/
|
||||
IBaritone createBaritone(Minecraft minecraft);
|
||||
|
||||
/**
|
||||
* Destroys and removes the specified {@link IBaritone} instance. If the specified instance is the
|
||||
* {@link #getPrimaryBaritone() primary baritone}, this operation has no effect and will return {@code false}.
|
||||
*
|
||||
* @param baritone The baritone instance to remove
|
||||
* @return Whether the baritone instance was removed
|
||||
*/
|
||||
boolean destroyBaritone(IBaritone baritone);
|
||||
|
||||
/**
|
||||
* Returns the {@link IWorldScanner} instance. This is not a type returned by
|
||||
* {@link IBaritone} implementation, because it is not linked with {@link IBaritone}.
|
||||
|
||||
@@ -17,22 +17,35 @@
|
||||
|
||||
package baritone.api;
|
||||
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.NotificationHelper;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.api.utils.TypeUtils;
|
||||
import baritone.api.utils.gui.BaritoneToast;
|
||||
import net.minecraft.client.GuiMessageTag;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.awt.*;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -42,6 +55,7 @@ import java.util.function.Consumer;
|
||||
* @author leijurv
|
||||
*/
|
||||
public final class Settings {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger("Baritone");
|
||||
|
||||
/**
|
||||
* Allow Baritone to break blocks
|
||||
@@ -63,11 +77,31 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> allowPlace = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Allow Baritone to place blocks in fluid source blocks
|
||||
*/
|
||||
public final Setting<Boolean> allowPlaceInFluidsSource = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Allow Baritone to place blocks in flowing fluid
|
||||
*/
|
||||
public final Setting<Boolean> allowPlaceInFluidsFlow = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Allow Baritone to move items in your inventory to your hotbar
|
||||
*/
|
||||
public final Setting<Boolean> allowInventory = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Wait this many ticks between InventoryBehavior moving inventory items
|
||||
*/
|
||||
public final Setting<Integer> ticksBetweenInventoryMoves = new Setting<>(1);
|
||||
|
||||
/**
|
||||
* Come to a halt before doing any inventory moves. Intended for anticheat such as 2b2t
|
||||
*/
|
||||
public final Setting<Boolean> inventoryMoveOnlyIfStationary = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Disable baritone's auto-tool at runtime, but still assume that another mod will provide auto tool functionality
|
||||
* <p>
|
||||
@@ -151,6 +185,13 @@ public final class Settings {
|
||||
* <p>
|
||||
* Defaults to false because this fails on constantiam. Please let me know if this is ever disabled. Please.
|
||||
*/
|
||||
public final Setting<Boolean> allowJumpAtBuildLimit = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Just here so mods that use the API don't break. Does nothing.
|
||||
*/
|
||||
@Deprecated
|
||||
@JavaOnly
|
||||
public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
|
||||
|
||||
/**
|
||||
@@ -364,6 +405,12 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Float> blockReachDistance = new Setting<>(4.5f);
|
||||
|
||||
/**
|
||||
* How many ticks between breaking a block and starting to break the next block. Default in game is 6 ticks.
|
||||
* Values under 1 will be clamped. The delay only applies to non-instant (1-tick) breaks.
|
||||
*/
|
||||
public final Setting<Integer> blockBreakSpeed = new Setting<>(6);
|
||||
|
||||
/**
|
||||
* How many degrees to randomize the pitch and yaw every tick. Set to 0 to disable
|
||||
*/
|
||||
@@ -609,6 +656,13 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* The chunk packer queue can never grow to larger than this, if it does, the oldest chunks are discarded
|
||||
* <p>
|
||||
* The newest chunks are kept, so that if you're moving in a straight line quickly then stop, your immediate render distance is still included
|
||||
*/
|
||||
public final Setting<Integer> chunkPackerQueueMaxSize = new Setting<>(2000);
|
||||
|
||||
/**
|
||||
* Fill in blocks behind you
|
||||
*/
|
||||
@@ -710,6 +764,37 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> freeLook = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Break and place blocks without having to force the client-sided rotations. Requires {@link #freeLook}.
|
||||
*/
|
||||
public final Setting<Boolean> blockFreeLook = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Automatically elytra fly without having to force the client-sided rotations.
|
||||
*/
|
||||
public final Setting<Boolean> elytraFreeLook = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Forces the client-sided yaw rotation to an average of the last {@link #smoothLookTicks} of server-sided rotations.
|
||||
*/
|
||||
public final Setting<Boolean> smoothLook = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Same as {@link #smoothLook} but for elytra flying.
|
||||
*/
|
||||
public final Setting<Boolean> elytraSmoothLook = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* The number of ticks to average across for {@link #smoothLook};
|
||||
*/
|
||||
public final Setting<Integer> smoothLookTicks = new Setting<>(5);
|
||||
|
||||
/**
|
||||
* When true, the player will remain with its existing look direction as often as possible.
|
||||
* Although, in some cases this can get it stuck, hence this setting to disable that behavior.
|
||||
*/
|
||||
public final Setting<Boolean> remainWithExistingLookDirection = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Will cause some minor behavioral differences to ensure that Baritone works on anticheats.
|
||||
* <p>
|
||||
@@ -772,6 +857,11 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> shortBaritonePrefix = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Use a modern message tag instead of a prefix when logging to chat
|
||||
*/
|
||||
public final Setting<Boolean> useMessageTag = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Echo commands to chat when they are run
|
||||
*/
|
||||
@@ -839,12 +929,24 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Integer> maxCachedWorldScanCount = new Setting<>(10);
|
||||
|
||||
/**
|
||||
* Mine will not scan for or remember more than this many target locations.
|
||||
* Note that the number of locations retrieved from cache is additionaly
|
||||
* limited by {@link #maxCachedWorldScanCount}.
|
||||
*/
|
||||
public final Setting<Integer> mineMaxOreLocationsCount = new Setting<>(64);
|
||||
|
||||
/**
|
||||
* Sets the minimum y level whilst mining - set to 0 to turn off.
|
||||
* if world has negative y values, subtract the min world height to get the value to put here
|
||||
*/
|
||||
public final Setting<Integer> minYLevelWhileMining = new Setting<>(0);
|
||||
|
||||
/**
|
||||
* Sets the maximum y level to mine ores at.
|
||||
*/
|
||||
public final Setting<Integer> maxYLevelWhileMining = new Setting<>(2031);
|
||||
|
||||
/**
|
||||
* This will only allow baritone to mine exposed ores, can be used to stop ore obfuscators on servers that use them.
|
||||
*/
|
||||
@@ -891,6 +993,11 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> replantNetherWart = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Farming will scan for at most this many blocks.
|
||||
*/
|
||||
public final Setting<Integer> farmMaxScanSize = new Setting<>(256);
|
||||
|
||||
/**
|
||||
* When the cache scan gives less blocks than the maximum threshold (but still above zero), scan the main world too.
|
||||
* <p>
|
||||
@@ -982,6 +1089,11 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Double> breakCorrectBlockPenaltyMultiplier = new Setting<>(10d);
|
||||
|
||||
/**
|
||||
* Multiply the cost of placing a block that's incorrect in the builder's schematic by this coefficient
|
||||
*/
|
||||
public final Setting<Double> placeIncorrectBlockPenaltyMultiplier = new Setting<>(2d);
|
||||
|
||||
/**
|
||||
* When this setting is true, build a schematic with the highest X coordinate being the origin, instead of the lowest
|
||||
*/
|
||||
@@ -997,6 +1109,28 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> schematicOrientationZ = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Rotates the schematic before building it.
|
||||
* Possible values are
|
||||
* <ul>
|
||||
* <li> NONE - No rotation </li>
|
||||
* <li> CLOCKWISE_90 - Rotate 90° clockwise </li>
|
||||
* <li> CLOCKWISE_180 - Rotate 180° clockwise </li>
|
||||
* <li> COUNTERCLOCKWISE_90 - Rotate 270° clockwise </li>
|
||||
* </ul>
|
||||
*/
|
||||
public final Setting<Rotation> buildSchematicRotation = new Setting<>(Rotation.NONE);
|
||||
|
||||
/**
|
||||
* Mirrors the schematic before building it.
|
||||
* Possible values are
|
||||
* <ul>
|
||||
* <li> FRONT_BACK - mirror the schematic along its local x axis </li>
|
||||
* <li> LEFT_RIGHT - mirror the schematic along its local z axis </li>
|
||||
* </ul>
|
||||
*/
|
||||
public final Setting<Mirror> buildSchematicMirror = new Setting<>(Mirror.NONE);
|
||||
|
||||
/**
|
||||
* The fallback used by the build command when no extension is specified. This may be useful if schematics of a
|
||||
* particular format are used often, and the user does not wish to have to specify the extension with every usage.
|
||||
@@ -1108,6 +1242,11 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Integer> followRadius = new Setting<>(3);
|
||||
|
||||
/**
|
||||
* The maximum distance to the entity you're following
|
||||
*/
|
||||
public final Setting<Integer> followTargetMaxDistance = new Setting<>(0);
|
||||
|
||||
/**
|
||||
* Turn this on if your exploration filter is enormous, you don't want it to check if it's done,
|
||||
* and you are just fine with it just hanging on completion
|
||||
@@ -1141,13 +1280,22 @@ public final class Settings {
|
||||
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
||||
* {@link Setting#value};
|
||||
*/
|
||||
public final Setting<Consumer<Component>> logger = new Setting<>(msg -> Minecraft.getInstance().gui.getChat().addMessage(msg));
|
||||
@JavaOnly
|
||||
public final Setting<Consumer<Component>> logger = new Setting<>((msg) -> {
|
||||
try {
|
||||
final GuiMessageTag tag = useMessageTag.value ? Helper.MESSAGE_TAG : null;
|
||||
Minecraft.getInstance().gui.getChat().addMessage(msg, null, tag);
|
||||
} catch (Throwable t) {
|
||||
LOGGER.warn("Failed to log message to chat: " + msg.getString(), t);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The function that is called when Baritone will send a desktop notification. This function can be added to
|
||||
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
||||
* {@link Setting#value};
|
||||
*/
|
||||
@JavaOnly
|
||||
public final Setting<BiConsumer<String, Boolean>> notifier = new Setting<>(NotificationHelper::notify);
|
||||
|
||||
/**
|
||||
@@ -1155,6 +1303,7 @@ public final class Settings {
|
||||
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
||||
* {@link Setting#value};
|
||||
*/
|
||||
@JavaOnly
|
||||
public final Setting<BiConsumer<Component, Component>> toaster = new Setting<>(BaritoneToast::addOrUpdate);
|
||||
|
||||
/**
|
||||
@@ -1287,6 +1436,120 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> notificationOnMineFail = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* The number of ticks of elytra movement to simulate while firework boost is not active. Higher values are
|
||||
* computationally more expensive.
|
||||
*/
|
||||
public final Setting<Integer> elytraSimulationTicks = new Setting<>(20);
|
||||
|
||||
/**
|
||||
* The maximum allowed deviation in pitch from a direct line-of-sight to the flight target. Higher values are
|
||||
* computationally more expensive.
|
||||
*/
|
||||
public final Setting<Integer> elytraPitchRange = new Setting<>(25);
|
||||
|
||||
/**
|
||||
* The minimum speed that the player can drop to (in blocks/tick) before a firework is automatically deployed.
|
||||
*/
|
||||
public final Setting<Double> elytraFireworkSpeed = new Setting<>(1.2);
|
||||
|
||||
/**
|
||||
* The delay after the player's position is set-back by the server that a firework may be automatically deployed.
|
||||
* Value is in ticks.
|
||||
*/
|
||||
public final Setting<Integer> elytraFireworkSetbackUseDelay = new Setting<>(15);
|
||||
|
||||
/**
|
||||
* The minimum padding value that is added to the player's hitbox when considering which point to fly to on the
|
||||
* path. High values can result in points not being considered which are otherwise safe to fly to. Low values can
|
||||
* result in flight paths which are extremely tight, and there's the possibility of crashing due to getting too low
|
||||
* to the ground.
|
||||
*/
|
||||
public final Setting<Double> elytraMinimumAvoidance = new Setting<>(0.2);
|
||||
|
||||
/**
|
||||
* If enabled, avoids using fireworks when descending along the flight path.
|
||||
*/
|
||||
public final Setting<Boolean> elytraConserveFireworks = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Renders the raytraces that are performed by the elytra fly calculation.
|
||||
*/
|
||||
public final Setting<Boolean> elytraRenderRaytraces = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Renders the raytraces that are used in the hitbox part of the elytra fly calculation.
|
||||
* Requires {@link #elytraRenderRaytraces}.
|
||||
*/
|
||||
public final Setting<Boolean> elytraRenderHitboxRaytraces = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Renders the best elytra flight path that was simulated each tick.
|
||||
*/
|
||||
public final Setting<Boolean> elytraRenderSimulation = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Automatically path to and jump off of ledges to initiate elytra flight when grounded.
|
||||
*/
|
||||
public final Setting<Boolean> elytraAutoJump = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* The seed used to generate chunks for long distance elytra path-finding in the nether.
|
||||
* Defaults to 2b2t's nether seed.
|
||||
*/
|
||||
public final Setting<Long> elytraNetherSeed = new Setting<>(146008555100680L);
|
||||
|
||||
/**
|
||||
* Whether nether-pathfinder should generate terrain based on {@link #elytraNetherSeed}.
|
||||
* If false all chunks that haven't been loaded are assumed to be air.
|
||||
*/
|
||||
public final Setting<Boolean> elytraPredictTerrain = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Automatically swap the current elytra with a new one when the durability gets too low
|
||||
*/
|
||||
public final Setting<Boolean> elytraAutoSwap = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* The minimum durability an elytra can have before being swapped
|
||||
*/
|
||||
public final Setting<Integer> elytraMinimumDurability = new Setting<>(5);
|
||||
|
||||
/**
|
||||
* The minimum fireworks before landing early for safety
|
||||
*/
|
||||
public final Setting<Integer> elytraMinFireworksBeforeLanding = new Setting<>(5);
|
||||
|
||||
/**
|
||||
* Automatically land when elytra is almost out of durability, or almost out of fireworks
|
||||
*/
|
||||
public final Setting<Boolean> elytraAllowEmergencyLand = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Time between culling far away chunks from the nether pathfinder chunk cache
|
||||
*/
|
||||
public final Setting<Long> elytraTimeBetweenCacheCullSecs = new Setting<>(TimeUnit.MINUTES.toSeconds(3));
|
||||
|
||||
/**
|
||||
* Maximum distance chunks can be before being culled from the nether pathfinder chunk cache
|
||||
*/
|
||||
public final Setting<Integer> elytraCacheCullDistance = new Setting<>(5000);
|
||||
|
||||
/**
|
||||
* Should elytra consider nether brick a valid landing block
|
||||
*/
|
||||
public final Setting<Boolean> elytraAllowLandOnNetherFortress = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Has the user read and understood the elytra terms and conditions
|
||||
*/
|
||||
public final Setting<Boolean> elytraTermsAccepted = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Verbose chat logging in elytra mode
|
||||
*/
|
||||
public final Setting<Boolean> elytraChatSpam = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* A map of lowercase setting field names to their respective setting
|
||||
*/
|
||||
@@ -1304,6 +1567,7 @@ public final class Settings {
|
||||
public T value;
|
||||
public final T defaultValue;
|
||||
private String name;
|
||||
private boolean javaOnly;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Setting(T value) {
|
||||
@@ -1312,6 +1576,7 @@ public final class Settings {
|
||||
}
|
||||
this.value = value;
|
||||
this.defaultValue = value;
|
||||
this.javaOnly = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1348,8 +1613,25 @@ public final class Settings {
|
||||
public final Type getType() {
|
||||
return settingTypes.get(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This should always be the same as whether the setting can be parsed from or serialized to a string; in other
|
||||
* words, the only way to modify it is by writing to {@link #value} programatically.
|
||||
*
|
||||
* @return {@code true} if the setting can not be set or read by the user
|
||||
*/
|
||||
public boolean isJavaOnly() {
|
||||
return javaOnly;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a {@link Setting} field as being {@link Setting#isJavaOnly() Java-only}
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
private @interface JavaOnly {}
|
||||
|
||||
// here be dragons
|
||||
|
||||
Settings() {
|
||||
@@ -1365,6 +1647,7 @@ public final class Settings {
|
||||
Setting<?> setting = (Setting<?>) field.get(this);
|
||||
String name = field.getName();
|
||||
setting.name = name;
|
||||
setting.javaOnly = field.isAnnotationPresent(JavaOnly.class);
|
||||
name = name.toLowerCase();
|
||||
if (tmpByName.containsKey(name)) {
|
||||
throw new IllegalStateException("Duplicate setting name");
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package baritone.api.behavior;
|
||||
|
||||
import baritone.api.Settings;
|
||||
import baritone.api.behavior.look.IAimProcessor;
|
||||
import baritone.api.utils.Rotation;
|
||||
|
||||
/**
|
||||
@@ -26,14 +28,23 @@ import baritone.api.utils.Rotation;
|
||||
public interface ILookBehavior extends IBehavior {
|
||||
|
||||
/**
|
||||
* Updates the current {@link ILookBehavior} target to target
|
||||
* the specified rotations on the next tick. If force is {@code true},
|
||||
* then freeLook will be overriden and angles will be set regardless.
|
||||
* If any sort of block interaction is required, force should be {@code true},
|
||||
* otherwise, it should be {@code false};
|
||||
* Updates the current {@link ILookBehavior} target to target the specified rotations on the next tick. If any sort
|
||||
* of block interaction is required, {@code blockInteract} should be {@code true}. It is not guaranteed that the
|
||||
* rotations set by the caller will be the exact rotations expressed by the client (This is due to settings like
|
||||
* {@link Settings#randomLooking}). If the rotations produced by this behavior are required, then the
|
||||
* {@link #getAimProcessor() aim processor} should be used.
|
||||
*
|
||||
* @param rotation The target rotations
|
||||
* @param force Whether or not to "force" the rotations
|
||||
* @param rotation The target rotations
|
||||
* @param blockInteract Whether the target rotations are needed for a block interaction
|
||||
*/
|
||||
void updateTarget(Rotation rotation, boolean force);
|
||||
void updateTarget(Rotation rotation, boolean blockInteract);
|
||||
|
||||
/**
|
||||
* The aim processor instance for this {@link ILookBehavior}, which is responsible for applying additional,
|
||||
* deterministic transformations to the target rotation set by {@link #updateTarget}.
|
||||
*
|
||||
* @return The aim processor
|
||||
* @see IAimProcessor#fork
|
||||
*/
|
||||
IAimProcessor getAimProcessor();
|
||||
}
|
||||
|
||||
45
src/api/java/baritone/api/behavior/look/IAimProcessor.java
Normal file
45
src/api/java/baritone/api/behavior/look/IAimProcessor.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.behavior.look;
|
||||
|
||||
import baritone.api.utils.Rotation;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public interface IAimProcessor {
|
||||
|
||||
/**
|
||||
* Returns the actual rotation that will be used when the desired rotation is requested. The returned rotation
|
||||
* always reflects what would happen in the upcoming tick. In other words, it is a pure function, and no internal
|
||||
* state changes. If simulation of the rotation states beyond the next tick is required, then a
|
||||
* {@link IAimProcessor#fork fork} should be created.
|
||||
*
|
||||
* @param desired The desired rotation to set
|
||||
* @return The actual rotation
|
||||
*/
|
||||
Rotation peekRotation(Rotation desired);
|
||||
|
||||
/**
|
||||
* Returns a copy of this {@link IAimProcessor} which has its own internal state and is manually tickable.
|
||||
*
|
||||
* @return The forked processor
|
||||
* @see ITickableAimProcessor
|
||||
*/
|
||||
ITickableAimProcessor fork();
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.behavior.look;
|
||||
|
||||
import baritone.api.utils.Rotation;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public interface ITickableAimProcessor extends IAimProcessor {
|
||||
|
||||
/**
|
||||
* Advances the internal state of this aim processor by a single tick.
|
||||
*/
|
||||
void tick();
|
||||
|
||||
/**
|
||||
* Calls {@link #tick()} the specified number of times.
|
||||
*
|
||||
* @param ticks The number of calls
|
||||
*/
|
||||
void advance(int ticks);
|
||||
|
||||
/**
|
||||
* Returns the actual rotation as provided by {@link #peekRotation(Rotation)}, and then automatically advances the
|
||||
* internal state by one {@link #tick() tick}.
|
||||
*
|
||||
* @param rotation The desired rotation to set
|
||||
* @return The actual rotation
|
||||
*/
|
||||
Rotation nextRotation(Rotation rotation);
|
||||
}
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package baritone.api.cache;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/24/2018
|
||||
@@ -29,4 +31,11 @@ public interface IWorldProvider {
|
||||
* @return The current world data
|
||||
*/
|
||||
IWorldData getCurrentWorld();
|
||||
|
||||
default void ifWorldLoaded(Consumer<IWorldData> callback) {
|
||||
final IWorldData currentWorld = this.getCurrentWorld();
|
||||
if (currentWorld != null) {
|
||||
callback.accept(currentWorld);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,13 +40,15 @@ public enum BlockById implements IDatatypeFor<Block> {
|
||||
|
||||
@Override
|
||||
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
||||
String arg = ctx.getConsumer().getString();
|
||||
|
||||
return new TabCompleteHelper()
|
||||
.append(
|
||||
BuiltInRegistries.BLOCK.keySet()
|
||||
.stream()
|
||||
.map(Object::toString)
|
||||
)
|
||||
.filterPrefixNamespaced(ctx.getConsumer().getString())
|
||||
.filterPrefixNamespaced(arg)
|
||||
.sortAlphabetically()
|
||||
.stream();
|
||||
}
|
||||
|
||||
43
src/api/java/baritone/api/command/datatypes/ForAxis.java
Normal file
43
src/api/java/baritone/api/command/datatypes/ForAxis.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.command.datatypes;
|
||||
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.helpers.TabCompleteHelper;
|
||||
import net.minecraft.core.Direction;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public enum ForAxis implements IDatatypeFor<Direction.Axis> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Direction.Axis get(IDatatypeContext ctx) throws CommandException {
|
||||
return Direction.Axis.valueOf(ctx.getConsumer().getString().toUpperCase(Locale.US));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
||||
return new TabCompleteHelper()
|
||||
.append(Stream.of(Direction.Axis.values())
|
||||
.map(Direction.Axis::getName).map(String::toLowerCase))
|
||||
.filterPrefix(ctx.getConsumer().getString())
|
||||
.stream();
|
||||
}
|
||||
}
|
||||
@@ -18,20 +18,137 @@
|
||||
package baritone.api.command.datatypes;
|
||||
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.helpers.TabCompleteHelper;
|
||||
import baritone.api.utils.BlockOptionalMeta;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public enum ForBlockOptionalMeta implements IDatatypeFor<BlockOptionalMeta> {
|
||||
INSTANCE;
|
||||
|
||||
/**
|
||||
* Matches (domain:)?name([(property=value)*])? but the input can be truncated at any position.
|
||||
* domain and name are [a-z0-9_.-]+ and [a-z0-9/_.-]+ because that's what mc 1.13+ accepts.
|
||||
* property and value use the same format as domain.
|
||||
*/
|
||||
// Good luck reading this.
|
||||
private static Pattern PATTERN = Pattern.compile("(?:[a-z0-9_.-]+:)?(?:[a-z0-9/_.-]+(?:\\[(?:(?:[a-z0-9_.-]+=[a-z0-9_.-]+,)*(?:[a-z0-9_.-]+(?:=(?:[a-z0-9_.-]+(?:\\])?)?)?)?|\\])?)?)?");
|
||||
|
||||
@Override
|
||||
public BlockOptionalMeta get(IDatatypeContext ctx) throws CommandException {
|
||||
return new BlockOptionalMeta(ctx.getConsumer().getString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> tabComplete(IDatatypeContext ctx) {
|
||||
return ctx.getConsumer().tabCompleteDatatype(BlockById.INSTANCE);
|
||||
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
||||
String arg = ctx.getConsumer().peekString();
|
||||
|
||||
if (!PATTERN.matcher(arg).matches()) {
|
||||
// Invalid format; we can't complete this.
|
||||
ctx.getConsumer().getString();
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
if (arg.endsWith("]")) {
|
||||
// We are already done.
|
||||
ctx.getConsumer().getString();
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
if (!arg.contains("[")) {
|
||||
// no properties so we are completing the block id
|
||||
return ctx.getConsumer().tabCompleteDatatype(BlockById.INSTANCE);
|
||||
}
|
||||
|
||||
ctx.getConsumer().getString();
|
||||
|
||||
// destructuring assignment? Please?
|
||||
String blockId, properties;
|
||||
{
|
||||
String[] parts = splitLast(arg, '[');
|
||||
blockId = parts[0];
|
||||
properties = parts[1];
|
||||
}
|
||||
|
||||
Block block = BuiltInRegistries.BLOCK.getOptional(new ResourceLocation(blockId)).orElse(null);
|
||||
if (block == null) {
|
||||
// This block doesn't exist so there's no properties to complete.
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
String leadingProperties, lastProperty;
|
||||
{
|
||||
String[] parts = splitLast(properties, ',');
|
||||
leadingProperties = parts[0];
|
||||
lastProperty = parts[1];
|
||||
}
|
||||
|
||||
if (!lastProperty.contains("=")) {
|
||||
// The last property-value pair doesn't have a value yet so we are completing its name
|
||||
Set<String> usedProps = Stream.of(leadingProperties.split(","))
|
||||
.map(pair -> pair.split("=")[0])
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
String prefix = arg.substring(0, arg.length() - lastProperty.length());
|
||||
return new TabCompleteHelper()
|
||||
.append(
|
||||
block.getStateDefinition()
|
||||
.getProperties()
|
||||
.stream()
|
||||
.map(Property::getName)
|
||||
)
|
||||
.filter(prop -> !usedProps.contains(prop))
|
||||
.filterPrefix(lastProperty)
|
||||
.sortAlphabetically()
|
||||
.map(prop -> prefix + prop)
|
||||
.stream();
|
||||
}
|
||||
|
||||
String lastName, lastValue;
|
||||
{
|
||||
String[] parts = splitLast(lastProperty, '=');
|
||||
lastName = parts[0];
|
||||
lastValue = parts[1];
|
||||
}
|
||||
|
||||
// We are completing the value of a property
|
||||
String prefix = arg.substring(0, arg.length() - lastValue.length());
|
||||
|
||||
Property<?> property = block.getStateDefinition().getProperty(lastName);
|
||||
if (property == null) {
|
||||
// The property does not exist so there's no values to complete
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
return new TabCompleteHelper()
|
||||
.append(getValues(property))
|
||||
.filterPrefix(lastValue)
|
||||
.sortAlphabetically()
|
||||
.map(val -> prefix + val)
|
||||
.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns exactly two strings.
|
||||
* If the separator is not found the FIRST returned string is empty.
|
||||
*/
|
||||
private static String[] splitLast(String string, char chr) {
|
||||
int idx = string.lastIndexOf(chr);
|
||||
if (idx == -1) {
|
||||
return new String[]{"", string};
|
||||
}
|
||||
return new String[]{string.substring(0, idx), string.substring(idx + 1)};
|
||||
}
|
||||
|
||||
// this shouldn't need to be a separate method?
|
||||
private static <T extends Comparable<T>> Stream<String> getValues(Property<T> property) {
|
||||
return property.getPossibleValues().stream().map(property::getName);
|
||||
}
|
||||
}
|
||||
|
||||
53
src/api/java/baritone/api/command/datatypes/ItemById.java
Normal file
53
src/api/java/baritone/api/command/datatypes/ItemById.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.command.datatypes;
|
||||
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.helpers.TabCompleteHelper;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public enum ItemById implements IDatatypeFor<Item> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Item get(IDatatypeContext ctx) throws CommandException {
|
||||
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
|
||||
Item item;
|
||||
if ((item = BuiltInRegistries.ITEM.getOptional(id).orElse(null)) == null) {
|
||||
throw new IllegalArgumentException("No item found by that id");
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
||||
return new TabCompleteHelper()
|
||||
.append(
|
||||
BuiltInRegistries.BLOCK.keySet()
|
||||
.stream()
|
||||
.map(ResourceLocation::toString)
|
||||
)
|
||||
.filterPrefixNamespaced(ctx.getConsumer().getString())
|
||||
.sortAlphabetically()
|
||||
.stream();
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@ package baritone.api.command.datatypes;
|
||||
|
||||
import baritone.api.command.argument.IArgConsumer;
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.utils.Helper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -30,8 +32,6 @@ import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static baritone.api.utils.Helper.HELPER;
|
||||
|
||||
public enum RelativeFile implements IDatatypePost<File, File> {
|
||||
INSTANCE;
|
||||
|
||||
@@ -93,8 +93,13 @@ public enum RelativeFile implements IDatatypePost<File, File> {
|
||||
.filter(s -> !s.contains(" "));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static File gameDir() {
|
||||
File gameDir = HELPER.mc.gameDirectory.getAbsoluteFile();
|
||||
return gameDir(Helper.mc);
|
||||
}
|
||||
|
||||
public static File gameDir(Minecraft mc) {
|
||||
File gameDir = mc.gameDirectory.getAbsoluteFile();
|
||||
if (gameDir.getName().equals(".")) {
|
||||
return gameDir.getParentFile();
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ package baritone.api.command.exception;
|
||||
|
||||
import baritone.api.command.ICommand;
|
||||
import baritone.api.command.argument.ICommandArgument;
|
||||
|
||||
import java.util.List;
|
||||
import net.minecraft.ChatFormatting;
|
||||
|
||||
import static baritone.api.utils.Helper.HELPER;
|
||||
|
||||
@@ -36,10 +36,6 @@ public class CommandUnhandledException extends RuntimeException implements IComm
|
||||
|
||||
@Override
|
||||
public void handle(ICommand command, List<ICommandArgument> args) {
|
||||
HELPER.logDirect("An unhandled exception occurred. " +
|
||||
"The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues",
|
||||
ChatFormatting.RED);
|
||||
|
||||
this.printStackTrace();
|
||||
HELPER.logUnhandledException(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,7 +212,12 @@ public class TabCompleteHelper {
|
||||
* @return This {@link TabCompleteHelper}
|
||||
*/
|
||||
public TabCompleteHelper filterPrefixNamespaced(String prefix) {
|
||||
return filterPrefix(new ResourceLocation(prefix).toString());
|
||||
ResourceLocation loc = ResourceLocation.tryParse(prefix);
|
||||
if (loc == null) {
|
||||
stream = Stream.empty();
|
||||
return this;
|
||||
}
|
||||
return filterPrefix(loc.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,7 +257,7 @@ public class TabCompleteHelper {
|
||||
public TabCompleteHelper addSettings() {
|
||||
return append(
|
||||
BaritoneAPI.getSettings().allSettings.stream()
|
||||
.filter(s -> !SettingsUtil.javaOnlySetting(s))
|
||||
.filter(s -> !s.isJavaOnly())
|
||||
.map(Settings.Setting::getName)
|
||||
.sorted(String.CASE_INSENSITIVE_ORDER)
|
||||
);
|
||||
|
||||
47
src/api/java/baritone/api/event/events/BlockChangeEvent.java
Normal file
47
src/api/java/baritone/api/event/events/BlockChangeEvent.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.event.events;
|
||||
|
||||
import baritone.api.utils.Pair;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class BlockChangeEvent {
|
||||
|
||||
private final ChunkPos chunk;
|
||||
private final List<Pair<BlockPos, BlockState>> blocks;
|
||||
|
||||
public BlockChangeEvent(ChunkPos pos, List<Pair<BlockPos, BlockState>> blocks) {
|
||||
this.chunk = pos;
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
public ChunkPos getChunkPos() {
|
||||
return this.chunk;
|
||||
}
|
||||
|
||||
public List<Pair<BlockPos, BlockState>> getBlocks() {
|
||||
return this.blocks;
|
||||
}
|
||||
}
|
||||
@@ -57,31 +57,38 @@ public final class ChunkEvent {
|
||||
/**
|
||||
* @return The state of the event
|
||||
*/
|
||||
public final EventState getState() {
|
||||
public EventState getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The type of chunk event that occurred;
|
||||
*/
|
||||
public final Type getType() {
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Chunk X position.
|
||||
*/
|
||||
public final int getX() {
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Chunk Z position.
|
||||
*/
|
||||
public final int getZ() {
|
||||
public int getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the event was fired after a chunk population
|
||||
*/
|
||||
public boolean isPostPopulate() {
|
||||
return this.state == EventState.POST && this.type.isPopulate();
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
|
||||
/**
|
||||
@@ -106,6 +113,10 @@ public final class ChunkEvent {
|
||||
* <p>
|
||||
* And it's a partial chunk
|
||||
*/
|
||||
POPULATE_PARTIAL
|
||||
POPULATE_PARTIAL;
|
||||
|
||||
public final boolean isPopulate() {
|
||||
return this == POPULATE_FULL || this == POPULATE_PARTIAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package baritone.api.event.events;
|
||||
|
||||
import baritone.api.utils.Rotation;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
@@ -32,14 +33,27 @@ public final class RotationMoveEvent {
|
||||
*/
|
||||
private final Type type;
|
||||
|
||||
private final Rotation original;
|
||||
|
||||
/**
|
||||
* The yaw rotation
|
||||
*/
|
||||
private float yaw;
|
||||
|
||||
public RotationMoveEvent(Type type, float yaw) {
|
||||
/**
|
||||
* The pitch rotation
|
||||
*/
|
||||
private float pitch;
|
||||
|
||||
public RotationMoveEvent(Type type, float yaw, float pitch) {
|
||||
this.type = type;
|
||||
this.original = new Rotation(yaw, pitch);
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
public Rotation getOriginal() {
|
||||
return this.original;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,21 +61,37 @@ public final class RotationMoveEvent {
|
||||
*
|
||||
* @param yaw Yaw rotation
|
||||
*/
|
||||
public final void setYaw(float yaw) {
|
||||
public void setYaw(float yaw) {
|
||||
this.yaw = yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The yaw rotation
|
||||
*/
|
||||
public final float getYaw() {
|
||||
public float getYaw() {
|
||||
return this.yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the pitch movement rotation
|
||||
*
|
||||
* @param pitch Pitch rotation
|
||||
*/
|
||||
public void setPitch(float pitch) {
|
||||
this.pitch = pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The pitch rotation
|
||||
*/
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The type of the event
|
||||
*/
|
||||
public final Type getType() {
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,18 @@
|
||||
package baritone.api.event.events;
|
||||
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* Called on and after each game tick of the primary {@link Minecraft} instance and dispatched to all Baritone
|
||||
* instances.
|
||||
* <p>
|
||||
* When {@link #state} is {@link EventState#PRE}, the event is being called just prior to when the current in-game
|
||||
* screen is ticked. When {@link #state} is {@link EventState#POST}, the event is being called at the very end
|
||||
* of the {@link Minecraft#runTick()} method.
|
||||
*/
|
||||
public final class TickEvent {
|
||||
|
||||
private static int overallTickCount;
|
||||
|
||||
@@ -33,6 +33,9 @@ public interface AbstractGameEventListener extends IGameEventListener {
|
||||
@Override
|
||||
default void onTick(TickEvent event) {}
|
||||
|
||||
@Override
|
||||
default void onPostTick(TickEvent event) {}
|
||||
|
||||
@Override
|
||||
default void onPlayerUpdate(PlayerUpdateEvent event) {}
|
||||
|
||||
@@ -45,6 +48,9 @@ public interface AbstractGameEventListener extends IGameEventListener {
|
||||
@Override
|
||||
default void onChunkEvent(ChunkEvent event) {}
|
||||
|
||||
@Override
|
||||
default void onBlockChange(BlockChangeEvent event) {}
|
||||
|
||||
@Override
|
||||
default void onRenderPass(RenderEvent event) {}
|
||||
|
||||
|
||||
@@ -40,6 +40,14 @@ public interface IGameEventListener {
|
||||
*/
|
||||
void onTick(TickEvent event);
|
||||
|
||||
/**
|
||||
* Run once per game tick after the tick is completed
|
||||
*
|
||||
* @param event The event
|
||||
* @see Minecraft#runTick()
|
||||
*/
|
||||
void onPostTick(TickEvent event);
|
||||
|
||||
/**
|
||||
* Run once per game tick from before and after the player rotation is sent to the server.
|
||||
*
|
||||
@@ -70,6 +78,13 @@ public interface IGameEventListener {
|
||||
*/
|
||||
void onChunkEvent(ChunkEvent event);
|
||||
|
||||
/**
|
||||
* Runs after a single or multi block change packet is received and processed.
|
||||
*
|
||||
* @param event The event
|
||||
*/
|
||||
void onBlockChange(BlockChangeEvent event);
|
||||
|
||||
/**
|
||||
* Runs once per world render pass.
|
||||
*
|
||||
|
||||
@@ -42,6 +42,16 @@ public class GoalAxis implements Goal {
|
||||
return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.value + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.value, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o.getClass() == GoalAxis.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 201385781;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GoalAxis";
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package baritone.api.pathing.goals;
|
||||
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -66,6 +67,26 @@ public class GoalBlock implements Goal, IGoalRenderPos {
|
||||
return calculate(xDiff, yDiff, zDiff);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GoalBlock goal = (GoalBlock) o;
|
||||
return x == goal.x
|
||||
&& y == goal.y
|
||||
&& z == goal.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int) BetterBlockPos.longHash(x, y, z) * 905165533;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
|
||||
@@ -67,6 +67,24 @@ public class GoalComposite implements Goal {
|
||||
return min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GoalComposite goal = (GoalComposite) o;
|
||||
return Arrays.equals(goals, goal.goals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(goals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GoalComposite" + Arrays.toString(goals);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package baritone.api.pathing.goals;
|
||||
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -60,6 +61,26 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
|
||||
return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GoalGetToBlock goal = (GoalGetToBlock) o;
|
||||
return x == goal.x
|
||||
&& y == goal.y
|
||||
&& z == goal.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int) BetterBlockPos.longHash(x, y, z) * -49639096;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
package baritone.api.pathing.goals;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Invert any goal.
|
||||
* <p>
|
||||
@@ -50,6 +52,24 @@ public class GoalInverted implements Goal {
|
||||
return Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GoalInverted goal = (GoalInverted) o;
|
||||
return Objects.equals(origin, goal.origin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return origin.hashCode() * 495796690;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("GoalInverted{%s}", origin.toString());
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package baritone.api.pathing.goals;
|
||||
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
|
||||
@@ -86,6 +87,27 @@ public class GoalNear implements Goal, IGoalRenderPos {
|
||||
return new BlockPos(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GoalNear goal = (GoalNear) o;
|
||||
return x == goal.x
|
||||
&& y == goal.y
|
||||
&& z == goal.z
|
||||
&& rangeSq == goal.rangeSq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int) BetterBlockPos.longHash(x, y, z) + rangeSq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
|
||||
@@ -23,6 +23,7 @@ import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Useful for automated combat (retreating specifically)
|
||||
@@ -43,7 +44,7 @@ public class GoalRunAway implements Goal {
|
||||
|
||||
public GoalRunAway(double distance, Integer maintainY, BlockPos... from) {
|
||||
if (from.length == 0) {
|
||||
throw new IllegalArgumentException();
|
||||
throw new IllegalArgumentException("Positions to run away from must not be empty");
|
||||
}
|
||||
this.from = from;
|
||||
this.distanceSq = (int) (distance * distance);
|
||||
@@ -124,6 +125,29 @@ public class GoalRunAway implements Goal {
|
||||
return maxInside;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GoalRunAway goal = (GoalRunAway) o;
|
||||
return distanceSq == goal.distanceSq
|
||||
&& Arrays.equals(from, goal.from)
|
||||
&& Objects.equals(maintainY, goal.maintainY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = Arrays.hashCode(from);
|
||||
hash = hash * 1196803141 + distanceSq;
|
||||
hash = hash * -2053788840 + maintainY;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (maintainY != null) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package baritone.api.pathing.goals;
|
||||
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
@@ -69,6 +70,31 @@ public class GoalStrictDirection implements Goal {
|
||||
return Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GoalStrictDirection goal = (GoalStrictDirection) o;
|
||||
return x == goal.x
|
||||
&& y == goal.y
|
||||
&& z == goal.z
|
||||
&& dx == goal.dx
|
||||
&& dz == goal.dz;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = (int) BetterBlockPos.longHash(x, y, z);
|
||||
hash = hash * 630627507 + dx;
|
||||
hash = hash * -283028380 + dz;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package baritone.api.pathing.goals;
|
||||
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -72,6 +73,26 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
|
||||
return new BlockPos(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GoalTwoBlocks goal = (GoalTwoBlocks) o;
|
||||
return x == goal.x
|
||||
&& y == goal.y
|
||||
&& z == goal.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (int) BetterBlockPos.longHash(x, y, z) * 516508351;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
|
||||
@@ -64,6 +64,27 @@ public class GoalXZ implements Goal {
|
||||
return calculate(xDiff, zDiff);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GoalXZ goal = (GoalXZ) o;
|
||||
return x == goal.x && z == goal.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 1791873246;
|
||||
hash = hash * 222601791 + x;
|
||||
hash = hash * -1331679453 + z;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
|
||||
@@ -58,6 +58,24 @@ public class GoalYLevel implements Goal, ActionCosts {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GoalYLevel goal = (GoalYLevel) o;
|
||||
return level == goal.level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return level * 1271009915;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
|
||||
@@ -24,6 +24,7 @@ import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
@@ -50,6 +51,7 @@ public interface IBuilderProcess extends IBaritoneProcess {
|
||||
*/
|
||||
boolean build(String name, File schematic, Vec3i origin);
|
||||
|
||||
@Deprecated
|
||||
default boolean build(String schematicFile, BlockPos origin) {
|
||||
File file = new File(new File(Minecraft.getInstance().gameDirectory, "schematics"), schematicFile);
|
||||
return build(schematicFile, file, origin);
|
||||
@@ -73,4 +75,17 @@ public interface IBuilderProcess extends IBaritoneProcess {
|
||||
* cause it to give up. This is updated every tick, but only while the builder process is active.
|
||||
*/
|
||||
List<BlockState> getApproxPlaceable();
|
||||
/**
|
||||
* Returns the lower bound of the current mining layer if mineInLayers is true.
|
||||
* If mineInLayers is false, this will return an empty optional.
|
||||
* @return The lower bound of the current mining layer
|
||||
*/
|
||||
Optional<Integer> getMinLayer();
|
||||
|
||||
/**
|
||||
* Returns the upper bound of the current mining layer if mineInLayers is true.
|
||||
* If mineInLayers is false, this will return an empty optional.
|
||||
* @return The upper bound of the current mining layer
|
||||
*/
|
||||
Optional<Integer> getMaxLayer();
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@ public interface ICustomGoalProcess extends IBaritoneProcess {
|
||||
*/
|
||||
Goal getGoal();
|
||||
|
||||
/**
|
||||
* @return The most recent set goal, which doesn't invalidate upon {@link #onLostControl()}
|
||||
*/
|
||||
Goal mostRecentGoal();
|
||||
|
||||
/**
|
||||
* Sets the goal and begins the path execution.
|
||||
*
|
||||
|
||||
50
src/api/java/baritone/api/process/IElytraProcess.java
Normal file
50
src/api/java/baritone/api/process/IElytraProcess.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.process;
|
||||
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
public interface IElytraProcess extends IBaritoneProcess {
|
||||
|
||||
void repackChunks();
|
||||
|
||||
/**
|
||||
* @return Where it is currently flying to, null if not active
|
||||
*/
|
||||
BlockPos currentDestination();
|
||||
|
||||
void pathTo(BlockPos destination);
|
||||
|
||||
void pathTo(Goal destination);
|
||||
|
||||
/**
|
||||
* Resets the state of the process but will maintain the same destination and will try to keep flying
|
||||
*/
|
||||
void resetState();
|
||||
|
||||
/**
|
||||
* @return {@code true} if the native library loaded and elytra is actually usable
|
||||
*/
|
||||
boolean isLoaded();
|
||||
|
||||
/*
|
||||
* FOR INTERNAL USE ONLY. MAY BE REMOVED AT ANY TIME.
|
||||
*/
|
||||
boolean isSafeToCancel();
|
||||
}
|
||||
@@ -17,9 +17,11 @@
|
||||
|
||||
package baritone.api.process;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
@@ -34,6 +36,13 @@ public interface IFollowProcess extends IBaritoneProcess {
|
||||
*/
|
||||
void follow(Predicate<Entity> filter);
|
||||
|
||||
/**
|
||||
* Try to pick up any items matching this predicate
|
||||
*
|
||||
* @param filter the predicate
|
||||
*/
|
||||
void pickup(Predicate<ItemStack> filter);
|
||||
|
||||
/**
|
||||
* @return The entities that are currently being followed. null if not currently following, empty if nothing matches the predicate
|
||||
*/
|
||||
|
||||
@@ -56,5 +56,10 @@ public enum PathingCommandType {
|
||||
/**
|
||||
* Go and ask the next process what to do
|
||||
*/
|
||||
DEFER
|
||||
DEFER,
|
||||
|
||||
/**
|
||||
* Sets the goal and calculates a path, but pauses instead of immediately starting the path.
|
||||
*/
|
||||
SET_GOAL_AND_PAUSE
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import baritone.api.command.registry.Registry;
|
||||
import baritone.api.schematic.format.ISchematicFormat;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@@ -41,4 +42,9 @@ public interface ISchematicSystem {
|
||||
* @return The corresponding format for the file, {@link Optional#empty()} if no candidates were found.
|
||||
*/
|
||||
Optional<ISchematicFormat> getByFile(File file);
|
||||
|
||||
/**
|
||||
* @return A list of file extensions used by supported formats
|
||||
*/
|
||||
List<String> getFileExtensions();
|
||||
}
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
|
||||
package baritone.api.schematic;
|
||||
|
||||
import java.util.List;
|
||||
import baritone.api.schematic.mask.Mask;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class MaskSchematic extends AbstractSchematic {
|
||||
|
||||
private final ISchematic schematic;
|
||||
@@ -40,4 +42,14 @@ public abstract class MaskSchematic extends AbstractSchematic {
|
||||
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
|
||||
return schematic.desiredState(x, y, z, current, approxPlaceable);
|
||||
}
|
||||
|
||||
public static MaskSchematic create(ISchematic schematic, Mask function) {
|
||||
return new MaskSchematic(schematic) {
|
||||
|
||||
@Override
|
||||
protected boolean partOfMask(int x, int y, int z, BlockState currentState) {
|
||||
return function.partOfMask(x, y, z, currentState);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
114
src/api/java/baritone/api/schematic/MirroredSchematic.java
Normal file
114
src/api/java/baritone/api/schematic/MirroredSchematic.java
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.schematic;
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MirroredSchematic implements ISchematic {
|
||||
|
||||
private final ISchematic schematic;
|
||||
private final Mirror mirror;
|
||||
|
||||
public MirroredSchematic(ISchematic schematic, Mirror mirror) {
|
||||
this.schematic = schematic;
|
||||
this.mirror = mirror;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inSchematic(int x, int y, int z, BlockState currentState) {
|
||||
return schematic.inSchematic(
|
||||
mirrorX(x, widthX(), mirror),
|
||||
y,
|
||||
mirrorZ(z, lengthZ(), mirror),
|
||||
mirror(currentState, mirror)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
|
||||
return mirror(schematic.desiredState(
|
||||
mirrorX(x, widthX(), mirror),
|
||||
y,
|
||||
mirrorZ(z, lengthZ(), mirror),
|
||||
mirror(current, mirror),
|
||||
mirror(approxPlaceable, mirror)
|
||||
), mirror);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
schematic.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int widthX() {
|
||||
return schematic.widthX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int heightY() {
|
||||
return schematic.heightY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lengthZ() {
|
||||
return schematic.lengthZ();
|
||||
}
|
||||
|
||||
private static int mirrorX(int x, int sizeX, Mirror mirror) {
|
||||
switch (mirror) {
|
||||
case NONE:
|
||||
case LEFT_RIGHT:
|
||||
return x;
|
||||
case FRONT_BACK:
|
||||
return sizeX - x - 1;
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown mirror");
|
||||
}
|
||||
|
||||
private static int mirrorZ(int z, int sizeZ, Mirror mirror) {
|
||||
switch (mirror) {
|
||||
case NONE:
|
||||
case FRONT_BACK:
|
||||
return z;
|
||||
case LEFT_RIGHT:
|
||||
return sizeZ - z - 1;
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown mirror");
|
||||
}
|
||||
|
||||
private static BlockState mirror(BlockState state, Mirror mirror) {
|
||||
if (state == null) {
|
||||
return null;
|
||||
}
|
||||
return state.mirror(mirror);
|
||||
}
|
||||
|
||||
private static List<BlockState> mirror(List<BlockState> states, Mirror mirror) {
|
||||
if (states == null) {
|
||||
return null;
|
||||
}
|
||||
return states.stream()
|
||||
.map(s -> mirror(s, mirror))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
136
src/api/java/baritone/api/schematic/RotatedSchematic.java
Normal file
136
src/api/java/baritone/api/schematic/RotatedSchematic.java
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.schematic;
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class RotatedSchematic implements ISchematic {
|
||||
|
||||
private final ISchematic schematic;
|
||||
private final Rotation rotation;
|
||||
private final Rotation inverseRotation;
|
||||
|
||||
public RotatedSchematic(ISchematic schematic, Rotation rotation) {
|
||||
this.schematic = schematic;
|
||||
this.rotation = rotation;
|
||||
// I don't think a 14 line switch would improve readability
|
||||
this.inverseRotation = rotation.getRotated(rotation).getRotated(rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inSchematic(int x, int y, int z, BlockState currentState) {
|
||||
return schematic.inSchematic(
|
||||
rotateX(x, z, widthX(), lengthZ(), inverseRotation),
|
||||
y,
|
||||
rotateZ(x, z, widthX(), lengthZ(), inverseRotation),
|
||||
rotate(currentState, inverseRotation)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState desiredState(int x, int y, int z, BlockState current, List<BlockState> approxPlaceable) {
|
||||
return rotate(schematic.desiredState(
|
||||
rotateX(x, z, widthX(), lengthZ(), inverseRotation),
|
||||
y,
|
||||
rotateZ(x, z, widthX(), lengthZ(), inverseRotation),
|
||||
rotate(current, inverseRotation),
|
||||
rotate(approxPlaceable, inverseRotation)
|
||||
), rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
schematic.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int widthX() {
|
||||
return flipsCoordinates(rotation) ? schematic.lengthZ() : schematic.widthX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int heightY() {
|
||||
return schematic.heightY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lengthZ() {
|
||||
return flipsCoordinates(rotation) ? schematic.widthX() : schematic.lengthZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wether {@code rotation} swaps the x and z components
|
||||
*/
|
||||
private static boolean flipsCoordinates(Rotation rotation) {
|
||||
return rotation == Rotation.CLOCKWISE_90 || rotation == Rotation.COUNTERCLOCKWISE_90;
|
||||
}
|
||||
|
||||
/**
|
||||
* The x component of x,y after applying the rotation
|
||||
*/
|
||||
private static int rotateX(int x, int z, int sizeX, int sizeZ, Rotation rotation) {
|
||||
switch (rotation) {
|
||||
case NONE:
|
||||
return x;
|
||||
case CLOCKWISE_90:
|
||||
return sizeZ - z - 1;
|
||||
case CLOCKWISE_180:
|
||||
return sizeX - x - 1;
|
||||
case COUNTERCLOCKWISE_90:
|
||||
return z;
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown rotation");
|
||||
}
|
||||
|
||||
/**
|
||||
* The z component of x,y after applying the rotation
|
||||
*/
|
||||
private static int rotateZ(int x, int z, int sizeX, int sizeZ, Rotation rotation) {
|
||||
switch (rotation) {
|
||||
case NONE:
|
||||
return z;
|
||||
case CLOCKWISE_90:
|
||||
return x;
|
||||
case CLOCKWISE_180:
|
||||
return sizeZ - z - 1;
|
||||
case COUNTERCLOCKWISE_90:
|
||||
return sizeX - x - 1;
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown rotation");
|
||||
}
|
||||
|
||||
private static BlockState rotate(BlockState state, Rotation rotation) {
|
||||
if (state == null) {
|
||||
return null;
|
||||
}
|
||||
return state.rotate(rotation);
|
||||
}
|
||||
|
||||
private static List<BlockState> rotate(List<BlockState> states, Rotation rotation) {
|
||||
if (states == null) {
|
||||
return null;
|
||||
}
|
||||
return states.stream()
|
||||
.map(s -> rotate(s, rotation))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import baritone.api.schematic.IStaticSchematic;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The base of a {@link ISchematic} file format
|
||||
@@ -42,4 +43,9 @@ public interface ISchematicFormat {
|
||||
* @return Whether or not the specified file matches this schematic format
|
||||
*/
|
||||
boolean isFileType(File file);
|
||||
|
||||
/**
|
||||
* @return A list of file extensions used by this format
|
||||
*/
|
||||
List<String> getFileExtensions();
|
||||
}
|
||||
|
||||
49
src/api/java/baritone/api/schematic/mask/AbstractMask.java
Normal file
49
src/api/java/baritone/api/schematic/mask/AbstractMask.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.schematic.mask;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public abstract class AbstractMask implements Mask {
|
||||
|
||||
private final int widthX;
|
||||
private final int heightY;
|
||||
private final int lengthZ;
|
||||
|
||||
public AbstractMask(int widthX, int heightY, int lengthZ) {
|
||||
this.widthX = widthX;
|
||||
this.heightY = heightY;
|
||||
this.lengthZ = lengthZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int widthX() {
|
||||
return this.widthX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int heightY() {
|
||||
return this.heightY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lengthZ() {
|
||||
return this.lengthZ;
|
||||
}
|
||||
}
|
||||
60
src/api/java/baritone/api/schematic/mask/Mask.java
Normal file
60
src/api/java/baritone/api/schematic/mask/Mask.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.schematic.mask;
|
||||
|
||||
import baritone.api.schematic.mask.operator.BinaryOperatorMask;
|
||||
import baritone.api.schematic.mask.operator.NotMask;
|
||||
import baritone.api.utils.BooleanBinaryOperators;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public interface Mask {
|
||||
|
||||
/**
|
||||
* @param x The relative x position of the block
|
||||
* @param y The relative y position of the block
|
||||
* @param z The relative z position of the block
|
||||
* @param currentState The current state of that block in the world, may be {@code null}
|
||||
* @return Whether the given position is included in this mask
|
||||
*/
|
||||
boolean partOfMask(int x, int y, int z, BlockState currentState);
|
||||
|
||||
int widthX();
|
||||
|
||||
int heightY();
|
||||
|
||||
int lengthZ();
|
||||
|
||||
default Mask not() {
|
||||
return new NotMask(this);
|
||||
}
|
||||
|
||||
default Mask union(Mask other) {
|
||||
return new BinaryOperatorMask(this, other, BooleanBinaryOperators.OR);
|
||||
}
|
||||
|
||||
default Mask intersection(Mask other) {
|
||||
return new BinaryOperatorMask(this, other, BooleanBinaryOperators.AND);
|
||||
}
|
||||
|
||||
default Mask xor(Mask other) {
|
||||
return new BinaryOperatorMask(this, other, BooleanBinaryOperators.XOR);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.schematic.mask;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
final class PreComputedMask extends AbstractMask implements StaticMask {
|
||||
|
||||
private final boolean[][][] mask;
|
||||
|
||||
public PreComputedMask(StaticMask mask) {
|
||||
super(mask.widthX(), mask.heightY(), mask.lengthZ());
|
||||
|
||||
this.mask = new boolean[this.heightY()][this.lengthZ()][this.widthX()];
|
||||
for (int y = 0; y < this.heightY(); y++) {
|
||||
for (int z = 0; z < this.lengthZ(); z++) {
|
||||
for (int x = 0; x < this.widthX(); x++) {
|
||||
this.mask[y][z][x] = mask.partOfMask(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean partOfMask(int x, int y, int z) {
|
||||
return this.mask[y][z][x];
|
||||
}
|
||||
}
|
||||
82
src/api/java/baritone/api/schematic/mask/StaticMask.java
Normal file
82
src/api/java/baritone/api/schematic/mask/StaticMask.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.schematic.mask;
|
||||
|
||||
import baritone.api.schematic.mask.operator.BinaryOperatorMask;
|
||||
import baritone.api.schematic.mask.operator.NotMask;
|
||||
import baritone.api.utils.BooleanBinaryOperators;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* A mask that is context-free. In other words, it doesn't require the current block state to determine if a relative
|
||||
* position is a part of the mask.
|
||||
*
|
||||
* @author Brady
|
||||
*/
|
||||
public interface StaticMask extends Mask {
|
||||
|
||||
/**
|
||||
* Determines if a given relative coordinate is included in this mask, without the need for the current block state.
|
||||
*
|
||||
* @param x The relative x position of the block
|
||||
* @param y The relative y position of the block
|
||||
* @param z The relative z position of the block
|
||||
* @return Whether the given position is included in this mask
|
||||
*/
|
||||
boolean partOfMask(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Implements the parent {@link Mask#partOfMask partOfMask function} by calling the static function
|
||||
* provided in this functional interface without needing the {@link BlockState} argument. This {@code default}
|
||||
* implementation should <b><u>NOT</u></b> be overriden.
|
||||
*
|
||||
* @param x The relative x position of the block
|
||||
* @param y The relative y position of the block
|
||||
* @param z The relative z position of the block
|
||||
* @param currentState The current state of that block in the world, may be {@code null}
|
||||
* @return Whether the given position is included in this mask
|
||||
*/
|
||||
@Override
|
||||
default boolean partOfMask(int x, int y, int z, BlockState currentState) {
|
||||
return this.partOfMask(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
default StaticMask not() {
|
||||
return new NotMask.Static(this);
|
||||
}
|
||||
|
||||
default StaticMask union(StaticMask other) {
|
||||
return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.OR);
|
||||
}
|
||||
|
||||
default StaticMask intersection(StaticMask other) {
|
||||
return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.AND);
|
||||
}
|
||||
|
||||
default StaticMask xor(StaticMask other) {
|
||||
return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.XOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pre-computed mask using {@code this} function, with the specified size parameters.
|
||||
*/
|
||||
default StaticMask compute() {
|
||||
return new PreComputedMask(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.schematic.mask.operator;
|
||||
|
||||
import baritone.api.schematic.mask.AbstractMask;
|
||||
import baritone.api.schematic.mask.Mask;
|
||||
import baritone.api.schematic.mask.StaticMask;
|
||||
import baritone.api.utils.BooleanBinaryOperator;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class BinaryOperatorMask extends AbstractMask {
|
||||
|
||||
private final Mask a;
|
||||
private final Mask b;
|
||||
private final BooleanBinaryOperator operator;
|
||||
|
||||
public BinaryOperatorMask(Mask a, Mask b, BooleanBinaryOperator operator) {
|
||||
super(Math.max(a.widthX(), b.widthX()), Math.max(a.heightY(), b.heightY()), Math.max(a.lengthZ(), b.lengthZ()));
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean partOfMask(int x, int y, int z, BlockState currentState) {
|
||||
return this.operator.applyAsBoolean(
|
||||
partOfMask(a, x, y, z, currentState),
|
||||
partOfMask(b, x, y, z, currentState)
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean partOfMask(Mask mask, int x, int y, int z, BlockState currentState) {
|
||||
return x < mask.widthX() && y < mask.heightY() && z < mask.lengthZ() && mask.partOfMask(x, y, z, currentState);
|
||||
}
|
||||
|
||||
public static final class Static extends AbstractMask implements StaticMask {
|
||||
|
||||
private final StaticMask a;
|
||||
private final StaticMask b;
|
||||
private final BooleanBinaryOperator operator;
|
||||
|
||||
public Static(StaticMask a, StaticMask b, BooleanBinaryOperator operator) {
|
||||
super(Math.max(a.widthX(), b.widthX()), Math.max(a.heightY(), b.heightY()), Math.max(a.lengthZ(), b.lengthZ()));
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean partOfMask(int x, int y, int z) {
|
||||
return this.operator.applyAsBoolean(
|
||||
partOfMask(a, x, y, z),
|
||||
partOfMask(b, x, y, z)
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean partOfMask(StaticMask mask, int x, int y, int z) {
|
||||
return x < mask.widthX() && y < mask.heightY() && z < mask.lengthZ() && mask.partOfMask(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.schematic.mask.operator;
|
||||
|
||||
import baritone.api.schematic.mask.AbstractMask;
|
||||
import baritone.api.schematic.mask.Mask;
|
||||
import baritone.api.schematic.mask.StaticMask;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class NotMask extends AbstractMask {
|
||||
|
||||
private final Mask source;
|
||||
|
||||
public NotMask(Mask source) {
|
||||
super(source.widthX(), source.heightY(), source.lengthZ());
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean partOfMask(int x, int y, int z, BlockState currentState) {
|
||||
return !this.source.partOfMask(x, y, z, currentState);
|
||||
}
|
||||
|
||||
public static final class Static extends AbstractMask implements StaticMask {
|
||||
|
||||
private final StaticMask source;
|
||||
|
||||
public Static(StaticMask source) {
|
||||
super(source.widthX(), source.heightY(), source.lengthZ());
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean partOfMask(int x, int y, int z) {
|
||||
return !this.source.partOfMask(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.schematic.mask.shape;
|
||||
|
||||
import baritone.api.schematic.mask.AbstractMask;
|
||||
import baritone.api.schematic.mask.StaticMask;
|
||||
import net.minecraft.core.Direction;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class CylinderMask extends AbstractMask implements StaticMask {
|
||||
|
||||
private final double centerA;
|
||||
private final double centerB;
|
||||
private final double radiusSqA;
|
||||
private final double radiusSqB;
|
||||
private final boolean filled;
|
||||
private final Direction.Axis alignment;
|
||||
|
||||
public CylinderMask(int widthX, int heightY, int lengthZ, boolean filled, Direction.Axis alignment) {
|
||||
super(widthX, heightY, lengthZ);
|
||||
this.centerA = this.getA(widthX, heightY, alignment) / 2.0;
|
||||
this.centerB = this.getB(heightY, lengthZ, alignment) / 2.0;
|
||||
this.radiusSqA = (this.centerA - 1) * (this.centerA - 1);
|
||||
this.radiusSqB = (this.centerB - 1) * (this.centerB - 1);
|
||||
this.filled = filled;
|
||||
this.alignment = alignment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean partOfMask(int x, int y, int z) {
|
||||
double da = Math.abs((this.getA(x, y, this.alignment) + 0.5) - this.centerA);
|
||||
double db = Math.abs((this.getB(y, z, this.alignment) + 0.5) - this.centerB);
|
||||
if (this.outside(da, db)) {
|
||||
return false;
|
||||
}
|
||||
return this.filled
|
||||
|| this.outside(da + 1, db)
|
||||
|| this.outside(da, db + 1);
|
||||
}
|
||||
|
||||
private boolean outside(double da, double db) {
|
||||
return da * da / this.radiusSqA + db * db / this.radiusSqB > 1;
|
||||
}
|
||||
|
||||
private static int getA(int x, int y, Direction.Axis alignment) {
|
||||
return alignment == Direction.Axis.X ? y : x;
|
||||
}
|
||||
|
||||
private static int getB(int y, int z, Direction.Axis alignment) {
|
||||
return alignment == Direction.Axis.Z ? y : z;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.schematic.mask.shape;
|
||||
|
||||
import baritone.api.schematic.mask.AbstractMask;
|
||||
import baritone.api.schematic.mask.StaticMask;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class SphereMask extends AbstractMask implements StaticMask {
|
||||
|
||||
private final double centerX;
|
||||
private final double centerY;
|
||||
private final double centerZ;
|
||||
private final double radiusSqX;
|
||||
private final double radiusSqY;
|
||||
private final double radiusSqZ;
|
||||
private final boolean filled;
|
||||
|
||||
public SphereMask(int widthX, int heightY, int lengthZ, boolean filled) {
|
||||
super(widthX, heightY, lengthZ);
|
||||
this.centerX = widthX / 2.0;
|
||||
this.centerY = heightY / 2.0;
|
||||
this.centerZ = lengthZ / 2.0;
|
||||
this.radiusSqX = this.centerX * this.centerX;
|
||||
this.radiusSqY = this.centerY * this.centerY;
|
||||
this.radiusSqZ = this.centerZ * this.centerZ;
|
||||
this.filled = filled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean partOfMask(int x, int y, int z) {
|
||||
double dx = Math.abs((x + 0.5) - this.centerX);
|
||||
double dy = Math.abs((y + 0.5) - this.centerY);
|
||||
double dz = Math.abs((z + 0.5) - this.centerZ);
|
||||
if (this.outside(dx, dy, dz)) {
|
||||
return false;
|
||||
}
|
||||
return this.filled
|
||||
|| this.outside(dx + 1, dy, dz)
|
||||
|| this.outside(dx, dy + 1, dz)
|
||||
|| this.outside(dx, dy, dz + 1);
|
||||
}
|
||||
|
||||
private boolean outside(double dx, double dy, double dz) {
|
||||
return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1;
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,15 @@ import net.minecraft.util.Mth;
|
||||
*/
|
||||
public final class BetterBlockPos extends BlockPos {
|
||||
|
||||
private static final int NUM_X_BITS = 26;
|
||||
private static final int NUM_Z_BITS = NUM_X_BITS;
|
||||
private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS;
|
||||
private static final int Y_SHIFT = NUM_Z_BITS;
|
||||
private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS;
|
||||
private static final long X_MASK = (1L << NUM_X_BITS) - 1L;
|
||||
private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L;
|
||||
private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L;
|
||||
|
||||
public static final BetterBlockPos ORIGIN = new BetterBlockPos(0, 0, 0);
|
||||
|
||||
public final int x;
|
||||
@@ -201,6 +210,20 @@ public final class BetterBlockPos extends BlockPos {
|
||||
return amt == 0 ? this : new BetterBlockPos(x - amt, y, z);
|
||||
}
|
||||
|
||||
public double distanceSq(final BetterBlockPos to) {
|
||||
double dx = (double) this.x - to.x;
|
||||
double dy = (double) this.y - to.y;
|
||||
double dz = (double) this.z - to.z;
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
public double distanceTo(final BetterBlockPos to) {
|
||||
double dx = (double) this.x - to.x;
|
||||
double dy = (double) this.y - to.y;
|
||||
double dz = (double) this.z - to.z;
|
||||
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public String toString() {
|
||||
@@ -211,4 +234,15 @@ public final class BetterBlockPos extends BlockPos {
|
||||
SettingsUtil.maybeCensor(z)
|
||||
);
|
||||
}
|
||||
|
||||
public static long serializeToLong(final int x, final int y, final int z) {
|
||||
return ((long) x & X_MASK) << X_SHIFT | ((long) y & Y_MASK) << Y_SHIFT | ((long) z & Z_MASK);
|
||||
}
|
||||
|
||||
public static BetterBlockPos deserializeFromLong(final long serialized) {
|
||||
final int x = (int) (serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS);
|
||||
final int y = (int) (serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS);
|
||||
final int z = (int) (serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS);
|
||||
return new BetterBlockPos(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.api.utils.accessor.IItemStack;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import io.netty.util.concurrent.ThreadPerTaskExecutor;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -27,12 +28,13 @@ import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.server.packs.*;
|
||||
import net.minecraft.server.packs.PackType;
|
||||
import net.minecraft.server.packs.VanillaPackResources;
|
||||
import net.minecraft.server.packs.repository.ServerPacksSource;
|
||||
import net.minecraft.server.packs.resources.MultiPackResourceManager;
|
||||
import net.minecraft.server.packs.resources.ReloadableResourceManager;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.RandomSequences;
|
||||
import net.minecraft.world.flag.FeatureFlagSet;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
@@ -40,63 +42,99 @@ import net.minecraft.world.level.CustomSpawner;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.LootTables;
|
||||
import net.minecraft.world.level.storage.loot.PredicateManager;
|
||||
import net.minecraft.world.level.storage.loot.LootDataManager;
|
||||
import net.minecraft.world.level.storage.loot.LootParams;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.regex.MatchResult;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class BlockOptionalMeta {
|
||||
// id or id[] or id[properties] where id and properties are any text with at least one character
|
||||
private static final Pattern PATTERN = Pattern.compile("^(?<id>.+?)(?:\\[(?<properties>.+?)?\\])?$");
|
||||
|
||||
private final Block block;
|
||||
private final String propertiesDescription; // exists so toString() can return something more useful than a list of all blockstates
|
||||
private final Set<BlockState> blockstates;
|
||||
private final ImmutableSet<Integer> stateHashes;
|
||||
private final ImmutableSet<Integer> stackHashes;
|
||||
private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$");
|
||||
private static LootTables lootTables;
|
||||
private static PredicateManager predicate = new PredicateManager();
|
||||
private static LootDataManager lootTables;
|
||||
private static Map<Block, List<Item>> drops = new HashMap<>();
|
||||
|
||||
public BlockOptionalMeta(@Nonnull Block block) {
|
||||
this.block = block;
|
||||
this.blockstates = getStates(block);
|
||||
this.propertiesDescription = "{}";
|
||||
this.blockstates = getStates(block, Collections.emptyMap());
|
||||
this.stateHashes = getStateHashes(blockstates);
|
||||
this.stackHashes = getStackHashes(blockstates);
|
||||
}
|
||||
|
||||
public BlockOptionalMeta(@Nonnull String selector) {
|
||||
Matcher matcher = pattern.matcher(selector);
|
||||
Matcher matcher = PATTERN.matcher(selector);
|
||||
|
||||
if (!matcher.find()) {
|
||||
throw new IllegalArgumentException("invalid block selector");
|
||||
}
|
||||
|
||||
MatchResult matchResult = matcher.toMatchResult();
|
||||
block = BlockUtils.stringToBlockRequired(matcher.group("id"));
|
||||
|
||||
block = BlockUtils.stringToBlockRequired(matchResult.group(1));
|
||||
blockstates = getStates(block);
|
||||
String props = matcher.group("properties");
|
||||
Map<Property<?>, ?> properties = props == null || props.equals("") ? Collections.emptyMap() : parseProperties(block, props);
|
||||
|
||||
propertiesDescription = props == null ? "{}" : "{" + props.replace("=", ":") + "}";
|
||||
blockstates = getStates(block, properties);
|
||||
stateHashes = getStateHashes(blockstates);
|
||||
stackHashes = getStackHashes(blockstates);
|
||||
}
|
||||
|
||||
private static Set<BlockState> getStates(@Nonnull Block block) {
|
||||
return new HashSet<>(block.getStateDefinition().getPossibleStates());
|
||||
private static <C extends Comparable<C>, P extends Property<C>> P castToIProperty(Object value) {
|
||||
//noinspection unchecked
|
||||
return (P) value;
|
||||
}
|
||||
|
||||
private static Map<Property<?>, ?> parseProperties(Block block, String raw) {
|
||||
ImmutableMap.Builder<Property<?>, Object> builder = ImmutableMap.builder();
|
||||
for (String pair : raw.split(",")) {
|
||||
String[] parts = pair.split("=");
|
||||
if (parts.length != 2) {
|
||||
throw new IllegalArgumentException(String.format("\"%s\" is not a valid property-value pair", pair));
|
||||
}
|
||||
String rawKey = parts[0];
|
||||
String rawValue = parts[1];
|
||||
Property<?> key = block.getStateDefinition().getProperty(rawKey);
|
||||
Comparable<?> value = castToIProperty(key).getValue(rawValue)
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
"\"%s\" is not a valid value for %s on %s",
|
||||
rawValue, key, block
|
||||
)));
|
||||
builder.put(key, value);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static Set<BlockState> getStates(@Nonnull Block block, @Nonnull Map<Property<?>, ?> properties) {
|
||||
return block.getStateDefinition().getPossibleStates().stream()
|
||||
.filter(blockstate -> properties.entrySet().stream().allMatch(entry ->
|
||||
blockstate.getValue(entry.getKey()) == entry.getValue()
|
||||
))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private static ImmutableSet<Integer> getStateHashes(Set<BlockState> blockstates) {
|
||||
@@ -144,7 +182,7 @@ public final class BlockOptionalMeta {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("BlockOptionalMeta{block=%s}", block);
|
||||
return String.format("BlockOptionalMeta{block=%s,properties=%s}", block, propertiesDescription);
|
||||
}
|
||||
|
||||
public BlockState getAnyBlockState() {
|
||||
@@ -155,6 +193,14 @@ public final class BlockOptionalMeta {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<BlockState> getAllBlockStates() {
|
||||
return blockstates;
|
||||
}
|
||||
|
||||
public Set<Integer> stackHashes() {
|
||||
return stackHashes;
|
||||
}
|
||||
|
||||
private static Method getVanillaServerPack;
|
||||
|
||||
private static VanillaPackResources getVanillaServerPack() {
|
||||
@@ -172,11 +218,11 @@ public final class BlockOptionalMeta {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static LootTables getManager() {
|
||||
public static LootDataManager getManager() {
|
||||
if (lootTables == null) {
|
||||
MultiPackResourceManager resources = new MultiPackResourceManager(PackType.SERVER_DATA, List.of(getVanillaServerPack()));
|
||||
ReloadableResourceManager resourceManager = new ReloadableResourceManager(PackType.SERVER_DATA);
|
||||
lootTables = new LootTables(predicate);
|
||||
lootTables = new LootDataManager();
|
||||
resourceManager.registerReloadListener(lootTables);
|
||||
try {
|
||||
resourceManager.createReload(new ThreadPerTaskExecutor(Thread::new), new ThreadPerTaskExecutor(Thread::new), CompletableFuture.completedFuture(Unit.INSTANCE), resources.listPacks().toList()).done().get();
|
||||
@@ -188,10 +234,6 @@ public final class BlockOptionalMeta {
|
||||
return lootTables;
|
||||
}
|
||||
|
||||
public static PredicateManager getPredicateManager() {
|
||||
return predicate;
|
||||
}
|
||||
|
||||
private static synchronized List<Item> drops(Block b) {
|
||||
return drops.computeIfAbsent(b, block -> {
|
||||
ResourceLocation lootTableLocation = block.getLootTable();
|
||||
@@ -200,15 +242,18 @@ public final class BlockOptionalMeta {
|
||||
} else {
|
||||
List<Item> items = new ArrayList<>();
|
||||
try {
|
||||
getManager().get(lootTableLocation).getRandomItems(
|
||||
new LootContext.Builder(ServerLevelStub.fastCreate())
|
||||
.withRandom(RandomSource.create())
|
||||
.withParameter(LootContextParams.ORIGIN, Vec3.atLowerCornerOf(BlockPos.ZERO))
|
||||
.withParameter(LootContextParams.TOOL, ItemStack.EMPTY)
|
||||
.withOptionalParameter(LootContextParams.BLOCK_ENTITY, null)
|
||||
.withParameter(LootContextParams.BLOCK_STATE, block.defaultBlockState())
|
||||
.create(LootContextParamSets.BLOCK),
|
||||
stack -> items.add(stack.getItem())
|
||||
|
||||
getManager().getLootTable(lootTableLocation).getRandomItemsRaw(
|
||||
new LootContext.Builder(
|
||||
new LootParams.Builder(ServerLevelStub.fastCreate())
|
||||
.withParameter(LootContextParams.ORIGIN, Vec3.atLowerCornerOf(BlockPos.ZERO))
|
||||
.withParameter(LootContextParams.TOOL, ItemStack.EMPTY)
|
||||
.withOptionalParameter(LootContextParams.BLOCK_ENTITY, null)
|
||||
.withParameter(LootContextParams.BLOCK_STATE, block.defaultBlockState())
|
||||
.create(LootContextParamSets.BLOCK)
|
||||
).withOptionalRandomSeed(1L)
|
||||
.create(null),
|
||||
stack -> items.add(stack.getItem())
|
||||
);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -221,8 +266,9 @@ public final class BlockOptionalMeta {
|
||||
private static class ServerLevelStub extends ServerLevel {
|
||||
private static Minecraft client = Minecraft.getInstance();
|
||||
private static Unsafe unsafe = getUnsafe();
|
||||
public ServerLevelStub(MinecraftServer $$0, Executor $$1, LevelStorageSource.LevelStorageAccess $$2, ServerLevelData $$3, ResourceKey<Level> $$4, LevelStem $$5, ChunkProgressListener $$6, boolean $$7, long $$8, List<CustomSpawner> $$9, boolean $$10) {
|
||||
super($$0, $$1, $$2, $$3, $$4, $$5, $$6, $$7, $$8, $$9, $$10);
|
||||
|
||||
public ServerLevelStub(MinecraftServer $$0, Executor $$1, LevelStorageSource.LevelStorageAccess $$2, ServerLevelData $$3, ResourceKey<Level> $$4, LevelStem $$5, ChunkProgressListener $$6, boolean $$7, long $$8, List<CustomSpawner> $$9, boolean $$10, @Nullable RandomSequences $$11) {
|
||||
super($$0, $$1, $$2, $$3, $$4, $$5, $$6, $$7, $$8, $$9, $$10, $$11);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,67 +17,70 @@
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import baritone.api.utils.accessor.IItemStack;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class BlockOptionalMetaLookup {
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class BlockOptionalMetaLookup {
|
||||
private final ImmutableSet<Block> blockSet;
|
||||
private final ImmutableSet<BlockState> blockStateSet;
|
||||
private final ImmutableSet<Integer> stackHashes;
|
||||
private final BlockOptionalMeta[] boms;
|
||||
|
||||
public BlockOptionalMetaLookup(BlockOptionalMeta... boms) {
|
||||
this.boms = boms;
|
||||
Set<Block> blocks = new HashSet<>();
|
||||
Set<BlockState> blockStates = new HashSet<>();
|
||||
Set<Integer> stacks = new HashSet<>();
|
||||
for (BlockOptionalMeta bom : boms) {
|
||||
blocks.add(bom.getBlock());
|
||||
blockStates.addAll(bom.getAllBlockStates());
|
||||
stacks.addAll(bom.stackHashes());
|
||||
}
|
||||
this.blockSet = ImmutableSet.copyOf(blocks);
|
||||
this.blockStateSet = ImmutableSet.copyOf(blockStates);
|
||||
this.stackHashes = ImmutableSet.copyOf(stacks);
|
||||
}
|
||||
|
||||
public BlockOptionalMetaLookup(Block... blocks) {
|
||||
this.boms = Stream.of(blocks)
|
||||
this(Stream.of(blocks)
|
||||
.map(BlockOptionalMeta::new)
|
||||
.toArray(BlockOptionalMeta[]::new);
|
||||
.toArray(BlockOptionalMeta[]::new));
|
||||
|
||||
}
|
||||
|
||||
public BlockOptionalMetaLookup(List<Block> blocks) {
|
||||
this.boms = blocks.stream()
|
||||
this(blocks.stream()
|
||||
.map(BlockOptionalMeta::new)
|
||||
.toArray(BlockOptionalMeta[]::new);
|
||||
.toArray(BlockOptionalMeta[]::new));
|
||||
}
|
||||
|
||||
public BlockOptionalMetaLookup(String... blocks) {
|
||||
this.boms = Stream.of(blocks)
|
||||
this(Stream.of(blocks)
|
||||
.map(BlockOptionalMeta::new)
|
||||
.toArray(BlockOptionalMeta[]::new);
|
||||
.toArray(BlockOptionalMeta[]::new));
|
||||
}
|
||||
|
||||
public boolean has(Block block) {
|
||||
for (BlockOptionalMeta bom : boms) {
|
||||
if (bom.getBlock() == block) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return blockSet.contains(block);
|
||||
}
|
||||
|
||||
public boolean has(BlockState state) {
|
||||
for (BlockOptionalMeta bom : boms) {
|
||||
if (bom.matches(state)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return blockStateSet.contains(state);
|
||||
}
|
||||
|
||||
public boolean has(ItemStack stack) {
|
||||
for (BlockOptionalMeta bom : boms) {
|
||||
if (bom.matches(stack)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
int hash = ((IItemStack) (Object) stack).getBaritoneHash();
|
||||
hash -= stack.getDamageValue();
|
||||
return stackHashes.contains(hash);
|
||||
}
|
||||
|
||||
public List<BlockOptionalMeta> blocks() {
|
||||
|
||||
27
src/api/java/baritone/api/utils/BooleanBinaryOperator.java
Normal file
27
src/api/java/baritone/api/utils/BooleanBinaryOperator.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BooleanBinaryOperator {
|
||||
|
||||
boolean applyAsBoolean(boolean a, boolean b);
|
||||
}
|
||||
38
src/api/java/baritone/api/utils/BooleanBinaryOperators.java
Normal file
38
src/api/java/baritone/api/utils/BooleanBinaryOperators.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public enum BooleanBinaryOperators implements BooleanBinaryOperator {
|
||||
OR((a, b) -> a || b),
|
||||
AND((a, b) -> a && b),
|
||||
XOR((a, b) -> a ^ b);
|
||||
|
||||
private final BooleanBinaryOperator op;
|
||||
|
||||
BooleanBinaryOperators(BooleanBinaryOperator op) {
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyAsBoolean(boolean a, boolean b) {
|
||||
return this.op.applyAsBoolean(a, b);
|
||||
}
|
||||
}
|
||||
@@ -18,13 +18,13 @@
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.utils.gui.BaritoneToast;
|
||||
import baritone.api.Settings;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.GuiMessageTag;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.stream.Stream;
|
||||
@@ -44,10 +44,17 @@ public interface Helper {
|
||||
Helper HELPER = new Helper() {};
|
||||
|
||||
/**
|
||||
* Instance of the game
|
||||
* The main game instance returned by {@link Minecraft#getInstance()}.
|
||||
* Deprecated since {@link IPlayerContext#minecraft()} should be used instead (In the majority of cases).
|
||||
*/
|
||||
@Deprecated
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
|
||||
/**
|
||||
* The tag to assign to chat messages when {@link Settings#useMessageTag} is {@code true}.
|
||||
*/
|
||||
GuiMessageTag MESSAGE_TAG = new GuiMessageTag(0xFF55FF, null, Component.literal("Baritone message."), "Baritone");
|
||||
|
||||
static Component getPrefix() {
|
||||
// Inner text component
|
||||
final Calendar now = Calendar.getInstance();
|
||||
@@ -72,7 +79,7 @@ public interface Helper {
|
||||
* @param message The message to display in the popup
|
||||
*/
|
||||
default void logToast(Component title, Component message) {
|
||||
mc.execute(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message));
|
||||
Minecraft.getInstance().execute(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,7 +140,7 @@ public interface Helper {
|
||||
* @param error Whether to log as an error
|
||||
*/
|
||||
default void logNotificationDirect(String message, boolean error) {
|
||||
mc.execute(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error));
|
||||
Minecraft.getInstance().execute(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,13 +167,15 @@ public interface Helper {
|
||||
*/
|
||||
default void logDirect(boolean logAsToast, Component... components) {
|
||||
MutableComponent component = Component.literal("");
|
||||
component.append(getPrefix());
|
||||
component.append(Component.literal(" "));
|
||||
if (!logAsToast && !BaritoneAPI.getSettings().useMessageTag.value) {
|
||||
component.append(getPrefix());
|
||||
component.append(Component.literal(" "));
|
||||
}
|
||||
Arrays.asList(components).forEach(component::append);
|
||||
if (logAsToast) {
|
||||
logToast(getPrefix(), component);
|
||||
} else {
|
||||
mc.execute(() -> BaritoneAPI.getSettings().logger.value.accept(component));
|
||||
Minecraft.getInstance().execute(() -> BaritoneAPI.getSettings().logger.value.accept(component));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,4 +235,11 @@ public interface Helper {
|
||||
default void logDirect(String message) {
|
||||
logDirect(message, BaritoneAPI.getSettings().logAsToast.value);
|
||||
}
|
||||
|
||||
default void logUnhandledException(final Throwable exception) {
|
||||
HELPER.logDirect("An unhandled exception occurred. " +
|
||||
"The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues",
|
||||
ChatFormatting.RED);
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.api.cache.IWorldData;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -31,12 +29,18 @@ import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 11/12/2018
|
||||
*/
|
||||
public interface IPlayerContext {
|
||||
|
||||
Minecraft minecraft();
|
||||
|
||||
LocalPlayer player();
|
||||
|
||||
IPlayerController playerController();
|
||||
@@ -85,10 +89,24 @@ public interface IPlayerContext {
|
||||
return new Vec3(player().position().x, player().position().y + player().getEyeHeight(), player().position().z);
|
||||
}
|
||||
|
||||
default Vec3 playerMotion() {
|
||||
return player().getDeltaMovement();
|
||||
}
|
||||
|
||||
BetterBlockPos viewerPos();
|
||||
|
||||
default Rotation playerRotations() {
|
||||
return new Rotation(player().getYRot(), player().getXRot());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player's eye height, taking into account whether or not the player is sneaking.
|
||||
*
|
||||
* @param ifSneaking Whether or not the player is sneaking
|
||||
* @return The player's eye height
|
||||
* @deprecated Use entity.getEyeHeight(Pose.CROUCHING) instead
|
||||
*/
|
||||
@Deprecated
|
||||
static double eyeHeight(boolean ifSneaking) {
|
||||
return ifSneaking ? 1.27 : 1.62;
|
||||
}
|
||||
|
||||
59
src/api/java/baritone/api/utils/Pair.java
Normal file
59
src/api/java/baritone/api/utils/Pair.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class Pair<A, B> {
|
||||
|
||||
private final A a;
|
||||
private final B b;
|
||||
|
||||
public Pair(A a, B b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public A first() {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
public B second() {
|
||||
return this.b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || o.getClass() != Pair.class) {
|
||||
return false;
|
||||
}
|
||||
Pair<?, ?> pair = (Pair<?, ?>) o;
|
||||
return Objects.equals(this.a, pair.a) && Objects.equals(this.b, pair.b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * Objects.hashCode(this.a) + Objects.hashCode(this.b);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Pose;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
@@ -51,16 +52,17 @@ public final class RayTraceUtils {
|
||||
} else {
|
||||
start = entity.getEyePosition(1.0F); // do whatever is correct
|
||||
}
|
||||
Vec3 direction = RotationUtils.calcVector3dFromRotation(rotation);
|
||||
|
||||
Vec3 direction = RotationUtils.calcLookDirectionFromRotation(rotation);
|
||||
Vec3 end = start.add(
|
||||
direction.x * blockReachDistance,
|
||||
direction.y * blockReachDistance,
|
||||
direction.z * blockReachDistance
|
||||
);
|
||||
return entity.level.clip(new ClipContext(start, end, ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, entity));
|
||||
return entity.level().clip(new ClipContext(start, end, ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, entity));
|
||||
}
|
||||
|
||||
public static Vec3 inferSneakingEyePosition(Entity entity) {
|
||||
return new Vec3(entity.getX(), entity.getY() + IPlayerContext.eyeHeight(true), entity.getZ());
|
||||
return new Vec3(entity.getX(), entity.getY() + entity.getEyeHeight(Pose.CROUCHING), entity.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,12 @@ public class Rotation {
|
||||
/**
|
||||
* The yaw angle of this Rotation
|
||||
*/
|
||||
private float yaw;
|
||||
private final float yaw;
|
||||
|
||||
/**
|
||||
* The pitch angle of this Rotation
|
||||
*/
|
||||
private float pitch;
|
||||
private final float pitch;
|
||||
|
||||
public Rotation(float yaw, float pitch) {
|
||||
this.yaw = yaw;
|
||||
@@ -113,6 +113,10 @@ public class Rotation {
|
||||
);
|
||||
}
|
||||
|
||||
public Rotation withPitch(float pitch) {
|
||||
return new Rotation(this.yaw, pitch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is really close to
|
||||
*
|
||||
|
||||
@@ -19,7 +19,6 @@ package baritone.api.utils;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
@@ -33,6 +32,8 @@ import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/25/2018
|
||||
@@ -43,11 +44,13 @@ public final class RotationUtils {
|
||||
* Constant that a degree value is multiplied by to get the equivalent radian value
|
||||
*/
|
||||
public static final double DEG_TO_RAD = Math.PI / 180.0;
|
||||
public static final float DEG_TO_RAD_F = (float) DEG_TO_RAD;
|
||||
|
||||
/**
|
||||
* Constant that a radian value is multiplied by to get the equivalent degree value
|
||||
*/
|
||||
public static final double RAD_TO_DEG = 180.0 / Math.PI;
|
||||
public static final float RAD_TO_DEG_F = (float) RAD_TO_DEG;
|
||||
|
||||
/**
|
||||
* Offsets from the root block position to the center of each side.
|
||||
@@ -128,26 +131,31 @@ public final class RotationUtils {
|
||||
* @param rotation The input rotation
|
||||
* @return Look vector for the rotation
|
||||
*/
|
||||
public static Vec3 calcVector3dFromRotation(Rotation rotation) {
|
||||
float f = Mth.cos(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
|
||||
float f1 = Mth.sin(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
|
||||
float f2 = -Mth.cos(-rotation.getPitch() * (float) DEG_TO_RAD);
|
||||
float f3 = Mth.sin(-rotation.getPitch() * (float) DEG_TO_RAD);
|
||||
return new Vec3((double) (f1 * f2), (double) f3, (double) (f * f2));
|
||||
public static Vec3 calcLookDirectionFromRotation(Rotation rotation) {
|
||||
float flatZ = Mth.cos((-rotation.getYaw() * DEG_TO_RAD_F) - (float) Math.PI);
|
||||
float flatX = Mth.sin((-rotation.getYaw() * DEG_TO_RAD_F) - (float) Math.PI);
|
||||
float pitchBase = -Mth.cos(-rotation.getPitch() * DEG_TO_RAD_F);
|
||||
float pitchHeight = Mth.sin(-rotation.getPitch() * DEG_TO_RAD_F);
|
||||
return new Vec3(flatX * pitchBase, pitchHeight, flatZ * pitchBase);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Vec3 calcVec3dFromRotation(Rotation rotation) {
|
||||
return calcLookDirectionFromRotation(rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ctx Context for the viewing entity
|
||||
* @param pos The target block position
|
||||
* @return The optional rotation
|
||||
* @see #reachable(LocalPlayer, BlockPos, double)
|
||||
* @see #reachable(IPlayerContext, BlockPos, double)
|
||||
*/
|
||||
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos) {
|
||||
return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
|
||||
return reachable(ctx, pos, false);
|
||||
}
|
||||
|
||||
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, boolean wouldSneak) {
|
||||
return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance(), wouldSneak);
|
||||
return reachable(ctx, pos, ctx.playerController().getBlockReachDistance(), wouldSneak);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,18 +165,17 @@ public final class RotationUtils {
|
||||
* side that is reachable. The return type will be {@link Optional#empty()} if the entity is
|
||||
* unable to reach any of the sides of the block.
|
||||
*
|
||||
* @param entity The viewing entity
|
||||
* @param ctx Context for the viewing entity
|
||||
* @param pos The target block position
|
||||
* @param blockReachDistance The block reach distance of the entity
|
||||
* @return The optional rotation
|
||||
*/
|
||||
public static Optional<Rotation> reachable(LocalPlayer entity, BlockPos pos, double blockReachDistance) {
|
||||
return reachable(entity, pos, blockReachDistance, false);
|
||||
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance) {
|
||||
return reachable(ctx, pos, blockReachDistance, false);
|
||||
}
|
||||
|
||||
public static Optional<Rotation> reachable(LocalPlayer entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
|
||||
if (baritone.getPlayerContext().isLookingAt(pos)) {
|
||||
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
|
||||
if (BaritoneAPI.getSettings().remainWithExistingLookDirection.value && ctx.isLookingAt(pos)) {
|
||||
/*
|
||||
* why add 0.0001?
|
||||
* to indicate that we actually have a desired pitch
|
||||
@@ -179,10 +186,10 @@ public final class RotationUtils {
|
||||
*
|
||||
* or if you're a normal person literally all this does it ensure that we don't nudge the pitch to a normal level
|
||||
*/
|
||||
Rotation hypothetical = new Rotation(entity.getYRot(), entity.getXRot() + 0.0001F);
|
||||
Rotation hypothetical = ctx.playerRotations().add(new Rotation(0, 0.0001F));
|
||||
if (wouldSneak) {
|
||||
// the concern here is: what if we're looking at it now, but as soon as we start sneaking we no longer are
|
||||
HitResult result = RayTraceUtils.rayTraceTowards(entity, hypothetical, blockReachDistance, true);
|
||||
HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), hypothetical, blockReachDistance, true);
|
||||
if (result != null && result.getType() == HitResult.Type.BLOCK && ((BlockHitResult) result).getBlockPos().equals(pos)) {
|
||||
return Optional.of(hypothetical); // yes, if we sneaked we would still be looking at the block
|
||||
}
|
||||
@@ -190,14 +197,14 @@ public final class RotationUtils {
|
||||
return Optional.of(hypothetical);
|
||||
}
|
||||
}
|
||||
Optional<Rotation> possibleRotation = reachableCenter(entity, pos, blockReachDistance, wouldSneak);
|
||||
Optional<Rotation> possibleRotation = reachableCenter(ctx, pos, blockReachDistance, wouldSneak);
|
||||
//System.out.println("center: " + possibleRotation);
|
||||
if (possibleRotation.isPresent()) {
|
||||
return possibleRotation;
|
||||
}
|
||||
|
||||
BlockState state = entity.level.getBlockState(pos);
|
||||
VoxelShape shape = state.getShape(entity.level, pos);
|
||||
BlockState state = ctx.world().getBlockState(pos);
|
||||
VoxelShape shape = state.getShape(ctx.world(), pos);
|
||||
if (shape.isEmpty()) {
|
||||
shape = Shapes.block();
|
||||
}
|
||||
@@ -205,7 +212,7 @@ public final class RotationUtils {
|
||||
double xDiff = shape.min(Direction.Axis.X) * sideOffset.x + shape.max(Direction.Axis.X) * (1 - sideOffset.x);
|
||||
double yDiff = shape.min(Direction.Axis.Y) * sideOffset.y + shape.max(Direction.Axis.Y) * (1 - sideOffset.y);
|
||||
double zDiff = shape.min(Direction.Axis.Z) * sideOffset.z + shape.max(Direction.Axis.Z) * (1 - sideOffset.z);
|
||||
possibleRotation = reachableOffset(entity, pos, new Vec3(pos.getX(), pos.getY(), pos.getZ()).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak);
|
||||
possibleRotation = reachableOffset(ctx, pos, new Vec3(pos.getX(), pos.getY(), pos.getZ()).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak);
|
||||
if (possibleRotation.isPresent()) {
|
||||
return possibleRotation;
|
||||
}
|
||||
@@ -218,22 +225,23 @@ public final class RotationUtils {
|
||||
* the given offsetted position. The return type will be {@link Optional#empty()} if
|
||||
* the entity is unable to reach the block with the offset applied.
|
||||
*
|
||||
* @param entity The viewing entity
|
||||
* @param ctx Context for the viewing entity
|
||||
* @param pos The target block position
|
||||
* @param offsetPos The position of the block with the offset applied.
|
||||
* @param blockReachDistance The block reach distance of the entity
|
||||
* @return The optional rotation
|
||||
*/
|
||||
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3 offsetPos, double blockReachDistance, boolean wouldSneak) {
|
||||
Vec3 eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getEyePosition(1.0F);
|
||||
Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, new Rotation(entity.getYRot(), entity.getXRot()));
|
||||
HitResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance, wouldSneak);
|
||||
public static Optional<Rotation> reachableOffset(IPlayerContext ctx, BlockPos pos, Vec3 offsetPos, double blockReachDistance, boolean wouldSneak) {
|
||||
Vec3 eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(ctx.player()) : ctx.player().getEyePosition(1.0F);
|
||||
Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, ctx.playerRotations());
|
||||
Rotation actualRotation = BaritoneAPI.getProvider().getBaritoneForPlayer(ctx.player()).getLookBehavior().getAimProcessor().peekRotation(rotation);
|
||||
HitResult result = RayTraceUtils.rayTraceTowards(ctx.player(), actualRotation, blockReachDistance, wouldSneak);
|
||||
//System.out.println(result);
|
||||
if (result != null && result.getType() == HitResult.Type.BLOCK) {
|
||||
if (((BlockHitResult) result).getBlockPos().equals(pos)) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
if (entity.level.getBlockState(pos).getBlock() instanceof BaseFireBlock && ((BlockHitResult) result).getBlockPos().equals(pos.below())) {
|
||||
if (ctx.world().getBlockState(pos).getBlock() instanceof BaseFireBlock && ((BlockHitResult) result).getBlockPos().equals(pos.below())) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
}
|
||||
@@ -244,12 +252,46 @@ public final class RotationUtils {
|
||||
* Determines if the specified entity is able to reach the specified block where it is
|
||||
* looking at the direct center of it's hitbox.
|
||||
*
|
||||
* @param entity The viewing entity
|
||||
* @param ctx Context for the viewing entity
|
||||
* @param pos The target block position
|
||||
* @param blockReachDistance The block reach distance of the entity
|
||||
* @return The optional rotation
|
||||
*/
|
||||
public static Optional<Rotation> reachableCenter(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
|
||||
return reachableOffset(ctx, pos, VecUtils.calculateBlockCenter(ctx.world(), pos), blockReachDistance, wouldSneak);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Optional<Rotation> reachable(LocalPlayer entity, BlockPos pos, double blockReachDistance) {
|
||||
return reachable(entity, pos, blockReachDistance, false);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Optional<Rotation> reachable(LocalPlayer entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
|
||||
IPlayerContext ctx = baritone.getPlayerContext();
|
||||
return reachable(ctx, pos, blockReachDistance, wouldSneak);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3 offsetPos, double blockReachDistance, boolean wouldSneak) {
|
||||
Vec3 eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getEyePosition(1.0F);
|
||||
Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, new Rotation(entity.getYRot(), entity.getXRot()));
|
||||
HitResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance, wouldSneak);
|
||||
//System.out.println(result);
|
||||
if (result != null && result.getType() == HitResult.Type.BLOCK) {
|
||||
if (((BlockHitResult) result).getBlockPos().equals(pos)) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
if (entity.level().getBlockState(pos).getBlock() instanceof BaseFireBlock && ((BlockHitResult) result).getBlockPos().equals(pos.below())) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
|
||||
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.level, pos), blockReachDistance, wouldSneak);
|
||||
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.level(), pos), blockReachDistance, wouldSneak);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
@@ -47,12 +50,10 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
public class SettingsUtil {
|
||||
|
||||
private static final Path SETTINGS_PATH = Minecraft.getInstance().gameDirectory.toPath().resolve("baritone").resolve("settings.txt");
|
||||
public static final String SETTINGS_DEFAULT_NAME = "settings.txt";
|
||||
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
|
||||
private static final String[] JAVA_ONLY_SETTINGS = {"logger", "notifier", "toaster"};
|
||||
|
||||
|
||||
private static boolean isComment(String line) {
|
||||
@@ -71,43 +72,51 @@ public class SettingsUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void readAndApply(Settings settings) {
|
||||
public static void readAndApply(Settings settings, String settingsName) {
|
||||
try {
|
||||
forEachLine(SETTINGS_PATH, line -> {
|
||||
forEachLine(settingsByName(settingsName), line -> {
|
||||
Matcher matcher = SETTING_PATTERN.matcher(line);
|
||||
if (!matcher.matches()) {
|
||||
System.out.println("Invalid syntax in setting file: " + line);
|
||||
Helper.HELPER.logDirect("Invalid syntax in setting file: " + line);
|
||||
return;
|
||||
}
|
||||
|
||||
String settingName = matcher.group("setting").toLowerCase();
|
||||
String settingValue = matcher.group("value");
|
||||
// TODO remove soonish
|
||||
if ("allowjumpat256".equals(settingName)) {
|
||||
settingName = "allowjumpatbuildlimit";
|
||||
}
|
||||
try {
|
||||
parseAndApply(settings, settingName, settingValue);
|
||||
} catch (Exception ex) {
|
||||
System.out.println("Unable to parse line " + line);
|
||||
Helper.HELPER.logDirect("Unable to parse line " + line);
|
||||
ex.printStackTrace();
|
||||
}
|
||||
});
|
||||
} catch (NoSuchFileException ignored) {
|
||||
System.out.println("Baritone settings file not found, resetting.");
|
||||
Helper.HELPER.logDirect("Baritone settings file not found, resetting.");
|
||||
} catch (Exception ex) {
|
||||
System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!");
|
||||
Helper.HELPER.logDirect("Exception while reading Baritone settings, some settings may be reset to default values!");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void save(Settings settings) {
|
||||
try (BufferedWriter out = Files.newBufferedWriter(SETTINGS_PATH)) {
|
||||
try (BufferedWriter out = Files.newBufferedWriter(settingsByName(SETTINGS_DEFAULT_NAME))) {
|
||||
for (Settings.Setting setting : modifiedSettings(settings)) {
|
||||
out.write(settingToString(setting) + "\n");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
System.out.println("Exception thrown while saving Baritone settings!");
|
||||
Helper.HELPER.logDirect("Exception thrown while saving Baritone settings!");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static Path settingsByName(String name) {
|
||||
return Minecraft.getInstance().gameDirectory.toPath().resolve("baritone").resolve(name);
|
||||
}
|
||||
|
||||
public static List<Settings.Setting> modifiedSettings(Settings settings) {
|
||||
List<Settings.Setting> modified = new ArrayList<>();
|
||||
for (Settings.Setting setting : settings.allSettings) {
|
||||
@@ -115,7 +124,7 @@ public class SettingsUtil {
|
||||
System.out.println("NULL SETTING?" + setting.getName());
|
||||
continue;
|
||||
}
|
||||
if (javaOnlySetting(setting)) {
|
||||
if (setting.isJavaOnly()) {
|
||||
continue; // NO
|
||||
}
|
||||
if (setting.value == setting.defaultValue) {
|
||||
@@ -147,7 +156,7 @@ public class SettingsUtil {
|
||||
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting.getName());
|
||||
}
|
||||
|
||||
return io.toString(new ParserContext(setting), value);
|
||||
return io.toString(setting.getType(), value);
|
||||
}
|
||||
|
||||
public static String settingValueToString(Settings.Setting setting) throws IllegalArgumentException {
|
||||
@@ -169,7 +178,7 @@ public class SettingsUtil {
|
||||
}
|
||||
|
||||
public static String settingToString(Settings.Setting setting) throws IllegalStateException {
|
||||
if (javaOnlySetting(setting)) {
|
||||
if (setting.isJavaOnly()) {
|
||||
return setting.getName();
|
||||
}
|
||||
|
||||
@@ -177,18 +186,14 @@ public class SettingsUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* This should always be the same as whether the setting can be parsed from or serialized to a string
|
||||
* Deprecated. Use {@link Settings.Setting#isJavaOnly()} instead.
|
||||
*
|
||||
* @param setting The Setting
|
||||
* @return true if the setting can not be set or read by the user
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean javaOnlySetting(Settings.Setting setting) {
|
||||
for (String name : JAVA_ONLY_SETTINGS) { // no JAVA_ONLY_SETTINGS.contains(...) because that would be case sensitive
|
||||
if (setting.getName().equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return setting.isJavaOnly();
|
||||
}
|
||||
|
||||
public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
|
||||
@@ -198,7 +203,7 @@ public class SettingsUtil {
|
||||
}
|
||||
Class intendedType = setting.getValueClass();
|
||||
ISettingParser ioMethod = Parser.getParser(setting.getType());
|
||||
Object parsed = ioMethod.parse(new ParserContext(setting), settingValue);
|
||||
Object parsed = ioMethod.parse(setting.getType(), settingValue);
|
||||
if (!intendedType.isInstance(parsed)) {
|
||||
throw new IllegalStateException(ioMethod + " parser returned incorrect type, expected " + intendedType + " got " + parsed + " which is " + parsed.getClass());
|
||||
}
|
||||
@@ -207,26 +212,13 @@ public class SettingsUtil {
|
||||
|
||||
private interface ISettingParser<T> {
|
||||
|
||||
T parse(ParserContext context, String raw);
|
||||
T parse(Type type, String raw);
|
||||
|
||||
String toString(ParserContext context, T value);
|
||||
String toString(Type type, T value);
|
||||
|
||||
boolean accepts(Type type);
|
||||
}
|
||||
|
||||
private static class ParserContext {
|
||||
|
||||
private final Settings.Setting<?> setting;
|
||||
|
||||
private ParserContext(Settings.Setting<?> setting) {
|
||||
this.setting = setting;
|
||||
}
|
||||
|
||||
private Settings.Setting<?> getSetting() {
|
||||
return this.setting;
|
||||
}
|
||||
}
|
||||
|
||||
private enum Parser implements ISettingParser {
|
||||
|
||||
DOUBLE(Double.class, Double::parseDouble),
|
||||
@@ -235,7 +227,8 @@ public class SettingsUtil {
|
||||
FLOAT(Float.class, Float::parseFloat),
|
||||
LONG(Long.class, Long::parseLong),
|
||||
STRING(String.class, String::new),
|
||||
DIRECTION(Direction.class, Direction::byName),
|
||||
MIRROR(Mirror.class, Mirror::valueOf, Mirror::name),
|
||||
ROTATION(Rotation.class, Rotation::valueOf, Rotation::name),
|
||||
COLOR(
|
||||
Color.class,
|
||||
str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])),
|
||||
@@ -258,21 +251,21 @@ public class SettingsUtil {
|
||||
),
|
||||
LIST() {
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(type);
|
||||
public Object parse(Type type, String raw) {
|
||||
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(elementType);
|
||||
return Stream.of(raw.split(","))
|
||||
.map(s -> parser.parse(context, s))
|
||||
.map(s -> parser.parse(elementType, s))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ParserContext context, Object value) {
|
||||
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(type);
|
||||
public String toString(Type type, Object value) {
|
||||
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(elementType);
|
||||
|
||||
return ((List<?>) value).stream()
|
||||
.map(o -> parser.toString(context, o))
|
||||
.map(o -> parser.toString(elementType, o))
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
@@ -283,26 +276,26 @@ public class SettingsUtil {
|
||||
},
|
||||
MAPPING() {
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
Type keyType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Type valueType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[1];
|
||||
public Object parse(Type type, String raw) {
|
||||
Type keyType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
Type valueType = ((ParameterizedType) type).getActualTypeArguments()[1];
|
||||
Parser keyParser = Parser.getParser(keyType);
|
||||
Parser valueParser = Parser.getParser(valueType);
|
||||
|
||||
return Stream.of(raw.split(",(?=[^,]*->)"))
|
||||
.map(s -> s.split("->"))
|
||||
.collect(Collectors.toMap(s -> keyParser.parse(context, s[0]), s -> valueParser.parse(context, s[1])));
|
||||
.collect(Collectors.toMap(s -> keyParser.parse(keyType, s[0]), s -> valueParser.parse(valueType, s[1])));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ParserContext context, Object value) {
|
||||
Type keyType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Type valueType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[1];
|
||||
public String toString(Type type, Object value) {
|
||||
Type keyType = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
Type valueType = ((ParameterizedType) type).getActualTypeArguments()[1];
|
||||
Parser keyParser = Parser.getParser(keyType);
|
||||
Parser valueParser = Parser.getParser(valueType);
|
||||
|
||||
return ((Map<?, ?>) value).entrySet().stream()
|
||||
.map(o -> keyParser.toString(context, o.getKey()) + "->" + valueParser.toString(context, o.getValue()))
|
||||
.map(o -> keyParser.toString(keyType, o.getKey()) + "->" + valueParser.toString(valueType, o.getValue()))
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
@@ -333,14 +326,14 @@ public class SettingsUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
public Object parse(Type type, String raw) {
|
||||
Object parsed = this.parser.apply(raw);
|
||||
Objects.requireNonNull(parsed);
|
||||
return parsed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ParserContext context, Object value) {
|
||||
public String toString(Type type, Object value) {
|
||||
return this.toString.apply(value);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ package baritone.api.utils.gui;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.toasts.Toast;
|
||||
import net.minecraft.client.gui.components.toasts.ToastComponent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
@@ -38,7 +39,7 @@ public class BaritoneToast implements Toast {
|
||||
this.totalShowTime = totalShowTime;
|
||||
}
|
||||
|
||||
public Visibility render(PoseStack matrixStack, ToastComponent toastGui, long delta) {
|
||||
public Visibility render(GuiGraphics gui, ToastComponent toastGui, long delta) {
|
||||
if (this.newDisplay) {
|
||||
this.firstDrawTime = delta;
|
||||
this.newDisplay = false;
|
||||
@@ -46,15 +47,13 @@ public class BaritoneToast implements Toast {
|
||||
|
||||
|
||||
//TODO: check
|
||||
toastGui.getMinecraft().getTextureManager().bindForSetup(new ResourceLocation("textures/gui/toasts.png"));
|
||||
//GlStateManager._color4f(1.0F, 1.0F, 1.0F, 255.0F);
|
||||
toastGui.blit(matrixStack, 0, 0, 0, 32, 160, 32);
|
||||
gui.blit(new ResourceLocation("textures/gui/toasts.png"), 0, 0, 0, 32, 160, 32);
|
||||
|
||||
if (this.subtitle == null) {
|
||||
toastGui.getMinecraft().font.draw(matrixStack, this.title, 18, 12, -11534256);
|
||||
gui.drawString(toastGui.getMinecraft().font, this.title, 18, 12, -11534256);
|
||||
} else {
|
||||
toastGui.getMinecraft().font.draw(matrixStack, this.title, 18, 7, -11534256);
|
||||
toastGui.getMinecraft().font.draw(matrixStack, this.subtitle, 18, 18, -16777216);
|
||||
gui.drawString(toastGui.getMinecraft().font, this.title, 18, 7, -11534256);
|
||||
gui.drawString(toastGui.getMinecraft().font, this.subtitle, 18, 18, -16777216);
|
||||
}
|
||||
|
||||
return delta - this.firstDrawTime < totalShowTime ? Visibility.SHOW : Visibility.HIDE;
|
||||
|
||||
@@ -20,29 +20,36 @@ package baritone.launch.mixins;
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.BlockChangeEvent;
|
||||
import baritone.api.event.events.ChatEvent;
|
||||
import baritone.api.event.events.ChunkEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.api.utils.Pair;
|
||||
import baritone.cache.CachedChunk;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.client.multiplayer.CommonListenerCookie;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/3/2018
|
||||
*/
|
||||
@Mixin(ClientPacketListener.class)
|
||||
public class MixinClientPlayNetHandler {
|
||||
public abstract class MixinClientPlayNetHandler extends ClientCommonPacketListenerImpl {
|
||||
|
||||
// unused lol
|
||||
/*@Inject(
|
||||
@@ -68,12 +75,14 @@ public class MixinClientPlayNetHandler {
|
||||
}
|
||||
}*/
|
||||
|
||||
@Shadow @Final private Minecraft minecraft;
|
||||
protected MixinClientPlayNetHandler(final Minecraft arg, final Connection arg2, final CommonListenerCookie arg3) {
|
||||
super(arg, arg2, arg3);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "sendChat(Ljava/lang/String;)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
method = "sendChat(Ljava/lang/String;)V",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private void sendChatMessage(String string, CallbackInfo ci) {
|
||||
ChatEvent event = new ChatEvent(string);
|
||||
@@ -116,7 +125,7 @@ public class MixinClientPlayNetHandler {
|
||||
LocalPlayer player = ibaritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == (ClientPacketListener) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(EventState.PRE, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ())
|
||||
new ChunkEvent(EventState.PRE, ChunkEvent.Type.UNLOAD, packet.pos().x, packet.pos().z)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -131,7 +140,7 @@ public class MixinClientPlayNetHandler {
|
||||
LocalPlayer player = ibaritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == (ClientPacketListener) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(EventState.POST, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ())
|
||||
new ChunkEvent(EventState.POST, ChunkEvent.Type.UNLOAD, packet.pos().x, packet.pos().z)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -168,31 +177,22 @@ public class MixinClientPlayNetHandler {
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postHandleMultiBlockChange(ClientboundSectionBlocksUpdatePacket packetIn, CallbackInfo ci) {
|
||||
if (!Baritone.settings().repackOnAnyBlockChange.value) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((ClientPacketListener) (Object) this);
|
||||
if (baritone == null) {
|
||||
return;
|
||||
}
|
||||
ChunkPos[] chunkPos = new ChunkPos[1];
|
||||
packetIn.runUpdates((pos, state) -> {
|
||||
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(state.getBlock())) {
|
||||
chunkPos[0] = new ChunkPos(pos);
|
||||
}
|
||||
|
||||
List<Pair<BlockPos, BlockState>> changes = new ArrayList<>();
|
||||
packetIn.runUpdates((mutPos, state) -> {
|
||||
changes.add(new Pair<>(mutPos.immutable(), state));
|
||||
});
|
||||
if (chunkPos[0] == null) {
|
||||
if (changes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
LocalPlayer player = ibaritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == (ClientPacketListener) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
ChunkEvent.Type.POPULATE_FULL,
|
||||
chunkPos[0].x,
|
||||
chunkPos[0].z
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
baritone.getGameEventHandler().onBlockChange(new BlockChangeEvent(
|
||||
new ChunkPos(changes.get(0).first()),
|
||||
changes
|
||||
));
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -210,4 +210,71 @@ public class MixinClientPlayNetHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@Inject(
|
||||
method = "handleChunkData",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/world/chunk/Chunk.read(Lnet/minecraft/network/PacketBuffer;IZ)V"
|
||||
)
|
||||
)
|
||||
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
|
||||
if (baritone == null) {
|
||||
return;
|
||||
}
|
||||
baritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.PRE,
|
||||
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
|
||||
packetIn.getChunkX(),
|
||||
packetIn.getChunkZ()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "handleChunkData",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
|
||||
if (baritone == null) {
|
||||
return;
|
||||
}
|
||||
baritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
|
||||
packetIn.getChunkX(),
|
||||
packetIn.getChunkZ()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "handleBlockChange",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postHandleBlockChange(SPacketBlockChange packetIn, CallbackInfo ci) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
|
||||
if (baritone == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ChunkPos pos = new ChunkPos(packetIn.getBlockPosition().getX() >> 4, packetIn.getBlockPosition().getZ() >> 4);
|
||||
final Pair<BlockPos, IBlockState> changed = new Pair<>(packetIn.getBlockPosition(), packetIn.getBlockState());
|
||||
baritone.getGameEventHandler().onBlockChange(new BlockChangeEvent(pos, Collections.singletonList(changed)));
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "handleMultiBlockChange",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postHandleMultiBlockChange(SPacketMultiBlockChange packetIn, CallbackInfo ci) {
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -19,41 +19,43 @@ package baritone.launch.mixins;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.ChatEvent;
|
||||
import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.SprintStateEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.behavior.LookBehavior;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Abilities;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Group;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/1/2018
|
||||
*/
|
||||
@Mixin(LocalPlayer.class)
|
||||
public class MixinClientPlayerEntity {
|
||||
@Unique
|
||||
private static final MethodHandle MAY_FLY = baritone$resolveMayFly();
|
||||
|
||||
@Inject(
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/player/LocalPlayer.isPassenger()Z",
|
||||
shift = At.Shift.BY,
|
||||
by = -3
|
||||
)
|
||||
)
|
||||
private void onPreUpdate(CallbackInfo ci) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this);
|
||||
if (baritone != null) {
|
||||
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.PRE));
|
||||
@Unique
|
||||
private static MethodHandle baritone$resolveMayFly() {
|
||||
try {
|
||||
var lookup = MethodHandles.publicLookup();
|
||||
return lookup.findVirtual(LocalPlayer.class, "mayFly", MethodType.methodType(boolean.class));
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,15 +63,14 @@ public class MixinClientPlayerEntity {
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/player/LocalPlayer.sendPosition()V",
|
||||
shift = At.Shift.BY,
|
||||
by = 2
|
||||
target = "net/minecraft/client/player/AbstractClientPlayer.tick()V",
|
||||
shift = At.Shift.AFTER
|
||||
)
|
||||
)
|
||||
private void onPostUpdate(CallbackInfo ci) {
|
||||
private void onPreUpdate(CallbackInfo ci) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this);
|
||||
if (baritone != null) {
|
||||
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
|
||||
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.PRE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +81,7 @@ public class MixinClientPlayerEntity {
|
||||
target = "net/minecraft/world/entity/player/Abilities.mayfly:Z"
|
||||
)
|
||||
)
|
||||
@Group(name = "mayFly", min = 1, max = 1)
|
||||
private boolean isAllowFlying(Abilities capabilities) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this);
|
||||
if (baritone == null) {
|
||||
@@ -88,6 +90,22 @@ public class MixinClientPlayerEntity {
|
||||
return !baritone.getPathingBehavior().isPathing() && capabilities.mayfly;
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "aiStep",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/LocalPlayer;mayFly()Z"
|
||||
)
|
||||
)
|
||||
@Group(name = "mayFly", min = 1, max = 1)
|
||||
private boolean onMayFlyNeoforge(LocalPlayer instance) throws Throwable {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this);
|
||||
if (baritone == null) {
|
||||
return (boolean) MAY_FLY.invokeExact(instance);
|
||||
}
|
||||
return !baritone.getPathingBehavior().isPathing() && (boolean) MAY_FLY.invokeExact(instance);
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "aiStep",
|
||||
at = @At(
|
||||
@@ -124,4 +142,19 @@ public class MixinClientPlayerEntity {
|
||||
((LookBehavior) baritone.getLookBehavior()).pig();
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "aiStep",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/player/LocalPlayer;tryToStartFallFlying()Z"
|
||||
)
|
||||
)
|
||||
private boolean tryToStartFallFlying(final LocalPlayer instance) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(instance);
|
||||
if (baritone != null && baritone.getPathingBehavior().isPathing()) {
|
||||
return false;
|
||||
}
|
||||
return instance.tryToStartFallFlying();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,12 @@ package baritone.launch.mixins;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.event.events.TabCompleteEvent;
|
||||
import com.mojang.brigadier.ParseResults;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
import com.mojang.brigadier.suggestion.Suggestion;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import net.minecraft.client.gui.components.CommandSuggestions;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -33,8 +36,6 @@ import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import net.minecraft.client.gui.components.CommandSuggestions;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
@@ -51,9 +52,18 @@ public class MixinCommandSuggestionHelper {
|
||||
@Final
|
||||
private List<String> commandUsage;
|
||||
|
||||
@Shadow
|
||||
private ParseResults currentParse;
|
||||
|
||||
@Shadow
|
||||
private CompletableFuture<Suggestions> pendingSuggestions;
|
||||
|
||||
@Shadow
|
||||
private CommandSuggestions.SuggestionsList suggestions;
|
||||
|
||||
@Shadow
|
||||
boolean keepSuggestions;
|
||||
|
||||
@Inject(
|
||||
method = "updateCommandInfo",
|
||||
at = @At("HEAD"),
|
||||
@@ -74,27 +84,32 @@ public class MixinCommandSuggestionHelper {
|
||||
if (event.completions != null) {
|
||||
ci.cancel();
|
||||
|
||||
this.currentParse = null; // stop coloring
|
||||
|
||||
if (this.keepSuggestions) { // Supress suggestions update when cycling suggestions.
|
||||
return;
|
||||
}
|
||||
|
||||
this.input.setSuggestion(null); // clear old suggestions
|
||||
this.suggestions = null;
|
||||
// TODO: Support populating the command usage
|
||||
this.commandUsage.clear();
|
||||
|
||||
if (event.completions.length == 0) {
|
||||
this.pendingSuggestions = Suggestions.empty();
|
||||
} else {
|
||||
int offset = this.input.getValue().endsWith(" ")
|
||||
? this.input.getCursorPosition()
|
||||
: this.input.getValue().lastIndexOf(" ") + 1; // If there is no space this is still 0 haha yes
|
||||
StringRange range = StringRange.between(prefix.lastIndexOf(" ") + 1, prefix.length()); // if there is no space this starts at 0
|
||||
|
||||
List<Suggestion> suggestionList = Stream.of(event.completions)
|
||||
.map(s -> new Suggestion(StringRange.between(offset, offset + s.length()), s))
|
||||
.map(s -> new Suggestion(range, s))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Suggestions suggestions = new Suggestions(
|
||||
StringRange.between(offset, offset + suggestionList.stream().mapToInt(s -> s.getText().length()).max().orElse(0)),
|
||||
suggestionList);
|
||||
Suggestions suggestions = new Suggestions(range, suggestionList);
|
||||
|
||||
this.pendingSuggestions = new CompletableFuture<>();
|
||||
this.pendingSuggestions.complete(suggestions);
|
||||
}
|
||||
((CommandSuggestions) (Object) this).showSuggestions(true); // actually populate the suggestions list from the suggestions future
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@@ -33,21 +34,25 @@ public class MixinEntity {
|
||||
@Shadow
|
||||
private float yRot;
|
||||
|
||||
float yawRestore;
|
||||
@Shadow
|
||||
private float xRot;
|
||||
|
||||
@Unique
|
||||
private RotationMoveEvent motionUpdateRotationEvent;
|
||||
|
||||
@Inject(
|
||||
method = "moveRelative",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void moveRelativeHead(CallbackInfo info) {
|
||||
this.yawRestore = this.yRot;
|
||||
// noinspection ConstantConditions
|
||||
if (!LocalPlayer.class.isInstance(this) || BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this) == null) {
|
||||
return;
|
||||
}
|
||||
RotationMoveEvent motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.yRot);
|
||||
this.motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.yRot, this.xRot);
|
||||
BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this).getGameEventHandler().onPlayerRotationMove(motionUpdateRotationEvent);
|
||||
this.yRot = motionUpdateRotationEvent.getYaw();
|
||||
this.yRot = this.motionUpdateRotationEvent.getYaw();
|
||||
this.xRot = this.motionUpdateRotationEvent.getPitch();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -55,6 +60,10 @@ public class MixinEntity {
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void moveRelativeReturn(CallbackInfo info) {
|
||||
this.yRot = this.yawRestore;
|
||||
if (this.motionUpdateRotationEvent != null) {
|
||||
this.yRot = this.motionUpdateRotationEvent.getOriginal().getYaw();
|
||||
this.xRot = this.motionUpdateRotationEvent.getOriginal().getPitch();
|
||||
this.motionUpdateRotationEvent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.utils.accessor.IFireworkRocketEntity;
|
||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.projectile.FireworkRocketEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
|
||||
@Mixin(FireworkRocketEntity.class)
|
||||
public abstract class MixinFireworkRocketEntity extends Entity implements IFireworkRocketEntity {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private static EntityDataAccessor<OptionalInt> DATA_ATTACHED_TO_TARGET;
|
||||
|
||||
@Shadow
|
||||
private LivingEntity attachedToEntity;
|
||||
|
||||
@Shadow
|
||||
public abstract boolean isAttachedToEntity();
|
||||
|
||||
private MixinFireworkRocketEntity(Level level) {
|
||||
super(EntityType.FIREWORK_ROCKET, level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LivingEntity getBoostedEntity() {
|
||||
if (this.isAttachedToEntity() && this.attachedToEntity == null) { // isAttachedToEntity checks if the optional is present
|
||||
final Entity entity = this.level().getEntity(this.entityData.get(DATA_ATTACHED_TO_TARGET).getAsInt());
|
||||
if (entity instanceof LivingEntity) {
|
||||
this.attachedToEntity = (LivingEntity) entity;
|
||||
}
|
||||
}
|
||||
return this.attachedToEntity;
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,15 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.GETFIELD;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
@@ -43,9 +45,13 @@ public abstract class MixinLivingEntity extends Entity {
|
||||
/**
|
||||
* Event called to override the movement direction when jumping
|
||||
*/
|
||||
@Unique
|
||||
private RotationMoveEvent jumpRotationEvent;
|
||||
|
||||
public MixinLivingEntity(EntityType<?> entityTypeIn, Level worldIn) {
|
||||
@Unique
|
||||
private RotationMoveEvent elytraRotationEvent;
|
||||
|
||||
private MixinLivingEntity(EntityType<?> entityTypeIn, Level worldIn) {
|
||||
super(entityTypeIn, worldIn);
|
||||
}
|
||||
|
||||
@@ -54,14 +60,10 @@ public abstract class MixinLivingEntity extends Entity {
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preMoveRelative(CallbackInfo ci) {
|
||||
// noinspection ConstantConditions
|
||||
if (LocalPlayer.class.isInstance(this)) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this);
|
||||
if (baritone != null) {
|
||||
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.getYRot());
|
||||
baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
|
||||
}
|
||||
}
|
||||
this.getBaritone().ifPresent(baritone -> {
|
||||
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.getYRot(), this.getXRot());
|
||||
baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
|
||||
});
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
@@ -78,5 +80,45 @@ public abstract class MixinLivingEntity extends Entity {
|
||||
return self.getYRot();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "travel",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/world/entity/LivingEntity.getLookAngle()Lnet/minecraft/world/phys/Vec3;"
|
||||
)
|
||||
)
|
||||
private void onPreElytraMove(Vec3 direction, CallbackInfo ci) {
|
||||
this.getBaritone().ifPresent(baritone -> {
|
||||
this.elytraRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.getYRot(), this.getXRot());
|
||||
baritone.getGameEventHandler().onPlayerRotationMove(this.elytraRotationEvent);
|
||||
this.setYRot(this.elytraRotationEvent.getYaw());
|
||||
this.setXRot(this.elytraRotationEvent.getPitch());
|
||||
});
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "travel",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/world/entity/LivingEntity.move(Lnet/minecraft/world/entity/MoverType;Lnet/minecraft/world/phys/Vec3;)V",
|
||||
shift = At.Shift.AFTER
|
||||
)
|
||||
)
|
||||
private void onPostElytraMove(Vec3 direction, CallbackInfo ci) {
|
||||
if (this.elytraRotationEvent != null) {
|
||||
this.setYRot(this.elytraRotationEvent.getOriginal().getYaw());
|
||||
this.setXRot(this.elytraRotationEvent.getOriginal().getPitch());
|
||||
this.elytraRotationEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private Optional<IBaritone> getBaritone() {
|
||||
// noinspection ConstantConditions
|
||||
if (LocalPlayer.class.isInstance(this)) {
|
||||
return Optional.ofNullable(BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,7 @@ import baritone.api.utils.BlockOptionalMeta;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.LootTables;
|
||||
import net.minecraft.world.level.storage.loot.PredicateManager;
|
||||
import net.minecraft.world.level.storage.loot.LootDataManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -48,27 +47,13 @@ public class MixinLootContext {
|
||||
method = "create",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/MinecraftServer;getLootTables()Lnet/minecraft/world/level/storage/loot/LootTables;"
|
||||
target = "Lnet/minecraft/server/MinecraftServer;getLootData()Lnet/minecraft/world/level/storage/loot/LootDataManager;"
|
||||
)
|
||||
)
|
||||
private LootTables getLootTableManager(MinecraftServer server) {
|
||||
private LootDataManager getLootTableManager(MinecraftServer server) {
|
||||
if (server == null) {
|
||||
return BlockOptionalMeta.getManager();
|
||||
}
|
||||
return server.getLootTables();
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "create",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/MinecraftServer;getPredicateManager()Lnet/minecraft/world/level/storage/loot/PredicateManager;"
|
||||
)
|
||||
)
|
||||
private PredicateManager getLootPredicateManager(MinecraftServer server) {
|
||||
if (server == null) {
|
||||
return BlockOptionalMeta.getPredicateManager();
|
||||
}
|
||||
return server.getPredicateManager();
|
||||
return server.getLootData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package baritone.launch.mixins;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.event.events.WorldEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
@@ -29,9 +30,11 @@ import net.minecraft.client.player.LocalPlayer;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.Slice;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
@@ -48,6 +51,9 @@ public class MixinMinecraft {
|
||||
@Shadow
|
||||
public ClientLevel level;
|
||||
|
||||
@Unique
|
||||
private BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider;
|
||||
|
||||
@Inject(
|
||||
method = "<init>",
|
||||
at = @At("RETURN")
|
||||
@@ -56,30 +62,68 @@ public class MixinMinecraft {
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
opcode = Opcodes.GETFIELD,
|
||||
target = "net/minecraft/client/Minecraft.screen:Lnet/minecraft/client/gui/screens/Screen;",
|
||||
ordinal = 0,
|
||||
shift = At.Shift.BEFORE
|
||||
),
|
||||
slice = @Slice(
|
||||
from = @At(
|
||||
value = "FIELD",
|
||||
opcode = Opcodes.PUTFIELD,
|
||||
target = "net/minecraft/client/Minecraft.missTime:I"
|
||||
)
|
||||
)
|
||||
)
|
||||
private void runTick(CallbackInfo ci) {
|
||||
this.tickProvider = TickEvent.createNextProvider();
|
||||
|
||||
for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null
|
||||
? TickEvent.Type.IN
|
||||
: TickEvent.Type.OUT;
|
||||
baritone.getGameEventHandler().onTick(this.tickProvider.apply(EventState.PRE, type));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "tick",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postRunTick(CallbackInfo ci) {
|
||||
if (this.tickProvider == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null
|
||||
? TickEvent.Type.IN
|
||||
: TickEvent.Type.OUT;
|
||||
baritone.getGameEventHandler().onPostTick(this.tickProvider.apply(EventState.POST, type));
|
||||
}
|
||||
|
||||
this.tickProvider = null;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
opcode = Opcodes.GETFIELD,
|
||||
target = "Lnet/minecraft/client/Minecraft;screen:Lnet/minecraft/client/gui/screens/Screen;",
|
||||
ordinal = 4,
|
||||
shift = At.Shift.BY,
|
||||
by = -3
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/multiplayer/ClientLevel.tickEntities()V",
|
||||
shift = At.Shift.AFTER
|
||||
)
|
||||
)
|
||||
private void runTick(CallbackInfo ci) {
|
||||
final BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider = TickEvent.createNextProvider();
|
||||
|
||||
for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
|
||||
TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null
|
||||
? TickEvent.Type.IN
|
||||
: TickEvent.Type.OUT;
|
||||
|
||||
baritone.getGameEventHandler().onTick(tickProvider.apply(EventState.PRE, type));
|
||||
private void postUpdateEntities(CallbackInfo ci) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(this.player);
|
||||
if (baritone != null) {
|
||||
// Intentionally call this after all entities have been updated. That way, any modification to rotations
|
||||
// can be recognized by other entity code. (Fireworks and Pigs, for example)
|
||||
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -123,12 +167,25 @@ public class MixinMinecraft {
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
opcode = Opcodes.GETFIELD,
|
||||
target = "Lnet/minecraft/client/gui/screens/Screen;passEvents:Z"
|
||||
target = "Lnet/minecraft/client/Minecraft;screen:Lnet/minecraft/client/gui/screens/Screen;"
|
||||
),
|
||||
slice = @Slice(
|
||||
from = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/gui/components/DebugScreenOverlay;showDebugScreen()Z"
|
||||
),
|
||||
to = @At(
|
||||
value = "CONSTANT",
|
||||
args = "stringValue=Keybindings"
|
||||
)
|
||||
)
|
||||
)
|
||||
private boolean passEvents(Screen screen) {
|
||||
private Screen passEvents(Minecraft instance) {
|
||||
// allow user input is only the primary baritone
|
||||
return (BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().isPathing() && player != null) || screen.passEvents;
|
||||
if (BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().isPathing() && player != null) {
|
||||
return null;
|
||||
}
|
||||
return instance.screen;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
@@ -23,8 +23,6 @@ import baritone.api.event.events.PacketEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.PacketSendListener;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
@@ -54,7 +52,7 @@ public class MixinNetworkManager {
|
||||
method = "sendPacket",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preDispatchPacket(Packet<?> packet, PacketSendListener packetSendListener, CallbackInfo ci) {
|
||||
private void preDispatchPacket(Packet<?> packet, PacketSendListener packetSendListener, boolean flush, CallbackInfo ci) {
|
||||
if (this.receiving != PacketFlow.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
@@ -70,7 +68,7 @@ public class MixinNetworkManager {
|
||||
method = "sendPacket",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postDispatchPacket(Packet<?> packet, PacketSendListener packetSendListener, CallbackInfo ci) {
|
||||
private void postDispatchPacket(Packet<?> packet, PacketSendListener packetSendListener, boolean flush, CallbackInfo ci) {
|
||||
if (this.receiving != PacketFlow.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.utils.accessor.IPalettedContainer.IData;
|
||||
import net.minecraft.util.BitStorage;
|
||||
import net.minecraft.world.level.chunk.Palette;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(targets = "net/minecraft/world/level/chunk/PalettedContainer$Data")
|
||||
public abstract class MixinPalettedContainer$Data<T> implements IData<T> {
|
||||
|
||||
@Accessor
|
||||
public abstract Palette<T> getPalette();
|
||||
|
||||
@Accessor
|
||||
public abstract BitStorage getStorage();
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.utils.accessor.IPalettedContainer;
|
||||
import baritone.utils.accessor.IPalettedContainer.IData;
|
||||
import net.minecraft.util.BitStorage;
|
||||
import net.minecraft.world.level.chunk.Palette;
|
||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
@Mixin(PalettedContainer.class)
|
||||
public abstract class MixinPalettedContainer<T> implements IPalettedContainer<T> {
|
||||
|
||||
private static final MethodHandle DATA_GETTER;
|
||||
|
||||
// Mixin has no way of referring to the data field and we can't use inheritance
|
||||
// tricks to determine its name, so we use this ugly workaround instead.
|
||||
// Classloading is hell here and causes accessor mixins (@Mixin interfaces with
|
||||
// only @Accessor and @Invoker methods) to break on use and proguard hates method
|
||||
// handles and on top of that mojang decided that error messages during world
|
||||
// load are not needed so if you want to debug this you'll probably need an extra
|
||||
// mixin just to display the error and hard quit the game before follow up errors
|
||||
// blow up your log file.
|
||||
// Mumphrey, please add the shadow classes you promised 5 years ago.
|
||||
static {
|
||||
Field dataField = null;
|
||||
for (Field field : PalettedContainer.class.getDeclaredFields()) {
|
||||
Class<?> fieldType = field.getType();
|
||||
if (IData.class.isAssignableFrom(fieldType)) {
|
||||
if ((field.getModifiers() & (Modifier.STATIC | Modifier.FINAL)) != 0 || field.isSynthetic()) {
|
||||
continue;
|
||||
}
|
||||
if (dataField != null) {
|
||||
throw new IllegalStateException("PalettedContainer has more than one Data field.");
|
||||
}
|
||||
dataField = field;
|
||||
}
|
||||
}
|
||||
if (dataField == null) {
|
||||
throw new IllegalStateException("PalettedContainer has no Data field.");
|
||||
}
|
||||
MethodHandle rawGetter;
|
||||
try {
|
||||
rawGetter = MethodHandles.lookup().unreflectGetter(dataField);
|
||||
} catch (IllegalAccessException impossible) {
|
||||
// we literally are the owning class, wtf?
|
||||
throw new IllegalStateException("PalettedContainer may not access its own field?!", impossible);
|
||||
}
|
||||
MethodType getterType = MethodType.methodType(IData.class, PalettedContainer.class);
|
||||
DATA_GETTER = MethodHandles.explicitCastArguments(rawGetter, getterType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Palette<T> getPalette() {
|
||||
return data().getPalette();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BitStorage getStorage() {
|
||||
return data().getStorage();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private IData<T> data() {
|
||||
try {
|
||||
// cast to Object first so the method handle doesn't hide the interface usage from proguard
|
||||
return (IData<T>) (Object) DATA_GETTER.invoke((PalettedContainer<T>) (Object) this);
|
||||
} catch (Throwable t) {
|
||||
throw sneaky(t, RuntimeException.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static <T extends Throwable> T sneaky(Throwable t, Class<T> as) throws T {
|
||||
throw (T) t;
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,10 @@ public abstract class MixinPlayerController implements IPlayerControllerMP {
|
||||
@Override
|
||||
public abstract void setIsHittingBlock(boolean isHittingBlock);
|
||||
|
||||
@Accessor("isDestroying")
|
||||
@Override
|
||||
public abstract boolean isHittingBlock();
|
||||
|
||||
@Accessor("destroyBlockPos")
|
||||
@Override
|
||||
public abstract BlockPos getCurrentBlock();
|
||||
@@ -38,4 +42,8 @@ public abstract class MixinPlayerController implements IPlayerControllerMP {
|
||||
@Invoker("ensureHasSentCarriedItem")
|
||||
@Override
|
||||
public abstract void callSyncCurrentPlayItem();
|
||||
|
||||
@Accessor("destroyDelay")
|
||||
@Override
|
||||
public abstract void setDestroyDelay(int destroyDelay);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user