Compare commits

..

61 Commits

Author SHA1 Message Date
Leijurv
060741bfdc fixes 2018-11-24 19:17:30 -08:00
Leijurv
2a21a1ca18 simplify 2018-11-24 12:53:09 -08:00
Leijurv
8ece179912 recalculate on allocation size change 2018-11-24 11:32:23 -08:00
Leijurv
c79f40a5f1 tenor comms integration, and priority allocation caching 2018-11-24 11:01:23 -08:00
Leijurv
3b7e1adf24 add default lol 2018-11-23 19:24:14 -08:00
Leijurv
01bec5d8f9 computation requests on the tenor side 2018-11-23 19:06:35 -08:00
Leijurv
82c64d4d06 Merge branch 'comms' into tenor 2018-11-23 16:35:35 -08:00
Leijurv
11e44acf65 helper to handle pending msgs 2018-11-23 16:35:03 -08:00
Leijurv
c73751ef98 Merge branch 'comms' into tenor 2018-11-23 16:10:06 -08:00
Leijurv
16fec4a1a0 buffered connection creation helper 2018-11-23 16:09:59 -08:00
Leijurv
81c95a2d43 fix tenor build after comms refactor 2018-11-23 13:36:06 -08:00
Leijurv
07970f803f Merge branch 'calc-request' into tenor 2018-11-23 13:35:03 -08:00
Leijurv
5ae4f23886 Merge branch 'comms' into calc-request 2018-11-23 13:34:48 -08:00
Leijurv
f222980a1a move comms to cabaletta.comms 2018-11-23 13:32:18 -08:00
Leijurv
7f1fb2a8fe Merge branch 'calc-request' into tenor 2018-11-23 13:17:42 -08:00
Leijurv
c57f65f832 complete new segmented calculation system 2018-11-23 13:17:03 -08:00
Leijurv
85a6ec022e Merge branch 'comms' into calc-request 2018-11-23 13:13:35 -08:00
Leijurv
c1032da828 Merge branch 'master' into comms 2018-11-23 13:12:38 -08:00
Leijurv
806c2a4af1 tenor dependency on comms 2018-11-23 13:08:38 -08:00
Leijurv
c5ecb9bb9b Merge branch 'calc-request' into tenor 2018-11-23 12:57:08 -08:00
Leijurv
e0d894d296 computation request and response 2018-11-23 12:09:35 -08:00
Leijurv
27c818f873 Merge branch 'comms' into calc-request 2018-11-23 11:49:49 -08:00
Leijurv
fdd758bc90 too much log spam 2018-11-23 11:48:01 -08:00
Leijurv
3a2620192b too much log spam 2018-11-23 11:46:47 -08:00
Leijurv
c423d5f575 report path start position 2018-11-23 11:35:13 -08:00
Leijurv
81a9b71429 Merge branch 'segment-calculation' into comms 2018-11-23 10:36:56 -08:00
Leijurv
81ecc209d3 synchronize partial reads and writes to a socket 2018-11-23 10:09:13 -08:00
Leijurv
0dc67593bb lots more status 2018-11-18 21:56:46 -08:00
Leijurv
2e180e81ed Merge branch 'comms' of github.com:cabaletta/baritone into comms 2018-11-18 21:42:04 -08:00
Leijurv
0b11057449 Merge branch 'master' into comms 2018-11-18 21:41:50 -08:00
Brady
186652a8d8 Protocol lol 2018-11-18 19:52:11 -06:00
Leijurv
18d8cfb6de Merge branch 'master' into comms 2018-11-18 17:39:26 -08:00
Leijurv
f99befd307 oh thats important 2018-11-18 12:04:37 -08:00
Leijurv
9ad35dbf28 remove the useless stuff 2018-11-18 11:35:54 -08:00
Leijurv
dfb49179c5 not a handler lol 2018-11-18 11:27:53 -08:00
Brady
3c913a7b85 Fix jar export 2018-11-18 13:27:25 -06:00
Leijurv
f01cf669e8 wtf 2018-11-18 11:06:40 -08:00
Leijurv
2d87033f49 f 2018-11-18 11:06:11 -08:00
Leijurv
f014e42aa4 initial comms 2018-11-18 11:01:46 -08:00
Brady
46de72e28c Comms Sourceset 2018-11-17 18:07:16 -06:00
Leijurv
87a44e4093 Merge branch 'master' into tenor 2018-11-12 16:16:03 -08:00
Brady
d082d25253 Tenor Sourceset 2018-11-12 18:09:57 -06:00
Leijurv
1cf6768e27 misc 2018-11-09 12:59:46 -08:00
Leijurv
890dbec852 bunch of stuff 2018-10-31 20:04:32 -07:00
Leijurv
24bb0c541c split up singular and quantized single parent priority allocators 2018-10-31 13:30:37 -07:00
Leijurv
e7a09c34ea cleanup and combine single parent priority allocation 2018-10-31 13:19:48 -07:00
Brady
9642950b54 oppa 2018-10-30 20:30:44 -05:00
Brady
f76736a378 Minecraft imports should only be in minecraft task implementations 2018-10-30 20:05:35 -05:00
Leijurv
91c6baead1 dont allocate parent tasks with empty priority 2018-10-30 17:42:58 -07:00
Leijurv
e81b01a8f3 fix priority allocation method 2018-10-30 17:18:08 -07:00
Brady
f2a45b9eeb Streams are nice 2018-10-30 18:21:09 -05:00
Leijurv
5e2ccdac08 i love generics 2018-10-30 15:44:52 -07:00
Leijurv
473f872d2f you are no longer being poisoned by a toxic cloud 2018-10-30 15:31:02 -07:00
Brady
3d03f15749 Fix bad interface naming 2018-10-30 17:30:03 -05:00
Leijurv
15e91c7c7c quite cool that this can now be done 2018-10-30 15:28:04 -07:00
Leijurv
5089c62ada generics LOL 2018-10-30 15:23:14 -07:00
Leijurv
7c69a188f6 pog 2018-10-30 15:07:16 -07:00
Leijurv
ef6b36b2cc wew lad 2018-10-30 15:05:17 -07:00
Brady
f2f806669c Generify pt 1 2018-10-30 15:51:19 -05:00
Leijurv
c887b27df9 in too deep 2018-10-30 11:51:49 -07:00
Leijurv
e1bb8fd570 here we go LOL 2018-10-29 23:15:08 -07:00
222 changed files with 6468 additions and 8709 deletions

1
.gitattributes vendored
View File

@@ -1 +0,0 @@
* text=auto

View File

@@ -1 +0,0 @@
<!-- No UwU's or OwO's allowed -->

View File

@@ -1 +0,0 @@
<!-- No UwU's or OwO's allowed -->

2
.gitignore vendored
View File

@@ -18,4 +18,4 @@ classes/
# Copyright Files
!/.idea/copyright/Baritone.xml
!/.idea/copyright/profiles_settings.xml
!/.idea/copyright/profiles_settings.xml

View File

@@ -9,7 +9,6 @@ install:
- travis_retry docker build -t cabaletta/baritone .
script:
- docker run --rm cabaletta/baritone ./gradlew javadoc
- 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

View File

@@ -1,83 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* No Anime
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* Anime
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* ~~Trolling, insulting/derogatory comments, and personal or political attacks~~
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
Project maintainers have the right and responsibility to immediately remove
without any sort of dispute any issues or pull requests that do not align
with their corresponding templates. Absolutely no leniancy shall be accepted
with these terms.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at complaints@leijurv.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View File

@@ -1,16 +1,17 @@
FROM debian:stretch
FROM debian:jessie
RUN echo 'deb http://deb.debian.org/debian stretch-backports main' > /etc/apt/sources.list.d/stretch-backports.list
RUN echo 'deb http://deb.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/jessie-backports.list
ENV DEBIAN_FRONTEND noninteractive
RUN apt update -y
RUN apt install \
RUN apt install --target-release jessie-backports \
openjdk-8-jdk \
ca-certificates-java \
--assume-yes
RUN apt install -qq --assume-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
COPY . /code
@@ -20,4 +21,4 @@ WORKDIR /code
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb
RUN ./gradlew build
RUN ./gradlew build

View File

