Compare commits
323 Commits
bot-system
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2679bea29 | ||
|
|
301ad40350 | ||
|
|
aee36e4d85 | ||
|
|
4efa2b1272 | ||
|
|
c2308c650a | ||
|
|
75b8554a11 | ||
|
|
d9cb2d91a0 | ||
|
|
d4b95110f5 | ||
|
|
8a2a20a1b3 | ||
|
|
7daf1022c0 | ||
|
|
60d6791f0c | ||
|
|
ca4385da7a | ||
|
|
661b16af7e | ||
|
|
f36072c8d3 | ||
|
|
b1be4f29ad | ||
|
|
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 | ||
|
|
2e2c0ecc0b | ||
|
|
31d1656c48 | ||
|
|
4b5a094f30 | ||
|
|
6b611cf4c7 | ||
|
|
90f2b39fba | ||
|
|
2164857408 | ||
|
|
601a781983 | ||
|
|
f14bb282f0 | ||
|
|
1e0dce8f41 | ||
|
|
45400a9685 | ||
|
|
6ffe31b59e | ||
|
|
293b556b56 | ||
|
|
dbf38efd83 | ||
|
|
e63aad7825 | ||
|
|
212ef4d4cc | ||
|
|
31e082b8dc | ||
|
|
75e8035551 | ||
|
|
f7f0521093 | ||
|
|
684fda2d1b | ||
|
|
886091df50 | ||
|
|
9707dd7ce8 | ||
|
|
b81d712a33 | ||
|
|
3ffacbf375 | ||
|
|
eec85b20be | ||
|
|
c0ead0147a | ||
|
|
9bfa2025d5 | ||
|
|
bf63ffbc1d | ||
|
|
985148b49a | ||
|
|
9e78443595 | ||
|
|
58723a33ca | ||
|
|
c9aa1658b2 | ||
|
|
7f9e50bbe2 | ||
|
|
664375a678 | ||
|
|
097e30850f | ||
|
|
a63cbab013 | ||
|
|
218de1cb98 | ||
|
|
0239a2cad4 | ||
|
|
38553b3324 | ||
|
|
ba78c48a75 | ||
|
|
f4996137a3 | ||
|
|
ccd80dfc8f | ||
|
|
ff1b3e7c5f | ||
|
|
2f0497756b | ||
|
|
afe9359d3e | ||
|
|
4b5d629df6 | ||
|
|
dbc0a46b10 | ||
|
|
9a6241af8a | ||
|
|
1b82bd1f33 | ||
|
|
90cfd82810 | ||
|
|
108dbdae5d | ||
|
|
32a4c4644e | ||
|
|
edc92753cf | ||
|
|
0e567f2f90 | ||
|
|
41e8c69db9 | ||
|
|
a83d1901f2 | ||
|
|
f3bb5a0cb2 | ||
|
|
76d3a13f58 | ||
|
|
6f99f891dc | ||
|
|
e579bf980d | ||
|
|
716b3ae0d2 | ||
|
|
b468b8eb95 | ||
|
|
1d109d4b9f | ||
|
|
29bf046aa8 | ||
|
|
4399b7c2fb | ||
|
|
d35571923f | ||
|
|
461f56c4d6 | ||
|
|
0b5d5b8176 | ||
|
|
42771686c6 | ||
|
|
8f5105c454 | ||
|
|
7c696b7055 | ||
|
|
349c951b55 | ||
|
|
5dc403e643 | ||
|
|
a8e1b16dee | ||
|
|
dc53a95bef | ||
|
|
eec4edea05 | ||
|
|
70249e5fa7 | ||
|
|
96a64b454e | ||
|
|
7a935fb2ea | ||
|
|
c0cdfb7781 | ||
|
|
487b3a759a | ||
|
|
fe67489419 | ||
|
|
308b9bbfea | ||
|
|
bfb4ffcafc | ||
|
|
537100a5e5 | ||
|
|
b6bf4427ef | ||
|
|
8de239f468 | ||
|
|
ecfd664f30 | ||
|
|
c4ac23837f | ||
|
|
aeeb001205 | ||
|
|
2552eb8dca | ||
|
|
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 | ||
|
|
2ccd464a49 | ||
|
|
f2374edd8b | ||
|
|
f56e0569a2 | ||
|
|
c10903be69 | ||
|
|
878a32228a | ||
|
|
bce2c74a8e | ||
|
|
90434b3178 | ||
|
|
9cf5538058 | ||
|
|
f4a99253f4 | ||
|
|
b366b1b1d1 | ||
|
|
a90e720956 | ||
|
|
535fd17a42 | ||
|
|
47dc0f9b94 | ||
|
|
4776fa1876 | ||
|
|
0aff31b768 | ||
|
|
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 | ||
|
|
9d05043fa0 | ||
|
|
5f709eef9c | ||
|
|
e57a84ded4 | ||
|
|
959b4cddbd | ||
|
|
82156250df | ||
|
|
90f401a067 | ||
|
|
c6a6624045 | ||
|
|
7d17ace15d | ||
|
|
8d3b0c8f07 | ||
|
|
6741dff12b | ||
|
|
9e10faa4c5 | ||
|
|
579e6d6e4c | ||
|
|
a32ac59ec1 | ||
|
|
2b259d6dee | ||
|
|
67efb7a5b6 | ||
|
|
1da7ab2c22 | ||
|
|
1257a0128c | ||
|
|
0886f176b3 | ||
|
|
7a8f8e8d47 | ||
|
|
7046927394 | ||
|
|
d2b1398cea | ||
|
|
9808f62fe4 | ||
|
|
1837b66bb5 | ||
|
|
efae476bc0 | ||
|
|
a236031435 | ||
|
|
812be14375 | ||
|
|
1dbfc9abe3 | ||
|
|
8dc32ae03c | ||
|
|
68901695ca | ||
|
|
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 | ||
|
|
071e6164fe | ||
|
|
b72bbfce5e | ||
|
|
cb7c2d7171 | ||
|
|
800cb2e747 | ||
|
|
5b39eb5041 | ||
|
|
53a0069704 | ||
|
|
8c12416348 | ||
|
|
e01093eb9a | ||
|
|
a9e9cd978d | ||
|
|
fe8ec19b6d | ||
|
|
0e87f350b3 | ||
|
|
8df6778641 | ||
|
|
06d11c1874 | ||
|
|
91bf7d726b | ||
|
|
bde0c620ad | ||
|
|
9672bd2c6d | ||
|
|
7b6f9b3eb6 | ||
|
|
92509f07e9 | ||
|
|
44cd5dcd41 | ||
|
|
410cfcf21a | ||
|
|
4148b98187 | ||
|
|
b9054cdfc9 | ||
|
|
35a996e2b0 | ||
|
|
c48c2aa45c | ||
|
|
a602863426 | ||
|
|
705a5a0712 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -30,3 +30,7 @@ baritone_Client.launch
|
||||
|
||||
.vscode/launch.json
|
||||
|
||||
libs/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar
|
||||
libs/java-objc-bridge-1.1.jar
|
||||
|
||||
mapping
|
||||
|
||||
31
README.md
31
README.md
@@ -1,3 +1,13 @@
|
||||
# Warning: Old Branch!!
|
||||
|
||||
**Click [here](https://github.com/cabaletta/baritone) to go to the current Baritone readme.**
|
||||
|
||||
**This branch (`master`) is Baritone for Minecraft 1.12.2. This is the original version of Minecraft that Baritone was written for, and it was the primary development branch for over 5 years. As such, it's quite mature, and arguably more reliable than Baritone for newer versions of Minecraft. Nevertheless, as of August 2023, with [2b2t's update from 1.12.2 to 1.19.4](https://2b2t.org/update/), I decided to move Baritone's primary development branch accordingly. PRs should now be made against the `1.19.4` branch going forward. This branch might see some fixes going forward, particularly to newer features such as `#elytra`, but it won't be the primary focus anymore.**
|
||||
|
||||
The other intermediary branches (`1.13.2`, `1.14.4`, `1.15.2`, `1.16.5`, `1.17.1`, `1.18.2`, `1.19.2`, and `1.19.3`) will probably not receive any updates at all. You can find their last releases in the releases tab, or in the quick download links table.
|
||||
|
||||
For `1.16.5` and `1.18.2`, the latest release is fully up to date with the code. ZacSharp merged master into some of those versions even after they were deprecated, if you are for some reason really interested in the latest Baritone bugfixes on these versions of Minecraft, you can build from source as of these commits: [1.13.2](https://github.com/cabaletta/baritone/commit/be54b8ee5b5639f80e3d6809ed1abd52444d8a08), [1.14.4](https://github.com/cabaletta/baritone/commit/be54b8ee5b5639f80e3d6809ed1abd52444d8a08), [1.15.2](https://github.com/cabaletta/baritone/commit/45abbb7fa1062cefc26abbb006a02a4edd6faa32), [1.17.1](https://github.com/cabaletta/baritone/commit/cbf0d79c9c5f7454071dc0a5289261ec9ca4373f), [1.19.2](https://github.com/cabaletta/baritone/commit/217dca53633610edc9483fda7a234e46c839fd99). For `1.19.3`, merging [this](https://github.com/cabaletta/baritone/commit/217dca53633610edc9483fda7a234e46c839fd99) commit into it is trivial and is left as an exercise for the reader. For other versions in between these (for example people always ask in the Discord for 1.16.1), you'll have to figure it out yourself.
|
||||
|
||||
# Baritone
|
||||
<p align="center">
|
||||
<a href="https://github.com/cabaletta/baritone/releases/"><img src="https://img.shields.io/github/downloads/cabaletta/baritone/total.svg" alt="GitHub All Releases"/></a>
|
||||
@@ -8,9 +18,9 @@
|
||||
<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-brightgreen.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-brightgreen.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>
|
||||
@@ -31,7 +41,8 @@
|
||||
<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">
|
||||
@@ -45,8 +56,8 @@
|
||||
</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.
|
||||
@@ -59,16 +70,18 @@ Baritone is the pathfinding system used in [Impact](https://impactclient.net/) s
|
||||
|
||||
| Forge | Fabric |
|
||||
|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
|
||||
| [1.12.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.2.17/baritone-api-forge-1.2.17.jar) | |
|
||||
| [1.16.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.6.4/baritone-api-forge-1.6.4.jar) | [1.16.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.6.4/baritone-api-fabric-1.6.4.jar) |
|
||||
| [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.4/baritone-api-forge-1.8.4.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-fabric-1.8.4.jar) |
|
||||
| [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.5/baritone-api-forge-1.8.5.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.5/baritone-api-fabric-1.8.5.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) |
|
||||
|
||||
**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)
|
||||
**Message for 2b2t players looking for 1.19/1.20 Baritone** Download it from right above ^. But also please check back in a few days for Baritone Elytra ([vid 1](https://youtu.be/4bGGPo8yiHo) [vid 2](https://www.youtube.com/watch?v=pUN9nmINe3I)), which will be ported to 1.19/1.20 soon! It will work on 2b2t with its anticheat, that was the whole point of Baritone Elytra (it's fully vanilla compatible). Also join [**the discord**](http://discord.gg/s6fRBAUpmr). Thanks!
|
||||
|
||||
**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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
144
build.gradle
144
build.gradle
@@ -16,13 +16,13 @@
|
||||
*/
|
||||
|
||||
group 'baritone'
|
||||
version '1.2.17'
|
||||
version '1.2.19'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
name = 'forge'
|
||||
url = 'http://files.minecraftforge.net/maven'
|
||||
url = 'https://files.minecraftforge.net/maven'
|
||||
}
|
||||
maven {
|
||||
name = 'SpongePowered'
|
||||
@@ -32,18 +32,19 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:4.+' // TODO: 5.+. `doHackyStuff` relies on 4.x internals.
|
||||
classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
import baritone.gradle.task.CreateDistTask
|
||||
import baritone.gradle.task.ProguardTask
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'net.minecraftforge.gradle'
|
||||
apply from: 'hacks.gradle'
|
||||
ext.doHackyStuff(Class.forName('net.minecraftforge.gradle.mcp.task.GenerateSRG')) // TODO: fg 5.0 - `ext.doHackyStuff(Class.forName('net.minecraftforge.gradle.mcp.tasks.GenerateSRG'))`
|
||||
apply plugin: 'org.spongepowered.mixin'
|
||||
|
||||
sourceCompatibility = targetCompatibility = '1.8'
|
||||
@@ -53,8 +54,19 @@ compileJava {
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
api {
|
||||
compileClasspath += main.compileClasspath
|
||||
}
|
||||
main {
|
||||
compileClasspath += api.output
|
||||
}
|
||||
test {
|
||||
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
}
|
||||
launch {
|
||||
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
}
|
||||
|
||||
schematica_api {
|
||||
@@ -67,13 +79,26 @@ sourceSets {
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = '1.12.2'
|
||||
mappings = 'stable_39'
|
||||
tweakClass = 'baritone.launch.BaritoneTweaker'
|
||||
runDir = 'run'
|
||||
mappings channel: 'stable', version: '39-1.12'
|
||||
runs {
|
||||
def nativesOutput = extractNatives.output // TODO: fg 5.0 - `def nativesOutput = extractNatives.output.get()`
|
||||
println("[Baritoe] Detected natives: ${nativesOutput}")
|
||||
client {
|
||||
workingDirectory project.file('run')
|
||||
source sourceSets.launch
|
||||
|
||||
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
|
||||
makeObfSourceJar = true
|
||||
main 'net.minecraft.launchwrapper.Launch'
|
||||
|
||||
args '--gameDir', '.'
|
||||
args '--version', '1.12.2'
|
||||
args '--assetsDir', downloadAssets.output
|
||||
args '--assetIndex', '{asset_index}'
|
||||
args '--accessToken', 'INVALID'
|
||||
|
||||
args '--tweakClass', 'baritone.launch.BaritoneTweaker'
|
||||
jvmArgs "-Dorg.lwjgl.librarypath=${nativesOutput}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
@@ -88,23 +113,74 @@ repositories {
|
||||
name = 'impactdevelopment-repo'
|
||||
url = 'https://impactdevelopment.github.io/maven/'
|
||||
}
|
||||
|
||||
maven {
|
||||
name = 'babbaj-repo'
|
||||
url = 'https://babbaj.github.io/maven/'
|
||||
}
|
||||
}
|
||||
|
||||
// fix forge gradle 4+ bug with 1.12.2
|
||||
afterEvaluate {
|
||||
configurations.minecraft {
|
||||
exclude group: 'net.minecraftforge', module: 'mergetool'
|
||||
}
|
||||
}
|
||||
|
||||
// lwjgl2 hack for running game on arm64 mac os
|
||||
afterEvaluate {
|
||||
def os = org.gradle.internal.os.OperatingSystem.current()
|
||||
if (os.isMacOsX()) {
|
||||
def arch = System.getProperty("os.arch").toLowerCase()
|
||||
println("Detected Mac OS X running on ${arch}")
|
||||
if (arch == "aarch64") {
|
||||
println("Configurating aarch64 dependencies.")
|
||||
|
||||
configurations.minecraft {
|
||||
exclude group: 'ca.weblite', module: 'java-objc-bridge'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// https://github.com/MinecraftMachina/lwjgl/releases/download/2.9.4-20150209-mmachina.2/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar
|
||||
minecraft files("libs/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar")
|
||||
// TODO: use prism launcher maven
|
||||
// https://github.com/MinecraftMachina/Java-Objective-C-Bridge/releases/download/1.1.0-mmachina.1/java-objc-bridge-1.1.jar
|
||||
minecraft files("libs/java-objc-bridge-1.1.jar") // TODO: use prism launcher maven
|
||||
minecraft(group: 'net.java.dev.jna', name: 'jna') {
|
||||
version {
|
||||
strictly '5.12.1'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
|
||||
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
|
||||
// Mixin includes a lot of dependencies that are too up-to-date
|
||||
exclude module: 'launchwrapper'
|
||||
exclude module: 'guava'
|
||||
exclude module: 'gson'
|
||||
exclude module: 'commons-io'
|
||||
exclude module: 'log4j-core'
|
||||
minecraft group: 'net.minecraft', name: 'joined', version: '1.12.2'
|
||||
implementation(group: 'net.minecraft', name: 'launchwrapper', version: '1.12') {
|
||||
transitive = false
|
||||
}
|
||||
|
||||
def asmVersion = '9.5'
|
||||
implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
|
||||
implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
|
||||
implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
|
||||
implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
|
||||
implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
|
||||
|
||||
launchImplementation('com.github.ImpactDevelopment:SimpleTweaker:1.2')
|
||||
launchImplementation('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
|
||||
// Mixin includes a lot of dependencies that are too up-to-date
|
||||
transitive = false
|
||||
}
|
||||
launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor'
|
||||
launchImplementation('dev.babbaj:nether-pathfinder:1.3.0')
|
||||
implementation 'dev.babbaj:nether-pathfinder:1.3.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
mixin {
|
||||
defaultObfuscationEnv searge
|
||||
add sourceSets.launch, 'mixins.baritone.refmap.json'
|
||||
}
|
||||
|
||||
@@ -130,7 +206,7 @@ jar {
|
||||
manifest {
|
||||
attributes(
|
||||
'MixinConfigs': 'mixins.baritone.json',
|
||||
|
||||
'TweakClass': 'baritone.launch.BaritoneTweaker',
|
||||
'Implementation-Title': 'Baritone',
|
||||
'Implementation-Version': version
|
||||
)
|
||||
@@ -145,25 +221,3 @@ task proguard(type: ProguardTask) {
|
||||
task createDist(type: CreateDistTask, dependsOn: proguard)
|
||||
|
||||
build.finalizedBy(createDist)
|
||||
|
||||
install {
|
||||
def jarApiName = String.format("%s-api-%s", rootProject.name, version.toString())
|
||||
def jarApiForgeName = String.format("%s-api-forge-%s", rootProject.name, version.toString())
|
||||
def jarSAName = String.format("%s-standalone-%s", rootProject.name, version.toString())
|
||||
def jarSAForgeName = String.format("%s-standalone-forge-%s", rootProject.name, version.toString())
|
||||
|
||||
artifacts {
|
||||
archives file("$buildDir/libs/"+jarApiName+".jar")
|
||||
archives file("$buildDir/libs/"+jarApiForgeName+".jar")
|
||||
archives file("$buildDir/libs/"+jarSAName+".jar")
|
||||
archives file("$buildDir/libs/"+jarSAForgeName+".jar")
|
||||
}
|
||||
repositories.mavenInstaller {
|
||||
addFilter('api') { artifact, file -> artifact.name == "baritone-api" }
|
||||
addFilter('api-forge') { artifact, file -> artifact.name == "baritone-api-forge" }
|
||||
addFilter('standalone') { artifact, file -> artifact.name == "baritone-standalone" }
|
||||
addFilter('standalone-forge') { artifact, file -> artifact.name == "baritone-standalone-forge" }
|
||||
}
|
||||
}
|
||||
|
||||
install.dependsOn(build)
|
||||
|
||||
@@ -20,6 +20,6 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
||||
compile group: 'commons-io', name: 'commons-io', version: '2.6'
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
||||
implementation group: 'commons-io', name: 'commons-io', version: '2.6'
|
||||
}
|
||||
@@ -32,21 +32,21 @@ import java.nio.file.Paths;
|
||||
class BaritoneGradleTask extends DefaultTask {
|
||||
|
||||
protected static final String
|
||||
PROGUARD_ZIP = "proguard.zip",
|
||||
PROGUARD_JAR = "proguard.jar",
|
||||
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
|
||||
PROGUARD_CONFIG_DEST = "template.pro",
|
||||
PROGUARD_API_CONFIG = "api.pro",
|
||||
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
|
||||
PROGUARD_EXPORT_PATH = "proguard_out.jar",
|
||||
PROGUARD_ZIP = "proguard.zip",
|
||||
PROGUARD_JAR = "proguard.jar",
|
||||
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
|
||||
PROGUARD_CONFIG_DEST = "template.pro",
|
||||
PROGUARD_API_CONFIG = "api.pro",
|
||||
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
|
||||
PROGUARD_EXPORT_PATH = "proguard_out.jar",
|
||||
|
||||
TEMP_LIBRARY_DIR = "tempLibraries/",
|
||||
TEMP_LIBRARY_DIR = "tempLibraries/",
|
||||
|
||||
ARTIFACT_STANDARD = "%s-%s.jar",
|
||||
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
|
||||
ARTIFACT_API = "%s-api-%s.jar",
|
||||
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
|
||||
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
|
||||
ARTIFACT_STANDARD = "%s-%s.jar",
|
||||
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
|
||||
ARTIFACT_API = "%s-api-%s.jar",
|
||||
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
|
||||
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
|
||||
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
|
||||
|
||||
protected String artifactName, artifactVersion;
|
||||
@@ -56,17 +56,17 @@ class BaritoneGradleTask extends DefaultTask {
|
||||
this.artifactName = getProject().getName();
|
||||
this.artifactVersion = getProject().getVersion().toString();
|
||||
|
||||
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
|
||||
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
|
||||
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
|
||||
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
|
||||
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
|
||||
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
|
||||
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
|
||||
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
|
||||
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
|
||||
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
|
||||
this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE));
|
||||
|
||||
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
|
||||
|
||||
if (!Files.exists(this.artifactPath)) {
|
||||
throw new IllegalStateException("Artifact not found! Run build first!");
|
||||
throw new IllegalStateException("Artifact not found! Run build first! " + this.artifactPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class BaritoneGradleTask extends DefaultTask {
|
||||
}
|
||||
|
||||
protected Path getRelativeFile(String file) {
|
||||
return Paths.get(new File(file).getAbsolutePath());
|
||||
return Paths.get(this.getProject().file(file).getAbsolutePath());
|
||||
}
|
||||
|
||||
protected Path getTemporaryFile(String file) {
|
||||
|
||||
@@ -18,40 +18,33 @@
|
||||
package baritone.gradle.task;
|
||||
|
||||
import baritone.gradle.util.Determinizer;
|
||||
import baritone.gradle.util.MappingType;
|
||||
import baritone.gradle.util.ReobfWrapper;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.gradle.api.JavaVersion;
|
||||
import org.gradle.api.NamedDomainObjectContainer;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.internal.file.IdentityFileResolver;
|
||||
import org.gradle.api.internal.plugins.DefaultConvention;
|
||||
import org.gradle.api.tasks.Input;
|
||||
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.Pair;
|
||||
import org.gradle.internal.jvm.Jvm;
|
||||
import org.gradle.internal.jvm.inspection.DefaultJvmVersionDetector;
|
||||
import org.gradle.process.internal.DefaultExecActionFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Objects;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 10/11/2018
|
||||
@@ -69,17 +62,18 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
private List<String> requiredLibraries;
|
||||
|
||||
private File mixin;
|
||||
private File pathfinder;
|
||||
|
||||
@TaskAction
|
||||
protected void exec() throws Exception {
|
||||
super.verifyArtifacts();
|
||||
|
||||
// "Haha brady why don't you make separate tasks"
|
||||
processArtifact();
|
||||
downloadProguard();
|
||||
extractProguard();
|
||||
generateConfigs();
|
||||
acquireDependencies();
|
||||
processArtifact();
|
||||
proguardApi();
|
||||
proguardStandalone();
|
||||
cleanup();
|
||||
@@ -90,7 +84,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
Files.delete(this.artifactUnoptimizedPath);
|
||||
}
|
||||
|
||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
|
||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Arrays.asList(pathfinder), false);
|
||||
}
|
||||
|
||||
private void downloadProguard() throws Exception {
|
||||
@@ -115,48 +109,38 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
try {
|
||||
path = findJavaPathByGradleConfig();
|
||||
if (path != null) return path;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Unable to find java by javaCompile options");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
path = findJavaByGradleCurrentRuntime();
|
||||
if (path != null) return path;
|
||||
|
||||
try {
|
||||
path = findJavaByJavaHome();
|
||||
if (path != null) return path;
|
||||
}
|
||||
catch(Exception ex) {
|
||||
} 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;
|
||||
System.out.println("Using Gradle's runtime Java for ProGuard");
|
||||
return path;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
System.out.println("Detected Java path by JAVA_HOME");
|
||||
return path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -172,19 +156,11 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
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");
|
||||
}
|
||||
});
|
||||
|
||||
File[] maybeJava = javacFile.getParentFile().listFiles((dir, name) -> 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;
|
||||
}
|
||||
System.out.println("Detected Java path by forkOptions");
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,21 +168,8 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean validateJavaVersion(String java) {
|
||||
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;
|
||||
}
|
||||
|
||||
private void generateConfigs() throws Exception {
|
||||
Files.copy(getRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), REPLACE_EXISTING);
|
||||
Files.copy(getRelativeFile(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));
|
||||
@@ -217,7 +180,6 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
Process p = new ProcessBuilder(this.getJavaBinPathForProguard(), "-verbose").start();
|
||||
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
|
||||
template.add(2, "-libraryjars '" + out + "'");
|
||||
template.add(3, "-libraryjars '" + Paths.get(out).resolveSibling("jce.jar") + "'");
|
||||
|
||||
// API config doesn't require any changes from the changes that we made to the template
|
||||
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
|
||||
@@ -239,14 +201,37 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
});
|
||||
}
|
||||
|
||||
private void acquireDependencies() throws Exception {
|
||||
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 acquireDependencies() throws Exception {
|
||||
// Create a map of all of the dependencies that we are able to access in this project
|
||||
// Likely a better way to do this, I just pair the dependency with the first valid configuration
|
||||
Map<String, Pair<Configuration, Dependency>> dependencyLookupMap = new HashMap<>();
|
||||
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config ->
|
||||
config.getAllDependencies().forEach(dependency ->
|
||||
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency))));
|
||||
Map<String, File> files = new HashMap<>();
|
||||
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config -> {
|
||||
for (File file : config.getFiles()) {
|
||||
files.put(file.getName(), file);
|
||||
}
|
||||
config.getAllDependencies().forEach(dependency ->
|
||||
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), new Pair<>(config, dependency)));
|
||||
});
|
||||
|
||||
// Create the directory if it doesn't already exist
|
||||
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
|
||||
@@ -261,7 +246,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
Path cachedJar = getMinecraftJar();
|
||||
Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar");
|
||||
// TODO: maybe try not to copy every time
|
||||
Files.copy(cachedJar, inTempDir, REPLACE_EXISTING);
|
||||
Files.copy(cachedJar, inTempDir, StandardCopyOption.REPLACE_EXISTING);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -273,118 +258,77 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
pair = entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
// The pair must be non-null
|
||||
Objects.requireNonNull(pair);
|
||||
|
||||
// Find the library jar file, and copy it to tempLibraries
|
||||
for (File file : pair.getLeft().files(pair.getRight())) {
|
||||
if (file.getName().startsWith(lib)) {
|
||||
if (lib.contains("mixin")) {
|
||||
mixin = file;
|
||||
if (pair == null) {
|
||||
File libFile = files.get(lib + ".jar");
|
||||
if (libFile == null) {
|
||||
libFile = files.values().stream().filter(file -> file.getName().startsWith(lib)).findFirst().orElse(null);
|
||||
if (libFile == null) {
|
||||
throw new IllegalStateException(lib);
|
||||
}
|
||||
}
|
||||
copyTempLib(lib, libFile);
|
||||
} else {
|
||||
for (File file : pair.a.files(pair.b)) {
|
||||
if (file.getName().startsWith(lib)) {
|
||||
copyTempLib(lib, file);
|
||||
}
|
||||
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mixin == null) {
|
||||
throw new IllegalStateException("Unable to find mixin jar");
|
||||
}
|
||||
if (pathfinder == null) {
|
||||
throw new IllegalStateException("Unable to find pathfinder jar");
|
||||
}
|
||||
}
|
||||
|
||||
private void copyTempLib(String lib, File libFile) throws IOException {
|
||||
if (lib.contains("mixin")) {
|
||||
mixin = libFile;
|
||||
}
|
||||
if (lib.contains("nether-pathfinder")) {
|
||||
pathfinder = libFile;
|
||||
}
|
||||
Files.copy(libFile.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
// a bunch of epic stuff to get the path to the cached jar
|
||||
private Path getMinecraftJar() throws Exception {
|
||||
MappingType mappingType;
|
||||
try {
|
||||
mappingType = getMappingType();
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to get mapping type, assuming NOTCH.");
|
||||
mappingType = MappingType.NOTCH;
|
||||
}
|
||||
|
||||
String suffix;
|
||||
switch (mappingType) {
|
||||
case NOTCH:
|
||||
suffix = "";
|
||||
break;
|
||||
case SEARGE:
|
||||
suffix = "-srgBin";
|
||||
break;
|
||||
case CUSTOM:
|
||||
throw new IllegalStateException("Custom mappings not supported!");
|
||||
default:
|
||||
throw new IllegalStateException("Unknown mapping type: " + mappingType);
|
||||
}
|
||||
|
||||
DefaultConvention convention = (DefaultConvention) this.getProject().getConvention();
|
||||
Object extension = convention.getAsMap().get("minecraft");
|
||||
Objects.requireNonNull(extension);
|
||||
|
||||
// for some reason cant use Class.forName
|
||||
Class<?> class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass(); // <-- cursed
|
||||
Field f_replacer = class_baseExtension.getDeclaredField("replacer");
|
||||
f_replacer.setAccessible(true);
|
||||
Object replacer = f_replacer.get(extension);
|
||||
Class<?> class_replacementProvider = replacer.getClass();
|
||||
Field replacement_replaceMap = class_replacementProvider.getDeclaredField("replaceMap");
|
||||
replacement_replaceMap.setAccessible(true);
|
||||
|
||||
Map<String, Object> replacements = (Map) replacement_replaceMap.get(replacer);
|
||||
String cacheDir = replacements.get("CACHE_DIR").toString() + "/net/minecraft";
|
||||
String mcVersion = replacements.get("MC_VERSION").toString();
|
||||
String mcpInsert = replacements.get("MAPPING_CHANNEL").toString() + "/" + replacements.get("MAPPING_VERSION").toString();
|
||||
String fullJarName = "minecraft-" + mcVersion + suffix + ".jar";
|
||||
|
||||
String baseDir = String.format("%s/minecraft/%s/", cacheDir, mcVersion);
|
||||
|
||||
String jarPath;
|
||||
if (mappingType == MappingType.SEARGE) {
|
||||
jarPath = String.format("%s/%s/%s", baseDir, mcpInsert, fullJarName);
|
||||
} else {
|
||||
jarPath = baseDir + fullJarName;
|
||||
}
|
||||
jarPath = jarPath
|
||||
.replace("/", File.separator)
|
||||
.replace("\\", File.separator); // hecking regex
|
||||
|
||||
return new File(jarPath).toPath();
|
||||
return getObfuscatedMinecraftJar(getProject(), false); // always notch jar for now.
|
||||
}
|
||||
|
||||
// throws IllegalStateException if mapping type is ambiguous or it fails to find it
|
||||
private MappingType getMappingType() {
|
||||
// if it fails to find this then its probably a forgegradle version problem
|
||||
Set<Object> reobf = (NamedDomainObjectContainer<Object>) this.getProject().getExtensions().getByName("reobf");
|
||||
private static Path getObfuscatedMinecraftJar(final Project project, final boolean srg) throws Exception {
|
||||
final Object extension = Objects.requireNonNull(project.getExtensions().findByName("minecraft"), "Unable to find Minecraft extension.");
|
||||
|
||||
List<MappingType> mappingTypes = getUsedMappingTypes(reobf);
|
||||
long mappingTypesUsed = mappingTypes.size();
|
||||
if (mappingTypesUsed == 0) {
|
||||
throw new IllegalStateException("Failed to find mapping type (no jar task?)");
|
||||
}
|
||||
if (mappingTypesUsed > 1) {
|
||||
throw new IllegalStateException("Ambiguous mapping type (multiple jars with different mapping types?)");
|
||||
}
|
||||
final Class<?> mcpRepoClass = mcpRepoClass(extension.getClass().getClassLoader());
|
||||
final Field mcpRepoInstanceField = mcpRepoClass.getDeclaredField("INSTANCE");
|
||||
mcpRepoInstanceField.setAccessible(true);
|
||||
final Method findMethod = mcpRepoClass.getDeclaredMethod(srg ? "findSrg" : "findRaw", String.class, String.class);
|
||||
findMethod.setAccessible(true);
|
||||
|
||||
return mappingTypes.get(0);
|
||||
final Object mcpRepo = mcpRepoInstanceField.get(null);
|
||||
final String mcpVersion = (String) Objects.requireNonNull(project.getExtensions().getExtraProperties().get("MCP_VERSION"), "Extra property \"MCP_VERSION\" not found");
|
||||
return ((File) findMethod.invoke(mcpRepo, "joined", mcpVersion)).toPath();
|
||||
}
|
||||
|
||||
private List<MappingType> getUsedMappingTypes(Set<Object> reobf) {
|
||||
return reobf.stream()
|
||||
.map(ReobfWrapper::new)
|
||||
.map(ReobfWrapper::getMappingType)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
private static Class<?> mcpRepoClass(final ClassLoader loader) throws Exception {
|
||||
final Method forName0 = Class.class.getDeclaredMethod("forName0", String.class, boolean.class, ClassLoader.class, Class.class);
|
||||
forName0.setAccessible(true);
|
||||
return (Class<?>) forName0.invoke(null, "net.minecraftforge.gradle.mcp.MCPRepo", true, loader, null);
|
||||
}
|
||||
|
||||
private void proguardApi() throws Exception {
|
||||
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Arrays.asList(pathfinder), false);
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Arrays.asList(pathfinder, mixin), true);
|
||||
}
|
||||
|
||||
private void proguardStandalone() throws Exception {
|
||||
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Arrays.asList(pathfinder), false);
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Arrays.asList(pathfinder, mixin), true);
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
@@ -397,10 +341,18 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setExtract(String extract) {
|
||||
this.extract = extract;
|
||||
}
|
||||
|
||||
public String getExtract() {
|
||||
return 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)) {
|
||||
@@ -411,7 +363,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
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())
|
||||
@@ -425,6 +377,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
// 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) {
|
||||
Thread.sleep(1000);
|
||||
throw new IllegalStateException("Proguard exited with code " + exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,10 @@ import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
@@ -36,10 +39,11 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class Determinizer {
|
||||
|
||||
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) 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));
|
||||
@@ -60,10 +64,10 @@ public class Determinizer {
|
||||
JarEntry clone = new JarEntry(entry.getName());
|
||||
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());
|
||||
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && toInclude.isPresent()) { // only replace for forge jar
|
||||
if (entry.getName().endsWith(".json")) {
|
||||
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());
|
||||
@@ -76,8 +80,8 @@ public class Determinizer {
|
||||
copy(jarFile.getInputStream(entry), jos);
|
||||
}
|
||||
}
|
||||
if (toInclude.isPresent()) {
|
||||
try (JarFile mixin = new JarFile(toInclude.get())) {
|
||||
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;
|
||||
@@ -89,6 +93,7 @@ public class Determinizer {
|
||||
}
|
||||
jos.finish();
|
||||
}
|
||||
System.out.println("Done with determinizer");
|
||||
}
|
||||
|
||||
private static void copy(InputStream is, OutputStream os) throws IOException {
|
||||
@@ -99,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);
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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.gradle.util;
|
||||
|
||||
/**
|
||||
* All credits go to AsmLibGradle and its contributors.
|
||||
*
|
||||
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/MappingType.java">Original Source</a>
|
||||
*/
|
||||
public enum MappingType {
|
||||
SEARGE,
|
||||
NOTCH,
|
||||
CUSTOM // forgegradle
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* 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.gradle.util;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* All credits go to AsmLibGradle and its contributors.
|
||||
*
|
||||
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/ReobfWrapper.java">Original Source</a>
|
||||
*/
|
||||
public class ReobfWrapper {
|
||||
|
||||
private final Object instance;
|
||||
private final Class<?> type;
|
||||
|
||||
public ReobfWrapper(Object instance) {
|
||||
this.instance = instance;
|
||||
Objects.requireNonNull(instance);
|
||||
this.type = instance.getClass();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
try {
|
||||
Field nameField = type.getDeclaredField("name");
|
||||
nameField.setAccessible(true);
|
||||
return (String) nameField.get(this.instance);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public MappingType getMappingType() {
|
||||
try {
|
||||
Field enumField = type.getDeclaredField("mappingType");
|
||||
enumField.setAccessible(true);
|
||||
Enum<?> aEnum = (Enum<?>) enumField.get(this.instance);
|
||||
MappingType mappingType = MappingType.values()[aEnum.ordinal()];
|
||||
if (!aEnum.name().equals(mappingType.name())) {
|
||||
throw new IllegalStateException("ForgeGradle ReobfMappingType is not equivalent to MappingType (version error?)");
|
||||
}
|
||||
return mappingType;
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,5 @@
|
||||
#Tue Jul 31 21:56:56 PDT 2018
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip
|
||||
|
||||
55
gradlew
vendored
55
gradlew
vendored
@@ -1,5 +1,21 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
@@ -56,7 +72,7 @@ case "`uname`" in
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
MSYS* | MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
@@ -66,6 +82,7 @@ esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
@@ -109,10 +126,11 @@ if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
@@ -138,19 +156,19 @@ if $cygwin ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -159,14 +177,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
43
gradlew.bat
vendored
43
gradlew.bat
vendored
@@ -1,3 +1,19 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -35,7 +54,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@@ -45,28 +64,14 @@ echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
161
hacks.gradle
Normal file
161
hacks.gradle
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
ext.doHackyStuff = { final Class<?> clazz ->
|
||||
def withExtension = { final File file, final String extension ->
|
||||
def i = file.getName().lastIndexOf('.')
|
||||
def name = file.getName().substring(0, i)
|
||||
return new File(file.getParent(), "$name.$extension")
|
||||
}
|
||||
|
||||
// https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/patcher/java/net/minecraftforge/gradle/patcher/PatcherPlugin.java#L545
|
||||
// https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/userdev/java/net/minecraftforge/gradle/userdev/UserDevPlugin.java#L149
|
||||
// create createMcp2Obf task
|
||||
this.tasks.register('createMcpToObf', clazz)
|
||||
.configure { task ->
|
||||
task.setNotch(true)
|
||||
task.setReverse(true)
|
||||
}
|
||||
afterEvaluate {
|
||||
def createMcp2Obf = this.tasks.getByName('createMcpToObf')
|
||||
def createMcp2Srg = this.tasks.getByName('createMcpToSrg')
|
||||
|
||||
// configure createMcp2Obf task
|
||||
if (createMcp2Obf.getSrg() == null) {
|
||||
createMcp2Obf.setSrg(createMcp2Srg.getSrg())
|
||||
createMcp2Obf.setMappings(createMcp2Srg.getMappings())
|
||||
createMcp2Obf.dependsOn(createMcp2Srg)
|
||||
}
|
||||
|
||||
def createSrgCopyTask = { final Task tsrgTask ->
|
||||
def srgCopyTask = this.tasks.register("${tsrgTask.name}Srg", tsrgTask.getClass())
|
||||
tsrgTask.getDependsOn().forEach({ dep ->
|
||||
srgCopyTask.get().dependsOn(dep)
|
||||
})
|
||||
// https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/mcp/java/net/minecraftforge/gradle/mcp/task/GenerateSRG.java#L39
|
||||
srgCopyTask.configure { task ->
|
||||
task.setSrg(tsrgTask.getSrg())
|
||||
task.setMappings(tsrgTask.getMappings())
|
||||
// https://github.com/MinecraftForge/SrgUtils/blob/bb2ca35bb8d349a122ef512dedd24f54f7cd0bdf/src/main/java/net/minecraftforge/srgutils/IMappingFile.java#L44
|
||||
task.setFormat('SRG')
|
||||
task.setNotch(tsrgTask.getNotch())
|
||||
task.setReverse(tsrgTask.getReverse())
|
||||
task.setOutput(withExtension(tsrgTask.getOutput(), 'srg'))
|
||||
}
|
||||
return srgCopyTask
|
||||
}
|
||||
def createMcp2ObfSrgCopyTask = createSrgCopyTask(createMcp2Obf)
|
||||
createMcp2Obf.dependsOn(createMcp2ObfSrgCopyTask)
|
||||
def createMcp2SrgSrgCopyTask = createSrgCopyTask(createMcp2Srg)
|
||||
createMcp2Srg.dependsOn(createMcp2SrgSrgCopyTask)
|
||||
|
||||
this.sourceSets.forEach({ set ->
|
||||
def compileTask = this.project.tasks[set.compileJavaTaskName]
|
||||
if (!(compileTask instanceof JavaCompile)) {
|
||||
println("[Baritoe] Non-java compile task for ${set} of type ${compileTask}")
|
||||
return
|
||||
}
|
||||
compileTask.dependsOn(createMcp2Obf)
|
||||
compileTask.doFirst {
|
||||
// inject legacy notch srg file
|
||||
def createMcp2ObfSrgCopy = createMcp2ObfSrgCopyTask.get()
|
||||
def reobfNotchSrgFileArgument = "-AreobfNotchSrgFile=${createMcp2ObfSrgCopy.output.canonicalPath}"
|
||||
compileTask.options.compilerArgs += reobfNotchSrgFileArgument
|
||||
println("[Baritoe] Injecting compiler argument: ${reobfNotchSrgFileArgument}")
|
||||
|
||||
// inject legacy notch srg out file
|
||||
def outTSrgFileArgument = '-AoutTsrgFile='
|
||||
def compilerArgsIterator = compileTask.options.compilerArgs.listIterator()
|
||||
while (compilerArgsIterator.hasNext()) {
|
||||
def compilerArg = compilerArgsIterator.next()
|
||||
if (compilerArg.startsWith(outTSrgFileArgument)) {
|
||||
def argumentFileValue = new File(compilerArg.substring(outTSrgFileArgument.length(), compilerArg.length()))
|
||||
def outNotchSrgFile = withExtension(argumentFileValue, 'notch.srg')
|
||||
def outNotchSrgFileArgument = "-AoutNotchSrgFile=${outNotchSrgFile.canonicalPath}"
|
||||
println("[Baritoe] Injecting compiler argument: ${outNotchSrgFileArgument}")
|
||||
compilerArgsIterator.add(outNotchSrgFileArgument)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// register reobf jars
|
||||
def reobfExtension = this.project.getExtensions().getByName('reobf')
|
||||
if (!reobfExtension) {
|
||||
throw new IllegalStateException("Could not find \"reobf\" extension")
|
||||
}
|
||||
def reobfNotchJar = reobfExtension.create(jar.getName())
|
||||
reobfNotchJar.dependsOn(createMcp2Obf)
|
||||
reobfNotchJar.setMappings(createMcp2Obf.getOutput())
|
||||
|
||||
// even more horrible hack :) for outNotchSrgFile injection
|
||||
reobfNotchJar.doFirst {
|
||||
// https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/userdev/java/net/minecraftforge/gradle/userdev/tasks/RenameJar.java#L96
|
||||
def extraMappings = reobfNotchJar.getExtraMappings()
|
||||
println("[Baritoe] Extra mappings: ${extraMappings}")
|
||||
def copy = new ArrayList<>()
|
||||
extraMappings.forEach { extraMapping ->
|
||||
copy.add(withExtension(extraMapping, 'notch.srg'))
|
||||
}
|
||||
println("[Baritoe] New extra mappings: ${copy}")
|
||||
reobfNotchJar.setExtraMappings(copy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: In-complete fg 5.0 port. Currently doesn't handle mixin notch srg mapping hack.
|
||||
//ext.doHackyStuff = { final Class<?> clazz ->
|
||||
// afterEvaluate {
|
||||
// def createMcp2Srg = this.tasks.getByName('createMcpToSrg')
|
||||
// def createMcpToObf = this.tasks.register('createMcpToObf', clazz)
|
||||
// createMcpToObf.configure { task ->
|
||||
// task.setNotch(true)
|
||||
// task.setReverse(true)
|
||||
// task.getSrg().set(createMcp2Srg.getSrg().get())
|
||||
// task.getMappings().set(createMcp2Srg.getMappings().get())
|
||||
// task.dependsOn(createMcp2Srg)
|
||||
// }
|
||||
// reobf {
|
||||
// jar {
|
||||
// dependsOn(createMcpToObf)
|
||||
// getMappings().set(createMcpToObf.get().getOutput().get())
|
||||
// }
|
||||
// }
|
||||
// this.sourceSets.forEach({ set ->
|
||||
// def compileTask = this.project.tasks[set.compileJavaTaskName]
|
||||
// if (!(compileTask instanceof JavaCompile)) {
|
||||
// println("[Baritoe] Non-java compile task for ${set} of type ${compileTask}")
|
||||
// return
|
||||
// }
|
||||
// compileTask.dependsOn(createMcpToObf)
|
||||
// compileTask.doFirst {
|
||||
// def reobfTSrgFile = '-AreobfTsrgFile='
|
||||
// def compilerArgsIterator = compileTask.options.compilerArgs.listIterator()
|
||||
// while (compilerArgsIterator.hasNext()) {
|
||||
// def compilerArg = compilerArgsIterator.next()
|
||||
// if (compilerArg.startsWith(reobfTSrgFile)) {
|
||||
// compilerArgsIterator.remove()
|
||||
// def toInject = "-AreobfTsrgFile=${createMcpToObf.get().output.get().asFile.canonicalPath}"
|
||||
// compilerArgsIterator.add(toInject)
|
||||
// println("[Baritoe] Injecting compiler argument: ${toInject}")
|
||||
// }
|
||||
// }
|
||||
// println("[Baritoe] Compiler arguments: ${compileTask.options.compilerArgs}")
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//}
|
||||
4
scripts/proguard.pro
vendored
4
scripts/proguard.pro
vendored
@@ -92,9 +92,9 @@
|
||||
-libraryjars 'tempLibraries/text2speech-1.10.3.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar'
|
||||
-libraryjars 'tempLibraries/launchwrapper-1.11.jar' # TODO why does only 1.11.jar exist?
|
||||
|
||||
-libraryjars 'tempLibraries/launchwrapper-1.12.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/nether-pathfinder-.jar'
|
||||
|
||||
|
||||
# Keep - Applications. Keep all application classes, along with their 'main'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
|
||||
package baritone.api;
|
||||
|
||||
import baritone.api.bot.IUserManager;
|
||||
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.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -83,6 +83,22 @@ public interface IBaritoneProvider {
|
||||
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(NetHandlerPlayClient connection) {
|
||||
for (IBaritone baritone : this.getAllBaritones()) {
|
||||
final EntityPlayerSP 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.
|
||||
@@ -109,11 +125,6 @@ public interface IBaritoneProvider {
|
||||
*/
|
||||
IWorldScanner getWorldScanner();
|
||||
|
||||
/**
|
||||
* @return The {@link IUserManager} instance.
|
||||
*/
|
||||
IUserManager getUserManager();
|
||||
|
||||
/**
|
||||
* Returns the {@link ICommandSystem} instance. This is not bound to a specific {@link IBaritone}
|
||||
* instance because {@link ICommandSystem} itself controls global behavior for {@link ICommand}s.
|
||||
|
||||
@@ -38,6 +38,7 @@ import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -622,6 +623,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
|
||||
*/
|
||||
@@ -724,11 +732,30 @@ public final class Settings {
|
||||
public final Setting<Boolean> freeLook = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Break and place blocks without having to force the client-sided rotations. Having this setting enabled implies
|
||||
* {@link #freeLook}.
|
||||
* 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<>(false);
|
||||
|
||||
/**
|
||||
* 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<>(true);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -1289,13 +1316,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> desktopNotifications = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Having this setting enabled keeps vanilla collision working. If disabled, bots will ignore
|
||||
* collision boxes and be able to walk inside each other without issues. This should only be
|
||||
* disabled when multiple bots are are needed to simultaneously use narrow tunnels.
|
||||
*/
|
||||
public final Setting<Boolean> botCollision = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Desktop notification on path complete
|
||||
*/
|
||||
@@ -1321,6 +1341,115 @@ 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<>(true);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* A map of lowercase setting field names to their respective setting
|
||||
*/
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* 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.bot;
|
||||
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.util.Session;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 10/23/2018
|
||||
*/
|
||||
public interface IBaritoneUser {
|
||||
|
||||
/**
|
||||
* @return The Baritone instance
|
||||
*/
|
||||
IBaritone getBaritone();
|
||||
|
||||
/**
|
||||
* Returns the player context. Equivalent to {@code getBaritone().getPlayerContext()}.
|
||||
*
|
||||
* @return The player context
|
||||
*/
|
||||
IPlayerContext getPlayerContext();
|
||||
|
||||
/**
|
||||
* @return The network manager that is responsible for the current connection.
|
||||
*/
|
||||
NetworkManager getNetworkManager();
|
||||
|
||||
/**
|
||||
* Returns the user login session. Should never be {@code null}, as this should be set when the
|
||||
* user is constructed.
|
||||
*
|
||||
* @return This users's login session
|
||||
*/
|
||||
Session getSession();
|
||||
|
||||
/**
|
||||
* Returns the game profile for the account represented by this user.
|
||||
*
|
||||
* @return This users's profile.
|
||||
*/
|
||||
GameProfile getProfile();
|
||||
|
||||
/**
|
||||
* @return The manager that spawned this {@link IBaritoneUser}.
|
||||
*/
|
||||
IUserManager getManager();
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* 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.bot;
|
||||
|
||||
import baritone.api.bot.connect.ConnectionStatus;
|
||||
import baritone.api.bot.connect.IConnectionResult;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.util.Session;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 1/17/2019
|
||||
*/
|
||||
public interface IUserManager {
|
||||
|
||||
/**
|
||||
* Connects a new user with the specified {@link Session} to the current server. Returns
|
||||
* a {@link IConnectionResult} describing the result of the attempted connection as well
|
||||
* as a {@link IBaritoneUser} instance if it was {@link ConnectionStatus#SUCCESS}.
|
||||
*
|
||||
* @param session The user session
|
||||
* @return The result of the attempted connection
|
||||
*/
|
||||
IConnectionResult connect(Session session);
|
||||
|
||||
/**
|
||||
* Disconnects the specified {@link IBaritoneUser} from its current server. All valid users
|
||||
* are automatically disconnected when the current game state becomes {@link TickEvent.Type#OUT}.
|
||||
* A reason may be specified, but is more widely used in server-initiated disconnects.
|
||||
*
|
||||
* @param user The user to disconnect
|
||||
* @param reason The reason for the disconnect, may be {@code null}
|
||||
*/
|
||||
void disconnect(IBaritoneUser user, ITextComponent reason);
|
||||
|
||||
/**
|
||||
* Finds the {@link IBaritoneUser} associated with the specified {@link GameProfile}
|
||||
*
|
||||
* @param profile The game profile of the user
|
||||
* @return The user, {@link Optional#empty()} if no match or {@code profile} is {@code null}
|
||||
*/
|
||||
default Optional<IBaritoneUser> getUserByProfile(GameProfile profile) {
|
||||
return profile == null
|
||||
? Optional.empty()
|
||||
: this.getUsers().stream().filter(user -> user.getProfile().equals(profile)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the {@link IBaritoneUser} associated with the specified {@link UUID}
|
||||
*
|
||||
* @param uuid The uuid of the user
|
||||
* @return The user, {@link Optional#empty()} if no match or {@code uuid} is {@code null}
|
||||
*/
|
||||
default Optional<IBaritoneUser> getUserByUUID(UUID uuid) {
|
||||
return uuid == null
|
||||
? Optional.empty()
|
||||
: this.getUsers().stream().filter(user -> user.getProfile().getId().equals(uuid)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the {@link IBaritoneUser} associated with the specified username
|
||||
*
|
||||
* @param username The username of the user
|
||||
* @return The user, {@link Optional#empty()} if no match or {@code uuid} is {@code null}
|
||||
*/
|
||||
default Optional<IBaritoneUser> getUserByName(String username) {
|
||||
return username == null || username.isEmpty()
|
||||
? Optional.empty()
|
||||
: this.getUsers().stream().filter(user -> user.getProfile().getName().equalsIgnoreCase(username)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return All of the users held by this manager
|
||||
*/
|
||||
List<IBaritoneUser> getUsers();
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* 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.bot.connect;
|
||||
|
||||
import baritone.api.bot.IBaritoneUser;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 1/17/2019
|
||||
*/
|
||||
public interface IConnectionResult {
|
||||
|
||||
/**
|
||||
* @return The actual status of the connection attempt.
|
||||
* @see ConnectionStatus
|
||||
*/
|
||||
ConnectionStatus getStatus();
|
||||
|
||||
/**
|
||||
* Returns the user that was created in this connection this result reflects, if
|
||||
* {@link #getStatus()} is {@link ConnectionStatus#SUCCESS}, otherwise it will
|
||||
* return {@link Optional#empty()}.
|
||||
*
|
||||
* @return The user created in the connection
|
||||
*/
|
||||
Optional<IBaritoneUser> getUser();
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package baritone.api.command.exception;
|
||||
|
||||
import baritone.api.command.ICommand;
|
||||
import baritone.api.command.argument.ICommandArgument;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -37,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",
|
||||
TextFormatting.RED);
|
||||
|
||||
this.printStackTrace();
|
||||
HELPER.logUnhandledException(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,29 +15,33 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.bot.impl;
|
||||
package baritone.api.event.events;
|
||||
|
||||
import net.minecraft.client.particle.ParticleManager;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import baritone.api.utils.Pair;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/8/2020
|
||||
*/
|
||||
public final class BotParticleManager extends ParticleManager {
|
||||
public final class BlockChangeEvent {
|
||||
|
||||
public static final BotParticleManager INSTANCE = new BotParticleManager();
|
||||
private final ChunkPos chunk;
|
||||
private final List<Pair<BlockPos, IBlockState>> blocks;
|
||||
|
||||
private BotParticleManager() {
|
||||
super(null, null);
|
||||
public BlockChangeEvent(ChunkPos pos, List<Pair<BlockPos, IBlockState>> blocks) {
|
||||
this.chunk = pos;
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitParticleAtEntity(Entity entityIn, @Nonnull EnumParticleTypes particleTypes) {}
|
||||
public ChunkPos getChunkPos() {
|
||||
return this.chunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitParticleAtEntity(Entity p_191271_1_, @Nonnull EnumParticleTypes p_191271_2_, int p_191271_3_) {}
|
||||
public List<Pair<BlockPos, IBlockState>> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
|
||||
@@ -41,6 +41,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.
|
||||
*
|
||||
@@ -72,6 +80,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. Two passes are made when {@link GameSettings#anaglyph} is on.
|
||||
* <p>
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -15,36 +15,36 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.bot.connect;
|
||||
package baritone.api.process;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 11/6/2018
|
||||
*/
|
||||
public enum ConnectionStatus {
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public interface IElytraProcess extends IBaritoneProcess {
|
||||
|
||||
void repackChunks();
|
||||
|
||||
/**
|
||||
* The local player is not connected to a server, therefore, there is no target server to connect to.
|
||||
* @return Where it is currently flying to, null if not active
|
||||
*/
|
||||
NO_CURRENT_CONNECTION,
|
||||
BlockPos currentDestination();
|
||||
|
||||
void pathTo(BlockPos destination);
|
||||
|
||||
void pathTo(Goal destination);
|
||||
|
||||
/**
|
||||
* The IP of the targetted address to connect to could not be resolved.
|
||||
* Resets the state of the process but will maintain the same destination and will try to keep flying
|
||||
*/
|
||||
CANT_RESOLVE_HOST,
|
||||
void resetState();
|
||||
|
||||
/**
|
||||
* The port for the detected LAN server could not be resolved.
|
||||
* @return {@code true} if the native library loaded and elytra is actually usable
|
||||
*/
|
||||
CANT_RESOLVE_LAN,
|
||||
boolean isLoaded();
|
||||
|
||||
/**
|
||||
* The connection initialization failed.
|
||||
/*
|
||||
* FOR INTERNAL USE ONLY. MAY BE REMOVED AT ANY TIME.
|
||||
*/
|
||||
CONNECTION_FAILED,
|
||||
|
||||
/**
|
||||
* The connection was a success
|
||||
*/
|
||||
SUCCESS
|
||||
boolean isSafeToCancel();
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -35,6 +35,15 @@ import javax.annotation.Nonnull;
|
||||
*/
|
||||
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;
|
||||
@@ -202,6 +211,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() {
|
||||
@@ -212,4 +235,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,4 +230,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",
|
||||
TextFormatting.RED);
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,10 @@ public interface IPlayerContext {
|
||||
return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ);
|
||||
}
|
||||
|
||||
default Vec3d playerMotion() {
|
||||
return new Vec3d(player().motionX, player().motionY, player().motionZ);
|
||||
}
|
||||
|
||||
BetterBlockPos viewerPos();
|
||||
|
||||
default Rotation playerRotations() {
|
||||
|
||||
@@ -46,8 +46,6 @@ public interface IPlayerController {
|
||||
|
||||
ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player);
|
||||
|
||||
void setGameType(GameType type);
|
||||
|
||||
GameType getGameType();
|
||||
|
||||
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);
|
||||
|
||||
@@ -15,29 +15,45 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch.mixins;
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.utils.accessor.IGameSettings;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.entity.player.EnumPlayerModelParts;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/6/2020
|
||||
*/
|
||||
@Mixin(GameSettings.class)
|
||||
public abstract class MixinGameSettings implements IGameSettings {
|
||||
public final class Pair<A, B> {
|
||||
|
||||
@Accessor
|
||||
@Override
|
||||
public abstract void setSetModelParts(Set<EnumPlayerModelParts> setModelParts);
|
||||
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;
|
||||
}
|
||||
|
||||
@Accessor
|
||||
@Override
|
||||
public abstract void setMc(Minecraft mc);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public final class RayTraceUtils {
|
||||
} else {
|
||||
start = entity.getPositionEyes(1.0F); // do whatever is correct
|
||||
}
|
||||
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
|
||||
Vec3d direction = RotationUtils.calcLookDirectionFromRotation(rotation);
|
||||
Vec3d end = start.add(
|
||||
direction.x * blockReachDistance,
|
||||
direction.y * blockReachDistance,
|
||||
|
||||
@@ -37,11 +37,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.
|
||||
@@ -122,12 +124,17 @@ public final class RotationUtils {
|
||||
* @param rotation The input rotation
|
||||
* @return Look vector for the rotation
|
||||
*/
|
||||
public static Vec3d calcLookDirectionFromRotation(Rotation rotation) {
|
||||
float flatZ = MathHelper.cos((-rotation.getYaw() * DEG_TO_RAD_F) - (float) Math.PI);
|
||||
float flatX = MathHelper.sin((-rotation.getYaw() * DEG_TO_RAD_F) - (float) Math.PI);
|
||||
float pitchBase = -MathHelper.cos(-rotation.getPitch() * DEG_TO_RAD_F);
|
||||
float pitchHeight = MathHelper.sin(-rotation.getPitch() * DEG_TO_RAD_F);
|
||||
return new Vec3d(flatX * pitchBase, pitchHeight, flatZ * pitchBase);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Vec3d calcVec3dFromRotation(Rotation rotation) {
|
||||
float f = MathHelper.cos(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
|
||||
float f1 = MathHelper.sin(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
|
||||
float f2 = -MathHelper.cos(-rotation.getPitch() * (float) DEG_TO_RAD);
|
||||
float f3 = MathHelper.sin(-rotation.getPitch() * (float) DEG_TO_RAD);
|
||||
return new Vec3d((double) (f1 * f2), (double) f3, (double) (f * f2));
|
||||
return calcLookDirectionFromRotation(rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.IEntityFireworkRocket;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityFireworkRocket;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(EntityFireworkRocket.class)
|
||||
public abstract class MixinEntityFireworkRocket extends Entity implements IEntityFireworkRocket {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private static DataParameter<Integer> BOOSTED_ENTITY_ID;
|
||||
|
||||
@Shadow
|
||||
private EntityLivingBase boostedEntity;
|
||||
|
||||
@Shadow
|
||||
public abstract boolean isAttachedToEntity();
|
||||
|
||||
private MixinEntityFireworkRocket(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityLivingBase getBoostedEntity() {
|
||||
if (this.isAttachedToEntity() && this.boostedEntity == null) {
|
||||
final Entity entity = this.world.getEntityByID(this.dataManager.get(BOOSTED_ENTITY_ID));
|
||||
if (entity instanceof EntityLivingBase) {
|
||||
this.boostedEntity = (EntityLivingBase) entity;
|
||||
}
|
||||
}
|
||||
return this.boostedEntity;
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ public abstract class MixinEntityLivingBase extends Entity {
|
||||
@Unique
|
||||
private RotationMoveEvent elytraRotationEvent;
|
||||
|
||||
public MixinEntityLivingBase(World worldIn) {
|
||||
private MixinEntityLivingBase(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,8 @@ public abstract class MixinEntityLivingBase extends Entity {
|
||||
private void onMoveRelative(EntityLivingBase self, float strafe, float up, float forward, float friction) {
|
||||
Optional<IBaritone> baritone = this.getBaritone();
|
||||
if (!baritone.isPresent()) {
|
||||
moveRelative(strafe, up, forward, friction);
|
||||
// If a shadow is used here it breaks on Forge
|
||||
this.moveRelative(strafe, up, forward, friction);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ import baritone.behavior.LookBehavior;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.entity.player.PlayerCapabilities;
|
||||
import net.minecraft.item.ItemElytra;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
@@ -123,4 +125,19 @@ public class MixinEntityPlayerSP {
|
||||
((LookBehavior) baritone.getLookBehavior()).pig();
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "onLivingUpdate",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/item/ItemElytra.isUsable(Lnet/minecraft/item/ItemStack;)Z"
|
||||
)
|
||||
)
|
||||
private boolean isElytraUsable(ItemStack stack) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
|
||||
if (baritone != null && baritone.getPathingBehavior().isPathing()) {
|
||||
return false;
|
||||
}
|
||||
return ItemElytra.isUsable(stack);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.RenderEvent;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
@@ -39,13 +38,7 @@ public class MixinEntityRenderer {
|
||||
)
|
||||
)
|
||||
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
||||
int renderViewDimension = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().provider.getDimensionType().getId();
|
||||
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
World world = ibaritone.getPlayerContext().world();
|
||||
if (world == null || world.provider.getDimensionType().getId() != renderViewDimension) {
|
||||
continue;
|
||||
}
|
||||
ibaritone.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* 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.IIntegratedServer;
|
||||
import net.minecraft.client.multiplayer.ThreadLanServerPing;
|
||||
import net.minecraft.server.integrated.IntegratedServer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/4/2020
|
||||
*/
|
||||
@Mixin(IntegratedServer.class)
|
||||
public abstract class MixinIntegratedServer implements IIntegratedServer {
|
||||
|
||||
@Accessor
|
||||
@Override
|
||||
public abstract ThreadLanServerPing getLanServerPing();
|
||||
}
|
||||
@@ -24,7 +24,6 @@ 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;
|
||||
import baritone.utils.accessor.IMinecraft;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
@@ -34,17 +33,16 @@ import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.spongepowered.asm.lib.Opcodes;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
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 org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
@@ -52,7 +50,7 @@ import java.util.function.BiFunction;
|
||||
* @since 7/31/2018
|
||||
*/
|
||||
@Mixin(Minecraft.class)
|
||||
public class MixinMinecraft implements IMinecraft {
|
||||
public class MixinMinecraft {
|
||||
|
||||
@Shadow
|
||||
public EntityPlayerSP player;
|
||||
@@ -60,10 +58,8 @@ public class MixinMinecraft implements IMinecraft {
|
||||
@Shadow
|
||||
public WorldClient world;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
@Mutable
|
||||
public File gameDir;
|
||||
@Unique
|
||||
private BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider;
|
||||
|
||||
@Inject(
|
||||
method = "init",
|
||||
@@ -79,24 +75,47 @@ public class MixinMinecraft implements IMinecraft {
|
||||
value = "FIELD",
|
||||
opcode = Opcodes.GETFIELD,
|
||||
target = "net/minecraft/client/Minecraft.currentScreen:Lnet/minecraft/client/gui/GuiScreen;",
|
||||
ordinal = 5,
|
||||
shift = At.Shift.BY,
|
||||
by = -3
|
||||
ordinal = 0,
|
||||
shift = At.Shift.BEFORE
|
||||
),
|
||||
slice = @Slice(
|
||||
from = @At(
|
||||
value = "FIELD",
|
||||
opcode = Opcodes.PUTFIELD,
|
||||
target = "net/minecraft/client/Minecraft.leftClickCounter:I"
|
||||
)
|
||||
)
|
||||
)
|
||||
private void runTick(CallbackInfo ci) {
|
||||
final BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider = TickEvent.createNextProvider();
|
||||
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(tickProvider.apply(EventState.PRE, type));
|
||||
baritone.getGameEventHandler().onTick(this.tickProvider.apply(EventState.PRE, type));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "runTick",
|
||||
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 = "runTick",
|
||||
at = @At(
|
||||
@@ -108,6 +127,8 @@ public class MixinMinecraft implements IMinecraft {
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -186,9 +207,4 @@ public class MixinMinecraft implements IMinecraft {
|
||||
// rightClickMouse is only for the main player
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(blockpos, BlockInteractEvent.Type.USE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGameDir(File gameDir) {
|
||||
this.gameDir = gameDir;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,37 +17,35 @@
|
||||
|
||||
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.ChunkEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.cache.CachedChunk;
|
||||
import baritone.utils.accessor.INetHandlerPlayClient;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import baritone.api.utils.Pair;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.network.play.server.SPacketBlockChange;
|
||||
import net.minecraft.network.play.server.SPacketChunkData;
|
||||
import net.minecraft.network.play.server.SPacketCombatEvent;
|
||||
import net.minecraft.network.play.server.SPacketMultiBlockChange;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
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.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/3/2018
|
||||
*/
|
||||
@Mixin(NetHandlerPlayClient.class)
|
||||
public abstract class MixinNetHandlerPlayClient implements INetHandlerPlayClient {
|
||||
|
||||
@Accessor
|
||||
@Override
|
||||
public abstract void setWorld(WorldClient world);
|
||||
public class MixinNetHandlerPlayClient {
|
||||
|
||||
@Inject(
|
||||
method = "handleChunkData",
|
||||
@@ -57,19 +55,18 @@ public abstract class MixinNetHandlerPlayClient implements INetHandlerPlayClient
|
||||
)
|
||||
)
|
||||
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
EntityPlayerSP player = ibaritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.PRE,
|
||||
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
|
||||
packetIn.getChunkX(),
|
||||
packetIn.getChunkZ()
|
||||
)
|
||||
);
|
||||
}
|
||||
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(
|
||||
@@ -77,19 +74,18 @@ public abstract class MixinNetHandlerPlayClient implements INetHandlerPlayClient
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
EntityPlayerSP player = ibaritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
|
||||
packetIn.getChunkX(),
|
||||
packetIn.getChunkZ()
|
||||
)
|
||||
);
|
||||
}
|
||||
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(
|
||||
@@ -97,25 +93,14 @@ public abstract class MixinNetHandlerPlayClient implements INetHandlerPlayClient
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postHandleBlockChange(SPacketBlockChange packetIn, CallbackInfo ci) {
|
||||
if (!Baritone.settings().repackOnAnyBlockChange.value) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
|
||||
if (baritone == null) {
|
||||
return;
|
||||
}
|
||||
if (!CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(packetIn.getBlockState().getBlock())) {
|
||||
return;
|
||||
}
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
EntityPlayerSP player = ibaritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
ChunkEvent.Type.POPULATE_FULL,
|
||||
packetIn.getBlockPosition().getX() >> 4,
|
||||
packetIn.getBlockPosition().getZ() >> 4
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
@@ -123,35 +108,20 @@ public abstract class MixinNetHandlerPlayClient implements INetHandlerPlayClient
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postHandleMultiBlockChange(SPacketMultiBlockChange packetIn, CallbackInfo ci) {
|
||||
if (!Baritone.settings().repackOnAnyBlockChange.value) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
|
||||
if (baritone == null) {
|
||||
return;
|
||||
}
|
||||
if (packetIn.getChangedBlocks().length == 0) {
|
||||
return;
|
||||
}
|
||||
https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.15
|
||||
{
|
||||
for (SPacketMultiBlockChange.BlockUpdateData update : packetIn.getChangedBlocks()) {
|
||||
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(update.getBlockState().getBlock())) {
|
||||
break https;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
ChunkPos pos = new ChunkPos(packetIn.getChangedBlocks()[0].getPos());
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
EntityPlayerSP player = ibaritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
ChunkEvent.Type.POPULATE_FULL,
|
||||
pos.x,
|
||||
pos.z
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// All blocks have the same ChunkPos
|
||||
final ChunkPos pos = new ChunkPos(packetIn.getChangedBlocks()[0].getPos());
|
||||
|
||||
baritone.getGameEventHandler().onBlockChange(new BlockChangeEvent(
|
||||
pos,
|
||||
Arrays.stream(packetIn.getChangedBlocks())
|
||||
.map(data -> new Pair<>(data.getPos(), data.getBlockState()))
|
||||
.collect(Collectors.toList())
|
||||
));
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -162,11 +132,10 @@ public abstract class MixinNetHandlerPlayClient implements INetHandlerPlayClient
|
||||
)
|
||||
)
|
||||
private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
EntityPlayerSP player = ibaritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onPlayerDeath();
|
||||
}
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
|
||||
if (baritone == null) {
|
||||
return;
|
||||
}
|
||||
baritone.getGameEventHandler().onPlayerDeath();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* 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.IThreadLanServerPing;
|
||||
import net.minecraft.client.multiplayer.ThreadLanServerPing;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/4/2020
|
||||
*/
|
||||
@Mixin(ThreadLanServerPing.class)
|
||||
public abstract class MixinThreadLanServerPing implements IThreadLanServerPing {
|
||||
|
||||
@Accessor
|
||||
@Override
|
||||
public abstract String getMotd();
|
||||
|
||||
@Accessor
|
||||
@Override
|
||||
public abstract String getAddress();
|
||||
}
|
||||
@@ -16,12 +16,11 @@
|
||||
"MixinChunkProviderServer",
|
||||
"MixinChunkRenderContainer",
|
||||
"MixinChunkRenderWorker",
|
||||
"MixinEntityFireworkRocket",
|
||||
"MixinEntityLivingBase",
|
||||
"MixinEntityPlayerSP",
|
||||
"MixinEntityRenderer",
|
||||
"MixinGameSettings",
|
||||
"MixinGuiScreen",
|
||||
"MixinIntegratedServer",
|
||||
"MixinItemStack",
|
||||
"MixinItemTool",
|
||||
"MixinMinecraft",
|
||||
@@ -33,8 +32,7 @@
|
||||
"MixinRenderList",
|
||||
"MixinStateImplementation",
|
||||
"MixinTabCompleter",
|
||||
"MixinThreadLanServerPing",
|
||||
"MixinVboRenderList",
|
||||
"MixinWorldClient"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@ import baritone.api.Settings;
|
||||
import baritone.api.behavior.IBehavior;
|
||||
import baritone.api.event.listener.IEventBus;
|
||||
import baritone.api.process.IBaritoneProcess;
|
||||
import baritone.api.process.IElytraProcess;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import baritone.behavior.*;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.command.ExampleBaritoneControl;
|
||||
import baritone.command.manager.CommandManager;
|
||||
import baritone.event.GameEventHandler;
|
||||
import baritone.process.*;
|
||||
@@ -37,11 +37,12 @@ import baritone.utils.InputOverrideHandler;
|
||||
import baritone.utils.PathingControlManager;
|
||||
import baritone.utils.player.BaritonePlayerContext;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
@@ -78,6 +79,7 @@ public class Baritone implements IBaritone {
|
||||
private final ExploreProcess exploreProcess;
|
||||
private final FarmProcess farmProcess;
|
||||
private final InventoryPauserProcess inventoryPauserProcess;
|
||||
private final ElytraProcess elytraProcess;
|
||||
|
||||
private final PathingControlManager pathingControlManager;
|
||||
private final SelectionManager selectionManager;
|
||||
@@ -120,6 +122,7 @@ public class Baritone implements IBaritone {
|
||||
this.exploreProcess = this.registerProcess(ExploreProcess::new);
|
||||
this.farmProcess = this.registerProcess(FarmProcess::new);
|
||||
this.inventoryPauserProcess = this.registerProcess(InventoryPauserProcess::new);
|
||||
this.elytraProcess = this.registerProcess(ElytraProcess::create);
|
||||
this.registerProcess(BackfillProcess::new);
|
||||
}
|
||||
|
||||
@@ -233,15 +236,16 @@ public class Baritone implements IBaritone {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openClick() {
|
||||
this.showScreen(new GuiClick());
|
||||
public IElytraProcess getElytraProcess() {
|
||||
return this.elytraProcess;
|
||||
}
|
||||
|
||||
public void showScreen(GuiScreen screen) {
|
||||
@Override
|
||||
public void openClick() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
mc.addScheduledTask(() -> mc.displayGuiScreen(screen));
|
||||
mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiClick()));
|
||||
} catch (Exception ignored) {}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@@ -19,11 +19,9 @@ package baritone;
|
||||
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.IBaritoneProvider;
|
||||
import baritone.api.bot.IUserManager;
|
||||
import baritone.api.cache.IWorldScanner;
|
||||
import baritone.api.command.ICommandSystem;
|
||||
import baritone.api.schematic.ISchematicSystem;
|
||||
import baritone.bot.UserManager;
|
||||
import baritone.cache.FasterWorldScanner;
|
||||
import baritone.command.CommandSystem;
|
||||
import baritone.command.ExampleBaritoneControl;
|
||||
@@ -81,11 +79,6 @@ public final class BaritoneProvider implements IBaritoneProvider {
|
||||
return FasterWorldScanner.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IUserManager getUserManager() {
|
||||
return UserManager.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICommandSystem getCommandSystem() {
|
||||
return CommandSystem.INSTANCE;
|
||||
|
||||
@@ -28,6 +28,8 @@ import baritone.api.utils.Rotation;
|
||||
import baritone.behavior.look.ForkableRandom;
|
||||
import net.minecraft.network.play.client.CPacketPlayer;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
@@ -51,14 +53,19 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
|
||||
private final AimProcessor processor;
|
||||
|
||||
private final Deque<Float> smoothYawBuffer;
|
||||
private final Deque<Float> smoothPitchBuffer;
|
||||
|
||||
public LookBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
this.processor = new AimProcessor(baritone.getPlayerContext());
|
||||
this.smoothYawBuffer = new ArrayDeque<>();
|
||||
this.smoothPitchBuffer = new ArrayDeque<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTarget(Rotation rotation, boolean blockInteract) {
|
||||
this.target = new Target(rotation, blockInteract);
|
||||
this.target = new Target(rotation, Target.Mode.resolve(ctx, blockInteract));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,10 +91,8 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
// Just return for PRE, we still want to set target to null on POST
|
||||
return;
|
||||
}
|
||||
if (this.target.mode == Target.Mode.SERVER) {
|
||||
this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch);
|
||||
}
|
||||
|
||||
this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch);
|
||||
final Rotation actual = this.processor.peekRotation(this.target.rotation);
|
||||
ctx.player().rotationYaw = actual.getYaw();
|
||||
ctx.player().rotationPitch = actual.getPitch();
|
||||
@@ -96,8 +101,24 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
case POST: {
|
||||
// Reset the player's rotations back to their original values
|
||||
if (this.prevRotation != null) {
|
||||
ctx.player().rotationYaw = this.prevRotation.getYaw();
|
||||
ctx.player().rotationPitch = this.prevRotation.getPitch();
|
||||
this.smoothYawBuffer.addLast(this.target.rotation.getYaw());
|
||||
while (this.smoothYawBuffer.size() > Baritone.settings().smoothLookTicks.value) {
|
||||
this.smoothYawBuffer.removeFirst();
|
||||
}
|
||||
this.smoothPitchBuffer.addLast(this.target.rotation.getPitch());
|
||||
while (this.smoothPitchBuffer.size() > Baritone.settings().smoothLookTicks.value) {
|
||||
this.smoothPitchBuffer.removeFirst();
|
||||
}
|
||||
if (this.target.mode == Target.Mode.SERVER) {
|
||||
ctx.player().rotationYaw = this.prevRotation.getYaw();
|
||||
ctx.player().rotationPitch = this.prevRotation.getPitch();
|
||||
} else if (ctx.player().isElytraFlying() ? Baritone.settings().elytraSmoothLook.value : Baritone.settings().smoothLook.value) {
|
||||
ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElse(this.prevRotation.getYaw());
|
||||
if (ctx.player().isElytraFlying()) {
|
||||
ctx.player().rotationPitch = (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElse(this.prevRotation.getPitch());
|
||||
}
|
||||
}
|
||||
|
||||
this.prevRotation = null;
|
||||
}
|
||||
// The target is done being used for this game tick, so it can be invalidated
|
||||
@@ -135,10 +156,10 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
}
|
||||
|
||||
public Optional<Rotation> getEffectiveRotation() {
|
||||
if (Baritone.settings().freeLook.value || Baritone.settings().blockFreeLook.value) {
|
||||
if (Baritone.settings().freeLook.value) {
|
||||
return Optional.ofNullable(this.serverRotation);
|
||||
}
|
||||
// If neither of the freeLook settings are on, just defer to the player's actual rotations
|
||||
// If freeLook isn't on, just defer to the player's actual rotations
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -279,9 +300,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
public final Rotation rotation;
|
||||
public final Mode mode;
|
||||
|
||||
public Target(Rotation rotation, boolean blockInteract) {
|
||||
public Target(Rotation rotation, Mode mode) {
|
||||
this.rotation = rotation;
|
||||
this.mode = Mode.resolve(blockInteract);
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
enum Mode {
|
||||
@@ -300,22 +321,26 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
*/
|
||||
NONE;
|
||||
|
||||
static Mode resolve(boolean blockInteract) {
|
||||
static Mode resolve(IPlayerContext ctx, boolean blockInteract) {
|
||||
final Settings settings = Baritone.settings();
|
||||
final boolean antiCheat = settings.antiCheatCompatibility.value;
|
||||
final boolean blockFreeLook = settings.blockFreeLook.value;
|
||||
final boolean freeLook = settings.freeLook.value;
|
||||
|
||||
if (!freeLook && !blockFreeLook) return CLIENT;
|
||||
if (!blockFreeLook && blockInteract) return CLIENT;
|
||||
if (ctx.player().isElytraFlying()) {
|
||||
// always need to set angles while flying
|
||||
return settings.elytraFreeLook.value ? SERVER : CLIENT;
|
||||
} else if (settings.freeLook.value) {
|
||||
// Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player
|
||||
// rotation needs to be set somehow, otherwise Baritone will halt since objectMouseOver() will just be
|
||||
// whatever the player is mousing over visually. Let's just settle for setting it silently.
|
||||
if (blockInteract) {
|
||||
return blockFreeLook ? SERVER : CLIENT;
|
||||
}
|
||||
return antiCheat ? SERVER : NONE;
|
||||
}
|
||||
|
||||
// Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player
|
||||
// rotation needs to be set somehow, otherwise Baritone will halt since objectMouseOver() will just be
|
||||
// whatever the player is mousing over visually. Let's just settle for setting it silently.
|
||||
if (antiCheat || blockInteract) return SERVER;
|
||||
|
||||
// Pathing regularly without antiCheatCompatibility, don't set the player rotation
|
||||
return NONE;
|
||||
// all freeLook settings are disabled so set the angles
|
||||
return CLIENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.path.PathExecutor;
|
||||
import baritone.process.ElytraProcess;
|
||||
import baritone.utils.PathRenderer;
|
||||
import baritone.utils.PathingCommandContext;
|
||||
import baritone.utils.pathing.Favoring;
|
||||
@@ -309,7 +310,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
}
|
||||
|
||||
public boolean isSafeToCancel() {
|
||||
return current == null || safeToCancel;
|
||||
if (current == null) {
|
||||
return !baritone.getElytraProcess().isActive() || baritone.getElytraProcess().isSafeToCancel();
|
||||
}
|
||||
return safeToCancel;
|
||||
}
|
||||
|
||||
public void requestPause() {
|
||||
@@ -352,7 +356,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
}
|
||||
|
||||
// just cancel the current path
|
||||
private void secretInternalSegmentCancel() {
|
||||
public void secretInternalSegmentCancel() {
|
||||
queuePathEvent(PathEvent.CANCELED);
|
||||
synchronized (pathPlanLock) {
|
||||
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* 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.bot;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.bot.IBaritoneUser;
|
||||
import baritone.api.event.events.WorldEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import baritone.bot.impl.BotMinecraft;
|
||||
import baritone.bot.impl.BotWorld;
|
||||
import baritone.bot.impl.BotPlayer;
|
||||
import baritone.command.ExampleBaritoneControl;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.client.multiplayer.PlayerControllerMP;
|
||||
import net.minecraft.client.multiplayer.ServerData;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.util.Session;
|
||||
|
||||
/**
|
||||
* Implementation of {@link IBaritoneUser}
|
||||
*
|
||||
* @author Brady
|
||||
* @since 11/6/2018
|
||||
*/
|
||||
public final class BaritoneUser implements IBaritoneUser {
|
||||
|
||||
private final BotMinecraft mc;
|
||||
private final UserManager manager;
|
||||
private final NetworkManager networkManager;
|
||||
private final Session session;
|
||||
private final Baritone baritone;
|
||||
|
||||
private GameProfile profile;
|
||||
|
||||
BaritoneUser(UserManager manager, NetworkManager networkManager, Session session, ServerData serverData) {
|
||||
this.mc = BotMinecraft.allocate(this);
|
||||
this.mc.setServerData(serverData);
|
||||
this.manager = manager;
|
||||
this.networkManager = networkManager;
|
||||
this.session = session;
|
||||
this.profile = session.getProfile();
|
||||
this.baritone = (Baritone) BaritoneAPI.getProvider().createBaritone(this.mc);
|
||||
this.baritone.registerBehavior(ExampleBaritoneControl::new);
|
||||
}
|
||||
|
||||
public void onLoginSuccess(GameProfile profile) {
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
public void onWorldLoad(BotWorld world, BotPlayer player, PlayerControllerMP playerController) {
|
||||
this.baritone.getGameEventHandler().onWorldEvent(new WorldEvent(world, EventState.PRE));
|
||||
|
||||
this.mc.player = player;
|
||||
this.mc.world = world;
|
||||
this.mc.playerController = playerController;
|
||||
|
||||
this.baritone.getGameEventHandler().onWorldEvent(new WorldEvent(world, EventState.POST));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBaritone getBaritone() {
|
||||
return this.baritone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPlayerContext getPlayerContext() {
|
||||
return this.baritone.getPlayerContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkManager getNetworkManager() {
|
||||
return this.networkManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session getSession() {
|
||||
return this.session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameProfile getProfile() {
|
||||
return this.profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserManager getManager() {
|
||||
return this.manager;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* 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.bot;
|
||||
|
||||
import baritone.bot.impl.BotWorld;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import net.minecraft.world.GameType;
|
||||
import net.minecraft.world.WorldSettings;
|
||||
import net.minecraft.world.WorldType;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 11/7/2018
|
||||
*/
|
||||
public final class BotWorldProvider {
|
||||
|
||||
/**
|
||||
* Generic world settings for a typical survival world.
|
||||
*/
|
||||
private static final WorldSettings GENERIC_WORLD_SETTINGS = new WorldSettings(0L, GameType.SURVIVAL, true, false, WorldType.DEFAULT);
|
||||
|
||||
/**
|
||||
* All of the dimensions mapped to their respective worlds.
|
||||
*/
|
||||
private final Int2ObjectMap<BotWorld> worlds = new Int2ObjectArrayMap<>();
|
||||
|
||||
/**
|
||||
* Gets or creates the {@link BotWorld} for the specified dimension
|
||||
*
|
||||
* @param dimension The dimension id
|
||||
* @return The world
|
||||
*/
|
||||
public BotWorld getWorld(int dimension) {
|
||||
return worlds.computeIfAbsent(dimension, this::createWorldForDim);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link BotWorld} for the given dimension id.
|
||||
*
|
||||
* @param dimension The dimension id
|
||||
* @return The new world
|
||||
*/
|
||||
private BotWorld createWorldForDim(int dimension) {
|
||||
return new BotWorld(GENERIC_WORLD_SETTINGS, dimension);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
this.worlds.forEach((dim, world) -> world.updateEntities());
|
||||
}
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* 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.bot;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.bot.IBaritoneUser;
|
||||
import baritone.api.bot.IUserManager;
|
||||
import baritone.api.bot.connect.IConnectionResult;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.api.event.listener.AbstractGameEventListener;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import baritone.bot.connect.ConnectionResult;
|
||||
import baritone.bot.handler.BotNetHandlerLoginClient;
|
||||
import baritone.bot.impl.BotPlayer;
|
||||
import baritone.bot.impl.BotWorld;
|
||||
import baritone.utils.accessor.IIntegratedServer;
|
||||
import baritone.utils.accessor.IThreadLanServerPing;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ServerAddress;
|
||||
import net.minecraft.client.multiplayer.ServerData;
|
||||
import net.minecraft.network.EnumConnectionState;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.handshake.client.C00Handshake;
|
||||
import net.minecraft.network.login.client.CPacketLoginStart;
|
||||
import net.minecraft.util.Session;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static baritone.api.bot.connect.ConnectionStatus.*;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 11/6/2018
|
||||
*/
|
||||
public enum UserManager implements IUserManager, AbstractGameEventListener {
|
||||
INSTANCE;
|
||||
|
||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
private final List<IBaritoneUser> users;
|
||||
private final BotWorldProvider worldProvider;
|
||||
|
||||
UserManager() {
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().registerEventListener(this);
|
||||
this.users = new CopyOnWriteArrayList<>();
|
||||
this.worldProvider = new BotWorldProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick(TickEvent event) {
|
||||
if (event.getState() != EventState.PRE) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.users.forEach(user -> {
|
||||
switch (event.getType()) {
|
||||
case IN: {
|
||||
final IPlayerContext ctx = user.getPlayerContext();
|
||||
if (ctx.player() != null) {
|
||||
ctx.playerController().syncHeldItem();
|
||||
}
|
||||
if (user.getNetworkManager().isChannelOpen()) {
|
||||
user.getNetworkManager().processReceivedPackets();
|
||||
} else {
|
||||
user.getNetworkManager().handleDisconnection();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OUT: {
|
||||
this.disconnect(user, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.worldProvider.tick();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects a new user with the specified {@link Session} to the current server.
|
||||
*
|
||||
* @param session The user session
|
||||
* @return The result of the attempted connection
|
||||
*/
|
||||
@Override
|
||||
public final IConnectionResult connect(Session session) {
|
||||
if (mc.getIntegratedServer() != null && mc.getIntegratedServer().getPublic()) {
|
||||
try {
|
||||
IIntegratedServer integratedServer = (IIntegratedServer) mc.getIntegratedServer();
|
||||
IThreadLanServerPing lanServerPing = (IThreadLanServerPing) integratedServer.getLanServerPing();
|
||||
int port = Integer.parseInt(lanServerPing.getAddress());
|
||||
|
||||
return connect0(session, new ServerData(lanServerPing.getMotd(), "localhost:" + port, true));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return ConnectionResult.failed(CANT_RESOLVE_LAN);
|
||||
}
|
||||
}
|
||||
|
||||
ServerData data = mc.getCurrentServerData();
|
||||
if (data == null) {
|
||||
return ConnectionResult.failed(NO_CURRENT_CONNECTION);
|
||||
}
|
||||
|
||||
// Connect to the server from the parsed server data
|
||||
return connect0(session, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects a new user with the specified {@link Session} to the specified server.
|
||||
* <p>
|
||||
* Hi Mickey :)
|
||||
*
|
||||
* @param session The user session
|
||||
* @param data The address of the server to connect to
|
||||
* @return The result of the attempted connection
|
||||
*/
|
||||
private IConnectionResult connect0(Session session, ServerData data) {
|
||||
ServerAddress address = ServerAddress.fromString(data.serverIP);
|
||||
InetAddress inetAddress;
|
||||
|
||||
try {
|
||||
inetAddress = InetAddress.getByName(address.getIP());
|
||||
} catch (UnknownHostException e) {
|
||||
return ConnectionResult.failed(CANT_RESOLVE_HOST);
|
||||
}
|
||||
|
||||
try {
|
||||
// Initialize Connection
|
||||
NetworkManager networkManager = NetworkManager.createNetworkManagerAndConnect(
|
||||
inetAddress,
|
||||
address.getPort(),
|
||||
mc.gameSettings.isUsingNativeTransport()
|
||||
);
|
||||
|
||||
// Create User
|
||||
BaritoneUser user = new BaritoneUser(this, networkManager, session, data);
|
||||
this.users.add(user);
|
||||
|
||||
// Setup login handler and send connection packets
|
||||
networkManager.setNetHandler(new BotNetHandlerLoginClient(networkManager, user));
|
||||
networkManager.sendPacket(new C00Handshake(address.getIP(), address.getPort(), EnumConnectionState.LOGIN));
|
||||
networkManager.sendPacket(new CPacketLoginStart(session.getProfile()));
|
||||
|
||||
return ConnectionResult.success(user);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return ConnectionResult.failed(CONNECTION_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The bot world provider
|
||||
*/
|
||||
public final BotWorldProvider getWorldProvider() {
|
||||
return this.worldProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void disconnect(IBaritoneUser user, ITextComponent reason) {
|
||||
if (this.users.contains(user)) {
|
||||
if (user.getNetworkManager().isChannelOpen()) {
|
||||
user.getNetworkManager().closeChannel(reason);
|
||||
}
|
||||
BaritoneAPI.getProvider().destroyBaritone(user.getBaritone());
|
||||
this.users.remove(user);
|
||||
Helper.HELPER.logDirect(user.getSession().getUsername() + " Disconnected: " +
|
||||
(reason == null ? "Unknown" : reason.getUnformattedText()));
|
||||
|
||||
final IPlayerContext ctx = user.getPlayerContext();
|
||||
if (ctx.player() != null && ctx.world() != null) {
|
||||
((BotWorld) ctx.world()).handleWorldRemove((BotPlayer) ctx.player());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<IBaritoneUser> getUsers() {
|
||||
return Collections.unmodifiableList(this.users);
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* 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.bot.connect;
|
||||
|
||||
import baritone.api.bot.IBaritoneUser;
|
||||
import baritone.api.bot.connect.ConnectionStatus;
|
||||
import baritone.api.bot.connect.IConnectionResult;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static baritone.api.bot.connect.ConnectionStatus.SUCCESS;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 11/6/2018
|
||||
*/
|
||||
public final class ConnectionResult implements IConnectionResult {
|
||||
|
||||
/**
|
||||
* The result status
|
||||
*/
|
||||
private final ConnectionStatus status;
|
||||
|
||||
/**
|
||||
* The user created, if the status is {@link ConnectionStatus#SUCCESS}
|
||||
*/
|
||||
private final IBaritoneUser user;
|
||||
|
||||
private ConnectionResult(ConnectionStatus status, IBaritoneUser user) {
|
||||
this.status = status;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionStatus getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IBaritoneUser> getUser() {
|
||||
return Optional.ofNullable(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new failed {@link ConnectionResult}.
|
||||
*
|
||||
* @param status The failed connection status
|
||||
* @return The connection result
|
||||
* @throws IllegalArgumentException if {@code status} is {@link ConnectionStatus#SUCCESS}
|
||||
*/
|
||||
public static ConnectionResult failed(ConnectionStatus status) {
|
||||
if (status == SUCCESS) {
|
||||
throw new IllegalArgumentException("Status must be a failure type");
|
||||
}
|
||||
|
||||
return new ConnectionResult(status, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new success {@link ConnectionResult}.
|
||||
*
|
||||
* @param user The user created
|
||||
* @return The connection result
|
||||
* @throws IllegalArgumentException if {@code user} is {@code null}
|
||||
*/
|
||||
public static ConnectionResult success(IBaritoneUser user) {
|
||||
Objects.requireNonNull(user);
|
||||
|
||||
return new ConnectionResult(SUCCESS, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConnectionResult{" +
|
||||
"status=" + status +
|
||||
", user=" + user +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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.bot.handler;
|
||||
|
||||
import baritone.bot.BaritoneUser;
|
||||
import baritone.bot.impl.BotMinecraft;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.network.NetHandlerLoginClient;
|
||||
import net.minecraft.network.EnumConnectionState;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.login.server.SPacketLoginSuccess;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Handles the login stage when connecting to a server.
|
||||
*
|
||||
* @author Brady
|
||||
* @since 10/29/2018
|
||||
*/
|
||||
public final class BotNetHandlerLoginClient extends NetHandlerLoginClient {
|
||||
|
||||
/**
|
||||
* The {@link NetworkManager} that is managing the connection with the server.
|
||||
*/
|
||||
private final NetworkManager networkManager;
|
||||
|
||||
/**
|
||||
* The {@link Minecraft} game instance
|
||||
*/
|
||||
private final BotMinecraft mc;
|
||||
|
||||
/**
|
||||
* The bot of this connection
|
||||
*/
|
||||
private final BaritoneUser user;
|
||||
|
||||
public BotNetHandlerLoginClient(NetworkManager networkManager, BaritoneUser user) {
|
||||
super(networkManager, user.getPlayerContext().minecraft(), null);
|
||||
this.networkManager = networkManager;
|
||||
this.mc = (BotMinecraft) user.getPlayerContext().minecraft();
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLoginSuccess(SPacketLoginSuccess packetIn) {
|
||||
this.networkManager.setConnectionState(EnumConnectionState.PLAY);
|
||||
this.networkManager.setNetHandler(new BotNetHandlerPlayClient(this.networkManager, this.user, this.mc, packetIn.getProfile()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(@Nonnull ITextComponent reason) {
|
||||
// It's important that we don't call the superclass method because that would mess up GUIs and make us upset
|
||||
this.user.getManager().disconnect(this.user, reason);
|
||||
}
|
||||
}
|
||||
@@ -1,521 +0,0 @@
|
||||
/*
|
||||
* 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.bot.handler;
|
||||
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.bot.BaritoneUser;
|
||||
import baritone.bot.impl.BotPlayer;
|
||||
import baritone.bot.impl.BotMinecraft;
|
||||
import baritone.bot.impl.BotWorld;
|
||||
import baritone.utils.accessor.INetHandlerPlayClient;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.client.multiplayer.ClientAdvancementManager;
|
||||
import net.minecraft.client.multiplayer.PlayerControllerMP;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.client.util.RecipeBookClient;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.network.PacketThreadUtil;
|
||||
import net.minecraft.network.play.client.CPacketClientStatus;
|
||||
import net.minecraft.network.play.client.CPacketCustomPayload;
|
||||
import net.minecraft.network.play.client.CPacketResourcePackStatus;
|
||||
import net.minecraft.network.play.server.*;
|
||||
import net.minecraft.stats.StatisticsManager;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
// Notes
|
||||
// - Make some sort of system that prevents repetition of entity info updating
|
||||
// - For some packets, such as ones that modify position, we can check if the existing server state matches the packet proposed state
|
||||
// - For other things, we'll actually need the system
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 10/22/2018
|
||||
*/
|
||||
public final class BotNetHandlerPlayClient extends NetHandlerPlayClient {
|
||||
|
||||
/**
|
||||
* The {@link NetworkManager} that is managing the connection with the server.
|
||||
*/
|
||||
private final NetworkManager networkManager;
|
||||
|
||||
/**
|
||||
* The bot's minecraft game instance
|
||||
*/
|
||||
private final BotMinecraft client;
|
||||
|
||||
/**
|
||||
* The bot of this connection
|
||||
*/
|
||||
private final BaritoneUser user;
|
||||
|
||||
/**
|
||||
* The bot player
|
||||
*/
|
||||
private BotPlayer player;
|
||||
|
||||
/**
|
||||
* The current world.
|
||||
*/
|
||||
private BotWorld world;
|
||||
|
||||
/**
|
||||
* The current player controller
|
||||
*/
|
||||
private PlayerControllerMP playerController;
|
||||
|
||||
BotNetHandlerPlayClient(NetworkManager networkManager, BaritoneUser user, BotMinecraft client, GameProfile profile) {
|
||||
// noinspection ConstantConditions
|
||||
super(client, null, networkManager, profile);
|
||||
this.networkManager = networkManager;
|
||||
this.client = client;
|
||||
this.user = user;
|
||||
|
||||
// Notify the user that we're ingame
|
||||
this.user.onLoginSuccess(profile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSpawnObject(@Nonnull SPacketSpawnObject packetIn) {
|
||||
super.handleSpawnObject(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSpawnExperienceOrb(@Nonnull SPacketSpawnExperienceOrb packetIn) {
|
||||
super.handleSpawnExperienceOrb(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSpawnGlobalEntity(@Nonnull SPacketSpawnGlobalEntity packetIn) {
|
||||
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||
|
||||
if (this.world != null) {
|
||||
if (this.world.weatherEffects.stream().noneMatch(entity -> entity.getEntityId() == packetIn.getEntityId())) {
|
||||
super.handleSpawnGlobalEntity(packetIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSpawnMob(@Nonnull SPacketSpawnMob packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleScoreboardObjective(@Nonnull SPacketScoreboardObjective packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleSpawnPainting(@Nonnull SPacketSpawnPainting packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleSpawnPlayer(@Nonnull SPacketSpawnPlayer packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleAnimation(@Nonnull SPacketAnimation packetIn) {
|
||||
super.handleAnimation(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleStatistics(@Nonnull SPacketStatistics packetIn) {
|
||||
super.handleStatistics(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRecipeBook(@Nonnull SPacketRecipeBook packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleBlockBreakAnim(@Nonnull SPacketBlockBreakAnim packetIn) {
|
||||
super.handleBlockBreakAnim(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSignEditorOpen(@Nonnull SPacketSignEditorOpen packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleUpdateTileEntity(@Nonnull SPacketUpdateTileEntity packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleBlockAction(@Nonnull SPacketBlockAction packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleBlockChange(@Nonnull SPacketBlockChange packetIn) {
|
||||
super.handleBlockChange(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleChat(@Nonnull SPacketChat packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleTabComplete(@Nonnull SPacketTabComplete packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleMultiBlockChange(@Nonnull SPacketMultiBlockChange packetIn) {
|
||||
super.handleMultiBlockChange(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMaps(@Nonnull SPacketMaps packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleConfirmTransaction(@Nonnull SPacketConfirmTransaction packetIn) {
|
||||
super.handleConfirmTransaction(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCloseWindow(@Nonnull SPacketCloseWindow packetIn) {
|
||||
super.handleCloseWindow(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleWindowItems(@Nonnull SPacketWindowItems packetIn) {
|
||||
super.handleWindowItems(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleOpenWindow(@Nonnull SPacketOpenWindow packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleWindowProperty(@Nonnull SPacketWindowProperty packetIn) {
|
||||
super.handleWindowProperty(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSetSlot(@Nonnull SPacketSetSlot packetIn) {
|
||||
super.handleSetSlot(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCustomPayload(@Nonnull SPacketCustomPayload packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleDisconnect(@Nonnull SPacketDisconnect packetIn) {
|
||||
super.handleDisconnect(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleUseBed(@Nonnull SPacketUseBed packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleEntityStatus(@Nonnull SPacketEntityStatus packetIn) {
|
||||
super.handleEntityStatus(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntityAttach(@Nonnull SPacketEntityAttach packetIn) {
|
||||
super.handleEntityAttach(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSetPassengers(@Nonnull SPacketSetPassengers packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleExplosion(@Nonnull SPacketExplosion packetIn) {
|
||||
super.handleExplosion(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleChangeGameState(@Nonnull SPacketChangeGameState packetIn) {
|
||||
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||
|
||||
if (packetIn.getGameState() == 4) {
|
||||
this.client.player.connection.sendPacket(new CPacketClientStatus(CPacketClientStatus.State.PERFORM_RESPAWN));
|
||||
} else if (packetIn.getGameState() != 5) {
|
||||
super.handleChangeGameState(packetIn);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleKeepAlive(@Nonnull SPacketKeepAlive packetIn) {
|
||||
super.handleKeepAlive(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleChunkData(@Nonnull SPacketChunkData packetIn) {
|
||||
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||
|
||||
if (packetIn.isFullChunk()) {
|
||||
if (!this.world.handlePreChunk(this.player, packetIn.getChunkX(), packetIn.getChunkZ(), true)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.handleChunkData(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processChunkUnload(@Nonnull SPacketUnloadChunk packetIn) {
|
||||
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||
|
||||
if (this.world.handlePreChunk(this.player, packetIn.getX(), packetIn.getZ(), false)) {
|
||||
super.processChunkUnload(packetIn);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEffect(@Nonnull SPacketEffect packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleJoinGame(@Nonnull SPacketJoinGame packetIn) {
|
||||
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||
|
||||
this.playerController = new PlayerControllerMP(this.user.getPlayerContext().minecraft(), this);
|
||||
this.world = this.user.getManager().getWorldProvider().getWorld(packetIn.getDimension());
|
||||
((INetHandlerPlayClient) (Object) this).setWorld(this.world);
|
||||
this.player = new BotPlayer(this.user, this.client, this.world, this, new StatisticsManager(), new RecipeBookClient());
|
||||
this.user.onWorldLoad(this.world, this.player, this.playerController);
|
||||
this.player.preparePlayerToSpawn();
|
||||
this.player.setEntityId(packetIn.getPlayerId());
|
||||
this.player.dimension = packetIn.getDimension();
|
||||
this.world.addEntityToWorld(packetIn.getPlayerId(), this.player);
|
||||
this.playerController.setGameType(packetIn.getGameType());
|
||||
packetIn.getGameType().configurePlayerCapabilities(this.player.capabilities);
|
||||
|
||||
this.client.gameSettings.sendSettingsToServer();
|
||||
this.networkManager.sendPacket(new CPacketCustomPayload("MC|Brand", new PacketBuffer(Unpooled.buffer()).writeString("vanilla")));
|
||||
|
||||
Helper.HELPER.logDirect("Initialized Player and World");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntityMovement(@Nonnull SPacketEntity packetIn) {
|
||||
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||
|
||||
Entity e = packetIn.getEntity(this.world);
|
||||
if (e instanceof BotPlayer && !e.equals(this.player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.handleEntityMovement(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePlayerPosLook(@Nonnull SPacketPlayerPosLook packetIn) {
|
||||
super.handlePlayerPosLook(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleParticles(@Nonnull SPacketParticles packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handlePlayerAbilities(@Nonnull SPacketPlayerAbilities packetIn) {
|
||||
super.handlePlayerAbilities(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePlayerListItem(@Nonnull SPacketPlayerListItem packetIn) {
|
||||
super.handlePlayerListItem(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDestroyEntities(@Nonnull SPacketDestroyEntities packetIn) {
|
||||
super.handleDestroyEntities(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRemoveEntityEffect(@Nonnull SPacketRemoveEntityEffect packetIn) {
|
||||
super.handleRemoveEntityEffect(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRespawn(@Nonnull SPacketRespawn packetIn) {
|
||||
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||
|
||||
if (packetIn.getDimensionID() != this.player.dimension) {
|
||||
this.world.handleWorldRemove(this.player);
|
||||
this.world = this.user.getManager().getWorldProvider().getWorld(packetIn.getDimensionID());
|
||||
((INetHandlerPlayClient) (Object) this).setWorld(this.world);
|
||||
}
|
||||
|
||||
BotPlayer prev = this.player;
|
||||
|
||||
this.player = new BotPlayer(this.user, this.client, this.world, this, prev.getStatFileWriter(), prev.getRecipeBook());
|
||||
this.user.onWorldLoad(this.world, this.player, this.playerController);
|
||||
// noinspection ConstantConditions
|
||||
this.player.getDataManager().setEntryValues(prev.getDataManager().getAll());
|
||||
this.player.preparePlayerToSpawn();
|
||||
this.player.setEntityId(prev.getEntityId());
|
||||
this.player.dimension = packetIn.getDimensionID();
|
||||
this.player.setServerBrand(prev.getServerBrand());
|
||||
this.world.addEntityToWorld(prev.getEntityId(), this.player);
|
||||
this.playerController.setGameType(packetIn.getGameType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntityHeadLook(@Nonnull SPacketEntityHeadLook packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleHeldItemChange(@Nonnull SPacketHeldItemChange packetIn) {
|
||||
super.handleHeldItemChange(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleDisplayObjective(@Nonnull SPacketDisplayObjective packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleEntityMetadata(@Nonnull SPacketEntityMetadata packetIn) {
|
||||
super.handleEntityMetadata(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntityVelocity(@Nonnull SPacketEntityVelocity packetIn) {
|
||||
super.handleEntityVelocity(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntityEquipment(@Nonnull SPacketEntityEquipment packetIn) {
|
||||
super.handleEntityEquipment(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSetExperience(@Nonnull SPacketSetExperience packetIn) {
|
||||
super.handleSetExperience(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleUpdateHealth(@Nonnull SPacketUpdateHealth packetIn) {
|
||||
super.handleUpdateHealth(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTeams(@Nonnull SPacketTeams packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleUpdateScore(@Nonnull SPacketUpdateScore packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleSpawnPosition(@Nonnull SPacketSpawnPosition packetIn) { /* We probably don't need to know this, the server handles everything related to spawn psoition? */ }
|
||||
|
||||
@Override
|
||||
public void handleTimeUpdate(@Nonnull SPacketTimeUpdate packetIn) {
|
||||
super.handleTimeUpdate(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSoundEffect(@Nonnull SPacketSoundEffect packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleCustomSound(@Nonnull SPacketCustomSound packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleCollectItem(@Nonnull SPacketCollectItem packetIn) {
|
||||
super.handleCollectItem(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntityTeleport(@Nonnull SPacketEntityTeleport packetIn) {
|
||||
super.handleEntityTeleport(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntityProperties(@Nonnull SPacketEntityProperties packetIn) {
|
||||
super.handleEntityProperties(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEntityEffect(@Nonnull SPacketEntityEffect packetIn) {
|
||||
super.handleEntityEffect(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCombatEvent(@Nonnull SPacketCombatEvent packetIn) {
|
||||
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||
|
||||
// We only care if we died
|
||||
if (packetIn.eventType == SPacketCombatEvent.Event.ENTITY_DIED) {
|
||||
if (packetIn.playerId == this.player.getEntityId()) {
|
||||
// Perform an instantaneous respawn
|
||||
this.networkManager.sendPacket(new CPacketClientStatus(CPacketClientStatus.State.PERFORM_RESPAWN));
|
||||
user.getBaritone().getGameEventHandler().onPlayerDeath();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServerDifficulty(@Nonnull SPacketServerDifficulty packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleCamera(SPacketCamera packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleWorldBorder(@Nonnull SPacketWorldBorder packetIn) {
|
||||
super.handleWorldBorder(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTitle(@Nonnull SPacketTitle packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handlePlayerListHeaderFooter(@Nonnull SPacketPlayerListHeaderFooter packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleResourcePack(@Nonnull SPacketResourcePackSend packetIn) {
|
||||
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||
|
||||
// Lie to the server and tell them we accepted it in response
|
||||
this.networkManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.ACCEPTED));
|
||||
this.networkManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.SUCCESSFULLY_LOADED));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleUpdateBossInfo(@Nonnull SPacketUpdateBossInfo packetIn) {}
|
||||
|
||||
@Override
|
||||
public void handleCooldown(@Nonnull SPacketCooldown packetIn) {
|
||||
super.handleCooldown(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMoveVehicle(@Nonnull SPacketMoveVehicle packetIn) {
|
||||
super.handleMoveVehicle(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAdvancementInfo(@Nonnull SPacketAdvancementInfo packetIn) {
|
||||
super.handleAdvancementInfo(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSelectAdvancementsTab(@Nonnull SPacketSelectAdvancementsTab packetIn) {
|
||||
super.handleSelectAdvancementsTab(packetIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_194307_a(@Nonnull SPacketPlaceGhostRecipe p_194307_1_) {}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(@Nonnull ITextComponent reason) {
|
||||
// TODO Maybe more world unloading
|
||||
this.world.removeEntity(this.player);
|
||||
this.user.getManager().disconnect(this.user, reason);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public ClientAdvancementManager getAdvancementManager() {
|
||||
throw new UnsupportedOperationException("This method shouldn't have been called; That is unepic!");
|
||||
}
|
||||
|
||||
public BotPlayer player() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public BotWorld world() {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* 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.bot.impl;
|
||||
|
||||
import baritone.api.bot.IBaritoneUser;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.inventory.GuiInventory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class BotGuiInventory extends GuiInventory {
|
||||
|
||||
private final IBaritoneUser user;
|
||||
|
||||
public BotGuiInventory(IBaritoneUser user) {
|
||||
super(user.getPlayerContext().player());
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWorldAndResolution(@Nonnull Minecraft primary, int width, int height) {
|
||||
final Minecraft mc = this.user.getPlayerContext().minecraft();
|
||||
mc.displayWidth = primary.displayWidth;
|
||||
mc.displayHeight = primary.displayHeight;
|
||||
super.setWorldAndResolution(mc, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
|
||||
final BotPlayer player = (BotPlayer) this.user.getPlayerContext().player();
|
||||
player.isUser = false;
|
||||
super.drawGuiContainerBackgroundLayer(partialTicks, mouseX, mouseY);
|
||||
player.isUser = true;
|
||||
}
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* 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.bot.impl;
|
||||
|
||||
import baritone.api.bot.IBaritoneUser;
|
||||
import baritone.utils.ObjectAllocator;
|
||||
import baritone.utils.accessor.IGameSettings;
|
||||
import baritone.utils.accessor.IMinecraft;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.SoundHandler;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.toasts.GuiToast;
|
||||
import net.minecraft.client.main.GameConfiguration;
|
||||
import net.minecraft.client.renderer.RenderItem;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.client.tutorial.Tutorial;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.EnumHandSide;
|
||||
import net.minecraft.util.Session;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* "Implementation" of {@link Minecraft} which gets allocated without receiving a constructor call.
|
||||
* This allows us to avoid the game's setup process (moreso in versions after 1.12 than 1.12 itself).
|
||||
*
|
||||
* @author Brady
|
||||
* @since 3/3/2020
|
||||
*/
|
||||
public final class BotMinecraft extends Minecraft {
|
||||
|
||||
private static final Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
private IBaritoneUser user;
|
||||
private Tutorial tutorial;
|
||||
private GuiToast toastGui;
|
||||
|
||||
private BotMinecraft(GameConfiguration gameConfig) {
|
||||
super(gameConfig);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity getRenderViewEntity() {
|
||||
return mc.getRenderViewEntity();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Session getSession() {
|
||||
return this.user.getSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nonnull MinecraftSessionService getSessionService() {
|
||||
return mc.getSessionService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> @Nonnull ListenableFuture<V> addScheduledTask(@Nonnull Callable<V> callableToSchedule) {
|
||||
return mc.addScheduledTask(callableToSchedule);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCallingFromMinecraftThread() {
|
||||
return mc.isCallingFromMinecraftThread();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Tutorial getTutorial() {
|
||||
return this.tutorial;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public SoundHandler getSoundHandler() {
|
||||
return BotSoundHandler.INSTANCE;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public GuiToast getToastGui() {
|
||||
return this.toastGui;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayGuiScreen(@Nullable GuiScreen guiScreenIn) {
|
||||
// do nothing
|
||||
if (guiScreenIn == null) {
|
||||
if (mc.currentScreen instanceof BotGuiInventory) {
|
||||
mc.displayGuiScreen(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public TextureManager getTextureManager() {
|
||||
return mc.getTextureManager();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public RenderItem getRenderItem() {
|
||||
return mc.getRenderItem();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public TextureMap getTextureMapBlocks() {
|
||||
return mc.getTextureMapBlocks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchKeypresses() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public static BotMinecraft allocate(IBaritoneUser user) {
|
||||
BotMinecraft bm = ObjectAllocator.allocate(BotMinecraft.class);
|
||||
((IMinecraft) (Object) bm).setGameDir(mc.gameDir);
|
||||
|
||||
// Gui Compatibility
|
||||
bm.fontRenderer = mc.fontRenderer;
|
||||
|
||||
bm.user = user;
|
||||
bm.tutorial = new Tutorial(bm);
|
||||
bm.gameSettings = createGameSettings(bm);
|
||||
bm.effectRenderer = BotParticleManager.INSTANCE;
|
||||
bm.toastGui = new GuiToast(bm);
|
||||
return bm;
|
||||
}
|
||||
|
||||
private static GameSettings createGameSettings(BotMinecraft bm) {
|
||||
GameSettings settings = ObjectAllocator.allocate(GameSettings.class);
|
||||
|
||||
// Settings that get accessed on entity tick
|
||||
settings.keyBindSprint = ObjectAllocator.allocate(KeyBinding.class);
|
||||
settings.autoJump = false;
|
||||
|
||||
// Settings that are sent to the server
|
||||
settings.language = "en_us";
|
||||
settings.renderDistanceChunks = 8;
|
||||
settings.chatVisibility = EntityPlayer.EnumChatVisibility.FULL;
|
||||
settings.chatColours = true;
|
||||
settings.mainHand = EnumHandSide.RIGHT;
|
||||
|
||||
// Gui Compatibility
|
||||
settings.keyBindPickBlock = mc.gameSettings.keyBindPickBlock;
|
||||
settings.keyBindsHotbar = mc.gameSettings.keyBindsHotbar;
|
||||
settings.keyBindInventory = mc.gameSettings.keyBindInventory;
|
||||
settings.keyBindDrop = mc.gameSettings.keyBindDrop;
|
||||
|
||||
// Private fields that must be initialized
|
||||
IGameSettings accessor = (IGameSettings) settings;
|
||||
accessor.setMc(bm);
|
||||
accessor.setSetModelParts(new HashSet<>());
|
||||
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* 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.bot.impl;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.bot.IBaritoneUser;
|
||||
import baritone.utils.PlayerMovementInput;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.client.network.NetworkPlayerInfo;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.IMerchant;
|
||||
import net.minecraft.entity.passive.AbstractHorse;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.stats.RecipeBook;
|
||||
import net.minecraft.stats.StatisticsManager;
|
||||
import net.minecraft.tileentity.CommandBlockBaseLogic;
|
||||
import net.minecraft.tileentity.TileEntityCommandBlock;
|
||||
import net.minecraft.tileentity.TileEntitySign;
|
||||
import net.minecraft.tileentity.TileEntityStructure;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.world.GameType;
|
||||
import net.minecraft.world.IInteractionObject;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
// Some Notes:
|
||||
// - Inventory handling!
|
||||
// - If chest deposit gets added it will be most useful for bot-system
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 10/23/2018
|
||||
*/
|
||||
@SuppressWarnings("EntityConstructor")
|
||||
public final class BotPlayer extends EntityPlayerSP {
|
||||
|
||||
private final IBaritoneUser user;
|
||||
private NetworkPlayerInfo playerInfo;
|
||||
public boolean isUser;
|
||||
|
||||
public BotPlayer(IBaritoneUser user, Minecraft mc, World world, NetHandlerPlayClient netHandlerPlayClient, StatisticsManager statisticsManager, RecipeBook recipeBook) {
|
||||
super(mc, world, netHandlerPlayClient, statisticsManager, recipeBook);
|
||||
this.user = user;
|
||||
this.movementInput = new PlayerMovementInput(this.user.getBaritone().getInputOverrideHandler());
|
||||
this.isUser = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
this.entityCollisionReduction = Baritone.settings().botCollision.value ? 0.0F : 1.0F;
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUser() {
|
||||
// Used by BotGuiInventory to fix player model rendering in the gui
|
||||
return this.isUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDistanceSq(@Nonnull Entity entityIn) {
|
||||
if (entityIn == Minecraft.getMinecraft().getRenderViewEntity()) {
|
||||
// Always render nametag in BotGuiInventory
|
||||
return 0.0;
|
||||
} else {
|
||||
return super.getDistanceSq(entityIn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void sendStatusMessage(@Nonnull ITextComponent chatComponent, boolean actionBar) {
|
||||
// TODO: Custom message handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(@Nonnull ITextComponent component) {
|
||||
// TODO: Custom message handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openEditSign(@Nonnull TileEntitySign signTile) {
|
||||
// TODO: Custom GUI handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayGuiEditCommandCart(@Nonnull CommandBlockBaseLogic commandBlock) {
|
||||
// TODO: Custom GUI handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayGuiCommandBlock(@Nonnull TileEntityCommandBlock commandBlock) {
|
||||
// TODO: Custom GUI handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openEditStructure(@Nonnull TileEntityStructure structure) {
|
||||
// TODO: Custom GUI handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openBook(ItemStack stack, EnumHand hand) {
|
||||
// TODO: Custom GUI handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayGUIChest(@Nonnull IInventory chestInventory) {
|
||||
// TODO: Custom GUI handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openGuiHorseInventory(@Nonnull AbstractHorse horse, IInventory inventoryIn) {
|
||||
// TODO: Custom GUI handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayGui(IInteractionObject guiOwner) {
|
||||
// TODO: Custom GUI handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayVillagerTradeGui(IMerchant villager) {
|
||||
// TODO: Custom GUI handling
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCriticalHit(@Nonnull Entity entityHit) {
|
||||
// Don't render
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnchantmentCritical(@Nonnull Entity entityHit) {
|
||||
// Don't render
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCurrentViewEntity() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpectator() {
|
||||
NetworkPlayerInfo networkplayerinfo = this.connection.getPlayerInfo(this.getGameProfile().getId());
|
||||
// noinspection ConstantConditions
|
||||
return networkplayerinfo != null && networkplayerinfo.getGameType() == GameType.SPECTATOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCreative() {
|
||||
NetworkPlayerInfo networkplayerinfo = this.connection.getPlayerInfo(this.getGameProfile().getId());
|
||||
// noinspection ConstantConditions
|
||||
return networkplayerinfo != null && networkplayerinfo.getGameType() == GameType.CREATIVE;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected NetworkPlayerInfo getPlayerInfo() {
|
||||
return this.playerInfo == null ? (this.playerInfo = this.connection.getPlayerInfo(this.getUniqueID())) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoJumpEnabled() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* 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.bot.impl;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.profiler.Profiler;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.EnumDifficulty;
|
||||
import net.minecraft.world.WorldSettings;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 11/7/2018
|
||||
*/
|
||||
public final class BotWorld extends WorldClient {
|
||||
|
||||
private static Profiler BOT_WORLD_PROFILER = new Profiler();
|
||||
private final Map<ChunkPos, IntSet> loadedChunksMap;
|
||||
|
||||
public BotWorld(WorldSettings settings, int dimension) {
|
||||
super(null, settings, dimension, EnumDifficulty.EASY, BOT_WORLD_PROFILER);
|
||||
this.loadedChunksMap = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(double x, double y, double z, SoundEvent soundIn, SoundCategory category, float volume, float pitch, boolean distanceDelay) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntityToWorld(int entityID, Entity entity) {
|
||||
this.removeEntityFromWorld(entityID);
|
||||
this.spawnEntity(entity);
|
||||
this.entitiesById.addKey(entityID, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity removeEntityFromWorld(int entityID) {
|
||||
Entity entity = this.entitiesById.lookup(entityID);
|
||||
if (entity != null && !(entity instanceof BotPlayer)) {
|
||||
this.removeEntity(entity);
|
||||
this.entitiesById.removeObject(entityID);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity getEntityByID(int id) {
|
||||
return this.entitiesById.lookup(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bot The bot requesting the chunk
|
||||
* @param chunkX The chunk X position
|
||||
* @param chunkZ The chunk Z position
|
||||
* @param load {@code true} if the chunk is being loaded, {@code false} if the chunk is being unloaded.
|
||||
* @return Whether or not the chunk needs to be loaded or unloaded accordingly.
|
||||
*/
|
||||
public boolean handlePreChunk(BotPlayer bot, int chunkX, int chunkZ, boolean load) {
|
||||
IntSet bots = this.loadedChunksMap.computeIfAbsent(new ChunkPos(chunkX, chunkZ), $ -> new IntArraySet());
|
||||
if (load) {
|
||||
boolean wasEmpty = bots.isEmpty();
|
||||
bots.add(bot.getEntityId());
|
||||
return wasEmpty;
|
||||
} else {
|
||||
bots.remove(bot.getEntityId());
|
||||
return bots.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public void handleWorldRemove(BotPlayer bot) {
|
||||
// Remove Bot from world
|
||||
this.removeEntity(bot);
|
||||
this.entitiesById.removeObject(bot.getEntityId());
|
||||
|
||||
// Unload all chunks that are no longer loaded by the removed Bot
|
||||
this.loadedChunksMap.entrySet().stream()
|
||||
.peek(entry -> entry.getValue().remove(bot.getEntityId()))
|
||||
.filter(entry -> entry.getValue().isEmpty())
|
||||
.forEach(entry -> this.doPreChunk(entry.getKey().x, entry.getKey().z, false));
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import baritone.api.IBaritone;
|
||||
import baritone.api.cache.ICachedWorld;
|
||||
import baritone.api.cache.IWorldData;
|
||||
import baritone.api.utils.Helper;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -35,7 +36,6 @@ import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
/**
|
||||
@@ -69,7 +69,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
* All chunk positions pending packing. This map will be updated in-place if a new update to the chunk occurs
|
||||
* while waiting in the queue for the packer thread to get to it.
|
||||
*/
|
||||
private final Map<ChunkPos, Chunk> toPackMap = new ConcurrentHashMap<>();
|
||||
private final Map<ChunkPos, Chunk> toPackMap = CacheBuilder.newBuilder().softValues().<ChunkPos, Chunk>build().asMap();
|
||||
|
||||
private final int dimension;
|
||||
|
||||
@@ -307,6 +307,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
try {
|
||||
ChunkPos pos = toPackQueue.take();
|
||||
Chunk chunk = toPackMap.remove(pos);
|
||||
if (toPackQueue.size() > Baritone.settings().chunkPackerQueueMaxSize.value) {
|
||||
continue;
|
||||
}
|
||||
CachedChunk cached = ChunkPacker.pack(chunk);
|
||||
CachedWorld.this.updateCachedChunk(cached);
|
||||
//System.out.println("Processed chunk at " + chunk.x + "," + chunk.z);
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package baritone.cache;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.cache.IWorldProvider;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import baritone.utils.accessor.IAnvilChunkLoader;
|
||||
@@ -161,10 +160,6 @@ public class WorldProvider implements IWorldProvider {
|
||||
readmeDir = baritone.getDirectory();
|
||||
}
|
||||
|
||||
if (this.baritone != BaritoneAPI.getProvider().getPrimaryBaritone()) {
|
||||
worldDir = worldDir.resolve("bot");
|
||||
}
|
||||
|
||||
return Optional.of(new Tuple<>(worldDir, readmeDir));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* 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.command.defaults;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.bot.IBaritoneUser;
|
||||
import baritone.api.bot.connect.IConnectionResult;
|
||||
import baritone.api.command.Command;
|
||||
import baritone.api.command.argument.IArgConsumer;
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.exception.CommandInvalidTypeException;
|
||||
import baritone.api.event.events.ChatEvent;
|
||||
import baritone.bot.UserManager;
|
||||
import baritone.bot.impl.BotGuiInventory;
|
||||
import net.minecraft.util.Session;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/2/2020
|
||||
*/
|
||||
public class BotCommand extends Command {
|
||||
|
||||
public BotCommand(IBaritone baritone) {
|
||||
super(baritone, "bot");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||
final Action action = Action.getByName(args.getString());
|
||||
if (action == null) {
|
||||
throw new CommandInvalidTypeException(args.consumed(), "an action");
|
||||
}
|
||||
|
||||
if (action == Action.ADD) {
|
||||
final String username = args.hasAny() ? args.getString() : "Bot" + System.currentTimeMillis() % 1000;
|
||||
final Session session = new Session(username, UUID.randomUUID().toString(), "", "");
|
||||
final IConnectionResult result = UserManager.INSTANCE.connect(session);
|
||||
logDirect(result.toString());
|
||||
} else if (action.requiresBotSelector()) {
|
||||
final String selector = args.getString();
|
||||
final List<IBaritoneUser> bots;
|
||||
|
||||
if (selector.equals("*")) {
|
||||
bots = UserManager.INSTANCE.getUsers();
|
||||
} else if (selector.contains(",")) {
|
||||
bots = Arrays.stream(selector.split(","))
|
||||
.map(UserManager.INSTANCE::getUserByName)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
bots = UserManager.INSTANCE.getUserByName(selector)
|
||||
.map(Collections::singletonList)
|
||||
.orElseGet(Collections::emptyList);
|
||||
}
|
||||
|
||||
if (bots.isEmpty()) {
|
||||
throw new CommandInvalidTypeException(args.consumed(), "selector didn't match any bots");
|
||||
}
|
||||
|
||||
if (action == Action.INVENTORY) {
|
||||
// Only display one inventory lol
|
||||
final IBaritoneUser bot = bots.get(0);
|
||||
((Baritone) baritone).showScreen(new BotGuiInventory(bot));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case DISCONNECT: {
|
||||
bots.forEach(bot -> UserManager.INSTANCE.disconnect(bot, null));
|
||||
break;
|
||||
}
|
||||
case SAY: {
|
||||
final String message = args.rawRest();
|
||||
bots.forEach(bot -> bot.getPlayerContext().player().sendChatMessage(message));
|
||||
break;
|
||||
}
|
||||
case EXECUTE: {
|
||||
final String command = FORCE_COMMAND_PREFIX + args.rawRest();
|
||||
bots.forEach(bot -> bot.getBaritone().getGameEventHandler().onSendChatMessage(new ChatEvent(command)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> tabComplete(String label, IArgConsumer args) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortDesc() {
|
||||
return "Manage bots";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLongDesc() {
|
||||
return Arrays.asList(
|
||||
"Spawns a bot",
|
||||
"",
|
||||
"Usage:",
|
||||
"> bot add/a <name>",
|
||||
"> bot inventory/i [bot]",
|
||||
"> bot disconnect/d [bot]",
|
||||
"> bot say/s [bot] [args...]",
|
||||
"> bot execute/e [bot] [args...]"
|
||||
);
|
||||
}
|
||||
|
||||
private enum Action {
|
||||
ADD("add", "a"),
|
||||
INVENTORY("inventory", "i"),
|
||||
DISCONNECT("disconnect", "d"),
|
||||
SAY("say", "s"),
|
||||
EXECUTE("execute", "e");
|
||||
private final String[] names;
|
||||
|
||||
Action(String... names) {
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
public boolean requiresBotSelector() {
|
||||
return this == INVENTORY || this == DISCONNECT || this == SAY || this == EXECUTE;
|
||||
}
|
||||
|
||||
public static Action getByName(String name) {
|
||||
for (Action action : Action.values()) {
|
||||
for (String alias : action.names) {
|
||||
if (alias.equalsIgnoreCase(name)) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String[] getAllNames() {
|
||||
Set<String> names = new HashSet<>();
|
||||
for (Action action : Action.values()) {
|
||||
names.addAll(Arrays.asList(action.names));
|
||||
}
|
||||
return names.toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,6 @@ public final class DefaultCommands {
|
||||
new LitematicaCommand(baritone),
|
||||
new ComeCommand(baritone),
|
||||
new AxisCommand(baritone),
|
||||
new BotCommand(baritone),
|
||||
new ForceCancelCommand(baritone),
|
||||
new GcCommand(baritone),
|
||||
new InvertCommand(baritone),
|
||||
@@ -67,7 +66,8 @@ public final class DefaultCommands {
|
||||
new WaypointsCommand(baritone),
|
||||
new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"),
|
||||
new CommandAlias(baritone, "home", "Path to your home waypoint", "waypoints goto home"),
|
||||
new SelCommand(baritone)
|
||||
new SelCommand(baritone),
|
||||
new ElytraCommand(baritone)
|
||||
));
|
||||
ExecutionControlCommands prc = new ExecutionControlCommands(baritone);
|
||||
commands.add(prc.pauseCommand);
|
||||
|
||||
224
src/main/java/baritone/command/defaults/ElytraCommand.java
Normal file
224
src/main/java/baritone/command/defaults/ElytraCommand.java
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* 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.command.defaults;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.command.Command;
|
||||
import baritone.api.command.argument.IArgConsumer;
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.exception.CommandInvalidStateException;
|
||||
import baritone.api.command.helpers.TabCompleteHelper;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.process.ICustomGoalProcess;
|
||||
import baritone.api.process.IElytraProcess;
|
||||
import net.minecraft.client.multiplayer.ServerData;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.util.text.event.ClickEvent;
|
||||
import net.minecraft.util.text.event.HoverEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
|
||||
|
||||
public class ElytraCommand extends Command {
|
||||
|
||||
public ElytraCommand(IBaritone baritone) {
|
||||
super(baritone, "elytra");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||
final ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
|
||||
final IElytraProcess elytra = baritone.getElytraProcess();
|
||||
if (args.hasExactlyOne() && args.peekString().equals("supported")) {
|
||||
logDirect(elytra.isLoaded() ? "yes" : unsupportedSystemMessage());
|
||||
return;
|
||||
}
|
||||
if (!elytra.isLoaded()) {
|
||||
throw new CommandInvalidStateException(unsupportedSystemMessage());
|
||||
}
|
||||
|
||||
if (!args.hasAny()) {
|
||||
if (Baritone.settings().elytraTermsAccepted.value) {
|
||||
if (detectOn2b2t()) {
|
||||
warn2b2t();
|
||||
}
|
||||
} else {
|
||||
gatekeep();
|
||||
}
|
||||
Goal iGoal = customGoalProcess.mostRecentGoal();
|
||||
if (iGoal == null) {
|
||||
throw new CommandInvalidStateException("No goal has been set");
|
||||
}
|
||||
if (ctx.player().dimension != -1) {
|
||||
throw new CommandInvalidStateException("Only works in the nether");
|
||||
}
|
||||
try {
|
||||
elytra.pathTo(iGoal);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new CommandInvalidStateException(ex.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final String action = args.getString();
|
||||
switch (action) {
|
||||
case "reset": {
|
||||
elytra.resetState();
|
||||
logDirect("Reset state but still flying to same goal");
|
||||
break;
|
||||
}
|
||||
case "repack": {
|
||||
elytra.repackChunks();
|
||||
logDirect("Queued all loaded chunks for repacking");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new CommandInvalidStateException("Invalid action");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void warn2b2t() {
|
||||
if (Baritone.settings().elytraPredictTerrain.value) {
|
||||
long seed = Baritone.settings().elytraNetherSeed.value;
|
||||
if (seed != NEW_2B2T_SEED && seed != OLD_2B2T_SEED) {
|
||||
logDirect(new TextComponentString("It looks like you're on 2b2t, but elytraNetherSeed is incorrect.")); // match color
|
||||
logDirect(suggest2b2tSeeds());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ITextComponent suggest2b2tSeeds() {
|
||||
TextComponentString clippy = new TextComponentString("");
|
||||
clippy.appendText("Within a few hundred blocks of spawn/axis/highways/etc, the terrain is too fragmented to be predictable. Baritone Elytra will still work, just with backtracking. ");
|
||||
clippy.appendText("However, once you get more than a few thousand blocks out, you should try ");
|
||||
TextComponentString olderSeed = new TextComponentString("the older seed (click here)");
|
||||
olderSeed.getStyle().setUnderlined(true).setBold(true).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraNetherSeed " + OLD_2B2T_SEED))).setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, FORCE_COMMAND_PREFIX + "set elytraNetherSeed " + OLD_2B2T_SEED));
|
||||
clippy.appendSibling(olderSeed);
|
||||
clippy.appendText(". Once you're further out into newer terrain generation (this includes everything up through 1.12), you should try ");
|
||||
TextComponentString newerSeed = new TextComponentString("the newer seed (click here)");
|
||||
newerSeed.getStyle().setUnderlined(true).setBold(true).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraNetherSeed " + NEW_2B2T_SEED))).setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, FORCE_COMMAND_PREFIX + "set elytraNetherSeed " + NEW_2B2T_SEED));
|
||||
clippy.appendSibling(newerSeed);
|
||||
clippy.appendText(". Once you get into 1.19 terrain, the terrain becomes unpredictable again, due to custom non-vanilla generation, and you should set #elytraPredictTerrain to false. ");
|
||||
return clippy;
|
||||
}
|
||||
|
||||
private void gatekeep() {
|
||||
TextComponentString gatekeep = new TextComponentString("");
|
||||
gatekeep.appendText("To disable this message, enable the setting elytraTermsAccepted\n");
|
||||
gatekeep.appendText("Baritone Elytra is an experimental feature. It is only intended for long distance travel in the Nether using fireworks for vanilla boost. It will not work with any other mods (\"hacks\") for non-vanilla boost. ");
|
||||
TextComponentString gatekeep2 = new TextComponentString("If you want Baritone to attempt to take off from the ground for you, you can enable the elytraAutoJump setting (not advisable on laggy servers!). ");
|
||||
gatekeep2.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraAutoJump true")));
|
||||
gatekeep.appendSibling(gatekeep2);
|
||||
TextComponentString gatekeep3 = new TextComponentString("If you want Baritone to go slower, enable the elytraConserveFireworks setting and/or decrease the elytraFireworkSpeed setting. ");
|
||||
gatekeep3.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraConserveFireworks true\n" + Baritone.settings().prefix.value + "set elytraFireworkSpeed 0.6\n(the 0.6 number is just an example, tweak to your liking)")));
|
||||
gatekeep.appendSibling(gatekeep3);
|
||||
TextComponentString gatekeep4 = new TextComponentString("Baritone Elytra ");
|
||||
TextComponentString red = new TextComponentString("wants to know the seed");
|
||||
red.getStyle().setColor(TextFormatting.RED).setUnderlined(true).setBold(true);
|
||||
gatekeep4.appendSibling(red);
|
||||
gatekeep4.appendText(" of the world you are in. If it doesn't have the correct seed, it will frequently backtrack. It uses the seed to generate terrain far beyond what you can see, since terrain obstacles in the Nether can be much larger than your render distance. ");
|
||||
gatekeep.appendSibling(gatekeep4);
|
||||
gatekeep.appendText("\n");
|
||||
if (detectOn2b2t()) {
|
||||
TextComponentString gatekeep5 = new TextComponentString("It looks like you're on 2b2t. ");
|
||||
gatekeep5.appendSibling(suggest2b2tSeeds());
|
||||
if (!Baritone.settings().elytraPredictTerrain.value) {
|
||||
gatekeep5.appendText(Baritone.settings().prefix.value + "elytraPredictTerrain is currently disabled. ");
|
||||
} else {
|
||||
if (Baritone.settings().elytraNetherSeed.value == NEW_2B2T_SEED) {
|
||||
gatekeep5.appendText("You are using the newer seed. ");
|
||||
} else if (Baritone.settings().elytraNetherSeed.value == OLD_2B2T_SEED) {
|
||||
gatekeep5.appendText("You are using the older seed. ");
|
||||
} else {
|
||||
gatekeep5.appendText("Defaulting to the newer seed. ");
|
||||
Baritone.settings().elytraNetherSeed.value = NEW_2B2T_SEED;
|
||||
}
|
||||
}
|
||||
gatekeep.appendSibling(gatekeep5);
|
||||
} else {
|
||||
if (Baritone.settings().elytraNetherSeed.value == NEW_2B2T_SEED) {
|
||||
TextComponentString gatekeep5 = new TextComponentString("Baritone doesn't know the seed of your world. Set it with: " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere\n");
|
||||
gatekeep5.appendText("For the time being, elytraPredictTerrain is defaulting to false since the seed is unknown.");
|
||||
gatekeep.appendSibling(gatekeep5);
|
||||
Baritone.settings().elytraPredictTerrain.value = false;
|
||||
} else {
|
||||
if (Baritone.settings().elytraPredictTerrain.value) {
|
||||
TextComponentString gatekeep5 = new TextComponentString("Baritone Elytra is predicting terrain assuming that " + Baritone.settings().elytraNetherSeed.value + " is the correct seed. Change that with " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere, or disable it with " + Baritone.settings().prefix.value + "set elytraPredictTerrain false");
|
||||
gatekeep.appendSibling(gatekeep5);
|
||||
} else {
|
||||
TextComponentString gatekeep5 = new TextComponentString("Baritone Elytra is not predicting terrain. If you don't know the seed, this is the correct thing to do. If you do know the seed, input it with " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere, and then enable it with " + Baritone.settings().prefix.value + "set elytraPredictTerrain true");
|
||||
gatekeep.appendSibling(gatekeep5);
|
||||
}
|
||||
}
|
||||
}
|
||||
logDirect(gatekeep);
|
||||
}
|
||||
|
||||
private boolean detectOn2b2t() {
|
||||
ServerData data = ctx.minecraft().getCurrentServerData();
|
||||
return data != null && data.serverIP.toLowerCase().contains("2b2t.org");
|
||||
}
|
||||
|
||||
private static final long OLD_2B2T_SEED = -4100785268875389365L;
|
||||
private static final long NEW_2B2T_SEED = 146008555100680L;
|
||||
|
||||
@Override
|
||||
public Stream<String> tabComplete(String label, IArgConsumer args) throws CommandException {
|
||||
TabCompleteHelper helper = new TabCompleteHelper();
|
||||
if (args.hasExactlyOne()) {
|
||||
helper.append("reset", "repack", "supported");
|
||||
}
|
||||
return helper.filterPrefix(args.getString()).stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortDesc() {
|
||||
return "elytra time";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLongDesc() {
|
||||
return Arrays.asList(
|
||||
"The elytra command tells baritone to, in the nether, automatically fly to the current goal.",
|
||||
"",
|
||||
"Usage:",
|
||||
"> elytra - fly to the current goal",
|
||||
"> elytra reset - Resets the state of the process, but will try to keep flying to the same goal.",
|
||||
"> elytra repack - Queues all of the chunks in render distance to be given to the native library.",
|
||||
"> elytra supported - Tells you if baritone ships a native library that is compatible with your PC."
|
||||
);
|
||||
}
|
||||
|
||||
private static String unsupportedSystemMessage() {
|
||||
final String osArch = System.getProperty("os.arch");
|
||||
final String osName = System.getProperty("os.name");
|
||||
return String.format(
|
||||
"Legacy architectures are not supported. Your CPU is %s and your operating system is %s. " +
|
||||
"Supported architectures are 64 bit x86, and 64 bit ARM. Supported operating systems are Windows, " +
|
||||
"Linux, and Mac",
|
||||
osArch, osName
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -23,8 +23,12 @@ import baritone.api.event.events.type.EventState;
|
||||
import baritone.api.event.listener.IEventBus;
|
||||
import baritone.api.event.listener.IGameEventListener;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.api.utils.Pair;
|
||||
import baritone.cache.CachedChunk;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
@@ -59,6 +63,11 @@ public final class GameEventHandler implements IEventBus, Helper {
|
||||
listeners.forEach(l -> l.onTick(event));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostTick(TickEvent event) {
|
||||
listeners.forEach(l -> l.onPostTick(event));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onPlayerUpdate(PlayerUpdateEvent event) {
|
||||
listeners.forEach(l -> l.onPlayerUpdate(event));
|
||||
@@ -75,13 +84,10 @@ public final class GameEventHandler implements IEventBus, Helper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onChunkEvent(ChunkEvent event) {
|
||||
public void onChunkEvent(ChunkEvent event) {
|
||||
EventState state = event.getState();
|
||||
ChunkEvent.Type type = event.getType();
|
||||
|
||||
boolean isPostPopulate = state == EventState.POST
|
||||
&& (type == ChunkEvent.Type.POPULATE_FULL || type == ChunkEvent.Type.POPULATE_PARTIAL);
|
||||
|
||||
World world = baritone.getPlayerContext().world();
|
||||
|
||||
// Whenever the server sends us to another dimension, chunks are unloaded
|
||||
@@ -91,7 +97,7 @@ public final class GameEventHandler implements IEventBus, Helper {
|
||||
&& type == ChunkEvent.Type.UNLOAD
|
||||
&& world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
|
||||
|
||||
if (isPostPopulate || isPreUnload) {
|
||||
if (event.isPostPopulate() || isPreUnload) {
|
||||
baritone.getWorldProvider().ifWorldLoaded(worldData -> {
|
||||
Chunk chunk = world.getChunk(event.getX(), event.getZ());
|
||||
worldData.getCachedWorld().queueForPacking(chunk);
|
||||
@@ -102,6 +108,25 @@ public final class GameEventHandler implements IEventBus, Helper {
|
||||
listeners.forEach(l -> l.onChunkEvent(event));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockChange(BlockChangeEvent event) {
|
||||
if (Baritone.settings().repackOnAnyBlockChange.value) {
|
||||
final boolean keepingTrackOf = event.getBlocks().stream()
|
||||
.map(Pair::second).map(IBlockState::getBlock)
|
||||
.anyMatch(CachedChunk.BLOCKS_TO_KEEP_TRACK_OF::contains);
|
||||
|
||||
if (keepingTrackOf) {
|
||||
baritone.getWorldProvider().ifWorldLoaded(worldData -> {
|
||||
final World world = baritone.getPlayerContext().world();
|
||||
ChunkPos pos = event.getChunkPos();
|
||||
worldData.getCachedWorld().queueForPacking(world.getChunk(pos.x, pos.z));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
listeners.forEach(l -> l.onBlockChange(event));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onRenderPass(RenderEvent event) {
|
||||
listeners.forEach(l -> l.onRenderPass(event));
|
||||
|
||||
@@ -66,11 +66,13 @@ public class CalculationContext {
|
||||
public final boolean allowJumpAt256;
|
||||
public final boolean allowParkourAscend;
|
||||
public final boolean assumeWalkOnWater;
|
||||
public boolean allowFallIntoLava;
|
||||
public final int frostWalker;
|
||||
public final boolean allowDiagonalDescend;
|
||||
public final boolean allowDiagonalAscend;
|
||||
public final boolean allowDownward;
|
||||
public final int maxFallHeightNoWater;
|
||||
public int minFallHeight;
|
||||
public int maxFallHeightNoWater;
|
||||
public final int maxFallHeightBucket;
|
||||
public final double waterWalkSpeed;
|
||||
public final double breakBlockAdditionalCost;
|
||||
@@ -105,10 +107,12 @@ public class CalculationContext {
|
||||
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value;
|
||||
this.allowParkourAscend = Baritone.settings().allowParkourAscend.value;
|
||||
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value;
|
||||
this.allowFallIntoLava = false; // Super secret internal setting for ElytraBehavior
|
||||
this.frostWalker = EnchantmentHelper.getMaxEnchantmentLevel(Enchantments.FROST_WALKER, baritone.getPlayerContext().player());
|
||||
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value;
|
||||
this.allowDiagonalAscend = Baritone.settings().allowDiagonalAscend.value;
|
||||
this.allowDownward = Baritone.settings().allowDownward.value;
|
||||
this.minFallHeight = 3; // Minimum fall height used by MovementFall
|
||||
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value;
|
||||
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value;
|
||||
int depth = EnchantmentHelper.getDepthStriderModifier(player);
|
||||
|
||||
@@ -154,10 +154,11 @@ public class MovementDescend extends Movement {
|
||||
// this check prevents it from getting the block at y=-1 and crashing
|
||||
return false;
|
||||
}
|
||||
boolean reachedMinimum = fallHeight >= context.minFallHeight;
|
||||
IBlockState ontoBlock = context.get(destX, newY, destZ);
|
||||
int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY
|
||||
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
|
||||
if (MovementHelper.isWater(ontoBlock.getBlock())) {
|
||||
if (reachedMinimum && MovementHelper.isWater(ontoBlock.getBlock())) {
|
||||
if (!MovementHelper.canWalkThrough(context, destX, newY, destZ, ontoBlock)) {
|
||||
return false;
|
||||
}
|
||||
@@ -178,6 +179,14 @@ public class MovementDescend extends Movement {
|
||||
res.cost = tentativeCost;// TODO incorporate water swim up cost?
|
||||
return false;
|
||||
}
|
||||
if (reachedMinimum && context.allowFallIntoLava && MovementHelper.isLava(ontoBlock.getBlock())) {
|
||||
// found a fall into lava
|
||||
res.x = destX;
|
||||
res.y = newY;
|
||||
res.z = destZ;
|
||||
res.cost = tentativeCost;
|
||||
return false;
|
||||
}
|
||||
if (unprotectedFallHeight <= 11 && (ontoBlock.getBlock() == Blocks.VINE || ontoBlock.getBlock() == Blocks.LADDER)) {
|
||||
// if fall height is greater than or equal to 11, we don't actually grab on to vines or ladders. the more you know
|
||||
// this effectively "resets" our falling speed
|
||||
@@ -195,7 +204,7 @@ public class MovementDescend extends Movement {
|
||||
if (MovementHelper.isBottomSlab(ontoBlock)) {
|
||||
return false; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
|
||||
}
|
||||
if (unprotectedFallHeight <= context.maxFallHeightNoWater + 1) {
|
||||
if (reachedMinimum && unprotectedFallHeight <= context.maxFallHeightNoWater + 1) {
|
||||
// fallHeight = 4 means onto.up() is 3 blocks down, which is the max
|
||||
res.x = destX;
|
||||
res.y = newY + 1;
|
||||
@@ -203,7 +212,7 @@ public class MovementDescend extends Movement {
|
||||
res.cost = tentativeCost;
|
||||
return false;
|
||||
}
|
||||
if (context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) {
|
||||
if (reachedMinimum && context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) {
|
||||
res.x = destX;
|
||||
res.y = newY + 1;// this is the block we're falling onto, so dest is +1
|
||||
res.z = destZ;
|
||||
|
||||
@@ -36,6 +36,11 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC
|
||||
*/
|
||||
private Goal goal;
|
||||
|
||||
/**
|
||||
* The most recent goal. Not invalidated upon {@link #onLostControl()}
|
||||
*/
|
||||
private Goal mostRecentGoal;
|
||||
|
||||
/**
|
||||
* The current process state.
|
||||
*
|
||||
@@ -50,6 +55,10 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC
|
||||
@Override
|
||||
public void setGoal(Goal goal) {
|
||||
this.goal = goal;
|
||||
this.mostRecentGoal = goal;
|
||||
if (baritone.getElytraProcess().isActive()) {
|
||||
baritone.getElytraProcess().pathTo(goal);
|
||||
}
|
||||
if (this.state == State.NONE) {
|
||||
this.state = State.GOAL_SET;
|
||||
}
|
||||
@@ -68,6 +77,11 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC
|
||||
return this.goal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Goal mostRecentGoal() {
|
||||
return this.mostRecentGoal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return this.state != State.NONE;
|
||||
|
||||
565
src/main/java/baritone/process/ElytraProcess.java
Normal file
565
src/main/java/baritone/process/ElytraProcess.java
Normal file
@@ -0,0 +1,565 @@
|
||||
/*
|
||||
* 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.process;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.*;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.api.event.listener.AbstractGameEventListener;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalBlock;
|
||||
import baritone.api.pathing.goals.GoalXZ;
|
||||
import baritone.api.pathing.goals.GoalYLevel;
|
||||
import baritone.api.pathing.movement.IMovement;
|
||||
import baritone.api.pathing.path.IPathExecutor;
|
||||
import baritone.api.process.IBaritoneProcess;
|
||||
import baritone.api.process.IElytraProcess;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.Rotation;
|
||||
import baritone.api.utils.RotationUtils;
|
||||
import baritone.api.utils.input.Input;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.movements.MovementFall;
|
||||
import baritone.process.elytra.ElytraBehavior;
|
||||
import baritone.process.elytra.NetherPathfinderContext;
|
||||
import baritone.process.elytra.NullElytraProcess;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import baritone.utils.PathingCommandContext;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static baritone.api.pathing.movement.ActionCosts.COST_INF;
|
||||
|
||||
public class ElytraProcess extends BaritoneProcessHelper implements IBaritoneProcess, IElytraProcess, AbstractGameEventListener {
|
||||
public State state;
|
||||
private boolean goingToLandingSpot;
|
||||
private BetterBlockPos landingSpot;
|
||||
private boolean reachedGoal; // this basically just prevents potential notification spam
|
||||
private Goal goal;
|
||||
private ElytraBehavior behavior;
|
||||
private boolean predictingTerrain;
|
||||
|
||||
private ElytraProcess(Baritone baritone) {
|
||||
super(baritone);
|
||||
baritone.getGameEventHandler().registerEventListener(this);
|
||||
}
|
||||
|
||||
public static <T extends IElytraProcess> T create(final Baritone baritone) {
|
||||
return (T) (NetherPathfinderContext.isSupported()
|
||||
? new ElytraProcess(baritone)
|
||||
: new NullElytraProcess(baritone));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return this.behavior != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetState() {
|
||||
BlockPos destination = this.currentDestination();
|
||||
this.onLostControl();
|
||||
if (destination != null) {
|
||||
this.pathTo(destination);
|
||||
this.repackChunks();
|
||||
}
|
||||
}
|
||||
|
||||
private static final String AUTO_JUMP_FAILURE_MSG = "Failed to compute a walking path to a spot to jump off from. Consider starting from a higher location, near an overhang. Or, you can disable elytraAutoJump and just manually begin gliding.";
|
||||
|
||||
@Override
|
||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||
final long seedSetting = Baritone.settings().elytraNetherSeed.value;
|
||||
if (seedSetting != this.behavior.context.getSeed()) {
|
||||
logDirect("Nether seed changed, recalculating path");
|
||||
this.resetState();
|
||||
}
|
||||
if (predictingTerrain != Baritone.settings().elytraPredictTerrain.value) {
|
||||
logDirect("elytraPredictTerrain setting changed, recalculating path");
|
||||
predictingTerrain = Baritone.settings().elytraPredictTerrain.value;
|
||||
this.resetState();
|
||||
}
|
||||
|
||||
this.behavior.onTick();
|
||||
|
||||
if (calcFailed) {
|
||||
onLostControl();
|
||||
logDirect(AUTO_JUMP_FAILURE_MSG);
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
|
||||
boolean safetyLanding = false;
|
||||
if (ctx.player().isElytraFlying() && shouldLandForSafety()) {
|
||||
if (Baritone.settings().elytraAllowEmergencyLand.value) {
|
||||
logDirect("Emergency landing - almost out of elytra durability or fireworks");
|
||||
safetyLanding = true;
|
||||
} else {
|
||||
logDirect("almost out of elytra durability or fireworks, but I'm going to continue since elytraAllowEmergencyLand is false");
|
||||
}
|
||||
}
|
||||
if (ctx.player().isElytraFlying() && this.state != State.LANDING && (this.behavior.pathManager.isComplete() || safetyLanding)) {
|
||||
final BetterBlockPos last = this.behavior.pathManager.path.getLast();
|
||||
if (last != null && (ctx.player().getDistanceSqToCenter(last) < (48 * 48) || safetyLanding) && (!goingToLandingSpot || (safetyLanding && this.landingSpot == null))) {
|
||||
logDirect("Path complete, picking a nearby safe landing spot...");
|
||||
BetterBlockPos landingSpot = findSafeLandingSpot(ctx.playerFeet());
|
||||
// if this fails we will just keep orbiting the last node until we run out of rockets or the user intervenes
|
||||
if (landingSpot != null) {
|
||||
this.pathTo0(landingSpot, true);
|
||||
this.landingSpot = landingSpot;
|
||||
}
|
||||
this.goingToLandingSpot = true;
|
||||
}
|
||||
|
||||
if (last != null && ctx.player().getDistanceSqToCenter(last) < 1) {
|
||||
if (Baritone.settings().notificationOnPathComplete.value && !reachedGoal) {
|
||||
logNotification("Pathing complete", false);
|
||||
}
|
||||
if (Baritone.settings().disconnectOnArrival.value && !reachedGoal) {
|
||||
// don't be active when the user logs back in
|
||||
this.onLostControl();
|
||||
ctx.world().sendQuittingDisconnectingPacket();
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
reachedGoal = true;
|
||||
|
||||
// we are goingToLandingSpot and we are in the last node of the path
|
||||
if (this.goingToLandingSpot) {
|
||||
this.state = State.LANDING;
|
||||
logDirect("Above the landing spot, landing...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state == State.LANDING) {
|
||||
final BetterBlockPos endPos = this.landingSpot != null ? this.landingSpot : behavior.pathManager.path.getLast();
|
||||
if (ctx.player().isElytraFlying() && endPos != null) {
|
||||
Vec3d from = ctx.player().getPositionVector();
|
||||
Vec3d to = new Vec3d(((double) endPos.x) + 0.5, from.y, ((double) endPos.z) + 0.5);
|
||||
Rotation rotation = RotationUtils.calcRotationFromVec3d(from, to, ctx.playerRotations());
|
||||
baritone.getLookBehavior().updateTarget(new Rotation(rotation.getYaw(), 0), false); // this will be overwritten, probably, by behavior tick
|
||||
|
||||
if (ctx.player().posY < endPos.y - LANDING_COLUMN_HEIGHT) {
|
||||
logDirect("bad landing spot, trying again...");
|
||||
landingSpotIsBad(endPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.player().isElytraFlying()) {
|
||||
behavior.landingMode = this.state == State.LANDING;
|
||||
this.goal = null;
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
behavior.tick();
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
} else if (this.state == State.LANDING) {
|
||||
if (Math.sqrt(ctx.player().motionX * ctx.player().motionX + ctx.player().motionZ * ctx.player().motionZ) > 0.001) {
|
||||
logDirect("Landed, but still moving, waiting for velocity to die down... ");
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.SNEAK, true);
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
logDirect("Done :)");
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
this.onLostControl();
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
|
||||
if (this.state == State.FLYING || this.state == State.START_FLYING) {
|
||||
this.state = ctx.player().onGround && Baritone.settings().elytraAutoJump.value
|
||||
? State.LOCATE_JUMP
|
||||
: State.START_FLYING;
|
||||
}
|
||||
|
||||
if (this.state == State.LOCATE_JUMP) {
|
||||
if (shouldLandForSafety()) {
|
||||
logDirect("Not taking off, because elytra durability or fireworks are so low that I would immediately emergency land anyway.");
|
||||
onLostControl();
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
if (this.goal == null) {
|
||||
this.goal = new GoalYLevel(31);
|
||||
}
|
||||
final IPathExecutor executor = baritone.getPathingBehavior().getCurrent();
|
||||
if (executor != null && executor.getPath().getGoal() == this.goal) {
|
||||
final IMovement fall = executor.getPath().movements().stream()
|
||||
.filter(movement -> movement instanceof MovementFall)
|
||||
.findFirst().orElse(null);
|
||||
|
||||
if (fall != null) {
|
||||
final BetterBlockPos from = new BetterBlockPos(
|
||||
(fall.getSrc().x + fall.getDest().x) / 2,
|
||||
(fall.getSrc().y + fall.getDest().y) / 2,
|
||||
(fall.getSrc().z + fall.getDest().z) / 2
|
||||
);
|
||||
behavior.pathManager.pathToDestination(from).whenComplete((result, ex) -> {
|
||||
if (ex == null) {
|
||||
this.state = State.GET_TO_JUMP;
|
||||
return;
|
||||
}
|
||||
onLostControl();
|
||||
});
|
||||
this.state = State.PAUSE;
|
||||
} else {
|
||||
onLostControl();
|
||||
logDirect(AUTO_JUMP_FAILURE_MSG);
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
}
|
||||
return new PathingCommandContext(this.goal, PathingCommandType.SET_GOAL_AND_PAUSE, new WalkOffCalculationContext(baritone));
|
||||
}
|
||||
|
||||
// yucky
|
||||
if (this.state == State.PAUSE) {
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
|
||||
if (this.state == State.GET_TO_JUMP) {
|
||||
final IPathExecutor executor = baritone.getPathingBehavior().getCurrent();
|
||||
final boolean canStartFlying = ctx.player().fallDistance > 1.0f
|
||||
&& !isSafeToCancel
|
||||
&& executor != null
|
||||
&& executor.getPath().movements().get(executor.getPosition()) instanceof MovementFall;
|
||||
|
||||
if (canStartFlying) {
|
||||
this.state = State.START_FLYING;
|
||||
} else {
|
||||
return new PathingCommand(null, PathingCommandType.SET_GOAL_AND_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state == State.START_FLYING) {
|
||||
if (!isSafeToCancel) {
|
||||
// owned
|
||||
baritone.getPathingBehavior().secretInternalSegmentCancel();
|
||||
}
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
if (ctx.player().fallDistance > 1.0f) {
|
||||
baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true);
|
||||
}
|
||||
}
|
||||
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
|
||||
}
|
||||
|
||||
public void landingSpotIsBad(BetterBlockPos endPos) {
|
||||
badLandingSpots.add(endPos);
|
||||
goingToLandingSpot = false;
|
||||
this.landingSpot = null;
|
||||
this.state = State.FLYING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLostControl() {
|
||||
this.goal = null;
|
||||
this.goingToLandingSpot = false;
|
||||
this.landingSpot = null;
|
||||
this.reachedGoal = false;
|
||||
this.state = State.START_FLYING; // TODO: null state?
|
||||
destroyBehaviorAsync();
|
||||
}
|
||||
|
||||
private void destroyBehaviorAsync() {
|
||||
ElytraBehavior behavior = this.behavior;
|
||||
if (behavior != null) {
|
||||
this.behavior = null;
|
||||
Baritone.getExecutor().execute(behavior::destroy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double priority() {
|
||||
return 0; // higher priority than CustomGoalProcess
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayName0() {
|
||||
return "Elytra - " + this.state.description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repackChunks() {
|
||||
if (this.behavior != null) {
|
||||
this.behavior.repackChunks();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos currentDestination() {
|
||||
return this.behavior != null ? this.behavior.destination : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pathTo(BlockPos destination) {
|
||||
this.pathTo0(destination, false);
|
||||
}
|
||||
|
||||
private void pathTo0(BlockPos destination, boolean appendDestination) {
|
||||
if (ctx.player() == null || ctx.player().dimension != -1) {
|
||||
return;
|
||||
}
|
||||
this.onLostControl();
|
||||
this.predictingTerrain = Baritone.settings().elytraPredictTerrain.value;
|
||||
this.behavior = new ElytraBehavior(this.baritone, this, destination, appendDestination);
|
||||
if (ctx.world() != null) {
|
||||
this.behavior.repackChunks();
|
||||
}
|
||||
this.behavior.pathTo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pathTo(Goal iGoal) {
|
||||
final int x;
|
||||
final int y;
|
||||
final int z;
|
||||
if (iGoal instanceof GoalXZ) {
|
||||
GoalXZ goal = (GoalXZ) iGoal;
|
||||
x = goal.getX();
|
||||
y = 64;
|
||||
z = goal.getZ();
|
||||
} else if (iGoal instanceof GoalBlock) {
|
||||
GoalBlock goal = (GoalBlock) iGoal;
|
||||
x = goal.x;
|
||||
y = goal.y;
|
||||
z = goal.z;
|
||||
} else {
|
||||
throw new IllegalArgumentException("The goal must be a GoalXZ or GoalBlock");
|
||||
}
|
||||
if (y <= 0 || y >= 128) {
|
||||
throw new IllegalArgumentException("The y of the goal is not between 0 and 128");
|
||||
}
|
||||
this.pathTo(new BlockPos(x, y, z));
|
||||
}
|
||||
|
||||
private boolean shouldLandForSafety() {
|
||||
ItemStack chest = ctx.player().inventory.armorInventory.get(2);
|
||||
if (chest.getItem() != Items.ELYTRA || chest.getItem().getMaxDamage() - chest.getItemDamage() < Baritone.settings().elytraMinimumDurability.value) {
|
||||
// elytrabehavior replaces when durability <= minimumDurability, so if durability < minimumDurability then we can reasonably assume that the elytra will soon be broken without replacement
|
||||
return true;
|
||||
}
|
||||
NonNullList<ItemStack> inv = ctx.player().inventory.mainInventory;
|
||||
int qty = 0;
|
||||
for (int i = 0; i < 36; i++) {
|
||||
if (ElytraBehavior.isFireworks(inv.get(i))) {
|
||||
qty += inv.get(i).getCount();
|
||||
}
|
||||
}
|
||||
if (qty <= Baritone.settings().elytraMinFireworksBeforeLanding.value) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoaded() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSafeToCancel() {
|
||||
return !this.isActive() || !(this.state == State.FLYING || this.state == State.START_FLYING);
|
||||
}
|
||||
|
||||
public enum State {
|
||||
LOCATE_JUMP("Finding spot to jump off"),
|
||||
PAUSE("Waiting for elytra path"),
|
||||
GET_TO_JUMP("Walking to takeoff"),
|
||||
START_FLYING("Begin flying"),
|
||||
FLYING("Flying"),
|
||||
LANDING("Landing");
|
||||
|
||||
public final String description;
|
||||
|
||||
State(String desc) {
|
||||
this.description = desc;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRenderPass(RenderEvent event) {
|
||||
if (this.behavior != null) this.behavior.onRenderPass(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWorldEvent(WorldEvent event) {
|
||||
if (event.getWorld() != null && event.getState() == EventState.POST) {
|
||||
// Exiting the world, just destroy
|
||||
destroyBehaviorAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkEvent(ChunkEvent event) {
|
||||
if (this.behavior != null) this.behavior.onChunkEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockChange(BlockChangeEvent event) {
|
||||
if (this.behavior != null) this.behavior.onBlockChange(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivePacket(PacketEvent event) {
|
||||
if (this.behavior != null) this.behavior.onReceivePacket(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostTick(TickEvent event) {
|
||||
IBaritoneProcess procThisTick = baritone.getPathingControlManager().mostRecentInControl().orElse(null);
|
||||
if (this.behavior != null && procThisTick == this) this.behavior.onPostTick(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom calculation context which makes the player fall into lava
|
||||
*/
|
||||
public static final class WalkOffCalculationContext extends CalculationContext {
|
||||
|
||||
public WalkOffCalculationContext(IBaritone baritone) {
|
||||
super(baritone, true);
|
||||
this.allowFallIntoLava = true;
|
||||
this.minFallHeight = 8;
|
||||
this.maxFallHeightNoWater = 10000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double costOfPlacingAt(int x, int y, int z, IBlockState current) {
|
||||
return COST_INF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double breakCostMultiplierAt(int x, int y, int z, IBlockState current) {
|
||||
return COST_INF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double placeBucketCost() {
|
||||
return COST_INF;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInBounds(BlockPos pos) {
|
||||
return pos.getY() >= 0 && pos.getY() < 128;
|
||||
}
|
||||
|
||||
private boolean isSafeBlock(Block block) {
|
||||
return block == Blocks.NETHERRACK || block == Blocks.GRAVEL || (block == Blocks.NETHER_BRICK && Baritone.settings().elytraAllowLandOnNetherFortress.value);
|
||||
}
|
||||
|
||||
private boolean isSafeBlock(BlockPos pos) {
|
||||
return isSafeBlock(ctx.world().getBlockState(pos).getBlock());
|
||||
}
|
||||
|
||||
private boolean isAtEdge(BlockPos pos) {
|
||||
return !isSafeBlock(pos.north())
|
||||
|| !isSafeBlock(pos.south())
|
||||
|| !isSafeBlock(pos.east())
|
||||
|| !isSafeBlock(pos.west())
|
||||
// corners
|
||||
|| !isSafeBlock(pos.north().west())
|
||||
|| !isSafeBlock(pos.north().east())
|
||||
|| !isSafeBlock(pos.south().west())
|
||||
|| !isSafeBlock(pos.south().east());
|
||||
}
|
||||
|
||||
private boolean isColumnAir(BlockPos landingSpot, int minHeight) {
|
||||
BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(landingSpot);
|
||||
final int maxY = mut.getY() + minHeight;
|
||||
for (int y = mut.getY() + 1; y <= maxY; y++) {
|
||||
mut.setPos(mut.getX(), y, mut.getZ());
|
||||
if (!ctx.world().isAirBlock(mut)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasAirBubble(BlockPos pos) {
|
||||
final int radius = 4; // Half of the full width, rounded down, as we're counting blocks in each direction from the center
|
||||
BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos();
|
||||
for (int x = -radius; x <= radius; x++) {
|
||||
for (int y = -radius; y <= radius; y++) {
|
||||
for (int z = -radius; z <= radius; z++) {
|
||||
mut.setPos(pos.getX() + x, pos.getY() + y, pos.getZ() + z);
|
||||
if (!ctx.world().isAirBlock(mut)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private BetterBlockPos checkLandingSpot(BlockPos pos, LongOpenHashSet checkedSpots) {
|
||||
BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(pos);
|
||||
while (mut.getY() >= 0) {
|
||||
if (checkedSpots.contains(mut.toLong())) {
|
||||
return null;
|
||||
}
|
||||
checkedSpots.add(mut.toLong());
|
||||
Block block = ctx.world().getBlockState(mut).getBlock();
|
||||
|
||||
if (isSafeBlock(block)) {
|
||||
if (!isAtEdge(mut)) {
|
||||
return new BetterBlockPos(mut);
|
||||
}
|
||||
return null;
|
||||
} else if (block != Blocks.AIR) {
|
||||
return null;
|
||||
}
|
||||
mut.setPos(mut.getX(), mut.getY() - 1, mut.getZ());
|
||||
}
|
||||
return null; // void
|
||||
}
|
||||
|
||||
private static final int LANDING_COLUMN_HEIGHT = 15;
|
||||
private Set<BetterBlockPos> badLandingSpots = new HashSet<>();
|
||||
|
||||
private BetterBlockPos findSafeLandingSpot(BetterBlockPos start) {
|
||||
Queue<BetterBlockPos> queue = new PriorityQueue<>(Comparator.<BetterBlockPos>comparingInt(pos -> (pos.x - start.x) * (pos.x - start.x) + (pos.z - start.z) * (pos.z - start.z)).thenComparingInt(pos -> -pos.y));
|
||||
Set<BetterBlockPos> visited = new HashSet<>();
|
||||
LongOpenHashSet checkedPositions = new LongOpenHashSet();
|
||||
queue.add(start);
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
BetterBlockPos pos = queue.poll();
|
||||
if (ctx.world().isBlockLoaded(pos, false) && isInBounds(pos) && ctx.world().getBlockState(pos).getBlock() == Blocks.AIR) {
|
||||
BetterBlockPos actualLandingSpot = checkLandingSpot(pos, checkedPositions);
|
||||
if (actualLandingSpot != null && isColumnAir(actualLandingSpot, LANDING_COLUMN_HEIGHT) && hasAirBubble(actualLandingSpot.up(LANDING_COLUMN_HEIGHT)) && !badLandingSpots.contains(actualLandingSpot.up(LANDING_COLUMN_HEIGHT))) {
|
||||
return actualLandingSpot.up(LANDING_COLUMN_HEIGHT);
|
||||
}
|
||||
if (visited.add(pos.north())) queue.add(pos.north());
|
||||
if (visited.add(pos.east())) queue.add(pos.east());
|
||||
if (visited.add(pos.south())) queue.add(pos.south());
|
||||
if (visited.add(pos.west())) queue.add(pos.west());
|
||||
if (visited.add(pos.up())) queue.add(pos.up());
|
||||
if (visited.add(pos.down())) queue.add(pos.down());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.process.elytra;
|
||||
|
||||
import dev.babbaj.pathfinder.NetherPathfinder;
|
||||
import dev.babbaj.pathfinder.Octree;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class BlockStateOctreeInterface {
|
||||
|
||||
private final NetherPathfinderContext context;
|
||||
private final long contextPtr;
|
||||
transient long chunkPtr;
|
||||
|
||||
// Guarantee that the first lookup will fetch the context by setting MAX_VALUE
|
||||
private int prevChunkX = Integer.MAX_VALUE;
|
||||
private int prevChunkZ = Integer.MAX_VALUE;
|
||||
|
||||
public BlockStateOctreeInterface(final NetherPathfinderContext context) {
|
||||
this.context = context;
|
||||
this.contextPtr = context.context;
|
||||
}
|
||||
|
||||
public boolean get0(final int x, final int y, final int z) {
|
||||
if ((y | (127 - y)) < 0) {
|
||||
return false;
|
||||
}
|
||||
final int chunkX = x >> 4;
|
||||
final int chunkZ = z >> 4;
|
||||
if (this.chunkPtr == 0 | ((chunkX ^ this.prevChunkX) | (chunkZ ^ this.prevChunkZ)) != 0) {
|
||||
this.prevChunkX = chunkX;
|
||||
this.prevChunkZ = chunkZ;
|
||||
this.chunkPtr = NetherPathfinder.getOrCreateChunk(this.contextPtr, chunkX, chunkZ);
|
||||
}
|
||||
return Octree.getBlock(this.chunkPtr, x & 0xF, y & 0x7F, z & 0xF);
|
||||
}
|
||||
}
|
||||
1366
src/main/java/baritone/process/elytra/ElytraBehavior.java
Normal file
1366
src/main/java/baritone/process/elytra/ElytraBehavior.java
Normal file
File diff suppressed because it is too large
Load Diff
65
src/main/java/baritone/process/elytra/NetherPath.java
Normal file
65
src/main/java/baritone/process/elytra/NetherPath.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.process.elytra;
|
||||
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class NetherPath extends AbstractList<BetterBlockPos> {
|
||||
|
||||
private static final NetherPath EMPTY_PATH = new NetherPath(Collections.emptyList());
|
||||
|
||||
private final List<BetterBlockPos> backing;
|
||||
|
||||
NetherPath(List<BetterBlockPos> backing) {
|
||||
this.backing = backing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BetterBlockPos get(int index) {
|
||||
return this.backing.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.backing.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The last position in the path, or {@code null} if empty
|
||||
*/
|
||||
public BetterBlockPos getLast() {
|
||||
return this.isEmpty() ? null : this.backing.get(this.backing.size() - 1);
|
||||
}
|
||||
|
||||
public Vec3d getVec(int index) {
|
||||
final BetterBlockPos pos = this.get(index);
|
||||
return new Vec3d(pos.x, pos.y, pos.z);
|
||||
}
|
||||
|
||||
public static NetherPath emptyPath() {
|
||||
return EMPTY_PATH;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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.process.elytra;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.event.events.BlockChangeEvent;
|
||||
import baritone.utils.accessor.IBitArray;
|
||||
import baritone.utils.accessor.IBlockStateContainer;
|
||||
import dev.babbaj.pathfinder.NetherPathfinder;
|
||||
import dev.babbaj.pathfinder.Octree;
|
||||
import dev.babbaj.pathfinder.PathSegment;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.BitArray;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.chunk.BlockStateContainer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class NetherPathfinderContext {
|
||||
|
||||
private static final IBlockState AIR_BLOCK_STATE = Blocks.AIR.getDefaultState();
|
||||
// This lock must be held while there are active pointers to chunks in java,
|
||||
// but we just hold it for the entire tick so we don't have to think much about it.
|
||||
public final Object cullingLock = new Object();
|
||||
|
||||
// Visible for access in BlockStateOctreeInterface
|
||||
final long context;
|
||||
private final long seed;
|
||||
private final ExecutorService executor;
|
||||
|
||||
public NetherPathfinderContext(long seed) {
|
||||
this.context = NetherPathfinder.newContext(seed);
|
||||
this.seed = seed;
|
||||
this.executor = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
public void queueCacheCulling(int chunkX, int chunkZ, int maxDistanceBlocks, BlockStateOctreeInterface boi) {
|
||||
this.executor.execute(() -> {
|
||||
synchronized (this.cullingLock) {
|
||||
boi.chunkPtr = 0L;
|
||||
NetherPathfinder.cullFarChunks(this.context, chunkX, chunkZ, maxDistanceBlocks);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void queueForPacking(final Chunk chunkIn) {
|
||||
final SoftReference<Chunk> ref = new SoftReference<>(chunkIn);
|
||||
this.executor.execute(() -> {
|
||||
// TODO: Prioritize packing recent chunks and/or ones that the path goes through,
|
||||
// and prune the oldest chunks per chunkPackerQueueMaxSize
|
||||
final Chunk chunk = ref.get();
|
||||
if (chunk != null) {
|
||||
long ptr = NetherPathfinder.getOrCreateChunk(this.context, chunk.x, chunk.z);
|
||||
writeChunkData(chunk, ptr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void queueBlockUpdate(BlockChangeEvent event) {
|
||||
this.executor.execute(() -> {
|
||||
ChunkPos chunkPos = event.getChunkPos();
|
||||
long ptr = NetherPathfinder.getChunkPointer(this.context, chunkPos.x, chunkPos.z);
|
||||
if (ptr == 0) return; // this shouldn't ever happen
|
||||
event.getBlocks().forEach(pair -> {
|
||||
BlockPos pos = pair.first();
|
||||
if (pos.getY() >= 128) return;
|
||||
boolean isSolid = pair.second() != AIR_BLOCK_STATE;
|
||||
Octree.setBlock(ptr, pos.getX() & 15, pos.getY(), pos.getZ() & 15, isSolid);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<PathSegment> pathFindAsync(final BlockPos src, final BlockPos dst) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
final PathSegment segment = NetherPathfinder.pathFind(
|
||||
this.context,
|
||||
src.getX(), src.getY(), src.getZ(),
|
||||
dst.getX(), dst.getY(), dst.getZ(),
|
||||
true,
|
||||
false,
|
||||
10000,
|
||||
!Baritone.settings().elytraPredictTerrain.value
|
||||
);
|
||||
if (segment == null) {
|
||||
throw new PathCalculationException("Path calculation failed");
|
||||
}
|
||||
return segment;
|
||||
}, this.executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a raytrace from the given start position to the given end position, returning {@code true} if there is
|
||||
* visibility between the two points.
|
||||
*
|
||||
* @param startX The start X coordinate
|
||||
* @param startY The start Y coordinate
|
||||
* @param startZ The start Z coordinate
|
||||
* @param endX The end X coordinate
|
||||
* @param endY The end Y coordinate
|
||||
* @param endZ The end Z coordinate
|
||||
* @return {@code true} if there is visibility between the points
|
||||
*/
|
||||
public boolean raytrace(final double startX, final double startY, final double startZ,
|
||||
final double endX, final double endY, final double endZ) {
|
||||
return NetherPathfinder.isVisible(this.context, NetherPathfinder.CACHE_MISS_SOLID, startX, startY, startZ, endX, endY, endZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a raytrace from the given start position to the given end position, returning {@code true} if there is
|
||||
* visibility between the two points.
|
||||
*
|
||||
* @param start The starting point
|
||||
* @param end The ending point
|
||||
* @return {@code true} if there is visibility between the points
|
||||
*/
|
||||
public boolean raytrace(final Vec3d start, final Vec3d end) {
|
||||
return NetherPathfinder.isVisible(this.context, NetherPathfinder.CACHE_MISS_SOLID, start.x, start.y, start.z, end.x, end.y, end.z);
|
||||
}
|
||||
|
||||
public boolean raytrace(final int count, final double[] src, final double[] dst, final int visibility) {
|
||||
switch (visibility) {
|
||||
case Visibility.ALL:
|
||||
return NetherPathfinder.isVisibleMulti(this.context, NetherPathfinder.CACHE_MISS_SOLID, count, src, dst, false) == -1;
|
||||
case Visibility.NONE:
|
||||
return NetherPathfinder.isVisibleMulti(this.context, NetherPathfinder.CACHE_MISS_SOLID, count, src, dst, true) == -1;
|
||||
case Visibility.ANY:
|
||||
return NetherPathfinder.isVisibleMulti(this.context, NetherPathfinder.CACHE_MISS_SOLID, count, src, dst, true) != -1;
|
||||
default:
|
||||
throw new IllegalArgumentException("lol");
|
||||
}
|
||||
}
|
||||
|
||||
public void raytrace(final int count, final double[] src, final double[] dst, final boolean[] hitsOut, final double[] hitPosOut) {
|
||||
NetherPathfinder.raytrace(this.context, NetherPathfinder.CACHE_MISS_SOLID, count, src, dst, hitsOut, hitPosOut);
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
NetherPathfinder.cancel(this.context);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
this.cancel();
|
||||
// Ignore anything that was queued up, just shutdown the executor
|
||||
this.executor.shutdownNow();
|
||||
|
||||
try {
|
||||
while (!this.executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) {}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
NetherPathfinder.freeContext(this.context);
|
||||
}
|
||||
|
||||
public long getSeed() {
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
private static void writeChunkData(Chunk chunk, long ptr) {
|
||||
try {
|
||||
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||
for (int y0 = 0; y0 < 8; y0++) {
|
||||
final ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||
if (extendedblockstorage == null) {
|
||||
continue;
|
||||
}
|
||||
final BlockStateContainer bsc = extendedblockstorage.getData();
|
||||
final int airId = ((IBlockStateContainer) bsc).getPalette().idFor(AIR_BLOCK_STATE);
|
||||
// pasted from FasterWorldScanner
|
||||
final BitArray array = ((IBlockStateContainer) bsc).getStorage();
|
||||
if (array == null) continue;
|
||||
final long[] longArray = array.getBackingLongArray();
|
||||
final int arraySize = array.size();
|
||||
final int bitsPerEntry = ((IBitArray) array).getBitsPerEntry();
|
||||
final long maxEntryValue = ((IBitArray) array).getMaxEntryValue();
|
||||
|
||||
final int yReal = y0 << 4;
|
||||
for (int idx = 0, kl = bitsPerEntry - 1; idx < arraySize; idx++, kl += bitsPerEntry) {
|
||||
final int i = idx * bitsPerEntry;
|
||||
final int j = i >> 6;
|
||||
final int l = i & 63;
|
||||
final int k = kl >> 6;
|
||||
final long jl = longArray[j] >>> l;
|
||||
|
||||
final int id;
|
||||
if (j == k) {
|
||||
id = (int) (jl & maxEntryValue);
|
||||
} else {
|
||||
id = (int) ((jl | longArray[k] << (64 - l)) & maxEntryValue);
|
||||
}
|
||||
int x = (idx & 15);
|
||||
int y = yReal + (idx >> 8);
|
||||
int z = ((idx >> 4) & 15);
|
||||
Octree.setBlock(ptr, x, y, z, id != airId);
|
||||
}
|
||||
}
|
||||
Octree.setIsFromJava(ptr);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Visibility {
|
||||
|
||||
public static final int ALL = 0;
|
||||
public static final int NONE = 1;
|
||||
public static final int ANY = 2;
|
||||
|
||||
private Visibility() {}
|
||||
}
|
||||
|
||||
public static boolean isSupported() {
|
||||
return NetherPathfinder.isThisSystemSupported();
|
||||
}
|
||||
}
|
||||
92
src/main/java/baritone/process/elytra/NullElytraProcess.java
Normal file
92
src/main/java/baritone/process/elytra/NullElytraProcess.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.process.elytra;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.process.IElytraProcess;
|
||||
import baritone.api.process.PathingCommand;
|
||||
import baritone.utils.BaritoneProcessHelper;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class NullElytraProcess extends BaritoneProcessHelper implements IElytraProcess {
|
||||
|
||||
public NullElytraProcess(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void repackChunks() {
|
||||
throw new UnsupportedOperationException("Called repackChunks() on NullElytraBehavior");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos currentDestination() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pathTo(BlockPos destination) {
|
||||
throw new UnsupportedOperationException("Called pathTo() on NullElytraBehavior");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pathTo(Goal destination) {
|
||||
throw new UnsupportedOperationException("Called pathTo() on NullElytraBehavior");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetState() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||
throw new UnsupportedOperationException("Called onTick on NullElytraProcess");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLostControl() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String displayName0() {
|
||||
return "NullElytraProcess";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoaded() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSafeToCancel() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -15,15 +15,14 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.utils.accessor;
|
||||
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
package baritone.process.elytra;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/8/2020
|
||||
*/
|
||||
public interface INetHandlerPlayClient {
|
||||
public final class PathCalculationException extends RuntimeException {
|
||||
|
||||
void setWorld(WorldClient world);
|
||||
public PathCalculationException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
83
src/main/java/baritone/process/elytra/UnpackedSegment.java
Normal file
83
src/main/java/baritone/process/elytra/UnpackedSegment.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.process.elytra;
|
||||
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import dev.babbaj.pathfinder.PathSegment;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public final class UnpackedSegment {
|
||||
|
||||
private final Stream<BetterBlockPos> path;
|
||||
private final boolean finished;
|
||||
|
||||
public UnpackedSegment(Stream<BetterBlockPos> path, boolean finished) {
|
||||
this.path = path;
|
||||
this.finished = finished;
|
||||
}
|
||||
|
||||
public UnpackedSegment append(Stream<BetterBlockPos> other, boolean otherFinished) {
|
||||
// The new segment is only finished if the one getting added on is
|
||||
return new UnpackedSegment(Stream.concat(this.path, other), otherFinished);
|
||||
}
|
||||
|
||||
public UnpackedSegment prepend(Stream<BetterBlockPos> other) {
|
||||
return new UnpackedSegment(Stream.concat(other, this.path), this.finished);
|
||||
}
|
||||
|
||||
public List<BetterBlockPos> collect() {
|
||||
final List<BetterBlockPos> path = this.path.collect(Collectors.toList());
|
||||
|
||||
// Remove backtracks
|
||||
final Map<BetterBlockPos, Integer> positionFirstSeen = new HashMap<>();
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
BetterBlockPos pos = path.get(i);
|
||||
if (positionFirstSeen.containsKey(pos)) {
|
||||
int j = positionFirstSeen.get(pos);
|
||||
while (i > j) {
|
||||
path.remove(i);
|
||||
i--;
|
||||
}
|
||||
} else {
|
||||
positionFirstSeen.put(pos, i);
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return this.finished;
|
||||
}
|
||||
|
||||
public static UnpackedSegment from(final PathSegment segment) {
|
||||
return new UnpackedSegment(
|
||||
Arrays.stream(segment.packed).mapToObj(BetterBlockPos::deserializeFromLong),
|
||||
segment.finished
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -15,25 +15,23 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.bot.impl;
|
||||
|
||||
import net.minecraft.client.audio.ISound;
|
||||
import net.minecraft.client.audio.SoundHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
package baritone.utils;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/7/2020
|
||||
*/
|
||||
public final class BotSoundHandler extends SoundHandler {
|
||||
public final class BaritoneMath {
|
||||
|
||||
public static final BotSoundHandler INSTANCE = new BotSoundHandler();
|
||||
private static final double FLOOR_DOUBLE_D = 1_073_741_824.0;
|
||||
private static final int FLOOR_DOUBLE_I = 1_073_741_824;
|
||||
|
||||
private BotSoundHandler() {
|
||||
super(null, null);
|
||||
private BaritoneMath() {}
|
||||
|
||||
public static int fastFloor(final double v) {
|
||||
return (int) (v + FLOOR_DOUBLE_D) - FLOOR_DOUBLE_I;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(@Nonnull ISound sound) {}
|
||||
public static int fastCeil(final double v) {
|
||||
return FLOOR_DOUBLE_I - (int) (FLOOR_DOUBLE_D - v);
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@@ -57,6 +58,7 @@ public interface IRenderer {
|
||||
GlStateManager.glLineWidth(lineWidth);
|
||||
GlStateManager.disableTexture2D();
|
||||
GlStateManager.depthMask(false);
|
||||
GlStateManager.disableLighting();
|
||||
|
||||
if (ignoreDepth) {
|
||||
GlStateManager.disableDepth();
|
||||
@@ -77,6 +79,7 @@ public interface IRenderer {
|
||||
GlStateManager.depthMask(true);
|
||||
GlStateManager.enableTexture2D();
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.enableLighting();
|
||||
}
|
||||
|
||||
static void emitAABB(AxisAlignedBB aabb) {
|
||||
@@ -120,4 +123,16 @@ public interface IRenderer {
|
||||
emitAABB(aabb);
|
||||
tessellator.draw();
|
||||
}
|
||||
|
||||
static void emitLine(Vec3d start, Vec3d end) {
|
||||
emitLine(start.x, start.y, start.z, end.x, end.y, end.z);
|
||||
}
|
||||
|
||||
static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) {
|
||||
double vpX = renderManager.viewerPosX;
|
||||
double vpY = renderManager.viewerPosY;
|
||||
double vpZ = renderManager.viewerPosZ;
|
||||
buffer.pos(x1 - vpX, y1 - vpY, z1 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x2 - vpX, y2 - vpY, z2 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri
|
||||
}
|
||||
|
||||
private boolean inControl() {
|
||||
for (Input input : new Input[]{Input.MOVE_FORWARD, Input.MOVE_BACK, Input.MOVE_LEFT, Input.MOVE_RIGHT, Input.SNEAK}) {
|
||||
for (Input input : new Input[]{Input.MOVE_FORWARD, Input.MOVE_BACK, Input.MOVE_LEFT, Input.MOVE_RIGHT, Input.SNEAK, Input.JUMP}) {
|
||||
if (isInputForcedDown(input)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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.utils;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Hacky util to allocate objects without needing to invoke their constructor.
|
||||
*
|
||||
* @author Brady
|
||||
* @since 3/3/2020
|
||||
*/
|
||||
public final class ObjectAllocator {
|
||||
|
||||
private static final Unsafe theUnsafe;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("sun.misc.Unsafe");
|
||||
Field field = clazz.getDeclaredField("theUnsafe");
|
||||
field.setAccessible(true);
|
||||
theUnsafe = (Unsafe) field.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ObjectAllocator() {}
|
||||
|
||||
public static <T> T allocate(Class<T> clazz) {
|
||||
try {
|
||||
// noinspection unchecked
|
||||
return (T) theUnsafe.allocateInstance(clazz);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ package baritone.utils;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.event.events.RenderEvent;
|
||||
import baritone.api.pathing.calc.IPath;
|
||||
import baritone.api.pathing.goals.*;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
@@ -41,8 +40,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/9/2018
|
||||
@@ -56,7 +53,7 @@ public final class PathRenderer implements IRenderer {
|
||||
if (ctx.world() == null) {
|
||||
return;
|
||||
}
|
||||
if (ctx.minecraft().currentScreen instanceof GuiClick && behavior.baritone == BaritoneAPI.getProvider().getPrimaryBaritone()) {
|
||||
if (ctx.minecraft().currentScreen instanceof GuiClick) {
|
||||
((GuiClick) ctx.minecraft().currentScreen).onRender();
|
||||
}
|
||||
|
||||
@@ -92,33 +89,36 @@ public final class PathRenderer implements IRenderer {
|
||||
// Render the current path, if there is one
|
||||
if (current != null && current.getPath() != null) {
|
||||
int renderBegin = Math.max(current.getPosition() - 3, 0);
|
||||
drawPath(current.getPath(), renderBegin, settings.colorCurrentPath.value, settings.fadePath.value, 10, 20);
|
||||
drawPath(current.getPath().positions(), renderBegin, settings.colorCurrentPath.value, settings.fadePath.value, 10, 20);
|
||||
}
|
||||
|
||||
if (next != null && next.getPath() != null) {
|
||||
drawPath(next.getPath(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20);
|
||||
drawPath(next.getPath().positions(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20);
|
||||
}
|
||||
|
||||
// If there is a path calculation currently running, render the path calculation process
|
||||
behavior.getInProgress().ifPresent(currentlyRunning -> {
|
||||
currentlyRunning.bestPathSoFar().ifPresent(p -> {
|
||||
drawPath(p, 0, settings.colorBestPathSoFar.value, settings.fadePath.value, 10, 20);
|
||||
drawPath(p.positions(), 0, settings.colorBestPathSoFar.value, settings.fadePath.value, 10, 20);
|
||||
});
|
||||
|
||||
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
|
||||
drawPath(mr, 0, settings.colorMostRecentConsidered.value, settings.fadePath.value, 10, 20);
|
||||
drawPath(mr.positions(), 0, settings.colorMostRecentConsidered.value, settings.fadePath.value, 10, 20);
|
||||
drawManySelectionBoxes(ctx.player(), Collections.singletonList(mr.getDest()), settings.colorMostRecentConsidered.value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static void drawPath(IPath path, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) {
|
||||
public static void drawPath(List<BetterBlockPos> positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) {
|
||||
drawPath(positions, startIndex, color, fadeOut, fadeStart0, fadeEnd0, 0.5D);
|
||||
}
|
||||
|
||||
public static void drawPath(List<BetterBlockPos> positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0, double offset) {
|
||||
IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value);
|
||||
|
||||
int fadeStart = fadeStart0 + startIndex;
|
||||
int fadeEnd = fadeEnd0 + startIndex;
|
||||
|
||||
List<BetterBlockPos> positions = path.positions();
|
||||
for (int i = startIndex, next; i < positions.size() - 1; i = next) {
|
||||
BetterBlockPos start = positions.get(i);
|
||||
BetterBlockPos end = positions.get(next = i + 1);
|
||||
@@ -149,30 +149,31 @@ public final class PathRenderer implements IRenderer {
|
||||
IRenderer.glColor(color, alpha);
|
||||
}
|
||||
|
||||
emitLine(start.x, start.y, start.z, end.x, end.y, end.z);
|
||||
emitPathLine(start.x, start.y, start.z, end.x, end.y, end.z, offset);
|
||||
}
|
||||
|
||||
IRenderer.endLines(settings.renderPathIgnoreDepth.value);
|
||||
}
|
||||
|
||||
private static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) {
|
||||
private static void emitPathLine(double x1, double y1, double z1, double x2, double y2, double z2, double offset) {
|
||||
final double extraOffset = offset + 0.03D;
|
||||
double vpX = renderManager.viewerPosX;
|
||||
double vpY = renderManager.viewerPosY;
|
||||
double vpZ = renderManager.viewerPosZ;
|
||||
boolean renderPathAsFrickinThingy = !settings.renderPathAsLine.value;
|
||||
|
||||
buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x1 + offset - vpX, y1 + offset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x2 + offset - vpX, y2 + offset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
|
||||
if (renderPathAsFrickinThingy) {
|
||||
buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x2 + offset - vpX, y2 + offset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x2 + offset - vpX, y2 + extraOffset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
|
||||
buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x2 + offset - vpX, y2 + extraOffset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x1 + offset - vpX, y1 + extraOffset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
|
||||
buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x1 + offset - vpX, y1 + extraOffset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
buffer.pos(x1 + offset - vpX, y1 + offset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +199,7 @@ public final class PathRenderer implements IRenderer {
|
||||
IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value);
|
||||
}
|
||||
|
||||
private static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) {
|
||||
public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) {
|
||||
drawGoal(player, goal, partialTicks, color, true);
|
||||
}
|
||||
|
||||
@@ -239,8 +240,6 @@ public final class PathRenderer implements IRenderer {
|
||||
GoalXZ goalPos = (GoalXZ) goal;
|
||||
|
||||
if (settings.renderGoalXZBeacon.value) {
|
||||
glPushAttrib(GL_LIGHTING_BIT);
|
||||
|
||||
textureManager.bindTexture(TileEntityBeaconRenderer.TEXTURE_BEACON_BEAM);
|
||||
|
||||
if (settings.renderGoalIgnoreDepth.value) {
|
||||
@@ -262,8 +261,6 @@ public final class PathRenderer implements IRenderer {
|
||||
if (settings.renderGoalIgnoreDepth.value) {
|
||||
GlStateManager.enableDepth();
|
||||
}
|
||||
|
||||
glPopAttrib();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ import baritone.api.process.PathingCommand;
|
||||
import baritone.api.process.PathingCommandType;
|
||||
import baritone.behavior.PathingBehavior;
|
||||
import baritone.pathing.path.PathExecutor;
|
||||
import baritone.process.CustomGoalProcess;
|
||||
import baritone.process.ElytraProcess;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.*;
|
||||
@@ -99,6 +101,8 @@ public class PathingControlManager implements IPathingControlManager {
|
||||
// get rid of the in progress stuff from the last process
|
||||
}
|
||||
switch (command.commandType) {
|
||||
case SET_GOAL_AND_PAUSE:
|
||||
p.secretInternalSetGoalAndPath(command);
|
||||
case REQUEST_PAUSE:
|
||||
p.requestPause();
|
||||
break;
|
||||
@@ -107,10 +111,6 @@ public class PathingControlManager implements IPathingControlManager {
|
||||
p.cancelSegmentIfSafe();
|
||||
break;
|
||||
case FORCE_REVALIDATE_GOAL_AND_PATH:
|
||||
if (!p.isPathing() && !p.getInProgress().isPresent()) {
|
||||
p.secretInternalSetGoalAndPath(command);
|
||||
}
|
||||
break;
|
||||
case REVALIDATE_GOAL_AND_PATH:
|
||||
if (!p.isPathing() && !p.getInProgress().isPresent()) {
|
||||
p.secretInternalSetGoalAndPath(command);
|
||||
@@ -119,7 +119,7 @@ public class PathingControlManager implements IPathingControlManager {
|
||||
case SET_GOAL_AND_PATH:
|
||||
// now this i can do
|
||||
if (command.goal != null) {
|
||||
baritone.getPathingBehavior().secretInternalSetGoalAndPath(command);
|
||||
p.secretInternalSetGoalAndPath(command);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -17,15 +17,14 @@
|
||||
|
||||
package baritone.utils;
|
||||
|
||||
import baritone.api.utils.IInputOverrideHandler;
|
||||
import baritone.api.utils.input.Input;
|
||||
import net.minecraft.util.MovementInput;
|
||||
|
||||
public class PlayerMovementInput extends MovementInput {
|
||||
|
||||
private final IInputOverrideHandler handler;
|
||||
private final InputOverrideHandler handler;
|
||||
|
||||
public PlayerMovementInput(IInputOverrideHandler handler) {
|
||||
PlayerMovementInput(InputOverrideHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +17,9 @@
|
||||
|
||||
package baritone.utils.accessor;
|
||||
|
||||
import java.io.File;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
*/
|
||||
public interface IMinecraft {
|
||||
public interface IEntityFireworkRocket {
|
||||
|
||||
void setGameDir(File gameDir);
|
||||
EntityLivingBase getBoostedEntity();
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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.utils.accessor;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EnumPlayerModelParts;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/6/2020
|
||||
*/
|
||||
public interface IGameSettings {
|
||||
|
||||
void setSetModelParts(Set<EnumPlayerModelParts> setModelParts);
|
||||
|
||||
void setMc(Minecraft mc);
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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.utils.accessor;
|
||||
|
||||
import net.minecraft.client.multiplayer.ThreadLanServerPing;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/4/2020
|
||||
*/
|
||||
public interface IIntegratedServer {
|
||||
|
||||
ThreadLanServerPing getLanServerPing();
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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.utils.accessor;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/4/2020
|
||||
*/
|
||||
public interface IThreadLanServerPing {
|
||||
|
||||
String getMotd();
|
||||
|
||||
String getAddress();
|
||||
}
|
||||
@@ -72,11 +72,6 @@ public final class BaritonePlayerController implements IPlayerController {
|
||||
return mc.playerController.windowClick(windowId, slotId, mouseButton, type, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGameType(GameType type) {
|
||||
mc.playerController.setGameType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameType getGameType() {
|
||||
return mc.playerController.getCurrentGameType();
|
||||
|
||||
Reference in New Issue
Block a user