Compare commits
348 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35cb592d09 | ||
|
|
863db53b24 | ||
|
|
fa3dab0adb | ||
|
|
2afdaa1ac9 | ||
|
|
d4947c3c47 | ||
|
|
35efd9293b | ||
|
|
d89aa887fb | ||
|
|
801727dca6 | ||
|
|
44963fa4c7 | ||
|
|
a2534a8227 | ||
|
|
4f9268e571 | ||
|
|
e343756e44 | ||
|
|
9480f0d2bc | ||
|
|
fb2a808f5c | ||
|
|
24c0ec905e | ||
|
|
bca6a580e3 | ||
|
|
1d0413f159 | ||
|
|
72d8863862 | ||
|
|
c15dac3582 | ||
|
|
efe06264bd | ||
|
|
d5e155d77f | ||
|
|
bf68afdda3 | ||
|
|
a61b82748c | ||
|
|
245b2483ab | ||
|
|
87dbf1dbba | ||
|
|
101f7cb7e2 | ||
|
|
c795913259 | ||
|
|
64eabf71f2 | ||
|
|
2760354943 | ||
|
|
28c2586452 | ||
|
|
21d8c11cfe | ||
|
|
862746038d | ||
|
|
2bd81b08c2 | ||
|
|
16aee33bdf | ||
|
|
f4161ed61c | ||
|
|
bfa0861065 | ||
|
|
86d1512e5b | ||
|
|
5c83ee2648 | ||
|
|
7ba987e7f7 | ||
|
|
b22e93d6d0 | ||
|
|
70b74d39fc | ||
|
|
0236cb35d9 | ||
|
|
b0066a93ca | ||
|
|
e25bf9f077 | ||
|
|
147df1ffb2 | ||
|
|
4c96759ed5 | ||
|
|
8e2df3a030 | ||
|
|
58a5720b6b | ||
|
|
eedf993d7a | ||
|
|
d058cbf501 | ||
|
|
d2413e1677 | ||
|
|
3cb1984892 | ||
|
|
17207d44e6 | ||
|
|
36cfcbbbe3 | ||
|
|
1a6c0cd4d9 | ||
|
|
5a97c512f7 | ||
|
|
57a3330200 | ||
|
|
07ce0a47f7 | ||
|
|
b9f7a05e2a | ||
|
|
7f73b4554a | ||
|
|
f2e02794b8 | ||
|
|
0a2e45b64b | ||
|
|
a017e14a48 | ||
|
|
5ef03ba1d5 | ||
|
|
6a402b4a2b | ||
|
|
5daaaf5282 | ||
|
|
6f7729e34e | ||
|
|
043d6ffd20 | ||
|
|
a8404a7286 | ||
|
|
58d9134286 | ||
|
|
f25786635b | ||
|
|
6d1130d2c3 | ||
|
|
d9effc4a29 | ||
|
|
cf2765e017 | ||
|
|
06dd07dbc6 | ||
|
|
14daf2ce85 | ||
|
|
f9a3a3b78b | ||
|
|
2ba0e6ada6 | ||
|
|
943b75455b | ||
|
|
2b56d68f7d | ||
|
|
93217a3ae3 | ||
|
|
ba5c8ffaa6 | ||
|
|
9c5274dde4 | ||
|
|
002c678b4a | ||
|
|
038533c33f | ||
|
|
50d4b5b4ed | ||
|
|
7632d667c9 | ||
|
|
5aa78cd478 | ||
|
|
84cd4b1acb | ||
|
|
b705279153 | ||
|
|
d854750ee8 | ||
|
|
653861107d | ||
|
|
4502adda28 | ||
|
|
a98c5d7d99 | ||
|
|
c81a00268a | ||
|
|
dd47e20070 | ||
|
|
f05613147e | ||
|
|
6ed8d617cd | ||
|
|
b228f4c6fb | ||
|
|
70f8d1d4ae | ||
|
|
0d7131413a | ||
|
|
b5a4e65fbf | ||
|
|
7c51106d27 | ||
|
|
1e9786d5b9 | ||
|
|
4b8c85f8a6 | ||
|
|
aed8dae175 | ||
|
|
8db26af36c | ||
|
|
cfa874982c | ||
|
|
2a674cb869 | ||
|
|
fb971301a4 | ||
|
|
3bb16de67e | ||
|
|
033da7e737 | ||
|
|
14650f93c5 | ||
|
|
e5184efdaa | ||
|
|
d95a72f2cc | ||
|
|
16e3fd9305 | ||
|
|
4fb6c71174 | ||
|
|
12bbd57a24 | ||
|
|
689dc74330 | ||
|
|
6caae889b7 | ||
|
|
ce0e8b4cd1 | ||
|
|
737c632227 | ||
|
|
04e87c9810 | ||
|
|
57c0613843 | ||
|
|
f5d0143b09 | ||
|
|
237f1846d3 | ||
|
|
f6dee1ecb7 | ||
|
|
f808fc9802 | ||
|
|
8385bc35ed | ||
|
|
80d6d7fd58 | ||
|
|
b56cdcda52 | ||
|
|
ea81cd76ca | ||
|
|
c3a3670785 | ||
|
|
e4045e1343 | ||
|
|
5a52cea415 | ||
|
|
933b295c40 | ||
|
|
ce6ec00a89 | ||
|
|
b53f3925a4 | ||
|
|
e93fd596ff | ||
|
|
57b60c734b | ||
|
|
c74ccaafbf | ||
|
|
f6891feb64 | ||
|
|
2675852dbe | ||
|
|
0302c6f14b | ||
|
|
a0dd43244c | ||
|
|
3ccb0c74c6 | ||
|
|
f9270a7ed0 | ||
|
|
d79d56c2f9 | ||
|
|
a8f09a7fe9 | ||
|
|
94bf8d4bbd | ||
|
|
5e2f40a322 | ||
|
|
17161fd576 | ||
|
|
d3db551cc9 | ||
|
|
72058c792a | ||
|
|
ef5e3ab06e | ||
|
|
71e7f0a04c | ||
|
|
bae34e5b80 | ||
|
|
1ab3e61984 | ||
|
|
e81b6d4d96 | ||
|
|
83f14b10bb | ||
|
|
7fecd1a5dd | ||
|
|
0ce4107d56 | ||
|
|
66769365d0 | ||
|
|
e3cb164723 | ||
|
|
903b1b16a4 | ||
|
|
e81d0a0b1b | ||
|
|
51243f0981 | ||
|
|
fad5a6deac | ||
|
|
355443e440 | ||
|
|
45e4239b26 | ||
|
|
a83074e773 | ||
|
|
f854d886d1 | ||
|
|
73d4e9bbb9 | ||
|
|
232644feb0 | ||
|
|
1c80950a70 | ||
|
|
0bd46e88a5 | ||
|
|
b054e9dbe8 | ||
|
|
3ddf6b2335 | ||
|
|
1a1686b7c3 | ||
|
|
dd08b2c825 | ||
|
|
a2a60e9847 | ||
|
|
13505a052f | ||
|
|
f2dcdda9b3 | ||
|
|
dc6389c46f | ||
|
|
7dc89b0190 | ||
|
|
5b395ce3da | ||
|
|
40da7b3734 | ||
|
|
842e50adb9 | ||
|
|
96da078219 | ||
|
|
4a1951b027 | ||
|
|
83348e6b3c | ||
|
|
a1778f401f | ||
|
|
9c93d3a474 | ||
|
|
cbc8a6d45b | ||
|
|
382c7e7888 | ||
|
|
ae200a56b0 | ||
|
|
c50af5acfd | ||
|
|
527691a2ec | ||
|
|
a182c22d36 | ||
|
|
aac0d623fa | ||
|
|
604ef2bb64 | ||
|
|
6ca7f47bf9 | ||
|
|
a1b71219cb | ||
|
|
d59c7cb7a8 | ||
|
|
d121ca182f | ||
|
|
2aee91be10 | ||
|
|
99da815f49 | ||
|
|
ebd3ce42d0 | ||
|
|
fdee1b9453 | ||
|
|
472e89239c | ||
|
|
5692e79e02 | ||
|
|
52246e41c8 | ||
|
|
2da3222115 | ||
|
|
4d0bfce712 | ||
|
|
cb153e039b | ||
|
|
8aa5a6756a | ||
|
|
23286dd8b8 | ||
|
|
30408384c6 | ||
|
|
e11e3dfd86 | ||
|
|
2c39cd06ed | ||
|
|
75a224cef1 | ||
|
|
0373f1875f | ||
|
|
fffd016008 | ||
|
|
f286c400a3 | ||
|
|
c0e0f8dc2a | ||
|
|
ffb044ffc6 | ||
|
|
1c4f029bf4 | ||
|
|
6812d2ba7d | ||
|
|
c0b5d60715 | ||
|
|
c814874cb6 | ||
|
|
cd3aef47a5 | ||
|
|
338fdb509a | ||
|
|
660efe5e16 | ||
|
|
58a2965fea | ||
|
|
c614d7ec6a | ||
|
|
e017238aca | ||
|
|
c37a5ba956 | ||
|
|
da5969c2fd | ||
|
|
990107a1fa | ||
|
|
42eb86b624 | ||
|
|
b65a199e54 | ||
|
|
88e3bcdf63 | ||
|
|
0fbfa32e6b | ||
|
|
20405716bc | ||
|
|
8da7406e8f | ||
|
|
97fd3df8f7 | ||
|
|
b9b33b5351 | ||
|
|
19ecb1bbb3 | ||
|
|
f6043f4ac6 | ||
|
|
ed1941abdb | ||
|
|
24d24728dc | ||
|
|
77db4cd19f | ||
|
|
adbb03e5cb | ||
|
|
f0226f1ea7 | ||
|
|
be5df2677b | ||
|
|
3d4a856bb2 | ||
|
|
1b1233d26a | ||
|
|
c4b0e0a810 | ||
|
|
1dee8ef355 | ||
|
|
8cee173f92 | ||
|
|
19e0e6d962 | ||
|
|
ef8fd70475 | ||
|
|
6df05f4b7f | ||
|
|
4e1491a0cc | ||
|
|
55091154c4 | ||
|
|
a0b1cb2993 | ||
|
|
7617081637 | ||
|
|
96e7f37799 | ||
|
|
a0bf22de86 | ||
|
|
9a1aecc002 | ||
|
|
ad941fcbb2 | ||
|
|
e5ca30dc26 | ||
|
|
a23eadf5cf | ||
|
|
82417f4f85 | ||
|
|
af788133c2 | ||
|
|
a6dc156a79 | ||
|
|
25bebdc172 | ||
|
|
b55d96169f | ||
|
|
1a809fa7a3 | ||
|
|
313a5fddbe | ||
|
|
732d806820 | ||
|
|
11ed8a2f21 | ||
|
|
3aa8f51015 | ||
|
|
85b038dada | ||
|
|
dd25527a62 | ||
|
|
ac372bc6fc | ||
|
|
63ce4fe0bd | ||
|
|
398169f68e | ||
|
|
46a24af373 | ||
|
|
0cd9bb658f | ||
|
|
b0678fd259 | ||
|
|
9cb4a1779e | ||
|
|
3cb4700b16 | ||
|
|
94921fe03f | ||
|
|
0202865837 | ||
|
|
b9b911eb3b | ||
|
|
54fb2c5f81 | ||
|
|
2df97ff986 | ||
|
|
4374619ba2 | ||
|
|
6b6ebd6968 | ||
|
|
b41fdc2bbd | ||
|
|
3cac37d1a5 | ||
|
|
2f7259714a | ||
|
|
c1076461e2 | ||
|
|
6fdf845349 | ||
|
|
c80b855dab | ||
|
|
83fc11e75b | ||
|
|
9654892e54 | ||
|
|
b46fad1442 | ||
|
|
ff652dbe40 | ||
|
|
897483884a | ||
|
|
ba68990ef8 | ||
|
|
de29a6532f | ||
|
|
9045791e7f | ||
|
|
ab2fa0ba88 | ||
|
|
56b67cbc47 | ||
|
|
b6a1608e73 | ||
|
|
6277c20e4c | ||
|
|
2fc282477d | ||
|
|
917f393f7a | ||
|
|
045504ecf7 | ||
|
|
7efc0ae8ca | ||
|
|
3958dce341 | ||
|
|
d1a9012deb | ||
|
|
dbde993a76 | ||
|
|
96c66d2809 | ||
|
|
df1633b2a1 | ||
|
|
24f18f0ac2 | ||
|
|
416fea2aa5 | ||
|
|
93286a646f | ||
|
|
8fba36c05e | ||
|
|
b443be1795 | ||
|
|
4892192c6c | ||
|
|
6b7a8e2bd3 | ||
|
|
c5f5445f4b | ||
|
|
8a65f43a0b | ||
|
|
76e4a1a649 | ||
|
|
5167c0c886 | ||
|
|
9d3d8f6c82 | ||
|
|
7e4a1169af | ||
|
|
773ad89951 | ||
|
|
c2adcdb051 | ||
|
|
b75bc6d03d | ||
|
|
e3b80f11ad | ||
|
|
f33a2ef11b | ||
|
|
130b21f738 | ||
|
|
ee954d6a4e | ||
|
|
54215bdb18 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@
|
||||
|
||||
run/
|
||||
autotest/
|
||||
dist/
|
||||
|
||||
# Gradle
|
||||
build/
|
||||
|
||||
@@ -9,7 +9,7 @@ install:
|
||||
- travis_retry docker build -t cabaletta/baritone .
|
||||
|
||||
script:
|
||||
- docker run --name baritone cabaletta/baritone /bin/sh -c "set -e; /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 128x128x24 -ac +extension GLX +render; sh scripts/build.sh; DISPLAY=:99 BARITONE_AUTO_TEST=true ./gradlew runClient"
|
||||
- docker run --name baritone cabaletta/baritone /bin/sh -c "set -e; /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 128x128x24 -ac +extension GLX +render; DISPLAY=:99 BARITONE_AUTO_TEST=true ./gradlew runClient"
|
||||
- docker cp baritone:/code/dist dist
|
||||
- ls dist
|
||||
- cat dist/checksums.txt
|
||||
|
||||
10
Dockerfile
10
Dockerfile
@@ -13,14 +13,12 @@ RUN apt install --target-release jessie-backports \
|
||||
|
||||
RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
|
||||
|
||||
RUN apt install -qq --force-yes unzip wget
|
||||
|
||||
COPY . /code
|
||||
|
||||
# this .deb is specially patched to support lwjgl
|
||||
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
|
||||
RUN dpkg -i /code/scripts/xvfb_1.16.4-1_amd64.deb
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
# this .deb is specially patched to support lwjgl
|
||||
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
|
||||
RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb
|
||||
|
||||
RUN ./gradlew build
|
||||
92
IMPACT.md
92
IMPACT.md
@@ -1,91 +1 @@
|
||||
# Integration between Baritone and Impact
|
||||
Impact 4.4 will have Baritone included on release, however, if you're impatient, you can install Baritone into Impact 4.3 right now!
|
||||
|
||||
## An Introduction
|
||||
There are some basic steps to getting Baritone setup with Impact.
|
||||
- Acquiring a build of Baritone
|
||||
- Placing Baritone in the libraries directory
|
||||
- Modifying the Impact Profile JSON to run baritone
|
||||
- How to use Baritone
|
||||
|
||||
## Acquiring a build of Baritone
|
||||
There are 3 methods of acquiring a build of Baritone (While it is still in development)
|
||||
|
||||
### Official Release (Not always up to date)
|
||||
https://github.com/cabaletta/baritone/releases
|
||||
|
||||
For Impact 4.3, there is no Baritone integration yet, so you will want `baritone-standalone-X.Y.Z.jar`.
|
||||
|
||||
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A) and ZeroMemes (73A788379A197567). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by those two public keys of `checksums.txt`.
|
||||
|
||||
The build for `baritone-unoptimized-X.Y.Z.jar` is deterministic, and you can verify Travis did it properly by running `scripts/build.sh` yourself and comparing the shasum. The proguarded files (api and standalone) aren't yet reproducible, because proguard annoyingly includes the current timestamp into the final jar.
|
||||
|
||||
### Building Baritone yourself
|
||||
There are a few steps to this
|
||||
- Clone this repository
|
||||
- Setup the project as instructed in the README
|
||||
- Run the ``build`` gradle task. You can either do this using IntelliJ's gradle UI or through a
|
||||
command line
|
||||
- Windows: ``gradlew build``
|
||||
- Mac/Linux: ``./gradlew build``
|
||||
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
|
||||
|
||||
### Cutting Edge Release
|
||||
If you want to trust @Plutie#9079, you can download an automatically generated build of the latest commit
|
||||
from his Jenkins server, found <a href="https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/">here</a>.
|
||||
|
||||
## Placing Baritone in the libraries directory
|
||||
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>
|
||||
that contains all of the dependencies that are required from the game and some mods. This is where we will be
|
||||
putting baritone.
|
||||
- Locate the ``libraries`` folder, it should be in the Minecraft Installation Directory
|
||||
- Create 3 new subdirectories starting from ``libraries``
|
||||
- ``cabaletta``
|
||||
- ``baritone``
|
||||
- ``X.Y.Z``
|
||||
- Copy the build of Baritone that was acquired earlier, and place it into the ``X.Y.Z`` folder
|
||||
- The full path should look like ``<Minecraft>/libraries/cabaletta/baritone/X.Y.Z/baritone-X.Y.Z.jar``
|
||||
|
||||
## Modifying the Impact Profile JSON to run baritone
|
||||
The final step is "registering" the Baritone library with Impact, so that it loads on launch.
|
||||
- Ensure your Minecraft launcher is closed
|
||||
- Navigate back to the Minecraft Installation Directory
|
||||
- Find the ``versions`` directory, and open in
|
||||
- In here there should be a ``1.12.2-Impact_4.3`` folder.
|
||||
- If you don't have any Impact folder or have a version older than 4.3, you can download Impact <a href="https://impactdevelopment.github.io">here</a>.
|
||||
- Open the folder and inside there should be a file called ``1.12.2-Impact_4.3.json``
|
||||
- Open the JSON file with a text editor that supports your system's line endings
|
||||
- For example, Notepad on Windows likely will NOT work for this. You should instead use a Text Editor like
|
||||
<a href="https://notepad-plus-plus.org/">Notepad++</a> if you're on Windows. (For other systems, I'm not sure
|
||||
what would work the best so you may have to do some research.)
|
||||
- Find the ``libraries`` array in the JSON. It should look something like this.
|
||||
```
|
||||
"libraries": [
|
||||
{
|
||||
"name": "net.minecraft:launchwrapper:1.12"
|
||||
},
|
||||
{
|
||||
"name": "com.github.ImpactDevelopment:Impact:4.3-1.12.2",
|
||||
"url": "https://impactdevelopment.github.io/maven/"
|
||||
},
|
||||
{
|
||||
"name": "com.github.ImpactDeveloment:ClientAPI:3.0.2",
|
||||
"url": "https://impactdevelopment.github.io/maven/"
|
||||
},
|
||||
...
|
||||
```
|
||||
- Create a new object in the array, between the ``Impact`` and ``ClientAPI`` dependencies preferably.
|
||||
```
|
||||
{
|
||||
"name": "cabaletta:baritone:X.Y.Z"
|
||||
},
|
||||
```
|
||||
- Now find the ``"minecraftArguments": "..."`` text near the top.
|
||||
- At the very end of the quotes where it says ``--tweakClass clientapi.load.ClientTweaker"``, add on the following so it looks like:
|
||||
- ``--tweakClass clientapi.load.ClientTweaker --tweakClass baritone.launch.BaritoneTweakerOptifine"``
|
||||
- If you didn't close your launcher for this step, restart it now.
|
||||
- You can now launch Impact 4.3 as normal, and Baritone should start up
|
||||
|
||||
## How to use Baritone
|
||||
Instructions on how to use Baritone are limited, and you may have to read a little bit of code (Really nothing much
|
||||
just plain English), you can view that <a href="https://github.com/cabaletta/baritone#chat-control">here</a>.
|
||||
Impact 4.4 is out. See <a href="INSTALL.md">INSTALL.md</a>
|
||||
96
INSTALL.md
Normal file
96
INSTALL.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# Integration between Baritone and Impact
|
||||
Impact 4.4 has Baritone included.
|
||||
|
||||
These instructions apply to Impact 4.3 (and potentially other hacked clients).
|
||||
|
||||
To run Baritone on Vanilla, just follow the instructions in the README (it's `./gradlew runClient`).
|
||||
|
||||
|
||||
## An Introduction
|
||||
There are some basic steps to getting Baritone setup with Impact.
|
||||
- Acquiring a build of Baritone
|
||||
- Placing Baritone in the libraries directory
|
||||
- Modifying the Impact Profile JSON to run baritone
|
||||
- How to use Baritone
|
||||
|
||||
## Acquiring a build of Baritone
|
||||
There are two methods of acquiring a build of Baritone
|
||||
|
||||
### Official Release (Not always up to date)
|
||||
https://github.com/cabaletta/baritone/releases
|
||||
|
||||
For Impact 4.3, there is no Baritone integration yet, so you will want `baritone-standalone-X.Y.Z.jar`.
|
||||
|
||||
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A) and ZeroMemes (73A788379A197567). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by those two public keys of `checksums.txt`.
|
||||
|
||||
The build is fully deterministic and reproducible, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone . && docker run --rm cabaletta/baritone cat /code/dist/checksums.txt` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too).
|
||||
|
||||
### Building Baritone yourself
|
||||
There are a few steps to this
|
||||
- Clone this repository
|
||||
- Setup the project as instructed in the README
|
||||
- Run the ``build`` gradle task. You can either do this using IntelliJ's gradle UI or through a
|
||||
command line
|
||||
- Windows: ``gradlew build``
|
||||
- Mac/Linux: ``./gradlew build``
|
||||
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
|
||||
|
||||
## Placing Baritone in the libraries directory
|
||||
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>
|
||||
that contains all of the dependencies that are required from the game and some mods. This is where we will be
|
||||
putting baritone.
|
||||
- Locate the ``libraries`` folder, it should be in the Minecraft Installation Directory
|
||||
- Create 3 new subdirectories starting from ``libraries``
|
||||
- ``cabaletta``
|
||||
- ``baritone``
|
||||
- ``X.Y.Z``
|
||||
- Copy the build of Baritone that was acquired earlier, and place it into the ``X.Y.Z`` folder
|
||||
- The full path should look like ``<Minecraft>/libraries/cabaletta/baritone/X.Y.Z/baritone-X.Y.Z.jar``
|
||||
|
||||
## Modifying the Impact Profile JSON to run baritone
|
||||
The final step is "registering" the Baritone library with Impact, so that it loads on launch.
|
||||
- Ensure your Minecraft launcher is closed
|
||||
- Navigate back to the Minecraft Installation Directory
|
||||
- Find the ``versions`` directory, and open in
|
||||
- In here there should be a ``1.12.2-Impact_4.3`` folder.
|
||||
- If you don't have any Impact folder or have a version older than 4.3, you can download Impact <a href="https://impactdevelopment.github.io">here</a>.
|
||||
- Open the folder and inside there should be a file called ``1.12.2-Impact_4.3.json``
|
||||
- Open the JSON file with a text editor that supports your system's line endings
|
||||
- For example, Notepad on Windows likely will NOT work for this. You should instead use a Text Editor like
|
||||
<a href="https://notepad-plus-plus.org/">Notepad++</a> if you're on Windows. (For other systems, I'm not sure
|
||||
what would work the best so you may have to do some research.)
|
||||
- Find the ``libraries`` array in the JSON. It should look something like this.
|
||||
```
|
||||
"libraries": [
|
||||
{
|
||||
"name": "net.minecraft:launchwrapper:1.12"
|
||||
},
|
||||
{
|
||||
"name": "com.github.ImpactDevelopment:Impact:4.3-1.12.2",
|
||||
"url": "https://impactdevelopment.github.io/maven/"
|
||||
},
|
||||
{
|
||||
"name": "com.github.ImpactDeveloment:ClientAPI:3.0.2",
|
||||
"url": "https://impactdevelopment.github.io/maven/"
|
||||
},
|
||||
...
|
||||
```
|
||||
- Create two new objects in the array, between the ``Impact`` and ``ClientAPI`` dependencies preferably.
|
||||
```
|
||||
{
|
||||
"name": "cabaletta:baritone:X.Y.Z"
|
||||
},
|
||||
{
|
||||
"name": "com.github.ImpactDevelopment:SimpleTweaker:1.2",
|
||||
"url": "https://impactdevelopment.github.io/maven/"
|
||||
},
|
||||
```
|
||||
- Now find the ``"minecraftArguments": "..."`` text near the top.
|
||||
- At the very end of the quotes where it says ``--tweakClass clientapi.load.ClientTweaker"``, add on the following so it looks like:
|
||||
- ``--tweakClass clientapi.load.ClientTweaker --tweakClass baritone.launch.BaritoneTweakerOptifine"``
|
||||
- If you didn't close your launcher for this step, restart it now.
|
||||
- You can now launch Impact 4.3 as normal, and Baritone should start up
|
||||
|
||||
## How to use Baritone
|
||||
Instructions on how to use Baritone are limited, and you may have to read a little bit of code (Really nothing much
|
||||
just plain English), you can view that <a href="https://github.com/cabaletta/baritone#chat-control">here</a>.
|
||||
50
README.md
50
README.md
@@ -1,46 +1,57 @@
|
||||
# Baritone
|
||||
[](https://travis-ci.com/cabaletta/baritone)
|
||||
[](LICENSE)
|
||||
[](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
|
||||
[](https://github.com/cabaletta/baritone/releases)
|
||||
[](LICENSE)
|
||||
[](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade)
|
||||
[](http://hits.dwyl.com/cabaletta/baritone)
|
||||
[](https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle)
|
||||
[](https://github.com/cabaletta/baritone/issues)
|
||||
[](https://minecraft.gamepedia.com/1.12.2)
|
||||
[](https://impactdevelopment.github.io/)
|
||||
[](https://github.com/zeroeightysix/KAMI/)
|
||||
[](https://github.com/EmotionalLove/Asuna/)
|
||||
[](https://futureclient.net/)
|
||||
|
||||
Unofficial Jenkins: [](https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/)
|
||||
A Minecraft pathfinder bot.
|
||||
|
||||
A Minecraft pathfinder bot. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
||||
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
|
||||
|
||||
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
||||
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
||||
|
||||
Here are some links to help to get started:
|
||||
|
||||
- [Features](FEATURES.md)
|
||||
|
||||
- [Baritone + Impact](IMPACT.md)
|
||||
- [Installation](INSTALL.md)
|
||||
|
||||
There's also some useful information down below
|
||||
|
||||
# Setup
|
||||
|
||||
## IntelliJ's Gradle UI
|
||||
- Open the project in IntelliJ as a Gradle project
|
||||
- Run the Gradle task `setupDecompWorkspace`
|
||||
- Run the Gradle task `genIntellijRuns`
|
||||
- Refresh the Gradle project (or just restart IntelliJ)
|
||||
- Select the "Minecraft Client" launch config and run
|
||||
|
||||
## Command Line
|
||||
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
|
||||
|
||||
Running Baritone:
|
||||
|
||||
```
|
||||
$ gradlew run
|
||||
$ gradlew runClient
|
||||
```
|
||||
|
||||
Setting up for IntelliJ:
|
||||
Building Baritone:
|
||||
```
|
||||
$ gradlew setupDecompWorkspace
|
||||
$ gradlew --refresh-dependencies
|
||||
$ gradlew genIntellijRuns
|
||||
$ gradlew build
|
||||
```
|
||||
|
||||
To replace out Impact 4.4's Baritone build with a customized one, switch to the `impact4.4-compat` branch, build Baritone as above then copy `dist/baritone-api-$VERSION$.jar` into `minecraft/libraries/cabaletta/baritone-api/1.0.0/baritone-api-1.0.0.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.4/1.12.2-Impact_4.4.json`, find the line `"name": "cabaletta:baritone-api:1.0.0"`, remove the comma from the end, and entirely remove the line that's immediately after (starts with `"url"`).
|
||||
|
||||
## IntelliJ's Gradle UI
|
||||
- Open the project in IntelliJ as a Gradle project
|
||||
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
|
||||
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
|
||||
- Select the "Minecraft Client" launch config
|
||||
- In `Edit Configurations...` you may need to select `baritone_launch` for `Use classpath of module:`.
|
||||
|
||||
# Chat control
|
||||
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
|
||||
|
||||
@@ -52,13 +63,12 @@ Quick start example: `thisway 1000` or `goal 70` to set the goal, `path` to actu
|
||||
BaritoneAPI.getSettings().allowSprint.value = true;
|
||||
BaritoneAPI.getSettings().pathTimeoutMS.value = 2000L;
|
||||
|
||||
BaritoneAPI.getPathingBehavior().setGoal(new GoalXZ(10000, 20000));
|
||||
BaritoneAPI.getPathingBehavior().path();
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
|
||||
```
|
||||
|
||||
# FAQ
|
||||
|
||||
## Can I use Baritone as a library in my hacked client?
|
||||
## Can I use Baritone as a library in my custom utility client?
|
||||
|
||||
Sure! (As long as usage is in compliance with the LGPL 3 License)
|
||||
|
||||
|
||||
56
build.gradle
56
build.gradle
@@ -1,7 +1,3 @@
|
||||
import java.util.jar.JarEntry
|
||||
import java.util.jar.JarFile
|
||||
import java.util.jar.JarOutputStream
|
||||
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
@@ -20,7 +16,7 @@ import java.util.jar.JarOutputStream
|
||||
*/
|
||||
|
||||
group 'baritone'
|
||||
version '0.0.8'
|
||||
version '1.0.0-hotfix-2'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
@@ -41,6 +37,10 @@ buildscript {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
import baritone.gradle.task.CreateDistTask
|
||||
import baritone.gradle.task.ProguardTask
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
|
||||
apply plugin: 'org.spongepowered.mixin'
|
||||
@@ -58,7 +58,7 @@ sourceSets {
|
||||
|
||||
minecraft {
|
||||
version = '1.12.2'
|
||||
mappings = 'snapshot_20180731'
|
||||
mappings = 'stable_39'
|
||||
tweakClass = 'baritone.launch.BaritoneTweaker'
|
||||
runDir = 'run'
|
||||
|
||||
@@ -73,9 +73,15 @@ repositories {
|
||||
name = 'spongepowered-repo'
|
||||
url = 'http://repo.spongepowered.org/maven/'
|
||||
}
|
||||
|
||||
maven {
|
||||
name = 'impactdevelopment-repo'
|
||||
url = 'https://impactdevelopment.github.io/maven/'
|
||||
}
|
||||
}
|
||||
|
||||
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'
|
||||
@@ -92,38 +98,22 @@ mixin {
|
||||
add sourceSets.launch, 'mixins.baritone.refmap.json'
|
||||
}
|
||||
|
||||
javadoc {
|
||||
source = sourceSets.api.allJava
|
||||
classpath = sourceSets.api.compileClasspath
|
||||
}
|
||||
|
||||
jar {
|
||||
from sourceSets.launch.output, sourceSets.api.output
|
||||
preserveFileTimestamps = false
|
||||
reproducibleFileOrder = true
|
||||
}
|
||||
|
||||
build {
|
||||
// while "jar" supports preserveFileTimestamps false
|
||||
// reobfJar doesn't, it just sets all the last modified times to that instant where it runs the reobfuscator
|
||||
// so we have to set all those last modified times back to zero
|
||||
doLast {
|
||||
File jarFile = new File("build/libs/baritone-" + version + ".jar")
|
||||
JarFile jf = new JarFile(jarFile)
|
||||
JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File("temp.jar")))
|
||||
jf.entries().unique { it.name }.sort { it.name }.each {
|
||||
if (it.name != "META-INF/fml_cache_annotation.json" && it.name != "META-INF/fml_cache_class_versions.json") {
|
||||
JarEntry clone = new JarEntry(it)
|
||||
clone.time = 0
|
||||
jos.putNextEntry(clone)
|
||||
copy(jf.getInputStream(it), jos)
|
||||
}
|
||||
}
|
||||
jos.finish()
|
||||
jf.close()
|
||||
file("temp.jar").renameTo(jarFile)
|
||||
}
|
||||
task proguard(type: ProguardTask) {
|
||||
url 'https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip'
|
||||
extract 'proguard6.0.3/lib/proguard.jar'
|
||||
}
|
||||
|
||||
void copy(InputStream is, OutputStream os) {
|
||||
byte[] buffer = new byte[1024]
|
||||
int len = 0
|
||||
while ((len = is.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, len)
|
||||
}
|
||||
}
|
||||
task createDist(type: CreateDistTask, dependsOn: proguard)
|
||||
|
||||
build.finalizedBy(createDist)
|
||||
|
||||
3
buildSrc/.gitignore
vendored
Normal file
3
buildSrc/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
build/
|
||||
.gradle/
|
||||
out/
|
||||
25
buildSrc/build.gradle
Normal file
25
buildSrc/build.gradle
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
||||
compile group: 'commons-io', name: 'commons-io', version: '2.6'
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.task;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.gradle.api.DefaultTask;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 10/12/2018
|
||||
*/
|
||||
class BaritoneGradleTask extends DefaultTask {
|
||||
|
||||
protected static final JsonParser PARSER = new JsonParser();
|
||||
|
||||
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",
|
||||
|
||||
VERSION_MANIFEST = "version_manifest.json",
|
||||
|
||||
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";
|
||||
|
||||
protected String artifactName, artifactVersion;
|
||||
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
|
||||
|
||||
protected void verifyArtifacts() throws IllegalStateException {
|
||||
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.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
|
||||
|
||||
if (!Files.exists(this.artifactPath)) {
|
||||
throw new IllegalStateException("Artifact not found! Run build first!");
|
||||
}
|
||||
}
|
||||
|
||||
protected void write(InputStream stream, Path file) throws Exception {
|
||||
if (Files.exists(file)) {
|
||||
Files.delete(file);
|
||||
}
|
||||
Files.copy(stream, file);
|
||||
}
|
||||
|
||||
protected String formatVersion(String string) {
|
||||
return String.format(string, this.artifactName, this.artifactVersion);
|
||||
}
|
||||
|
||||
protected Path getRelativeFile(String file) {
|
||||
return Paths.get(new File(file).getAbsolutePath());
|
||||
}
|
||||
|
||||
protected Path getTemporaryFile(String file) {
|
||||
return Paths.get(new File(getTemporaryDir(), file).getAbsolutePath());
|
||||
}
|
||||
|
||||
protected Path getBuildFile(String file) {
|
||||
return getRelativeFile("build/libs/" + file);
|
||||
}
|
||||
|
||||
protected JsonElement readJson(List<String> lines) {
|
||||
return PARSER.parse(String.join("\n", lines));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.gradle.task;
|
||||
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 10/12/2018
|
||||
*/
|
||||
public class CreateDistTask extends BaritoneGradleTask {
|
||||
|
||||
private static MessageDigest SHA1_DIGEST;
|
||||
|
||||
@TaskAction
|
||||
protected void exec() throws Exception {
|
||||
super.verifyArtifacts();
|
||||
|
||||
// Define the distribution file paths
|
||||
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
|
||||
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
|
||||
Path unoptimized = getRelativeFile("dist/" + formatVersion(ARTIFACT_UNOPTIMIZED));
|
||||
|
||||
// NIO will not automatically create directories
|
||||
Path dir = getRelativeFile("dist/");
|
||||
if (!Files.exists(dir)) {
|
||||
Files.createDirectory(dir);
|
||||
}
|
||||
|
||||
// Copy build jars to dist/
|
||||
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
|
||||
Files.copy(this.artifactStandalonePath, standalone, REPLACE_EXISTING);
|
||||
Files.copy(this.artifactUnoptimizedPath, unoptimized, REPLACE_EXISTING);
|
||||
|
||||
// Calculate all checksums and format them like "shasum"
|
||||
List<String> shasum = Stream.of(api, standalone, unoptimized)
|
||||
.map(path -> sha1(path) + " " + path.getFileName().toString())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
shasum.forEach(System.out::println);
|
||||
|
||||
// Write the checksums to a file
|
||||
Files.write(getRelativeFile("dist/checksums.txt"), shasum);
|
||||
}
|
||||
|
||||
private static synchronized String sha1(Path path) {
|
||||
try {
|
||||
if (SHA1_DIGEST == null) {
|
||||
SHA1_DIGEST = MessageDigest.getInstance("SHA-1");
|
||||
}
|
||||
return DatatypeConverter.printHexBinary(SHA1_DIGEST.digest(Files.readAllBytes(path))).toLowerCase();
|
||||
} catch (Exception e) {
|
||||
// haha no thanks
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
323
buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java
Normal file
323
buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* 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.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.NamedDomainObjectContainer;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.internal.plugins.DefaultConvention;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.internal.Pair;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
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
|
||||
*/
|
||||
public class ProguardTask extends BaritoneGradleTask {
|
||||
|
||||
private static final Pattern TEMP_LIBRARY_PATTERN = Pattern.compile("-libraryjars 'tempLibraries\\/([a-zA-Z0-9/_\\-\\.]+)\\.jar'");
|
||||
|
||||
@Input
|
||||
private String url;
|
||||
|
||||
@Input
|
||||
private String extract;
|
||||
|
||||
private List<String> requiredLibraries;
|
||||
|
||||
@TaskAction
|
||||
protected void exec() throws Exception {
|
||||
super.verifyArtifacts();
|
||||
|
||||
// "Haha brady why don't you make separate tasks"
|
||||
processArtifact();
|
||||
downloadProguard();
|
||||
extractProguard();
|
||||
generateConfigs();
|
||||
acquireDependencies();
|
||||
proguardApi();
|
||||
proguardStandalone();
|
||||
cleanup();
|
||||
}
|
||||
|
||||
private void processArtifact() throws Exception {
|
||||
if (Files.exists(this.artifactUnoptimizedPath)) {
|
||||
Files.delete(this.artifactUnoptimizedPath);
|
||||
}
|
||||
|
||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
|
||||
}
|
||||
|
||||
private void downloadProguard() throws Exception {
|
||||
Path proguardZip = getTemporaryFile(PROGUARD_ZIP);
|
||||
if (!Files.exists(proguardZip)) {
|
||||
write(new URL(this.url).openStream(), proguardZip);
|
||||
}
|
||||
}
|
||||
|
||||
private void extractProguard() throws Exception {
|
||||
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
|
||||
if (!Files.exists(proguardJar)) {
|
||||
ZipFile zipFile = new ZipFile(getTemporaryFile(PROGUARD_ZIP).toFile());
|
||||
ZipEntry zipJarEntry = zipFile.getEntry(this.extract);
|
||||
write(zipFile.getInputStream(zipJarEntry), proguardJar);
|
||||
zipFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void generateConfigs() throws Exception {
|
||||
Files.copy(getRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), 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));
|
||||
template.add(0, "-injars " + this.artifactPath.toString());
|
||||
template.add(1, "-outjars " + this.getTemporaryFile(PROGUARD_EXPORT_PATH));
|
||||
|
||||
// Acquire the RT jar using "java -verbose". This doesn't work on Java 9+
|
||||
Process p = new ProcessBuilder("java", "-verbose").start();
|
||||
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
|
||||
template.add(2, "-libraryjars '" + out + "'");
|
||||
|
||||
// API config doesn't require any changes from the changes that we made to the template
|
||||
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
|
||||
|
||||
// For the Standalone config, don't keep the API package
|
||||
List<String> standalone = new ArrayList<>(template);
|
||||
standalone.removeIf(s -> s.contains("# this is the keep api"));
|
||||
Files.write(getTemporaryFile(PROGUARD_STANDALONE_CONFIG), standalone);
|
||||
|
||||
// Discover all of the libraries that we will need to acquire from gradle
|
||||
this.requiredLibraries = new ArrayList<>();
|
||||
template.forEach(line -> {
|
||||
if (!line.startsWith("#")) {
|
||||
Matcher m = TEMP_LIBRARY_PATTERN.matcher(line);
|
||||
if (m.find()) {
|
||||
this.requiredLibraries.add(m.group(1));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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))));
|
||||
|
||||
// Create the directory if it doesn't already exist
|
||||
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
|
||||
if (!Files.exists(tempLibraries)) {
|
||||
Files.createDirectory(tempLibraries);
|
||||
}
|
||||
|
||||
// Iterate the required libraries to copy them to tempLibraries
|
||||
for (String lib : this.requiredLibraries) {
|
||||
// copy from the forgegradle cache
|
||||
if (lib.equals("minecraft")) {
|
||||
Path cachedJar = getMinecraftJar();
|
||||
Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar");
|
||||
// TODO: maybe try not to copy every time
|
||||
Files.copy(cachedJar, inTempDir, REPLACE_EXISTING);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find a configuration/dependency pair that matches the desired library
|
||||
Pair<Configuration, Dependency> pair = null;
|
||||
for (Map.Entry<String, Pair<Configuration, Dependency>> entry : dependencyLookupMap.entrySet()) {
|
||||
if (entry.getKey().startsWith(lib)) {
|
||||
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)) {
|
||||
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), 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();
|
||||
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();
|
||||
}
|
||||
|
||||
// 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");
|
||||
|
||||
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?)");
|
||||
}
|
||||
|
||||
return mappingTypes.get(0);
|
||||
}
|
||||
|
||||
private List<MappingType> getUsedMappingTypes(Set<Object> reobf) {
|
||||
return reobf.stream()
|
||||
.map(ReobfWrapper::new)
|
||||
.map(ReobfWrapper::getMappingType)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void proguardApi() throws Exception {
|
||||
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
|
||||
}
|
||||
|
||||
private void proguardStandalone() throws Exception {
|
||||
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
try {
|
||||
Files.delete(this.proguardOut);
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public void setExtract(String extract) {
|
||||
this.extract = extract;
|
||||
}
|
||||
|
||||
private void runProguard(Path config) throws Exception {
|
||||
// Delete the existing proguard output file. Proguard probably handles this already, but why not do it ourselves
|
||||
if (Files.exists(this.proguardOut)) {
|
||||
Files.delete(this.proguardOut);
|
||||
}
|
||||
|
||||
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
|
||||
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
|
||||
.directory(getTemporaryFile("").toFile()) // Set the working directory to the temporary folder]
|
||||
.start();
|
||||
|
||||
// We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this
|
||||
this.printOutputLog(p.getInputStream());
|
||||
this.printOutputLog(p.getErrorStream());
|
||||
|
||||
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
|
||||
int exitCode = p.waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new IllegalStateException("Proguard exited with code " + exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
private void printOutputLog(InputStream stream) {
|
||||
new Thread(() -> {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
System.out.println(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
143
buildSrc/src/main/java/baritone/gradle/util/Determinizer.java
Normal file
143
buildSrc/src/main/java/baritone/gradle/util/Determinizer.java
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* 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 com.google.gson.*;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.*;
|
||||
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;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 42069.
|
||||
* This makes the build 100% reproducible since the timestamp when you built it no longer affects the final file.
|
||||
*
|
||||
* @author leijurv
|
||||
*/
|
||||
public class Determinizer {
|
||||
|
||||
public static void determinize(String inputPath, String outputPath) throws IOException {
|
||||
System.out.println("Running Determinizer");
|
||||
System.out.println(" Input path: " + inputPath);
|
||||
System.out.println(" Output path: " + outputPath);
|
||||
|
||||
try (
|
||||
JarFile jarFile = new JarFile(new File(inputPath));
|
||||
JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File(outputPath)))
|
||||
) {
|
||||
|
||||
List<JarEntry> entries = jarFile.stream()
|
||||
.sorted(Comparator.comparing(JarEntry::getName))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (JarEntry entry : entries) {
|
||||
if (entry.getName().equals("META-INF/fml_cache_annotation.json")) {
|
||||
continue;
|
||||
}
|
||||
if (entry.getName().equals("META-INF/fml_cache_class_versions.json")) {
|
||||
continue;
|
||||
}
|
||||
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 {
|
||||
copy(jarFile.getInputStream(entry), jos);
|
||||
}
|
||||
}
|
||||
jos.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private static void copy(InputStream is, OutputStream os) throws IOException {
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
while ((len = is.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
private static String writeSorted(JsonObject in) throws IOException {
|
||||
StringWriter writer = new StringWriter();
|
||||
JsonWriter jw = new JsonWriter(writer);
|
||||
ORDERED_JSON_WRITER.write(jw, in);
|
||||
return writer.toString() + "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* All credits go to GSON and its contributors. GSON is licensed under the Apache 2.0 License.
|
||||
* This implementation has been modified to write {@link JsonObject} keys in order.
|
||||
*
|
||||
* @see <a href="https://github.com/google/gson/blob/master/LICENSE">GSON License</a>
|
||||
* @see <a href="https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java#L698">Original Source</a>
|
||||
*/
|
||||
private static final TypeAdapter<JsonElement> ORDERED_JSON_WRITER = new TypeAdapter<JsonElement>() {
|
||||
|
||||
@Override
|
||||
public JsonElement read(JsonReader in) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, JsonElement value) throws IOException {
|
||||
if (value == null || value.isJsonNull()) {
|
||||
out.nullValue();
|
||||
} else if (value.isJsonPrimitive()) {
|
||||
JsonPrimitive primitive = value.getAsJsonPrimitive();
|
||||
if (primitive.isNumber()) {
|
||||
out.value(primitive.getAsNumber());
|
||||
} else if (primitive.isBoolean()) {
|
||||
out.value(primitive.getAsBoolean());
|
||||
} else {
|
||||
out.value(primitive.getAsString());
|
||||
}
|
||||
|
||||
} else if (value.isJsonArray()) {
|
||||
out.beginArray();
|
||||
for (JsonElement e : value.getAsJsonArray()) {
|
||||
write(out, e);
|
||||
}
|
||||
out.endArray();
|
||||
|
||||
} else if (value.isJsonObject()) {
|
||||
out.beginObject();
|
||||
|
||||
List<Map.Entry<String, JsonElement>> entries = new ArrayList<>(value.getAsJsonObject().entrySet());
|
||||
entries.sort(Comparator.comparing(Map.Entry::getKey));
|
||||
for (Map.Entry<String, JsonElement> e : entries) {
|
||||
out.name(e.getKey());
|
||||
write(out, e.getValue());
|
||||
}
|
||||
out.endObject();
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Couldn't write " + value.getClass());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
29
buildSrc/src/main/java/baritone/gradle/util/MappingType.java
Normal file
29
buildSrc/src/main/java/baritone/gradle/util/MappingType.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e # this makes the whole script fail immediately if any one of these commands fails
|
||||
./gradlew build
|
||||
export VERSION=$(cat build.gradle | grep "version '" | cut -d "'" -f 2-2)
|
||||
|
||||
wget -nv https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip
|
||||
unzip proguard6.0.3.zip 2>&1 > /dev/null
|
||||
cd build/libs
|
||||
echo "-injars 'baritone-$VERSION.jar'" >> api.pro # insert current version
|
||||
cat ../../scripts/proguard.pro | grep -v "this is the rt jar" | grep -v "\-injars" >> api.pro # remove default rt jar and injar lines
|
||||
echo "-libraryjars '$(java -verbose 2>/dev/null | sed -ne '1 s/\[Opened \(.*\)\]/\1/p')'" >> api.pro # insert correct rt.jar location
|
||||
tail api.pro # debug, print out what the previous two commands generated
|
||||
cat api.pro | grep -v "this is the keep api" > standalone.pro # standalone doesn't keep baritone api
|
||||
|
||||
#instead of downloading these jars from my dropbox in a zip, just assume gradle's already got them for us
|
||||
mkdir -p tempLibraries
|
||||
cat ../../scripts/proguard.pro | grep tempLibraries | grep .jar | cut -d "/" -f 2- | cut -d "'" -f -1 | xargs -n1 -I{} bash -c "find ~/.gradle -name {}" | tee /dev/stderr | xargs -n1 -I{} cp {} tempLibraries
|
||||
|
||||
mkdir ../../dist
|
||||
java -jar ../../proguard6.0.3/lib/proguard.jar @api.pro
|
||||
mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-api-$VERSION.jar
|
||||
java -jar ../../proguard6.0.3/lib/proguard.jar @standalone.pro
|
||||
mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-standalone-$VERSION.jar
|
||||
mv baritone-$VERSION.jar ../../dist/baritone-unoptimized-$VERSION.jar
|
||||
cd ../../dist
|
||||
shasum * | tee checksums.txt
|
||||
cd ..
|
||||
27
scripts/proguard.pro
vendored
27
scripts/proguard.pro
vendored
@@ -1,7 +1,3 @@
|
||||
-injars baritone-0.0.8.jar
|
||||
-outjars Obfuscated
|
||||
|
||||
|
||||
-keepattributes Signature
|
||||
-keepattributes *Annotation*
|
||||
|
||||
@@ -17,9 +13,14 @@
|
||||
-repackageclasses 'baritone'
|
||||
|
||||
-keep class baritone.api.** { *; } # this is the keep api
|
||||
|
||||
# service provider needs these class names
|
||||
-keep class baritone.BaritoneProvider
|
||||
-keep class baritone.api.IBaritoneProvider
|
||||
|
||||
# hack
|
||||
-keep class baritone.utils.ExampleBaritoneControl { *; } # have to include this string to remove this keep in the standalone build: # this is the keep api
|
||||
|
||||
# setting names are reflected from field names, so keep field names
|
||||
-keepclassmembers class baritone.api.Settings {
|
||||
public <fields>;
|
||||
@@ -29,9 +30,11 @@
|
||||
-keep class baritone.launch.** { *; }
|
||||
|
||||
# copy all necessary libraries into tempLibraries to build
|
||||
-libraryjars '/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/rt.jar' # this is the rt jar
|
||||
|
||||
-libraryjars 'tempLibraries/minecraft-1.12.2.jar'
|
||||
# The correct jar will be copied from the forgegradle cache based on the mapping type being compiled with
|
||||
-libraryjars 'tempLibraries/minecraft.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/SimpleTweaker-1.2.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/authlib-1.5.25.jar'
|
||||
-libraryjars 'tempLibraries/codecjorbis-20101023.jar'
|
||||
@@ -47,7 +50,6 @@
|
||||
-libraryjars 'tempLibraries/httpclient-4.3.3.jar'
|
||||
-libraryjars 'tempLibraries/httpcore-4.3.2.jar'
|
||||
-libraryjars 'tempLibraries/icu4j-core-mojang-51.2.jar'
|
||||
-libraryjars 'tempLibraries/java-objc-bridge-1.0.0.jar'
|
||||
-libraryjars 'tempLibraries/jinput-2.0.5.jar'
|
||||
-libraryjars 'tempLibraries/jna-4.4.0.jar'
|
||||
-libraryjars 'tempLibraries/jopt-simple-5.0.3.jar'
|
||||
@@ -58,13 +60,10 @@
|
||||
-libraryjars 'tempLibraries/log4j-api-2.8.1.jar'
|
||||
-libraryjars 'tempLibraries/log4j-core-2.8.1.jar'
|
||||
|
||||
# linux / travis
|
||||
-libraryjars 'tempLibraries/lwjgl-2.9.4-nightly-20150209.jar'
|
||||
-libraryjars 'tempLibraries/lwjgl_util-2.9.4-nightly-20150209.jar'
|
||||
|
||||
# mac
|
||||
#-libraryjars 'tempLibraries/lwjgl_util-2.9.2-nightly-20140822.jar'
|
||||
#-libraryjars 'tempLibraries/lwjgl-2.9.2-nightly-20140822.jar'
|
||||
# startsWith is used to check the library, and mac/linux differ in which version they use
|
||||
# this is FINE
|
||||
-libraryjars 'tempLibraries/lwjgl-.jar'
|
||||
-libraryjars 'tempLibraries/lwjgl_util-.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
|
||||
-libraryjars 'tempLibraries/oshi-core-1.1.jar'
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
|
||||
package baritone.api;
|
||||
|
||||
import baritone.api.behavior.*;
|
||||
import baritone.api.cache.IWorldProvider;
|
||||
import baritone.api.cache.IWorldScanner;
|
||||
import baritone.api.event.listener.IGameEventListener;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
|
||||
import java.util.Iterator;
|
||||
@@ -36,51 +32,23 @@ import java.util.ServiceLoader;
|
||||
*/
|
||||
public final class BaritoneAPI {
|
||||
|
||||
private final static IBaritoneProvider baritone;
|
||||
private final static Settings settings;
|
||||
private static final IBaritoneProvider provider;
|
||||
private static final Settings settings;
|
||||
|
||||
static {
|
||||
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);
|
||||
Iterator<IBaritoneProvider> instances = baritoneLoader.iterator();
|
||||
baritone = instances.next();
|
||||
provider = instances.next();
|
||||
|
||||
settings = new Settings();
|
||||
SettingsUtil.readAndApply(settings);
|
||||
}
|
||||
|
||||
public static IFollowBehavior getFollowBehavior() {
|
||||
return baritone.getFollowBehavior();
|
||||
}
|
||||
|
||||
public static ILookBehavior getLookBehavior() {
|
||||
return baritone.getLookBehavior();
|
||||
}
|
||||
|
||||
public static IMemoryBehavior getMemoryBehavior() {
|
||||
return baritone.getMemoryBehavior();
|
||||
}
|
||||
|
||||
public static IMineBehavior getMineBehavior() {
|
||||
return baritone.getMineBehavior();
|
||||
}
|
||||
|
||||
public static IPathingBehavior getPathingBehavior() {
|
||||
return baritone.getPathingBehavior();
|
||||
public static IBaritoneProvider getProvider() {
|
||||
return BaritoneAPI.provider;
|
||||
}
|
||||
|
||||
public static Settings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public static IWorldProvider getWorldProvider() {
|
||||
return baritone.getWorldProvider();
|
||||
}
|
||||
|
||||
public static IWorldScanner getWorldScanner() {
|
||||
return baritone.getWorldScanner();
|
||||
}
|
||||
|
||||
public static void registerEventListener(IGameEventListener listener) {
|
||||
baritone.registerEventListener(listener);
|
||||
return BaritoneAPI.settings;
|
||||
}
|
||||
}
|
||||
|
||||
76
src/api/java/baritone/api/IBaritone.java
Normal file
76
src/api/java/baritone/api/IBaritone.java
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import baritone.api.behavior.ILookBehavior;
|
||||
import baritone.api.behavior.IPathingBehavior;
|
||||
import baritone.api.cache.IWorldProvider;
|
||||
import baritone.api.event.listener.IEventBus;
|
||||
import baritone.api.process.ICustomGoalProcess;
|
||||
import baritone.api.process.IFollowProcess;
|
||||
import baritone.api.process.IGetToBlockProcess;
|
||||
import baritone.api.process.IMineProcess;
|
||||
import baritone.api.utils.IInputOverrideHandler;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/29/2018
|
||||
*/
|
||||
public interface IBaritone {
|
||||
|
||||
/**
|
||||
* @return The {@link IFollowProcess} instance
|
||||
* @see IFollowProcess
|
||||
*/
|
||||
IFollowProcess getFollowProcess();
|
||||
|
||||
/**
|
||||
* @return The {@link ILookBehavior} instance
|
||||
* @see ILookBehavior
|
||||
*/
|
||||
ILookBehavior getLookBehavior();
|
||||
|
||||
/**
|
||||
* @return The {@link IMineProcess} instance
|
||||
* @see IMineProcess
|
||||
*/
|
||||
IMineProcess getMineProcess();
|
||||
|
||||
/**
|
||||
* @return The {@link IPathingBehavior} instance
|
||||
* @see IPathingBehavior
|
||||
*/
|
||||
IPathingBehavior getPathingBehavior();
|
||||
|
||||
/**
|
||||
* @return The {@link IWorldProvider} instance
|
||||
* @see IWorldProvider
|
||||
*/
|
||||
IWorldProvider getWorldProvider();
|
||||
|
||||
IInputOverrideHandler getInputOverrideHandler();
|
||||
|
||||
ICustomGoalProcess getCustomGoalProcess();
|
||||
|
||||
IGetToBlockProcess getGetToBlockProcess();
|
||||
|
||||
IPlayerContext getPlayerContext();
|
||||
|
||||
IEventBus getGameEventHandler();
|
||||
}
|
||||
@@ -17,70 +17,55 @@
|
||||
|
||||
package baritone.api;
|
||||
|
||||
import baritone.api.behavior.*;
|
||||
import baritone.api.cache.IWorldProvider;
|
||||
import baritone.api.cache.IWorldScanner;
|
||||
import baritone.api.event.listener.IGameEventListener;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/29/2018
|
||||
* @author Leijurv
|
||||
*/
|
||||
public interface IBaritoneProvider {
|
||||
|
||||
/**
|
||||
* @see IFollowBehavior
|
||||
* Returns the primary {@link IBaritone} instance. This instance is persistent, and
|
||||
* is represented by the local player that is created by the game itself, not a "bot"
|
||||
* player through Baritone.
|
||||
*
|
||||
* @return The {@link IFollowBehavior} instance
|
||||
* @return The primary {@link IBaritone} instance.
|
||||
*/
|
||||
IFollowBehavior getFollowBehavior();
|
||||
IBaritone getPrimaryBaritone();
|
||||
|
||||
/**
|
||||
* @see ILookBehavior
|
||||
* Returns all of the active {@link IBaritone} instances. This includes the local one
|
||||
* returned by {@link #getPrimaryBaritone()}.
|
||||
*
|
||||
* @return The {@link ILookBehavior} instance
|
||||
* @return All active {@link IBaritone} instances.
|
||||
* @see #getBaritoneForPlayer(EntityPlayerSP)
|
||||
*/
|
||||
ILookBehavior getLookBehavior();
|
||||
List<IBaritone> getAllBaritones();
|
||||
|
||||
/**
|
||||
* @see IMemoryBehavior
|
||||
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
|
||||
* replaced with {@code #getBaritoneForUser(IBaritoneUser)} when {@code bot-system} is merged.
|
||||
*
|
||||
* @return The {@link IMemoryBehavior} instance
|
||||
* @param player The player
|
||||
* @return The {@link IBaritone} instance.
|
||||
*/
|
||||
IMemoryBehavior getMemoryBehavior();
|
||||
default IBaritone getBaritoneForPlayer(EntityPlayerSP player) {
|
||||
for (IBaritone baritone : getAllBaritones()) {
|
||||
if (player.equals(baritone.getPlayerContext().player())) {
|
||||
return baritone;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("No baritone for player " + player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IMineBehavior
|
||||
* Returns the {@link IWorldScanner} instance. This is not a type returned by
|
||||
* {@link IBaritone} implementation, because it is not linked with {@link IBaritone}.
|
||||
*
|
||||
* @return The {@link IMineBehavior} instance
|
||||
*/
|
||||
IMineBehavior getMineBehavior();
|
||||
|
||||
/**
|
||||
* @see IPathingBehavior
|
||||
*
|
||||
* @return The {@link IPathingBehavior} instance
|
||||
*/
|
||||
IPathingBehavior getPathingBehavior();
|
||||
|
||||
/**
|
||||
* @see IWorldProvider
|
||||
*
|
||||
* @return The {@link IWorldProvider} instance
|
||||
*/
|
||||
IWorldProvider getWorldProvider();
|
||||
|
||||
/**
|
||||
* @see IWorldScanner
|
||||
*
|
||||
* @return The {@link IWorldScanner} instance
|
||||
* @return The {@link IWorldScanner} instance.
|
||||
*/
|
||||
IWorldScanner getWorldScanner();
|
||||
|
||||
/**
|
||||
* Registers a {@link IGameEventListener} with Baritone's "event bus".
|
||||
*
|
||||
* @param listener The listener
|
||||
*/
|
||||
void registerEventListener(IGameEventListener listener);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,11 @@ public class Settings {
|
||||
*/
|
||||
public Setting<Boolean> allowPlace = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Allow Baritone to move items in your inventory to your hotbar
|
||||
*/
|
||||
public Setting<Boolean> allowInventory = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* It doesn't actually take twenty ticks to place a block, this cost is so high
|
||||
* because we want to generally conserve blocks which might be limited
|
||||
@@ -89,6 +94,13 @@ public class Settings {
|
||||
*/
|
||||
public Setting<Boolean> assumeSafeWalk = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* If true, parkour is allowed to make jumps when standing on blocks at the maximum height, so player feet is y=256
|
||||
* <p>
|
||||
* Defaults to false because this fails on NCP
|
||||
*/
|
||||
public Setting<Boolean> allowJumpAt256 = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
||||
*/
|
||||
@@ -141,8 +153,10 @@ public class Settings {
|
||||
* metric gets better and better with each block, instead of slightly worse.
|
||||
* <p>
|
||||
* Finding the optimal path is worth it, so it's the default.
|
||||
* <p>
|
||||
* This value is an expression instead of a literal so that it's exactly equal to SPRINT_ONE_BLOCK_COST defined in ActionCosts.java
|
||||
*/
|
||||
public Setting<Double> costHeuristic = new Setting<>(3.5D);
|
||||
public Setting<Double> costHeuristic = new Setting<>(20 / 5.612);
|
||||
|
||||
// a bunch of obscure internal A* settings that you probably don't want to change
|
||||
/**
|
||||
@@ -158,6 +172,42 @@ public class Settings {
|
||||
*/
|
||||
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
|
||||
|
||||
/**
|
||||
* Toggle the following 4 settings
|
||||
* <p>
|
||||
* They have a noticable performance impact, so they default off
|
||||
*/
|
||||
public Setting<Boolean> avoidance = new Setting<>(false);
|
||||
/**
|
||||
* Set to 1.0 to effectively disable this feature
|
||||
* <p>
|
||||
* Set below 1.0 to go out of your way to walk near mob spawners
|
||||
*/
|
||||
public Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
|
||||
|
||||
public Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16);
|
||||
|
||||
/**
|
||||
* Set to 1.0 to effectively disable this feature
|
||||
* <p>
|
||||
* Set below 1.0 to go out of your way to walk near mobs
|
||||
*/
|
||||
public Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
|
||||
|
||||
public Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
|
||||
|
||||
/**
|
||||
* When running a goto towards a container block (chest, ender chest, furnace, etc),
|
||||
* right click and open it once you arrive.
|
||||
*/
|
||||
public Setting<Boolean> rightClickContainerOnArrival = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* When running a goto towards a nether portal block, walk all the way into the portal
|
||||
* instead of stopping one block before.
|
||||
*/
|
||||
public Setting<Boolean> enterPortal = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Don't repropagate cost improvements below 0.01 ticks. They're all just floating point inaccuracies,
|
||||
* and there's no point.
|
||||
@@ -247,14 +297,28 @@ public class Settings {
|
||||
public Setting<Integer> movementTimeoutTicks = new Setting<>(100);
|
||||
|
||||
/**
|
||||
* Pathing can never take longer than this
|
||||
* Pathing ends after this amount of time, but only if a path has been found
|
||||
* <p>
|
||||
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
|
||||
*/
|
||||
public Setting<Long> pathTimeoutMS = new Setting<>(2000L);
|
||||
public Setting<Long> primaryTimeoutMS = new Setting<>(500L);
|
||||
|
||||
/**
|
||||
* Planning ahead while executing a segment can never take longer than this
|
||||
* Pathing can never take longer than this, even if that means failing to find any path at all
|
||||
*/
|
||||
public Setting<Long> planAheadTimeoutMS = new Setting<>(4000L);
|
||||
public Setting<Long> failureTimeoutMS = new Setting<>(2000L);
|
||||
|
||||
/**
|
||||
* Planning ahead while executing a segment ends after this amount of time, but only if a path has been found
|
||||
* <p>
|
||||
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
|
||||
*/
|
||||
public Setting<Long> planAheadPrimaryTimeoutMS = new Setting<>(4000L);
|
||||
|
||||
/**
|
||||
* Planning ahead while executing a segment can never take longer than this, even if that means failing to find any path at all
|
||||
*/
|
||||
public Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
|
||||
|
||||
/**
|
||||
* For debugging, consider nodes much much slower
|
||||
@@ -276,6 +340,13 @@ public class Settings {
|
||||
*/
|
||||
public Setting<Boolean> chunkCaching = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
|
||||
* <p>
|
||||
* Temporarily disabled, see issue #248
|
||||
*/
|
||||
public Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Print all the debug messages to chat
|
||||
*/
|
||||
@@ -305,17 +376,23 @@ public class Settings {
|
||||
/**
|
||||
* Ignore depth when rendering the goal
|
||||
*/
|
||||
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(false);
|
||||
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Renders X/Z type Goals with the vanilla beacon beam effect. Combining this with
|
||||
* {@link #renderGoalIgnoreDepth} will cause strange render clipping.
|
||||
*/
|
||||
public Setting<Boolean> renderGoalXZBeacon = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
|
||||
*/
|
||||
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(false);
|
||||
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Ignore depth when rendering the path
|
||||
*/
|
||||
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(false);
|
||||
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Line width of the path when rendered, in pixels
|
||||
@@ -370,12 +447,27 @@ public class Settings {
|
||||
*/
|
||||
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* If we are more than 500 movements into the current path, discard the oldest segments, as they are no longer useful
|
||||
*/
|
||||
public Setting<Integer> maxPathHistoryLength = new Setting<>(300);
|
||||
|
||||
/**
|
||||
* If the current path is too long, cut off this many movements from the beginning.
|
||||
*/
|
||||
public Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
|
||||
|
||||
/**
|
||||
* Rescan for the goal once every 5 ticks.
|
||||
* Set to 0 to disable.
|
||||
*/
|
||||
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
|
||||
|
||||
/**
|
||||
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
|
||||
*/
|
||||
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
|
||||
* <p>
|
||||
@@ -389,13 +481,25 @@ public class Settings {
|
||||
* <p>
|
||||
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
|
||||
*/
|
||||
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(false);
|
||||
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
|
||||
*/
|
||||
public Setting<Integer> axisHeight = new Setting<>(120);
|
||||
|
||||
/**
|
||||
* Allow MineBehavior to use X-Ray to see where the ores are. Turn this option off to force it to mine "legit"
|
||||
* where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
|
||||
* couldn't. If you don't want it to look like you're X-Raying, turn this off
|
||||
*/
|
||||
public Setting<Boolean> legitMine = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* What Y level to go to for legit strip mining
|
||||
*/
|
||||
public Setting<Integer> legitMineYLevel = new Setting<>(11);
|
||||
|
||||
/**
|
||||
* When mining block of a certain type, try to mine two at once instead of one.
|
||||
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
|
||||
@@ -505,6 +609,12 @@ public class Settings {
|
||||
*/
|
||||
public final List<Setting<?>> allSettings;
|
||||
|
||||
public void reset() {
|
||||
for (Setting setting : allSettings) {
|
||||
setting.value = setting.defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public class Setting<T> {
|
||||
public T value;
|
||||
public final T defaultValue;
|
||||
|
||||
@@ -18,10 +18,9 @@
|
||||
package baritone.api.behavior;
|
||||
|
||||
import baritone.api.event.listener.AbstractGameEventListener;
|
||||
import baritone.api.utils.interfaces.Toggleable;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/23/2018
|
||||
*/
|
||||
public interface IBehavior extends AbstractGameEventListener, Toggleable {}
|
||||
public interface IBehavior extends AbstractGameEventListener {}
|
||||
|
||||
@@ -33,7 +33,7 @@ public interface ILookBehavior extends IBehavior {
|
||||
* otherwise, it should be {@code false};
|
||||
*
|
||||
* @param rotation The target rotations
|
||||
* @param force Whether or not to "force" the rotations
|
||||
* @param force Whether or not to "force" the rotations
|
||||
*/
|
||||
void updateTarget(Rotation rotation, boolean force);
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
package baritone.api.behavior;
|
||||
|
||||
import baritone.api.pathing.calc.IPath;
|
||||
import baritone.api.pathing.calc.IPathFinder;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.calc.IPath;
|
||||
import baritone.api.pathing.path.IPathExecutor;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -39,35 +39,25 @@ public interface IPathingBehavior extends IBehavior {
|
||||
*/
|
||||
Optional<Double> ticksRemainingInSegment();
|
||||
|
||||
/**
|
||||
* Sets the pathing goal.
|
||||
*
|
||||
* @param goal The pathing goal
|
||||
*/
|
||||
void setGoal(Goal goal);
|
||||
|
||||
/**
|
||||
* @return The current pathing goal
|
||||
*/
|
||||
Goal getGoal();
|
||||
|
||||
/**
|
||||
* Begins pathing. Calculation will start in a new thread, and once completed,
|
||||
* movement will commence. Returns whether or not the operation was successful.
|
||||
*
|
||||
* @return Whether or not the operation was successful
|
||||
*/
|
||||
boolean path();
|
||||
|
||||
/**
|
||||
* @return Whether or not a path is currently being executed.
|
||||
*/
|
||||
boolean isPathing();
|
||||
|
||||
/**
|
||||
* Cancels the pathing behavior or the current path calculation.
|
||||
* Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path.
|
||||
* <p>
|
||||
* Basically, "MAKE IT STOP".
|
||||
*
|
||||
* @return Whether or not the pathing behavior was canceled. All processes are guaranteed to be canceled, but the
|
||||
* PathingBehavior might be in the middle of an uncancelable action like a parkour jump
|
||||
*/
|
||||
void cancel();
|
||||
boolean cancelEverything();
|
||||
|
||||
/**
|
||||
* Returns the current path, from the current path executor, if there is one.
|
||||
@@ -81,7 +71,7 @@ public interface IPathingBehavior extends IBehavior {
|
||||
/**
|
||||
* @return The current path finder being executed
|
||||
*/
|
||||
Optional<IPathFinder> getPathFinder();
|
||||
Optional<? extends IPathFinder> getInProgress();
|
||||
|
||||
/**
|
||||
* @return The current path executor
|
||||
|
||||
@@ -22,7 +22,7 @@ import net.minecraft.util.math.BlockPos;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/4/2018 2:01 AM
|
||||
* @since 8/4/2018
|
||||
*/
|
||||
public interface IBlockTypeAccess {
|
||||
|
||||
|
||||
@@ -29,21 +29,20 @@ public interface ICachedRegion extends IBlockTypeAccess {
|
||||
* however, the block coordinates should in on a scale from 0 to 511 (inclusive)
|
||||
* because region sizes are 512x512 blocks.
|
||||
*
|
||||
* @see ICachedWorld#isCached(int, int)
|
||||
*
|
||||
* @param blockX The block X coordinate
|
||||
* @param blockZ The block Z coordinate
|
||||
* @return Whether or not the specified XZ location is cached
|
||||
* @see ICachedWorld#isCached(int, int)
|
||||
*/
|
||||
boolean isCached(int blockX, int blockZ);
|
||||
|
||||
/**
|
||||
* The X coordinate of this region
|
||||
* @return The X coordinate of this region
|
||||
*/
|
||||
int getX();
|
||||
|
||||
/**
|
||||
* The Z coordinate of this region
|
||||
* @return The Z coordinate of this region
|
||||
*/
|
||||
int getZ();
|
||||
}
|
||||
|
||||
@@ -61,12 +61,14 @@ public interface ICachedWorld {
|
||||
* information that is returned by this method may not be up to date, because
|
||||
* older cached chunks can contain data that is much more likely to have changed.
|
||||
*
|
||||
* @param block The special block to search for
|
||||
* @param maximum The maximum number of position results to receive
|
||||
* @param block The special block to search for
|
||||
* @param maximum The maximum number of position results to receive
|
||||
* @param centerX The x block coordinate center of the search
|
||||
* @param centerZ The z block coordinate center of the search
|
||||
* @param maxRegionDistanceSq The maximum region distance, squared
|
||||
* @return The locations found that match the special block
|
||||
*/
|
||||
LinkedList<BlockPos> getLocationsOf(String block, int maximum, int maxRegionDistanceSq);
|
||||
LinkedList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq);
|
||||
|
||||
/**
|
||||
* Reloads all of the cached regions in this world from disk. Anything that is not saved
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.behavior;
|
||||
package baritone.api.cache;
|
||||
|
||||
import baritone.api.behavior.memory.IRememberedInventory;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -26,7 +25,7 @@ import java.util.Map;
|
||||
* @author Brady
|
||||
* @since 9/23/2018
|
||||
*/
|
||||
public interface IMemoryBehavior extends IBehavior {
|
||||
public interface IContainerMemory {
|
||||
|
||||
/**
|
||||
* Gets a remembered inventory by its block position.
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.behavior.memory;
|
||||
package baritone.api.cache;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
@@ -50,19 +50,17 @@ public interface IWaypointCollection {
|
||||
/**
|
||||
* Gets all of the waypoints that have the specified tag
|
||||
*
|
||||
* @see IWaypointCollection#getAllWaypoints()
|
||||
*
|
||||
* @param tag The tag
|
||||
* @return All of the waypoints with the specified tag
|
||||
* @see IWaypointCollection#getAllWaypoints()
|
||||
*/
|
||||
Set<IWaypoint> getByTag(IWaypoint.Tag tag);
|
||||
|
||||
/**
|
||||
* Gets all of the waypoints in this collection, regardless of the tag.
|
||||
*
|
||||
* @see IWaypointCollection#getByTag(IWaypoint.Tag)
|
||||
*
|
||||
* @return All of the waypoints in this collection
|
||||
* @see IWaypointCollection#getByTag(IWaypoint.Tag)
|
||||
*/
|
||||
Set<IWaypoint> getAllWaypoints();
|
||||
}
|
||||
|
||||
10
src/api/java/baritone/api/cache/IWorldData.java
vendored
10
src/api/java/baritone/api/cache/IWorldData.java
vendored
@@ -27,13 +27,19 @@ public interface IWorldData {
|
||||
* Returns the cached world for this world. A cached world is a simplified format
|
||||
* of a regular world, intended for use on multiplayer servers where chunks are not
|
||||
* traditionally stored to disk, allowing for long distance pathing with minimal disk usage.
|
||||
*
|
||||
* @return The cached world for this world
|
||||
*/
|
||||
ICachedWorld getCachedWorld();
|
||||
|
||||
/**
|
||||
* Returns the waypoint collection for this world.
|
||||
*
|
||||
* @return The waypoint collection for this world
|
||||
*/
|
||||
IWaypointCollection getWaypoints();
|
||||
|
||||
/**
|
||||
* @return The {@link IContainerMemory} instance
|
||||
* @see IContainerMemory
|
||||
*/
|
||||
IContainerMemory getContainerMemory();
|
||||
}
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
|
||||
package baritone.api.cache;
|
||||
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -31,6 +33,8 @@ public interface IWorldScanner {
|
||||
/**
|
||||
* Scans the world, up to the specified max chunk radius, for the specified blocks.
|
||||
*
|
||||
* @param ctx The {@link IPlayerContext} containing player and world info that the
|
||||
* scan is based upon
|
||||
* @param blocks The blocks to scan for
|
||||
* @param max The maximum number of blocks to scan before cutoff
|
||||
* @param yLevelThreshold If a block is found within this Y level, the current result will be
|
||||
@@ -38,5 +42,19 @@ public interface IWorldScanner {
|
||||
* @param maxSearchRadius The maximum chunk search radius
|
||||
* @return The matching block positions
|
||||
*/
|
||||
List<BlockPos> scanLoadedChunks(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
|
||||
List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
|
||||
|
||||
/**
|
||||
* Scans a single chunk for the specified blocks.
|
||||
*
|
||||
* @param ctx The {@link IPlayerContext} containing player and world info that the
|
||||
* scan is based upon
|
||||
* @param blocks The blocks to scan for
|
||||
* @param pos The position of the target chunk
|
||||
* @param max The maximum number of blocks to scan before cutoff
|
||||
* @param yLevelThreshold If a block is found within this Y level, the current result will be
|
||||
* returned, if the value is negative, then this condition doesn't apply.
|
||||
* @return The matching block positions
|
||||
*/
|
||||
List<BlockPos> scanChunk(IPlayerContext ctx, List<Block> blocks, ChunkPos pos, int max, int yLevelThreshold);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ package baritone.api.event.events;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
/**
|
||||
* Called when the local player interacts with a block, can be either {@link Type#BREAK} or {@link Type#USE}.
|
||||
* Called when the local player interacts with a block, can be either {@link Type#START_BREAK} or {@link Type#USE}.
|
||||
*
|
||||
* @author Brady
|
||||
* @since 8/22/2018
|
||||
@@ -59,9 +59,9 @@ public final class BlockInteractEvent {
|
||||
public enum Type {
|
||||
|
||||
/**
|
||||
* We're breaking the target block.
|
||||
* We're starting to break the target block.
|
||||
*/
|
||||
BREAK,
|
||||
START_BREAK,
|
||||
|
||||
/**
|
||||
* We're right clicking on the target block. Either placing or interacting with.
|
||||
|
||||
@@ -22,7 +22,7 @@ import net.minecraft.client.entity.EntityPlayerSP;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/1/2018 6:39 PM
|
||||
* @since 8/1/2018
|
||||
*/
|
||||
public final class ChatEvent extends ManagedPlayerEvent.Cancellable {
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import baritone.api.event.events.type.EventState;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/2/2018 12:32 AM
|
||||
* @since 8/2/2018
|
||||
*/
|
||||
public final class ChunkEvent {
|
||||
|
||||
@@ -31,7 +31,9 @@ public final class ChunkEvent {
|
||||
private final EventState state;
|
||||
|
||||
/**
|
||||
* The type of chunk event that occurred;
|
||||
* The type of chunk event that occurred
|
||||
*
|
||||
* @see Type
|
||||
*/
|
||||
private final Type type;
|
||||
|
||||
@@ -94,7 +96,16 @@ public final class ChunkEvent {
|
||||
|
||||
/**
|
||||
* When the chunk is being populated with blocks, tile entities, etc.
|
||||
* <p>
|
||||
* And it's a full chunk
|
||||
*/
|
||||
POPULATE
|
||||
POPULATE_FULL,
|
||||
|
||||
/**
|
||||
* When the chunk is being populated with blocks, tile entities, etc.
|
||||
* <p>
|
||||
* And it's a partial chunk
|
||||
*/
|
||||
POPULATE_PARTIAL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import net.minecraft.network.Packet;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/6/2018 9:31 PM
|
||||
* @since 8/6/2018
|
||||
*/
|
||||
public final class PacketEvent {
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ package baritone.api.event.events;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/5/2018 12:28 AM
|
||||
* @since 8/5/2018
|
||||
*/
|
||||
public final class RenderEvent {
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
package baritone.api.event.events;
|
||||
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.api.event.events.type.ManagedPlayerEvent;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -35,21 +34,30 @@ public final class RotationMoveEvent extends ManagedPlayerEvent {
|
||||
private final Type type;
|
||||
|
||||
/**
|
||||
* The state of the event
|
||||
* The yaw rotation
|
||||
*/
|
||||
private final EventState state;
|
||||
private float yaw;
|
||||
|
||||
public RotationMoveEvent(EntityPlayerSP player, EventState state, Type type) {
|
||||
public RotationMoveEvent(EntityPlayerSP player, Type type, float yaw) {
|
||||
super(player);
|
||||
this.state = state;
|
||||
this.type = type;
|
||||
this.yaw = yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The state of the event
|
||||
* Set the yaw movement rotation
|
||||
*
|
||||
* @param yaw Yaw rotation
|
||||
*/
|
||||
public final EventState getState() {
|
||||
return this.state;
|
||||
public final void setYaw(float yaw) {
|
||||
this.yaw = yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The yaw rotation
|
||||
*/
|
||||
public final float getYaw() {
|
||||
return this.yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,7 +22,7 @@ import net.minecraft.client.multiplayer.WorldClient;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/4/2018 3:13 AM
|
||||
* @since 8/4/2018
|
||||
*/
|
||||
public final class WorldEvent {
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ package baritone.api.event.events.type;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/1/2018 6:41 PM
|
||||
* @since 8/1/2018
|
||||
*/
|
||||
public class Cancellable implements ICancellable {
|
||||
|
||||
|
||||
@@ -19,19 +19,17 @@ package baritone.api.event.events.type;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/2/2018 12:34 AM
|
||||
* @since 8/2/2018
|
||||
*/
|
||||
public enum EventState {
|
||||
|
||||
/**
|
||||
* Indicates that whatever movement the event is being
|
||||
* dispatched as a result of is about to occur.
|
||||
* Before the dispatching of what the event is targetting
|
||||
*/
|
||||
PRE,
|
||||
|
||||
/**
|
||||
* Indicates that whatever movement the event is being
|
||||
* dispatched as a result of has already occurred.
|
||||
* After the dispatching of what the event is targetting
|
||||
*/
|
||||
POST
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import baritone.api.event.events.*;
|
||||
*
|
||||
* @author Brady
|
||||
* @see IGameEventListener
|
||||
* @since 8/1/2018 6:29 PM
|
||||
* @since 8/1/2018
|
||||
*/
|
||||
public interface AbstractGameEventListener extends IGameEventListener {
|
||||
|
||||
|
||||
36
src/api/java/baritone/api/event/listener/IEventBus.java
Normal file
36
src/api/java/baritone/api/event/listener/IEventBus.java
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.event.listener;
|
||||
|
||||
/**
|
||||
* A type of {@link IGameEventListener} that can have additional listeners
|
||||
* registered so that they receive the events that are dispatched to this
|
||||
* listener.
|
||||
*
|
||||
* @author Brady
|
||||
* @since 11/14/2018
|
||||
*/
|
||||
public interface IEventBus extends IGameEventListener {
|
||||
|
||||
/**
|
||||
* Registers the specified {@link IGameEventListener} to this event bus
|
||||
*
|
||||
* @param listener The listener
|
||||
*/
|
||||
void registerEventListener(IGameEventListener listener);
|
||||
}
|
||||
@@ -23,23 +23,20 @@ import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.gui.GuiGameOver;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 7/31/2018 11:05 PM
|
||||
* @since 7/31/2018
|
||||
*/
|
||||
public interface IGameEventListener {
|
||||
|
||||
/**
|
||||
* Run once per game tick before screen input is handled.
|
||||
*
|
||||
* @param event The event
|
||||
* @see Minecraft#runTick()
|
||||
*/
|
||||
void onTick(TickEvent event);
|
||||
@@ -47,20 +44,20 @@ public interface IGameEventListener {
|
||||
/**
|
||||
* Run once per game tick from before and after the player rotation is sent to the server.
|
||||
*
|
||||
* @param event The event
|
||||
* @see EntityPlayerSP#onUpdate()
|
||||
*/
|
||||
void onPlayerUpdate(PlayerUpdateEvent event);
|
||||
|
||||
/**
|
||||
* Run once per game tick from before keybinds are processed.
|
||||
*
|
||||
* @see Minecraft#processKeyBinds()
|
||||
*/
|
||||
void onProcessKeyBinds();
|
||||
|
||||
/**
|
||||
* Runs whenever the client player sends a message to the server.
|
||||
*
|
||||
* @param event The event
|
||||
* @see EntityPlayerSP#sendChatMessage(String)
|
||||
*/
|
||||
void onSendChatMessage(ChatEvent event);
|
||||
@@ -68,6 +65,7 @@ public interface IGameEventListener {
|
||||
/**
|
||||
* Runs before and after whenever a chunk is either loaded, unloaded, or populated.
|
||||
*
|
||||
* @param event The event
|
||||
* @see WorldClient#doPreChunk(int, int, boolean)
|
||||
*/
|
||||
void onChunkEvent(ChunkEvent event);
|
||||
@@ -77,13 +75,14 @@ public interface IGameEventListener {
|
||||
* <p>
|
||||
* <b>Note:</b> {@link GameSettings#anaglyph} has been removed in Minecraft 1.13
|
||||
*
|
||||
* @see EntityRenderer#renderWorldPass(int, float, long)
|
||||
* @param event The event
|
||||
*/
|
||||
void onRenderPass(RenderEvent event);
|
||||
|
||||
/**
|
||||
* Runs before and after whenever a new world is loaded
|
||||
*
|
||||
* @param event The event
|
||||
* @see Minecraft#loadWorld(WorldClient, String)
|
||||
*/
|
||||
void onWorldEvent(WorldEvent event);
|
||||
@@ -91,7 +90,7 @@ public interface IGameEventListener {
|
||||
/**
|
||||
* Runs before a outbound packet is sent
|
||||
*
|
||||
* @see NetworkManager#dispatchPacket(Packet, GenericFutureListener[])
|
||||
* @param event The event
|
||||
* @see Packet
|
||||
* @see GenericFutureListener
|
||||
*/
|
||||
@@ -100,7 +99,7 @@ public interface IGameEventListener {
|
||||
/**
|
||||
* Runs before an inbound packet is processed
|
||||
*
|
||||
* @see NetworkManager#dispatchPacket(Packet, GenericFutureListener[])
|
||||
* @param event The event
|
||||
* @see Packet
|
||||
* @see GenericFutureListener
|
||||
*/
|
||||
@@ -110,31 +109,29 @@ public interface IGameEventListener {
|
||||
* Run once per game tick from before and after the player's moveRelative method is called
|
||||
* and before and after the player jumps.
|
||||
*
|
||||
* @param event The event
|
||||
* @see Entity#moveRelative(float, float, float, float)
|
||||
* @see EntityLivingBase#jump()
|
||||
*/
|
||||
void onPlayerRotationMove(RotationMoveEvent event);
|
||||
|
||||
/**
|
||||
* Called when the local player interacts with a block, whether it is breaking or opening/placing.
|
||||
*
|
||||
* @see Minecraft#clickMouse()
|
||||
* @see Minecraft#rightClickMouse()
|
||||
* @param event The event
|
||||
*/
|
||||
void onBlockInteract(BlockInteractEvent event);
|
||||
|
||||
/**
|
||||
* Called when the local player dies, as indicated by the creation of the {@link GuiGameOver} screen.
|
||||
*
|
||||
* @see GuiGameOver(ITextComponent)
|
||||
* @see ITextComponent
|
||||
* @see GuiGameOver
|
||||
*/
|
||||
void onPlayerDeath();
|
||||
|
||||
/**
|
||||
* When the pathfinder's state changes
|
||||
*
|
||||
* @param event
|
||||
* @param event The event
|
||||
*/
|
||||
void onPathEvent(PathEvent event);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.movement.IMovement;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -50,8 +51,12 @@ public interface IPath {
|
||||
/**
|
||||
* This path is actually going to be executed in the world. Do whatever additional processing is required.
|
||||
* (as opposed to Path objects that are just constructed every frame for rendering)
|
||||
*
|
||||
* @return The result of path post processing
|
||||
*/
|
||||
default void postProcess() {}
|
||||
default IPath postProcess() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of positions in this path. Equivalent to {@code positions().size()}.
|
||||
@@ -105,8 +110,9 @@ public interface IPath {
|
||||
default double ticksRemainingFrom(int pathPosition) {
|
||||
double sum = 0;
|
||||
//this is fast because we aren't requesting recalculation, it's just cached
|
||||
for (int i = pathPosition; i < movements().size(); i++) {
|
||||
sum += movements().get(i).getCost();
|
||||
List<IMovement> movements = movements();
|
||||
for (int i = pathPosition; i < movements.size(); i++) {
|
||||
sum += movements.get(i).getCost();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
@@ -114,23 +120,60 @@ public interface IPath {
|
||||
/**
|
||||
* Cuts off this path at the loaded chunk border, and returns the resulting path. Default
|
||||
* implementation just returns this path, without the intended functionality.
|
||||
* <p>
|
||||
* The argument is supposed to be a BlockStateInterface LOL LOL LOL LOL LOL
|
||||
*
|
||||
* @param bsi The block state lookup, highly cursed
|
||||
* @return The result of this cut-off operation
|
||||
*/
|
||||
default IPath cutoffAtLoadedChunks() {
|
||||
return this;
|
||||
default IPath cutoffAtLoadedChunks(Object bsi) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cuts off this path using the min length and cutoff factor settings, and returns the resulting path.
|
||||
* Default implementation just returns this path, without the intended functionality.
|
||||
*
|
||||
* @param destination The end goal of this path
|
||||
* @return The result of this cut-off operation
|
||||
* @see Settings#pathCutoffMinimumLength
|
||||
* @see Settings#pathCutoffFactor
|
||||
*
|
||||
* @return The result of this cut-off operation
|
||||
*/
|
||||
default IPath staticCutoff(Goal destination) {
|
||||
return this;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a series of checks to ensure that the assembly of the path went as expected.
|
||||
*/
|
||||
default void sanityCheck() {
|
||||
List<BetterBlockPos> path = positions();
|
||||
List<IMovement> movements = movements();
|
||||
if (!getSrc().equals(path.get(0))) {
|
||||
throw new IllegalStateException("Start node does not equal first path element");
|
||||
}
|
||||
if (!getDest().equals(path.get(path.size() - 1))) {
|
||||
throw new IllegalStateException("End node does not equal last path element");
|
||||
}
|
||||
if (path.size() != movements.size() + 1) {
|
||||
throw new IllegalStateException("Size of path array is unexpected");
|
||||
}
|
||||
HashSet<BetterBlockPos> seenSoFar = new HashSet<>();
|
||||
for (int i = 0; i < path.size() - 1; i++) {
|
||||
BetterBlockPos src = path.get(i);
|
||||
BetterBlockPos dest = path.get(i + 1);
|
||||
IMovement movement = movements.get(i);
|
||||
if (!src.equals(movement.getSrc())) {
|
||||
throw new IllegalStateException("Path source is not equal to the movement source");
|
||||
}
|
||||
if (!dest.equals(movement.getDest())) {
|
||||
throw new IllegalStateException("Path destination is not equal to the movement destination");
|
||||
}
|
||||
if (seenSoFar.contains(src)) {
|
||||
throw new IllegalStateException("Path doubles back on itself, making a loop");
|
||||
}
|
||||
seenSoFar.add(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package baritone.api.pathing.calc;
|
||||
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.utils.PathCalculationResult;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -33,9 +34,12 @@ public interface IPathFinder {
|
||||
/**
|
||||
* Calculate the path in full. Will take several seconds.
|
||||
*
|
||||
* @param primaryTimeout If a path is found, the path finder will stop after this amount of time
|
||||
* @param failureTimeout If a path isn't found, the path finder will continue for this amount of time
|
||||
*
|
||||
* @return The final path
|
||||
*/
|
||||
Optional<IPath> calculate(long timeout);
|
||||
PathCalculationResult calculate(long primaryTimeout, long failureTimeout);
|
||||
|
||||
/**
|
||||
* Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.pathing.calc;
|
||||
|
||||
import baritone.api.process.IBaritoneProcess;
|
||||
import baritone.api.process.PathingCommand;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface IPathingControlManager {
|
||||
void registerProcess(IBaritoneProcess process);
|
||||
|
||||
Optional<IBaritoneProcess> mostRecentInControl();
|
||||
|
||||
Optional<PathingCommand> mostRecentCommand();
|
||||
}
|
||||
@@ -30,6 +30,10 @@ public interface Goal {
|
||||
* Returns whether or not the specified position
|
||||
* meets the requirement for this goal based.
|
||||
*
|
||||
* @param x The goal X position
|
||||
* @param y The goal Y position
|
||||
* @param z The goal Z position
|
||||
*
|
||||
* @return Whether or not it satisfies this goal
|
||||
*/
|
||||
boolean isInGoal(int x, int y, int z);
|
||||
@@ -37,6 +41,10 @@ public interface Goal {
|
||||
/**
|
||||
* Estimate the number of ticks it will take to get to the goal
|
||||
*
|
||||
* @param x The goal X position
|
||||
* @param y The goal Y position
|
||||
* @param z The goal Z position
|
||||
*
|
||||
* @return The estimate number of ticks to satisfy the goal
|
||||
*/
|
||||
double heuristic(int x, int y, int z);
|
||||
|
||||
@@ -17,10 +17,7 @@
|
||||
|
||||
package baritone.api.pathing.goals;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A composite of many goals, any one of which satisfies the composite.
|
||||
@@ -40,14 +37,6 @@ public class GoalComposite implements Goal {
|
||||
this.goals = goals;
|
||||
}
|
||||
|
||||
public GoalComposite(BlockPos... blocks) {
|
||||
this(Arrays.asList(blocks));
|
||||
}
|
||||
|
||||
public GoalComposite(Collection<BlockPos> blocks) {
|
||||
this(blocks.stream().map(GoalBlock::new).toArray(Goal[]::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGoal(int x, int y, int z) {
|
||||
for (Goal goal : goals) {
|
||||
|
||||
@@ -48,10 +48,7 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
|
||||
int xDiff = x - this.x;
|
||||
int yDiff = y - this.y;
|
||||
int zDiff = z - this.z;
|
||||
if (yDiff < 0) {
|
||||
yDiff++;
|
||||
}
|
||||
return Math.abs(xDiff) + Math.abs(yDiff) + Math.abs(zDiff) <= 1;
|
||||
return Math.abs(xDiff) + Math.abs(yDiff < 0 ? yDiff + 1 : yDiff) + Math.abs(zDiff) <= 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,7 +56,7 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
|
||||
int xDiff = x - this.x;
|
||||
int yDiff = y - this.y;
|
||||
int zDiff = z - this.z;
|
||||
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
||||
return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,16 +32,26 @@ public class GoalRunAway implements Goal {
|
||||
|
||||
private final double distanceSq;
|
||||
|
||||
private final Integer maintainY;
|
||||
|
||||
public GoalRunAway(double distance, BlockPos... from) {
|
||||
this(distance, null, from);
|
||||
}
|
||||
|
||||
public GoalRunAway(double distance, Integer maintainY, BlockPos... from) {
|
||||
if (from.length == 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.from = from;
|
||||
this.distanceSq = distance * distance;
|
||||
this.maintainY = maintainY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInGoal(int x, int y, int z) {
|
||||
if (maintainY != null && maintainY != y) {
|
||||
return false;
|
||||
}
|
||||
for (BlockPos p : from) {
|
||||
int diffX = x - p.getX();
|
||||
int diffZ = z - p.getZ();
|
||||
@@ -62,11 +72,19 @@ public class GoalRunAway implements Goal {
|
||||
min = h;
|
||||
}
|
||||
}
|
||||
return -min;
|
||||
min = -min;
|
||||
if (maintainY != null) {
|
||||
min = min * 0.6 + GoalYLevel.calculate(maintainY, y) * 1.5;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GoalRunAwayFrom" + Arrays.asList(from);
|
||||
if (maintainY != null) {
|
||||
return "GoalRunAwayFromMaintainY y=" + maintainY + ", " + Arrays.asList(from);
|
||||
} else {
|
||||
return "GoalRunAwayFrom" + Arrays.asList(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,10 +63,7 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
|
||||
int xDiff = x - this.x;
|
||||
int yDiff = y - this.y;
|
||||
int zDiff = z - this.z;
|
||||
if (yDiff < 0) {
|
||||
yDiff++;
|
||||
}
|
||||
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
||||
return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,8 +20,6 @@ package baritone.api.pathing.movement;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 10/8/2018
|
||||
@@ -58,10 +56,4 @@ public interface IMovement {
|
||||
BetterBlockPos getDest();
|
||||
|
||||
BlockPos getDirection();
|
||||
|
||||
List<BlockPos> toBreak();
|
||||
|
||||
List<BlockPos> toPlace();
|
||||
|
||||
List<BlockPos> toWalkInto();
|
||||
}
|
||||
|
||||
99
src/api/java/baritone/api/process/IBaritoneProcess.java
Normal file
99
src/api/java/baritone/api/process/IBaritoneProcess.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.process;
|
||||
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.behavior.IPathingBehavior;
|
||||
import baritone.api.event.events.PathEvent;
|
||||
|
||||
/**
|
||||
* A process that can control the PathingBehavior.
|
||||
* <p>
|
||||
* Differences between a baritone process and a behavior:
|
||||
* Only one baritone process can be active at a time
|
||||
* PathingBehavior can only be controlled by a process
|
||||
* <p>
|
||||
* That's it actually
|
||||
*
|
||||
* @author leijurv
|
||||
*/
|
||||
public interface IBaritoneProcess {
|
||||
|
||||
/**
|
||||
* Would this process like to be in control?
|
||||
*
|
||||
* @return Whether or not this process would like to be in contorl.
|
||||
*/
|
||||
boolean isActive();
|
||||
|
||||
/**
|
||||
* Called when this process is in control of pathing; Returns what Baritone should do.
|
||||
*
|
||||
* @param calcFailed {@code true} if this specific process was in control last tick,
|
||||
* and there was a {@link PathEvent#CALC_FAILED} event last tick
|
||||
* @param isSafeToCancel {@code true} if a {@link PathingCommandType#REQUEST_PAUSE} would happen this tick, and
|
||||
* {@link IPathingBehavior} wouldn't actually tick. {@code false} if the PathExecutor reported
|
||||
* pausing would be unsafe at the end of the last tick. Effectively "could request cancel or
|
||||
* pause and have it happen right away"
|
||||
* @return What the {@link IPathingBehavior} should do
|
||||
*/
|
||||
PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel);
|
||||
|
||||
/**
|
||||
* Returns whether or not this process should be treated as "temporary".
|
||||
* <p>
|
||||
* If a process is temporary, it doesn't call {@link #onLostControl} on the processes that aren't execute because of it.
|
||||
* <p>
|
||||
* For example, {@code CombatPauserProcess} and {@code PauseForAutoEatProcess} should return {@code true} always,
|
||||
* and should return {@link #isActive} {@code true} only if there's something in range this tick, or if the player would like
|
||||
* to start eating this tick. {@code PauseForAutoEatProcess} should only actually right click once onTick is called with
|
||||
* {@code isSafeToCancel} true though.
|
||||
*
|
||||
* @return Whethor or not if this control is temporary
|
||||
*/
|
||||
boolean isTemporary();
|
||||
|
||||
/**
|
||||
* Called if {@link #isActive} returned {@code true}, but another non-temporary
|
||||
* process has control. Effectively the same as cancel. You want control but you
|
||||
* don't get it.
|
||||
*/
|
||||
void onLostControl();
|
||||
|
||||
/**
|
||||
* Used to determine which Process gains control if multiple are reporting {@link #isActive()}. The one
|
||||
* that returns the highest value will be given control.
|
||||
*
|
||||
* @return A double representing the priority
|
||||
*/
|
||||
double priority();
|
||||
|
||||
/**
|
||||
* Returns which bot this process is associated with. (5000000iq forward thinking)
|
||||
*
|
||||
* @return The Bot associated with this process
|
||||
*/
|
||||
IBaritone associatedWith();
|
||||
|
||||
/**
|
||||
* Returns a user-friendly name for this process. Suitable for a HUD.
|
||||
*
|
||||
* @return A display name that's suitable for a HUD
|
||||
*/
|
||||
String displayName();
|
||||
}
|
||||
@@ -15,40 +15,36 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils.interfaces;
|
||||
package baritone.api.process;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/20/2018
|
||||
*/
|
||||
public interface Toggleable {
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
|
||||
public interface ICustomGoalProcess extends IBaritoneProcess {
|
||||
|
||||
/**
|
||||
* Toggles the enabled state of this {@link Toggleable}.
|
||||
* Sets the pathing goal
|
||||
*
|
||||
* @return The new state.
|
||||
* @param goal The new goal
|
||||
*/
|
||||
boolean toggle();
|
||||
void setGoal(Goal goal);
|
||||
|
||||
/**
|
||||
* Sets the enabled state of this {@link Toggleable}.
|
||||
* Starts path calculation and execution.
|
||||
*/
|
||||
void path();
|
||||
|
||||
/**
|
||||
* @return The current goal
|
||||
*/
|
||||
Goal getGoal();
|
||||
|
||||
/**
|
||||
* Sets the goal and begins the path execution.
|
||||
*
|
||||
* @return The new state.
|
||||
* @param goal The new goal
|
||||
*/
|
||||
boolean setEnabled(boolean enabled);
|
||||
|
||||
/**
|
||||
* @return Whether or not this {@link Toggleable} object is enabled
|
||||
*/
|
||||
boolean isEnabled();
|
||||
|
||||
/**
|
||||
* Called when the state changes from disabled to enabled
|
||||
*/
|
||||
default void onEnable() {}
|
||||
|
||||
/**
|
||||
* Called when the state changes from enabled to disabled
|
||||
*/
|
||||
default void onDisable() {}
|
||||
default void setGoalAndPath(Goal goal) {
|
||||
this.setGoal(goal);
|
||||
this.path();
|
||||
}
|
||||
}
|
||||
@@ -15,30 +15,37 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.behavior;
|
||||
package baritone.api.process;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/23/2018
|
||||
*/
|
||||
public interface IFollowBehavior extends IBehavior {
|
||||
public interface IFollowProcess extends IBaritoneProcess {
|
||||
|
||||
/**
|
||||
* Set the follow target to the specified entity;
|
||||
* Set the follow target to any entities matching this predicate
|
||||
*
|
||||
* @param entity The entity to follow
|
||||
* @param filter the predicate
|
||||
*/
|
||||
void follow(Entity entity);
|
||||
void follow(Predicate<Entity> filter);
|
||||
|
||||
/**
|
||||
* @return The entity that is currently being followed
|
||||
* @return The entities that are currently being followed. null if not currently following, empty if nothing matches the predicate
|
||||
*/
|
||||
Entity following();
|
||||
List<Entity> following();
|
||||
|
||||
Predicate<Entity> currentFilter();
|
||||
|
||||
/**
|
||||
* Cancels the follow behavior, this will clear the current follow target.
|
||||
*/
|
||||
void cancel();
|
||||
default void cancel() {
|
||||
onLostControl();
|
||||
}
|
||||
}
|
||||
@@ -15,20 +15,14 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch;
|
||||
package baritone.api.process;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 7/31/2018 10:10 PM
|
||||
* but it rescans the world every once in a while so it doesn't get fooled by its cache
|
||||
*/
|
||||
public class BaritoneTweakerOptifine extends BaritoneTweaker {
|
||||
public interface IGetToBlockProcess extends IBaritoneProcess {
|
||||
|
||||
@Override
|
||||
public final void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
|
||||
this.args = new ArrayList<>();
|
||||
}
|
||||
void getToBlock(Block block);
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.behavior;
|
||||
package baritone.api.process;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
@@ -23,7 +23,7 @@ import net.minecraft.block.Block;
|
||||
* @author Brady
|
||||
* @since 9/23/2018
|
||||
*/
|
||||
public interface IMineBehavior extends IBehavior {
|
||||
public interface IMineProcess extends IBaritoneProcess {
|
||||
|
||||
/**
|
||||
* Begin to search for and mine the specified blocks until
|
||||
@@ -31,9 +31,9 @@ public interface IMineBehavior extends IBehavior {
|
||||
* are mined. This is based on the first target block to mine.
|
||||
*
|
||||
* @param quantity The number of items to get from blocks mined
|
||||
* @param blocks The blocks to mine
|
||||
* @param blocks The blocks to mine
|
||||
*/
|
||||
void mine(int quantity, String... blocks);
|
||||
void mineByName(int quantity, String... blocks);
|
||||
|
||||
/**
|
||||
* Begin to search for and mine the specified blocks until
|
||||
@@ -41,7 +41,7 @@ public interface IMineBehavior extends IBehavior {
|
||||
* are mined. This is based on the first target block to mine.
|
||||
*
|
||||
* @param quantity The number of items to get from blocks mined
|
||||
* @param blocks The blocks to mine
|
||||
* @param blocks The blocks to mine
|
||||
*/
|
||||
void mine(int quantity, Block... blocks);
|
||||
|
||||
@@ -50,8 +50,8 @@ public interface IMineBehavior extends IBehavior {
|
||||
*
|
||||
* @param blocks The blocks to mine
|
||||
*/
|
||||
default void mine(String... blocks) {
|
||||
this.mine(0, blocks);
|
||||
default void mineByName(String... blocks) {
|
||||
mineByName(0, blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,11 +60,13 @@ public interface IMineBehavior extends IBehavior {
|
||||
* @param blocks The blocks to mine
|
||||
*/
|
||||
default void mine(Block... blocks) {
|
||||
this.mine(0, blocks);
|
||||
mine(0, blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the current mining task
|
||||
*/
|
||||
void cancel();
|
||||
default void cancel() {
|
||||
onLostControl();
|
||||
}
|
||||
}
|
||||
56
src/api/java/baritone/api/process/PathingCommand.java
Normal file
56
src/api/java/baritone/api/process/PathingCommand.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.process;
|
||||
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author leijurv
|
||||
*/
|
||||
public class PathingCommand {
|
||||
|
||||
/**
|
||||
* The target goal, may be {@code null}.
|
||||
*/
|
||||
public final Goal goal;
|
||||
|
||||
/**
|
||||
* The command type.
|
||||
*
|
||||
* @see PathingCommandType
|
||||
*/
|
||||
public final PathingCommandType commandType;
|
||||
|
||||
/**
|
||||
* Create a new {@link PathingCommand}.
|
||||
*
|
||||
* @param goal The target goal, may be {@code null}.
|
||||
* @param commandType The command type, cannot be {@code null}.
|
||||
* @throws NullPointerException if {@code commandType} is {@code null}.
|
||||
* @see Goal
|
||||
* @see PathingCommandType
|
||||
*/
|
||||
public PathingCommand(Goal goal, PathingCommandType commandType) {
|
||||
Objects.requireNonNull(commandType);
|
||||
|
||||
this.goal = goal;
|
||||
this.commandType = commandType;
|
||||
}
|
||||
}
|
||||
55
src/api/java/baritone/api/process/PathingCommandType.java
Normal file
55
src/api/java/baritone/api/process/PathingCommandType.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.process;
|
||||
|
||||
import baritone.api.Settings;
|
||||
|
||||
public enum PathingCommandType {
|
||||
|
||||
/**
|
||||
* Set the goal and path.
|
||||
* <p>
|
||||
* If you use this alongside a {@code null} goal, it will continue along its current path and current goal.
|
||||
*/
|
||||
SET_GOAL_AND_PATH,
|
||||
|
||||
/**
|
||||
* Has no effect on the current goal or path, just requests a pause
|
||||
*/
|
||||
REQUEST_PAUSE,
|
||||
|
||||
/**
|
||||
* Set the goal (regardless of {@code null}), and request a cancel of the current path (when safe)
|
||||
*/
|
||||
CANCEL_AND_SET_GOAL,
|
||||
|
||||
/**
|
||||
* Set the goal and path.
|
||||
* <p>
|
||||
* If {@link Settings#cancelOnGoalInvalidation} is {@code true}, revalidate the
|
||||
* current goal, and cancel if it's no longer valid, or if the new goal is {@code null}.
|
||||
*/
|
||||
REVALIDATE_GOAL_AND_PATH,
|
||||
|
||||
/**
|
||||
* Set the goal and path.
|
||||
* <p>
|
||||
* Cancel the current path if the goals are not equal
|
||||
*/
|
||||
FORCE_REVALIDATE_GOAL_AND_PATH
|
||||
}
|
||||
39
src/api/java/baritone/api/utils/IInputOverrideHandler.java
Normal file
39
src/api/java/baritone/api/utils/IInputOverrideHandler.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.api.behavior.IBehavior;
|
||||
import baritone.api.utils.input.Input;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 11/12/2018
|
||||
*/
|
||||
public interface IInputOverrideHandler extends IBehavior {
|
||||
|
||||
default boolean isInputForcedDown(KeyBinding key) {
|
||||
return isInputForcedDown(Input.getInputForBind(key));
|
||||
}
|
||||
|
||||
boolean isInputForcedDown(Input input);
|
||||
|
||||
void setInputForceState(Input input, boolean forced);
|
||||
|
||||
void clearAllKeys();
|
||||
}
|
||||
92
src/api/java/baritone/api/utils/IPlayerContext.java
Normal file
92
src/api/java/baritone/api/utils/IPlayerContext.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.api.utils;
|
||||
|
||||
import baritone.api.cache.IWorldData;
|
||||
import net.minecraft.block.BlockSlab;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.multiplayer.PlayerControllerMP;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 11/12/2018
|
||||
*/
|
||||
public interface IPlayerContext {
|
||||
|
||||
EntityPlayerSP player();
|
||||
|
||||
PlayerControllerMP playerController();
|
||||
|
||||
World world();
|
||||
|
||||
IWorldData worldData();
|
||||
|
||||
RayTraceResult objectMouseOver();
|
||||
|
||||
default BetterBlockPos playerFeet() {
|
||||
// TODO find a better way to deal with soul sand!!!!!
|
||||
BetterBlockPos feet = new BetterBlockPos(player().posX, player().posY + 0.1251, player().posZ);
|
||||
if (world().getBlockState(feet).getBlock() instanceof BlockSlab) {
|
||||
return feet.up();
|
||||
}
|
||||
return feet;
|
||||
}
|
||||
|
||||
default Vec3d playerFeetAsVec() {
|
||||
return new Vec3d(player().posX, player().posY, player().posZ);
|
||||
}
|
||||
|
||||
default Vec3d playerHead() {
|
||||
return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ);
|
||||
}
|
||||
|
||||
default Rotation playerRotations() {
|
||||
return new Rotation(player().rotationYaw, player().rotationPitch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block that the crosshair is currently placed over. Updated once per tick.
|
||||
*
|
||||
* @return The position of the highlighted block
|
||||
*/
|
||||
default Optional<BlockPos> getSelectedBlock() {
|
||||
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
return Optional.of(objectMouseOver().getBlockPos());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entity that the crosshair is currently placed over. Updated once per tick.
|
||||
*
|
||||
* @return The entity
|
||||
*/
|
||||
default Optional<Entity> getSelectedEntity() {
|
||||
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.ENTITY) {
|
||||
return Optional.of(objectMouseOver().entityHit);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
56
src/api/java/baritone/api/utils/PathCalculationResult.java
Normal file
56
src/api/java/baritone/api/utils/PathCalculationResult.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.api.pathing.calc.IPath;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class PathCalculationResult {
|
||||
|
||||
private final IPath path;
|
||||
private final Type type;
|
||||
|
||||
public PathCalculationResult(Type type) {
|
||||
this(type, null);
|
||||
}
|
||||
|
||||
public PathCalculationResult(Type type, IPath path) {
|
||||
this.path = path;
|
||||
this.type = type;
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("come on");
|
||||
}
|
||||
}
|
||||
|
||||
public final Optional<IPath> getPath() {
|
||||
return Optional.ofNullable(this.path);
|
||||
}
|
||||
|
||||
public final Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
SUCCESS_TO_GOAL,
|
||||
SUCCESS_SEGMENT,
|
||||
FAILURE,
|
||||
CANCELLATION,
|
||||
EXCEPTION,
|
||||
}
|
||||
}
|
||||
52
src/api/java/baritone/api/utils/RayTraceUtils.java
Normal file
52
src/api/java/baritone/api/utils/RayTraceUtils.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/25/2018
|
||||
*/
|
||||
public final class RayTraceUtils {
|
||||
|
||||
private RayTraceUtils() {}
|
||||
|
||||
/**
|
||||
* Performs a block raytrace with the specified rotations. This should only be used when
|
||||
* any entity collisions can be ignored, because this method will not recognize if an
|
||||
* entity is in the way or not. The local player's block reach distance will be used.
|
||||
*
|
||||
* @param entity The entity representing the raytrace source
|
||||
* @param rotation The rotation to raytrace towards
|
||||
* @param blockReachDistance The block reach distance of the entity
|
||||
* @return The calculated raytrace result
|
||||
*/
|
||||
public static RayTraceResult rayTraceTowards(Entity entity, Rotation rotation, double blockReachDistance) {
|
||||
Vec3d start = entity.getPositionEyes(1.0F);
|
||||
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
|
||||
Vec3d end = start.add(
|
||||
direction.x * blockReachDistance,
|
||||
direction.y * blockReachDistance,
|
||||
direction.z * blockReachDistance
|
||||
);
|
||||
return entity.world.rayTraceBlocks(start, end, false, false, true);
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ public class Rotation {
|
||||
public Rotation clamp() {
|
||||
return new Rotation(
|
||||
this.yaw,
|
||||
RotationUtils.clampPitch(this.pitch)
|
||||
clampPitch(this.pitch)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public class Rotation {
|
||||
*/
|
||||
public Rotation normalize() {
|
||||
return new Rotation(
|
||||
RotationUtils.normalizeYaw(this.yaw),
|
||||
normalizeYaw(this.yaw),
|
||||
this.pitch
|
||||
);
|
||||
}
|
||||
@@ -105,8 +105,46 @@ public class Rotation {
|
||||
*/
|
||||
public Rotation normalizeAndClamp() {
|
||||
return new Rotation(
|
||||
RotationUtils.normalizeYaw(this.yaw),
|
||||
RotationUtils.clampPitch(this.pitch)
|
||||
normalizeYaw(this.yaw),
|
||||
clampPitch(this.pitch)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is really close to
|
||||
*
|
||||
* @param other another rotation
|
||||
* @return are they really close
|
||||
*/
|
||||
public boolean isReallyCloseTo(Rotation other) {
|
||||
float yawDiff = Math.abs(this.yaw - other.yaw); // you cant fool me
|
||||
return (yawDiff < 0.01 || yawDiff > 359.9) && Math.abs(this.pitch - other.pitch) < 0.01;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamps the specified pitch value between -90 and 90.
|
||||
*
|
||||
* @param pitch The input pitch
|
||||
* @return The clamped pitch
|
||||
*/
|
||||
public static float clampPitch(float pitch) {
|
||||
return Math.max(-90, Math.min(90, pitch));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the specified yaw value between -180 and 180.
|
||||
*
|
||||
* @param yaw The input yaw
|
||||
* @return The normalized yaw
|
||||
*/
|
||||
public static float normalizeYaw(float yaw) {
|
||||
float newYaw = yaw % 360F;
|
||||
if (newYaw < -180F) {
|
||||
newYaw += 360F;
|
||||
}
|
||||
if (newYaw > 180F) {
|
||||
newYaw -= 360F;
|
||||
}
|
||||
return newYaw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,38 +17,199 @@
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import net.minecraft.block.BlockFire;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.*;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/25/2018
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Offsets from the root block position to the center of each side.
|
||||
*/
|
||||
private static final Vec3d[] BLOCK_SIDE_MULTIPLIERS = new Vec3d[]{
|
||||
new Vec3d(0.5, 0, 0.5), // Down
|
||||
new Vec3d(0.5, 1, 0.5), // Up
|
||||
new Vec3d(0.5, 0.5, 0), // North
|
||||
new Vec3d(0.5, 0.5, 1), // South
|
||||
new Vec3d(0, 0.5, 0.5), // West
|
||||
new Vec3d(1, 0.5, 0.5) // East
|
||||
};
|
||||
|
||||
private RotationUtils() {}
|
||||
|
||||
/**
|
||||
* Clamps the specified pitch value between -90 and 90.
|
||||
* Calculates the rotation from BlockPos<sub>dest</sub> to BlockPos<sub>orig</sub>
|
||||
*
|
||||
* @param pitch The input pitch
|
||||
* @return The clamped pitch
|
||||
* @param orig The origin position
|
||||
* @param dest The destination position
|
||||
* @return The rotation from the origin to the destination
|
||||
*/
|
||||
public static float clampPitch(float pitch) {
|
||||
return Math.max(-90, Math.min(90, pitch));
|
||||
public static Rotation calcRotationFromCoords(BlockPos orig, BlockPos dest) {
|
||||
return calcRotationFromVec3d(new Vec3d(orig), new Vec3d(dest));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the specified yaw value between -180 and 180.
|
||||
* Wraps the target angles to a relative value from the current angles. This is done by
|
||||
* subtracting the current from the target, normalizing it, and then adding the current
|
||||
* angles back to it.
|
||||
*
|
||||
* @param yaw The input yaw
|
||||
* @return The normalized yaw
|
||||
* @param current The current angles
|
||||
* @param target The target angles
|
||||
* @return The wrapped angles
|
||||
*/
|
||||
public static float normalizeYaw(float yaw) {
|
||||
float newYaw = yaw % 360F;
|
||||
if (newYaw < -180F) {
|
||||
newYaw += 360F;
|
||||
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
|
||||
return target.subtract(current).normalize().add(current);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the rotation from Vec<sub>dest</sub> to Vec<sub>orig</sub> and makes the
|
||||
* return value relative to the specified current rotations.
|
||||
*
|
||||
* @param orig The origin position
|
||||
* @param dest The destination position
|
||||
* @param current The current rotations
|
||||
* @return The rotation from the origin to the destination
|
||||
* @see #wrapAnglesToRelative(Rotation, Rotation)
|
||||
*/
|
||||
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest, Rotation current) {
|
||||
return wrapAnglesToRelative(current, calcRotationFromVec3d(orig, dest));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the rotation from Vec<sub>dest</sub> to Vec<sub>orig</sub>
|
||||
*
|
||||
* @param orig The origin position
|
||||
* @param dest The destination position
|
||||
* @return The rotation from the origin to the destination
|
||||
*/
|
||||
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
|
||||
double[] delta = {orig.x - dest.x, orig.y - dest.y, orig.z - dest.z};
|
||||
double yaw = MathHelper.atan2(delta[0], -delta[2]);
|
||||
double dist = Math.sqrt(delta[0] * delta[0] + delta[2] * delta[2]);
|
||||
double pitch = MathHelper.atan2(delta[1], dist);
|
||||
return new Rotation(
|
||||
(float) (yaw * RAD_TO_DEG),
|
||||
(float) (pitch * RAD_TO_DEG)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the look vector for the specified yaw/pitch rotations.
|
||||
*
|
||||
* @param rotation The input rotation
|
||||
* @return Look vector for the rotation
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the specified entity is able to reach the center of any of the sides
|
||||
* of the specified block. It first checks if the block center is reachable, and if so,
|
||||
* that rotation will be returned. If not, it will return the first center of a given
|
||||
* side that is reachable. The return type will be {@link Optional#empty()} if the entity is
|
||||
* unable to reach any of the sides of the block.
|
||||
*
|
||||
* @param entity The viewing entity
|
||||
* @param pos The target block position
|
||||
* @param blockReachDistance The block reach distance of the entity
|
||||
* @return The optional rotation
|
||||
*/
|
||||
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
|
||||
if (pos.equals(baritone.getPlayerContext().getSelectedBlock().orElse(null))) {
|
||||
/*
|
||||
* why add 0.0001?
|
||||
* to indicate that we actually have a desired pitch
|
||||
* the way we indicate that the pitch can be whatever and we only care about the yaw
|
||||
* is by setting the desired pitch to the current pitch
|
||||
* setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's
|
||||
* just what it currently is
|
||||
*
|
||||
* or if you're a normal person literally all this does it ensure that we don't nudge the pitch to a normal level
|
||||
*/
|
||||
return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F));
|
||||
}
|
||||
if (newYaw >= 180F) {
|
||||
newYaw -= 360F;
|
||||
Optional<Rotation> possibleRotation = reachableCenter(entity, pos, blockReachDistance);
|
||||
//System.out.println("center: " + possibleRotation);
|
||||
if (possibleRotation.isPresent()) {
|
||||
return possibleRotation;
|
||||
}
|
||||
return newYaw;
|
||||
|
||||
IBlockState state = entity.world.getBlockState(pos);
|
||||
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
|
||||
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
|
||||
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
|
||||
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
|
||||
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
|
||||
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance);
|
||||
if (possibleRotation.isPresent()) {
|
||||
return possibleRotation;
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the specified entity is able to reach the specified block with
|
||||
* the given offsetted position. The return type will be {@link Optional#empty()} if
|
||||
* the entity is unable to reach the block with the offset applied.
|
||||
*
|
||||
* @param entity The viewing entity
|
||||
* @param pos The target block position
|
||||
* @param offsetPos The position of the block with the offset applied.
|
||||
* @param blockReachDistance The block reach distance of the entity
|
||||
* @return The optional rotation
|
||||
*/
|
||||
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
|
||||
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos);
|
||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
|
||||
//System.out.println(result);
|
||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
if (result.getBlockPos().equals(pos)) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
if (entity.world.getBlockState(pos).getBlock() instanceof BlockFire && result.getBlockPos().equals(pos.down())) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the specified entity is able to reach the specified block where it is
|
||||
* looking at the direct center of it's hitbox.
|
||||
*
|
||||
* @param entity The viewing entity
|
||||
* @param pos The target block position
|
||||
* @param blockReachDistance The block reach distance of the entity
|
||||
* @return The optional rotation
|
||||
*/
|
||||
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos, double blockReachDistance) {
|
||||
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.world, pos), blockReachDistance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SettingsUtil {
|
||||
|
||||
private static final File settingsFile = new File(new File(Minecraft.getMinecraft().gameDir, "baritone"), "settings.txt");
|
||||
|
||||
private static final Map<Class<?>, SettingsIO> map;
|
||||
|
||||
116
src/api/java/baritone/api/utils/VecUtils.java
Normal file
116
src/api/java/baritone/api/utils/VecUtils.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.block.BlockFire;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 10/13/2018
|
||||
*/
|
||||
public final class VecUtils {
|
||||
|
||||
private VecUtils() {}
|
||||
|
||||
/**
|
||||
* Calculates the center of the block at the specified position's bounding box
|
||||
*
|
||||
* @param world The world that the block is in, used to provide the bounding box
|
||||
* @param pos The block position
|
||||
* @return The center of the block's bounding box
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*/
|
||||
public static Vec3d calculateBlockCenter(World world, BlockPos pos) {
|
||||
IBlockState b = world.getBlockState(pos);
|
||||
AxisAlignedBB bbox = b.getBoundingBox(world, pos);
|
||||
double xDiff = (bbox.minX + bbox.maxX) / 2;
|
||||
double yDiff = (bbox.minY + bbox.maxY) / 2;
|
||||
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
|
||||
if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
|
||||
yDiff = 0;
|
||||
}
|
||||
return new Vec3d(
|
||||
pos.getX() + xDiff,
|
||||
pos.getY() + yDiff,
|
||||
pos.getZ() + zDiff
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the assumed center position of the given block position.
|
||||
* This is done by adding 0.5 to the X, Y, and Z axes.
|
||||
* <p>
|
||||
* TODO: We may want to consider replacing many usages of this method with #calculateBlockCenter(BlockPos)
|
||||
*
|
||||
* @param pos The block position
|
||||
* @return The assumed center of the position
|
||||
* @see #calculateBlockCenter(World, BlockPos)
|
||||
*/
|
||||
public static Vec3d getBlockPosCenter(BlockPos pos) {
|
||||
return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the distance from the specified position to the assumed center of the specified block position.
|
||||
*
|
||||
* @param pos The block position
|
||||
* @param x The x pos
|
||||
* @param y The y pos
|
||||
* @param z The z pos
|
||||
* @return The distance from the assumed block center to the position
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*/
|
||||
public static double distanceToCenter(BlockPos pos, double x, double y, double z) {
|
||||
double xdiff = pos.getX() + 0.5 - x;
|
||||
double ydiff = pos.getY() + 0.5 - y;
|
||||
double zdiff = pos.getZ() + 0.5 - z;
|
||||
return Math.sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the distance from the specified entity's position to the assumed
|
||||
* center of the specified block position.
|
||||
*
|
||||
* @param entity The entity
|
||||
* @param pos The block position
|
||||
* @return The distance from the entity to the block's assumed center
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*/
|
||||
public static double entityDistanceToCenter(Entity entity, BlockPos pos) {
|
||||
return distanceToCenter(pos, entity.posX, entity.posY, entity.posZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the distance from the specified entity's position to the assumed
|
||||
* center of the specified block position, ignoring the Y axis.
|
||||
*
|
||||
* @param entity The entity
|
||||
* @param pos The block position
|
||||
* @return The horizontal distance from the entity to the block's assumed center
|
||||
* @see #getBlockPosCenter(BlockPos)
|
||||
*/
|
||||
public static double entityFlatDistanceToCenter(Entity entity, BlockPos pos) {
|
||||
return distanceToCenter(pos, entity.posX, pos.getY() + 0.5, entity.posZ);
|
||||
}
|
||||
}
|
||||
119
src/api/java/baritone/api/utils/input/Input.java
Normal file
119
src/api/java/baritone/api/utils/input/Input.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.api.utils.input;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* An {@link Enum} representing the inputs that control the player's
|
||||
* behavior. This includes moving, interacting with blocks, jumping,
|
||||
* sneaking, and sprinting.
|
||||
*/
|
||||
public enum Input {
|
||||
|
||||
/**
|
||||
* The move forward input
|
||||
*/
|
||||
MOVE_FORWARD(s -> s.keyBindForward),
|
||||
|
||||
/**
|
||||
* The move back input
|
||||
*/
|
||||
MOVE_BACK(s -> s.keyBindBack),
|
||||
|
||||
/**
|
||||
* The move left input
|
||||
*/
|
||||
MOVE_LEFT(s -> s.keyBindLeft),
|
||||
|
||||
/**
|
||||
* The move right input
|
||||
*/
|
||||
MOVE_RIGHT(s -> s.keyBindRight),
|
||||
|
||||
/**
|
||||
* The attack input
|
||||
*/
|
||||
CLICK_LEFT(s -> s.keyBindAttack),
|
||||
|
||||
/**
|
||||
* The use item input
|
||||
*/
|
||||
CLICK_RIGHT(s -> s.keyBindUseItem),
|
||||
|
||||
/**
|
||||
* The jump input
|
||||
*/
|
||||
JUMP(s -> s.keyBindJump),
|
||||
|
||||
/**
|
||||
* The sneak input
|
||||
*/
|
||||
SNEAK(s -> s.keyBindSneak),
|
||||
|
||||
/**
|
||||
* The sprint input
|
||||
*/
|
||||
SPRINT(s -> s.keyBindSprint);
|
||||
|
||||
/**
|
||||
* Map of {@link KeyBinding} to {@link Input}. Values should be queried through {@link #getInputForBind(KeyBinding)}
|
||||
*/
|
||||
private static final Map<KeyBinding, Input> bindToInputMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The actual game {@link KeyBinding} being forced.
|
||||
*/
|
||||
private final KeyBinding keyBinding;
|
||||
|
||||
Input(Function<GameSettings, KeyBinding> keyBindingMapper) {
|
||||
/*
|
||||
|
||||
Here, a Function is used because referring to a static field in this enum for the game instance,
|
||||
as it was before, wouldn't be possible in an Enum constructor unless the static field was in an
|
||||
interface that this class implemented. (Helper acted as this interface) I didn't feel like making
|
||||
an interface with a game instance field just to not have to do this.
|
||||
|
||||
*/
|
||||
this.keyBinding = keyBindingMapper.apply(Minecraft.getMinecraft().gameSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The actual game {@link KeyBinding} being forced.
|
||||
*/
|
||||
public final KeyBinding getKeyBinding() {
|
||||
return this.keyBinding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the {@link Input} constant that is associated with the specified {@link KeyBinding}.
|
||||
*
|
||||
* @param binding The {@link KeyBinding} to find the associated {@link Input} for
|
||||
* @return The {@link Input} associated with the specified {@link KeyBinding}
|
||||
*/
|
||||
public static Input getInputForBind(KeyBinding binding) {
|
||||
return bindToInputMap.computeIfAbsent(binding, b -> Arrays.stream(values()).filter(input -> input.keyBinding == b).findFirst().orElse(null));
|
||||
}
|
||||
}
|
||||
@@ -17,61 +17,39 @@
|
||||
|
||||
package baritone.launch;
|
||||
|
||||
import net.minecraft.launchwrapper.ITweaker;
|
||||
import io.github.impactdevelopment.simpletweaker.SimpleTweaker;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraft.launchwrapper.LaunchClassLoader;
|
||||
import org.spongepowered.asm.launch.MixinBootstrap;
|
||||
import org.spongepowered.asm.mixin.MixinEnvironment;
|
||||
import org.spongepowered.asm.mixin.Mixins;
|
||||
import org.spongepowered.tools.obfuscation.mcp.ObfuscationServiceMCP;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 7/31/2018 9:59 PM
|
||||
* @since 7/31/2018
|
||||
*/
|
||||
public class BaritoneTweaker implements ITweaker {
|
||||
|
||||
List<String> args;
|
||||
|
||||
@Override
|
||||
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
|
||||
this.args = new ArrayList<>(args);
|
||||
if (gameDir != null) {
|
||||
addArg("gameDir", gameDir.getAbsolutePath());
|
||||
}
|
||||
if (assetsDir != null) {
|
||||
addArg("assetsDir", assetsDir.getAbsolutePath());
|
||||
}
|
||||
if (profile != null) {
|
||||
addArg("version", profile);
|
||||
}
|
||||
}
|
||||
public class BaritoneTweaker extends SimpleTweaker {
|
||||
|
||||
@Override
|
||||
public void injectIntoClassLoader(LaunchClassLoader classLoader) {
|
||||
super.injectIntoClassLoader(classLoader);
|
||||
|
||||
MixinBootstrap.init();
|
||||
|
||||
// noinspection unchecked
|
||||
List<String> tweakClasses = (List<String>) Launch.blackboard.get("TweakClasses");
|
||||
|
||||
String obfuscation = ObfuscationServiceMCP.NOTCH;
|
||||
if (tweakClasses.stream().anyMatch(s -> s.contains("net.minecraftforge.fml.common.launcher"))) {
|
||||
obfuscation = ObfuscationServiceMCP.SEARGE;
|
||||
}
|
||||
|
||||
MixinEnvironment.getDefaultEnvironment().setSide(MixinEnvironment.Side.CLIENT);
|
||||
MixinEnvironment.getDefaultEnvironment().setObfuscationContext(ObfuscationServiceMCP.NOTCH);
|
||||
MixinEnvironment.getDefaultEnvironment().setObfuscationContext(obfuscation);
|
||||
|
||||
Mixins.addConfiguration("mixins.baritone.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getLaunchTarget() {
|
||||
return "net.minecraft.client.main.Main";
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String[] getLaunchArguments() {
|
||||
return this.args.toArray(new String[0]);
|
||||
}
|
||||
|
||||
private void addArg(String label, String value) {
|
||||
if (!args.contains("--" + label) && value != null) {
|
||||
this.args.add("--" + label);
|
||||
this.args.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.launch;
|
||||
|
||||
import net.minecraft.launchwrapper.LaunchClassLoader;
|
||||
import org.spongepowered.asm.mixin.MixinEnvironment;
|
||||
import org.spongepowered.tools.obfuscation.mcp.ObfuscationServiceMCP;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 7/31/2018 10:09 PM
|
||||
*/
|
||||
public class BaritoneTweakerForge extends BaritoneTweaker {
|
||||
|
||||
@Override
|
||||
public final void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
|
||||
this.args = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void injectIntoClassLoader(LaunchClassLoader classLoader) {
|
||||
super.injectIntoClassLoader(classLoader);
|
||||
MixinEnvironment.getDefaultEnvironment().setObfuscationContext(ObfuscationServiceMCP.SEARGE);
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,9 @@ import java.io.File;
|
||||
@Mixin(AnvilChunkLoader.class)
|
||||
public class MixinAnvilChunkLoader implements IAnvilChunkLoader {
|
||||
|
||||
@Shadow @Final private File chunkSaveLocation;
|
||||
@Shadow
|
||||
@Final
|
||||
private File chunkSaveLocation;
|
||||
|
||||
@Override
|
||||
public File getChunkSaveLocation() {
|
||||
|
||||
@@ -35,6 +35,12 @@ public class MixinBlockPos extends Vec3i {
|
||||
super(xIn, yIn, zIn);
|
||||
}
|
||||
|
||||
/**
|
||||
* The purpose of this was to ensure a friendly name for when we print raw
|
||||
* block positions to chat in the context of an obfuscated environment.
|
||||
*
|
||||
* @return a string representation of the object.
|
||||
*/
|
||||
@Override
|
||||
@Nonnull
|
||||
public String toString() {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.IChunkProviderClient;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(ChunkProviderClient.class)
|
||||
public class MixinChunkProviderClient implements IChunkProviderClient {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private Long2ObjectMap<Chunk> loadedChunks;
|
||||
|
||||
@Override
|
||||
public Long2ObjectMap<Chunk> loadedChunks() {
|
||||
return this.loadedChunks;
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,9 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
@Mixin(ChunkProviderServer.class)
|
||||
public class MixinChunkProviderServer implements IChunkProviderServer {
|
||||
|
||||
@Shadow @Final private IChunkLoader chunkLoader;
|
||||
@Shadow
|
||||
@Final
|
||||
private IChunkLoader chunkLoader;
|
||||
|
||||
@Override
|
||||
public IChunkLoader getChunkLoader() {
|
||||
|
||||
@@ -17,16 +17,19 @@
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.event.events.RotationMoveEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.entity.Entity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/21/2018
|
||||
@@ -34,23 +37,38 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(Entity.class)
|
||||
public class MixinEntity {
|
||||
|
||||
@Shadow
|
||||
public float rotationYaw;
|
||||
|
||||
/**
|
||||
* Event called to override the movement direction when walking
|
||||
*/
|
||||
private RotationMoveEvent motionUpdateRotationEvent;
|
||||
|
||||
@Inject(
|
||||
method = "moveRelative",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
|
||||
Entity _this = (Entity) (Object) this;
|
||||
if (EntityPlayerSP.class.isInstance(_this))
|
||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.MOTION_UPDATE));
|
||||
// noinspection ConstantConditions
|
||||
if (EntityPlayerSP.class.isInstance(this)) {
|
||||
this.motionUpdateRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
|
||||
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.motionUpdateRotationEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@Redirect(
|
||||
method = "moveRelative",
|
||||
at = @At("RETURN")
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
opcode = GETFIELD,
|
||||
target = "net/minecraft/entity/Entity.rotationYaw:F"
|
||||
)
|
||||
)
|
||||
private void postMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
|
||||
Entity _this = (Entity) (Object) this;
|
||||
if (EntityPlayerSP.class.isInstance(_this))
|
||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.MOTION_UPDATE));
|
||||
private float overrideYaw(Entity self) {
|
||||
if (self instanceof EntityPlayerSP) {
|
||||
return this.motionUpdateRotationEvent.getYaw();
|
||||
}
|
||||
return self.rotationYaw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,40 +17,61 @@
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.event.events.RotationMoveEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
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;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/10/2018
|
||||
*/
|
||||
@Mixin(EntityLivingBase.class)
|
||||
public class MixinEntityLivingBase {
|
||||
public abstract class MixinEntityLivingBase extends Entity {
|
||||
|
||||
/**
|
||||
* Event called to override the movement direction when jumping
|
||||
*/
|
||||
private RotationMoveEvent jumpRotationEvent;
|
||||
|
||||
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
|
||||
super(worldIn);
|
||||
this.jumpRotationEvent = jumpRotationEvent;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "jump",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preJump(CallbackInfo ci) {
|
||||
EntityLivingBase _this = (EntityLivingBase) (Object) this;
|
||||
if (EntityPlayerSP.class.isInstance(_this))
|
||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP));
|
||||
private void preMoveRelative(CallbackInfo ci) {
|
||||
// noinspection ConstantConditions
|
||||
if (EntityPlayerSP.class.isInstance(this)) {
|
||||
this.jumpRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.JUMP, this.rotationYaw);
|
||||
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@Redirect(
|
||||
method = "jump",
|
||||
at = @At("RETURN")
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
opcode = GETFIELD,
|
||||
target = "net/minecraft/entity/EntityLivingBase.rotationYaw:F"
|
||||
)
|
||||
)
|
||||
private void postJump(CallbackInfo ci) {
|
||||
EntityLivingBase _this = (EntityLivingBase) (Object) this;
|
||||
if (EntityPlayerSP.class.isInstance(_this))
|
||||
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP));
|
||||
private float overrideYaw(EntityLivingBase self) {
|
||||
if (self instanceof EntityPlayerSP) {
|
||||
return this.jumpRotationEvent.getYaw();
|
||||
}
|
||||
return self.rotationYaw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,19 +17,22 @@
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.behavior.IPathingBehavior;
|
||||
import baritone.api.event.events.ChatEvent;
|
||||
import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.entity.player.PlayerCapabilities;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/1/2018 5:06 PM
|
||||
* @since 8/1/2018
|
||||
*/
|
||||
@Mixin(EntityPlayerSP.class)
|
||||
public class MixinEntityPlayerSP {
|
||||
@@ -41,7 +44,7 @@ public class MixinEntityPlayerSP {
|
||||
)
|
||||
private void sendChatMessage(String msg, CallbackInfo ci) {
|
||||
ChatEvent event = new ChatEvent((EntityPlayerSP) (Object) this, msg);
|
||||
Baritone.INSTANCE.getGameEventHandler().onSendChatMessage(event);
|
||||
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onSendChatMessage(event);
|
||||
if (event.isCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
@@ -57,7 +60,7 @@ public class MixinEntityPlayerSP {
|
||||
)
|
||||
)
|
||||
private void onPreUpdate(CallbackInfo ci) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
|
||||
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -70,6 +73,18 @@ public class MixinEntityPlayerSP {
|
||||
)
|
||||
)
|
||||
private void onPostUpdate(CallbackInfo ci) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
|
||||
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "onLivingUpdate",
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
target = "net/minecraft/entity/player/PlayerCapabilities.allowFlying:Z"
|
||||
)
|
||||
)
|
||||
private boolean isAllowFlying(PlayerCapabilities capabilities) {
|
||||
IPathingBehavior pathingBehavior = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getPathingBehavior();
|
||||
return !pathingBehavior.isPathing() && capabilities.allowFlying;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.RenderEvent;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -33,10 +34,12 @@ public class MixinEntityRenderer {
|
||||
at = @At(
|
||||
value = "INVOKE_STRING",
|
||||
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
|
||||
args = { "ldc=hand" }
|
||||
args = {"ldc=hand"}
|
||||
)
|
||||
)
|
||||
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
ibaritone.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -26,7 +26,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 7/31/2018 11:44 PM
|
||||
* @since 7/31/2018
|
||||
*/
|
||||
@Mixin(KeyBinding.class)
|
||||
public class MixinKeyBinding {
|
||||
@@ -37,7 +37,8 @@ public class MixinKeyBinding {
|
||||
cancellable = true
|
||||
)
|
||||
private void isKeyDown(CallbackInfoReturnable<Boolean> cir) {
|
||||
if (Baritone.INSTANCE.getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this)) {
|
||||
// only the primary baritone forces keys
|
||||
if (BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this)) {
|
||||
cir.setReturnValue(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,22 +18,25 @@
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.BlockInteractEvent;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.event.events.WorldEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.behavior.PathingBehavior;
|
||||
import baritone.utils.BaritoneAutoTest;
|
||||
import baritone.utils.ExampleBaritoneControl;
|
||||
import baritone.utils.resource.BaritoneResourcePack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.resources.IResourcePack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
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.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -42,27 +45,25 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 7/31/2018 10:51 PM
|
||||
* @since 7/31/2018
|
||||
*/
|
||||
@Mixin(Minecraft.class)
|
||||
public class MixinMinecraft {
|
||||
|
||||
@Shadow
|
||||
private int leftClickCounter;
|
||||
@Shadow
|
||||
public EntityPlayerSP player;
|
||||
@Shadow
|
||||
public WorldClient world;
|
||||
@Shadow public EntityPlayerSP player;
|
||||
@Shadow public WorldClient world;
|
||||
@Shadow @Final private List<IResourcePack> defaultResourcePacks;
|
||||
|
||||
@Inject(
|
||||
method = "init",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postInit(CallbackInfo ci) {
|
||||
Baritone.INSTANCE.init();
|
||||
ExampleBaritoneControl.INSTANCE.initAndRegister();
|
||||
((Baritone) BaritoneAPI.getProvider().getPrimaryBaritone()).init();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -74,6 +75,7 @@ public class MixinMinecraft {
|
||||
)
|
||||
private void preInit(CallbackInfo ci) {
|
||||
BaritoneAutoTest.INSTANCE.onPreInit();
|
||||
this.defaultResourcePacks.add(new BaritoneResourcePack());
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -88,13 +90,15 @@ public class MixinMinecraft {
|
||||
)
|
||||
)
|
||||
private void runTick(CallbackInfo ci) {
|
||||
Minecraft mc = (Minecraft) (Object) this;
|
||||
Baritone.INSTANCE.getGameEventHandler().onTick(new TickEvent(
|
||||
EventState.PRE,
|
||||
(mc.player != null && mc.world != null)
|
||||
? TickEvent.Type.IN
|
||||
: TickEvent.Type.OUT
|
||||
));
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
|
||||
TickEvent.Type type = ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().world() != null
|
||||
? TickEvent.Type.IN
|
||||
: TickEvent.Type.OUT;
|
||||
|
||||
ibaritone.getGameEventHandler().onTick(new TickEvent(EventState.PRE, type));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -102,7 +106,8 @@ public class MixinMinecraft {
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void runTickKeyboard(CallbackInfo ci) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onProcessKeyBinds();
|
||||
// keyboard input is only the primary baritone
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onProcessKeyBinds();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -115,7 +120,9 @@ public class MixinMinecraft {
|
||||
return;
|
||||
}
|
||||
|
||||
Baritone.INSTANCE.getGameEventHandler().onWorldEvent(
|
||||
// mc.world changing is only the primary baritone
|
||||
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onWorldEvent(
|
||||
new WorldEvent(
|
||||
world,
|
||||
EventState.PRE
|
||||
@@ -130,7 +137,8 @@ public class MixinMinecraft {
|
||||
private void postLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
||||
// still fire event for both null, as that means we've just finished exiting a world
|
||||
|
||||
Baritone.INSTANCE.getGameEventHandler().onWorldEvent(
|
||||
// mc.world changing is only the primary baritone
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onWorldEvent(
|
||||
new WorldEvent(
|
||||
world,
|
||||
EventState.POST
|
||||
@@ -147,7 +155,8 @@ public class MixinMinecraft {
|
||||
)
|
||||
)
|
||||
private boolean isAllowUserInput(GuiScreen screen) {
|
||||
return (PathingBehavior.INSTANCE.getCurrent() != null && player != null) || screen.allowUserInput;
|
||||
// allow user input is only the primary baritone
|
||||
return (BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().getCurrent() != null && player != null) || screen.allowUserInput;
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -159,7 +168,8 @@ public class MixinMinecraft {
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private void onBlockBreak(CallbackInfo ci, BlockPos pos) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onBlockInteract(new BlockInteractEvent(pos, BlockInteractEvent.Type.BREAK));
|
||||
// clickMouse is only for the main player
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(pos, BlockInteractEvent.Type.START_BREAK));
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -171,6 +181,7 @@ public class MixinMinecraft {
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private void onBlockUse(CallbackInfo ci, EnumHand var1[], int var2, int var3, EnumHand enumhand, ItemStack itemstack, BlockPos blockpos, int i, EnumActionResult enumactionresult) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onBlockInteract(new BlockInteractEvent(blockpos, BlockInteractEvent.Type.USE));
|
||||
// rightClickMouse is only for the main player
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(blockpos, BlockInteractEvent.Type.USE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.ChunkEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
@@ -30,7 +31,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/3/2018 12:54 AM
|
||||
* @since 8/3/2018
|
||||
*/
|
||||
@Mixin(NetHandlerPlayClient.class)
|
||||
public class MixinNetHandlerPlayClient {
|
||||
@@ -43,14 +44,18 @@ public class MixinNetHandlerPlayClient {
|
||||
)
|
||||
)
|
||||
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.PRE,
|
||||
ChunkEvent.Type.POPULATE,
|
||||
packetIn.getChunkX(),
|
||||
packetIn.getChunkZ()
|
||||
)
|
||||
);
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().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()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -58,14 +63,18 @@ public class MixinNetHandlerPlayClient {
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
ChunkEvent.Type.POPULATE,
|
||||
packetIn.getChunkX(),
|
||||
packetIn.getChunkZ()
|
||||
)
|
||||
);
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().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()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -76,6 +85,10 @@ public class MixinNetHandlerPlayClient {
|
||||
)
|
||||
)
|
||||
private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onPlayerDeath();
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onPlayerDeath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.PacketEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import io.netty.channel.Channel;
|
||||
@@ -36,7 +37,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/6/2018 9:30 PM
|
||||
* @since 8/6/2018
|
||||
*/
|
||||
@Mixin(NetworkManager.class)
|
||||
public class MixinNetworkManager {
|
||||
@@ -53,8 +54,14 @@ public class MixinNetworkManager {
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
||||
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, inPacket));
|
||||
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, inPacket));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,8 +70,14 @@ public class MixinNetworkManager {
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
||||
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, inPacket));
|
||||
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, inPacket));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +89,14 @@ public class MixinNetworkManager {
|
||||
)
|
||||
)
|
||||
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
||||
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, packet));}
|
||||
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, packet));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -85,8 +104,13 @@ public class MixinNetworkManager {
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
||||
if (this.channel.isOpen() && this.direction == EnumPacketDirection.CLIENTBOUND) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, packet));
|
||||
if (!this.channel.isOpen() || this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, packet));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.ChunkEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
@@ -28,7 +29,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/2/2018 12:41 AM
|
||||
* @since 8/2/2018
|
||||
*/
|
||||
@Mixin(WorldClient.class)
|
||||
public class MixinWorldClient {
|
||||
@@ -38,14 +39,19 @@ public class MixinWorldClient {
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.PRE,
|
||||
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||
chunkX,
|
||||
chunkZ
|
||||
)
|
||||
);
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.PRE,
|
||||
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||
chunkX,
|
||||
chunkZ
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -53,13 +59,17 @@ public class MixinWorldClient {
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
||||
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||
chunkX,
|
||||
chunkZ
|
||||
)
|
||||
);
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||
chunkX,
|
||||
chunkZ
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"client": [
|
||||
"MixinAnvilChunkLoader",
|
||||
"MixinBlockPos",
|
||||
"MixinChunkProviderClient",
|
||||
"MixinChunkProviderServer",
|
||||
"MixinEntity",
|
||||
"MixinEntityLivingBase",
|
||||
|
||||
@@ -18,13 +18,26 @@
|
||||
package baritone;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.Settings;
|
||||
import baritone.api.event.listener.IGameEventListener;
|
||||
import baritone.api.event.listener.IEventBus;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import baritone.behavior.*;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.event.GameEventHandler;
|
||||
import baritone.process.CustomGoalProcess;
|
||||
import baritone.process.FollowProcess;
|
||||
import baritone.process.GetToBlockProcess;
|
||||
import baritone.process.MineProcess;
|
||||
import baritone.utils.BaritoneAutoTest;
|
||||
import baritone.utils.ExampleBaritoneControl;
|
||||
import baritone.utils.InputOverrideHandler;
|
||||
import baritone.utils.PathingControlManager;
|
||||
import baritone.utils.player.PrimaryPlayerContext;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.PositionedSoundRecord;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -38,14 +51,23 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 7/31/2018 10:50 PM
|
||||
* @since 7/31/2018
|
||||
*/
|
||||
public enum Baritone {
|
||||
public class Baritone implements IBaritone {
|
||||
|
||||
/**
|
||||
* Singleton instance of this class
|
||||
*/
|
||||
INSTANCE;
|
||||
private static ThreadPoolExecutor threadPool;
|
||||
private static File dir;
|
||||
|
||||
static {
|
||||
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||
|
||||
dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
||||
if (!Files.exists(dir.toPath())) {
|
||||
try {
|
||||
Files.createDirectories(dir.toPath());
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not {@link Baritone#init()} has been called yet
|
||||
@@ -53,97 +75,146 @@ public enum Baritone {
|
||||
private boolean initialized;
|
||||
|
||||
private GameEventHandler gameEventHandler;
|
||||
private InputOverrideHandler inputOverrideHandler;
|
||||
private Settings settings;
|
||||
private List<Behavior> behaviors;
|
||||
private File dir;
|
||||
private ThreadPoolExecutor threadPool;
|
||||
|
||||
/**
|
||||
* Whether or not Baritone is active
|
||||
*/
|
||||
private boolean active;
|
||||
private List<Behavior> behaviors;
|
||||
private PathingBehavior pathingBehavior;
|
||||
private LookBehavior lookBehavior;
|
||||
private MemoryBehavior memoryBehavior;
|
||||
private InputOverrideHandler inputOverrideHandler;
|
||||
|
||||
private FollowProcess followProcess;
|
||||
private MineProcess mineProcess;
|
||||
private GetToBlockProcess getToBlockProcess;
|
||||
private CustomGoalProcess customGoalProcess;
|
||||
|
||||
private PathingControlManager pathingControlManager;
|
||||
|
||||
private IPlayerContext playerContext;
|
||||
private WorldProvider worldProvider;
|
||||
|
||||
Baritone() {
|
||||
this.gameEventHandler = new GameEventHandler();
|
||||
this.gameEventHandler = new GameEventHandler(this);
|
||||
}
|
||||
|
||||
public void fitmc() {
|
||||
SoundEvent event = new SoundEvent(new ResourceLocation("baritone", "fitmc_intro"));
|
||||
Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(event, 0.8F + (float) Math.random() * 0.4F));
|
||||
}
|
||||
|
||||
public synchronized void init() {
|
||||
if (initialized) {
|
||||
return;
|
||||
}
|
||||
this.threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||
this.inputOverrideHandler = new InputOverrideHandler();
|
||||
|
||||
// Acquire the "singleton" instance of the settings directly from the API
|
||||
// We might want to change this...
|
||||
this.settings = BaritoneAPI.getSettings();
|
||||
fitmc();
|
||||
|
||||
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
|
||||
this.playerContext = PrimaryPlayerContext.INSTANCE;
|
||||
|
||||
this.behaviors = new ArrayList<>();
|
||||
{
|
||||
registerBehavior(PathingBehavior.INSTANCE);
|
||||
registerBehavior(LookBehavior.INSTANCE);
|
||||
registerBehavior(MemoryBehavior.INSTANCE);
|
||||
registerBehavior(LocationTrackingBehavior.INSTANCE);
|
||||
registerBehavior(FollowBehavior.INSTANCE);
|
||||
registerBehavior(MineBehavior.INSTANCE);
|
||||
}
|
||||
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
|
||||
registerEventListener(BaritoneAutoTest.INSTANCE);
|
||||
}
|
||||
this.dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
||||
if (!Files.exists(dir.toPath())) {
|
||||
try {
|
||||
Files.createDirectories(dir.toPath());
|
||||
} catch (IOException ignored) {}
|
||||
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
|
||||
pathingBehavior = new PathingBehavior(this);
|
||||
lookBehavior = new LookBehavior(this);
|
||||
memoryBehavior = new MemoryBehavior(this);
|
||||
new InventoryBehavior(this);
|
||||
inputOverrideHandler = new InputOverrideHandler(this);
|
||||
new ExampleBaritoneControl(this);
|
||||
}
|
||||
|
||||
this.pathingControlManager = new PathingControlManager(this);
|
||||
{
|
||||
followProcess = new FollowProcess(this);
|
||||
mineProcess = new MineProcess(this);
|
||||
customGoalProcess = new CustomGoalProcess(this); // very high iq
|
||||
getToBlockProcess = new GetToBlockProcess(this);
|
||||
}
|
||||
|
||||
this.worldProvider = new WorldProvider();
|
||||
|
||||
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
|
||||
this.gameEventHandler.registerEventListener(BaritoneAutoTest.INSTANCE);
|
||||
}
|
||||
|
||||
this.active = true;
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return this.initialized;
|
||||
}
|
||||
|
||||
public IGameEventListener getGameEventHandler() {
|
||||
return this.gameEventHandler;
|
||||
}
|
||||
|
||||
public InputOverrideHandler getInputOverrideHandler() {
|
||||
return this.inputOverrideHandler;
|
||||
public PathingControlManager getPathingControlManager() {
|
||||
return this.pathingControlManager;
|
||||
}
|
||||
|
||||
public List<Behavior> getBehaviors() {
|
||||
return this.behaviors;
|
||||
}
|
||||
|
||||
public Executor getExecutor() {
|
||||
return threadPool;
|
||||
}
|
||||
|
||||
public void registerBehavior(Behavior behavior) {
|
||||
this.behaviors.add(behavior);
|
||||
this.registerEventListener(behavior);
|
||||
this.gameEventHandler.registerEventListener(behavior);
|
||||
}
|
||||
|
||||
public void registerEventListener(IGameEventListener listener) {
|
||||
this.gameEventHandler.registerEventListener(listener);
|
||||
@Override
|
||||
public InputOverrideHandler getInputOverrideHandler() {
|
||||
return this.inputOverrideHandler;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this.active;
|
||||
@Override
|
||||
public CustomGoalProcess getCustomGoalProcess() { // Iffy
|
||||
return this.customGoalProcess;
|
||||
}
|
||||
|
||||
public Settings getSettings() {
|
||||
return this.settings;
|
||||
@Override
|
||||
public GetToBlockProcess getGetToBlockProcess() { // Iffy
|
||||
return this.getToBlockProcess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPlayerContext getPlayerContext() {
|
||||
return this.playerContext;
|
||||
}
|
||||
|
||||
public MemoryBehavior getMemoryBehavior() {
|
||||
return this.memoryBehavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FollowProcess getFollowProcess() {
|
||||
return this.followProcess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LookBehavior getLookBehavior() {
|
||||
return this.lookBehavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MineProcess getMineProcess() {
|
||||
return this.mineProcess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PathingBehavior getPathingBehavior() {
|
||||
return this.pathingBehavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldProvider getWorldProvider() {
|
||||
return this.worldProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEventBus getGameEventHandler() {
|
||||
return this.gameEventHandler;
|
||||
}
|
||||
|
||||
public static Settings settings() {
|
||||
return Baritone.INSTANCE.settings; // yolo
|
||||
return BaritoneAPI.getSettings();
|
||||
}
|
||||
|
||||
public File getDir() {
|
||||
return this.dir;
|
||||
public static File getDir() {
|
||||
return dir;
|
||||
}
|
||||
|
||||
public static Executor getExecutor() {
|
||||
return threadPool;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,58 +17,35 @@
|
||||
|
||||
package baritone;
|
||||
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.IBaritoneProvider;
|
||||
import baritone.api.behavior.*;
|
||||
import baritone.api.cache.IWorldProvider;
|
||||
import baritone.api.cache.IWorldScanner;
|
||||
import baritone.api.event.listener.IGameEventListener;
|
||||
import baritone.behavior.*;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.cache.WorldScanner;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/29/2018
|
||||
*/
|
||||
public final class BaritoneProvider implements IBaritoneProvider {
|
||||
|
||||
private final Baritone primary = new Baritone();
|
||||
|
||||
@Override
|
||||
public IFollowBehavior getFollowBehavior() {
|
||||
return FollowBehavior.INSTANCE;
|
||||
public IBaritone getPrimaryBaritone() {
|
||||
return primary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILookBehavior getLookBehavior() {
|
||||
return LookBehavior.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMemoryBehavior getMemoryBehavior() {
|
||||
return MemoryBehavior.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMineBehavior getMineBehavior() {
|
||||
return MineBehavior.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPathingBehavior getPathingBehavior() {
|
||||
return PathingBehavior.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWorldProvider getWorldProvider() {
|
||||
return WorldProvider.INSTANCE;
|
||||
public List<IBaritone> getAllBaritones() {
|
||||
// TODO return a CopyOnWriteArrayList
|
||||
return Collections.singletonList(primary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWorldScanner getWorldScanner() {
|
||||
return WorldScanner.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEventListener(IGameEventListener listener) {
|
||||
Baritone.INSTANCE.registerEventListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,54 +17,24 @@
|
||||
|
||||
package baritone.behavior;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.behavior.IBehavior;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
|
||||
/**
|
||||
* A type of game event listener that can be toggled.
|
||||
* A type of game event listener that is given {@link Baritone} instance context.
|
||||
*
|
||||
* @author Brady
|
||||
* @since 8/1/2018 6:29 PM
|
||||
* @since 8/1/2018
|
||||
*/
|
||||
public class Behavior implements IBehavior {
|
||||
|
||||
/**
|
||||
* Whether or not this behavior is enabled
|
||||
*/
|
||||
private boolean enabled = true;
|
||||
public final Baritone baritone;
|
||||
public final IPlayerContext ctx;
|
||||
|
||||
/**
|
||||
* Toggles the enabled state of this {@link Behavior}.
|
||||
*
|
||||
* @return The new state.
|
||||
*/
|
||||
@Override
|
||||
public final boolean toggle() {
|
||||
return this.setEnabled(!this.isEnabled());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the enabled state of this {@link Behavior}.
|
||||
*
|
||||
* @return The new state.
|
||||
*/
|
||||
@Override
|
||||
public final boolean setEnabled(boolean enabled) {
|
||||
if (enabled == this.enabled) {
|
||||
return this.enabled;
|
||||
}
|
||||
if (this.enabled = enabled) {
|
||||
this.onEnable();
|
||||
} else {
|
||||
this.onDisable();
|
||||
}
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether or not this {@link Behavior} is active.
|
||||
*/
|
||||
@Override
|
||||
public final boolean isEnabled() {
|
||||
return this.enabled;
|
||||
protected Behavior(Baritone baritone) {
|
||||
this.baritone = baritone;
|
||||
this.ctx = baritone.getPlayerContext();
|
||||
baritone.registerBehavior(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,79 +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.behavior;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.behavior.IFollowBehavior;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.pathing.goals.GoalNear;
|
||||
import baritone.api.pathing.goals.GoalXZ;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
/**
|
||||
* Follow an entity
|
||||
*
|
||||
* @author leijurv
|
||||
*/
|
||||
public final class FollowBehavior extends Behavior implements IFollowBehavior, Helper {
|
||||
|
||||
public static final FollowBehavior INSTANCE = new FollowBehavior();
|
||||
|
||||
private Entity following;
|
||||
|
||||
private FollowBehavior() {}
|
||||
|
||||
@Override
|
||||
public void onTick(TickEvent event) {
|
||||
if (event.getType() == TickEvent.Type.OUT) {
|
||||
following = null;
|
||||
return;
|
||||
}
|
||||
if (following == null) {
|
||||
return;
|
||||
}
|
||||
// lol this is trashy but it works
|
||||
BlockPos pos;
|
||||
if (Baritone.settings().followOffsetDistance.get() == 0) {
|
||||
pos = following.getPosition();
|
||||
} else {
|
||||
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
|
||||
pos = new BlockPos(g.getX(), following.posY, g.getZ());
|
||||
}
|
||||
PathingBehavior.INSTANCE.setGoal(new GoalNear(pos, Baritone.settings().followRadius.get()));
|
||||
PathingBehavior.INSTANCE.revalidateGoal();
|
||||
PathingBehavior.INSTANCE.path();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void follow(Entity entity) {
|
||||
this.following = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity following() {
|
||||
return this.following;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
PathingBehavior.INSTANCE.cancel();
|
||||
follow(null);
|
||||
}
|
||||
}
|
||||
93
src/main/java/baritone/behavior/InventoryBehavior.java
Normal file
93
src/main/java/baritone/behavior/InventoryBehavior.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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.behavior;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.utils.ToolSet;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.inventory.ClickType;
|
||||
import net.minecraft.item.ItemPickaxe;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemTool;
|
||||
import net.minecraft.util.NonNullList;
|
||||
|
||||
public class InventoryBehavior extends Behavior {
|
||||
public InventoryBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick(TickEvent event) {
|
||||
if (!Baritone.settings().allowInventory.get()) {
|
||||
return;
|
||||
}
|
||||
if (event.getType() == TickEvent.Type.OUT) {
|
||||
return;
|
||||
}
|
||||
if (ctx.player().openContainer != ctx.player().inventoryContainer) {
|
||||
// we have a crafting table or a chest or something open
|
||||
return;
|
||||
}
|
||||
if (firstValidThrowaway() >= 9) { // aka there are none on the hotbar, but there are some in main inventory
|
||||
swapWithHotBar(firstValidThrowaway(), 8);
|
||||
}
|
||||
int pick = bestToolAgainst(Blocks.STONE, ItemPickaxe.class);
|
||||
if (pick >= 9) {
|
||||
swapWithHotBar(pick, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void swapWithHotBar(int inInventory, int inHotbar) {
|
||||
if (inInventory < 9) {
|
||||
inInventory += 36;
|
||||
}
|
||||
ctx.playerController().windowClick(ctx.player().inventoryContainer.windowId, inInventory, inHotbar, ClickType.SWAP, ctx.player());
|
||||
}
|
||||
|
||||
private int firstValidThrowaway() { // TODO offhand idk
|
||||
NonNullList<ItemStack> invy = ctx.player().inventory.mainInventory;
|
||||
for (int i = 0; i < invy.size(); i++) {
|
||||
if (Baritone.settings().acceptableThrowawayItems.get().contains(invy.get(i).getItem())) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int bestToolAgainst(Block against, Class<? extends ItemTool> klass) {
|
||||
NonNullList<ItemStack> invy = ctx.player().inventory.mainInventory;
|
||||
int bestInd = -1;
|
||||
double bestSpeed = -1;
|
||||
for (int i = 0; i < invy.size(); i++) {
|
||||
ItemStack stack = invy.get(i);
|
||||
if (stack.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (klass.isInstance(stack.getItem())) {
|
||||
double speed = ToolSet.calculateStrVsBlock(stack, against.getDefaultState()); // takes into account enchants
|
||||
if (speed > bestSpeed) {
|
||||
bestSpeed = speed;
|
||||
bestInd = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestInd;
|
||||
}
|
||||
}
|
||||
@@ -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.behavior;
|
||||
|
||||
import baritone.api.event.events.BlockInteractEvent;
|
||||
import baritone.cache.Waypoint;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.block.BlockBed;
|
||||
|
||||
/**
|
||||
* A collection of event methods that are used to interact with Baritone's
|
||||
* waypoint system. This class probably needs a better name.
|
||||
*
|
||||
* @see Waypoint
|
||||
*
|
||||
* @author Brady
|
||||
* @since 8/22/2018
|
||||
*/
|
||||
public final class LocationTrackingBehavior extends Behavior implements Helper {
|
||||
|
||||
public static final LocationTrackingBehavior INSTANCE = new LocationTrackingBehavior();
|
||||
|
||||
private LocationTrackingBehavior() {}
|
||||
|
||||
@Override
|
||||
public void onBlockInteract(BlockInteractEvent event) {
|
||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
|
||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerDeath() {
|
||||
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
|
||||
}
|
||||
}
|
||||
@@ -23,11 +23,8 @@ import baritone.api.behavior.ILookBehavior;
|
||||
import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.RotationMoveEvent;
|
||||
import baritone.api.utils.Rotation;
|
||||
import baritone.utils.Helper;
|
||||
|
||||
public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
|
||||
|
||||
public static final LookBehavior INSTANCE = new LookBehavior();
|
||||
public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
|
||||
/**
|
||||
* Target's values are as follows:
|
||||
@@ -49,7 +46,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
|
||||
*/
|
||||
private float lastYaw;
|
||||
|
||||
private LookBehavior() {}
|
||||
public LookBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTarget(Rotation target, boolean force) {
|
||||
@@ -64,28 +63,29 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
|
||||
}
|
||||
|
||||
// Whether or not we're going to silently set our angles
|
||||
boolean silent = Baritone.settings().antiCheatCompatibility.get();
|
||||
boolean silent = Baritone.settings().antiCheatCompatibility.get() && !this.force;
|
||||
|
||||
switch (event.getState()) {
|
||||
case PRE: {
|
||||
if (this.force) {
|
||||
player().rotationYaw = this.target.getYaw();
|
||||
float oldPitch = player().rotationPitch;
|
||||
ctx.player().rotationYaw = this.target.getYaw();
|
||||
float oldPitch = ctx.player().rotationPitch;
|
||||
float desiredPitch = this.target.getPitch();
|
||||
player().rotationPitch = desiredPitch;
|
||||
ctx.player().rotationPitch = desiredPitch;
|
||||
if (desiredPitch == oldPitch) {
|
||||
nudgeToLevel();
|
||||
}
|
||||
this.target = null;
|
||||
} else if (silent) {
|
||||
this.lastYaw = player().rotationYaw;
|
||||
player().rotationYaw = this.target.getYaw();
|
||||
}
|
||||
if (silent) {
|
||||
this.lastYaw = ctx.player().rotationYaw;
|
||||
ctx.player().rotationYaw = this.target.getYaw();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case POST: {
|
||||
if (!this.force && silent) {
|
||||
player().rotationYaw = this.lastYaw;
|
||||
if (silent) {
|
||||
ctx.player().rotationYaw = this.lastYaw;
|
||||
this.target = null;
|
||||
}
|
||||
break;
|
||||
@@ -98,31 +98,25 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
|
||||
@Override
|
||||
public void onPlayerRotationMove(RotationMoveEvent event) {
|
||||
if (this.target != null && !this.force) {
|
||||
switch (event.getState()) {
|
||||
case PRE:
|
||||
this.lastYaw = player().rotationYaw;
|
||||
player().rotationYaw = this.target.getYaw();
|
||||
break;
|
||||
case POST:
|
||||
player().rotationYaw = this.lastYaw;
|
||||
|
||||
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
|
||||
// Also the type has to be MOTION_UPDATE because that is called after JUMP
|
||||
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) {
|
||||
this.target = null;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
event.setYaw(this.target.getYaw());
|
||||
|
||||
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
|
||||
// Also the type has to be MOTION_UPDATE because that is called after JUMP
|
||||
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) {
|
||||
this.target = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1})
|
||||
*/
|
||||
private void nudgeToLevel() {
|
||||
if (player().rotationPitch < -20) {
|
||||
player().rotationPitch++;
|
||||
} else if (player().rotationPitch > 10) {
|
||||
player().rotationPitch--;
|
||||
if (ctx.player().rotationPitch < -20) {
|
||||
ctx.player().rotationPitch++;
|
||||
} else if (ctx.player().rotationPitch > 10) {
|
||||
ctx.player().rotationPitch--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,139 +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.behavior;
|
||||
|
||||
import baritone.api.utils.Rotation;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.utils.RayTraceUtils;
|
||||
import baritone.utils.Utils;
|
||||
import net.minecraft.block.BlockFire;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.math.*;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static baritone.utils.Utils.DEG_TO_RAD;
|
||||
|
||||
public final class LookBehaviorUtils implements Helper {
|
||||
|
||||
/**
|
||||
* Offsets from the root block position to the center of each side.
|
||||
*/
|
||||
private static final Vec3d[] BLOCK_SIDE_MULTIPLIERS = new Vec3d[]{
|
||||
new Vec3d(0.5, 0, 0.5), // Down
|
||||
new Vec3d(0.5, 1, 0.5), // Up
|
||||
new Vec3d(0.5, 0.5, 0), // North
|
||||
new Vec3d(0.5, 0.5, 1), // South
|
||||
new Vec3d(0, 0.5, 0.5), // West
|
||||
new Vec3d(1, 0.5, 0.5) // East
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates a vector given a rotation array
|
||||
*
|
||||
* @param rotation {@link LookBehavior#target}
|
||||
* @return vector of the rotation
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
public static Optional<Rotation> reachable(BlockPos pos) {
|
||||
if (pos.equals(getSelectedBlock().orElse(null))) {
|
||||
/*
|
||||
* why add 0.0001?
|
||||
* to indicate that we actually have a desired pitch
|
||||
* the way we indicate that the pitch can be whatever and we only care about the yaw
|
||||
* is by setting the desired pitch to the current pitch
|
||||
* setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's
|
||||
* just what it currently is
|
||||
*/
|
||||
return Optional.of(new Rotation(mc.player.rotationYaw, mc.player.rotationPitch + 0.0001f));
|
||||
}
|
||||
Optional<Rotation> possibleRotation = reachableCenter(pos);
|
||||
//System.out.println("center: " + possibleRotation);
|
||||
if (possibleRotation.isPresent()) {
|
||||
return possibleRotation;
|
||||
}
|
||||
|
||||
IBlockState state = BlockStateInterface.get(pos);
|
||||
AxisAlignedBB aabb = state.getBoundingBox(mc.world, pos);
|
||||
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
|
||||
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
|
||||
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
|
||||
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
|
||||
possibleRotation = reachableOffset(pos, new Vec3d(pos).add(xDiff, yDiff, zDiff));
|
||||
if (possibleRotation.isPresent()) {
|
||||
return possibleRotation;
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if coordinate is reachable with the given block-face rotation offset
|
||||
*
|
||||
* @param pos
|
||||
* @param offsetPos
|
||||
* @return
|
||||
*/
|
||||
protected static Optional<Rotation> reachableOffset(BlockPos pos, Vec3d offsetPos) {
|
||||
Rotation rotation = Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), offsetPos);
|
||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(rotation);
|
||||
System.out.println(result);
|
||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
if (result.getBlockPos().equals(pos)) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
if (BlockStateInterface.get(pos).getBlock() instanceof BlockFire) {
|
||||
if (result.getBlockPos().equals(pos.down())) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if center of block at coordinate is reachable
|
||||
*
|
||||
* @param pos
|
||||
* @return
|
||||
*/
|
||||
protected static Optional<Rotation> reachableCenter(BlockPos pos) {
|
||||
return reachableOffset(pos, Utils.calcCenterFromCoords(pos, mc.world));
|
||||
}
|
||||
|
||||
/**
|
||||
* The currently highlighted block.
|
||||
* Updated once a tick by Minecraft.
|
||||
*
|
||||
* @return the position of the highlighted block
|
||||
*/
|
||||
public static Optional<BlockPos> getSelectedBlock() {
|
||||
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
return Optional.of(mc.objectMouseOver.getBlockPos());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,18 @@
|
||||
|
||||
package baritone.behavior;
|
||||
|
||||
import baritone.api.behavior.IMemoryBehavior;
|
||||
import baritone.api.behavior.memory.IRememberedInventory;
|
||||
import baritone.api.cache.IWorldData;
|
||||
import baritone.Baritone;
|
||||
import baritone.api.event.events.BlockInteractEvent;
|
||||
import baritone.api.event.events.PacketEvent;
|
||||
import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.cache.ContainerMemory;
|
||||
import baritone.cache.Waypoint;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockBed;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.play.client.CPacketCloseWindow;
|
||||
@@ -33,21 +37,28 @@ import net.minecraft.network.play.server.SPacketCloseWindow;
|
||||
import net.minecraft.network.play.server.SPacketOpenWindow;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityLockable;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/6/2018 9:47 PM
|
||||
* @since 8/6/2018
|
||||
*/
|
||||
public final class MemoryBehavior extends Behavior implements IMemoryBehavior, Helper {
|
||||
public final class MemoryBehavior extends Behavior {
|
||||
|
||||
public static MemoryBehavior INSTANCE = new MemoryBehavior();
|
||||
private final List<FutureInventory> futureInventories = new ArrayList<>(); // this is per-bot
|
||||
|
||||
private final Map<IWorldData, WorldDataContainer> worldDataContainers = new HashMap<>();
|
||||
private Integer enderChestWindowId; // nae nae
|
||||
|
||||
private MemoryBehavior() {}
|
||||
public MemoryBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
|
||||
@@ -64,20 +75,31 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
|
||||
if (p instanceof CPacketPlayerTryUseItemOnBlock) {
|
||||
CPacketPlayerTryUseItemOnBlock packet = event.cast();
|
||||
|
||||
TileEntity tileEntity = world().getTileEntity(packet.getPos());
|
||||
TileEntity tileEntity = ctx.world().getTileEntity(packet.getPos());
|
||||
// if tileEntity is an ender chest, we don't need to do anything. ender chests are treated the same regardless of what coordinate right clicked
|
||||
|
||||
// Ensure the TileEntity is a container of some sort
|
||||
if (tileEntity instanceof TileEntityLockable) {
|
||||
|
||||
TileEntityLockable lockable = (TileEntityLockable) tileEntity;
|
||||
int size = lockable.getSizeInventory();
|
||||
BlockPos position = tileEntity.getPos();
|
||||
BlockPos adj = neighboringConnectedBlock(position);
|
||||
System.out.println(position + " " + adj);
|
||||
if (adj != null) {
|
||||
size *= 2; // double chest or double trapped chest
|
||||
if (adj.getX() < position.getX() || adj.getZ() < position.getZ()) {
|
||||
position = adj; // standardize on the lower coordinate, regardless of which side of the large chest we right clicked
|
||||
}
|
||||
}
|
||||
|
||||
this.getCurrentContainer().futureInventories.add(new FutureInventory(System.nanoTime() / 1000000L, size, lockable.getGuiID(), tileEntity.getPos()));
|
||||
this.futureInventories.add(new FutureInventory(System.nanoTime() / 1000000L, size, lockable.getGuiID(), position));
|
||||
}
|
||||
}
|
||||
|
||||
if (p instanceof CPacketCloseWindow) {
|
||||
updateInventory();
|
||||
getCurrent().save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,68 +111,84 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
|
||||
if (event.getState() == EventState.PRE) {
|
||||
if (p instanceof SPacketOpenWindow) {
|
||||
SPacketOpenWindow packet = event.cast();
|
||||
|
||||
WorldDataContainer container = this.getCurrentContainer();
|
||||
|
||||
// Remove any entries that were created over a second ago, this should make up for INSANE latency
|
||||
container.futureInventories.removeIf(i -> System.nanoTime() / 1000000L - i.time > 1000);
|
||||
futureInventories.removeIf(i -> System.nanoTime() / 1000000L - i.time > 1000);
|
||||
|
||||
container.futureInventories.stream()
|
||||
System.out.println("Received packet " + packet.getGuiId() + " " + packet.getEntityId() + " " + packet.getSlotCount() + " " + packet.getWindowId());
|
||||
System.out.println(packet.getWindowTitle());
|
||||
if (packet.getWindowTitle() instanceof TextComponentTranslation) {
|
||||
// title is not customized (i.e. this isn't just a renamed shulker)
|
||||
if (((TextComponentTranslation) packet.getWindowTitle()).getKey().equals("container.enderchest")) {
|
||||
enderChestWindowId = packet.getWindowId();
|
||||
return;
|
||||
}
|
||||
}
|
||||
futureInventories.stream()
|
||||
.filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
|
||||
.findFirst().ifPresent(matched -> {
|
||||
// Remove the future inventory
|
||||
container.futureInventories.remove(matched);
|
||||
futureInventories.remove(matched);
|
||||
|
||||
// Setup the remembered inventory
|
||||
RememberedInventory inventory = container.rememberedInventories.computeIfAbsent(matched.pos, pos -> new RememberedInventory());
|
||||
inventory.windowId = packet.getWindowId();
|
||||
inventory.size = packet.getSlotCount();
|
||||
getCurrentContainer().setup(matched.pos, packet.getWindowId(), packet.getSlotCount());
|
||||
});
|
||||
}
|
||||
|
||||
if (p instanceof SPacketCloseWindow) {
|
||||
updateInventory();
|
||||
getCurrent().save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
|
||||
return this.getCurrentContainer().rememberedInventories.values().stream().filter(i -> i.windowId == windowId).findFirst();
|
||||
@Override
|
||||
public void onBlockInteract(BlockInteractEvent event) {
|
||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerDeath() {
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet()));
|
||||
}
|
||||
|
||||
|
||||
private void updateInventory() {
|
||||
getInventoryFromWindow(player().openContainer.windowId).ifPresent(inventory -> {
|
||||
inventory.items.clear();
|
||||
inventory.items.addAll(player().openContainer.getInventory().subList(0, inventory.size));
|
||||
});
|
||||
int windowId = ctx.player().openContainer.windowId;
|
||||
if (enderChestWindowId != null) {
|
||||
if (windowId == enderChestWindowId) {
|
||||
getCurrent().contents = ctx.player().openContainer.getInventory().subList(0, 27);
|
||||
} else {
|
||||
getCurrent().save();
|
||||
enderChestWindowId = null;
|
||||
}
|
||||
}
|
||||
if (getCurrentContainer() != null) {
|
||||
getCurrentContainer().getInventoryFromWindow(windowId).ifPresent(inventory -> inventory.updateFromOpenWindow(ctx));
|
||||
}
|
||||
}
|
||||
|
||||
private WorldDataContainer getCurrentContainer() {
|
||||
return this.worldDataContainers.computeIfAbsent(WorldProvider.INSTANCE.getCurrentWorld(), data -> new WorldDataContainer());
|
||||
private ContainerMemory getCurrentContainer() {
|
||||
if (baritone.getWorldProvider().getCurrentWorld() == null) {
|
||||
return null;
|
||||
}
|
||||
return (ContainerMemory) baritone.getWorldProvider().getCurrentWorld().getContainerMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final synchronized RememberedInventory getInventoryByPos(BlockPos pos) {
|
||||
return this.getCurrentContainer().rememberedInventories.get(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final synchronized Map<BlockPos, IRememberedInventory> getRememberedInventories() {
|
||||
// make a copy since this map is modified from the packet thread
|
||||
return new HashMap<>(this.getCurrentContainer().rememberedInventories);
|
||||
}
|
||||
|
||||
private static final class WorldDataContainer {
|
||||
|
||||
/**
|
||||
* Possible future inventories that we will be able to remember
|
||||
*/
|
||||
private final List<FutureInventory> futureInventories = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The current remembered inventories
|
||||
*/
|
||||
private final Map<BlockPos, RememberedInventory> rememberedInventories = new HashMap<>();
|
||||
private BlockPos neighboringConnectedBlock(BlockPos in) {
|
||||
BlockStateInterface bsi = new CalculationContext(baritone).bsi();
|
||||
Block block = bsi.get0(in).getBlock();
|
||||
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
|
||||
return null; // other things that have contents, but can be placed adjacent without combining
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
BlockPos adj = in.offset(EnumFacing.byHorizontalIndex(i));
|
||||
if (bsi.get0(adj).getBlock() == block) {
|
||||
return adj;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,43 +221,51 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
|
||||
this.slots = slots;
|
||||
this.type = type;
|
||||
this.pos = pos;
|
||||
System.out.println("Future inventory created " + time + " " + slots + " " + type + " " + pos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An inventory that we are aware of.
|
||||
* <p>
|
||||
* Associated with a {@link BlockPos} in {@link WorldDataContainer#rememberedInventories}.
|
||||
*/
|
||||
public static class RememberedInventory implements IRememberedInventory {
|
||||
public Optional<List<ItemStack>> echest() {
|
||||
return Optional.ofNullable(getCurrent().contents).map(Collections::unmodifiableList);
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of items in the inventory
|
||||
*/
|
||||
private final List<ItemStack> items;
|
||||
public EnderChestMemory getCurrent() {
|
||||
Path path = baritone.getWorldProvider().getCurrentWorld().directory;
|
||||
return EnderChestMemory.getByServerAndPlayer(path.getParent(), ctx.player().getUniqueID());
|
||||
}
|
||||
|
||||
/**
|
||||
* The last known window ID of the inventory
|
||||
*/
|
||||
private int windowId;
|
||||
public static class EnderChestMemory {
|
||||
private static final Map<Path, EnderChestMemory> memory = new HashMap<>();
|
||||
private final Path enderChest;
|
||||
private List<ItemStack> contents;
|
||||
|
||||
/**
|
||||
* The size of the inventory
|
||||
*/
|
||||
private int size;
|
||||
|
||||
private RememberedInventory() {
|
||||
this.items = new ArrayList<>();
|
||||
private EnderChestMemory(Path enderChest) {
|
||||
this.enderChest = enderChest;
|
||||
System.out.println("Echest storing in " + enderChest);
|
||||
try {
|
||||
this.contents = ContainerMemory.readItemStacks(Files.readAllBytes(enderChest));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("CANNOT read echest =( =(");
|
||||
this.contents = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<ItemStack> getContents() {
|
||||
return Collections.unmodifiableList(this.items);
|
||||
public synchronized void save() {
|
||||
System.out.println("Saving");
|
||||
if (contents != null) {
|
||||
try {
|
||||
enderChest.getParent().toFile().mkdir();
|
||||
Files.write(enderChest, ContainerMemory.writeItemStacks(contents));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("CANNOT save echest =( =(");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getSize() {
|
||||
return this.size;
|
||||
private static synchronized EnderChestMemory getByServerAndPlayer(Path serverStorage, UUID player) {
|
||||
return memory.computeIfAbsent(serverStorage.resolve("echests").resolve(player.toString()), EnderChestMemory::new);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,198 +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.behavior;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.behavior.IMineBehavior;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalBlock;
|
||||
import baritone.api.pathing.goals.GoalComposite;
|
||||
import baritone.api.pathing.goals.GoalTwoBlocks;
|
||||
import baritone.cache.CachedChunk;
|
||||
import baritone.cache.ChunkPacker;
|
||||
import baritone.cache.WorldProvider;
|
||||
import baritone.cache.WorldScanner;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.Helper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.chunk.EmptyChunk;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Mine blocks of a certain type
|
||||
*
|
||||
* @author leijurv
|
||||
*/
|
||||
public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
|
||||
|
||||
public static final MineBehavior INSTANCE = new MineBehavior();
|
||||
|
||||
private List<Block> mining;
|
||||
private List<BlockPos> locationsCache;
|
||||
private int quantity;
|
||||
|
||||
private MineBehavior() {}
|
||||
|
||||
@Override
|
||||
public void onTick(TickEvent event) {
|
||||
if (event.getType() == TickEvent.Type.OUT) {
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
if (mining == null) {
|
||||
return;
|
||||
}
|
||||
if (quantity > 0) {
|
||||
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 0);
|
||||
int curr = player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum();
|
||||
System.out.println("Currently have " + curr + " " + item);
|
||||
if (curr >= quantity) {
|
||||
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
|
||||
if (mineGoalUpdateInterval != 0) {
|
||||
if (event.getCount() % mineGoalUpdateInterval == 0) {
|
||||
Baritone.INSTANCE.getExecutor().execute(this::rescan);
|
||||
}
|
||||
}
|
||||
updateGoal();
|
||||
PathingBehavior.INSTANCE.revalidateGoal();
|
||||
}
|
||||
|
||||
private void updateGoal() {
|
||||
if (mining == null) {
|
||||
return;
|
||||
}
|
||||
List<BlockPos> locs = locationsCache;
|
||||
if (!locs.isEmpty()) {
|
||||
locs = prune(new ArrayList<>(locs), mining, 64);
|
||||
PathingBehavior.INSTANCE.setGoal(coalesce(locs));
|
||||
PathingBehavior.INSTANCE.path();
|
||||
locationsCache = locs;
|
||||
}
|
||||
}
|
||||
|
||||
private void rescan() {
|
||||
if (mining == null) {
|
||||
return;
|
||||
}
|
||||
List<BlockPos> locs = scanFor(mining, 64);
|
||||
if (locs.isEmpty()) {
|
||||
logDebug("No locations for " + mining + " known, cancelling");
|
||||
mine(0, (String[]) null);
|
||||
return;
|
||||
}
|
||||
locationsCache = locs;
|
||||
}
|
||||
|
||||
public GoalComposite coalesce(List<BlockPos> locs) {
|
||||
return new GoalComposite(locs.stream().map(loc -> {
|
||||
if (!Baritone.settings().forceInternalMining.get()) {
|
||||
return new GoalTwoBlocks(loc);
|
||||
}
|
||||
|
||||
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
|
||||
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
|
||||
if (upwardGoal) {
|
||||
if (downwardGoal) {
|
||||
return new GoalTwoBlocks(loc);
|
||||
} else {
|
||||
return new GoalBlock(loc);
|
||||
}
|
||||
} else {
|
||||
if (downwardGoal) {
|
||||
return new GoalBlock(loc.down());
|
||||
} else {
|
||||
return new GoalTwoBlocks(loc);
|
||||
}
|
||||
}
|
||||
}).toArray(Goal[]::new));
|
||||
}
|
||||
|
||||
public List<BlockPos> scanFor(List<Block> mining, int max) {
|
||||
List<BlockPos> locs = new ArrayList<>();
|
||||
List<Block> uninteresting = new ArrayList<>();
|
||||
//long b = System.currentTimeMillis();
|
||||
for (Block m : mining) {
|
||||
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
|
||||
locs.addAll(WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, 1));
|
||||
} else {
|
||||
uninteresting.add(m);
|
||||
}
|
||||
}
|
||||
//System.out.println("Scan of cached chunks took " + (System.currentTimeMillis() - b) + "ms");
|
||||
if (locs.isEmpty()) {
|
||||
uninteresting = mining;
|
||||
}
|
||||
if (!uninteresting.isEmpty()) {
|
||||
//long before = System.currentTimeMillis();
|
||||
locs.addAll(WorldScanner.INSTANCE.scanLoadedChunks(uninteresting, max, 10, 26));
|
||||
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
|
||||
}
|
||||
return prune(locs, mining, max);
|
||||
}
|
||||
|
||||
public List<BlockPos> prune(List<BlockPos> locs, List<Block> mining, int max) {
|
||||
BlockPos playerFeet = MineBehavior.INSTANCE.playerFeet();
|
||||
locs.sort(Comparator.comparingDouble(playerFeet::distanceSq));
|
||||
|
||||
// remove any that are within loaded chunks that aren't actually what we want
|
||||
locs.removeAll(locs.stream()
|
||||
.filter(pos -> !(MineBehavior.INSTANCE.world().getChunk(pos) instanceof EmptyChunk))
|
||||
.filter(pos -> !mining.contains(BlockStateInterface.get(pos).getBlock()))
|
||||
.collect(Collectors.toList()));
|
||||
if (locs.size() > max) {
|
||||
return locs.subList(0, max);
|
||||
}
|
||||
return locs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mine(int quantity, String... blocks) {
|
||||
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList());
|
||||
this.quantity = quantity;
|
||||
this.locationsCache = new ArrayList<>();
|
||||
rescan();
|
||||
updateGoal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mine(int quantity, Block... blocks) {
|
||||
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
|
||||
this.quantity = quantity;
|
||||
this.locationsCache = new ArrayList<>();
|
||||
rescan();
|
||||
updateGoal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
mine(0, (String[]) null);
|
||||
PathingBehavior.INSTANCE.cancel();
|
||||
}
|
||||
}
|
||||
@@ -24,68 +24,105 @@ import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.RenderEvent;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.pathing.calc.IPath;
|
||||
import baritone.api.pathing.calc.IPathFinder;
|
||||
import baritone.api.pathing.goals.Goal;
|
||||
import baritone.api.pathing.goals.GoalXZ;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.PathCalculationResult;
|
||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||
import baritone.pathing.calc.AStarPathFinder;
|
||||
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||
import baritone.pathing.calc.CutoffPath;
|
||||
import baritone.pathing.movement.CalculationContext;
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.path.CutoffPath;
|
||||
import baritone.pathing.path.PathExecutor;
|
||||
import baritone.utils.BlockBreakHelper;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.utils.PathRenderer;
|
||||
import baritone.utils.pathing.Favoring;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.chunk.EmptyChunk;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
public final class PathingBehavior extends Behavior implements IPathingBehavior, Helper {
|
||||
|
||||
public static final PathingBehavior INSTANCE = new PathingBehavior();
|
||||
|
||||
private PathExecutor current;
|
||||
private PathExecutor next;
|
||||
|
||||
private Goal goal;
|
||||
|
||||
private volatile boolean isPathCalcInProgress;
|
||||
private boolean safeToCancel;
|
||||
private boolean pauseRequestedLastTick;
|
||||
private boolean cancelRequested;
|
||||
private boolean calcFailedLastTick;
|
||||
|
||||
private volatile AbstractNodeCostSearch inProgress;
|
||||
private final Object pathCalcLock = new Object();
|
||||
|
||||
private final Object pathPlanLock = new Object();
|
||||
|
||||
private boolean lastAutoJump;
|
||||
|
||||
private PathingBehavior() {}
|
||||
private final LinkedBlockingQueue<PathEvent> toDispatch = new LinkedBlockingQueue<>();
|
||||
|
||||
private void dispatchPathEvent(PathEvent event) {
|
||||
Baritone.INSTANCE.getExecutor().execute(() -> Baritone.INSTANCE.getGameEventHandler().onPathEvent(event));
|
||||
public PathingBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
private void queuePathEvent(PathEvent event) {
|
||||
toDispatch.add(event);
|
||||
}
|
||||
|
||||
private void dispatchEvents() {
|
||||
ArrayList<PathEvent> curr = new ArrayList<>();
|
||||
toDispatch.drainTo(curr);
|
||||
calcFailedLastTick = curr.contains(PathEvent.CALC_FAILED);
|
||||
for (PathEvent event : curr) {
|
||||
baritone.getGameEventHandler().onPathEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick(TickEvent event) {
|
||||
dispatchEvents();
|
||||
if (event.getType() == TickEvent.Type.OUT) {
|
||||
this.cancel();
|
||||
secretInternalSegmentCancel();
|
||||
baritone.getPathingControlManager().cancelEverything();
|
||||
return;
|
||||
}
|
||||
mc.playerController.setPlayerCapabilities(mc.player);
|
||||
baritone.getPathingControlManager().preTick();
|
||||
tickPath();
|
||||
dispatchEvents();
|
||||
}
|
||||
|
||||
private void tickPath() {
|
||||
if (pauseRequestedLastTick && safeToCancel) {
|
||||
pauseRequestedLastTick = false;
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
|
||||
return;
|
||||
}
|
||||
if (cancelRequested) {
|
||||
cancelRequested = false;
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
}
|
||||
if (current == null) {
|
||||
return;
|
||||
}
|
||||
boolean safe = current.onTick(event);
|
||||
safeToCancel = current.onTick();
|
||||
synchronized (pathPlanLock) {
|
||||
if (current.failed() || current.finished()) {
|
||||
current = null;
|
||||
if (goal == null || goal.isInGoal(playerFeet())) {
|
||||
if (goal == null || goal.isInGoal(ctx.playerFeet())) {
|
||||
logDebug("All done. At " + goal);
|
||||
dispatchPathEvent(PathEvent.AT_GOAL);
|
||||
queuePathEvent(PathEvent.AT_GOAL);
|
||||
next = null;
|
||||
return;
|
||||
}
|
||||
if (next != null && !next.getPath().positions().contains(playerFeet())) {
|
||||
if (next != null && !next.getPath().positions().contains(ctx.playerFeet())) {
|
||||
// if the current path failed, we may not actually be on the next one, so make sure
|
||||
logDebug("Discarding next path as it does not contain current position");
|
||||
// for example if we had a nicely planned ahead path that starts where current ends
|
||||
@@ -93,46 +130,45 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
// but if we fail in the middle of current
|
||||
// we're nowhere close to our planned ahead path
|
||||
// so need to discard it sadly.
|
||||
dispatchPathEvent(PathEvent.DISCARD_NEXT);
|
||||
queuePathEvent(PathEvent.DISCARD_NEXT);
|
||||
next = null;
|
||||
}
|
||||
if (next != null) {
|
||||
logDebug("Continuing on to planned next path");
|
||||
dispatchPathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
|
||||
queuePathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
|
||||
current = next;
|
||||
next = null;
|
||||
current.onTick(event);
|
||||
current.onTick();
|
||||
return;
|
||||
}
|
||||
// at this point, current just ended, but we aren't in the goal and have no plan for the future
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
dispatchPathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
|
||||
if (inProgress != null) {
|
||||
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
|
||||
// if we aren't calculating right now
|
||||
return;
|
||||
}
|
||||
dispatchPathEvent(PathEvent.CALC_STARTED);
|
||||
findPathInNewThread(pathStart(), true, Optional.empty());
|
||||
queuePathEvent(PathEvent.CALC_STARTED);
|
||||
findPathInNewThread(pathStart(), true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// at this point, we know current is in progress
|
||||
if (safe) {
|
||||
// a movement just ended
|
||||
if (next != null) {
|
||||
if (next.snipsnapifpossible()) {
|
||||
// jump directly onto the next path
|
||||
logDebug("Splicing into planned next path early...");
|
||||
dispatchPathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
|
||||
current = next;
|
||||
next = null;
|
||||
current.onTick(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (safeToCancel && next != null && next.snipsnapifpossible()) {
|
||||
// a movement just ended; jump directly onto the next path
|
||||
logDebug("Splicing into planned next path early...");
|
||||
queuePathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
|
||||
current = next;
|
||||
next = null;
|
||||
current.onTick();
|
||||
return;
|
||||
}
|
||||
current = current.trySplice(next);
|
||||
if (next != null && current.getPath().getDest().equals(next.getPath().getDest())) {
|
||||
next = null;
|
||||
}
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
if (inProgress != null) {
|
||||
// if we aren't calculating right now
|
||||
return;
|
||||
}
|
||||
@@ -147,8 +183,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) {
|
||||
// and this path has 5 seconds or less left
|
||||
logDebug("Path almost over. Planning ahead...");
|
||||
dispatchPathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
|
||||
findPathInNewThread(current.getPath().getDest(), false, Optional.of(current.getPath()));
|
||||
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
|
||||
findPathInNewThread(current.getPath().getDest(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,11 +215,15 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGoal(Goal goal) {
|
||||
public void secretInternalSetGoal(Goal goal) {
|
||||
this.goal = goal;
|
||||
}
|
||||
|
||||
public boolean secretInternalSetGoalAndPath(Goal goal) {
|
||||
secretInternalSetGoal(goal);
|
||||
return secretInternalPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Goal getGoal() {
|
||||
return goal;
|
||||
@@ -200,8 +240,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IPathFinder> getPathFinder() {
|
||||
return Optional.ofNullable(AbstractNodeCostSearch.currentlyRunning());
|
||||
public Optional<AbstractNodeCostSearch> getInProgress() {
|
||||
return Optional.ofNullable(inProgress);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -209,18 +249,65 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
return this.current != null;
|
||||
}
|
||||
|
||||
public boolean isSafeToCancel() {
|
||||
return current == null || safeToCancel;
|
||||
}
|
||||
|
||||
public void requestPause() {
|
||||
pauseRequestedLastTick = true;
|
||||
}
|
||||
|
||||
public boolean cancelSegmentIfSafe() {
|
||||
if (isSafeToCancel()) {
|
||||
secretInternalSegmentCancel();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
dispatchPathEvent(PathEvent.CANCELED);
|
||||
current = null;
|
||||
next = null;
|
||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
|
||||
BlockBreakHelper.stopBreakingBlock();
|
||||
public boolean cancelEverything() {
|
||||
boolean doIt = isSafeToCancel();
|
||||
if (doIt) {
|
||||
secretInternalSegmentCancel();
|
||||
}
|
||||
baritone.getPathingControlManager().cancelEverything();
|
||||
return doIt;
|
||||
}
|
||||
|
||||
public boolean calcFailedLastTick() { // NOT exposed on public api
|
||||
return calcFailedLastTick;
|
||||
}
|
||||
|
||||
public void softCancelIfSafe() {
|
||||
synchronized (pathPlanLock) {
|
||||
if (!isSafeToCancel()) {
|
||||
return;
|
||||
}
|
||||
current = null;
|
||||
next = null;
|
||||
}
|
||||
cancelRequested = true;
|
||||
getInProgress().ifPresent(AbstractNodeCostSearch::cancel); // only cancel ours
|
||||
// do everything BUT clear keys
|
||||
}
|
||||
|
||||
// just cancel the current path
|
||||
public void secretInternalSegmentCancel() {
|
||||
queuePathEvent(PathEvent.CANCELED);
|
||||
synchronized (pathPlanLock) {
|
||||
current = null;
|
||||
next = null;
|
||||
}
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
|
||||
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
|
||||
}
|
||||
|
||||
public void forceCancel() { // NOT exposed on public api
|
||||
isPathCalcInProgress = false;
|
||||
cancelEverything();
|
||||
secretInternalSegmentCancel();
|
||||
inProgress = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,12 +315,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
*
|
||||
* @return true if this call started path calculation, false if it was already calculating or executing a path
|
||||
*/
|
||||
@Override
|
||||
public boolean path() {
|
||||
public boolean secretInternalPath() {
|
||||
if (goal == null) {
|
||||
return false;
|
||||
}
|
||||
if (goal.isInGoal(playerFeet())) {
|
||||
if (goal.isInGoal(ctx.playerFeet())) {
|
||||
return false;
|
||||
}
|
||||
synchronized (pathPlanLock) {
|
||||
@@ -241,27 +327,33 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
return false;
|
||||
}
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
if (inProgress != null) {
|
||||
return false;
|
||||
}
|
||||
dispatchPathEvent(PathEvent.CALC_STARTED);
|
||||
findPathInNewThread(pathStart(), true, Optional.empty());
|
||||
queuePathEvent(PathEvent.CALC_STARTED);
|
||||
findPathInNewThread(pathStart(), true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void secretCursedFunctionDoNotCall(IPath path) {
|
||||
synchronized (pathPlanLock) {
|
||||
current = new PathExecutor(this, path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #209
|
||||
*
|
||||
* @return The starting {@link BlockPos} for a new path
|
||||
*/
|
||||
public BlockPos pathStart() {
|
||||
BetterBlockPos feet = playerFeet();
|
||||
if (!MovementHelper.canWalkOn(feet.down())) {
|
||||
if (player().onGround) {
|
||||
double playerX = player().posX;
|
||||
double playerZ = player().posZ;
|
||||
public BetterBlockPos pathStart() { // TODO move to a helper or util class
|
||||
BetterBlockPos feet = ctx.playerFeet();
|
||||
if (!MovementHelper.canWalkOn(ctx, feet.down())) {
|
||||
if (ctx.player().onGround) {
|
||||
double playerX = ctx.player().posX;
|
||||
double playerZ = ctx.player().posZ;
|
||||
ArrayList<BetterBlockPos> closest = new ArrayList<>();
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
@@ -277,7 +369,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
// can't possibly be sneaking off of this one, we're too far away
|
||||
continue;
|
||||
}
|
||||
if (MovementHelper.canWalkOn(possibleSupport.down()) && MovementHelper.canWalkThrough(possibleSupport) && MovementHelper.canWalkThrough(possibleSupport.up())) {
|
||||
if (MovementHelper.canWalkOn(ctx, possibleSupport.down()) && MovementHelper.canWalkThrough(ctx, possibleSupport) && MovementHelper.canWalkThrough(ctx, possibleSupport.up())) {
|
||||
// this is plausible
|
||||
logDebug("Faking path start assuming player is standing off the edge of a block");
|
||||
return possibleSupport;
|
||||
@@ -287,7 +379,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
} else {
|
||||
// !onGround
|
||||
// we're in the middle of a jump
|
||||
if (MovementHelper.canWalkOn(feet.down().down())) {
|
||||
if (MovementHelper.canWalkOn(ctx, feet.down().down())) {
|
||||
logDebug("Faking path start assuming player is midair and falling");
|
||||
return feet.down();
|
||||
}
|
||||
@@ -302,22 +394,46 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
* @param start
|
||||
* @param talkAboutIt
|
||||
*/
|
||||
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt, final Optional<IPath> previous) {
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
throw new IllegalStateException("Already doing it");
|
||||
}
|
||||
isPathCalcInProgress = true;
|
||||
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt) {
|
||||
// this must be called with synchronization on pathCalcLock!
|
||||
// actually, we can check this, muahaha
|
||||
if (!Thread.holdsLock(pathCalcLock)) {
|
||||
throw new IllegalStateException("Must be called with synchronization on pathCalcLock");
|
||||
// why do it this way? it's already indented so much that putting the whole thing in a synchronized(pathCalcLock) was just too much lol
|
||||
}
|
||||
Baritone.INSTANCE.getExecutor().execute(() -> {
|
||||
if (inProgress != null) {
|
||||
throw new IllegalStateException("Already doing it"); // should have been checked by caller
|
||||
}
|
||||
Goal goal = this.goal;
|
||||
if (goal == null) {
|
||||
logDebug("no goal"); // TODO should this be an exception too? definitely should be checked by caller
|
||||
return;
|
||||
}
|
||||
long primaryTimeout;
|
||||
long failureTimeout;
|
||||
if (current == null) {
|
||||
primaryTimeout = Baritone.settings().primaryTimeoutMS.get();
|
||||
failureTimeout = Baritone.settings().failureTimeoutMS.get();
|
||||
} else {
|
||||
primaryTimeout = Baritone.settings().planAheadPrimaryTimeoutMS.get();
|
||||
failureTimeout = Baritone.settings().planAheadFailureTimeoutMS.get();
|
||||
}
|
||||
CalculationContext context = new CalculationContext(baritone, true); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
|
||||
AbstractNodeCostSearch pathfinder = createPathfinder(start, goal, current == null ? null : current.getPath(), context);
|
||||
if (!Objects.equals(pathfinder.getGoal(), goal)) { // will return the exact same object if simplification didn't happen
|
||||
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
|
||||
}
|
||||
inProgress = pathfinder;
|
||||
Baritone.getExecutor().execute(() -> {
|
||||
if (talkAboutIt) {
|
||||
logDebug("Starting to search for path from " + start + " to " + goal);
|
||||
}
|
||||
|
||||
Optional<IPath> path = findPath(start, previous);
|
||||
PathCalculationResult calcResult = pathfinder.calculate(primaryTimeout, failureTimeout);
|
||||
Optional<IPath> path = calcResult.getPath();
|
||||
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
|
||||
path = path.map(p -> {
|
||||
IPath result = p.cutoffAtLoadedChunks();
|
||||
IPath result = p.cutoffAtLoadedChunks(context.bsi());
|
||||
|
||||
if (result instanceof CutoffPath) {
|
||||
logDebug("Cutting off path at edge of loaded chunks");
|
||||
@@ -338,114 +454,61 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
}
|
||||
|
||||
return result;
|
||||
}).map(PathExecutor::new);
|
||||
}).map(p -> new PathExecutor(this, p));
|
||||
|
||||
synchronized (pathPlanLock) {
|
||||
if (current == null) {
|
||||
if (executor.isPresent()) {
|
||||
dispatchPathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
||||
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
||||
current = executor.get();
|
||||
} else {
|
||||
dispatchPathEvent(PathEvent.CALC_FAILED);
|
||||
if (calcResult.getType() != PathCalculationResult.Type.CANCELLATION && calcResult.getType() != PathCalculationResult.Type.EXCEPTION) {
|
||||
// don't dispatch CALC_FAILED on cancellation
|
||||
queuePathEvent(PathEvent.CALC_FAILED);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (next == null) {
|
||||
if (executor.isPresent()) {
|
||||
dispatchPathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
|
||||
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
|
||||
next = executor.get();
|
||||
} else {
|
||||
dispatchPathEvent(PathEvent.NEXT_CALC_FAILED);
|
||||
queuePathEvent(PathEvent.NEXT_CALC_FAILED);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("I have no idea what to do with this path");
|
||||
//throw new IllegalStateException("I have no idea what to do with this path");
|
||||
// no point in throwing an exception here, and it gets it stuck with inProgress being not null
|
||||
logDirect("Warning: PathingBehaivor illegal state! Discarding invalid path!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (talkAboutIt && current != null && current.getPath() != null) {
|
||||
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
|
||||
logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||
} else {
|
||||
logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||
|
||||
if (talkAboutIt && current != null && current.getPath() != null) {
|
||||
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
|
||||
logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||
} else {
|
||||
logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||
}
|
||||
}
|
||||
synchronized (pathCalcLock) {
|
||||
inProgress = null;
|
||||
}
|
||||
}
|
||||
synchronized (pathCalcLock) {
|
||||
isPathCalcInProgress = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually do the pathing
|
||||
*
|
||||
* @param start
|
||||
* @return
|
||||
*/
|
||||
private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous) {
|
||||
Goal goal = this.goal;
|
||||
if (goal == null) {
|
||||
logDebug("no goal");
|
||||
return Optional.empty();
|
||||
}
|
||||
if (Baritone.settings().simplifyUnloadedYCoord.get()) {
|
||||
BlockPos pos = null;
|
||||
if (goal instanceof IGoalRenderPos) {
|
||||
pos = ((IGoalRenderPos) goal).getGoalPos();
|
||||
}
|
||||
|
||||
if (pos != null && world().getChunk(pos) instanceof EmptyChunk) {
|
||||
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
|
||||
goal = new GoalXZ(pos.getX(), pos.getZ());
|
||||
}
|
||||
}
|
||||
long timeout;
|
||||
if (current == null) {
|
||||
timeout = Baritone.settings().pathTimeoutMS.<Long>get();
|
||||
} else {
|
||||
timeout = Baritone.settings().planAheadTimeoutMS.<Long>get();
|
||||
}
|
||||
Optional<HashSet<Long>> favoredPositions;
|
||||
if (Baritone.settings().backtrackCostFavoringCoefficient.get() == 1D) {
|
||||
favoredPositions = Optional.empty();
|
||||
} else {
|
||||
favoredPositions = previous.map(IPath::positions).map(Collection::stream).map(x -> x.map(BetterBlockPos::longHash)).map(x -> x.collect(Collectors.toList())).map(HashSet::new); // <-- okay this is EPIC
|
||||
}
|
||||
try {
|
||||
IPathFinder pf = new AStarPathFinder(start.getX(), start.getY(), start.getZ(), goal, favoredPositions);
|
||||
return pf.calculate(timeout);
|
||||
} catch (Exception e) {
|
||||
logDebug("Pathing exception: " + e);
|
||||
e.printStackTrace();
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void revalidateGoal() {
|
||||
if (!Baritone.settings().cancelOnGoalInvalidation.get()) {
|
||||
return;
|
||||
}
|
||||
synchronized (pathPlanLock) {
|
||||
if (current == null || goal == null) {
|
||||
return;
|
||||
}
|
||||
Goal intended = current.getPath().getGoal();
|
||||
BlockPos end = current.getPath().getDest();
|
||||
if (intended.isInGoal(end) && !goal.isInGoal(end)) {
|
||||
// this path used to end in the goal
|
||||
// but the goal has changed, so there's no reason to continue...
|
||||
cancel();
|
||||
public static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) {
|
||||
Goal transformed = goal;
|
||||
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
|
||||
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
|
||||
if (context.world().getChunk(pos) instanceof EmptyChunk) {
|
||||
transformed = new GoalXZ(pos.getX(), pos.getZ());
|
||||
}
|
||||
}
|
||||
Favoring favoring = new Favoring(context.getBaritone().getPlayerContext(), previous);
|
||||
return new AStarPathFinder(start.getX(), start.getY(), start.getZ(), transformed, favoring, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRenderPass(RenderEvent event) {
|
||||
PathRenderer.render(event, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||
}
|
||||
}
|
||||
|
||||
101
src/main/java/baritone/cache/CachedChunk.java
vendored
101
src/main/java/baritone/cache/CachedChunk.java
vendored
@@ -17,8 +17,6 @@
|
||||
|
||||
package baritone.cache;
|
||||
|
||||
import baritone.api.cache.IBlockTypeAccess;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.utils.pathing.PathingBlockType;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
@@ -29,44 +27,66 @@ import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/3/2018 1:04 AM
|
||||
* @since 8/3/2018
|
||||
*/
|
||||
public final class CachedChunk implements IBlockTypeAccess, Helper {
|
||||
public final class CachedChunk {
|
||||
|
||||
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(new HashSet<Block>() {{
|
||||
add(Blocks.DIAMOND_ORE);
|
||||
add(Blocks.DIAMOND_BLOCK);
|
||||
//add(Blocks.COAL_ORE);
|
||||
add(Blocks.COAL_BLOCK);
|
||||
//add(Blocks.IRON_ORE);
|
||||
add(Blocks.IRON_BLOCK);
|
||||
//add(Blocks.GOLD_ORE);
|
||||
add(Blocks.GOLD_BLOCK);
|
||||
add(Blocks.EMERALD_ORE);
|
||||
add(Blocks.EMERALD_BLOCK);
|
||||
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
|
||||
|
||||
add(Blocks.ENDER_CHEST);
|
||||
add(Blocks.FURNACE);
|
||||
add(Blocks.CHEST);
|
||||
add(Blocks.END_PORTAL);
|
||||
add(Blocks.END_PORTAL_FRAME);
|
||||
add(Blocks.MOB_SPAWNER);
|
||||
// TODO add all shulker colors
|
||||
add(Blocks.PORTAL);
|
||||
add(Blocks.HOPPER);
|
||||
add(Blocks.BEACON);
|
||||
add(Blocks.BREWING_STAND);
|
||||
add(Blocks.SKULL);
|
||||
add(Blocks.ENCHANTING_TABLE);
|
||||
add(Blocks.ANVIL);
|
||||
add(Blocks.LIT_FURNACE);
|
||||
add(Blocks.BED);
|
||||
add(Blocks.DRAGON_EGG);
|
||||
add(Blocks.JUKEBOX);
|
||||
add(Blocks.END_GATEWAY);
|
||||
add(Blocks.WEB);
|
||||
add(Blocks.NETHER_WART);
|
||||
}});
|
||||
static {
|
||||
HashSet<Block> temp = new HashSet<>();
|
||||
//temp.add(Blocks.DIAMOND_ORE);
|
||||
temp.add(Blocks.DIAMOND_BLOCK);
|
||||
//temp.add(Blocks.COAL_ORE);
|
||||
temp.add(Blocks.COAL_BLOCK);
|
||||
//temp.add(Blocks.IRON_ORE);
|
||||
temp.add(Blocks.IRON_BLOCK);
|
||||
//temp.add(Blocks.GOLD_ORE);
|
||||
temp.add(Blocks.GOLD_BLOCK);
|
||||
temp.add(Blocks.EMERALD_ORE);
|
||||
temp.add(Blocks.EMERALD_BLOCK);
|
||||
|
||||
temp.add(Blocks.ENDER_CHEST);
|
||||
temp.add(Blocks.FURNACE);
|
||||
temp.add(Blocks.CHEST);
|
||||
temp.add(Blocks.TRAPPED_CHEST);
|
||||
temp.add(Blocks.END_PORTAL);
|
||||
temp.add(Blocks.END_PORTAL_FRAME);
|
||||
temp.add(Blocks.MOB_SPAWNER);
|
||||
temp.add(Blocks.BARRIER);
|
||||
temp.add(Blocks.OBSERVER);
|
||||
temp.add(Blocks.WHITE_SHULKER_BOX);
|
||||
temp.add(Blocks.ORANGE_SHULKER_BOX);
|
||||
temp.add(Blocks.MAGENTA_SHULKER_BOX);
|
||||
temp.add(Blocks.LIGHT_BLUE_SHULKER_BOX);
|
||||
temp.add(Blocks.YELLOW_SHULKER_BOX);
|
||||
temp.add(Blocks.LIME_SHULKER_BOX);
|
||||
temp.add(Blocks.PINK_SHULKER_BOX);
|
||||
temp.add(Blocks.GRAY_SHULKER_BOX);
|
||||
temp.add(Blocks.SILVER_SHULKER_BOX);
|
||||
temp.add(Blocks.CYAN_SHULKER_BOX);
|
||||
temp.add(Blocks.PURPLE_SHULKER_BOX);
|
||||
temp.add(Blocks.BLUE_SHULKER_BOX);
|
||||
temp.add(Blocks.BROWN_SHULKER_BOX);
|
||||
temp.add(Blocks.GREEN_SHULKER_BOX);
|
||||
temp.add(Blocks.RED_SHULKER_BOX);
|
||||
temp.add(Blocks.BLACK_SHULKER_BOX);
|
||||
temp.add(Blocks.PORTAL);
|
||||
temp.add(Blocks.HOPPER);
|
||||
temp.add(Blocks.BEACON);
|
||||
temp.add(Blocks.BREWING_STAND);
|
||||
temp.add(Blocks.SKULL);
|
||||
temp.add(Blocks.ENCHANTING_TABLE);
|
||||
temp.add(Blocks.ANVIL);
|
||||
temp.add(Blocks.LIT_FURNACE);
|
||||
temp.add(Blocks.BED);
|
||||
temp.add(Blocks.DRAGON_EGG);
|
||||
temp.add(Blocks.JUKEBOX);
|
||||
temp.add(Blocks.END_GATEWAY);
|
||||
temp.add(Blocks.WEB);
|
||||
temp.add(Blocks.NETHER_WART);
|
||||
BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* The size of the chunk data in bits. Equal to 16 KiB.
|
||||
@@ -121,8 +141,7 @@ public final class CachedChunk implements IBlockTypeAccess, Helper {
|
||||
calculateHeightMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBlockState getBlock(int x, int y, int z) {
|
||||
public final IBlockState getBlock(int x, int y, int z, int dimension) {
|
||||
int internalPos = z << 4 | x;
|
||||
if (heightMap[internalPos] == y) {
|
||||
// we have this exact block, it's a surface block
|
||||
@@ -133,10 +152,10 @@ public final class CachedChunk implements IBlockTypeAccess, Helper {
|
||||
return overview[internalPos];
|
||||
}
|
||||
PathingBlockType type = getType(x, y, z);
|
||||
if (type == PathingBlockType.SOLID && y == 127 && mc.player.dimension == -1) {
|
||||
if (type == PathingBlockType.SOLID && y == 127 && dimension == -1) {
|
||||
return Blocks.BEDROCK.getDefaultState();
|
||||
}
|
||||
return ChunkPacker.pathingTypeToBlock(type);
|
||||
return ChunkPacker.pathingTypeToBlock(type, dimension);
|
||||
}
|
||||
|
||||
private PathingBlockType getType(int x, int y, int z) {
|
||||
|
||||
24
src/main/java/baritone/cache/CachedRegion.java
vendored
24
src/main/java/baritone/cache/CachedRegion.java
vendored
@@ -32,7 +32,7 @@ import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/3/2018 9:35 PM
|
||||
* @since 8/3/2018
|
||||
*/
|
||||
public final class CachedRegion implements ICachedRegion {
|
||||
|
||||
@@ -59,22 +59,25 @@ public final class CachedRegion implements ICachedRegion {
|
||||
*/
|
||||
private final int z;
|
||||
|
||||
private final int dimension;
|
||||
|
||||
/**
|
||||
* Has this region been modified since its most recent load or save
|
||||
*/
|
||||
private boolean hasUnsavedChanges;
|
||||
|
||||
CachedRegion(int x, int z) {
|
||||
CachedRegion(int x, int z, int dimension) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.hasUnsavedChanges = false;
|
||||
this.dimension = dimension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IBlockState getBlock(int x, int y, int z) {
|
||||
CachedChunk chunk = chunks[x >> 4][z >> 4];
|
||||
if (chunk != null) {
|
||||
return chunk.getBlock(x & 15, y, z & 15);
|
||||
return chunk.getBlock(x & 15, y, z & 15, dimension);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -319,6 +322,21 @@ public final class CachedRegion implements ICachedRegion {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized final CachedChunk mostRecentlyModified() {
|
||||
CachedChunk recent = null;
|
||||
for (int x = 0; x < 32; x++) {
|
||||
for (int z = 0; z < 32; z++) {
|
||||
if (this.chunks[x][z] == null) {
|
||||
continue;
|
||||
}
|
||||
if (recent == null || this.chunks[x][z].cacheTimestamp > recent.cacheTimestamp) {
|
||||
recent = this.chunks[x][z];
|
||||
}
|
||||
}
|
||||
}
|
||||
return recent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The region x coordinate
|
||||
*/
|
||||
|
||||
83
src/main/java/baritone/cache/CachedWorld.java
vendored
83
src/main/java/baritone/cache/CachedWorld.java
vendored
@@ -18,7 +18,10 @@
|
||||
package baritone.cache;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.cache.ICachedWorld;
|
||||
import baritone.api.cache.IWorldData;
|
||||
import baritone.utils.Helper;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
@@ -35,7 +38,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/4/2018 12:02 AM
|
||||
* @since 8/4/2018
|
||||
*/
|
||||
public final class CachedWorld implements ICachedWorld, Helper {
|
||||
|
||||
@@ -56,7 +59,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
|
||||
private final LinkedBlockingQueue<Chunk> toPack = new LinkedBlockingQueue<>();
|
||||
|
||||
CachedWorld(Path directory) {
|
||||
private final int dimension;
|
||||
|
||||
CachedWorld(Path directory, int dimension) {
|
||||
if (!Files.exists(directory)) {
|
||||
try {
|
||||
Files.createDirectories(directory);
|
||||
@@ -64,11 +69,12 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
}
|
||||
}
|
||||
this.directory = directory.toString();
|
||||
this.dimension = dimension;
|
||||
System.out.println("Cached world directory: " + directory);
|
||||
// Insert an invalid region element
|
||||
cachedRegions.put(0, null);
|
||||
Baritone.INSTANCE.getExecutor().execute(new PackerThread());
|
||||
Baritone.INSTANCE.getExecutor().execute(() -> {
|
||||
Baritone.getExecutor().execute(new PackerThread());
|
||||
Baritone.getExecutor().execute(() -> {
|
||||
try {
|
||||
Thread.sleep(30000);
|
||||
while (true) {
|
||||
@@ -103,10 +109,10 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final LinkedList<BlockPos> getLocationsOf(String block, int maximum, int maxRegionDistanceSq) {
|
||||
public final LinkedList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq) {
|
||||
LinkedList<BlockPos> res = new LinkedList<>();
|
||||
int playerRegionX = playerFeet().getX() >> 9;
|
||||
int playerRegionZ = playerFeet().getZ() >> 9;
|
||||
int centerRegionX = centerX >> 9;
|
||||
int centerRegionZ = centerZ >> 9;
|
||||
|
||||
int searchRadius = 0;
|
||||
while (searchRadius <= maxRegionDistanceSq) {
|
||||
@@ -116,8 +122,8 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
if (distance != searchRadius) {
|
||||
continue;
|
||||
}
|
||||
int regionX = xoff + playerRegionX;
|
||||
int regionZ = zoff + playerRegionZ;
|
||||
int regionX = xoff + centerRegionX;
|
||||
int regionZ = zoff + centerRegionZ;
|
||||
CachedRegion region = getOrCreateRegion(regionX, regionZ);
|
||||
if (region != null) {
|
||||
// TODO: 100% verify if this or addAll is faster.
|
||||
@@ -147,6 +153,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
region.removeExpired();
|
||||
}
|
||||
}); // even if we aren't saving to disk, still delete expired old chunks from RAM
|
||||
prune();
|
||||
return;
|
||||
}
|
||||
long start = System.nanoTime() / 1000000L;
|
||||
@@ -157,6 +164,58 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
});
|
||||
long now = System.nanoTime() / 1000000L;
|
||||
System.out.println("World save took " + (now - start) + "ms");
|
||||
prune();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete regions that are too far from the player
|
||||
*/
|
||||
private synchronized void prune() {
|
||||
if (!Baritone.settings().pruneRegionsFromRAM.get()) {
|
||||
return;
|
||||
}
|
||||
BlockPos pruneCenter = guessPosition();
|
||||
for (CachedRegion region : allRegions()) {
|
||||
if (region == null) {
|
||||
continue;
|
||||
}
|
||||
int distX = (region.getX() * 512 + 256) - pruneCenter.getX();
|
||||
int distZ = (region.getZ() * 512 + 256) - pruneCenter.getZ();
|
||||
double dist = Math.sqrt(distX * distX + distZ * distZ);
|
||||
if (dist > 1024) {
|
||||
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
|
||||
cachedRegions.remove(getRegionID(region.getX(), region.getZ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we are still in this world and dimension, return player feet, otherwise return most recently modified chunk
|
||||
*/
|
||||
private BlockPos guessPosition() {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
IWorldData data = ibaritone.getWorldProvider().getCurrentWorld();
|
||||
if (data != null && data.getCachedWorld() == this) {
|
||||
return ibaritone.getPlayerContext().playerFeet();
|
||||
}
|
||||
}
|
||||
CachedChunk mostRecentlyModified = null;
|
||||
for (CachedRegion region : allRegions()) {
|
||||
if (region == null) {
|
||||
continue;
|
||||
}
|
||||
CachedChunk ch = region.mostRecentlyModified();
|
||||
if (ch == null) {
|
||||
continue;
|
||||
}
|
||||
if (mostRecentlyModified == null || mostRecentlyModified.cacheTimestamp < ch.cacheTimestamp) {
|
||||
mostRecentlyModified = ch;
|
||||
}
|
||||
}
|
||||
if (mostRecentlyModified == null) {
|
||||
return new BlockPos(0, 0, 0);
|
||||
}
|
||||
return new BlockPos(mostRecentlyModified.x * 16 + 8, 0, mostRecentlyModified.z * 16 + 8);
|
||||
}
|
||||
|
||||
private synchronized List<CachedRegion> allRegions() {
|
||||
@@ -190,12 +249,16 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
*/
|
||||
private synchronized CachedRegion getOrCreateRegion(int regionX, int regionZ) {
|
||||
return cachedRegions.computeIfAbsent(getRegionID(regionX, regionZ), id -> {
|
||||
CachedRegion newRegion = new CachedRegion(regionX, regionZ);
|
||||
CachedRegion newRegion = new CachedRegion(regionX, regionZ, dimension);
|
||||
newRegion.load(this.directory);
|
||||
return newRegion;
|
||||
});
|
||||
}
|
||||
|
||||
public void tryLoadFromDisk(int regionX, int regionZ) {
|
||||
getOrCreateRegion(regionX, regionZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the region ID based on the region coordinates. 0 will be
|
||||
* returned if the specified region coordinates are out of bounds.
|
||||
|
||||
17
src/main/java/baritone/cache/ChunkPacker.java
vendored
17
src/main/java/baritone/cache/ChunkPacker.java
vendored
@@ -18,7 +18,6 @@
|
||||
package baritone.cache;
|
||||
|
||||
import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.utils.Helper;
|
||||
import baritone.utils.pathing.PathingBlockType;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockDoublePlant;
|
||||
@@ -36,9 +35,11 @@ import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/3/2018 1:09 AM
|
||||
* @since 8/3/2018
|
||||
*/
|
||||
public final class ChunkPacker implements Helper {
|
||||
public final class ChunkPacker {
|
||||
|
||||
private static final Map<String, Block> resourceCache = new HashMap<>();
|
||||
|
||||
private ChunkPacker() {}
|
||||
|
||||
@@ -92,9 +93,7 @@ public final class ChunkPacker implements Helper {
|
||||
IBlockState[] blocks = new IBlockState[256];
|
||||
|
||||
for (int z = 0; z < 16; z++) {
|
||||
// @formatter:off
|
||||
https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
|
||||
// @formatter:on
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int y = 255; y >= 0; y--) {
|
||||
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||
@@ -120,12 +119,12 @@ public final class ChunkPacker implements Helper {
|
||||
}
|
||||
|
||||
public static Block stringToBlock(String name) {
|
||||
return Block.getBlockFromName(name.contains(":") ? name : "minecraft:" + name);
|
||||
return resourceCache.computeIfAbsent(name, n -> Block.getBlockFromName(n.contains(":") ? n : "minecraft:" + n));
|
||||
}
|
||||
|
||||
private static PathingBlockType getPathingBlockType(IBlockState state) {
|
||||
Block block = state.getBlock();
|
||||
if (block.equals(Blocks.WATER)) {
|
||||
if (block == Blocks.WATER && !MovementHelper.isFlowing(state)) {
|
||||
// only water source blocks are plausibly usable, flowing water should be avoid
|
||||
return PathingBlockType.WATER;
|
||||
}
|
||||
@@ -144,7 +143,7 @@ public final class ChunkPacker implements Helper {
|
||||
return PathingBlockType.SOLID;
|
||||
}
|
||||
|
||||
public static IBlockState pathingTypeToBlock(PathingBlockType type) {
|
||||
public static IBlockState pathingTypeToBlock(PathingBlockType type, int dimension) {
|
||||
switch (type) {
|
||||
case AIR:
|
||||
return Blocks.AIR.getDefaultState();
|
||||
@@ -154,7 +153,7 @@ public final class ChunkPacker implements Helper {
|
||||
return Blocks.LAVA.getDefaultState();
|
||||
case SOLID:
|
||||
// Dimension solid types
|
||||
switch (mc.player.dimension) {
|
||||
switch (dimension) {
|
||||
case -1:
|
||||
return Blocks.NETHERRACK.getDefaultState();
|
||||
case 0:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user