@@ -4,14 +4,13 @@
- **Block breaking** Baritone considers breaking blocks as part of its path. It also takes into account your current tool set and hot bar. For example, if you have a Eff V diamond pick, it may choose to mine through a stone barrier, while if you only had a wood pick it might be faster to climb over it.
- **Block placing** Baritone considers placing blocks as part of its path. This includes sneak-back-placing, pillaring, etc. It has a configurable penalty of placing a block (set to 1 second by default), to conserve its resources. The list of acceptable throwaway blocks is also configurable, and is cobble, dirt, or netherrack by default. <a href="https://www.youtube.com/watch?v=F6FbI1L9UmU">Example</a>
- **Falling** Baritone will fall up to 3 blocks onto solid ground (configurable, if you have Feather Falling and/or don't mind taking a little damage). If you have a water bucket on your hotbar, it will fall up to 23 blocks and place the bucket beneath it. It will fall an unlimited distance into existing still water.
- **Vines and ladders** Baritone understands how to climb and descend vines and ladders. There is experimental support for more advanced maneuvers, like strafing to a different ladder / vine column in midair (off by default, setting named `allowVines`). Baritone can break its fall by grabbing ladders / vines midair, and understands when that is and isn't possible.
- **Vines and ladders** Baritone understands how to climb and descend vines and ladders. There is experimental support for more advanced maneuvers, like strafing to a different ladder / vine column in midair (off by default, setting named `allowVines`).
- **Opening fence gates and doors**
- **Slabs and stairs**
- **Falling blocks** Baritone understands the costs of breaking blocks with falling blocks on top, and includes all of their break costs. Additionally, since it avoids breaking any blocks touching a liquid, it won't break the bottom of a gravel stack below a lava lake (anymore).
- **Avoiding dangerous blocks** Obviously, it knows not to walk through fire or on magma, not to corner over lava (that deals some damage), not to break any blocks touching a liquid (it might drown), etc.
- **Parkour** Sprint jumping over 1, 2, or 3 block gaps
- **Parkour place** Sprint jumping over a 3 block gap and placing the block to land on while executing the jump. It's really cool.
- **Pigs** It can sort of control pigs. I wouldn't rely on it though.
# Pathing method
Baritone uses A*, with some modifications:
@@ -22,9 +21,9 @@ Baritone uses A*, with some modifications:
- **Backtrack cost favoring** While calculating the next segment, Baritone favors backtracking its current segment. The cost is decreased heavily, but is still positive (this won't cause it to backtrack if it doesn't need to). This allows it to splice and jump onto the next segment as early as possible, if the next segment begins with a backtrack of the current one. <a href="https://www.youtube.com/watch?v=CGiMcb8-99Y">Example</a>
- **Backtrack detection and pausing** While path calculation happens on a separate thread, the main game thread has access to the latest node considered, and the best path so far (those are rendered light blue and dark blue respectively). When the current best path (rendered dark blue) passes through the player's current position on the current path segment, path execution is paused (if it's safe to do so), because there's no point continuing forward if we're about to turn around and go back that same way. Note that the current best path as reported by the path calculation thread takes into account the incremental cost backoff system, so it's accurate to what the path calculation thread will actually pick once it finishes.
# Chat control
- [Baritone chat control usage](USAGE.md)
# Configuring Baritone
All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/Settings.java">here</a>.
To change a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `pathTimeoutMS 250`). It's case insensitive.
# Goals
The pathing goal can be set to any of these options:
@@ -47,6 +46,7 @@ Things it doesn't have yet
See <a href="https://github.com/cabaletta/baritone/issues">issues</a> for more.
Things it may not ever have, from most likely to least likely =(
- Pigs
- Boats
- Horses (2x3 path instead of 1x2)
- Elytra

1
IMPACT.md Normal file
View File

@@ -0,0 +1 @@
Impact 4.4 is out. See <a href="INSTALL.md">INSTALL.md</a>

96
INSTALL.md Normal file
View 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>.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

36
PROTOCOL.md Normal file
View File

@@ -0,0 +1,36 @@
# Baritone Comms Protocol
## Data Types
| Name | Descriptor | Java |
|------------|-----------------------------------------------------------|-----------------------------|
| coordinate | Big endian 8-byte floating point number | [readDouble], [writeDouble] |
| string | unsigned short (length) followed by UTF-8 character bytes | [readUTF], [writeUTF] |
## Inbound
Allows the server to execute a chat command on behalf of the client's player
### Chat
| Name | Type |
|---------|--------|
| Message | string |
## Outbound
Update the player position with the server
### Status
| Name | Type |
|------|------------|
| X | coordinate |
| Y | coordinate |
| Z | coordinate |
<!-- External links -->
[readUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readUTF()
[writeUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeUTF(java.lang.String)
[readDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readDouble()
[writeDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeDouble(double)

View File

@@ -1,68 +1,62 @@
# Baritone
[![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone)
[![Release](https://img.shields.io/github/release/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/releases)
[![License](https://img.shields.io/badge/license-LGPL--3.0%20with%20anime%20exception-green.svg)](LICENSE)
[![License](https://img.shields.io/github/license/cabaletta/baritone.svg)](LICENSE)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade)
[![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone)
[![GitHub All Releases](https://img.shields.io/github/downloads/cabaletta/baritone/total.svg)](https://github.com/cabaletta/baritone/releases)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://github.com/cabaletta/baritone/tree/master/)
[![Minecraft](https://img.shields.io/badge/MC-1.13.2-brightgreen.svg)](https://github.com/cabaletta/baritone/tree/1.13.2/)
[![Code of Conduct](https://img.shields.io/badge/%E2%9D%A4-code%20of%20conduct-blue.svg?style=flat)](https://github.com/cabaletta/baritone/blob/master/CODE_OF_CONDUCT.md)
[![Known Vulnerabilities](https://snyk.io/test/github/cabaletta/baritone/badge.svg?targetFile=build.gradle)](https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle)
[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues)
[![Issues](https://img.shields.io/github/issues/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/issues/)
[![GitHub issues-closed](https://img.shields.io/github/issues-closed/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/issues?q=is%3Aissue+is%3Aclosed)
[![Pull Requests](https://img.shields.io/github/issues-pr/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/pulls/)
![Code size](https://img.shields.io/github/languages/code-size/cabaletta/baritone.svg)
![GitHub repo size](https://img.shields.io/github/repo-size/cabaletta/baritone.svg)
![Lines of Code](https://tokei.rs/b1/github/cabaletta/baritone?category=code)
[![GitHub contributors](https://img.shields.io/github/contributors/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/graphs/contributors/)
[![GitHub commits](https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg)](https://github.com/cabaletta/baritone/commit/)
[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.6%20/%20v1.3.2-brightgreen.svg)](https://impactdevelopment.github.io/)
[![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg)](https://github.com/fr1kin/ForgeHax/)
[![WWE integration](https://img.shields.io/badge/WWE%20%22integration%22-master%3F-green.svg)](https://wweclient.com/)
[![Future integration](https://img.shields.io/badge/Future%20integration-Soon™%3F%3F%3F-red.svg)](https://futureclient.net/)
[![forthebadge](https://forthebadge.com/images/badges/built-with-swag.svg)](http://forthebadge.com/)
[![forthebadge](https://forthebadge.com/images/badges/mom-made-pizza-rolls.svg)](http://forthebadge.com/)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2)
A Minecraft pathfinder bot.
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.
The easiest way to install Baritone is to install [Impact](https://impactdevelopment.github.io/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to install the forge jar from [releases](https://github.com/cabaletta/baritone/releases). Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 and 1.13.2. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
Have committed at least once a day for the last 11 months =D 🦀
1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2
# Getting Started
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)
- [Installation & setup](SETUP.md)
- [Installation](INSTALL.md)
- [API Javadocs](https://baritone.leijurv.com)
There's also some useful information down below
- [Settings](https://baritone.leijurv.com/baritone/api/Settings.html#field.detail)
# Setup
- [Usage (chat control)](USAGE.md)
## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
# API
Running Baritone:
The API is heavily documented, you can find the Javadocs for the latest release [here](https://baritone.leijurv.com/).
Please note that usage of anything located outside of the ``baritone.api`` package is not supported by the API release
jar.
```
$ gradlew runClient
```
Below is an example of basic usage for changing some settings, and then pathing to a X/Z goal.
Building Baritone:
```
$ gradlew build
```
For example, 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)
Quick start example: `thisway 1000` or `goal 70` to set the goal, `path` to actually start pathing. Also try `mine diamond_ore`. `cancel` to cancel.
# API example
```
BaritoneAPI.getSettings().allowSprint.value = true;
BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L;
BaritoneAPI.getSettings().pathTimeoutMS.value = 2000L;
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
```
@@ -71,11 +65,11 @@ BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAnd
## Can I use Baritone as a library in my custom utility client?
That's what it's for, sure! (As long as usage is in compliance with the LGPL 3.0 License)
Sure! (As long as usage is in compliance with the LGPL 3 License)
## How is it so fast?
Magic. (Hours of [leijurv](https://github.com/leijurv) enduring excruciating pain)
Magic. (Hours of [Leijurv](https://github.com/leijurv) enduring excruciating pain)
## Why is it called Baritone?

102
SETUP.md
View File

@@ -1,102 +0,0 @@
# Installation
The easiest way to install Baritone is to install [Impact](https://impactdevelopment.github.io/), which comes with Baritone.
Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
## Prebuilt official releases
These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `backfill-2` branch for example, you'll have to build it yourself)
Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
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 .` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too).
## Artifacts
Building Baritone will result in 5 artifacts created in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases).
**The Forge release can simply be added as a Forge mod.**
If another one of your Forge mods has a Baritone integration, you want `baritone-api-forge-VERSION.jar`. Otherwise, you want `baritone-standalone-forge-VERSION.jar`
- **API**: Only the non-api packages are obfuscated. This should be used in environments where other mods would like to use Baritone's features.
- **Forge API**: Same as API, but packaged for Forge. This should be used where another mod has a Baritone integration.
- **Standalone**: Everything is obfuscated. This should be used in environments where there are no other mods present that would like to use Baritone's features.
- **Forge Standalone**: Same as Standalone, but packaged for Forge. This should be used when Baritone is your only Forge mod, or none of your other Forge mods integrate with Baritone.
- **Unoptimized**: Nothing is obfuscated. This shouldn't be used ever in production.
## More Info
To replace out Impact 4.5's Baritone build with a customized one, build Baritone as above then copy & **rename** `dist/baritone-api-$VERSION$.jar` into `minecraft/libraries/cabaletta/baritone-api/1.2/baritone-api-1.2.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.5/1.12.2-Impact_4.5.json`, find the line `"name": "cabaletta:baritone-api:1.2"`, remove the comma from the end, and **entirely remove the NEXT line** (starts with `"url"`). **Restart your launcher** then load as normal.
You can verify whether or not it worked by running `.b version` in chat (only valid in Impact). It should print out the version that you downloaded. Note: The version that comes with 4.5 is `v1.2.3`.
## Build it yourself
- Clone or download Baritone
![Image](https://i.imgur.com/kbqBtoN.png)
- If you choose to download, make sure you extract the ZIP archive.
- Follow one of the instruction sets below, based on your preference
## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
Setting up the Environment:
```
$ gradlew setupDecompWorkspace
$ gradlew --refresh-dependencies
```
Running Baritone:
```
$ gradlew runClient
```
For information on how to build baritone, see [Building Baritone](#building-baritone)
## IntelliJ
- Open the project in IntelliJ as a Gradle project
![Image](https://i.imgur.com/jw7Q6vY.png)
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
![Image](https://i.imgur.com/QEfVvWP.png)
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
![Image](https://i.imgur.com/3V7EdWr.png)
- Select the "Minecraft Client" launch config
![Image](https://i.imgur.com/1qz2QGV.png)
- Click on ``Edit Configurations...`` from the same dropdown and select the "Minecraft Client" config
![Image](https://i.imgur.com/s4ly0ZF.png)
- In `Edit Configurations...` you need to select `baritone_launch` for `Use classpath of module:`.
![Image](https://i.imgur.com/hrLhG9u.png)
# Building
Make sure that you have properly [setup](#setup) the environment before trying to build it.
## Command Line
```
$ gradlew build
```
## IntelliJ
- Navigate to the gradle tasks on the right tab as follows
![Image](https://i.imgur.com/PE6r9iN.png)
- Double click on **build** to run it

View File

@@ -1,80 +0,0 @@
(assuming you already have Baritone [set up](SETUP.md))
# Prefix
Baritone's chat control prefix is `#` by default. In Impact, you can also use `.b` as a prefix. (for example, `.b click` instead of `#click`)
Baritone commands can also by default be typed in the chatbox. However if you make a typo, like typing "gola 10000 10000" instead of "goal" it goes into public chat, which is bad, so using `#` is suggested.
To disable direct chat control (with no prefix), turn off the `chatControl` setting. To disable chat control with the `#` prefix, turn off the `prefixControl` setting. In Impact, `.b` cannot be disabled. Be careful that you don't leave yourself with all control methods disabled (if you do, reset your settings by deleting the file `minecraft/baritone/settings.txt` and relaunching).
# Commands
**All** of these commands may need a prefix before them, as above ^.
`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java#L47).
To toggle a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `primaryTimeoutMS 250`). It's case insensitive. To reset a setting to its default value, say `acceptableThrowawayItems reset`. To reset all settings, say `reset`. To see all settings that have been modified from their default values, say `modified`.
Some common examples:
- `thisway 1000` then `path` to go in the direction you're facing for a thousand blocks
- `goal x y z` or `goal x z` or `goal y`, then `path` to go to a certain coordinate
- `goal` to set the goal to your player's feet
- `goal clear` to clear the goal
- `cancel` or `stop` to stop everything
- `goto portal` or `goto ender_chest` or `goto block_type` to go to a block. (in Impact, `.goto` is an alias for `.b goto` for the most part)
- `mine diamond_ore` to mine diamond ore (turn on the setting `legitMine` to only mine ores that it can actually see. It will explore randomly around y=11 until it finds them.)
- `click` to click your destination on the screen. Right click path to on top of the block, left click to path into it (either at foot level or eye level), and left click and drag to clear all blocks from an area.
- `follow playerName` to follow a player. `follow` to follow the entity you're looking at (only works if it hitting range). `followplayers` to follow any players in range (combine with Kill Aura for a fun time).
- `save waypointName` to save a waypoint. `goto waypointName` to go to it.
- `build` to build a schematic. `build blah` will load `schematics/blah.schematic` and build it with the origin being your player feet. `build blah x y z` to set the origin. Any of those can be relative to your player (`~ 69 ~-420` would build at x=player x, y=69, z=player z-420).
- `tunnel` to dig just straight ahead and make a tunnel
- `farm` to automatically harvest, replant, or bone meal crops
- `axis` to go to an axis or diagonal axis at y=120 (`axisHeight` is a configurable setting, defaults to 120).
- `explore x z` to explore the world from the origin of x,z. Leave out x and z to default to player feet. This will continually path towards the closest chunk to the origin that it's never seen before. `explorefilter filter.json` with optional invert can be used to load in a list of chunks to load.
- `invert` to invert the current goal and path. This gets as far away from it as possible, instead of as close as possible. For example, do `goal` then `invert` to run as far as possible from where you're standing at the start.
- `version` to get the version of Baritone you're running
- `damn` daniel
For the rest of the commands, you can take a look at the code [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java).
All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/Settings.java">here</a>. If you find HTML easier to read than Javadoc, you can look <a href="https://baritone.leijurv.com/baritone/api/Settings.html#field.detail">here</a>.
There are about a hundred settings, but here are some fun / interesting / important ones that you might want to look at changing in normal usage of Baritone. The documentation for each can be found at the above links.
- `allowBreak`
- `allowSprint`
- `allowPlace`
- `allowParkour`
- `allowParkourPlace`
- `blockPlacementPenalty`
- `renderCachedChunks` (and `cachedChunksOpacity`) <-- very fun but you need a beefy computer
- `avoidance` (avoidance of mobs / mob spawners)
- `legitMine`
- `followRadius`
- `backfill` (fill in tunnels behind you)
- `buildInLayers`
- `buildRepeatDistance` and `buildRepeatDirection`
- `worldExploringChunkOffset`
- `acceptableThrowawayItems`
- `blocksToAvoidBreaking`
# Troubleshooting / common issues
## Why doesn't Baritone respond to any of my chat commands?
This could be one of many things.
First, make sure it's actually installed. An easy way to check is seeing if it created the folder `baritone` in your Minecraft folder.
Second, make sure that you're using the prefix properly, and that chat control is enabled in the way you expect.
For example, Impact disables direct chat control. (i.e. anything typed in chat without a prefix will be ignored and sent publicly). **This is a saved setting**, so if you run Impact once, `chatControl` will be off from then on, **even in other clients**.
So you'll need to use the `#` prefix or edit `baritone/settings.txt` in your Minecraft folder to undo that (specifically, remove the line `chatControl false` then restart your client).
## Why can I do `.goto x z` in Impact but nowhere else? Why can I do `-path to x z` in KAMI but nowhere else?
These are custom commands that they added; those aren't from Baritone.
The equivalent you're looking for is `goal x z` then `path`.

View File

@@ -1,132 +1,125 @@
/*
* 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/>.
*/
group 'baritone'
version '1.2.7'
buildscript {
repositories {
maven {
name = 'forge'
url = 'http://files.minecraftforge.net/maven'
}
maven {
name = 'SpongePowered'
url = 'http://repo.spongepowered.org/maven'
}
jcenter()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
}
}
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'
sourceCompatibility = targetCompatibility = '1.8'
compileJava {
sourceCompatibility = targetCompatibility = '1.8'
options.encoding = "UTF-8" // allow emoji in comments :^)
}
sourceSets {
launch {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
}
}
minecraft {
version = '1.12.2'
mappings = 'stable_39'
tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run'
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
makeObfSourceJar = true
}
repositories {
mavenCentral()
maven {
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'
exclude module: 'guava'
exclude module: 'gson'
exclude module: 'commons-io'
exclude module: 'log4j-core'
}
testImplementation 'junit:junit:4.12'
}
mixin {
defaultObfuscationEnv searge
add sourceSets.launch, 'mixins.baritone.refmap.json'
}
javadoc {
options.addStringOption('Xwerror', '-quiet') // makes the build fail on travis when there is a javadoc error
options.linkSource true
options.encoding "UTF-8" // allow emoji in comments :^)
source = sourceSets.api.allJava
classpath += sourceSets.api.compileClasspath
}
jar {
from sourceSets.launch.output, sourceSets.api.output
preserveFileTimestamps = false
reproducibleFileOrder = true
manifest {
attributes(
'MixinConfigs': 'mixins.baritone.json',
'Implementation-Title': 'Baritone',
'Implementation-Version': version
)
}
}
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'
}
task createDist(type: CreateDistTask, dependsOn: proguard)
build.finalizedBy(createDist)
/*
* 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/>.
*/
group 'baritone'
version '1.0.0-hotfix-2'
buildscript {
repositories {
maven {
name = 'forge'
url = 'http://files.minecraftforge.net/maven'
}
maven {
name = 'SpongePowered'
url = 'http://repo.spongepowered.org/maven'
}
jcenter()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
}
}
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'
sourceCompatibility = targetCompatibility = '1.8'
compileJava {
sourceCompatibility = targetCompatibility = '1.8'
}
sourceSets {
comms {}
main {
compileClasspath += comms.compileClasspath + comms.output
}
launch {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
}
tenor {
compileClasspath += comms.compileClasspath + comms.output
}
main {
compileClasspath += tenor.compileClasspath + tenor.output
}
}
minecraft {
version = '1.12.2'
mappings = 'stable_39'
tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run'
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
makeObfSourceJar = true
}
repositories {
mavenCentral()
maven {
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'
exclude module: 'guava'
exclude module: 'gson'
exclude module: 'commons-io'
exclude module: 'log4j-core'
}
testImplementation 'junit:junit:4.12'
}
mixin {
defaultObfuscationEnv notch
add sourceSets.launch, 'mixins.baritone.refmap.json'
}
jar {
from sourceSets.comms.output, sourceSets.launch.output, sourceSets.api.output
preserveFileTimestamps = false
reproducibleFileOrder = true
}
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'
versionManifest 'https://launchermeta.mojang.com/mc/game/version_manifest.json'
}
task createDist(type: CreateDistTask, dependsOn: proguard)
build.finalizedBy(createDist)

View File

@@ -17,6 +17,8 @@
package baritone.gradle.task;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.gradle.api.DefaultTask;
import java.io.File;
@@ -24,6 +26,7 @@ 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
@@ -31,6 +34,8 @@ import java.nio.file.Paths;
*/
class BaritoneGradleTask extends DefaultTask {
protected static final JsonParser PARSER = new JsonParser();
protected static final String
PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar",
@@ -40,28 +45,26 @@ class BaritoneGradleTask extends DefaultTask {
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",
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
protected String artifactName, artifactVersion;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, artifactForgeApiPath, artifactForgeStandalonePath, proguardOut;
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.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE));
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);
@@ -92,4 +95,8 @@ class BaritoneGradleTask extends DefaultTask {
protected Path getBuildFile(String file) {
return getRelativeFile("build/libs/" + file);
}
protected JsonElement readJson(List<String> lines) {
return PARSER.parse(String.join("\n", lines));
}
}

View File

@@ -42,11 +42,9 @@ public class CreateDistTask extends BaritoneGradleTask {
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));
Path forgeApi = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE_API));
Path forgeStandalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE_STANDALONE));
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/");
@@ -55,14 +53,12 @@ public class CreateDistTask extends BaritoneGradleTask {
}
// 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);
Files.copy(this.artifactForgeApiPath, forgeApi, REPLACE_EXISTING);
Files.copy(this.artifactForgeStandalonePath, forgeStandalone, REPLACE_EXISTING);
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, forgeApi, standalone, forgeStandalone, unoptimized)
List<String> shasum = Stream.of(api, standalone, unoptimized)
.map(path -> sha1(path) + " " + path.getFileName().toString())
.collect(Collectors.toList());

View File

@@ -18,26 +18,21 @@
package baritone.gradle.task;
import baritone.gradle.util.Determinizer;
import baritone.gradle.util.MappingType;
import baritone.gradle.util.ReobfWrapper;
import com.google.gson.*;
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;
@@ -57,9 +52,11 @@ public class ProguardTask extends BaritoneGradleTask {
@Input
private String extract;
private List<String> requiredLibraries;
@Input
private String versionManifest;
private File mixin;
private Map<String, String> versionDownloadMap;
private List<String> requiredLibraries;
@TaskAction
protected void exec() throws Exception {
@@ -70,6 +67,7 @@ public class ProguardTask extends BaritoneGradleTask {
downloadProguard();
extractProguard();
generateConfigs();
downloadVersionManifest();
acquireDependencies();
proguardApi();
proguardStandalone();
@@ -81,7 +79,7 @@ public class ProguardTask extends BaritoneGradleTask {
Files.delete(this.artifactUnoptimizedPath);
}
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
}
private void downloadProguard() throws Exception {
@@ -134,6 +132,20 @@ public class ProguardTask extends BaritoneGradleTask {
});
}
private void downloadVersionManifest() throws Exception {
Path manifestJson = getTemporaryFile(VERSION_MANIFEST);
write(new URL(this.versionManifest).openStream(), manifestJson);
// Place all the versions in the map with their download URL
this.versionDownloadMap = new HashMap<>();
JsonObject json = readJson(Files.readAllLines(manifestJson)).getAsJsonObject();
JsonArray versions = json.getAsJsonArray("versions");
versions.forEach(element -> {
JsonObject object = element.getAsJsonObject();
this.versionDownloadMap.put(object.get("id").getAsString(), object.get("url").getAsString());
});
}
private void acquireDependencies() throws Exception {
// Create a map of all of the dependencies that we are able to access in this project
@@ -151,13 +163,15 @@ public class ProguardTask extends BaritoneGradleTask {
// 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);
// Download the version jar from the URL acquired from the version manifest
if (lib.startsWith("minecraft")) {
String version = lib.split("-")[1];
Path versionJar = getTemporaryFile("tempLibraries/" + lib + ".jar");
if (!Files.exists(versionJar)) {
JsonObject versionJson = PARSER.parse(new InputStreamReader(new URL(this.versionDownloadMap.get(version)).openStream())).getAsJsonObject();
String url = versionJson.getAsJsonObject("downloads").getAsJsonObject("client").getAsJsonPrimitive("url").getAsString();
write(new URL(url).openStream(), versionJar);
}
continue;
}
@@ -175,111 +189,20 @@ public class ProguardTask extends BaritoneGradleTask {
// Find the library jar file, and copy it to tempLibraries
for (File file : pair.getLeft().files(pair.getRight())) {
if (file.getName().startsWith(lib)) {
if (lib.contains("mixin")) {
mixin = file;
}
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
}
}
}
if (mixin == null) {
throw new IllegalStateException("Unable to find mixin jar");
}
}
// a bunch of epic stuff to get the path to the cached jar
private Path getMinecraftJar() throws Exception {
MappingType mappingType;
try {
mappingType = getMappingType();
} catch (Exception e) {
System.err.println("Failed to get mapping type, assuming NOTCH.");
mappingType = MappingType.NOTCH;
}
String suffix;
switch (mappingType) {
case NOTCH:
suffix = "";
break;
case SEARGE:
suffix = "-srgBin";
break;
case CUSTOM:
throw new IllegalStateException("Custom mappings not supported!");
default:
throw new IllegalStateException("Unknown mapping type: " + mappingType);
}
DefaultConvention convention = (DefaultConvention) this.getProject().getConvention();
Object extension = convention.getAsMap().get("minecraft");
Objects.requireNonNull(extension);
// for some reason cant use Class.forName
Class<?> class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass(); // <-- cursed
Field f_replacer = class_baseExtension.getDeclaredField("replacer");
f_replacer.setAccessible(true);
Object replacer = f_replacer.get(extension);
Class<?> class_replacementProvider = replacer.getClass();
Field replacement_replaceMap = class_replacementProvider.getDeclaredField("replaceMap");
replacement_replaceMap.setAccessible(true);
Map<String, Object> replacements = (Map) replacement_replaceMap.get(replacer);
String cacheDir = replacements.get("CACHE_DIR").toString() + "/net/minecraft";
String mcVersion = replacements.get("MC_VERSION").toString();
String mcpInsert = replacements.get("MAPPING_CHANNEL").toString() + "/" + replacements.get("MAPPING_VERSION").toString();
String fullJarName = "minecraft-" + mcVersion + suffix + ".jar";
String baseDir = String.format("%s/minecraft/%s/", cacheDir, mcVersion);
String jarPath;
if (mappingType == MappingType.SEARGE) {
jarPath = String.format("%s/%s/%s", baseDir, mcpInsert, fullJarName);
} else {
jarPath = baseDir + fullJarName;
}
jarPath = jarPath
.replace("/", File.separator)
.replace("\\", File.separator); // hecking regex
return new File(jarPath).toPath();
}
// 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(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
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(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
}
private void cleanup() {
@@ -296,6 +219,10 @@ public class ProguardTask extends BaritoneGradleTask {
this.extract = extract;
}
public void setVersionManifest(String versionManifest) {
this.versionManifest = versionManifest;
}
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)) {
@@ -308,8 +235,8 @@ public class ProguardTask extends BaritoneGradleTask {
.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(), System.out);
this.printOutputLog(p.getErrorStream(), System.err);
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();
@@ -318,14 +245,14 @@ public class ProguardTask extends BaritoneGradleTask {
}
}
private void printOutputLog(InputStream stream, PrintStream outerr) {
private void printOutputLog(InputStream stream) {
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
String line;
while ((line = reader.readLine()) != null) {
outerr.println(line);
System.out.println(line);
}
} catch (Exception e) {
} catch (final Exception e) {
e.printStackTrace();
}
}).start();

View File

@@ -22,7 +22,10 @@ import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@@ -36,7 +39,7 @@ import java.util.stream.Collectors;
*/
public class Determinizer {
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
public static void determinize(String inputPath, String outputPath) throws IOException {
System.out.println("Running Determinizer");
System.out.println(" Input path: " + inputPath);
System.out.println(" Output path: " + outputPath);
@@ -63,30 +66,10 @@ public class Determinizer {
if (entry.getName().endsWith(".refmap.json")) {
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
jos.write(writeSorted(object).getBytes());
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && toInclude.isPresent()) { // only replace for forge jar
ByteArrayOutputStream cancer = new ByteArrayOutputStream();
copy(jarFile.getInputStream(entry), cancer);
String manifest = new String(cancer.toByteArray());
if (!manifest.contains("baritone.launch.BaritoneTweaker")) {
throw new IllegalStateException("unable to replace");
}
manifest = manifest.replace("baritone.launch.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker");
jos.write(manifest.getBytes());
} else {
copy(jarFile.getInputStream(entry), jos);
}
}
if (toInclude.isPresent()) {
try (JarFile mixin = new JarFile(toInclude.get())) {
for (JarEntry entry : mixin.stream().sorted(Comparator.comparing(JarEntry::getName)).collect(Collectors.toList())) {
if (entry.getName().startsWith("META-INF") && !entry.getName().startsWith("META-INF/services")) {
continue;
}
jos.putNextEntry(entry);
copy(mixin.getInputStream(entry), jos);
}
}
}
jos.finish();
}
}

View File

@@ -1,63 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.gradle.util;
import java.lang.reflect.Field;
import java.util.Objects;
/**
* All credits go to AsmLibGradle and its contributors.
*
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/ReobfWrapper.java">Original Source</a>
*/
public class ReobfWrapper {
private final Object instance;
private final Class<?> type;
public ReobfWrapper(Object instance) {
this.instance = instance;
Objects.requireNonNull(instance);
this.type = instance.getClass();
}
public String getName() {
try {
Field nameField = type.getDeclaredField("name");
nameField.setAccessible(true);
return (String) nameField.get(this.instance);
} catch (ReflectiveOperationException ex) {
throw new IllegalStateException(ex);
}
}
public MappingType getMappingType() {
try {
Field enumField = type.getDeclaredField("mappingType");
enumField.setAccessible(true);
Enum<?> aEnum = (Enum<?>) enumField.get(this.instance);
MappingType mappingType = MappingType.values()[aEnum.ordinal()];
if (!aEnum.name().equals(mappingType.name())) {
throw new IllegalStateException("ForgeGradle ReobfMappingType is not equivalent to MappingType (version error?)");
}
return mappingType;
} catch (ReflectiveOperationException ex) {
throw new IllegalStateException(ex);
}
}
}

View File

@@ -1,6 +1,6 @@
#Tue Jul 31 21:56:56 PDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip
#Tue Jul 31 21:56:56 PDT 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip

168
gradlew.bat vendored
View File

@@ -1,84 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -12,16 +12,14 @@
-flattenpackagehierarchy
-repackageclasses 'baritone'
# lwjgl is weird
-dontwarn org.lwjgl.**
-keep class baritone.api.** { *; } # this is the keep api
# service provider needs these class names
-keep class baritone.BaritoneProvider
-keep class baritone.api.IBaritoneProvider
-keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect
# 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 {
@@ -33,8 +31,7 @@
# copy all necessary libraries into tempLibraries to build
# The correct jar will be copied from the forgegradle cache based on the mapping type being compiled with
-libraryjars 'tempLibraries/minecraft.jar'
-libraryjars 'tempLibraries/minecraft-1.12.2.jar'
-libraryjars 'tempLibraries/SimpleTweaker-1.2.jar'

View File

@@ -1,19 +1,19 @@
/*
* 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/>.
*/
rootProject.name = 'baritone'
/*
* 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/>.
*/
rootProject.name = 'baritone'

View File

@@ -23,7 +23,9 @@ import java.util.Iterator;
import java.util.ServiceLoader;
/**
* Exposes the {@link IBaritoneProvider} instance and the {@link Settings} instance for API usage.
* API exposure for various things implemented in Baritone.
* <p>
* W.I.P
*
* @author Brady
* @since 9/23/2018

View File

@@ -18,11 +18,15 @@
package baritone.api;
import baritone.api.behavior.ILookBehavior;
import baritone.api.behavior.IMemoryBehavior;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.cache.IWorldProvider;
import baritone.api.event.listener.IEventBus;
import baritone.api.pathing.calc.IPathingControlManager;
import baritone.api.process.*;
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;
@@ -33,19 +37,10 @@ import baritone.api.utils.IPlayerContext;
public interface IBaritone {
/**
* Call as soon as Minecraft is ready, initializes all of the processes, behaviors, etc. This will
* only effectively be ran once, any additional calls are redundant because the initialization state
* is saved.
* <p>
* Or whenever your overeager utility client wants.
* @return The {@link IFollowProcess} instance
* @see IFollowProcess
*/
void init();
/**
* @return The {@link IPathingBehavior} instance
* @see IPathingBehavior
*/
IPathingBehavior getPathingBehavior();
IFollowProcess getFollowProcess();
/**
* @return The {@link ILookBehavior} instance
@@ -54,10 +49,10 @@ public interface IBaritone {
ILookBehavior getLookBehavior();
/**
* @return The {@link IFollowProcess} instance
* @see IFollowProcess
* @return The {@link IMemoryBehavior} instance
* @see IMemoryBehavior
*/
IFollowProcess getFollowProcess();
IMemoryBehavior getMemoryBehavior();
/**
* @return The {@link IMineProcess} instance
@@ -65,35 +60,13 @@ public interface IBaritone {
*/
IMineProcess getMineProcess();
/**
* @return The {@link IBuilderProcess} instance
* @see IBuilderProcess
*/
IBuilderProcess getBuilderProcess();
IPathingControlManager getPathingControlManager();
/**
* @return The {@link IExploreProcess} instance
* @see IExploreProcess
* @return The {@link IPathingBehavior} instance
* @see IPathingBehavior
*/
IExploreProcess getExploreProcess();
/**
* @return The {@link IFarmProcess} instance
* @see IFarmProcess
*/
IFarmProcess getFarmProcess();
/**
* @return The {@link ICustomGoalProcess} instance
* @see ICustomGoalProcess
*/
ICustomGoalProcess getCustomGoalProcess();
/**
* @return The {@link IGetToBlockProcess} instance
* @see IGetToBlockProcess
*/
IGetToBlockProcess getGetToBlockProcess();
IPathingBehavior getPathingBehavior();
/**
* @return The {@link IWorldProvider} instance
@@ -101,32 +74,13 @@ public interface IBaritone {
*/
IWorldProvider getWorldProvider();
/**
* Returns the {@link IPathingControlManager} for this {@link IBaritone} instance, which is responsible
* for managing the {@link IBaritoneProcess}es which control the {@link IPathingBehavior} state.
*
* @return The {@link IPathingControlManager} instance
* @see IPathingControlManager
*/
IPathingControlManager getPathingControlManager();
/**
* @return The {@link IInputOverrideHandler} instance
* @see IInputOverrideHandler
*/
IInputOverrideHandler getInputOverrideHandler();
/**
* @return The {@link IPlayerContext} instance
* @see IPlayerContext
*/
ICustomGoalProcess getCustomGoalProcess();
IGetToBlockProcess getGetToBlockProcess();
IPlayerContext getPlayerContext();
/**
* @return The {@link IEventBus} instance
* @see IEventBus
*/
IEventBus getGameEventHandler();
void openClick();
}

View File

@@ -23,9 +23,7 @@ import net.minecraft.client.entity.EntityPlayerSP;
import java.util.List;
/**
* Provides the present {@link IBaritone} instances
*
* @author leijurv
* @author Leijurv
*/
public interface IBaritoneProvider {
@@ -49,8 +47,7 @@ public interface IBaritoneProvider {
/**
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
* replaced with or be overloaded in addition to {@code #getBaritoneForUser(IBaritoneUser)} when
* {@code bot-system} is merged into {@code master}.
* replaced with {@code #getBaritoneForUser(IBaritoneUser)} when {@code bot-system} is merged.
*
* @param player The player
* @return The {@link IBaritone} instance.
@@ -61,7 +58,7 @@ public interface IBaritoneProvider {
return baritone;
}
}
return null;
throw new IllegalStateException("No baritone for player " + player);
}
/**

View File

@@ -17,96 +17,68 @@
package baritone.api;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.TypeUtils;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.util.math.Vec3i;
import net.minecraft.util.text.ITextComponent;
import java.awt.*;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.List;
import java.util.function.Consumer;
/**
* Baritone's settings. Settings apply to all Baritone instances.
* Baritone's settings
*
* @author leijurv
*/
public final class Settings {
public class Settings {
/**
* Allow Baritone to break blocks
*/
public final Setting<Boolean> allowBreak = new Setting<>(true);
public Setting<Boolean> allowBreak = new Setting<>(true);
/**
* Allow Baritone to sprint
*/
public final Setting<Boolean> allowSprint = new Setting<>(true);
public Setting<Boolean> allowSprint = new Setting<>(true);
/**
* Allow Baritone to place blocks
*/
public final Setting<Boolean> allowPlace = new Setting<>(true);
/**
* Allow Baritone to move items in your inventory to your hotbar
*/
public final Setting<Boolean> allowInventory = new Setting<>(false);
public Setting<Boolean> allowPlace = new Setting<>(true);
/**
* 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.
* <p>
* Decrease to make Baritone more often consider paths that would require placing blocks
* because we want to generally conserve blocks which might be limited
*/
public final Setting<Double> blockPlacementPenalty = new Setting<>(20D);
public Setting<Double> blockPlacementPenalty = new Setting<>(20D);
/**
* This is just a tiebreaker to make it less likely to break blocks if it can avoid it.
* For example, fire has a break cost of 0, this makes it nonzero, so all else being equal
* it will take an otherwise equivalent route that doesn't require it to put out fire.
*/
public final Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
/**
* Additional penalty for hitting the space bar (ascend, pillar, or parkour) because it uses hunger
*/
public final Setting<Double> jumpPenalty = new Setting<>(2D);
/**
* Walking on water uses up hunger really quick, so penalize it
*/
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(3D);
public Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
/**
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
* Reliability: questionable.
*/
public final Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
public Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
/**
* Allow Baritone to assume it can walk on still water just like any other block.
* This functionality is assumed to be provided by a separate library that might have imported Baritone.
*/
public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
/**
* If you have Fire Resistance and Jesus then I guess you could turn this on lol
*/
public final Setting<Boolean> assumeWalkOnLava = new Setting<>(false);
public Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
/**
* Assume step functionality; don't jump on an Ascend.
*/
public final Setting<Boolean> assumeStep = new Setting<>(false);
public Setting<Boolean> assumeStep = new Setting<>(false);
/**
* Assume safe walk functionality; don't sneak on a backplace traverse.
@@ -115,122 +87,45 @@ public final class Settings {
* it won't sneak right click, it'll just right click, which means it'll open the chest instead of placing
* against it. That's why this defaults to off.
*/
public final 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 constantiam. Please let me know if this is ever disabled. Please.
*/
public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
/**
* Allow descending diagonally
* <p>
* Safer than allowParkour yet still slightly unsafe, can make contact with unchecked adjacent blocks, so it's unsafe in the nether.
* <p>
* For a generic "take some risks" mode I'd turn on this one, parkour, and parkour place.
*/
public final Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
/**
* Allow mining the block directly beneath its feet
* <p>
* Turn this off to force it to make more staircases and less shafts
*/
public final Setting<Boolean> allowDownward = new Setting<>(true);
public Setting<Boolean> assumeSafeWalk = new Setting<>(false);
/**
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
*/
public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
public Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
Item.getItemFromBlock(Blocks.DIRT),
Item.getItemFromBlock(Blocks.COBBLESTONE),
Item.getItemFromBlock(Blocks.NETHERRACK),
Item.getItemFromBlock(Blocks.STONE)
Item.getItemFromBlock(Blocks.NETHERRACK)
)));
/**
* Blocks that Baritone will attempt to avoid (Used in avoidance)
*/
public final Setting<List<Block>> blocksToAvoid = new Setting<>(new ArrayList<>(
// Leave Empty by Default
));
/**
* Blocks that Baritone is not allowed to break
*/
public final Setting<List<Block>> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet?
Blocks.CRAFTING_TABLE,
Blocks.FURNACE,
Blocks.LIT_FURNACE,
Blocks.CHEST,
Blocks.TRAPPED_CHEST
)));
/**
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
* <p>
* I.E. it will never trigger cascading sand / gravel falls
*/
public final Setting<Boolean> avoidUpdatingFallingBlocks = new Setting<>(true);
/**
* Enables some more advanced vine features. They're honestly just gimmicks and won't ever be needed in real
* pathing scenarios. And they can cause Baritone to get trapped indefinitely in a strange scenario.
* <p>
* Never turn this on lol
*/
public final Setting<Boolean> allowVines = new Setting<>(false);
public Setting<Boolean> allowVines = new Setting<>(false);
/**
* Slab behavior is complicated, disable this for higher path reliability. Leave enabled if you have bottom slabs
* everywhere in your base.
*/
public final Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
public Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
/**
* You know what it is
* <p>
* But it's very unreliable and falls off when cornering like all the time so.
* <p>
* It also overshoots the landing pretty much always (making contact with the next block over), so be careful
*/
public final Setting<Boolean> allowParkour = new Setting<>(false);
public Setting<Boolean> allowParkour = new Setting<>(false);
/**
* Actually pretty reliable.
* <p>
* Doesn't make it any more dangerous compared to just normal allowParkour th
* Like parkour, but even more unreliable!
*/
public final Setting<Boolean> allowParkourPlace = new Setting<>(false);
public Setting<Boolean> allowParkourPlace = new Setting<>(false);
/**
* For example, if you have Mining Fatigue or Haste, adjust the costs of breaking blocks accordingly.
*/
public final Setting<Boolean> considerPotionEffects = new Setting<>(true);
/**
* Sprint and jump a block early on ascends wherever possible
*/
public final Setting<Boolean> sprintAscends = new Setting<>(true);
/**
* If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway.
* <p>
* This helps with speed at >=20m/s
*/
public final Setting<Boolean> overshootTraverse = new Setting<>(true);
/**
* When breaking blocks for a movement, wait until all falling blocks have settled before continuing
*/
public final Setting<Boolean> pauseMiningForFallingBlocks = new Setting<>(true);
/**
* How many ticks between right clicks are allowed. Default in game is 4
*/
public final Setting<Integer> rightClickSpeed = new Setting<>(4);
public Setting<Boolean> considerPotionEffects = new Setting<>(true);
/**
* This is the big A* setting.
@@ -247,139 +142,95 @@ public final class Settings {
* <p>
* Finding the optimal path is worth it, so it's the default.
*/
public final Setting<Double> costHeuristic = new Setting<>(3.563);
public Setting<Double> costHeuristic = new Setting<>(3.5D);
// a bunch of obscure internal A* settings that you probably don't want to change
/**
* The maximum number of times it will fetch outside loaded or cached chunks before assuming that
* pathing has reached the end of the known area, and should therefore stop.
*/
public final Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
public Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
/**
* Set to 1.0 to effectively disable this feature
*
* @see <a href="https://github.com/cabaletta/baritone/issues/18">Issue #18</a>
*/
public final Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
/**
* Toggle the following 4 settings
* <p>
* They have a noticeable performance impact, so they default off
* <p>
* Specifically, building up the avoidance map on the main thread before pathing starts actually takes a noticeable
* amount of time, especially when there are a lot of mobs around, and your game jitters for like 200ms while doing so
*/
public final 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 final Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
public final 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 final Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
public final 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 final 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 final Setting<Boolean> enterPortal = new Setting<>(true);
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
/**
* Don't repropagate cost improvements below 0.01 ticks. They're all just floating point inaccuracies,
* and there's no point.
*/
public final Setting<Boolean> minimumImprovementRepropagation = new Setting<>(true);
public Setting<Boolean> minimumImprovementRepropagation = new Setting<>(true);
/**
* After calculating a path (potentially through cached chunks), artificially cut it off to just the part that is
* entirely within currently loaded chunks. Improves path safety because cached chunks are heavily simplified.
* <p>
* This is much safer to leave off now, and makes pathing more efficient. More explanation in the issue.
*
* @see <a href="https://github.com/cabaletta/baritone/issues/114">Issue #114</a>
* @see <a href="https://github.com/cabaletta/baritone/issues/144">Issue #144</a>
*/
public final Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(false);
public Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(false);
/**
* If a movement's cost increases by more than this amount between calculation and execution (due to changes
* in the environment / world), cancel and recalculate
*/
public final Setting<Double> maxCostIncrease = new Setting<>(10D);
public Setting<Double> maxCostIncrease = new Setting<>(10D);
/**
* Stop 5 movements before anything that made the path COST_INF.
* For example, if lava has spread across the path, don't walk right up to it then recalculate, it might
* still be spreading lol
*/
public final Setting<Integer> costVerificationLookahead = new Setting<>(5);
public Setting<Integer> costVerificationLookahead = new Setting<>(5);
/**
* Static cutoff factor. 0.9 means cut off the last 10% of all paths, regardless of chunk load state
*/
public final Setting<Double> pathCutoffFactor = new Setting<>(0.9);
public Setting<Double> pathCutoffFactor = new Setting<>(0.9);
/**
* Only apply static cutoff for paths of at least this length (in terms of number of movements)
*/
public final Setting<Integer> pathCutoffMinimumLength = new Setting<>(30);
public Setting<Integer> pathCutoffMinimumLength = new Setting<>(30);
/**
* Start planning the next path once the remaining movements tick estimates sum up to less than this value
*/
public final Setting<Integer> planningTickLookahead = new Setting<>(150);
public Setting<Integer> planningTickLookAhead = new Setting<>(150);
/**
* Default size of the Long2ObjectOpenHashMap used in pathing
*/
public final Setting<Integer> pathingMapDefaultSize = new Setting<>(1024);
public Setting<Integer> pathingMapDefaultSize = new Setting<>(1024);
/**
* Load factor coefficient for the Long2ObjectOpenHashMap used in pathing
* <p>
* Decrease for faster map operations, but higher memory usage
*/
public final Setting<Float> pathingMapLoadFactor = new Setting<>(0.75f);
public Setting<Float> pathingMapLoadFactor = new Setting<>(0.75f);
/**
* How far are you allowed to fall onto solid ground (without a water bucket)?
* 3 won't deal any damage. But if you just want to get down the mountain quickly and you have
* Feather Falling IV, you might set it a bit higher, like 4 or 5.
*/
public final Setting<Integer> maxFallHeightNoWater = new Setting<>(3);
public Setting<Integer> maxFallHeightNoWater = new Setting<>(3);
/**
* How far are you allowed to fall onto solid ground (with a water bucket)?
* It's not that reliable, so I've set it below what would kill an unarmored player (23)
*/
public final Setting<Integer> maxFallHeightBucket = new Setting<>(20);
public Setting<Integer> maxFallHeightBucket = new Setting<>(20);
/**
* Is it okay to sprint through a descend followed by a diagonal?
* The player overshoots the landing, but not enough to fall off. And the diagonal ensures that there isn't
* lava or anything that's !canWalkInto in that space, so it's technically safe, just a little sketchy.
* <p>
* Note: this is *not* related to the allowDiagonalDescend setting, that is a completely different thing.
*/
public final Setting<Boolean> allowOvershootDiagonalDescend = new Setting<>(true);
public Setting<Boolean> allowOvershootDiagonalDescend = new Setting<>(true);
/**
* If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord
@@ -388,152 +239,125 @@ public final class Settings {
* of considering the Y coord. The reasoning is that if your X and Z are 10,000 blocks away,
* your Y coordinate's accuracy doesn't matter at all until you get much much closer.
*/
public final Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true);
public Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true);
/**
* If a movement takes this many ticks more than its initial cost estimate, cancel it
*/
public final Setting<Integer> movementTimeoutTicks = new Setting<>(100);
public Setting<Integer> movementTimeoutTicks = new Setting<>(100);
/**
* 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 final Setting<Long> primaryTimeoutMS = new Setting<>(500L);
public Setting<Long> primaryTimeoutMS = new Setting<>(500L);
/**
* Pathing can never take longer than this, even if that means failing to find any path at all
*/
public final Setting<Long> failureTimeoutMS = new Setting<>(2000L);
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 final Setting<Long> planAheadPrimaryTimeoutMS = new Setting<>(4000L);
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 final Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
public Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
/**
* For debugging, consider nodes much much slower
*/
public final Setting<Boolean> slowPath = new Setting<>(false);
public Setting<Boolean> slowPath = new Setting<>(false);
/**
* Milliseconds between each node
*/
public final Setting<Long> slowPathTimeDelayMS = new Setting<>(100L);
public Setting<Long> slowPathTimeDelayMS = new Setting<>(100L);
/**
* The alternative timeout number when slowPath is on
*/
public final Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
public Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
/**
* The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing.
*/
public final Setting<Boolean> chunkCaching = new Setting<>(true);
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
* <p>
* Temporarily reenabled
*
* @see <a href="https://github.com/cabaletta/baritone/issues/248">Issue #248</a>
* Temporarily disabled, see issue #248
*/
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);
/**
* Remember the contents of containers (chests, echests, furnaces)
* <p>
* Really buggy since the packet stuff is multithreaded badly thanks to brady
*/
public final Setting<Boolean> containerMemory = new Setting<>(false);
/**
* Fill in blocks behind you
*/
public final Setting<Boolean> backfill = new Setting<>(false);
public Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
/**
* Print all the debug messages to chat
*/
public final Setting<Boolean> chatDebug = new Setting<>(false);
public Setting<Boolean> chatDebug = new Setting<>(true);
/**
* Allow chat based control of Baritone. Most likely should be disabled when Baritone is imported for use in
* something else
*/
public final Setting<Boolean> chatControl = new Setting<>(true);
public Setting<Boolean> chatControl = new Setting<>(true);
/**
* A second override over chatControl to force it on
*/
public final Setting<Boolean> removePrefix = new Setting<>(false);
public Setting<Boolean> removePrefix = new Setting<>(false);
/**
* Render the path
*/
public final Setting<Boolean> renderPath = new Setting<>(true);
public Setting<Boolean> renderPath = new Setting<>(true);
/**
* Render the goal
*/
public final Setting<Boolean> renderGoal = new Setting<>(true);
/**
* Render selection boxes
*/
public final Setting<Boolean> renderSelectionBoxes = new Setting<>(true);
public Setting<Boolean> renderGoal = new Setting<>(true);
/**
* Ignore depth when rendering the goal
*/
public final 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 final Setting<Boolean> renderGoalXZBeacon = new Setting<>(false);
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
/**
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
*/
public final Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
/**
* Ignore depth when rendering the path
*/
public final Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
/**
* Line width of the path when rendered, in pixels
*/
public final Setting<Float> pathRenderLineWidthPixels = new Setting<>(5F);
public Setting<Float> pathRenderLineWidthPixels = new Setting<>(5F);
/**
* Line width of the goal when rendered, in pixels
*/
public final Setting<Float> goalRenderLineWidthPixels = new Setting<>(3F);
public Setting<Float> goalRenderLineWidthPixels = new Setting<>(3F);
/**
* Start fading out the path at 20 movements ahead, and stop rendering it entirely 30 movements ahead.
* Improves FPS.
*/
public final Setting<Boolean> fadePath = new Setting<>(false);
public Setting<Boolean> fadePath = new Setting<>(false);
/**
* Move without having to force the client-sided rotations
*/
public final Setting<Boolean> freeLook = new Setting<>(true);
public Setting<Boolean> freeLook = new Setting<>(true);
/**
* Will cause some minor behavioral differences to ensure that Baritone works on anticheats.
@@ -541,159 +365,52 @@ public final class Settings {
* At the moment this will silently set the player's rotations when using freeLook so you're not sprinting in
* directions other than forward, which is picken up by more "advanced" anticheats like AAC, but not NCP.
*/
public final Setting<Boolean> antiCheatCompatibility = new Setting<>(true);
public Setting<Boolean> antiCheatCompatibility = new Setting<>(true);
/**
* Exclusively use cached chunks for pathing
* <p>
* Never turn this on
*/
public final Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
/**
* Continue sprinting while in water
*/
public final Setting<Boolean> sprintInWater = new Setting<>(true);
/**
* When GetToBlockProcess or MineProcess fails to calculate a path, instead of just giving up, mark the closest instance
* of that block as "unreachable" and go towards the next closest. GetToBlock expands this seaarch to the whole "vein"; MineProcess does not.
* This is because MineProcess finds individual impossible blocks (like one block in a vein that has gravel on top then lava, so it can't break)
* Whereas GetToBlock should blacklist the whole "vein" if it can't get to any of them.
*/
public final Setting<Boolean> blacklistClosestOnFailure = new Setting<>(true);
/**
* 😎 Render cached chunks as semitransparent. Doesn't work with OptiFine 😭 Rarely randomly crashes, see <a href="https://github.com/cabaletta/baritone/issues/327">this issue</a>.
* <p>
* Can be very useful on servers with low render distance. After enabling, you may need to reload the world in order for it to have an effect
* (e.g. disconnect and reconnect, enter then exit the nether, die and respawn, etc). This may literally kill your FPS and CPU because
* every chunk gets recompiled twice as much as normal, since the cached version comes into range, then the normal one comes from the server for real.
* <p>
* Note that flowing water is cached as AVOID, which is rendered as lava. As you get closer, you may therefore see lava falls being replaced with water falls.
* <p>
* SOLID is rendered as stone in the overworld, netherrack in the nether, and end stone in the end
*/
public final Setting<Boolean> renderCachedChunks = new Setting<>(false);
/**
* 0.0f = not visible, fully transparent (instead of setting this to 0, turn off renderCachedChunks)
* 1.0f = fully opaque
*/
public final Setting<Float> cachedChunksOpacity = new Setting<>(0.5f);
public Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
/**
* Whether or not to use the "#" command prefix
*/
public final Setting<Boolean> prefixControl = new Setting<>(true);
public Setting<Boolean> prefix = new Setting<>(false);
/**
* {@code true}: can mine blocks when in inventory, chat, or tabbed away in ESC menu
* <p>
* {@code false}: works on cosmic prisons
* <p>
* LOL
*/
public Setting<Boolean> leftClickWorkaround = new Setting<>(true);
/**
* Don't stop walking forward when you need to break blocks in your way
*/
public final Setting<Boolean> walkWhileBreaking = new Setting<>(true);
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
/**
* When a new segment is calculated that doesn't overlap with the current one, but simply begins where the current segment ends,
* splice it on and make a longer combined path. If this setting is off, any planned segment will not be spliced and will instead
* be the "next path" in PathingBehavior, and will only start after this one ends. Turning this off hurts planning ahead,
* because the next segment will exist even if it's very short.
*
* @see #planningTickLookahead
* If we are more than 500 movements into the current path, discard the oldest segments, as they are no longer useful
*/
public final Setting<Boolean> splicePath = new Setting<>(true);
/**
* If we are more than 300 movements into the current path, discard the oldest segments, as they are no longer useful
*/
public final Setting<Integer> maxPathHistoryLength = new Setting<>(300);
public Setting<Integer> maxPathHistoryLength = new Setting<>(300);
/**
* If the current path is too long, cut off this many movements from the beginning.
*/
public final Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
public Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
/**
* Rescan for the goal once every 5 ticks.
* Set to 0 to disable.
*/
public final Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
/**
* After finding this many instances of the target block in the cache, it will stop expanding outward the chunk search.
*/
public final Setting<Integer> maxCachedWorldScanCount = new Setting<>(10);
/**
* When GetToBlock doesn't know any locations for the desired block, explore randomly instead of giving up.
*/
public final Setting<Boolean> exploreForBlocks = new Setting<>(true);
/**
* While exploring the world, offset the closest unloaded chunk by this much in both axes.
* <p>
* This can result in more efficient loading, if you set this to the render distance.
*/
public final Setting<Integer> worldExploringChunkOffset = new Setting<>(0);
/**
* Take the 10 closest chunks, even if they aren't strictly tied for distance metric from origin.
*/
public final Setting<Integer> exploreChunkSetMinimumSize = new Setting<>(10);
/**
* Attempt to maintain Y coordinate while exploring
* <p>
* -1 to disable
*/
public final Setting<Integer> exploreMaintainY = new Setting<>(64);
/**
* Replant nether wart while farming
*/
public final Setting<Boolean> replantNetherWart = new Setting<>(false);
/**
* When the cache scan gives less blocks than the maximum threshold (but still above zero), scan the main world too.
* <p>
* Only if you have a beefy CPU and automatically mine blocks that are in cache
*/
public final Setting<Boolean> extendCacheOnThreshold = new Setting<>(false);
/**
* Don't consider the next layer in builder until the current one is done
*/
public final Setting<Boolean> buildInLayers = new Setting<>(false);
/**
* false = build from bottom to top
* <p>
* true = build from top to bottom
*/
public final Setting<Boolean> layerOrder = new Setting<>(false);
/**
* How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely
*/
public final Setting<Vec3i> buildRepeat = new Setting<>(new Vec3i(0, 0, 0));
/**
* Allow standing above a block while mining it, in BuilderProcess
* <p>
* Experimental
*/
public final Setting<Boolean> breakFromAbove = new Setting<>(false);
/**
* As well as breaking from above, set a goal to up and to the side of all blocks to break.
* <p>
* Never turn this on without also turning on breakFromAbove.
*/
public final Setting<Boolean> goalBreakFromAbove = new Setting<>(false);
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 final Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
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.
@@ -708,78 +425,54 @@ public final 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 final Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
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 final Setting<Integer> axisHeight = new Setting<>(120);
public Setting<Integer> axisHeight = new Setting<>(120);
/**
* Disconnect from the server upon arriving at your goal
*/
public final Setting<Boolean> disconnectOnArrival = new Setting<>(false);
/**
* Disallow MineBehavior from using X-Ray to see where the ores are. Turn this option on to force it to mine "legit"
* 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 on
* couldn't. If you don't want it to look like you're X-Raying, turn this off
*/
public final Setting<Boolean> legitMine = new Setting<>(false);
public Setting<Boolean> legitMine = new Setting<>(false);
/**
* What Y level to go to for legit strip mining
*/
public final Setting<Integer> legitMineYLevel = new Setting<>(11);
/**
* Magically see ores that are separated diagonally from existing ores. Basically like mining around the ores that it finds
* in case there's one there touching it diagonally, except it checks it un-legit-ly without having the mine blocks to see it.
* You can decide whether this looks plausible or not.
* <p>
* This is disabled because it results in some weird behavior. For example, it can """see""" the top block of a vein of iron_ore
* through a lava lake. This isn't an issue normally since it won't consider anything touching lava, so it just ignores it.
* However, this setting expands that and allows it to see the entire vein so it'll mine under the lava lake to get the iron that
* it can reach without mining blocks adjacent to lava. This really defeats the purpose of legitMine since a player could never
* do that lol, so thats one reason why its disabled
*/
public final Setting<Boolean> legitMineIncludeDiagonals = new Setting<>(false);
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
* If the block below is also a goal block, set GoalBlock to the position one down instead of GoalTwoBlocks
*/
public final Setting<Boolean> forceInternalMining = new Setting<>(true);
public Setting<Boolean> forceInternalMining = new Setting<>(true);
/**
* Modification to the previous setting, only has effect if forceInternalMining is true
* If true, only apply the previous setting if the block adjacent to the goal isn't air.
*/
public final Setting<Boolean> internalMiningAirException = new Setting<>(true);
public Setting<Boolean> internalMiningAirException = new Setting<>(true);
/**
* The actual GoalNear is set this distance away from the entity you're following
* <p>
* For example, set followOffsetDistance to 5 and followRadius to 0 to always stay precisely 5 blocks north of your follow target.
*/
public final Setting<Double> followOffsetDistance = new Setting<>(0D);
public Setting<Double> followOffsetDistance = new Setting<>(0D);
/**
* The actual GoalNear is set in this direction from the entity you're following. This value is in degrees.
* The actual GoalNear is set in this direction from the entity you're following
*/
public final Setting<Float> followOffsetDirection = new Setting<>(0F);
public Setting<Float> followOffsetDirection = new Setting<>(0F);
/**
* The radius (for the GoalNear) of how close to your target position you actually have to be
*/
public final Setting<Integer> followRadius = new Setting<>(3);
/**
* Turn this on if your exploration filter is enormous, you don't want it to check if it's done,
* and you are just fine with it just hanging on completion
*/
public final Setting<Boolean> disableCompletionCheck = new Setting<>(false);
public Setting<Integer> followRadius = new Setting<>(3);
/**
* Cached chunks (regardless of if they're in RAM or saved to disk) expire and are deleted after this number of seconds
@@ -801,60 +494,54 @@ public final class Settings {
* has to build up that cache from scratch. But after it's gone through an area just once, the next time will have zero
* backtracking, since the entire area is now known and cached.
*/
public final Setting<Long> cachedChunksExpirySeconds = new Setting<>(-1L);
public Setting<Long> cachedChunksExpirySeconds = new Setting<>(-1L);
/**
* The function that is called when Baritone will log to chat. This function can be added to
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
* {@link Setting#value};
*/
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
/**
* The size of the box that is rendered when the current goal is a GoalYLevel
*/
public final Setting<Double> yLevelBoxSize = new Setting<>(15D);
public Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
/**
* The color of the current path
*/
public final Setting<Color> colorCurrentPath = new Setting<>(Color.RED);
public Setting<Color> colorCurrentPath = new Setting<>(Color.RED);
/**
* The color of the next path
*/
public final Setting<Color> colorNextPath = new Setting<>(Color.MAGENTA);
public Setting<Color> colorNextPath = new Setting<>(Color.MAGENTA);
/**
* The color of the blocks to break
*/
public final Setting<Color> colorBlocksToBreak = new Setting<>(Color.RED);
public Setting<Color> colorBlocksToBreak = new Setting<>(Color.RED);
/**
* The color of the blocks to place
*/
public final Setting<Color> colorBlocksToPlace = new Setting<>(Color.GREEN);
public Setting<Color> colorBlocksToPlace = new Setting<>(Color.GREEN);
/**
* The color of the blocks to walk into
*/
public final Setting<Color> colorBlocksToWalkInto = new Setting<>(Color.MAGENTA);
public Setting<Color> colorBlocksToWalkInto = new Setting<>(Color.MAGENTA);
/**
* The color of the best path so far
*/
public final Setting<Color> colorBestPathSoFar = new Setting<>(Color.BLUE);
public Setting<Color> colorBestPathSoFar = new Setting<>(Color.BLUE);
/**
* The color of the path to the most recent considered node
*/
public final Setting<Color> colorMostRecentConsidered = new Setting<>(Color.CYAN);
public Setting<Color> colorMostRecentConsidered = new Setting<>(Color.CYAN);
/**
* The color of the goal box
*/
public final Setting<Color> colorGoalBox = new Setting<>(Color.GREEN);
public Setting<Color> colorGoalBox = new Setting<>(Color.GREEN);
/**
* A map of lowercase setting field names to their respective setting
@@ -866,12 +553,11 @@ public final class Settings {
*/
public final List<Setting<?>> allSettings;
public final Map<Setting<?>, Type> settingTypes;
public final class Setting<T> {
public class Setting<T> {
public T value;
public final T defaultValue;
private String name;
private final Class<T> klass;
@SuppressWarnings("unchecked")
private Setting(T value) {
@@ -880,16 +566,12 @@ public final class Settings {
}
this.value = value;
this.defaultValue = value;
this.klass = (Class<T>) value.getClass();
}
/**
* Deprecated! Please use .value directly instead
*
* @return the current setting value
*/
@Deprecated
public final T get() {
return value;
@SuppressWarnings("unchecked")
public final <K extends T> K get() {
return (K) value;
}
public final String getName() {
@@ -897,24 +579,11 @@ public final class Settings {
}
public Class<T> getValueClass() {
// noinspection unchecked
return (Class<T>) TypeUtils.resolveBaseClass(getType());
return klass;
}
@Override
public String toString() {
return SettingsUtil.settingToString(this);
}
/**
* Reset this setting to its default value
*/
public void reset() {
value = defaultValue;
}
public final Type getType() {
return settingTypes.get(this);
return name + ": " + value;
}
}
@@ -922,11 +591,8 @@ public final class Settings {
Settings() {
Field[] temp = getClass().getFields();
Map<String, Setting<?>> tmpByName = new HashMap<>();
HashMap<String, Setting<?>> tmpByName = new HashMap<>();
List<Setting<?>> tmpAll = new ArrayList<>();
Map<Setting<?>, Type> tmpSettingTypes = new HashMap<>();
try {
for (Field field : temp) {
if (field.getType().equals(Setting.class)) {
@@ -939,7 +605,6 @@ public final class Settings {
}
tmpByName.put(name, setting);
tmpAll.add(setting);
tmpSettingTypes.put(setting, ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]);
}
}
} catch (IllegalAccessException e) {
@@ -947,7 +612,6 @@ public final class Settings {
}
byLowerName = Collections.unmodifiableMap(tmpByName);
allSettings = Collections.unmodifiableList(tmpAll);
settingTypes = Collections.unmodifiableMap(tmpSettingTypes);
}
@SuppressWarnings("unchecked")

View File

@@ -18,13 +18,9 @@
package baritone.api.behavior;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.event.listener.IGameEventListener;
/**
* A behavior is simply a type that is able to listen to events.
*
* @author Brady
* @see IGameEventListener
* @since 9/23/2018
*/
public interface IBehavior extends AbstractGameEventListener {}

View File

@@ -15,8 +15,9 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.cache;
package baritone.api.behavior;
import baritone.api.behavior.memory.IRememberedInventory;
import net.minecraft.util.math.BlockPos;
import java.util.Map;
@@ -25,7 +26,7 @@ import java.util.Map;
* @author Brady
* @since 9/23/2018
*/
public interface IContainerMemory {
public interface IMemoryBehavior extends IBehavior {
/**
* Gets a remembered inventory by its block position.

View File

@@ -37,26 +37,7 @@ public interface IPathingBehavior extends IBehavior {
*
* @return The estimated remaining ticks in the current segment.
*/
default Optional<Double> ticksRemainingInSegment() {
return ticksRemainingInSegment(true);
}
/**
* Returns the estimated remaining ticks in the current pathing
* segment. Given that the return type is an optional, {@link Optional#empty()}
* will be returned in the case that there is no current segment being pathed.
*
* @param includeCurrentMovement whether or not to include the entirety of the cost of the currently executing movement in the total
* @return The estimated remaining ticks in the current segment.
*/
default Optional<Double> ticksRemainingInSegment(boolean includeCurrentMovement) {
IPathExecutor current = getCurrent();
if (current == null) {
return Optional.empty();
}
int start = includeCurrentMovement ? current.getPosition() : current.getPosition() + 1;
return Optional.of(current.getPath().ticksRemainingFrom(start));
}
Optional<Double> ticksRemainingInSegment();
/**
* @return The current pathing goal
@@ -66,9 +47,7 @@ public interface IPathingBehavior extends IBehavior {
/**
* @return Whether or not a path is currently being executed.
*/
default boolean isPathing() {
return getCurrent() != null;
}
boolean isPathing();
/**
* Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path.
@@ -80,13 +59,6 @@ public interface IPathingBehavior extends IBehavior {
*/
boolean cancelEverything();
/**
* PLEASE never call this
* <p>
* If cancelEverything was like "kill" this is "sudo kill -9". Or shutting off your computer.
*/
void forceCancel();
/**
* Returns the current path, from the current path executor, if there is one.
*

View File

@@ -15,7 +15,7 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.cache;
package baritone.api.behavior.memory;
import net.minecraft.item.ItemStack;

View File

@@ -37,12 +37,12 @@ public interface ICachedRegion extends IBlockTypeAccess {
boolean isCached(int blockX, int blockZ);
/**
* @return The X coordinate of this region
* The X coordinate of this region
*/
int getX();
/**
* @return The Z coordinate of this region
* The Z coordinate of this region
*/
int getZ();
}

View File

@@ -20,7 +20,7 @@ package baritone.api.cache;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.Chunk;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* @author Brady
@@ -68,7 +68,7 @@ public interface ICachedWorld {
* @param maxRegionDistanceSq The maximum region distance, squared
* @return The locations found that match the special block
*/
ArrayList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, 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
@@ -81,6 +81,4 @@ public interface ICachedWorld {
* in a new thread by default.
*/
void save();
}

View File

@@ -27,19 +27,13 @@ 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();
}

View File

@@ -20,7 +20,6 @@ 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;
@@ -43,18 +42,4 @@ public interface IWorldScanner {
* @return The matching block positions
*/
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);
}

View File

@@ -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#START_BREAK} or {@link Type#USE}.
* Called when the local player interacts with a block, can be either {@link Type#BREAK} or {@link Type#USE}.
*
* @author Brady
* @since 8/22/2018
@@ -59,9 +59,9 @@ public final class BlockInteractEvent {
public enum Type {
/**
* We're starting to break the target block.
* We're breaking the target block.
*/
START_BREAK,
BREAK,
/**
* We're right clicking on the target block. Either placing or interacting with.

View File

@@ -17,20 +17,22 @@
package baritone.api.event.events;
import baritone.api.event.events.type.Cancellable;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
/**
* @author Brady
* @since 8/1/2018
*/
public final class ChatEvent extends Cancellable {
public final class ChatEvent extends ManagedPlayerEvent.Cancellable {
/**
* The message being sent
*/
private final String message;
public ChatEvent(String message) {
public ChatEvent(EntityPlayerSP player, String message) {
super(player);
this.message = message;
}

View File

@@ -31,9 +31,7 @@ public final class ChunkEvent {
private final EventState state;
/**
* The type of chunk event that occurred
*
* @see Type
* The type of chunk event that occurred;
*/
private final Type type;

View File

@@ -18,19 +18,22 @@
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;
/**
* @author Brady
* @since 8/21/2018
*/
public final class PlayerUpdateEvent {
public final class PlayerUpdateEvent extends ManagedPlayerEvent {
/**
* The state of the event
*/
private final EventState state;
public PlayerUpdateEvent(EventState state) {
public PlayerUpdateEvent(EntityPlayerSP player, EventState state) {
super(player);
this.state = state;
}

View File

@@ -17,6 +17,8 @@
package baritone.api.event.events;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
@@ -24,7 +26,7 @@ import net.minecraft.entity.EntityLivingBase;
* @author Brady
* @since 8/21/2018
*/
public final class RotationMoveEvent {
public final class RotationMoveEvent extends ManagedPlayerEvent {
/**
* The type of event
@@ -36,7 +38,8 @@ public final class RotationMoveEvent {
*/
private float yaw;
public RotationMoveEvent(Type type, float yaw) {
public RotationMoveEvent(EntityPlayerSP player, Type type, float yaw) {
super(player);
this.type = type;
this.yaw = yaw;
}

View File

@@ -0,0 +1,61 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.event.events.type;
import net.minecraft.client.entity.EntityPlayerSP;
/**
* An event that has a reference to a locally managed player.
*
* @author Brady
* @since 10/11/2018
*/
public class ManagedPlayerEvent {
protected final EntityPlayerSP player;
public ManagedPlayerEvent(EntityPlayerSP player) {
this.player = player;
}
public final EntityPlayerSP getPlayer() {
return this.player;
}
public static class Cancellable extends ManagedPlayerEvent implements ICancellable {
/**
* Whether or not this event has been cancelled
*/
private boolean cancelled;
public Cancellable(EntityPlayerSP player) {
super(player);
}
@Override
public final void cancel() {
this.cancelled = true;
}
@Override
public final boolean isCancelled() {
return this.cancelled;
}
}
}

View File

@@ -36,6 +36,9 @@ public interface AbstractGameEventListener extends IGameEventListener {
@Override
default void onPlayerUpdate(PlayerUpdateEvent event) {}
@Override
default void onProcessKeyBinds() {}
@Override
default void onSendChatMessage(ChatEvent event) {}
@@ -57,9 +60,6 @@ public interface AbstractGameEventListener extends IGameEventListener {
@Override
default void onPlayerRotationMove(RotationMoveEvent event) {}
@Override
default void onPlayerSprintState(SprintStateEvent event) {}
@Override
default void onBlockInteract(BlockInteractEvent event) {}

View File

@@ -23,9 +23,13 @@ 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
@@ -36,7 +40,6 @@ public interface IGameEventListener {
/**
* Run once per game tick before screen input is handled.
*
* @param event The event
* @see Minecraft#runTick()
*/
void onTick(TickEvent event);
@@ -44,15 +47,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);
@@ -60,7 +68,6 @@ 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);
@@ -70,14 +77,13 @@ public interface IGameEventListener {
* <p>
* <b>Note:</b> {@link GameSettings#anaglyph} has been removed in Minecraft 1.13
*
* @param event The event
* @see EntityRenderer#renderWorldPass(int, float, long)
*/
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);
@@ -85,7 +91,7 @@ public interface IGameEventListener {
/**
* Runs before a outbound packet is sent
*
* @param event The event
* @see NetworkManager#dispatchPacket(Packet, GenericFutureListener[])
* @see Packet
* @see GenericFutureListener
*/
@@ -94,7 +100,7 @@ public interface IGameEventListener {
/**
* Runs before an inbound packet is processed
*
* @param event The event
* @see NetworkManager#dispatchPacket(Packet, GenericFutureListener[])
* @see Packet
* @see GenericFutureListener
*/
@@ -104,37 +110,31 @@ 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 whenever the sprint keybind state is checked in {@link EntityPlayerSP#onLivingUpdate}
*
* @param event The event
* @see EntityPlayerSP#onLivingUpdate()
*/
void onPlayerSprintState(SprintStateEvent event);
/**
* Called when the local player interacts with a block, whether it is breaking or opening/placing.
*
* @param event The event
* @see Minecraft#clickMouse()
* @see Minecraft#rightClickMouse()
*/
void onBlockInteract(BlockInteractEvent event);
/**
* Called when the local player dies, as indicated by the creation of the {@link GuiGameOver} screen.
*
* @see GuiGameOver
* @see GuiGameOver(ITextComponent)
* @see ITextComponent
*/
void onPlayerDeath();
/**
* When the pathfinder's state changes
*
* @param event The event
* @param event
*/
void onPathEvent(PathEvent event);
}

View File

@@ -21,6 +21,7 @@ import baritone.api.Settings;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.world.World;
import java.util.HashSet;
import java.util.List;
@@ -51,8 +52,6 @@ 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 IPath postProcess() {
throw new UnsupportedOperationException();
@@ -105,28 +104,33 @@ public interface IPath {
* Returns the estimated number of ticks to complete the path from the given node index.
*
* @param pathPosition The index of the node we're calculating from
* @return The estimated number of ticks remaining frm the given position
* @return The estimated number of ticks remaining from the given position
*/
default double ticksRemainingFrom(int pathPosition) {
double sum = 0;
//this is fast because we aren't requesting recalculation, it's just cached
List<IMovement> movements = movements();
for (int i = pathPosition; i < movements.size(); i++) {
sum += movements.get(i).getCost();
for (int i = pathPosition; i < movements().size(); i++) {
sum += movements().get(i).getCost();
}
return sum;
}
/**
* Returns the estimated amount of time needed to complete this path from start to finish
*
* @return The estimated amount of time, in ticks
*/
default double totalTicks() {
return ticksRemainingFrom(0);
}
/**
* 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(Object bsi) {
default IPath cutoffAtLoadedChunks(World world) {
throw new UnsupportedOperationException();
}
@@ -134,7 +138,6 @@ public interface IPath {
* 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

View File

@@ -34,8 +34,6 @@ 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
*/
PathCalculationResult calculate(long primaryTimeout, long failureTimeout);

View File

@@ -22,26 +22,10 @@ import baritone.api.process.PathingCommand;
import java.util.Optional;
/**
* @author leijurv
*/
public interface IPathingControlManager {
/**
* Registers a process with this pathing control manager. See {@link IBaritoneProcess} for more details.
*
* @param process The process
* @see IBaritoneProcess
*/
void registerProcess(IBaritoneProcess process);
/**
* @return The most recent {@link IBaritoneProcess} that had control
*/
Optional<IBaritoneProcess> mostRecentInControl();
/**
* @return The most recent pathing command executed
*/
Optional<PathingCommand> mostRecentCommand();
}

View File

@@ -30,9 +30,6 @@ 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);
@@ -40,9 +37,6 @@ 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);

View File

@@ -25,7 +25,7 @@ public class GoalAxis implements Goal {
@Override
public boolean isInGoal(int x, int y, int z) {
return y == BaritoneAPI.getSettings().axisHeight.value && (x == 0 || z == 0 || Math.abs(x) == Math.abs(z));
return y == BaritoneAPI.getSettings().axisHeight.get() && (x == 0 || z == 0 || Math.abs(x) == Math.abs(z));
}
@Override
@@ -39,7 +39,7 @@ public class GoalAxis implements Goal {
double flatAxisDistance = Math.min(x, Math.min(z, diff * SQRT_2_OVER_2));
return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.value + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.value, y);
return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.get() + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.get(), y);
}
@Override

View File

@@ -30,17 +30,17 @@ public class GoalBlock implements Goal, IGoalRenderPos {
/**
* The X block position of this goal
*/
public final int x;
private final int x;
/**
* The Y block position of this goal
*/
public final int y;
private final int y;
/**
* The Z block position of this goal
*/
public final int z;
private final int z;
public GoalBlock(BlockPos pos) {
this(pos.getX(), pos.getY(), pos.getZ());

View File

@@ -28,9 +28,9 @@ import net.minecraft.util.math.BlockPos;
*/
public class GoalGetToBlock implements Goal, IGoalRenderPos {
public final int x;
public final int y;
public final int z;
private final int x;
private final int y;
private final int z;
public GoalGetToBlock(BlockPos pos) {
this.x = pos.getX();

View File

@@ -61,6 +61,6 @@ public class GoalNear implements Goal, IGoalRenderPos {
", y=" + y +
", z=" + z +
", rangeSq=" + rangeSq +
"}";
'}';
}
}

View File

@@ -1,75 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.pathing.goals;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
/**
* Dig a tunnel in a certain direction, but if you have to deviate from the path, go back to where you started
*/
public class GoalStrictDirection implements Goal {
public final int x;
public final int y;
public final int z;
public final int dx;
public final int dz;
public GoalStrictDirection(BlockPos origin, EnumFacing direction) {
x = origin.getX();
y = origin.getY();
z = origin.getZ();
dx = direction.getXOffset();
dz = direction.getZOffset();
if (dx == 0 && dz == 0) {
throw new IllegalArgumentException(direction + "");
}
}
@Override
public boolean isInGoal(int x, int y, int z) {
return false;
}
@Override
public double heuristic(int x, int y, int z) {
int distanceFromStartInDesiredDirection = (x - this.x) * dx + (z - this.z) * dz;
int distanceFromStartInIncorrectDirection = Math.abs((x - this.x) * dz) + Math.abs((z - this.z) * dx);
int verticalDistanceFromStart = Math.abs(y - this.y);
// we want heuristic to decrease as desiredDirection increases
double heuristic = -distanceFromStartInDesiredDirection * 100;
heuristic += distanceFromStartInIncorrectDirection * 1000;
heuristic += verticalDistanceFromStart * 1000;
return heuristic;
}
@Override
public String toString() {
return "GoalStrictDirection{" +
"x=" + x +
", y=" + y +
", z=" + z +
", dx=" + dx +
", dz=" + dz +
"}";
}
}

View File

@@ -31,17 +31,17 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
/**
* The X block position of this goal
*/
protected final int x;
private final int x;
/**
* The Y block position of this goal
*/
protected final int y;
private final int y;
/**
* The Z block position of this goal
*/
protected final int z;
private final int z;
public GoalTwoBlocks(BlockPos pos) {
this(pos.getX(), pos.getY(), pos.getZ());

View File

@@ -80,7 +80,7 @@ public class GoalXZ implements Goal {
diagonal = z;
}
diagonal *= SQRT_2;
return (diagonal + straight) * BaritoneAPI.getSettings().costHeuristic.value; // big TODO tune
return (diagonal + straight) * BaritoneAPI.getSettings().costHeuristic.get(); // big TODO tune
}
public static GoalXZ fromDirection(Vec3d origin, float yaw, double distance) {

View File

@@ -29,7 +29,7 @@ public class GoalYLevel implements Goal, ActionCosts {
/**
* The target Y level
*/
public final int level;
private final int level;
public GoalYLevel(int level) {
this.level = level;

View File

@@ -20,6 +20,8 @@ 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
@@ -45,6 +47,10 @@ public interface IMovement {
*/
boolean safeToCancel();
double recalculateCost();
double calculateCostWithoutCaching();
boolean calculatedWhileLoaded();
BetterBlockPos getSrc();
@@ -52,4 +58,10 @@ public interface IMovement {
BetterBlockPos getDest();
BlockPos getDirection();
List<BlockPos> toBreak();
List<BlockPos> toPlace();
List<BlockPos> toWalkInto();
}

View File

@@ -26,6 +26,4 @@ import baritone.api.pathing.calc.IPath;
public interface IPathExecutor {
IPath getPath();
int getPosition();
}

View File

@@ -17,6 +17,7 @@
package baritone.api.process;
import baritone.api.IBaritone;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.event.events.PathEvent;
@@ -24,10 +25,8 @@ import baritone.api.event.events.PathEvent;
* A process that can control the PathingBehavior.
* <p>
* Differences between a baritone process and a behavior:
* <ul>
* <li>Only one baritone process can be active at a time</li>
* <li>PathingBehavior can only be controlled by a process</li>
* </ul>
* Only one baritone process can be active at a time
* PathingBehavior can only be controlled by a process
* <p>
* That's it actually
*
@@ -35,16 +34,6 @@ import baritone.api.event.events.PathEvent;
*/
public interface IBaritoneProcess {
/**
* Default priority. Most normal processes should have this value.
* <p>
* Some examples of processes that should have different values might include some kind of automated mob avoidance
* that would be temporary and would forcefully take control. Same for something that pauses pathing for auto eat, etc.
* <p>
* The value is -1 beacuse that's what Impact 4.5's beta auto walk returns and I want to tie with it.
*/
double DEFAULT_PRIORITY = -1;
/**
* Would this process like to be in control?
*
@@ -92,23 +81,19 @@ public interface IBaritoneProcess {
*
* @return A double representing the priority
*/
default double priority() {
return DEFAULT_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
*/
default String displayName() {
if (!isActive()) {
// i love it when impcat's scuffed HUD calls displayName for inactive processes for 1 tick too long
// causing NPEs when the displayname relies on fields that become null when inactive
return "INACTIVE";
}
return displayName0();
}
String displayName0();
String displayName();
}

View File

@@ -1,62 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.process;
import baritone.api.utils.ISchematic;
import net.minecraft.client.Minecraft;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import java.io.File;
/**
* @author Brady
* @since 1/15/2019
*/
public interface IBuilderProcess extends IBaritoneProcess {
/**
* Requests a build for the specified schematic, labeled as specified, with the specified origin.
*
* @param name A user-friendly name for the schematic
* @param schematic The object representation of the schematic
* @param origin The origin position of the schematic being built
*/
void build(String name, ISchematic schematic, Vec3i origin);
/**
* Requests a build for the specified schematic, labeled as specified, with the specified origin.
*
* @param name A user-friendly name for the schematic
* @param schematic The file path of the schematic
* @param origin The origin position of the schematic being built
* @return Whether or not the schematic was able to load from file
*/
boolean build(String name, File schematic, Vec3i origin);
default boolean build(String schematicFile, BlockPos origin) {
File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile);
return build(schematicFile, file, origin);
}
void pause();
void resume();
void clearArea(BlockPos corner1, BlockPos corner2);
}

View File

@@ -25,6 +25,4 @@ import net.minecraft.block.Block;
public interface IGetToBlockProcess extends IBaritoneProcess {
void getToBlock(Block block);
boolean blacklistClosest();
}

View File

@@ -53,9 +53,4 @@ public class PathingCommand {
this.goal = goal;
this.commandType = commandType;
}
@Override
public String toString() {
return commandType + " " + goal;
}
}

View File

@@ -51,10 +51,5 @@ public enum PathingCommandType {
* <p>
* Cancel the current path if the goals are not equal
*/
FORCE_REVALIDATE_GOAL_AND_PATH,
/**
* Go and ask the next process what to do
*/
DEFER
FORCE_REVALIDATE_GOAL_AND_PATH
}

View File

@@ -61,8 +61,6 @@ public final class BetterBlockPos extends BlockPos {
}
public static long longHash(int x, int y, int z) {
// TODO use the same thing as BlockPos.fromLong();
// invertibility would be incredibly useful
/*
* This is the hashcode implementation of Vec3i (the superclass of the class which I shall not name)
*

View File

@@ -1,63 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils;
import net.minecraft.block.Block;
import net.minecraft.util.ResourceLocation;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class BlockUtils {
private static transient Map<String, Block> resourceCache = new HashMap<>();
public static String blockToString(Block block) {
ResourceLocation loc = Block.REGISTRY.getNameForObject(block);
String name = loc.getPath(); // normally, only write the part after the minecraft:
if (!loc.getNamespace().equals("minecraft")) {
// Baritone is running on top of forge with mods installed, perhaps?
name = loc.toString(); // include the namespace with the colon
}
return name;
}
public static Block stringToBlockRequired(String name) {
Block block = stringToBlockNullable(name);
Objects.requireNonNull(block);
return block;
}
public static Block stringToBlockNullable(String name) {
// do NOT just replace this with a computeWithAbsent, it isn't thread safe
Block block = resourceCache.get(name); // map is never mutated in place so this is safe
if (block != null) {
return block;
}
if (resourceCache.containsKey(name)) {
return null; // cached as null
}
block = Block.getBlockFromName(name.contains(":") ? name : "minecraft:" + name);
Map<String, Block> copy = new HashMap<>(resourceCache); // read only copy is safe, wont throw concurrentmodification
copy.put(name, block);
resourceCache = copy;
return block;
}
private BlockUtils() {}
}

View File

@@ -1,712 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.cache.IRememberedInventory;
import baritone.api.cache.IWaypoint;
import baritone.api.cache.Waypoint;
import baritone.api.event.events.ChatEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.pathing.goals.*;
import baritone.api.process.IBaritoneProcess;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.process.IGetToBlockProcess;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.crash.CrashReport;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ReportedException;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.Chunk;
import java.nio.file.Path;
import java.util.*;
public class ExampleBaritoneControl implements Helper, AbstractGameEventListener {
private static final String HELP_MSG =
"baritone - Output settings into chat\n" +
"settings - Same as baritone\n" +
"goal - Create a goal (one number is '<Y>', two is '<X> <Z>', three is '<X> <Y> <Z>, 'clear' to clear)\n" +
"path - Go towards goal\n" +
"repack - (debug) Repacks chunk cache\n" +
"rescan - (debug) Same as repack\n" +
"axis - Paths towards the closest axis or diagonal axis, at y=120\n" +
"cancel - Cancels current path\n" +
"forcecancel - sudo cancel (only use if very glitched, try toggling 'pause' first)\n" +
"gc - Calls System.gc();\n" +
"invert - Runs away from the goal instead of towards it\n" +
"follow - Follows a player 'follow username'\n" +
"reloadall - (debug) Reloads chunk cache\n" +
"saveall - (debug) Saves chunk cache\n" +
"find - (debug) outputs how many blocks of a certain type are within the cache\n" +
"mine - Paths to and mines specified blocks 'mine x_ore y_ore ...'\n" +
"thisway - Creates a goal X blocks where you're facing\n" +
"list - Lists waypoints under a category\n" +
"get - Same as list\n" +
"show - Same as list\n" +
"save - Saves a waypoint (works but don't try to make sense of it)\n" +
"delete - Deletes a waypoint\n" +
"goto - Paths towards specified block or waypoint\n" +
"spawn - Paths towards world spawn or your most recent bed right-click\n" +
"sethome - Sets \"home\"\n" +
"home - Paths towards \"home\" \n" +
"costs - (debug) all movement costs from current location\n" +
"damn - Daniel\n" +
"Go to https://github.com/cabaletta/baritone/blob/master/USAGE.md for more information";
private static final String COMMAND_PREFIX = "#";
public final IBaritone baritone;
public final IPlayerContext ctx;
public ExampleBaritoneControl(IBaritone baritone) {
this.baritone = baritone;
this.ctx = baritone.getPlayerContext();
baritone.getGameEventHandler().registerEventListener(this);
}
@Override
public void onSendChatMessage(ChatEvent event) {
String msg = event.getMessage();
if (BaritoneAPI.getSettings().prefixControl.value && msg.startsWith(COMMAND_PREFIX)) {
if (!runCommand(msg.substring(COMMAND_PREFIX.length()))) {
logDirect("Invalid command");
}
event.cancel(); // always cancel if using prefixControl
return;
}
if (!BaritoneAPI.getSettings().chatControl.value && !BaritoneAPI.getSettings().removePrefix.value) {
return;
}
if (runCommand(msg)) {
event.cancel();
}
}
public boolean runCommand(String msg0) { // you may think this can be private, but impcat calls it from .b =)
String msg = msg0.toLowerCase(Locale.US).trim(); // don't reassign the argument LOL
IPathingBehavior pathingBehavior = baritone.getPathingBehavior();
ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
List<Settings.Setting<Boolean>> toggleable = BaritoneAPI.getSettings().getAllValuesByType(Boolean.class);
for (Settings.Setting<Boolean> setting : toggleable) {
if (msg.equalsIgnoreCase(setting.getName())) {
setting.value ^= true;
logDirect("Toggled " + setting.getName() + " to " + setting.value);
SettingsUtil.save(BaritoneAPI.getSettings());
return true;
}
}
if (msg.equals("baritone") || msg.equals("modifiedsettings") || msg.startsWith("settings m") || msg.equals("modified")) {
logDirect("All settings that have been modified from their default values:");
for (Settings.Setting<?> setting : SettingsUtil.modifiedSettings(BaritoneAPI.getSettings())) {
logDirect(setting.toString());
}
return true;
}
if (msg.startsWith("settings")) {
String rest = msg.substring("settings".length());
try {
int page = Integer.parseInt(rest.trim());
int min = page * 10;
int max = Math.min(BaritoneAPI.getSettings().allSettings.size(), (page + 1) * 10);
logDirect("Settings " + min + " to " + (max - 1) + ":");
for (int i = min; i < max; i++) {
logDirect(BaritoneAPI.getSettings().allSettings.get(i).toString());
}
} catch (Exception ex) { // NumberFormatException | ArrayIndexOutOfBoundsException and probably some others I'm forgetting lol
ex.printStackTrace();
logDirect("All settings:");
for (Settings.Setting<?> setting : BaritoneAPI.getSettings().allSettings) {
logDirect(setting.toString());
}
logDirect("To get one page of ten settings at a time, do settings <num>");
}
return true;
}
if (msg.equals("") || msg.equals("help") || msg.equals("?")) {
for (String line : HELP_MSG.split("\n")) {
logDirect(line);
}
return true;
}
if (msg.contains(" ")) {
String settingName = msg.substring(0, msg.indexOf(' '));
String settingValue = msg.substring(msg.indexOf(' ') + 1);
Settings.Setting setting = BaritoneAPI.getSettings().byLowerName.get(settingName);
if (setting != null) {
if (settingValue.equals("reset")) {
logDirect("Resetting setting " + settingName + " to default value.");
setting.reset();
} else {
try {
SettingsUtil.parseAndApply(BaritoneAPI.getSettings(), settingName, settingValue);
} catch (Exception ex) {
logDirect("Unable to parse setting");
return true;
}
}
SettingsUtil.save(BaritoneAPI.getSettings());
logDirect(setting.toString());
return true;
}
}
if (BaritoneAPI.getSettings().byLowerName.containsKey(msg)) {
Settings.Setting<?> setting = BaritoneAPI.getSettings().byLowerName.get(msg);
logDirect(setting.toString());
return true;
}
if (msg.startsWith("goal")) {
String rest = msg.substring(4).trim();
Goal goal;
if (rest.equals("clear") || rest.equals("none")) {
goal = null;
} else {
String[] params = rest.split(" ");
if (params[0].equals("")) {
params = new String[]{};
}
goal = parseGoal(params);
if (goal == null) {
return true;
}
}
customGoalProcess.setGoal(goal);
logDirect("Goal: " + goal);
return true;
}
if (msg.equals("crash")) {
StringBuilder meme = new StringBuilder();
CrashReport rep = new CrashReport("Manually triggered debug crash", new Throwable());
mc.addGraphicsAndWorldToCrashReport(rep);
new ReportedException(rep).printStackTrace();
rep.getSectionsInStringBuilder(meme);
System.out.println(meme);
logDirect(meme.toString());
logDirect("ok");
return true;
}
if (msg.equals("path")) {
if (pathingBehavior.getGoal() == null) {
logDirect("No goal.");
} else if (pathingBehavior.getGoal().isInGoal(ctx.playerFeet())) {
logDirect("Already in goal");
} else if (pathingBehavior.isPathing()) {
logDirect("Currently executing a path. Please cancel it first.");
} else {
customGoalProcess.setGoalAndPath(pathingBehavior.getGoal());
}
return true;
}
/*if (msg.equals("fullpath")) {
if (pathingBehavior.getGoal() == null) {
logDirect("No goal.");
} else {
logDirect("Started segmented calculator");
SegmentedCalculator.calculateSegmentsThreaded(pathingBehavior.pathStart(), pathingBehavior.getGoal(), new CalculationContext(baritone, true), ipath -> {
logDirect("Found a path");
logDirect("Ends at " + ipath.getDest());
logDirect("Length " + ipath.length());
logDirect("Estimated time " + ipath.ticksRemainingFrom(0));
pathingBehavior.secretCursedFunctionDoNotCall(ipath); // it's okay when *I* do it
}, () -> {
logDirect("Path calculation failed, no path");
});
}
return true;
}*/
if (msg.equals("proc")) {
Optional<IBaritoneProcess> proc = baritone.getPathingControlManager().mostRecentInControl();
if (!proc.isPresent()) {
logDirect("No process is in control");
return true;
}
IBaritoneProcess p = proc.get();
logDirect("Class: " + p.getClass());
logDirect("Priority: " + p.priority());
logDirect("Temporary: " + p.isTemporary());
logDirect("Display name: " + p.displayName());
logDirect("Command: " + baritone.getPathingControlManager().mostRecentCommand());
return true;
}
if (msg.equals("version")) {
String version = ExampleBaritoneControl.class.getPackage().getImplementationVersion();
if (version == null) {
logDirect("No version detected. Either dev environment or broken install.");
} else {
logDirect("You are using Baritone v" + version);
}
return true;
}
if (msg.equals("repack") || msg.equals("rescan")) {
ChunkProviderClient cli = (ChunkProviderClient) ctx.world().getChunkProvider();
int playerChunkX = ctx.playerFeet().getX() >> 4;
int playerChunkZ = ctx.playerFeet().getZ() >> 4;
int count = 0;
for (int x = playerChunkX - 40; x <= playerChunkX + 40; x++) {
for (int z = playerChunkZ - 40; z <= playerChunkZ + 40; z++) {
Chunk chunk = cli.getLoadedChunk(x, z);
if (chunk != null) {
count++;
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().queueForPacking(chunk);
}
}
}
logDirect("Queued " + count + " chunks for repacking");
return true;
}
if (msg.startsWith("build")) {
String file;
BlockPos origin;
try {
String[] coords = msg.substring("build".length()).trim().split(" ");
file = coords[0] + ".schematic";
origin = new BlockPos(parseOrDefault(coords[1], ctx.playerFeet().x), parseOrDefault(coords[2], ctx.playerFeet().y), parseOrDefault(coords[3], ctx.playerFeet().z));
} catch (Exception ex) {
file = msg.substring(5).trim() + ".schematic";
origin = ctx.playerFeet();
}
logDirect("Loading '" + file + "' to build from origin " + origin);
boolean success = baritone.getBuilderProcess().build(file, origin);
logDirect(success ? "Loaded" : "Unable to load");
return true;
}
if (msg.equals("come")) {
customGoalProcess.setGoalAndPath(new GoalBlock(new BlockPos(Helper.mc.getRenderViewEntity())));
logDirect("Coming");
return true;
}
if (msg.equals("axis") || msg.equals("highway")) {
customGoalProcess.setGoalAndPath(new GoalAxis());
return true;
}
if (msg.equals("cancel") || msg.equals("stop")) {
pathingBehavior.cancelEverything();
logDirect("ok canceled");
return true;
}
if (msg.equals("forcecancel")) {
pathingBehavior.cancelEverything();
pathingBehavior.forceCancel();
logDirect("ok force canceled");
return true;
}
if (msg.equals("gc")) {
System.gc();
logDirect("Called System.gc();");
return true;
}
if (msg.equals("invert")) {
Goal goal = pathingBehavior.getGoal();
BlockPos runAwayFrom;
if (goal instanceof GoalXZ) {
runAwayFrom = new BlockPos(((GoalXZ) goal).getX(), 0, ((GoalXZ) goal).getZ());
} else if (goal instanceof GoalBlock) {
runAwayFrom = ((GoalBlock) goal).getGoalPos();
} else {
logDirect("Goal must be GoalXZ or GoalBlock to invert");
logDirect("Inverting goal of player feet");
runAwayFrom = ctx.playerFeet();
}
customGoalProcess.setGoalAndPath(new GoalRunAway(1, runAwayFrom) {
@Override
public boolean isInGoal(int x, int y, int z) {
return false;
}
});
return true;
}
if (msg.startsWith("cleararea")) {
String suffix = msg.substring("cleararea".length());
BlockPos corner1;
BlockPos corner2;
if (suffix.isEmpty()) {
// clear the area from the current goal to here
Goal goal = baritone.getPathingBehavior().getGoal();
if (!(goal instanceof GoalBlock)) {
logDirect("Need to specify goal of opposite corner");
return true;
}
corner1 = ((GoalBlock) goal).getGoalPos();
corner2 = ctx.playerFeet();
} else {
try {
String[] spl = suffix.split(" ");
corner1 = ctx.playerFeet();
corner2 = new BlockPos(Integer.parseInt(spl[0]), Integer.parseInt(spl[1]), Integer.parseInt(spl[2]));
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {
logDirect("unable to parse");
return true;
}
}
baritone.getBuilderProcess().clearArea(corner1, corner2);
return true;
}
if (msg.equals("resume")) {
baritone.getBuilderProcess().resume();
logDirect("resumed");
return true;
}
if (msg.equals("pause")) {
baritone.getBuilderProcess().pause();
logDirect("paused");
return true;
}
if (msg.equals("reset")) {
for (Settings.Setting setting : BaritoneAPI.getSettings().allSettings) {
setting.reset();
}
SettingsUtil.save(BaritoneAPI.getSettings());
logDirect("Baritone settings reset");
return true;
}
if (msg.equals("tunnel")) {
customGoalProcess.setGoalAndPath(new GoalStrictDirection(ctx.playerFeet(), ctx.player().getHorizontalFacing()));
logDirect("tunneling");
return true;
}
if (msg.equals("render")) {
BetterBlockPos pf = ctx.playerFeet();
Minecraft.getMinecraft().renderGlobal.markBlockRangeForRenderUpdate(pf.x - 500, pf.y - 500, pf.z - 500, pf.x + 500, pf.y + 500, pf.z + 500);
logDirect("okay");
return true;
}
if (msg.equals("farm")) {
baritone.getFarmProcess().farm();
logDirect("farming");
return true;
}
if (msg.equals("chests")) {
for (Map.Entry<BlockPos, IRememberedInventory> entry : baritone.getWorldProvider().getCurrentWorld().getContainerMemory().getRememberedInventories().entrySet()) {
logDirect(entry.getKey() + "");
log(entry.getValue().getContents());
}
return true;
}
if (msg.startsWith("followplayers")) {
baritone.getFollowProcess().follow(EntityPlayer.class::isInstance); // O P P A
logDirect("Following any players");
return true;
}
if (msg.startsWith("follow")) {
String name = msg.substring(6).trim();
Optional<Entity> toFollow = Optional.empty();
if (name.length() == 0) {
toFollow = ctx.getSelectedEntity();
} else {
for (EntityPlayer pl : ctx.world().playerEntities) {
String theirName = pl.getName().trim().toLowerCase();
if (!theirName.equals(ctx.player().getName().trim().toLowerCase()) && (theirName.contains(name) || name.contains(theirName))) { // don't follow ourselves lol
toFollow = Optional.of(pl);
}
}
}
if (!toFollow.isPresent()) {
logDirect("Not found");
return true;
}
Entity effectivelyFinal = toFollow.get();
baritone.getFollowProcess().follow(effectivelyFinal::equals);
logDirect("Following " + toFollow.get());
return true;
}
if (msg.startsWith("explorefilter")) {
// explorefilter blah.json
// means that entries in blah.json are already explored
// explorefilter blah.json invert
// means that entries in blah.json are NOT already explored
String path = msg.substring("explorefilter".length()).trim();
String[] parts = path.split(" ");
Path path1 = Minecraft.getMinecraft().gameDir.toPath().resolve(parts[0]);
boolean invert = parts.length > 1;
try {
baritone.getExploreProcess().applyJsonFilter(path1, invert);
logDirect("Loaded filter. Inverted: " + invert);
if (invert) {
logDirect("Chunks on this list will be treated as possibly unexplored, all others will be treated as certainly explored");
} else {
logDirect("Chunks on this list will be treated as certainly explored, all others will be treated as possibly unexplored");
}
} catch (Exception e) {
e.printStackTrace();
logDirect("Unable to load " + path1);
}
return true;
}
if (msg.equals("reloadall")) {
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().reloadAllFromDisk();
logDirect("ok");
return true;
}
if (msg.equals("saveall")) {
baritone.getWorldProvider().getCurrentWorld().getCachedWorld().save();
logDirect("ok");
return true;
}
if (msg.startsWith("explore")) {
String rest = msg.substring("explore".length()).trim();
int centerX;
int centerZ;
try {
centerX = Integer.parseInt(rest.split(" ")[0]);
centerZ = Integer.parseInt(rest.split(" ")[1]);
} catch (Exception ex) {
centerX = ctx.playerFeet().x;
centerZ = ctx.playerFeet().z;
}
baritone.getExploreProcess().explore(centerX, centerZ);
logDirect("Exploring from " + centerX + "," + centerZ);
return true;
}
if (msg.equals("blacklist")) {
IGetToBlockProcess proc = baritone.getGetToBlockProcess();
if (!proc.isActive()) {
logDirect("GetToBlockProcess is not currently active");
return true;
}
if (proc.blacklistClosest()) {
logDirect("Blacklisted closest instances");
} else {
logDirect("No known locations, unable to blacklist");
}
return true;
}
if (msg.startsWith("find")) {
String blockType = msg.substring(4).trim();
ArrayList<BlockPos> locs = baritone.getWorldProvider().getCurrentWorld().getCachedWorld().getLocationsOf(blockType, 1, ctx.playerFeet().getX(), ctx.playerFeet().getZ(), 4);
logDirect("Have " + locs.size() + " locations");
for (BlockPos pos : locs) {
Block actually = ctx.world().getBlockState(pos).getBlock();
if (!BlockUtils.blockToString(actually).equalsIgnoreCase(blockType)) {
logDebug("Was looking for " + blockType + " but actually found " + actually + " " + BlockUtils.blockToString(actually));
}
}
return true;
}
if (msg.startsWith("mine")) {
String[] blockTypes = msg.substring(4).trim().split(" ");
try {
int quantity = Integer.parseInt(blockTypes[1]);
Block block = BlockUtils.stringToBlockRequired(blockTypes[0]);
baritone.getMineProcess().mine(quantity, block);
logDirect("Will mine " + quantity + " " + blockTypes[0]);
return true;
} catch (NumberFormatException | ArrayIndexOutOfBoundsException | NullPointerException ex) {}
for (String s : blockTypes) {
if (BlockUtils.stringToBlockNullable(s) == null) {
logDirect(s + " isn't a valid block name");
return true;
}
}
baritone.getMineProcess().mineByName(0, blockTypes);
logDirect("Started mining blocks of type " + Arrays.toString(blockTypes));
return true;
}
if (msg.equals("click")) {
baritone.openClick();
logDirect("aight dude");
return true;
}
if (msg.startsWith("thisway") || msg.startsWith("forward")) {
try {
Goal goal = GoalXZ.fromDirection(ctx.playerFeetAsVec(), ctx.player().rotationYaw, Double.parseDouble(msg.substring(7).trim()));
customGoalProcess.setGoal(goal);
logDirect("Goal: " + goal);
} catch (NumberFormatException ex) {
logDirect("Error unable to parse '" + msg.substring(7).trim() + "' to a double.");
}
return true;
}
if (msg.startsWith("list") || msg.startsWith("get ") || msg.startsWith("show")) {
String waypointType = msg.substring(4).trim();
if (waypointType.endsWith("s")) {
// for example, "show deaths"
waypointType = waypointType.substring(0, waypointType.length() - 1);
}
IWaypoint.Tag tag = IWaypoint.Tag.fromString(waypointType);
if (tag == null) {
logDirect("Not a valid tag. Tags are: " + Arrays.asList(IWaypoint.Tag.values()).toString().toLowerCase());
return true;
}
Set<IWaypoint> waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(tag);
// might as well show them from oldest to newest
List<IWaypoint> sorted = new ArrayList<>(waypoints);
sorted.sort(Comparator.comparingLong(IWaypoint::getCreationTimestamp));
logDirect("Waypoints under tag " + tag + ":");
for (IWaypoint waypoint : sorted) {
logDirect(waypoint.toString());
}
return true;
}
if (msg.startsWith("save")) {
String name = msg.substring(4).trim();
BlockPos pos = ctx.playerFeet();
if (name.contains(" ")) {
logDirect("Name contains a space, assuming it's in the format 'save waypointName X Y Z'");
String[] parts = name.split(" ");
if (parts.length != 4) {
logDirect("Unable to parse, expected four things");
return true;
}
try {
pos = new BlockPos(Integer.parseInt(parts[1]), Integer.parseInt(parts[2]), Integer.parseInt(parts[3]));
} catch (NumberFormatException ex) {
logDirect("Unable to parse coordinate integers");
return true;
}
name = parts[0];
}
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint(name, IWaypoint.Tag.USER, pos));
logDirect("Saved user defined position " + pos + " under name '" + name + "'. Say 'goto " + name + "' to set goal, say 'list user' to list custom waypoints.");
return true;
}
if (msg.startsWith("delete")) {
String name = msg.substring(6).trim();
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getTag() == IWaypoint.Tag.USER && w.getName().equalsIgnoreCase(name)).findFirst().orElse(null);
if (waypoint == null) {
logDirect("No user defined position under the name '" + name + "' found.");
return true;
}
baritone.getWorldProvider().getCurrentWorld().getWaypoints().removeWaypoint(waypoint);
logDirect("Deleted user defined position under name '" + name + "'.");
return true;
}
if (msg.startsWith("goto")) {
String waypointType = msg.substring(4).trim();
if (waypointType.endsWith("s") && IWaypoint.Tag.fromString(waypointType.substring(0, waypointType.length() - 1)) != null) {
// for example, "show deaths"
waypointType = waypointType.substring(0, waypointType.length() - 1);
}
IWaypoint.Tag tag = IWaypoint.Tag.fromString(waypointType);
IWaypoint waypoint;
if (tag == null) {
String mining = waypointType;
Block block = BlockUtils.stringToBlockNullable(mining);
//logDirect("Not a valid tag. Tags are: " + Arrays.asList(Waypoint.Tag.values()).toString().toLowerCase());
if (block == null) {
waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getAllWaypoints().stream().filter(w -> w.getName().equalsIgnoreCase(mining)).max(Comparator.comparingLong(IWaypoint::getCreationTimestamp)).orElse(null);
if (waypoint == null) {
Goal goal = parseGoal(waypointType.split(" "));
if (goal != null) {
logDirect("Going to " + goal);
customGoalProcess.setGoalAndPath(goal);
}
return true;
}
} else {
baritone.getGetToBlockProcess().getToBlock(block);
return true;
}
} else {
waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(tag);
if (waypoint == null) {
logDirect("None saved for tag " + tag);
return true;
}
}
Goal goal = waypoint.getTag() == IWaypoint.Tag.BED ? new GoalGetToBlock(waypoint.getLocation()) : new GoalBlock(waypoint.getLocation());
customGoalProcess.setGoalAndPath(goal);
return true;
}
if (msg.equals("spawn") || msg.equals("bed")) {
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(IWaypoint.Tag.BED);
if (waypoint == null) {
BlockPos spawnPoint = ctx.player().getBedLocation();
// for some reason the default spawnpoint is underground sometimes
Goal goal = new GoalXZ(spawnPoint.getX(), spawnPoint.getZ());
logDirect("spawn not saved, defaulting to world spawn. set goal to " + goal);
customGoalProcess.setGoalAndPath(goal);
} else {
Goal goal = new GoalGetToBlock(waypoint.getLocation());
customGoalProcess.setGoalAndPath(goal);
logDirect("Set goal to most recent bed " + goal);
}
return true;
}
if (msg.equals("sethome")) {
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("", IWaypoint.Tag.HOME, ctx.playerFeet()));
logDirect("Saved. Say home to set goal.");
return true;
}
if (msg.equals("home")) {
IWaypoint waypoint = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getMostRecentByTag(IWaypoint.Tag.HOME);
if (waypoint == null) {
logDirect("home not saved");
} else {
Goal goal = new GoalBlock(waypoint.getLocation());
customGoalProcess.setGoalAndPath(goal);
logDirect("Going to saved home " + goal);
}
return true;
}
if (msg.equals("damn")) {
logDirect("daniel");
}
return false;
}
private int parseOrDefault(String str, int i) {
return str.equals("~") ? i : str.startsWith("~") ? Integer.parseInt(str.substring(1)) + i : Integer.parseInt(str);
}
private void log(List<ItemStack> stacks) {
for (ItemStack stack : stacks) {
if (!stack.isEmpty()) {
logDirect(stack.getCount() + "x " + stack.getDisplayName() + "@" + stack.getItemDamage());
}
}
}
private Goal parseGoal(String[] params) {
Goal goal;
try {
BetterBlockPos playerFeet = ctx.playerFeet();
switch (params.length) {
case 0:
goal = new GoalBlock(playerFeet);
break;
case 1:
goal = new GoalYLevel(parseOrDefault(params[0], playerFeet.y));
break;
case 2:
goal = new GoalXZ(parseOrDefault(params[0], playerFeet.x), parseOrDefault(params[1], playerFeet.z));
break;
case 3:
goal = new GoalBlock(new BlockPos(parseOrDefault(params[0], playerFeet.x), parseOrDefault(params[1], playerFeet.y), parseOrDefault(params[2], playerFeet.z)));
break;
default:
logDirect("unable to understand lol");
return null;
}
} catch (NumberFormatException ex) {
logDirect("unable to parse integer " + ex);
return null;
}
return goal;
}
}

View File

@@ -19,6 +19,7 @@ package baritone.api.utils;
import baritone.api.behavior.IBehavior;
import baritone.api.utils.input.Input;
import net.minecraft.client.settings.KeyBinding;
/**
* @author Brady
@@ -26,6 +27,10 @@ import baritone.api.utils.input.Input;
*/
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);

View File

@@ -20,6 +20,7 @@ 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;
@@ -36,7 +37,7 @@ public interface IPlayerContext {
EntityPlayerSP player();
IPlayerController playerController();
PlayerControllerMP playerController();
World world();
@@ -71,26 +72,20 @@ public interface IPlayerContext {
* @return The position of the highlighted block
*/
default Optional<BlockPos> getSelectedBlock() {
RayTraceResult result = objectMouseOver();
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(result.getBlockPos());
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(objectMouseOver().getBlockPos());
}
return Optional.empty();
}
default boolean isLookingAt(BlockPos pos) {
return getSelectedBlock().equals(Optional.of(pos));
}
/**
* Returns the entity that the crosshair is currently placed over. Updated once per tick.
*
* @return The entity
*/
default Optional<Entity> getSelectedEntity() {
RayTraceResult result = objectMouseOver();
if (result != null && result.typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(result.entityHit);
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(objectMouseOver().entityHit);
}
return Optional.empty();
}

View File

@@ -1,55 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ClickType;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameType;
import net.minecraft.world.World;
/**
* @author Brady
* @since 12/14/2018
*/
public interface IPlayerController {
boolean onPlayerDamageBlock(BlockPos pos, EnumFacing side);
void resetBlockRemoving();
ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player);
void setGameType(GameType type);
GameType getGameType();
default double getBlockReachDistance() {
return this.getGameType().isCreative() ? 5.0F : 4.5F;
}
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);
EnumActionResult processRightClick(EntityPlayerSP player, World world, EnumHand hand);
}

View File

@@ -1,85 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
/**
* Basic representation of a schematic. Provides the dimensions and
* the desired statefor a given position relative to the origin.
*
* @author leijurv
*/
public interface ISchematic {
/**
* Does the block at this coordinate matter to the schematic?
* <p>
* Normally just a check for if the coordinate is in the cube.
* <p>
* However, in the case of something like a map art, anything that's below the level of the map art doesn't matter,
* so this function should return false in that case. (i.e. it doesn't really have to be air below the art blocks)
*
* @param x The x position of the block, relative to the origin
* @param y The y position of the block, relative to the origin
* @param z The z position of the block, relative to the origin
* @return Whether or not the specified position is within the bounds of this schematic
*/
default boolean inSchematic(int x, int y, int z) {
return x >= 0 && x < widthX() && y >= 0 && y < heightY() && z >= 0 && z < lengthZ();
}
default int size(EnumFacing.Axis axis) {
switch (axis) {
case X:
return widthX();
case Y:
return heightY();
case Z:
return lengthZ();
default:
throw new UnsupportedOperationException(axis + "");
}
}
/**
* Returns the desired block state at a given (X, Y, Z) position relative to the origin (0, 0, 0).
*
* @param x The x position of the block, relative to the origin
* @param y The y position of the block, relative to the origin
* @param z The z position of the block, relative to the origin
* @return The desired block state at the specified position
*/
IBlockState desiredState(int x, int y, int z);
/**
* @return The width (X axis length) of this schematic
*/
int widthX();
/**
* @return The height (Y axis length) of this schematic
*/
int heightY();
/**
* @return The length (Z axis length) of this schematic
*/
int lengthZ();
}

View File

@@ -15,8 +15,13 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.process;
package baritone.api.utils;
/**
* @author Brady
* @since 9/23/2018
*/
public class Logger {
public interface IFarmProcess extends IBaritoneProcess {
void farm();
}

View File

@@ -19,7 +19,6 @@ package baritone.api.utils;
import baritone.api.pathing.calc.IPath;
import java.util.Objects;
import java.util.Optional;
public class PathCalculationResult {
@@ -32,9 +31,11 @@ public class PathCalculationResult {
}
public PathCalculationResult(Type type, IPath path) {
Objects.requireNonNull(type);
this.path = path;
this.type = type;
if (type == null) {
throw new IllegalArgumentException("come on");
}
}
public final Optional<IPath> getPath() {

View File

@@ -34,9 +34,7 @@ public final class RayTraceUtils {
* 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
* @param rotation The rotation to raytrace towards
* @return The calculated raytrace result
*/
public static RayTraceResult rayTraceTowards(Entity entity, Rotation rotation, double blockReachDistance) {

View File

@@ -110,21 +110,6 @@ public class Rotation {
);
}
/**
* Is really close to
*
* @param other another rotation
* @return are they really close
*/
public boolean isReallyCloseTo(Rotation other) {
return yawIsReallyClose(other) && Math.abs(this.pitch - other.pitch) < 0.01;
}
public boolean yawIsReallyClose(Rotation other) {
float yawDiff = Math.abs(normalizeYaw(yaw) - normalizeYaw(other.yaw)); // you cant fool me
return (yawDiff < 0.01 || yawDiff > 359.99);
}
/**
* Clamps the specified pitch value between -90 and 90.
*
@@ -146,14 +131,9 @@ public class Rotation {
if (newYaw < -180F) {
newYaw += 360F;
}
if (newYaw > 180F) {
if (newYaw >= 180F) {
newYaw -= 360F;
}
return newYaw;
}
@Override
public String toString() {
return "Yaw: " + yaw + ", Pitch: " + pitch;
}
}

View File

@@ -78,9 +78,6 @@ public final class RotationUtils {
* @return The wrapped angles
*/
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
if (current.yawIsReallyClose(target)) {
return new Rotation(current.getYaw(), target.getPitch());
}
return target.subtract(current).normalize().add(current);
}
@@ -105,7 +102,7 @@ public final class RotationUtils {
* @param dest The destination position
* @return The rotation from the origin to the destination
*/
private static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
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]);
@@ -130,16 +127,6 @@ public final class RotationUtils {
return new Vec3d((double) (f1 * f2), (double) f3, (double) (f * f2));
}
/**
* @param ctx Context for the viewing entity
* @param pos The target block position
* @return The optional rotation
* @see #reachable(EntityPlayerSP, BlockPos, double)
*/
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos) {
return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
}
/**
* 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,
@@ -147,14 +134,13 @@ public final class RotationUtils {
* side that is reachable. The return type will be {@link Optional#empty()} if the entity is
* unable to reach any of the sides of the block.
*
* @param entity The viewing entity
* @param pos The target block position
* @param blockReachDistance The block reach distance of the entity
* @param entity The viewing entity
* @param pos The target block position
* @return The optional rotation
*/
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
if (baritone.getPlayerContext().isLookingAt(pos)) {
if (pos.equals(baritone.getPlayerContext().getSelectedBlock().orElse(null))) {
/*
* why add 0.0001?
* to indicate that we actually have a desired pitch
@@ -192,14 +178,13 @@ public final class RotationUtils {
* the given offsetted position. The return type will be {@link Optional#empty()} if
* the entity is unable to reach the block with the offset applied.
*
* @param entity The viewing entity
* @param 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
* @param entity The viewing entity
* @param pos The target block position
* @param offsetPos The position of the block with the offset applied.
* @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, new Rotation(entity.rotationYaw, entity.rotationPitch));
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) {
@@ -217,9 +202,8 @@ public final class RotationUtils {
* Determines if the specified entity is able to reach the specified block where it is
* looking at the direct center of it's hitbox.
*
* @param entity The viewing entity
* @param pos The target block position
* @param blockReachDistance The block reach distance of the entity
* @param entity The viewing entity
* @param pos The target block position
* @return The optional rotation
*/
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos, double blockReachDistance) {

View File

@@ -18,251 +18,124 @@
package baritone.api.utils;
import baritone.api.Settings;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.Vec3i;
import net.minecraft.util.ResourceLocation;
import java.awt.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.io.File;
import java.io.FileOutputStream;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static net.minecraft.client.Minecraft.getMinecraft;
import java.util.stream.Stream;
public class SettingsUtil {
private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt");
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
private static final File settingsFile = new File(new File(Minecraft.getMinecraft().gameDir, "baritone"), "settings.txt");
private static boolean isComment(String line) {
return line.startsWith("#") || line.startsWith("//");
}
private static void forEachLine(Path file, Consumer<String> consumer) throws IOException {
try (BufferedReader scan = Files.newBufferedReader(file)) {
String line;
while ((line = scan.readLine()) != null) {
if (line.isEmpty() || isComment(line)) {
continue;
}
consumer.accept(line);
}
}
}
private static final Map<Class<?>, SettingsIO> map;
public static void readAndApply(Settings settings) {
try {
forEachLine(SETTINGS_PATH, line -> {
Matcher matcher = SETTING_PATTERN.matcher(line);
if (!matcher.matches()) {
System.out.println("Invalid syntax in setting file: " + line);
return;
try (Scanner scan = new Scanner(settingsFile)) {
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line.isEmpty()) {
continue;
}
String settingName = matcher.group("setting").toLowerCase();
String settingValue = matcher.group("value");
if (line.startsWith("#") || line.startsWith("//")) {
continue;
}
int space = line.indexOf(" ");
if (space == -1) {
System.out.println("Skipping invalid line with no space: " + line);
continue;
}
String settingName = line.substring(0, space).trim().toLowerCase();
String settingValue = line.substring(space).trim();
try {
parseAndApply(settings, settingName, settingValue);
} catch (Exception ex) {
System.out.println("Unable to parse line " + line);
ex.printStackTrace();
System.out.println("Unable to parse line " + line);
}
});
} catch (NoSuchFileException ignored) {
System.out.println("Baritone settings file not found, resetting.");
}
} catch (Exception ex) {
System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!");
ex.printStackTrace();
System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!");
}
}
public static synchronized void save(Settings settings) {
try (BufferedWriter out = Files.newBufferedWriter(SETTINGS_PATH)) {
for (Settings.Setting setting : modifiedSettings(settings)) {
out.write(settingToString(setting) + "\n");
try (FileOutputStream out = new FileOutputStream(settingsFile)) {
for (Settings.Setting setting : settings.allSettings) {
if (setting.get() == null) {
System.out.println("NULL SETTING?" + setting.getName());
continue;
}
if (setting.getName().equals("logger")) {
continue; // NO
}
if (setting.value == setting.defaultValue) {
continue;
}
SettingsIO io = map.get(setting.getValueClass());
if (io == null) {
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting + " " + setting.getName());
}
out.write((setting.getName() + " " + io.toString.apply(setting.get()) + "\n").getBytes());
}
} catch (Exception ex) {
System.out.println("Exception thrown while saving Baritone settings!");
ex.printStackTrace();
System.out.println("Exception while saving Baritone settings!");
}
}
public static List<Settings.Setting> modifiedSettings(Settings settings) {
List<Settings.Setting> modified = new ArrayList<>();
for (Settings.Setting setting : settings.allSettings) {
if (setting.value == null) {
System.out.println("NULL SETTING?" + setting.getName());
continue;
}
if (setting.getName().equals("logger")) {
continue; // NO
}
if (setting.value == setting.defaultValue) {
continue;
}
modified.add(setting);
}
return modified;
}
public static String settingToString(Settings.Setting setting) throws IllegalStateException {
if (setting.getName().equals("logger")) {
return "logger";
}
Parser io = Parser.getParser(setting.getType());
if (io == null) {
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting.getName());
}
return setting.getName() + " " + io.toString(new ParserContext(setting), setting.value);
}
public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
private static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
Settings.Setting setting = settings.byLowerName.get(settingName);
if (setting == null) {
throw new IllegalStateException("No setting by that name");
}
Class intendedType = setting.getValueClass();
ISettingParser ioMethod = Parser.getParser(setting.getType());
Object parsed = ioMethod.parse(new ParserContext(setting), settingValue);
SettingsIO ioMethod = map.get(intendedType);
Object parsed = ioMethod.parser.apply(settingValue);
if (!intendedType.isInstance(parsed)) {
throw new IllegalStateException(ioMethod + " parser returned incorrect type, expected " + intendedType + " got " + parsed + " which is " + parsed.getClass());
}
setting.value = parsed;
}
private interface ISettingParser<T> {
T parse(ParserContext context, String raw);
String toString(ParserContext context, T value);
boolean accepts(Type type);
}
private static class ParserContext {
private final Settings.Setting<?> setting;
private ParserContext(Settings.Setting<?> setting) {
this.setting = setting;
}
private Settings.Setting<?> getSetting() {
return this.setting;
}
}
private enum Parser implements ISettingParser {
private enum SettingsIO {
DOUBLE(Double.class, Double::parseDouble),
BOOLEAN(Boolean.class, Boolean::parseBoolean),
INTEGER(Integer.class, Integer::parseInt),
FLOAT(Float.class, Float::parseFloat),
LONG(Long.class, Long::parseLong),
ENUMFACING(EnumFacing.class, EnumFacing::byName),
COLOR(
Color.class,
str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])),
color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue()
),
VEC3I(
Vec3i.class,
str -> new Vec3i(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])),
vec -> vec.getX() + "," + vec.getY() + "," + vec.getZ()
),
BLOCK(
Block.class,
str -> BlockUtils.stringToBlockRequired(str.trim()),
BlockUtils::blockToString
),
ITEM(
Item.class,
str -> Item.getByNameOrId(str.trim()),
item -> Item.REGISTRY.getNameForObject(item).toString()
),
LIST() {
@Override
public Object parse(ParserContext context, String raw) {
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
Parser parser = Parser.getParser(type);
return Arrays.stream(raw.split(","))
.map(s -> parser.parse(context, s))
.collect(Collectors.toList());
}
ITEM_LIST(ArrayList.class, str -> Stream.of(str.split(",")).map(Item::getByNameOrId).collect(Collectors.toCollection(ArrayList::new)), list -> ((ArrayList<Item>) list).stream().map(Item.REGISTRY::getNameForObject).map(ResourceLocation::toString).collect(Collectors.joining(","))),
COLOR(Color.class, str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])), color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue());
@Override
public String toString(ParserContext context, Object value) {
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
Parser parser = Parser.getParser(type);
return ((List<?>) value).stream()
.map(o -> parser.toString(context, o))
.collect(Collectors.joining(","));
}
Class<?> klass;
Function<String, Object> parser;
Function<Object, String> toString;
@Override
public boolean accepts(Type type) {
return List.class.isAssignableFrom(TypeUtils.resolveBaseClass(type));
}
};
private final Class<?> klass;
private final Function<String, Object> parser;
private final Function<Object, String> toString;
Parser() {
this.klass = null;
this.parser = null;
this.toString = null;
}
<T> Parser(Class<T> klass, Function<String, T> parser) {
<T> SettingsIO(Class<T> klass, Function<String, T> parser) {
this(klass, parser, Object::toString);
}
<T> Parser(Class<T> klass, Function<String, T> parser, Function<T, String> toString) {
<T> SettingsIO(Class<T> klass, Function<String, T> parser, Function<T, String> toString) {
this.klass = klass;
this.parser = parser::apply;
this.toString = x -> toString.apply((T) x);
}
}
@Override
public Object parse(ParserContext context, String raw) {
Object parsed = this.parser.apply(raw);
Objects.requireNonNull(parsed);
return parsed;
}
@Override
public String toString(ParserContext context, Object value) {
return this.toString.apply(value);
}
@Override
public boolean accepts(Type type) {
return type instanceof Class && this.klass.isAssignableFrom((Class) type);
}
public static Parser getParser(Type type) {
return Arrays.stream(values())
.filter(parser -> parser.accepts(type))
.findFirst().orElse(null);
static {
HashMap<Class<?>, SettingsIO> tempMap = new HashMap<>();
for (SettingsIO type : SettingsIO.values()) {
tempMap.put(type.klass, type);
}
map = Collections.unmodifiableMap(tempMap);
}
}

View File

@@ -1,44 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* @author Brady
* @since 4/20/2019
*/
public final class TypeUtils {
private TypeUtils() {}
/**
* Resolves the "base type" for the specified type. For example, if the specified
* type is {@code List<String>}, then {@code List.class} will be returned. If the
* specified type is already a class, then it is directly returned.
*
* @param type The type to resolve
* @return The base class
*/
public static Class<?> resolveBaseClass(Type type) {
return type instanceof Class ? (Class<?>) type
: type instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) type).getRawType()
: null;
}
}

View File

@@ -36,8 +36,7 @@ public final class 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
* @param pos The block position
* @return The center of the block's bounding box
* @see #getBlockPosCenter(BlockPos)
*/
@@ -82,9 +81,10 @@ public final class VecUtils {
* @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;
Vec3d center = getBlockPosCenter(pos);
double xdiff = x - center.x;
double ydiff = y - center.y;
double zdiff = z - center.z;
return Math.sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
}

View File

@@ -17,6 +17,15 @@
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,
@@ -27,45 +36,84 @@ public enum Input {
/**
* The move forward input
*/
MOVE_FORWARD,
MOVE_FORWARD(s -> s.keyBindForward),
/**
* The move back input
*/
MOVE_BACK,
MOVE_BACK(s -> s.keyBindBack),
/**
* The move left input
*/
MOVE_LEFT,
MOVE_LEFT(s -> s.keyBindLeft),
/**
* The move right input
*/
MOVE_RIGHT,
MOVE_RIGHT(s -> s.keyBindRight),
/**
* The attack input
*/
CLICK_LEFT,
CLICK_LEFT(s -> s.keyBindAttack),
/**
* The use item input
*/
CLICK_RIGHT,
CLICK_RIGHT(s -> s.keyBindUseItem),
/**
* The jump input
*/
JUMP,
JUMP(s -> s.keyBindJump),
/**
* The sneak input
*/
SNEAK,
SNEAK(s -> s.keyBindSneak),
/**
* The sprint input
*/
SPRINT
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));
}
}

View File

@@ -0,0 +1,98 @@
/*
* 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 cabaletta.comms;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Do you not like having a blocking "receiveMessage" thingy?
* <p>
* Do you prefer just being able to get a list of all messages received since the last tick?
* <p>
* If so, this class is for you!
*
* @author leijurv
*/
public class BufferedConnection implements IConnection {
private final IConnection wrapped;
private final LinkedBlockingQueue<iMessage> queue;
private volatile transient IOException thrownOnRead;
public BufferedConnection(IConnection wrapped) {
this(wrapped, Integer.MAX_VALUE); // LinkedBlockingQueue accepts this as "no limit"
}
public BufferedConnection(IConnection wrapped, int maxInternalQueueSize) {
this.wrapped = wrapped;
this.queue = new LinkedBlockingQueue<>();
this.thrownOnRead = null;
new Thread(() -> {
try {
while (thrownOnRead == null) {
queue.put(wrapped.receiveMessage());
}
} catch (IOException e) {
thrownOnRead = e;
} catch (InterruptedException e) {
thrownOnRead = new IOException("Interrupted while enqueueing", e);
}
}).start();
}
@Override
public void sendMessage(iMessage message) throws IOException {
wrapped.sendMessage(message);
}
@Override
public iMessage receiveMessage() {
throw new UnsupportedOperationException("BufferedConnection can only be read from non-blockingly");
}
@Override
public void close() {
wrapped.close();
thrownOnRead = new EOFException("Closed");
}
public List<iMessage> receiveMessagesNonBlocking() throws IOException {
ArrayList<iMessage> msgs = new ArrayList<>();
queue.drainTo(msgs); // preserves order -- first message received will be first in this arraylist
if (msgs.isEmpty() && thrownOnRead != null) {
IOException up = new IOException("BufferedConnection wrapped", thrownOnRead);
throw up;
}
return msgs;
}
public void handleAllPendingMessages(IMessageListener listener) throws IOException {
receiveMessagesNonBlocking().forEach(msg -> msg.handle(listener));
}
public static BufferedConnection makeBuffered(IConnection conn) {
if (conn instanceof BufferedConnection) {
return (BufferedConnection) conn;
} else {
return new BufferedConnection(conn);
}
}
}

View File

@@ -0,0 +1,54 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import java.io.DataInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public enum ConstructingDeserializer implements MessageDeserializer {
INSTANCE;
private final List<Class<? extends iMessage>> MSGS;
ConstructingDeserializer() {
MSGS = new ArrayList<>();
// imagine doing something in reflect but it's actually concise and you don't need to catch 42069 different exceptions. huh.
for (Method m : IMessageListener.class.getDeclaredMethods()) {
if (m.getName().equals("handle")) {
MSGS.add((Class<? extends iMessage>) m.getParameterTypes()[0]);
}
}
}
@Override
public synchronized iMessage deserialize(DataInputStream in) throws IOException {
int type = ((int) in.readByte()) & 0xff;
try {
return MSGS.get(type).getConstructor(DataInputStream.class).newInstance(in);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException ex) {
throw new IOException("Unknown message type " + type, ex);
}
}
public byte getHeader(Class<? extends iMessage> klass) {
return (byte) MSGS.indexOf(klass);
}
}

View File

@@ -15,12 +15,14 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.process;
package cabaletta.comms;
import java.nio.file.Path;
import java.io.IOException;
public interface IExploreProcess extends IBaritoneProcess {
void explore(int centerX, int centerZ);
public interface IConnection {
void sendMessage(iMessage message) throws IOException;
void applyJsonFilter(Path path, boolean invert) throws Exception;
iMessage receiveMessage() throws IOException;
void close();
}

View File

@@ -0,0 +1,46 @@
/*
* 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 cabaletta.comms;
import cabaletta.comms.downward.MessageChat;
import cabaletta.comms.downward.MessageComputationRequest;
import cabaletta.comms.upward.MessageComputationResponse;
import cabaletta.comms.upward.MessageStatus;
public interface IMessageListener {
default void handle(MessageStatus message) {
unhandled(message);
}
default void handle(MessageChat message) {
unhandled(message);
}
default void handle(MessageComputationRequest message) {
unhandled(message);
}
default void handle(MessageComputationResponse message) {
unhandled(message);
}
default void unhandled(iMessage msg) {
// can override this to throw UnsupportedOperationException, if you want to make sure you're handling everything
// default is to silently ignore messages without handlers
}
}

View 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/>.
*/
package cabaletta.comms;
import java.io.DataInputStream;
import java.io.IOException;
public interface MessageDeserializer {
iMessage deserialize(DataInputStream in) throws IOException;
}

View 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 cabaletta.comms;
import java.io.EOFException;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Do you want a socket to localhost without actually making a gross real socket to localhost?
*/
public class Pipe<T extends iMessage> {
private final LinkedBlockingQueue<Optional<iMessage>> AtoB;
private final LinkedBlockingQueue<Optional<iMessage>> BtoA;
private final PipedConnection A;
private final PipedConnection B;
private volatile boolean closed;
public Pipe() {
this.AtoB = new LinkedBlockingQueue<>();
this.BtoA = new LinkedBlockingQueue<>();
this.A = new PipedConnection(BtoA, AtoB);
this.B = new PipedConnection(AtoB, BtoA);
}
public PipedConnection getA() {
return A;
}
public PipedConnection getB() {
return B;
}
public class PipedConnection implements IConnection {
private final LinkedBlockingQueue<Optional<iMessage>> in;
private final LinkedBlockingQueue<Optional<iMessage>> out;
private PipedConnection(LinkedBlockingQueue<Optional<iMessage>> in, LinkedBlockingQueue<Optional<iMessage>> out) {
this.in = in;
this.out = out;
}
@Override
public void sendMessage(iMessage message) throws IOException {
if (closed) {
throw new EOFException("Closed");
}
try {
out.put(Optional.of(message));
} catch (InterruptedException e) {
// this can never happen since the LinkedBlockingQueues are not constructed with a maximum capacity, see above
}
}
@Override
public iMessage receiveMessage() throws IOException {
if (closed) {
throw new EOFException("Closed");
}
try {
Optional<iMessage> t = in.take();
if (!t.isPresent()) {
throw new EOFException("Closed");
}
return t.get();
} catch (InterruptedException e) {
// again, cannot happen
// but we have to throw something
throw new IllegalStateException(e);
}
}
@Override
public void close() {
closed = true;
try {
AtoB.put(Optional.empty()); // unstick threads
BtoA.put(Optional.empty());
} catch (InterruptedException e) {
}
}
}
}

View File

@@ -0,0 +1,59 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import java.io.*;
public class SerializedConnection implements IConnection {
private final DataInputStream in;
private final DataOutputStream out;
private final MessageDeserializer deserializer;
public SerializedConnection(InputStream in, OutputStream out) {
this(ConstructingDeserializer.INSTANCE, in, out);
}
public SerializedConnection(MessageDeserializer d, InputStream in, OutputStream out) {
this.in = new DataInputStream(in);
this.out = new DataOutputStream(out);
this.deserializer = d;
}
@Override
public synchronized void sendMessage(iMessage message) throws IOException {
message.writeHeader(out);
message.write(out);
}
@Override
public iMessage receiveMessage() throws IOException {
return deserializer.deserialize(in);
}
@Override
public void close() {
try {
in.close();
} catch (IOException e) {
}
try {
out.close();
} catch (IOException e) {
}
}
}

View File

@@ -0,0 +1,27 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import java.io.IOException;
import java.net.Socket;
public class SocketConnection extends SerializedConnection {
public SocketConnection(Socket s) throws IOException {
super(s.getInputStream(), s.getOutputStream());
}
}

View File

@@ -0,0 +1,48 @@
/*
* 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 cabaletta.comms.downward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageChat implements iMessage {
public final String msg;
public MessageChat(DataInputStream in) throws IOException {
this.msg = in.readUTF();
}
public MessageChat(String msg) {
this.msg = msg;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeUTF(msg);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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 cabaletta.comms.downward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageComputationRequest implements iMessage {
public final long computationID;
public final int startX;
public final int startY;
public final int startZ;
public final String goal; // TODO find a better way to do this lol
public MessageComputationRequest(DataInputStream in) throws IOException {
this.computationID = in.readLong();
this.startX = in.readInt();
this.startY = in.readInt();
this.startZ = in.readInt();
this.goal = in.readUTF();
}
public MessageComputationRequest(long computationID, int startX, int startY, int startZ, String goal) {
this.computationID = computationID;
this.startX = startX;
this.startY = startY;
this.startZ = startZ;
this.goal = goal;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeLong(computationID);
out.writeInt(startX);
out.writeInt(startY);
out.writeUTF(goal);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}

View File

@@ -15,15 +15,30 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.gradle.util;
package cabaletta.comms;
import java.io.DataOutputStream;
import java.io.IOException;
/**
* All credits go to AsmLibGradle and its contributors.
* hell yeah
* <p>
* <p>
* dumb android users cant read this file
* <p>
*
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/MappingType.java">Original Source</a>
* @author leijurv
*/
public enum MappingType {
SEARGE,
NOTCH,
CUSTOM // forgegradle
public interface iMessage {
void write(DataOutputStream out) throws IOException;
default void writeHeader(DataOutputStream out) throws IOException {
out.writeByte(getHeader());
}
default byte getHeader() {
return ConstructingDeserializer.INSTANCE.getHeader(getClass());
}
void handle(IMessageListener listener);
}

View File

@@ -0,0 +1,72 @@
/*
* 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 cabaletta.comms.upward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageComputationResponse implements iMessage {
public final long computationID;
public final int pathLength;
public final double pathCost;
public final boolean endsInGoal;
public final int endX;
public final int endY;
public final int endZ;
public MessageComputationResponse(DataInputStream in) throws IOException {
this.computationID = in.readLong();
this.pathLength = in.readInt();
this.pathCost = in.readDouble();
this.endsInGoal = in.readBoolean();
this.endX = in.readInt();
this.endY = in.readInt();
this.endZ = in.readInt();
}
public MessageComputationResponse(long computationID, int pathLength, double pathCost, boolean endsInGoal, int endX, int endY, int endZ) {
this.computationID = computationID;
this.pathLength = pathLength;
this.pathCost = pathCost;
this.endsInGoal = endsInGoal;
this.endX = endX;
this.endY = endY;
this.endZ = endZ;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeLong(computationID);
out.writeInt(pathLength);
out.writeDouble(pathCost);
out.writeBoolean(endsInGoal);
out.writeInt(endX);
out.writeInt(endY);
out.writeInt(endZ);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}

View File

@@ -0,0 +1,124 @@
/*
* 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 cabaletta.comms.upward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageStatus implements iMessage {
public final double x;
public final double y;
public final double z;
public final float yaw;
public final float pitch;
public final boolean onGround;
public final float health;
public final float saturation;
public final int foodLevel;
public final int pathStartX;
public final int pathStartY;
public final int pathStartZ;
public final boolean hasCurrentSegment;
public final boolean hasNextSegment;
public final boolean calcInProgress;
public final double ticksRemainingInCurrent;
public final boolean calcFailedLastTick;
public final boolean safeToCancel;
public final String currentGoal;
public final String currentProcess;
public MessageStatus(DataInputStream in) throws IOException {
this.x = in.readDouble();
this.y = in.readDouble();
this.z = in.readDouble();
this.yaw = in.readFloat();
this.pitch = in.readFloat();
this.onGround = in.readBoolean();
this.health = in.readFloat();
this.saturation = in.readFloat();
this.foodLevel = in.readInt();
this.pathStartX = in.readInt();
this.pathStartY = in.readInt();
this.pathStartZ = in.readInt();
this.hasCurrentSegment = in.readBoolean();
this.hasNextSegment = in.readBoolean();
this.calcInProgress = in.readBoolean();
this.ticksRemainingInCurrent = in.readDouble();
this.calcFailedLastTick = in.readBoolean();
this.safeToCancel = in.readBoolean();
this.currentGoal = in.readUTF();
this.currentProcess = in.readUTF();
}
public MessageStatus(double x, double y, double z, float yaw, float pitch, boolean onGround, float health, float saturation, int foodLevel, int pathStartX, int pathStartY, int pathStartZ, boolean hasCurrentSegment, boolean hasNextSegment, boolean calcInProgress, double ticksRemainingInCurrent, boolean calcFailedLastTick, boolean safeToCancel, String currentGoal, String currentProcess) {
this.x = x;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
this.onGround = onGround;
this.health = health;
this.saturation = saturation;
this.foodLevel = foodLevel;
this.pathStartX = pathStartX;
this.pathStartY = pathStartY;
this.pathStartZ = pathStartZ;
this.hasCurrentSegment = hasCurrentSegment;
this.hasNextSegment = hasNextSegment;
this.calcInProgress = calcInProgress;
this.ticksRemainingInCurrent = ticksRemainingInCurrent;
this.calcFailedLastTick = calcFailedLastTick;
this.safeToCancel = safeToCancel;
this.currentGoal = currentGoal;
this.currentProcess = currentProcess;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeDouble(x);
out.writeDouble(y);
out.writeDouble(z);
out.writeFloat(yaw);
out.writeFloat(pitch);
out.writeBoolean(onGround);
out.writeFloat(health);
out.writeFloat(saturation);
out.writeInt(foodLevel);
out.writeInt(pathStartX);
out.writeInt(pathStartY);
out.writeInt(pathStartZ);
out.writeBoolean(hasCurrentSegment);
out.writeBoolean(hasNextSegment);
out.writeBoolean(calcInProgress);
out.writeDouble(ticksRemainingInCurrent);
out.writeBoolean(calcFailedLastTick);
out.writeBoolean(safeToCancel);
out.writeUTF(currentGoal);
out.writeUTF(currentProcess);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}

View File

@@ -1,52 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.Baritone;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ChunkRenderContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.chunk.RenderChunk;
import net.minecraft.util.math.BlockPos;
import org.lwjgl.opengl.GL14;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import static org.lwjgl.opengl.GL11.*;
@Mixin(ChunkRenderContainer.class)
public class MixinChunkRenderContainer {
@Redirect( // avoid creating CallbackInfo at all costs; this is called 40k times per second
method = "preRenderChunk",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/renderer/chunk/RenderChunk.getPosition()Lnet/minecraft/util/math/BlockPos;"
)
)
private BlockPos getPosition(RenderChunk renderChunkIn) {
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer() && Minecraft.getMinecraft().world.getChunk(renderChunkIn.getPosition()).isEmpty()) {
GlStateManager.enableAlpha();
GlStateManager.enableBlend();
GL14.glBlendColor(0, 0, 0, Baritone.settings().cachedChunksOpacity.value);
GlStateManager.tryBlendFuncSeparate(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_ONE, GL_ZERO);
}
return renderChunkIn.getPosition();
}
}

View File

@@ -1,57 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.utils.IPlayerContext;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.chunk.ChunkRenderWorker;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
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.Redirect;
@Mixin(ChunkRenderWorker.class)
public abstract class MixinChunkRenderWorker {
@Shadow
protected abstract boolean isChunkExisting(BlockPos pos, World worldIn);
@Redirect(
method = "processTask",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/renderer/chunk/ChunkRenderWorker.isChunkExisting(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/World;)Z"
)
)
private boolean isChunkExisting(ChunkRenderWorker worker, BlockPos pos, World world) {
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
IPlayerContext ctx = baritone.getPlayerContext();
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
return baritone.bsi.isLoaded(pos.getX(), pos.getZ()) || this.isChunkExisting(pos, world);
}
}
return this.isChunkExisting(pos, world);
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.api.BaritoneAPI;
import baritone.api.event.events.RotationMoveEvent;
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
*/
@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) {
// 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);
}
}
@Redirect(
method = "moveRelative",
at = @At(
value = "FIELD",
opcode = GETFIELD,
target = "net/minecraft/entity/Entity.rotationYaw:F"
)
)
private float overrideYaw(Entity self) {
if (self instanceof EntityPlayerSP) {
return this.motionUpdateRotationEvent.getYaw();
}
return self.rotationYaw;
}
}

View File

@@ -18,7 +18,6 @@
package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.RotationMoveEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
@@ -56,11 +55,8 @@ public abstract class MixinEntityLivingBase extends Entity {
private void preMoveRelative(CallbackInfo ci) {
// noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(this)) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone != null) {
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw);
baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
}
this.jumpRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.JUMP, this.rotationYaw);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
}
}
@@ -73,30 +69,9 @@ public abstract class MixinEntityLivingBase extends Entity {
)
)
private float overrideYaw(EntityLivingBase self) {
if (self instanceof EntityPlayerSP && BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) != null) {
if (self instanceof EntityPlayerSP) {
return this.jumpRotationEvent.getYaw();
}
return self.rotationYaw;
}
@Redirect(
method = "travel",
at = @At(
value = "INVOKE",
target = "net/minecraft/entity/EntityLivingBase.moveRelative(FFFF)V"
)
)
private void travel(EntityLivingBase self, float strafe, float up, float forward, float friction) {
// noinspection ConstantConditions
if (!EntityPlayerSP.class.isInstance(this) || BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) == null) {
moveRelative(strafe, up, forward, friction);
return;
}
RotationMoveEvent motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(motionUpdateRotationEvent);
float originalYaw = this.rotationYaw;
this.rotationYaw = motionUpdateRotationEvent.getYaw();
this.moveRelative(strafe, up, forward, friction);
this.rotationYaw = originalYaw;
}
}

View File

@@ -18,14 +18,11 @@
package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.event.events.ChatEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.SprintStateEvent;
import baritone.api.event.events.type.EventState;
import baritone.behavior.LookBehavior;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.PlayerCapabilities;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -46,12 +43,8 @@ public class MixinEntityPlayerSP {
cancellable = true
)
private void sendChatMessage(String msg, CallbackInfo ci) {
ChatEvent event = new ChatEvent(msg);
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone == null) {
return;
}
baritone.getGameEventHandler().onSendChatMessage(event);
ChatEvent event = new ChatEvent((EntityPlayerSP) (Object) this, msg);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onSendChatMessage(event);
if (event.isCancelled()) {
ci.cancel();
}
@@ -67,10 +60,7 @@ public class MixinEntityPlayerSP {
)
)
private void onPreUpdate(CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone != null) {
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.PRE));
}
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
}
@Inject(
@@ -83,10 +73,7 @@ public class MixinEntityPlayerSP {
)
)
private void onPostUpdate(CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone != null) {
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
}
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
}
@Redirect(
@@ -97,47 +84,7 @@ public class MixinEntityPlayerSP {
)
)
private boolean isAllowFlying(PlayerCapabilities capabilities) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone == null) {
return capabilities.allowFlying;
}
return !baritone.getPathingBehavior().isPathing() && capabilities.allowFlying;
}
@Redirect(
method = "onLivingUpdate",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/settings/KeyBinding.isKeyDown()Z"
)
)
private boolean isKeyDown(KeyBinding keyBinding) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone == null) {
return keyBinding.isKeyDown();
}
SprintStateEvent event = new SprintStateEvent();
baritone.getGameEventHandler().onPlayerSprintState(event);
if (event.getState() != null) {
return event.getState();
}
if (baritone != BaritoneAPI.getProvider().getPrimaryBaritone()) {
// hitting control shouldn't make all bots sprint
return false;
}
return keyBinding.isKeyDown();
}
@Inject(
method = "updateRidden",
at = @At(
value = "HEAD"
)
)
private void updateRidden(CallbackInfo cb) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone != null) {
((LookBehavior) baritone.getLookBehavior()).pig();
}
IPathingBehavior pathingBehavior = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getPathingBehavior();
return !pathingBehavior.isPathing() && capabilities.allowFlying;
}
}

View File

@@ -0,0 +1,45 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import net.minecraft.client.settings.KeyBinding;
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.callback.CallbackInfoReturnable;
/**
* @author Brady
* @since 7/31/2018
*/
@Mixin(KeyBinding.class)
public class MixinKeyBinding {
@Inject(
method = "isKeyDown",
at = @At("HEAD"),
cancellable = true
)
private void isKeyDown(CallbackInfoReturnable<Boolean> cir) {
// only the primary baritone forces keys
if (BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this)) {
cir.setReturnValue(true);
}
}
}

View File

@@ -96,6 +96,15 @@ public class MixinMinecraft {
}
@Inject(
method = "processKeyBinds",
at = @At("HEAD")
)
private void runTickKeyboard(CallbackInfo ci) {
// keyboard input is only the primary baritone
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onProcessKeyBinds();
}
@Inject(
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
at = @At("HEAD")
@@ -155,7 +164,7 @@ public class MixinMinecraft {
)
private void onBlockBreak(CallbackInfo ci, BlockPos pos) {
// clickMouse is only for the main player
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(pos, BlockInteractEvent.Type.START_BREAK));
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(pos, BlockInteractEvent.Type.BREAK));
}
@Inject(

Some files were not shown because too many files have changed in this diff Show More