Merge conflicts

This commit is contained in:
Brady 2019-10-04 10:19:35 -05:00
commit 7af0ed6ea1
No known key found for this signature in database
GPG Key ID: 73A788379A197567
276 changed files with 17323 additions and 3307 deletions

1
.gitattributes vendored Normal file
View File

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

25
.github/ISSUE_TEMPLATE/bug.md vendored Normal file
View File

@ -0,0 +1,25 @@
---
name: Bug report
about: Please file a separate report for each issue
title: Please add a brief but descriptive title
labels: bug
assignees: ''
---
## Some information
Operating system:
Java version:
Minecraft version:
Baritone version:
Forge mods (if used):
## Exception, error or logs
You can find your logs in `%appdata%/.minecraft/logs/` (Windows) or `/Library/Application\ Support/minecraft/logs` (Mac).
## How to reproduce
Add your steps to reproduce the issue/bug experienced here.
## Final checklist
- [ ] I have included the version of Minecraft I'm running, baritone's version and forge mods (if used).
- [ ] I have included logs, exceptions and / or steps to reproduce the issue.
- [ ] I have not used any OwO's or UwU's in this issue.

13
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@ -0,0 +1,13 @@
---
name: Question
about: Please file a separate report for each question
title: Please add a brief but descriptive title
labels: question
assignees: ''
---
## What do you need help with?
With as much detail as possible, describe your question and what you may need help with.
## Final checklist
- [ ] I have not used any OwO's or UwU's in this issue.

19
.github/ISSUE_TEMPLATE/suggestion.md vendored Normal file
View File

@ -0,0 +1,19 @@
---
name: Suggestion
about: Please file a separate report for each suggestion
title: Please add a brief but descriptive title
labels: enhancement
assignees: ''
---
## Describe your suggestion
With as much detail as possible, describe what your suggestion would do for Baritone.
## Settings
If applicable, what settings/customizability should be offered to tweak the functionality of your suggestion.
## Context
Describe how your suggestion would improve Baritone, or the reason behind it being added.
## Final checklist
- [ ] I have not used any OwO's or UwU's in this issue.

1
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

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

4
.gitignore vendored
View File

@ -14,8 +14,10 @@ classes/
# IntelliJ Files
.idea/
*.iml
*.ipr
*.iws
/logs/
# Copyright Files
!/.idea/copyright/Baritone.xml
!/.idea/copyright/profiles_settings.xml
!/.idea/copyright/profiles_settings.xml

View File

@ -9,6 +9,7 @@ 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

83
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,83 @@
# 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 (including uwu's or owo's)
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Giving and 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 or consent
* 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,17 +1,16 @@
FROM debian:jessie
FROM debian:stretch
RUN echo 'deb http://deb.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/jessie-backports.list
RUN echo 'deb http://deb.debian.org/debian stretch-backports main' > /etc/apt/sources.list.d/stretch-backports.list
ENV DEBIAN_FRONTEND noninteractive
RUN apt update -y
RUN apt install --target-release jessie-backports \
RUN apt install \
openjdk-8-jdk \
ca-certificates-java \
--assume-yes
RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
RUN apt install -qq --assume-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
COPY . /code
@ -21,4 +20,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,13 +4,14 @@
- **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`).
- **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.
- **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:
@ -21,9 +22,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.
# 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.
# Chat control
- [Baritone chat control usage](USAGE.md)
# Goals
The pathing goal can be set to any of these options:
@ -46,7 +47,6 @@ 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

View File

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

View File

@ -1,96 +0,0 @@
# 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>.

BIN
LICENSE-Part-2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -1,65 +1,72 @@
# 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-green.svg)](LICENSE)
[![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)
[![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)
[![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-brightgreen.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/)
[![Minecraft](https://img.shields.io/badge/MC-1.14.4-brightgreen.svg)](https://github.com/cabaletta/baritone/tree/1.14.4/)
[![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)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2)
[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.0.0--hotfix--4-brightgreen.svg)](https://impactdevelopment.github.io/)
[![KAMI integration](https://img.shields.io/badge/KAMI%20integration-v1.0.0-orange.svg)](https://github.com/zeroeightysix/KAMI/)
[![Asuna integration](https://img.shields.io/badge/Asuna%20integration-v1.0.0-orange.svg)](https://github.com/EmotionalLove/Asuna/)
[![Future integration](https://img.shields.io/badge/Future%20integration-%3F%3F%3F-red.svg)](https://futureclient.net/)
[![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.8%20/%20v1.3.4%20/%20v1.4.1-brightgreen.svg)](https://impactclient.net/)
[![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg)](https://github.com/fr1kin/ForgeHax/)
[![Aristois add-on integration](https://img.shields.io/badge/Aristois%20add--on%20integration-v1.3.4%20/%20v1.4.1-green.svg)](https://gitlab.com/emc-mods-indrit/baritone_api)
[![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/)
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.
Baritone is the pathfinding system used in [Impact](https://impactclient.net/) 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://impactclient.net/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to install the v1.2.* forge api 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.
For 1.14.4, [click here](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1). Or [with optifine](https://github.com/cabaletta/baritone/issues/797).
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
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 from Aug 1 2018 to Aug 1 2019.
1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2
# Getting Started
Here are some links to help to get started:
- [Features](FEATURES.md)
- [Installation](INSTALL.md)
- [Installation & setup](SETUP.md)
# Setup
- [API Javadocs](https://baritone.leijurv.com/)
## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
- [Settings](https://baritone.leijurv.com/baritone/api/Settings.html#field.detail)
Running Baritone:
- [Usage (chat control)](USAGE.md)
```
$ gradlew runClient
```
# API
Building Baritone:
```
$ gradlew build
```
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.
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
Below is an example of basic usage for changing some settings, and then pathing to a X/Z goal.
```
BaritoneAPI.getSettings().allowSprint.value = true;
BaritoneAPI.getSettings().pathTimeoutMS.value = 2000L;
BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L;
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
```
@ -68,11 +75,11 @@ BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAnd
## Can I use Baritone as a library in my custom utility client?
Sure! (As long as usage is in compliance with the LGPL 3 License)
That's what it's for, sure! (As long as usage is in compliance with the LGPL 3.0 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?

106
SETUP.md Normal file
View File

@ -0,0 +1,106 @@
# Installation
The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone.
For 1.14.4, [click here](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1).
Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
## Prebuilt official releases
These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `backfill-2` branch for example, you'll have to build it yourself)
Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
v1.2.* is for 1.12.2, v1.3.* is for 1.13.2
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

87
USAGE.md Normal file
View File

@ -0,0 +1,87 @@
(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 set a goal to a certain coordinate then path to it
- `goto x y z` or `goto x z` or `goto y` to go to a certain coordinate (in a single step, starts going immediately)
- `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 iron_ore` to mine diamond ore or iron 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.) An amount of blocks can also be specified, for example, `mine diamond_ore 64`.
- `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. `followplayers` to follow any players in range (combine with Kill Aura for a fun time). `followentities` to follow any entities. `followentity pig` to follow entities of a specific type.
- `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).
- `schematica` to build the schematic that is currently open in schematica
- `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
New commands:
- `sel` to manage selections
- some others
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,124 +1,140 @@
/*
* 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
}
}
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'
}
javadoc {
source = sourceSets.api.allJava
classpath = sourceSets.api.compileClasspath
}
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'
}
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.2.9'
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
}
schematica_api {
compileClasspath += main.compileClasspath
}
main {
compileClasspath += schematica_api.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)

View File

@ -17,8 +17,6 @@
package baritone.gradle.task;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.gradle.api.DefaultTask;
import java.io.File;
@ -26,7 +24,6 @@ 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
@ -34,8 +31,6 @@ import java.util.List;
*/
class BaritoneGradleTask extends DefaultTask {
protected static final JsonParser PARSER = new JsonParser();
protected static final String
PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar",
@ -45,26 +40,28 @@ 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_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
protected String artifactName, artifactVersion;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, artifactForgeApiPath, artifactForgeStandalonePath, 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.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE));
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
@ -95,8 +92,4 @@ 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,9 +42,11 @@ 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 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));
// NIO will not automatically create directories
Path dir = getRelativeFile("dist/");
@ -53,12 +55,14 @@ 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.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);
// Calculate all checksums and format them like "shasum"
List<String> shasum = Stream.of(api, standalone, unoptimized)
List<String> shasum = Stream.of(api, forgeApi, standalone, forgeStandalone, unoptimized)
.map(path -> sha1(path) + " " + path.getFileName().toString())
.collect(Collectors.toList());

View File

@ -60,6 +60,8 @@ public class ProguardTask extends BaritoneGradleTask {
private List<String> requiredLibraries;
private File mixin;
@TaskAction
protected void exec() throws Exception {
super.verifyArtifacts();
@ -80,7 +82,7 @@ public class ProguardTask extends BaritoneGradleTask {
Files.delete(this.artifactUnoptimizedPath);
}
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
}
private void downloadProguard() throws Exception {
@ -175,10 +177,16 @@ 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
@ -266,12 +274,14 @@ public class ProguardTask extends BaritoneGradleTask {
private void proguardApi() throws Exception {
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
}
private void proguardStandalone() throws Exception {
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
}
private void cleanup() {
@ -300,8 +310,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());
this.printOutputLog(p.getErrorStream());
this.printOutputLog(p.getInputStream(), System.out);
this.printOutputLog(p.getErrorStream(), System.err);
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
int exitCode = p.waitFor();
@ -310,12 +320,12 @@ public class ProguardTask extends BaritoneGradleTask {
}
}
private void printOutputLog(InputStream stream) {
private void printOutputLog(InputStream stream, PrintStream outerr) {
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
outerr.println(line);
}
} catch (Exception e) {
e.printStackTrace();

View File

@ -22,10 +22,7 @@ import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@ -39,7 +36,7 @@ import java.util.stream.Collectors;
*/
public class Determinizer {
public static void determinize(String inputPath, String outputPath) throws IOException {
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
System.out.println("Running Determinizer");
System.out.println(" Input path: " + inputPath);
System.out.println(" Output path: " + outputPath);
@ -66,10 +63,30 @@ 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,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

11
scripts/proguard.pro vendored
View File

@ -12,14 +12,16 @@
-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
# hack
-keep class baritone.utils.ExampleBaritoneControl { *; } # have to include this string to remove this keep in the standalone build: # this is the keep api
-keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect
# setting names are reflected from field names, so keep field names
-keepclassmembers class baritone.api.Settings {
@ -29,6 +31,11 @@
# need to keep mixin names
-keep class baritone.launch.** { *; }
#try to keep usage of schematica in separate classes
-keep class baritone.utils.schematic.schematica.**
#proguard doesnt like it when it cant find our fake schematica classes
-dontwarn baritone.utils.schematic.schematica.**
# 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

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,9 +23,7 @@ import java.util.Iterator;
import java.util.ServiceLoader;
/**
* API exposure for various things implemented in Baritone.
* <p>
* W.I.P
* Exposes the {@link IBaritoneProvider} instance and the {@link Settings} instance for API usage.
*
* @author Brady
* @since 9/23/2018
@ -36,12 +34,12 @@ public final class BaritoneAPI {
private static final Settings settings;
static {
settings = new Settings();
SettingsUtil.readAndApply(settings);
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);
Iterator<IBaritoneProvider> instances = baritoneLoader.iterator();
provider = instances.next();
settings = new Settings();
SettingsUtil.readAndApply(settings);
}
public static IBaritoneProvider getProvider() {

View File

@ -22,12 +22,11 @@ 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.ICustomGoalProcess;
import baritone.api.process.IFollowProcess;
import baritone.api.process.IGetToBlockProcess;
import baritone.api.process.IMineProcess;
import baritone.api.process.*;
import baritone.api.selection.ISelectionManager;
import baritone.api.utils.IInputOverrideHandler;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.command.manager.ICommandManager;
/**
* @author Brady
@ -36,10 +35,10 @@ import baritone.api.utils.IPlayerContext;
public interface IBaritone {
/**
* @return The {@link IFollowProcess} instance
* @see IFollowProcess
* @return The {@link IPathingBehavior} instance
* @see IPathingBehavior
*/
IFollowProcess getFollowProcess();
IPathingBehavior getPathingBehavior();
/**
* @return The {@link ILookBehavior} instance
@ -47,6 +46,12 @@ public interface IBaritone {
*/
ILookBehavior getLookBehavior();
/**
* @return The {@link IFollowProcess} instance
* @see IFollowProcess
*/
IFollowProcess getFollowProcess();
/**
* @return The {@link IMineProcess} instance
* @see IMineProcess
@ -54,10 +59,34 @@ public interface IBaritone {
IMineProcess getMineProcess();
/**
* @return The {@link IPathingBehavior} instance
* @see IPathingBehavior
* @return The {@link IBuilderProcess} instance
* @see IBuilderProcess
*/
IPathingBehavior getPathingBehavior();
IBuilderProcess getBuilderProcess();
/**
* @return The {@link IExploreProcess} instance
* @see IExploreProcess
*/
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();
/**
* @return The {@link IWorldProvider} instance
@ -65,15 +94,47 @@ 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();
ICustomGoalProcess getCustomGoalProcess();
IGetToBlockProcess getGetToBlockProcess();
/**
* @return The {@link IPlayerContext} instance
* @see IPlayerContext
*/
IPlayerContext getPlayerContext();
/**
* @return The {@link IEventBus} instance
* @see IEventBus
*/
IEventBus getGameEventHandler();
/**
* @return The {@link ISelectionManager} instance
* @see ISelectionManager
*/
ISelectionManager getSelectionManager();
/**
* @return The {@link ICommandManager} instance
* @see ICommandManager
*/
ICommandManager getCommandManager();
/**
* Open click
*/
void openClick();
}

View File

@ -22,9 +22,12 @@ import baritone.api.cache.IWorldScanner;
import net.minecraft.client.entity.EntityPlayerSP;
import java.util.List;
import java.util.Objects;
/**
* @author Leijurv
* Provides the present {@link IBaritone} instances
*
* @author leijurv
*/
public interface IBaritoneProvider {
@ -48,18 +51,19 @@ public interface IBaritoneProvider {
/**
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
* replaced with {@code #getBaritoneForUser(IBaritoneUser)} when {@code bot-system} is merged.
* replaced with or be overloaded in addition to {@code #getBaritoneForUser(IBaritoneUser)} when
* {@code bot-system} is merged into {@code master}.
*
* @param player The player
* @return The {@link IBaritone} instance.
*/
default IBaritone getBaritoneForPlayer(EntityPlayerSP player) {
for (IBaritone baritone : getAllBaritones()) {
if (player.equals(baritone.getPlayerContext().player())) {
if (Objects.equals(player, baritone.getPlayerContext().player())) {
return baritone;
}
}
throw new IllegalStateException("No baritone for player " + player);
return null;
}
/**

File diff suppressed because it is too large Load Diff

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 baritone.api.accessor;
import java.net.URI;
public interface IGuiScreen {
void openLink(URI url);
}

View File

@ -0,0 +1,23 @@
/*
* 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.accessor;
public interface IItemStack {
int getBaritoneHash();
}

View File

@ -18,9 +18,13 @@
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

@ -37,7 +37,26 @@ public interface IPathingBehavior extends IBehavior {
*
* @return The estimated remaining ticks in the current segment.
*/
Optional<Double> ticksRemainingInSegment();
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));
}
/**
* @return The current pathing goal
@ -45,10 +64,20 @@ public interface IPathingBehavior extends IBehavior {
Goal getGoal();
/**
* @return Whether or not a path is currently being executed.
* @return Whether or not a path is currently being executed. This will be false if there's currently a pause.
* @see #hasPath()
*/
boolean isPathing();
/**
* @return If there is a current path. Note that the path is not necessarily being executed, for example when there
* is a pause in effect.
* @see #isPathing()
*/
default boolean hasPath() {
return getCurrent() != null;
}
/**
* Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path.
* <p>
@ -59,6 +88,13 @@ 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

@ -20,7 +20,7 @@ package baritone.api.cache;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.Chunk;
import java.util.LinkedList;
import java.util.ArrayList;
/**
* @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
*/
LinkedList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq);
ArrayList<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,4 +81,6 @@ public interface ICachedWorld {
* in a new thread by default.
*/
void save();
}

View File

@ -17,12 +17,9 @@
package baritone.api.cache;
import net.minecraft.util.math.BlockPos;
import org.apache.commons.lang3.ArrayUtils;
import baritone.api.utils.BetterBlockPos;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.*;
/**
* A marker for a position in the world.
@ -60,7 +57,7 @@ public interface IWaypoint {
*
* @return The block position of this waypoint
*/
BlockPos getLocation();
BetterBlockPos getLocation();
enum Tag {
@ -92,20 +89,48 @@ public interface IWaypoint {
/**
* The names for the tag, anything that the tag can be referred to as.
*/
private final String[] names;
public final String[] names;
Tag(String... names) {
this.names = names;
}
/**
* Finds a tag from one of the names that could be used to identify said tag.
*
* @param name The name of the tag
* @return The tag, if one is found, otherwise, {@code null}
* @return A name that can be passed to {@link #getByName(String)} to retrieve this tag
*/
public static Tag fromString(String name) {
return TAG_LIST.stream().filter(tag -> ArrayUtils.contains(tag.names, name.toLowerCase())).findFirst().orElse(null);
public String getName() {
return names[0];
}
/**
* Gets a tag by one of its names.
*
* @param name The name to search for.
* @return The tag, if found, or null.
*/
public static Tag getByName(String name) {
for (Tag action : Tag.values()) {
for (String alias : action.names) {
if (alias.equalsIgnoreCase(name)) {
return action;
}
}
}
return null;
}
/**
* @return All tag names.
*/
public static String[] getAllNames() {
Set<String> names = new HashSet<>();
for (Tag tag : Tag.values()) {
names.addAll(Arrays.asList(tag.names));
}
return names.toArray(new String[0]);
}
}
}

View File

@ -17,6 +17,7 @@
package baritone.api.cache;
import baritone.api.utils.BlockOptionalMetaLookup;
import baritone.api.utils.IPlayerContext;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos;
@ -33,28 +34,53 @@ public interface IWorldScanner {
/**
* Scans the world, up to the specified max chunk radius, for the specified blocks.
*
* @param ctx The {@link IPlayerContext} containing player and world info that the
* scan is based upon
* @param blocks The blocks to scan for
* @param ctx The {@link IPlayerContext} containing player and world info that the scan is based upon
* @param filter The blocks to scan for
* @param max The maximum number of blocks to scan before cutoff
* @param yLevelThreshold If a block is found within this Y level, the current result will be
* returned, if the value is negative, then this condition doesn't apply.
* @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.
* @param maxSearchRadius The maximum chunk search radius
* @return The matching block positions
*/
List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
List<BlockPos> scanChunkRadius(IPlayerContext ctx, BlockOptionalMetaLookup filter, int max, int yLevelThreshold, int maxSearchRadius);
default List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> filter, int max, int yLevelThreshold, int maxSearchRadius) {
return scanChunkRadius(ctx, new BlockOptionalMetaLookup(filter.toArray(new Block[0])), max, yLevelThreshold, 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 ctx The {@link IPlayerContext} containing player and world info that the scan is based upon
* @param filter 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, BlockOptionalMetaLookup filter, ChunkPos pos, int max, int yLevelThreshold);
/**
* 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.
* @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);
default List<BlockPos> scanChunk(IPlayerContext ctx, List<Block> blocks, ChunkPos pos, int max, int yLevelThreshold) {
return scanChunk(ctx, new BlockOptionalMetaLookup(blocks), pos, max, yLevelThreshold);
}
/**
* Repacks 40 chunks around the player.
*
* @param ctx The player context for that player.
* @return The number of chunks queued for repacking.
*/
int repack(IPlayerContext ctx);
}

View File

@ -15,10 +15,9 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.cache;
package baritone.api.cache;
import baritone.api.cache.IWaypoint;
import net.minecraft.util.math.BlockPos;
import baritone.api.utils.BetterBlockPos;
import java.util.Date;
@ -32,9 +31,9 @@ public class Waypoint implements IWaypoint {
private final String name;
private final Tag tag;
private final long creationTimestamp;
private final BlockPos location;
private final BetterBlockPos location;
public Waypoint(String name, Tag tag, BlockPos location) {
public Waypoint(String name, Tag tag, BetterBlockPos location) {
this(name, tag, location, System.currentTimeMillis());
}
@ -47,7 +46,7 @@ public class Waypoint implements IWaypoint {
* @param location The waypoint location
* @param creationTimestamp When the waypoint was created
*/
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
public Waypoint(String name, Tag tag, BetterBlockPos location, long creationTimestamp) {
this.name = name;
this.tag = tag;
this.location = location;
@ -56,7 +55,7 @@ public class Waypoint implements IWaypoint {
@Override
public int hashCode() {
return name.hashCode() + tag.hashCode() + location.hashCode(); //lol
return name.hashCode() ^ tag.hashCode() ^ location.hashCode() ^ Long.hashCode(creationTimestamp);
}
@Override
@ -75,13 +74,18 @@ public class Waypoint implements IWaypoint {
}
@Override
public BlockPos getLocation() {
public BetterBlockPos getLocation() {
return this.location;
}
@Override
public String toString() {
return name + " " + location.toString() + " " + new Date(creationTimestamp).toString();
return String.format(
"%s %s %s",
name,
BetterBlockPos.from(location).toString(),
new Date(creationTimestamp).toString()
);
}
@Override

View File

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

View File

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

View File

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

View File

@ -17,21 +17,14 @@
package baritone.api.event.events;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
/**
* @author Brady
* @since 1/18/2019
*/
public class SprintStateEvent extends ManagedPlayerEvent {
public final class SprintStateEvent {
private Boolean state;
public SprintStateEvent(EntityPlayerSP player) {
super(player);
}
public final void setState(boolean state) {
this.state = state;
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.event.events;
import baritone.api.event.events.type.Cancellable;
import baritone.api.event.events.type.Overrideable;
/**
* @author LoganDark
*/
public abstract class TabCompleteEvent extends Cancellable {
public final Overrideable<String> prefix;
public final Overrideable<String[]> completions;
TabCompleteEvent(String prefix, String[] completions) {
this.prefix = new Overrideable<>(prefix);
this.completions = new Overrideable<>(completions);
}
public boolean wasModified() {
return prefix.wasModified() || completions.wasModified();
}
public static final class Pre extends TabCompleteEvent {
public Pre(String prefix) {
super(prefix, null);
}
}
public static final class Post extends TabCompleteEvent {
public Post(String prefix, String[] completions) {
super(prefix, completions);
}
}
}

View File

@ -1,61 +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.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

@ -0,0 +1,53 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.event.events.type;
/**
* @author LoganDark
*/
public class Overrideable<T> {
private T value;
private boolean modified;
public Overrideable(T current) {
value = current;
}
public T get() {
return value;
}
public void set(T newValue) {
value = newValue;
modified = true;
}
public boolean wasModified() {
return modified;
}
@Override
public String toString() {
return String.format(
"Overrideable{modified=%b,value=%s}",
modified,
value.toString()
);
}
}

View File

@ -39,6 +39,12 @@ public interface AbstractGameEventListener extends IGameEventListener {
@Override
default void onSendChatMessage(ChatEvent event) {}
@Override
default void onPreTabComplete(TabCompleteEvent.Pre event) {}
@Override
default void onPostTabComplete(TabCompleteEvent.Post event) {}
@Override
default void onChunkEvent(ChunkEvent event) {}

View File

@ -57,6 +57,21 @@ public interface IGameEventListener {
*/
void onSendChatMessage(ChatEvent event);
/**
* Runs whenever the client player tries to tab complete in chat.
*
* @param event The event
*/
void onPreTabComplete(TabCompleteEvent.Pre event);
/**
* Runs whenever the client player tries to tab complete in chat once completions have been recieved from the
* server. This will only be called if the {@link TabCompleteEvent#cancel()} method was not called.
*
* @param event The event
*/
void onPostTabComplete(TabCompleteEvent.Post event);
/**
* Runs before and after whenever a chunk is either loaded, unloaded, or populated.
*

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.get() && (x == 0 || z == 0 || Math.abs(x) == Math.abs(z));
return y == BaritoneAPI.getSettings().axisHeight.value && (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.get() + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.get(), y);
return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.value + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.value, y);
}
@Override

View File

@ -17,6 +17,7 @@
package baritone.api.pathing.goals;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos;
import net.minecraft.util.math.BlockPos;
@ -30,17 +31,17 @@ public class GoalBlock implements Goal, IGoalRenderPos {
/**
* The X block position of this goal
*/
private final int x;
public final int x;
/**
* The Y block position of this goal
*/
private final int y;
public final int y;
/**
* The Z block position of this goal
*/
private final int z;
public final int z;
public GoalBlock(BlockPos pos) {
this(pos.getX(), pos.getY(), pos.getZ());
@ -67,7 +68,12 @@ public class GoalBlock implements Goal, IGoalRenderPos {
@Override
public String toString() {
return "GoalBlock{x=" + x + ",y=" + y + ",z=" + z + "}";
return String.format(
"GoalBlock{x=%s,y=%s,z=%s}",
SettingsUtil.maybeCensor(x),
SettingsUtil.maybeCensor(y),
SettingsUtil.maybeCensor(z)
);
}
/**

View File

@ -17,6 +17,7 @@
package baritone.api.pathing.goals;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos;
import net.minecraft.util.math.BlockPos;
@ -28,9 +29,9 @@ import net.minecraft.util.math.BlockPos;
*/
public class GoalGetToBlock implements Goal, IGoalRenderPos {
private final int x;
private final int y;
private final int z;
public final int x;
public final int y;
public final int z;
public GoalGetToBlock(BlockPos pos) {
this.x = pos.getX();
@ -61,6 +62,11 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
@Override
public String toString() {
return "GoalGetToBlock{x=" + x + ",y=" + y + ",z=" + z + "}";
return String.format(
"GoalGetToBlock{x=%s,y=%s,z=%s}",
SettingsUtil.maybeCensor(x),
SettingsUtil.maybeCensor(y),
SettingsUtil.maybeCensor(z)
);
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.pathing.goals;
/**
* Invert any goal.
* <p>
* In the old chat control system, #invert just tried to pick a {@link GoalRunAway} that <i>effectively</i> inverted the
* current goal. This goal just reverses the heuristic to act as a TRUE invert. Inverting a Y level? Baritone tries to
* get away from that Y level. Inverting a GoalBlock? Baritone will try to make distance whether it's in the X, Y or Z
* directions. And of course, you can always invert a GoalXZ.
*
* @author LoganDark
*/
public class GoalInverted implements Goal {
public final Goal origin;
public GoalInverted(Goal origin) {
this.origin = origin;
}
@Override
public boolean isInGoal(int x, int y, int z) {
return false;
}
@Override
public double heuristic(int x, int y, int z) {
return -origin.heuristic(x, y, z);
}
@Override
public String toString() {
return String.format("GoalInverted{%s}", origin.toString());
}
}

View File

@ -17,10 +17,12 @@
package baritone.api.pathing.goals;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos;
import net.minecraft.util.math.BlockPos;
public class GoalNear implements Goal, IGoalRenderPos {
private final int x;
private final int y;
private final int z;
@ -56,11 +58,12 @@ public class GoalNear implements Goal, IGoalRenderPos {
@Override
public String toString() {
return "GoalNear{" +
"x=" + x +
", y=" + y +
", z=" + z +
", rangeSq=" + rangeSq +
'}';
return String.format(
"GoalNear{x=%s, y=%s, z=%s, rangeSq=%d}",
SettingsUtil.maybeCensor(x),
SettingsUtil.maybeCensor(y),
SettingsUtil.maybeCensor(z),
rangeSq
);
}
}

View File

@ -17,6 +17,7 @@
package baritone.api.pathing.goals;
import baritone.api.utils.SettingsUtil;
import net.minecraft.util.math.BlockPos;
import java.util.Arrays;
@ -82,7 +83,11 @@ public class GoalRunAway implements Goal {
@Override
public String toString() {
if (maintainY != null) {
return "GoalRunAwayFromMaintainY y=" + maintainY + ", " + Arrays.asList(from);
return String.format(
"GoalRunAwayFromMaintainY y=%s, %s",
SettingsUtil.maybeCensor(maintainY),
Arrays.asList(from)
);
} else {
return "GoalRunAwayFrom" + Arrays.asList(from);
}

View File

@ -0,0 +1,78 @@
/*
* 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 baritone.api.utils.SettingsUtil;
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 String.format(
"GoalStrictDirection{x=%s, y=%s, z=%s, dx=%s, dz=%s}",
SettingsUtil.maybeCensor(x),
SettingsUtil.maybeCensor(y),
SettingsUtil.maybeCensor(z),
SettingsUtil.maybeCensor(dx),
SettingsUtil.maybeCensor(dz)
);
}
}

View File

@ -17,6 +17,7 @@
package baritone.api.pathing.goals;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos;
import net.minecraft.util.math.BlockPos;
@ -31,17 +32,17 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
/**
* The X block position of this goal
*/
private final int x;
protected final int x;
/**
* The Y block position of this goal
*/
private final int y;
protected final int y;
/**
* The Z block position of this goal
*/
private final int z;
protected final int z;
public GoalTwoBlocks(BlockPos pos) {
this(pos.getX(), pos.getY(), pos.getZ());
@ -73,6 +74,11 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
@Override
public String toString() {
return "GoalTwoBlocks{x=" + x + ",y=" + y + ",z=" + z + "}";
return String.format(
"GoalTwoBlocks{x=%s,y=%s,z=%s}",
SettingsUtil.maybeCensor(x),
SettingsUtil.maybeCensor(y),
SettingsUtil.maybeCensor(z)
);
}
}

View File

@ -18,6 +18,8 @@
package baritone.api.pathing.goals;
import baritone.api.BaritoneAPI;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
@ -45,6 +47,11 @@ public class GoalXZ implements Goal {
this.z = z;
}
public GoalXZ(BetterBlockPos pos) {
this.x = pos.x;
this.z = pos.z;
}
@Override
public boolean isInGoal(int x, int y, int z) {
return x == this.x && z == this.z;
@ -59,7 +66,11 @@ public class GoalXZ implements Goal {
@Override
public String toString() {
return "GoalXZ{x=" + x + ",z=" + z + "}";
return String.format(
"GoalXZ{x=%s,z=%s}",
SettingsUtil.maybeCensor(x),
SettingsUtil.maybeCensor(z)
);
}
public static double calculate(double xDiff, double zDiff) {
@ -80,14 +91,14 @@ public class GoalXZ implements Goal {
diagonal = z;
}
diagonal *= SQRT_2;
return (diagonal + straight) * BaritoneAPI.getSettings().costHeuristic.get(); // big TODO tune
return (diagonal + straight) * BaritoneAPI.getSettings().costHeuristic.value; // big TODO tune
}
public static GoalXZ fromDirection(Vec3d origin, float yaw, double distance) {
float theta = (float) Math.toRadians(yaw);
double x = origin.x - MathHelper.sin(theta) * distance;
double z = origin.z + MathHelper.cos(theta) * distance;
return new GoalXZ((int) x, (int) z);
return new GoalXZ(MathHelper.floor(x), MathHelper.floor(z));
}
public int getX() {

View File

@ -18,6 +18,7 @@
package baritone.api.pathing.goals;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.SettingsUtil;
/**
* Useful for mining (getting to diamond / iron level)
@ -29,7 +30,7 @@ public class GoalYLevel implements Goal, ActionCosts {
/**
* The target Y level
*/
private final int level;
public final int level;
public GoalYLevel(int level) {
this.level = level;
@ -59,6 +60,9 @@ public class GoalYLevel implements Goal, ActionCosts {
@Override
public String toString() {
return "GoalYLevel{y=" + level + "}";
return String.format(
"GoalYLevel{y=%s}",
SettingsUtil.maybeCensor(level)
);
}
}

View File

@ -45,10 +45,6 @@ public interface IMovement {
*/
boolean safeToCancel();
double recalculateCost();
double calculateCostWithoutCaching();
boolean calculatedWhileLoaded();
BetterBlockPos getSrc();

View File

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

View File

@ -25,8 +25,8 @@ import baritone.api.event.events.PathEvent;
* <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>
* <li>Only one baritone process can be active at a time</li>
* <li>PathingBehavior can only be controlled by a process</li>
* </ul>
* <p>
* That's it actually
@ -35,6 +35,16 @@ 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?
*
@ -82,12 +92,23 @@ public interface IBaritoneProcess {
*
* @return A double representing the priority
*/
double priority();
default double priority() {
return DEFAULT_PRIORITY;
}
/**
* Returns a user-friendly name for this process. Suitable for a HUD.
*
* @return A display name that's suitable for a HUD
*/
String displayName();
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();
}

View File

@ -0,0 +1,75 @@
/*
* 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.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import java.io.File;
import java.util.List;
/**
* @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 buildOpenSchematic();
void pause();
boolean isPaused();
void resume();
void clearArea(BlockPos corner1, BlockPos corner2);
/**
* @return A list of block states that are estimated to be placeable by this builder process. You can use this in
* schematics, for example, to pick a state that the builder process will be happy with, because any variation will
* cause it to give up. This is updated every tick, but only while the builder process is active.
*/
List<IBlockState> getApproxPlaceable();
}

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 baritone.api.process;
import java.nio.file.Path;
public interface IExploreProcess extends IBaritoneProcess {
void explore(int centerX, int centerZ);
void applyJsonFilter(Path path, boolean invert) throws Exception;
}

View File

@ -0,0 +1,23 @@
/*
* 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;
public interface IFarmProcess extends IBaritoneProcess {
void farm();
}

View File

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

View File

@ -17,8 +17,12 @@
package baritone.api.process;
import baritone.api.utils.BlockOptionalMeta;
import baritone.api.utils.BlockOptionalMetaLookup;
import net.minecraft.block.Block;
import java.util.stream.Stream;
/**
* @author Brady
* @since 9/23/2018
@ -28,9 +32,9 @@ public interface IMineProcess extends IBaritoneProcess {
/**
* Begin to search for and mine the specified blocks until
* the number of specified items to get from the blocks that
* are mined. This is based on the first target block to mine.
* are mined.
*
* @param quantity The number of items to get from blocks mined
* @param quantity The total number of items to get
* @param blocks The blocks to mine
*/
void mineByName(int quantity, String... blocks);
@ -41,9 +45,18 @@ public interface IMineProcess extends IBaritoneProcess {
* are mined. This is based on the first target block to mine.
*
* @param quantity The number of items to get from blocks mined
* @param blocks The blocks to mine
* @param filter The blocks to mine
*/
void mine(int quantity, Block... blocks);
void mine(int quantity, BlockOptionalMetaLookup filter);
/**
* Begin to search for and mine the specified blocks.
*
* @param filter The blocks to mine
*/
default void mine(BlockOptionalMetaLookup filter) {
mine(0, filter);
}
/**
* Begin to search for and mine the specified blocks.
@ -54,6 +67,38 @@ public interface IMineProcess extends IBaritoneProcess {
mineByName(0, blocks);
}
/**
* Begin to search for and mine the specified blocks.
*
* @param boms The blocks to mine
*/
default void mine(int quantity, BlockOptionalMeta... boms) {
mine(quantity, new BlockOptionalMetaLookup(boms));
}
/**
* Begin to search for and mine the specified blocks.
*
* @param boms The blocks to mine
*/
default void mine(BlockOptionalMeta... boms) {
mine(0, boms);
}
/**
* Begin to search for and mine the specified blocks.
*
* @param quantity The total number of items to get
* @param blocks The blocks to mine
*/
default void mine(int quantity, Block... blocks) {
mine(quantity, new BlockOptionalMetaLookup(
Stream.of(blocks)
.map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new)
));
}
/**
* Begin to search for and mine the specified blocks.
*

View File

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

View File

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

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 baritone.api.schematic;
import baritone.api.utils.ISchematic;
public abstract class AbstractSchematic implements ISchematic {
protected int x;
protected int y;
protected int z;
public AbstractSchematic(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
@Override
public int widthX() {
return x;
}
@Override
public int heightY() {
return y;
}
@Override
public int lengthZ() {
return z;
}
}

View File

@ -0,0 +1,75 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic;
import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState;
import java.util.ArrayList;
import java.util.List;
public class CompositeSchematic extends AbstractSchematic {
private final List<CompositeSchematicEntry> schematics;
private CompositeSchematicEntry[] schematicArr;
private void recalcArr() {
schematicArr = schematics.toArray(new CompositeSchematicEntry[0]);
for (CompositeSchematicEntry entry : schematicArr) {
this.x = Math.max(x, entry.x + entry.schematic.widthX());
this.y = Math.max(y, entry.y + entry.schematic.heightY());
this.z = Math.max(z, entry.z + entry.schematic.lengthZ());
}
}
public CompositeSchematic(int x, int y, int z) {
super(x, y, z);
schematics = new ArrayList<>();
recalcArr();
}
public void put(ISchematic extra, int x, int y, int z) {
schematics.add(new CompositeSchematicEntry(extra, x, y, z));
recalcArr();
}
private CompositeSchematicEntry getSchematic(int x, int y, int z, IBlockState currentState) {
for (CompositeSchematicEntry entry : schematicArr) {
if (x >= entry.x && y >= entry.y && z >= entry.z &&
entry.schematic.inSchematic(x - entry.x, y - entry.y, z - entry.z, currentState)) {
return entry;
}
}
return null;
}
@Override
public boolean inSchematic(int x, int y, int z, IBlockState currentState) {
CompositeSchematicEntry entry = getSchematic(x, y, z, currentState);
return entry != null && entry.schematic.inSchematic(x - entry.x, y - entry.y, z - entry.z, currentState);
}
@Override
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
CompositeSchematicEntry entry = getSchematic(x, y, z, current);
if (entry == null) {
throw new IllegalStateException("couldn't find schematic for this position");
}
return entry.schematic.desiredState(x - entry.x, y - entry.y, z - entry.z, current, approxPlaceable);
}
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic;
import baritone.api.utils.ISchematic;
public class CompositeSchematicEntry {
public final ISchematic schematic;
public final int x;
public final int y;
public final int z;
public CompositeSchematicEntry(ISchematic schematic, int x, int y, int z) {
this.schematic = schematic;
this.x = x;
this.y = y;
this.z = z;
}
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic;
import baritone.api.utils.BlockOptionalMeta;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import java.util.List;
public class FillSchematic extends AbstractSchematic {
private final BlockOptionalMeta bom;
public FillSchematic(int x, int y, int z, BlockOptionalMeta bom) {
super(x, y, z);
this.bom = bom;
}
public BlockOptionalMeta getBom() {
return bom;
}
@Override
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
if (bom.matches(current)) {
return current;
} else if (current.getBlock() != Blocks.AIR) {
return Blocks.AIR.getDefaultState();
}
for (IBlockState placeable : approxPlaceable) {
if (bom.matches(placeable)) {
return placeable;
}
}
return bom.getAnyBlockState();
}
}

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.api.schematic;
import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState;
import java.util.List;
public abstract class MaskSchematic extends AbstractSchematic {
private final ISchematic schematic;
public MaskSchematic(ISchematic schematic) {
super(schematic.widthX(), schematic.heightY(), schematic.lengthZ());
this.schematic = schematic;
}
protected abstract boolean partOfMask(int x, int y, int z, IBlockState currentState);
@Override
public boolean inSchematic(int x, int y, int z, IBlockState currentState) {
return schematic.inSchematic(x, y, z, currentState) && partOfMask(x, y, z, currentState);
}
@Override
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
return schematic.desiredState(x, y, z, current, approxPlaceable);
}
}

View File

@ -0,0 +1,42 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic;
import baritone.api.utils.BlockOptionalMetaLookup;
import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState;
public class ReplaceSchematic extends MaskSchematic {
private final BlockOptionalMetaLookup filter;
private final Boolean[][][] cache;
public ReplaceSchematic(ISchematic schematic, BlockOptionalMetaLookup filter) {
super(schematic);
this.filter = filter;
this.cache = new Boolean[widthX()][heightY()][lengthZ()];
}
@Override
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {
if (cache[x][y][z] == null) {
cache[x][y][z] = filter.has(currentState);
}
return cache[x][y][z];
}
}

View File

@ -0,0 +1,33 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic;
import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState;
public class ShellSchematic extends MaskSchematic {
public ShellSchematic(ISchematic schematic) {
super(schematic);
}
@Override
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {
return x == 0 || y == 0 || z == 0 || x == widthX() - 1 || y == heightY() - 1 || z == lengthZ() - 1;
}
}

View File

@ -0,0 +1,33 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic;
import baritone.api.utils.ISchematic;
import net.minecraft.block.state.IBlockState;
public class WallsSchematic extends MaskSchematic {
public WallsSchematic(ISchematic schematic) {
super(schematic);
}
@Override
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {
return x == 0 || z == 0 || x == widthX() - 1 || z == lengthZ() - 1;
}
}

View File

@ -0,0 +1,91 @@
/*
* 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.selection;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3i;
/**
* A selection is an immutable object representing the current selection. The selection is commonly used for certain
* types of build commands, however it can be used for anything.
*/
public interface ISelection {
/**
* @return The first corner of this selection. This is meant to preserve the user's original first corner.
*/
BetterBlockPos pos1();
/**
* @return The second corner of this selection. This is meant to preserve the user's original second corner.
*/
BetterBlockPos pos2();
/**
* @return The {@link BetterBlockPos} with the lowest x, y, and z position in the selection.
*/
BetterBlockPos min();
/**
* @return The opposite corner from the {@link #min()}.
*/
BetterBlockPos max();
/**
* @return The size of this ISelection.
*/
Vec3i size();
/**
* @return An {@link AxisAlignedBB} encompassing all blocks in this selection.
*/
AxisAlignedBB aabb();
/**
* Returns a new {@link ISelection} expanded in the specified direction by the specified number of blocks.
*
* @param direction The direction to expand the selection.
* @param blocks How many blocks to expand it.
* @return A new selection, expanded as specified.
*/
ISelection expand(EnumFacing direction, int blocks);
/**
* Returns a new {@link ISelection} contracted in the specified direction by the specified number of blocks.
* <p>
* Note that, for example, if the direction specified is UP, the bottom of the selection will be shifted up. If it
* is DOWN, the top of the selection will be shifted down.
*
* @param direction The direction to contract the selection.
* @param blocks How many blocks to contract it.
* @return A new selection, contracted as specified.
*/
ISelection contract(EnumFacing direction, int blocks);
/**
* Returns a new {@link ISelection} shifted in the specified direction by the specified number of blocks. This moves
* the whole selection.
*
* @param direction The direction to shift the selection.
* @param blocks How many blocks to shift it.
* @return A new selection, shifted as specified.
*/
ISelection shift(EnumFacing direction, int blocks);
}

View File

@ -0,0 +1,116 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.selection;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.EnumFacing;
/**
* The selection manager handles setting Baritone's selections. You can set the selection here, as well as retrieving
* the current selection.
*/
public interface ISelectionManager {
/**
* Adds a new selection. The added selection is returned.
*
* @param selection The new selection to add.
*/
ISelection addSelection(ISelection selection);
/**
* Adds a new {@link ISelection} constructed from the given block positions. The new selection is returned.
*
* @param pos1 One corner of the selection
* @param pos2 The new corner of the selection
*/
ISelection addSelection(BetterBlockPos pos1, BetterBlockPos pos2);
/**
* Removes the selection from the current selections.
*
* @param selection The selection to remove.
* @return The removed selection.
*/
ISelection removeSelection(ISelection selection);
/**
* Removes all selections.
*
* @return The selections that were removed, sorted from oldest to newest..
*/
ISelection[] removeAllSelections();
/**
* @return The current selections, sorted from oldest to newest.
*/
ISelection[] getSelections();
/**
* For anything expecting only one selection, this method is provided. However, to enforce multi-selection support,
* this method will only return a selection if there is ONLY one.
*
* @return The only selection, or null if there isn't only one.
*/
ISelection getOnlySelection();
/**
* This method will always return the last selection. ONLY use this if you want to, for example, modify the most
* recent selection based on user input. ALWAYS use {@link #getOnlySelection()} or, ideally,
* {@link #getSelections()} for retrieving the content of selections.
*
* @return The last selection, or null if it doesn't exist.
*/
ISelection getLastSelection();
/**
* Replaces the specified {@link ISelection} with one expanded in the specified direction by the specified number of
* blocks. Returns the new selection.
*
* @param selection The selection to expand.
* @param direction The direction to expand the selection.
* @param blocks How many blocks to expand it.
* @return The new selection, expanded as specified.
*/
ISelection expand(ISelection selection, EnumFacing direction, int blocks);
/**
* Replaces the specified {@link ISelection} with one contracted in the specified direction by the specified number
* of blocks.
* <p>
* Note that, for example, if the direction specified is UP, the bottom of the selection will be shifted up. If it
* is DOWN, the top of the selection will be shifted down.
*
* @param selection The selection to contract.
* @param direction The direction to contract the selection.
* @param blocks How many blocks to contract it.
* @return The new selection, contracted as specified.
*/
ISelection contract(ISelection selection, EnumFacing direction, int blocks);
/**
* Replaces the specified {@link ISelection} with one shifted in the specified direction by the specified number of
* blocks. This moves the whole selection.
*
* @param selection The selection to shift.
* @param direction The direction to shift the selection.
* @param blocks How many blocks to shift it.
* @return The new selection, shifted as specified.
*/
ISelection shift(ISelection selection, EnumFacing direction, int blocks);
}

View File

@ -22,6 +22,8 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3i;
import javax.annotation.Nonnull;
/**
* A better BlockPos that has fewer hash collisions (and slightly more performant offsets)
* <p>
@ -32,6 +34,9 @@ import net.minecraft.util.math.Vec3i;
* @author leijurv
*/
public final class BetterBlockPos extends BlockPos {
public static final BetterBlockPos ORIGIN = new BetterBlockPos(0, 0, 0);
public final int x;
public final int y;
public final int z;
@ -51,6 +56,20 @@ public final class BetterBlockPos extends BlockPos {
this(pos.getX(), pos.getY(), pos.getZ());
}
/**
* Like constructor but returns null if pos is null, good if you just need to possibly censor coordinates
*
* @param pos The BlockPos, possibly null, to convert
* @return A BetterBlockPos or null if pos was null
*/
public static BetterBlockPos from(BlockPos pos) {
if (pos == null) {
return null;
}
return new BetterBlockPos(pos);
}
@Override
public int hashCode() {
return (int) longHash(x, y, z);
@ -61,6 +80,8 @@ 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)
*
@ -180,4 +201,15 @@ public final class BetterBlockPos extends BlockPos {
public BetterBlockPos west(int amt) {
return amt == 0 ? this : new BetterBlockPos(x - amt, y, z);
}
@Override
@Nonnull
public String toString() {
return String.format(
"BetterBlockPos{x=%s,y=%s,z=%s}",
SettingsUtil.maybeCensor(x),
SettingsUtil.maybeCensor(y),
SettingsUtil.maybeCensor(z)
);
}
}

View File

@ -0,0 +1,299 @@
/*
* 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.accessor.IItemStack;
import com.google.common.collect.ImmutableSet;
import net.minecraft.block.*;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.function.Consumer;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public final class BlockOptionalMeta {
private final Block block;
private final int meta;
private final boolean noMeta;
private final Set<IBlockState> blockstates;
private final ImmutableSet<Integer> stateHashes;
private final ImmutableSet<Integer> stackHashes;
private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$");
private static final Map<Object, Object> normalizations;
public BlockOptionalMeta(@Nonnull Block block, @Nullable Integer meta) {
this.block = block;
this.noMeta = meta == null;
this.meta = noMeta ? 0 : meta;
this.blockstates = getStates(block, meta);
this.stateHashes = getStateHashes(blockstates);
this.stackHashes = getStackHashes(blockstates);
}
public BlockOptionalMeta(@Nonnull Block block) {
this(block, null);
}
public BlockOptionalMeta(@Nonnull String selector) {
Matcher matcher = pattern.matcher(selector);
if (!matcher.find()) {
throw new IllegalArgumentException("invalid block selector");
}
MatchResult matchResult = matcher.toMatchResult();
noMeta = matchResult.group(2) == null;
ResourceLocation id = new ResourceLocation(matchResult.group(1));
if (!Block.REGISTRY.containsKey(id)) {
throw new IllegalArgumentException("Invalid block ID");
}
block = Block.REGISTRY.getObject(id);
meta = noMeta ? 0 : Integer.parseInt(matchResult.group(2));
blockstates = getStates(block, getMeta());
stateHashes = getStateHashes(blockstates);
stackHashes = getStackHashes(blockstates);
}
static {
Map<Object, Object> _normalizations = new HashMap<>();
Consumer<Enum> put = instance -> _normalizations.put(instance.getClass(), instance);
put.accept(EnumFacing.NORTH);
put.accept(EnumFacing.Axis.Y);
put.accept(BlockLog.EnumAxis.Y);
put.accept(BlockStairs.EnumHalf.BOTTOM);
put.accept(BlockStairs.EnumShape.STRAIGHT);
put.accept(BlockLever.EnumOrientation.DOWN_X);
put.accept(BlockDoublePlant.EnumBlockHalf.LOWER);
put.accept(BlockSlab.EnumBlockHalf.BOTTOM);
put.accept(BlockDoor.EnumDoorHalf.LOWER);
put.accept(BlockDoor.EnumHingePosition.LEFT);
put.accept(BlockBed.EnumPartType.HEAD);
put.accept(BlockRailBase.EnumRailDirection.NORTH_SOUTH);
put.accept(BlockTrapDoor.DoorHalf.BOTTOM);
_normalizations.put(BlockBanner.ROTATION, 0);
_normalizations.put(BlockBed.OCCUPIED, false);
_normalizations.put(BlockBrewingStand.HAS_BOTTLE[0], false);
_normalizations.put(BlockBrewingStand.HAS_BOTTLE[1], false);
_normalizations.put(BlockBrewingStand.HAS_BOTTLE[2], false);
_normalizations.put(BlockButton.POWERED, false);
// _normalizations.put(BlockCactus.AGE, 0);
// _normalizations.put(BlockCauldron.LEVEL, 0);
// _normalizations.put(BlockChorusFlower.AGE, 0);
_normalizations.put(BlockChorusPlant.NORTH, false);
_normalizations.put(BlockChorusPlant.EAST, false);
_normalizations.put(BlockChorusPlant.SOUTH, false);
_normalizations.put(BlockChorusPlant.WEST, false);
_normalizations.put(BlockChorusPlant.UP, false);
_normalizations.put(BlockChorusPlant.DOWN, false);
// _normalizations.put(BlockCocoa.AGE, 0);
// _normalizations.put(BlockCrops.AGE, 0);
_normalizations.put(BlockDirt.SNOWY, false);
_normalizations.put(BlockDoor.OPEN, false);
_normalizations.put(BlockDoor.POWERED, false);
// _normalizations.put(BlockFarmland.MOISTURE, 0);
_normalizations.put(BlockFence.NORTH, false);
_normalizations.put(BlockFence.EAST, false);
_normalizations.put(BlockFence.WEST, false);
_normalizations.put(BlockFence.SOUTH, false);
// _normalizations.put(BlockFenceGate.POWERED, false);
// _normalizations.put(BlockFenceGate.IN_WALL, false);
_normalizations.put(BlockFire.AGE, 0);
_normalizations.put(BlockFire.NORTH, false);
_normalizations.put(BlockFire.EAST, false);
_normalizations.put(BlockFire.SOUTH, false);
_normalizations.put(BlockFire.WEST, false);
_normalizations.put(BlockFire.UPPER, false);
// _normalizations.put(BlockFrostedIce.AGE, 0);
_normalizations.put(BlockGrass.SNOWY, false);
// _normalizations.put(BlockHopper.ENABLED, true);
// _normalizations.put(BlockLever.POWERED, false);
// _normalizations.put(BlockLiquid.LEVEL, 0);
// _normalizations.put(BlockMycelium.SNOWY, false);
// _normalizations.put(BlockNetherWart.AGE, false);
_normalizations.put(BlockLeaves.CHECK_DECAY, false);
// _normalizations.put(BlockLeaves.DECAYABLE, false);
// _normalizations.put(BlockObserver.POWERED, false);
_normalizations.put(BlockPane.NORTH, false);
_normalizations.put(BlockPane.EAST, false);
_normalizations.put(BlockPane.WEST, false);
_normalizations.put(BlockPane.SOUTH, false);
// _normalizations.put(BlockPistonBase.EXTENDED, false);
// _normalizations.put(BlockPressurePlate.POWERED, false);
// _normalizations.put(BlockPressurePlateWeighted.POWER, false);
_normalizations.put(BlockQuartz.EnumType.LINES_X, BlockQuartz.EnumType.LINES_Y);
_normalizations.put(BlockQuartz.EnumType.LINES_Z, BlockQuartz.EnumType.LINES_Y);
// _normalizations.put(BlockRailDetector.POWERED, false);
// _normalizations.put(BlockRailPowered.POWERED, false);
_normalizations.put(BlockRedstoneWire.NORTH, false);
_normalizations.put(BlockRedstoneWire.EAST, false);
_normalizations.put(BlockRedstoneWire.SOUTH, false);
_normalizations.put(BlockRedstoneWire.WEST, false);
// _normalizations.put(BlockReed.AGE, false);
_normalizations.put(BlockSapling.STAGE, 0);
_normalizations.put(BlockSkull.NODROP, false);
_normalizations.put(BlockStandingSign.ROTATION, 0);
_normalizations.put(BlockStem.AGE, 0);
_normalizations.put(BlockTripWire.NORTH, false);
_normalizations.put(BlockTripWire.EAST, false);
_normalizations.put(BlockTripWire.WEST, false);
_normalizations.put(BlockTripWire.SOUTH, false);
_normalizations.put(BlockVine.NORTH, false);
_normalizations.put(BlockVine.EAST, false);
_normalizations.put(BlockVine.SOUTH, false);
_normalizations.put(BlockVine.WEST, false);
_normalizations.put(BlockVine.UP, false);
_normalizations.put(BlockWall.UP, false);
_normalizations.put(BlockWall.NORTH, false);
_normalizations.put(BlockWall.EAST, false);
_normalizations.put(BlockWall.WEST, false);
_normalizations.put(BlockWall.SOUTH, false);
normalizations = Collections.unmodifiableMap(_normalizations);
}
private static <C extends Comparable<C>, P extends IProperty<C>> P castToIProperty(Object value) {
//noinspection unchecked
return (P) value;
}
private static <C extends Comparable<C>, P extends IProperty<C>> C castToIPropertyValue(P iproperty, Object value) {
//noinspection unchecked
return (C) value;
}
public static IBlockState normalize(IBlockState state) {
IBlockState newState = state;
for (IProperty<?> property : state.getProperties().keySet()) {
Class<?> valueClass = property.getValueClass();
if (normalizations.containsKey(property)) {
try {
newState = newState.withProperty(
castToIProperty(property),
castToIPropertyValue(property, normalizations.get(property))
);
} catch (IllegalArgumentException ignored) {}
} else if (normalizations.containsKey(state.getValue(property))) {
try {
newState = newState.withProperty(
castToIProperty(property),
castToIPropertyValue(property, normalizations.get(state.getValue(property)))
);
} catch (IllegalArgumentException ignored) {}
} else if (normalizations.containsKey(valueClass)) {
try {
newState = newState.withProperty(
castToIProperty(property),
castToIPropertyValue(property, normalizations.get(valueClass))
);
} catch (IllegalArgumentException ignored) {}
}
}
return newState;
}
public static int stateMeta(IBlockState state) {
return state.getBlock().getMetaFromState(normalize(state));
}
private static Set<IBlockState> getStates(@Nonnull Block block, @Nullable Integer meta) {
return block.getBlockState().getValidStates().stream()
.filter(blockstate -> meta == null || stateMeta(blockstate) == meta)
.collect(Collectors.toSet());
}
private static ImmutableSet<Integer> getStateHashes(Set<IBlockState> blockstates) {
return ImmutableSet.copyOf(
blockstates.stream()
.map(IBlockState::hashCode)
.toArray(Integer[]::new)
);
}
private static ImmutableSet<Integer> getStackHashes(Set<IBlockState> blockstates) {
//noinspection ConstantConditions
return ImmutableSet.copyOf(
blockstates.stream()
.map(state -> new ItemStack(
state.getBlock().getItemDropped(state, new Random(), 0),
state.getBlock().damageDropped(state)
))
.map(stack -> ((IItemStack) (Object) stack).getBaritoneHash())
.toArray(Integer[]::new)
);
}
public Block getBlock() {
return block;
}
public Integer getMeta() {
return noMeta ? null : meta;
}
public boolean matches(@Nonnull Block block) {
return block == this.block;
}
public boolean matches(@Nonnull IBlockState blockstate) {
Block block = blockstate.getBlock();
return block == this.block && stateHashes.contains(blockstate.hashCode());
}
public boolean matches(ItemStack stack) {
//noinspection ConstantConditions
int hash = ((IItemStack) (Object) stack).getBaritoneHash();
if (noMeta) {
hash -= stack.getItemDamage();
}
return stackHashes.contains(hash);
}
@Override
public String toString() {
return String.format("BlockOptionalMeta{block=%s,meta=%s}", block, getMeta());
}
public static IBlockState blockStateFromStack(ItemStack stack) {
//noinspection deprecation
return Block.getBlockFromItem(stack.getItem()).getStateFromMeta(stack.getMetadata());
}
public IBlockState getAnyBlockState() {
if (blockstates.size() > 0) {
return blockstates.iterator().next();
}
return null;
}
}

View File

@ -0,0 +1,95 @@
/*
* 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.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class BlockOptionalMetaLookup {
private final BlockOptionalMeta[] boms;
public BlockOptionalMetaLookup(BlockOptionalMeta... boms) {
this.boms = boms;
}
public BlockOptionalMetaLookup(Block... blocks) {
this.boms = Stream.of(blocks)
.map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new);
}
public BlockOptionalMetaLookup(List<Block> blocks) {
this.boms = blocks.stream()
.map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new);
}
public BlockOptionalMetaLookup(String... blocks) {
this.boms = Stream.of(blocks)
.map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new);
}
public boolean has(Block block) {
for (BlockOptionalMeta bom : boms) {
if (bom.getBlock() == block) {
return true;
}
}
return false;
}
public boolean has(IBlockState state) {
for (BlockOptionalMeta bom : boms) {
if (bom.matches(state)) {
return true;
}
}
return false;
}
public boolean has(ItemStack stack) {
for (BlockOptionalMeta bom : boms) {
if (bom.matches(stack)) {
return true;
}
}
return false;
}
public List<BlockOptionalMeta> blocks() {
return Arrays.asList(boms);
}
@Override
public String toString() {
return String.format(
"BlockOptionalMetaLookup{%s}",
Arrays.toString(boms)
);
}
}

View File

@ -0,0 +1,67 @@
/*
* 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;
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);
if (block == null) {
throw new IllegalArgumentException(String.format("Invalid block name %s", name));
}
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

@ -0,0 +1,111 @@
/*
* 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 net.minecraft.client.Minecraft;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import java.util.Arrays;
import java.util.stream.Stream;
/**
* @author Brady
* @since 8/1/2018
*/
public interface Helper {
/**
* Instance of {@link Helper}. Used for static-context reference.
*/
Helper HELPER = new Helper() {};
/**
* Instance of the game
*/
Minecraft mc = Minecraft.getMinecraft();
static ITextComponent getPrefix() {
// Inner text component
ITextComponent baritone = new TextComponentString(BaritoneAPI.getSettings().shortBaritonePrefix.value ? "B" : "Baritone");
baritone.getStyle().setColor(TextFormatting.LIGHT_PURPLE);
// Outer brackets
ITextComponent prefix = new TextComponentString("");
prefix.getStyle().setColor(TextFormatting.DARK_PURPLE);
prefix.appendText("[");
prefix.appendSibling(baritone);
prefix.appendText("]");
return prefix;
}
/**
* Send a message to chat only if chatDebug is on
*
* @param message The message to display in chat
*/
default void logDebug(String message) {
if (!BaritoneAPI.getSettings().chatDebug.value) {
//System.out.println("Suppressed debug message:");
//System.out.println(message);
return;
}
logDirect(message);
}
/**
* Send components to chat with the [Baritone] prefix
*
* @param components The components to send
*/
default void logDirect(ITextComponent... components) {
ITextComponent component = new TextComponentString("");
component.appendSibling(getPrefix());
component.appendSibling(new TextComponentString(" "));
Arrays.asList(components).forEach(component::appendSibling);
Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component));
}
/**
* Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a
* direct response to a chat command)
*
* @param message The message to display in chat
* @param color The color to print that message in
*/
default void logDirect(String message, TextFormatting color) {
Stream.of(message.split("\n")).forEach(line -> {
ITextComponent component = new TextComponentString(line.replace("\t", " "));
component.getStyle().setColor(color);
logDirect(component);
});
}
/**
* Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a
* direct response to a chat command)
*
* @param message The message to display in chat
*/
default void logDirect(String message) {
logDirect(message, TextFormatting.GRAY);
}
}

View File

@ -19,7 +19,6 @@ package baritone.api.utils;
import baritone.api.behavior.IBehavior;
import baritone.api.utils.input.Input;
import net.minecraft.client.settings.KeyBinding;
/**
* @author Brady
@ -27,8 +26,6 @@ import net.minecraft.client.settings.KeyBinding;
*/
public interface IInputOverrideHandler extends IBehavior {
Boolean isInputForcedDown(KeyBinding key);
boolean isInputForcedDown(Input input);
void setInputForceState(Input input, boolean forced);

View File

@ -49,9 +49,21 @@ public interface IPlayerContext {
default BetterBlockPos playerFeet() {
// TODO find a better way to deal with soul sand!!!!!
BetterBlockPos feet = new BetterBlockPos(player().posX, player().posY + 0.1251, player().posZ);
if (world().getBlockState(feet).getBlock() instanceof BlockSlab) {
return feet.up();
}
// sometimes when calling this from another thread or while world is null, it'll throw a NullPointerException
// that causes the game to immediately crash
//
// so of course crashing on 2b is horribly bad due to queue times and logout spot
// catch the NPE and ignore it if it does happen
//
// this does not impact performance at all since we're not null checking constantly
// if there is an exception, the only overhead is Java generating the exception object... so we can ignore it
try {
if (world().getBlockState(feet).getBlock() instanceof BlockSlab) {
return feet.up();
}
} catch (NullPointerException ignored) {}
return feet;
}
@ -73,20 +85,26 @@ public interface IPlayerContext {
* @return The position of the highlighted block
*/
default Optional<BlockPos> getSelectedBlock() {
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(objectMouseOver().getBlockPos());
RayTraceResult result = objectMouseOver();
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(result.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() {
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(objectMouseOver().entityHit);
RayTraceResult result = objectMouseOver();
if (result != null && result.typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(result.entityHit);
}
return Optional.empty();
}

View File

@ -17,13 +17,17 @@
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.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameType;
import net.minecraft.world.World;
/**
* @author Brady
@ -31,6 +35,10 @@ import net.minecraft.world.GameType;
*/
public interface IPlayerController {
void syncHeldItem();
boolean hasBrokenBlock();
boolean onPlayerDamageBlock(BlockPos pos, EnumFacing side);
void resetBlockRemoving();
@ -41,7 +49,13 @@ public interface IPlayerController {
GameType getGameType();
RayTraceResult objectMouseOver();
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);
EnumActionResult processRightClick(EntityPlayerSP player, World world, EnumHand hand);
boolean clickBlock(BlockPos loc, EnumFacing face);
void setHittingBlock(boolean hittingBlock);
default double getBlockReachDistance() {
return this.getGameType().isCreative() ? 5.0F : 4.5F;

View File

@ -0,0 +1,90 @@
/*
* 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;
import java.util.List;
/**
* Basic representation of a schematic. Provides the dimensions and the desired state for 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
* @param currentState The current state of that block in the world, or null
* @return Whether or not the specified position is within the bounds of this schematic
*/
default boolean inSchematic(int x, int y, int z, IBlockState currentState) {
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
* @param current The current state of that block in the world, or null
* @param approxPlaceable The list of blockstates estimated to be placeable
* @return The desired block state at the specified position
*/
IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable);
/**
* @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

@ -0,0 +1,37 @@
/*
* 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 com.google.gson.annotations.SerializedName;
/**
* Need a non obfed chunkpos that we can load using GSON
*/
public class MyChunkPos {
@SerializedName("x")
public int x;
@SerializedName("z")
public int z;
@Override
public String toString() {
return x + ", " + z;
}
}

View File

@ -117,8 +117,12 @@ public class Rotation {
* @return are they really close
*/
public boolean isReallyCloseTo(Rotation other) {
float yawDiff = Math.abs(this.yaw - other.yaw); // you cant fool me
return (yawDiff < 0.01 || yawDiff > 359.9) && Math.abs(this.pitch - other.pitch) < 0.01;
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);
}
/**
@ -147,4 +151,9 @@ public class Rotation {
}
return newYaw;
}
@Override
public String toString() {
return "Yaw: " + yaw + ", Pitch: " + pitch;
}
}

View File

@ -78,6 +78,9 @@ 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);
}
@ -102,7 +105,7 @@ public final class RotationUtils {
* @param dest The destination position
* @return The rotation from the origin to the destination
*/
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
private 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]);
@ -151,7 +154,7 @@ public final class RotationUtils {
*/
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
if (pos.equals(baritone.getPlayerContext().getSelectedBlock().orElse(null))) {
if (baritone.getPlayerContext().isLookingAt(pos)) {
/*
* why add 0.0001?
* to indicate that we actually have a desired pitch
@ -196,7 +199,7 @@ public final class RotationUtils {
* @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);
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
//System.out.println(result);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {

View File

@ -17,20 +17,25 @@
package baritone.api.utils;
import baritone.api.BaritoneAPI;
import baritone.api.Settings;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.Vec3i;
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.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Matcher;
@ -43,9 +48,7 @@ import static net.minecraft.client.Minecraft.getMinecraft;
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>[^ ]+)"); // 2 words separated by spaces
private static final Map<Class<?>, SettingsIO> map;
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
private static boolean isComment(String line) {
return line.startsWith("#") || line.startsWith("//");
@ -81,6 +84,8 @@ public class SettingsUtil {
ex.printStackTrace();
}
});
} 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();
@ -89,22 +94,8 @@ public class SettingsUtil {
public static synchronized void save(Settings settings) {
try (BufferedWriter out = Files.newBufferedWriter(SETTINGS_PATH)) {
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");
for (Settings.Setting setting : modifiedSettings(settings)) {
out.write(settingToString(setting) + "\n");
}
} catch (Exception ex) {
System.out.println("Exception thrown while saving Baritone settings!");
@ -112,51 +103,207 @@ public class SettingsUtil {
}
}
private static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
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;
}
/**
* Gets the type of a setting and returns it as a string, with package names stripped.
* <p>
* For example, if the setting type is {@code java.util.List<java.lang.String>}, this function returns
* {@code List<String>}.
*
* @param setting The setting
* @return The type
*/
public static String settingTypeToString(Settings.Setting setting) {
return setting.getType().getTypeName()
.replaceAll("(?:\\w+\\.)+(\\w+)", "$1");
}
public static <T> String settingValueToString(Settings.Setting<T> setting, T value) throws IllegalArgumentException {
Parser io = Parser.getParser(setting.getType());
if (io == null) {
throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting.getName());
}
return io.toString(new ParserContext(setting), value);
}
public static String settingValueToString(Settings.Setting setting) throws IllegalArgumentException {
//noinspection unchecked
return settingValueToString(setting, setting.value);
}
public static String settingDefaultToString(Settings.Setting setting) throws IllegalArgumentException {
//noinspection unchecked
return settingValueToString(setting, setting.defaultValue);
}
public static String maybeCensor(int coord) {
if (BaritoneAPI.getSettings().censorCoordinates.value) {
return "<censored>";
}
return Integer.toString(coord);
}
public static String settingToString(Settings.Setting setting) throws IllegalStateException {
if (setting.getName().equals("logger")) {
return "logger";
}
return setting.getName() + " " + settingValueToString(setting);
}
public 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();
SettingsIO ioMethod = map.get(intendedType);
Object parsed = ioMethod.parser.apply(settingValue);
ISettingParser ioMethod = Parser.getParser(setting.getType());
Object parsed = ioMethod.parse(new ParserContext(setting), 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 enum SettingsIO {
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 {
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),
STRING(String.class, String::new),
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);
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());
return Stream.of(raw.split(","))
.map(s -> parser.parse(context, s))
.collect(Collectors.toList());
}
@Override
public String toString(ParserContext context, Object value) {
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
Parser parser = Parser.getParser(type);
Class<?> klass;
Function<String, Object> parser;
Function<Object, String> toString;
return ((List<?>) value).stream()
.map(o -> parser.toString(context, o))
.collect(Collectors.joining(","));
}
<T> SettingsIO(Class<T> klass, Function<String, T> parser) {
this(klass, parser, Object::toString);
@Override
public boolean accepts(Type type) {
return List.class.isAssignableFrom(TypeUtils.resolveBaseClass(type));
}
};
private final Class<?> cla$$;
private final Function<String, Object> parser;
private final Function<Object, String> toString;
Parser() {
this.cla$$ = null;
this.parser = null;
this.toString = null;
}
<T> SettingsIO(Class<T> klass, Function<String, T> parser, Function<T, String> toString) {
this.klass = klass;
<T> Parser(Class<T> cla$$, Function<String, T> parser) {
this(cla$$, parser, Object::toString);
}
<T> Parser(Class<T> cla$$, Function<String, T> parser, Function<T, String> toString) {
this.cla$$ = cla$$;
this.parser = parser::apply;
this.toString = x -> toString.apply((T) x);
}
}
static {
HashMap<Class<?>, SettingsIO> tempMap = new HashMap<>();
for (SettingsIO type : SettingsIO.values()) {
tempMap.put(type.klass, type);
@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.cla$$.isAssignableFrom((Class) type);
}
public static Parser getParser(Type type) {
return Stream.of(values())
.filter(parser -> parser.accepts(type))
.findFirst().orElse(null);
}
map = Collections.unmodifiableMap(tempMap);
}
}

View File

@ -0,0 +1,44 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.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

@ -0,0 +1,86 @@
/*
* 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.command;
import baritone.api.IBaritone;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.arguments.IArgConsumer;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public abstract class Command implements Helper {
protected IBaritone baritone;
protected IPlayerContext ctx;
/**
* The names of this command. This is what you put after the command prefix.
*/
public final List<String> names;
/**
* Creates a new Baritone control command.
*
* @param names The names of this command. This is what you put after the command prefix.
*/
protected Command(IBaritone baritone, List<String> names) {
this.names = names.stream()
.map(s -> s.toLowerCase(Locale.US))
.collect(Collectors.toList());
this.baritone = baritone;
this.ctx = baritone.getPlayerContext();
}
protected Command(IBaritone baritone, String name) {
this(baritone, Collections.singletonList(name));
}
/**
* Called when this command is executed.
*/
public abstract void execute(String label, IArgConsumer args) throws CommandException;
/**
* Called when the command needs to tab complete. Return a Stream representing the entries to put in the completions
* list.
*/
public abstract Stream<String> tabComplete(String label, IArgConsumer args) throws CommandException;
/**
* @return A <b>single-line</b> string containing a short description of this command's purpose.
*/
public abstract String getShortDesc();
/**
* @return A list of lines that will be printed by the help command when the user wishes to view them.
*/
public abstract List<String> getLongDesc();
/**
* @return {@code true} if this command should be hidden from the help menu
*/
public boolean hiddenFromHelp() {
return false;
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.command;
import baritone.api.Settings;
import java.util.UUID;
/**
* @author Brady
* @since 9/26/2019
*/
public interface IBaritoneChatControl {
/**
* In certain cases chat components need to execute commands for you. For example, the paginator automatically runs
* commands when you click the forward and back arrows to show you the previous/next page.
* <p>
* If the prefix is changed in the meantime, then the command will go to chat. That's no good. So here's a permanent
* prefix that forces a command to run, regardless of the current prefix, chat/prefix control being enabled, etc.
* <p>
* If used right (by both developers and users), it should be impossible to expose a command accidentally to the
* server. As a rule of thumb, if you have a clickable chat component, always use this prefix. If you're suggesting
* a command (a component that puts text into your text box, or something else), use {@link Settings#prefix}.
*/
String FORCE_COMMAND_PREFIX = String.format("<<%s>>", UUID.randomUUID().toString());
}

View File

@ -0,0 +1,104 @@
/*
* 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.command.argparser;
import baritone.api.utils.command.argument.ICommandArgument;
import baritone.api.utils.command.exception.CommandInvalidTypeException;
import baritone.api.utils.command.exception.CommandNoParserForTypeException;
import baritone.api.utils.command.registry.Registry;
public class ArgParserManager {
public static final Registry<IArgParser> REGISTRY = new Registry<>();
static {
DefaultArgParsers.ALL.forEach(REGISTRY::register);
}
/**
* @param type The type trying to be parsed
* @return A parser that can parse arguments into this class, if found.
*/
public static <T> IArgParser.Stateless<T> getParserStateless(Class<T> type) {
//noinspection unchecked
return REGISTRY.descendingStream()
.filter(IArgParser.Stateless.class::isInstance)
.map(IArgParser.Stateless.class::cast)
.filter(parser -> parser.getTarget().isAssignableFrom(type))
.findFirst()
.orElse(null);
}
/**
* @param type The type trying to be parsed
* @return A parser that can parse arguments into this class, if found.
*/
public static <T, S> IArgParser.Stated<T, S> getParserStated(Class<T> type, Class<S> stateKlass) {
//noinspection unchecked
return REGISTRY.descendingStream()
.filter(IArgParser.Stated.class::isInstance)
.map(IArgParser.Stated.class::cast)
.filter(parser -> parser.getTarget().isAssignableFrom(type))
.filter(parser -> parser.getStateType().isAssignableFrom(stateKlass))
.map(IArgParser.Stated.class::cast)
.findFirst()
.orElse(null);
}
/**
* Attempt to parse the specified argument with a stateless {@link IArgParser} that outputs the specified class.
*
* @param type The type to try and parse the argument into.
* @param arg The argument to parse.
* @return An instance of the specified class.
* @throws CommandInvalidTypeException If the parsing failed
*/
public static <T> T parseStateless(Class<T> type, ICommandArgument arg) throws CommandInvalidTypeException {
IArgParser.Stateless<T> parser = getParserStateless(type);
if (parser == null) {
throw new CommandNoParserForTypeException(type);
}
try {
return parser.parseArg(arg);
} catch (Exception exc) {
throw new CommandInvalidTypeException(arg, type.getSimpleName());
}
}
/**
* Attempt to parse the specified argument with a stated {@link IArgParser} that outputs the specified class.
*
* @param type The type to try and parse the argument into.
* @param arg The argument to parse.
* @param state The state to pass to the {@link IArgParser.Stated}.
* @return An instance of the specified class.
* @throws CommandInvalidTypeException If the parsing failed
* @see IArgParser.Stated
*/
public static <T, S> T parseStated(Class<T> type, Class<S> stateKlass, ICommandArgument arg, S state) throws CommandInvalidTypeException {
IArgParser.Stated<T, S> parser = getParserStated(type, stateKlass);
if (parser == null) {
throw new CommandNoParserForTypeException(type);
}
try {
return parser.parseArg(arg, state);
} catch (Exception exc) {
throw new CommandInvalidTypeException(arg, type.getSimpleName());
}
}
}

View File

@ -0,0 +1,123 @@
/*
* 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.command.argparser;
import baritone.api.utils.command.argument.ICommandArgument;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
public class DefaultArgParsers {
public enum IntArgumentParser implements IArgParser.Stateless<Integer> {
INSTANCE;
@Override
public Class<Integer> getTarget() {
return Integer.class;
}
@Override
public Integer parseArg(ICommandArgument arg) throws RuntimeException {
return Integer.parseInt(arg.getValue());
}
}
public enum LongArgumentParser implements IArgParser.Stateless<Long> {
INSTANCE;
@Override
public Class<Long> getTarget() {
return Long.class;
}
@Override
public Long parseArg(ICommandArgument arg) throws RuntimeException {
return Long.parseLong(arg.getValue());
}
}
public enum FloatArgumentParser implements IArgParser.Stateless<Float> {
INSTANCE;
@Override
public Class<Float> getTarget() {
return Float.class;
}
@Override
public Float parseArg(ICommandArgument arg) throws RuntimeException {
String value = arg.getValue();
if (!value.matches("^([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)|)$")) {
throw new IllegalArgumentException("failed float format check");
}
return Float.parseFloat(value);
}
}
public enum DoubleArgumentParser implements IArgParser.Stateless<Double> {
INSTANCE;
@Override
public Class<Double> getTarget() {
return Double.class;
}
@Override
public Double parseArg(ICommandArgument arg) throws RuntimeException {
String value = arg.getValue();
if (!value.matches("^([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)|)$")) {
throw new IllegalArgumentException("failed double format check");
}
return Double.parseDouble(value);
}
}
public static class BooleanArgumentParser implements IArgParser.Stateless<Boolean> {
public static final BooleanArgumentParser INSTANCE = new BooleanArgumentParser();
public static final List<String> TRUTHY_VALUES = Arrays.asList("1", "true", "yes", "t", "y", "on", "enable");
public static final List<String> FALSY_VALUES = Arrays.asList("0", "false", "no", "f", "n", "off", "disable");
@Override
public Class<Boolean> getTarget() {
return Boolean.class;
}
@Override
public Boolean parseArg(ICommandArgument arg) throws RuntimeException {
String value = arg.getValue();
if (TRUTHY_VALUES.contains(value.toLowerCase(Locale.US))) {
return true;
} else if (FALSY_VALUES.contains(value.toLowerCase(Locale.US))) {
return false;
} else {
throw new IllegalArgumentException("invalid boolean");
}
}
}
public static final List<IArgParser<?>> ALL = Arrays.asList(
IntArgumentParser.INSTANCE,
LongArgumentParser.INSTANCE,
FloatArgumentParser.INSTANCE,
DoubleArgumentParser.INSTANCE,
BooleanArgumentParser.INSTANCE
);
}

View File

@ -0,0 +1,64 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils.command.argparser;
import baritone.api.utils.command.argument.ICommandArgument;
public interface IArgParser<T> {
/**
* @return the class of this parser.
*/
Class<T> getTarget();
/**
* A stateless argument parser is just that. It takes a {@link ICommandArgument} and outputs its type.
*
* @see ArgParserManager#REGISTRY
*/
interface Stateless<T> extends IArgParser<T> {
/**
* @param arg The argument to parse.
* @return What it was parsed into.
* @throws RuntimeException if you want the parsing to fail. The exception will be caught and turned into an
* appropriate error.
*/
T parseArg(ICommandArgument arg) throws Exception;
}
/**
* A stated argument parser is similar to a stateless one. It also takes a {@link ICommandArgument}, but it also
* takes a second argument that can be any type, referred to as the state.
*
* @see ArgParserManager#REGISTRY
*/
interface Stated<T, S> extends IArgParser<T> {
Class<S> getStateType();
/**
* @param arg The argument to parse.
* @param state Can be anything.
* @return What it was parsed into.
* @throws RuntimeException if you want the parsing to fail. The exception will be caught and turned into an
* appropriate error.
*/
T parseArg(ICommandArgument arg, S state) throws Exception;
}
}

View File

@ -0,0 +1,102 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils.command.argument;
import baritone.api.utils.command.argparser.IArgParser;
import baritone.api.utils.command.exception.CommandInvalidTypeException;
import baritone.api.utils.command.helpers.arguments.IArgConsumer;
import net.minecraft.util.EnumFacing;
/**
* A {@link ICommandArgument} is an immutable object representing one command argument. It contains data on the index of
* that argument, its value, and the rest of the string that argument was found in
* <p>
* You're recommended to use {@link IArgConsumer}}s to handle these.
*
* @author Brady
* @since 10/2/2019
*/
public interface ICommandArgument {
/**
* @return The index of this command argument in the list of command arguments generated
*/
int getIndex();
/**
* @return The raw value of just this argument
*/
String getValue();
/**
* @return The raw value of the remaining arguments after this one was captured
*/
String getRawRest();
/**
* Gets an enum value from the enum class with the same name as this argument's value
* <p>
* For example if you getEnum as an {@link EnumFacing}, and this argument's value is "up", it will return {@link
* EnumFacing#UP}
*
* @param enumClass The enum class to search
* @return An enum constant of that class with the same name as this argument's value
* @throws CommandInvalidTypeException If the constant couldn't be found
* @see IArgConsumer#peekEnum(Class)
* @see IArgConsumer#peekEnum(Class, int)
* @see IArgConsumer#peekEnumOrNull(Class)
* @see IArgConsumer#peekEnumOrNull(Class, int)
* @see IArgConsumer#getEnum(Class)
* @see IArgConsumer#getEnumOrNull(Class)
*/
<E extends Enum<?>> E getEnum(Class<E> enumClass) throws CommandInvalidTypeException;
/**
* Tries to use a <b>stateless</b> {@link IArgParser} to parse this argument into the specified class
*
* @param type The class to parse this argument into
* @return An instance of the specified type
* @throws CommandInvalidTypeException If the parsing failed
*/
<T> T getAs(Class<T> type) throws CommandInvalidTypeException;
/**
* Tries to use a <b>stateless</b> {@link IArgParser} to parse this argument into the specified class
*
* @param type The class to parse this argument into
* @return If the parser succeeded
*/
<T> boolean is(Class<T> type);
/**
* Tries to use a <b>stated</b> {@link IArgParser} to parse this argument into the specified class
*
* @param type The class to parse this argument into
* @return An instance of the specified type
* @throws CommandInvalidTypeException If the parsing failed
*/
<T, S> T getAs(Class<T> type, Class<S> stateType, S state) throws CommandInvalidTypeException;
/**
* Tries to use a <b>stated</b> {@link IArgParser} to parse this argument into the specified class
*
* @param type The class to parse this argument into
* @return If the parser succeeded
*/
<T, S> boolean is(Class<T> type, Class<S> stateType, S state);
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils.command.datatypes;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.util.ResourceLocation;
import java.util.stream.Stream;
public enum BlockById implements IDatatypeFor<Block> {
INSTANCE;
@Override
public Block get(IDatatypeContext ctx) throws CommandException {
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
Block block;
if ((block = Block.REGISTRY.getObject(id)) == Blocks.AIR) {
throw new IllegalArgumentException("no block found by that id");
}
return block;
}
@Override
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
return new TabCompleteHelper()
.append(
Block.REGISTRY.getKeys()
.stream()
.map(Object::toString)
)
.filterPrefixNamespaced(ctx.getConsumer().getString())
.sortAlphabetically()
.stream();
}
}

View File

@ -0,0 +1,49 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils.command.datatypes;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.util.ResourceLocation;
import java.util.stream.Stream;
public enum EntityClassById implements IDatatypeFor<Class<? extends Entity>> {
INSTANCE;
@Override
public Class<? extends Entity> get(IDatatypeContext ctx) throws CommandException {
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
Class<? extends Entity> entity;
if ((entity = EntityList.REGISTRY.getObject(id)) == null) {
throw new IllegalArgumentException("no entity found by that id");
}
return entity;
}
@Override
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
return new TabCompleteHelper()
.append(EntityList.getEntityNameList().stream().map(Object::toString))
.filterPrefixNamespaced(ctx.getConsumer().getString())
.sortAlphabetically()
.stream();
}
}

View File

@ -0,0 +1,37 @@
/*
* 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.command.datatypes;
import baritone.api.utils.BlockOptionalMeta;
import baritone.api.utils.command.exception.CommandException;
import java.util.stream.Stream;
public enum ForBlockOptionalMeta implements IDatatypeFor<BlockOptionalMeta> {
INSTANCE;
@Override
public BlockOptionalMeta get(IDatatypeContext ctx) throws CommandException {
return new BlockOptionalMeta(ctx.getConsumer().getString());
}
@Override
public Stream<String> tabComplete(IDatatypeContext ctx) {
return ctx.getConsumer().tabCompleteDatatype(BlockById.INSTANCE);
}
}

View File

@ -0,0 +1,43 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils.command.datatypes;
import baritone.api.utils.command.exception.CommandException;
import baritone.api.utils.command.helpers.tabcomplete.TabCompleteHelper;
import net.minecraft.util.EnumFacing;
import java.util.Locale;
import java.util.stream.Stream;
public enum ForEnumFacing implements IDatatypeFor<EnumFacing> {
INSTANCE;
@Override
public EnumFacing get(IDatatypeContext ctx) throws CommandException {
return EnumFacing.valueOf(ctx.getConsumer().getString().toUpperCase(Locale.US));
}
@Override
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
return new TabCompleteHelper()
.append(Stream.of(EnumFacing.values())
.map(EnumFacing::getName).map(String::toLowerCase))
.filterPrefix(ctx.getConsumer().getString())
.stream();
}
}

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