Compare commits
115 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc68493dc2 | ||
|
|
6a1f716dc8 | ||
|
|
e9b9977674 | ||
|
|
3f65d46e12 | ||
|
|
15fd313757 | ||
|
|
f41c873852 | ||
|
|
eb8a673165 | ||
|
|
2a830b6b68 | ||
|
|
fc620f8ba8 | ||
|
|
e7658b75ef | ||
|
|
b9a7efc25b | ||
|
|
3b7f13babd | ||
|
|
520142427d | ||
|
|
ebe3f457c6 | ||
|
|
6289e540b8 | ||
|
|
399037b866 | ||
|
|
50783e65a9 | ||
|
|
f7041022d0 | ||
|
|
dd76d2eabc | ||
|
|
e3d3407de5 | ||
|
|
f3d860e8fa | ||
|
|
1edd7126fd | ||
|
|
a57668bd15 | ||
|
|
a324b58f55 | ||
|
|
105c7d438a | ||
|
|
1c00e167ca | ||
|
|
861ee5049a | ||
|
|
c1fe588de4 | ||
|
|
8fa2dac261 | ||
|
|
f0ae31f455 | ||
|
|
dc7d64fb88 | ||
|
|
62df244db7 | ||
|
|
2b4d6f4aa0 | ||
|
|
7e505fc68f | ||
|
|
9c323aba91 | ||
|
|
ae9671bff0 | ||
|
|
d256f05787 | ||
|
|
a9ba05bf5e | ||
|
|
7c9b812a5b | ||
|
|
a8226ba4c8 | ||
|
|
e34b2d1392 | ||
|
|
de6e96b952 | ||
|
|
9dd6856872 | ||
|
|
ed4753e968 | ||
|
|
1a4635df16 | ||
|
|
1390af20b6 | ||
|
|
1427cf57a8 | ||
|
|
d70243b4c0 | ||
|
|
8f63dd4ba6 | ||
|
|
c7e1c917c3 | ||
|
|
125facfbb6 | ||
|
|
16b74ff53c | ||
|
|
9297e98ac3 | ||
|
|
b521d7bee1 | ||
|
|
4e96c5e5ee | ||
|
|
ec819220b7 | ||
|
|
3d3a5f420e | ||
|
|
9c9c9d4387 | ||
|
|
82d09a536d | ||
|
|
6e49adea33 | ||
|
|
f85afdbc70 | ||
|
|
563028a5b3 | ||
|
|
d5c317b88b | ||
|
|
c59ec9da10 | ||
|
|
3a675836da | ||
|
|
7e0fc81246 | ||
|
|
f970f932c7 | ||
|
|
52d2741f52 | ||
|
|
7bc6765cac | ||
|
|
85b2aea6e9 | ||
|
|
c6ba5481d9 | ||
|
|
81f47d5632 | ||
|
|
9b1440ed2c | ||
|
|
2a8dcee028 | ||
|
|
277ba3643c | ||
|
|
e5fbaf60f3 | ||
|
|
0deb854e1b | ||
|
|
8268e3ec1b | ||
|
|
af91da6a28 | ||
|
|
9a15a65ad5 | ||
|
|
0cbe9f81c8 | ||
|
|
42afd2dd54 | ||
|
|
315929f31c | ||
|
|
358aa80280 | ||
|
|
1dd9e11994 | ||
|
|
5a8f02c944 | ||
|
|
f248a5b677 | ||
|
|
e4a49c5529 | ||
|
|
449b44ba50 | ||
|
|
a00eec402e | ||
|
|
717779f742 | ||
|
|
6f843bd24d | ||
|
|
d79fbea433 | ||
|
|
4d22c10ddb | ||
|
|
1ea92a6092 | ||
|
|
66eba84d06 | ||
|
|
92e39b5d1d | ||
|
|
0ddc47f473 | ||
|
|
ddfeca6947 | ||
|
|
6bd2e90cfd | ||
|
|
82505ddb01 | ||
|
|
2790d1d308 | ||
|
|
11e503a022 | ||
|
|
6fe49380ba | ||
|
|
1f2e267e3d | ||
|
|
4cf6783622 | ||
|
|
82d77a7bac | ||
|
|
841a927033 | ||
|
|
5a16561954 | ||
|
|
e2cc51908b | ||
|
|
1390e04435 | ||
|
|
84d961cbab | ||
|
|
87b9d3915c | ||
|
|
c38d17563d | ||
|
|
0c2af85ac0 |
2
.github/ISSUE_TEMPLATE/bug.md
vendored
2
.github/ISSUE_TEMPLATE/bug.md
vendored
@@ -11,7 +11,7 @@ Operating system:
|
||||
Java version:
|
||||
Minecraft version:
|
||||
Baritone version:
|
||||
Other mods (if used):
|
||||
Forge mods (if used):
|
||||
|
||||
## Exception, error or logs
|
||||
Please find your `latest.log` or `debug.log` in this folder and attach it to the issue
|
||||
|
||||
39
.github/workflows/gradle_build.yml
vendored
39
.github/workflows/gradle_build.yml
vendored
@@ -1,39 +0,0 @@
|
||||
# This workflow will build a Java project with Gradle
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Java CI with Gradle
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 8
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '8'
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Archive Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Artifacts
|
||||
path: dist/
|
||||
|
||||
- name: Archive mapping.txt
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Mappings
|
||||
path: build/tmp/proguard/mapping.txt
|
||||
26
.github/workflows/run_tests.yml
vendored
26
.github/workflows/run_tests.yml
vendored
@@ -1,26 +0,0 @@
|
||||
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 8
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '8'
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Executing tests
|
||||
run: ./gradlew test
|
||||
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -11,6 +11,8 @@ build/
|
||||
classes/
|
||||
*.class
|
||||
|
||||
/out
|
||||
|
||||
# IntelliJ Files
|
||||
.idea/
|
||||
*.iml
|
||||
@@ -18,15 +20,6 @@ classes/
|
||||
*.iws
|
||||
/logs/
|
||||
|
||||
# Eclipse Files
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
baritone_Client.launch
|
||||
|
||||
# Copyright Files
|
||||
!/.idea/copyright/Baritone.xml
|
||||
!/.idea/copyright/profiles_settings.xml
|
||||
|
||||
.vscode/launch.json
|
||||
|
||||
|
||||
28
.travis.yml
Normal file
28
.travis.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
language: java
|
||||
|
||||
sudo: required
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
install:
|
||||
- travis_retry docker build -t cabaletta/baritone .
|
||||
|
||||
script:
|
||||
- docker run --name baritone cabaletta/baritone ./gradlew javadoc
|
||||
- docker cp baritone:/code/dist dist
|
||||
- ls dist
|
||||
- cat dist/checksums.txt
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: YOuiXoJNpB4bW89TQoY2IGXg0tqOKls55YMXsSPU6Mx8WzRu8CjjO/A8KA9nGfNrKM+NucjiKr/h53O2Dp2uyy0i0SLvav/G0MaBMeB1NlPRwFopi6tVPNaoZsvr8NW4BIURhspckYLpOTYWnfmOkIv8q7AxrjUZWPKDlq0dte20UxEqUE6msHJ7U9XlKo/4fX40kvWMfwGI2hTyAtL0cRT1QPsd+uW3OQjAPcQj+jKaWld46V8pBK8g9Qde9mo8HC9NBv97zw1bBF1EFkynW569kElHvaS2Opl2QLGaf66guDbpnqDpGHMhQrDdxsZHJ4RksyITn+8A9UArmbkU35BxKqBeQqOWxod2+M0axdLh1pvX43Q1t9n7RiZBf7GvV8vkXL5Sjf8v6Y4LqkJGhvQkTUwpH+0knwrE761DMCtBC34AiWG70D4u7msmhurkflr9kmRHSj/3lyJ1Q2lkt8L+FOAlQBVs64vXTsfgc6Yge7N0O3UD5hCkrDNoz3BzhNBdCkbdxdKCGip71UZgUNkPy9o3ui8jATNj9ypx3+U8ovqP0XWlJqUZmyeXyNGW9NrLeCkRLTlLnZ/dv6OPONa1oAu4TwF1w5A+TGRFZcZjH/PnZKZDQ1OYQOR6drLKRYdr2unvuf5KUKUGqZ7aYtLGhP0rBvGWddRV7DSmX/s=
|
||||
all_branches: true
|
||||
file_glob: true
|
||||
file:
|
||||
- dist/*
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
repo: cabaletta/baritone
|
||||
128
README.md
128
README.md
@@ -1,127 +1 @@
|
||||
# Baritone
|
||||
<p align="center">
|
||||
<a href="https://github.com/cabaletta/baritone/releases/"><img src="https://img.shields.io/github/downloads/cabaletta/baritone/total.svg" alt="GitHub All Releases"/></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/cabaletta/baritone/tree/master"><img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.13.2"><img src="https://img.shields.io/badge/MC-1.13.2-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.14.4"><img src="https://img.shields.io/badge/MC-1.14.4-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.15.2"><img src="https://img.shields.io/badge/MC-1.15.2-yellow.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.16.5"><img src="https://img.shields.io/badge/MC-1.16.5-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.17.1"><img src="https://img.shields.io/badge/MC-1.17.1-brightgreen.svg" alt="Minecraft"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/tree/1.18.2"><img src="https://img.shields.io/badge/MC-1.18.2-brightgreen.svg" alt="Minecraft"/></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.com/cabaletta/baritone/"><img src="https://travis-ci.com/cabaletta/baritone.svg?branch=master" alt="Build Status"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/releases/"><img src="https://img.shields.io/github/release/cabaletta/baritone.svg" alt="Release"/></a>
|
||||
<a href="LICENSE"><img src="https://img.shields.io/badge/license-LGPL--3.0%20with%20anime%20exception-green.svg" alt="License"/></a>
|
||||
<a href="https://www.codacy.com/gh/cabaletta/baritone/dashboard?utm_source=github.com&utm_medium=referral&utm_content=cabaletta/baritone&utm_campaign=Badge_Grade"><img src="https://app.codacy.com/project/badge/Grade/cadab857dab049438b6e28b3cfc5570e" alt="Codacy Badge"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/blob/master/CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/%E2%9D%A4-code%20of%20conduct-blue.svg?style=flat" alt="Code of Conduct"/></a>
|
||||
<a href="https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle"><img src="https://snyk.io/test/github/cabaletta/baritone/badge.svg?targetFile=build.gradle" alt="Known Vulnerabilities"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/issues/"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="Contributions welcome"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/issues/"><img src="https://img.shields.io/github/issues/cabaletta/baritone.svg" alt="Issues"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/cabaletta/baritone.svg" alt="GitHub issues-closed"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/pulls/"><img src="https://img.shields.io/github/issues-pr/cabaletta/baritone.svg" alt="Pull Requests"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/graphs/contributors/"><img src="https://img.shields.io/github/contributors/cabaletta/baritone.svg" alt="GitHub contributors"/></a>
|
||||
<a href="https://github.com/cabaletta/baritone/commit/"><img src="https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg" alt="GitHub commits"/></a>
|
||||
<img src="https://img.shields.io/github/languages/code-size/cabaletta/baritone.svg" alt="Code size"/>
|
||||
<img src="https://img.shields.io/github/repo-size/cabaletta/baritone.svg" alt="GitHub repo size"/>
|
||||
<img src="https://tokei.rs/b1/github/cabaletta/baritone?category=code" alt="Lines of Code"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://impactclient.net/"><img src="https://img.shields.io/badge/Impact%20integration-v1.2.14%20/%20v1.3.8%20/%20v1.4.6%20/%20v1.5.3%20/%20v1.6.3-brightgreen.svg" alt="Impact integration"/></a>
|
||||
<a href="https://github.com/kami-blue/client"><img src="https://img.shields.io/badge/KAMI%20Blue%20integration-v1.2.14--master-green" alt="KAMI Blue integration"/></a>
|
||||
<a href="https://github.com/fr1kin/ForgeHax/"><img src="https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg" alt="ForgeHax integration"/></a>
|
||||
<a href="https://aristois.net/"><img src="https://img.shields.io/badge/Aristois%20add--on%20integration-v1.6.3-green.svg" alt="Aristois add-on integration"/></a>
|
||||
<a href="https://rootnet.dev/"><img src="https://img.shields.io/badge/rootNET%20integration-v1.2.14-green.svg" alt="rootNET integration"/></a>
|
||||
<a href="https://futureclient.net/"><img src="https://img.shields.io/badge/Future%20integration-v1.2.12%20%2F%20v1.3.6%20%2F%20v1.4.4-red" alt="Future integration"/></a>
|
||||
<a href="https://rusherhack.org/"><img src="https://img.shields.io/badge/RusherHack%20integration-v1.2.14-green" alt="RusherHack integration"/></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="http://forthebadge.com/"><img src="https://forthebadge.com/images/badges/built-with-swag.svg" alt="forthebadge"/></a>
|
||||
<a href="http://forthebadge.com/"><img src="https://forthebadge.com/images/badges/mom-made-pizza-rolls.svg" alt="forthebadge"/></a>
|
||||
</p>
|
||||
|
||||
A Minecraft pathfinder bot.
|
||||
|
||||
[**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr)
|
||||
|
||||
Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#0730 on Baritone which I recommend. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do.
|
||||
|
||||
[Tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa)
|
||||
|
||||
The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to install the v1.2.* `api-forge` jar from [releases](https://github.com/cabaletta/baritone/releases). **For 1.12.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.2.15/baritone-api-forge-1.2.15.jar)**. Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
|
||||
|
||||
For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. If you need Forge or Fabric 1.16.5, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.6.3) and get the `api-forge` or `api-fabric` jar. **For 1.16.5 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.6.3/baritone-api-fabric-1.6.3.jar)**.
|
||||
|
||||
If you need Forge or Fabric 1.17.1, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.7.2) and get the `api-forge` or `api-fabric` jar. **For 1.17.1 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.7.2/baritone-api-fabric-1.7.2.jar)**.
|
||||
|
||||
If you need Forge or Fabric 1.18.2, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.8.3) and get the `api-forge` or `api-fabric` jar. **For 1.18.2 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-fabric-1.8.3.jar)**. **For 1.18.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-forge-1.8.3.jar)**.
|
||||
|
||||
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
|
||||
the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 onwards. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
|
||||
|
||||
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 & setup](SETUP.md)
|
||||
|
||||
- [API Javadocs](https://baritone.leijurv.com/)
|
||||
|
||||
- [Settings](https://baritone.leijurv.com/baritone/api/Settings.html#field.detail)
|
||||
|
||||
- [Usage (chat control)](USAGE.md)
|
||||
|
||||
## Stars over time
|
||||
|
||||
[](https://starchart.cc/cabaletta/baritone)
|
||||
|
||||
# API
|
||||
|
||||
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.
|
||||
|
||||
Below is an example of basic usage for changing some settings, and then pathing to an X/Z goal.
|
||||
|
||||
```java
|
||||
BaritoneAPI.getSettings().allowSprint.value = true;
|
||||
BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L;
|
||||
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
|
||||
```
|
||||
|
||||
# FAQ
|
||||
|
||||
## Can I use Baritone as a library in my custom utility client?
|
||||
|
||||
That's what it's for, sure! (As long as usage complies with the LGPL 3.0 License)
|
||||
|
||||
## How is it so fast?
|
||||
|
||||
Magic. (Hours of [leijurv](https://github.com/leijurv/) enduring excruciating pain)
|
||||
|
||||
### Additional Special Thanks To:
|
||||
|
||||

|
||||
|
||||
YourKit supports open source projects with innovative and intelligent tools for monitoring and profiling Java and .NET applications.
|
||||
|
||||
YourKit is the creator of the [YourKit Java Profiler](https://www.yourkit.com/java/profiler/), [YourKit .NET Profiler](https://www.yourkit.com/.net/profiler/), and [YourKit YouMonitor](https://www.yourkit.com/youmonitor/).
|
||||
|
||||
We thank them for granting Baritone an OSS license so that we can make our software the best it can be.
|
||||
|
||||
## Why is it called Baritone?
|
||||
|
||||
It's named for FitMC's deep sultry voice.
|
||||
This branch of Baritone is deprecated. It will no longer recieve updates. Updates to older versions of Minecraft will not be merged into this branch, even if a newer branch is not deprecated (this branch will be skipped). Bug reports that only affect deprecated branches will not be addressed.
|
||||
30
SETUP.md
30
SETUP.md
@@ -2,7 +2,7 @@
|
||||
|
||||
The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone.
|
||||
|
||||
You can also use a custom version json for Minecraft, with the [1.14.4](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1) version or the [1.15.2](https://www.dropbox.com/s/8rx6f0kts9hvd4f/1.15.2-Baritone.zip?dl=1) version or the [1.16.5](https://www.dropbox.com/s/i6f292o2i7o9acp/1.16.5-Baritone.zip?dl=1) version.
|
||||
You can also use a custom version json for Minecraft, with the [1.14.4](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1) version or the [1.15.2](https://www.dropbox.com/s/8rx6f0kts9hvd4f/1.15.2-Baritone.zip?dl=1) version
|
||||
|
||||
Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
|
||||
|
||||
@@ -11,9 +11,9 @@ These releases are not always completely up to date with latest features, and ar
|
||||
|
||||
Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
|
||||
|
||||
v1.2.* is for 1.12.2, v1.3.* is for 1.13.2, v1.4.* is for 1.14.4, v1.5.* is for 1.15.2, v1.6.* is for 1.16.5, v1.7.* is for 1.17.1, v1.8.* is for 1.18.1
|
||||
v1.2.* is for 1.12.2, v1.3.* is for 1.13.2
|
||||
|
||||
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by that public keys of `checksums.txt`.
|
||||
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).
|
||||
|
||||
@@ -22,16 +22,20 @@ The build is fully deterministic and reproducible, and you can verify Travis did
|
||||
|
||||
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 and Fabric releases can simply be added as a Forge/Fabric mods.**
|
||||
**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/Fabric API**: Same as API, but packaged for Forge/Fabric. This should be used where another mod has a Baritone integration.
|
||||
- **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/Fabric Standalone**: Same as Standalone, but packaged for Forge/Fabric. This should be used when Baritone is your only Forge/Fabric mod, or none of your other Forge/Fabric mods integrate with Baritone.
|
||||
- **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.
|
||||
- **Forge/Fabric Unoptimized**: Same as Unoptimized, but packaged for Forge/Fabric.
|
||||
|
||||
## 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
|
||||
@@ -43,13 +47,13 @@ If another one of your Forge mods has a Baritone integration, you want `baritone
|
||||
## Command Line
|
||||
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
|
||||
|
||||
If you have errors with a package missing please make sure you have setup your environment, and are using Oracle JDK 8 for 1.12.2-1.16.5, JDK 16 for 1.17.1, and JDK 17 for 1.18.1.
|
||||
If you have errors with a package missing please make sure you have setup your environment, and are using Oracle JDK 8.
|
||||
|
||||
To check which java you are using do
|
||||
`java -version` in a command prompt or terminal.
|
||||
If you are using anything above OpenJDK 8 for 1.12.2-1.16.5, it might not work because the Java distributions above JDK 8 using may not have the needed javax classes.
|
||||
If you are using anything above OpenJDK 8, it might not work because the Java distributions above JDK 8 using may not have the needed javax classes.
|
||||
|
||||
Open JDK download: https://openjdk.java.net/install/
|
||||
Open JDK 8 download: https://openjdk.java.net/install/
|
||||
#### macOS guide
|
||||
In order to get JDK 8, Try running the following command:
|
||||
`% /usr/libexec/java_home -V`
|
||||
@@ -85,12 +89,6 @@ For minecraft 1.15.2+, run the following instead to include the Forge jars:
|
||||
$ gradlew build -Pbaritone.forge_build
|
||||
```
|
||||
|
||||
Do this instead for Fabric jars:
|
||||
|
||||
```
|
||||
$ gradlew build -Pbaritone.fabric_build
|
||||
```
|
||||
|
||||
Running Baritone:
|
||||
|
||||
```
|
||||
|
||||
18
USAGE.md
18
USAGE.md
@@ -32,13 +32,13 @@ Watch this [showcase video](https://youtu.be/CZkLXWo4Fg4)!
|
||||
|
||||
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`.
|
||||
|
||||
Commands in Baritone:
|
||||
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, `forcecancel` is also an option
|
||||
- `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 64 diamond_ore`.
|
||||
- `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 select an area (`#help sel` to see what you can do with that selection).
|
||||
@@ -47,23 +47,15 @@ Commands in Baritone:
|
||||
- `build` to build a schematic. `build blah.schematic` will load `schematics/blah.schematic` and build it with the origin being your player feet. `build blah.schematic 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 and make a tunnel, 1x2. It will only deviate from the straight line if necessary such as to avoid lava. For a dumber tunnel that is really just cleararea, you can `tunnel 3 2 100`, to clear an area 3 high, 2 wide, and 100 deep.
|
||||
- `farm` to automatically harvest, replant, or bone meal crops. Use `farm <range>` or `farm <range> <waypoint>` to limit the max distance from the starting point or a waypoint.
|
||||
- `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.
|
||||
- `come` tells Baritone to head towards your camera, useful when freecam doesn't move your player position.
|
||||
- `blacklist` will stop baritone from going to the closest block so it won't attempt to get to it.
|
||||
- `eta` to get information about the estimated time until the next segment and the goal, be aware that the ETA to your goal is really unprecise.
|
||||
- `proc` to view miscellaneous information about the process currently controlling Baritone.
|
||||
- `repack` to re-cache the chunks around you.
|
||||
- `gc` to call `System.gc()` which may free up some memory.
|
||||
- `render` to fix glitched chunk rendering without having to reload all of them.
|
||||
- `reloadall` to reload Baritone's world cache or `saveall` to save Baritone's world cache.
|
||||
- `find` to search through Baritone's cache and attempt to find the location of the block.
|
||||
- `surface` or `top` to tell Baritone to head towards the closest surface-like area, this can be the surface or highest available air space.
|
||||
- `version` to get the version of Baritone you're running
|
||||
- `damn` daniel
|
||||
|
||||
For the rest of the commands, you can take a look at the code [here](https://baritone.leijurv.com/baritone/api/Settings.html).
|
||||
|
||||
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.
|
||||
|
||||
108
build.gradle
108
build.gradle
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
group 'baritone'
|
||||
version '1.2.16'
|
||||
version '1.3.8'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
@@ -25,25 +25,24 @@ buildscript {
|
||||
url = 'http://files.minecraftforge.net/maven'
|
||||
}
|
||||
maven {
|
||||
name = 'SpongePowered'
|
||||
url = 'https://repo.spongepowered.org/repository/maven-public/'
|
||||
name = 'impactdevelopment-repo'
|
||||
url = 'https://impactdevelopment.github.io/maven/'
|
||||
}
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
|
||||
classpath group: 'com.github.ImpactDevelopment', name: 'ForgeGradle', version: '3.0.115'
|
||||
classpath group: 'com.github.ImpactDevelopment', name: 'MixinGradle', version: '0.6.2'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
import baritone.gradle.task.CreateDistTask
|
||||
import baritone.gradle.task.ProguardTask
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
|
||||
apply plugin: 'net.minecraftforge.gradle'
|
||||
apply plugin: 'org.spongepowered.mixin'
|
||||
|
||||
sourceCompatibility = targetCompatibility = '1.8'
|
||||
@@ -53,8 +52,19 @@ compileJava {
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
api {
|
||||
compileClasspath += main.compileClasspath
|
||||
}
|
||||
main {
|
||||
compileClasspath += api.output
|
||||
}
|
||||
test {
|
||||
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
}
|
||||
launch {
|
||||
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||
}
|
||||
|
||||
schematica_api {
|
||||
@@ -66,21 +76,58 @@ sourceSets {
|
||||
}
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = '1.12.2'
|
||||
mappings = 'stable_39'
|
||||
tweakClass = 'baritone.launch.BaritoneTweaker'
|
||||
runDir = 'run'
|
||||
task sourceJar(type: Jar, dependsOn: classes) {
|
||||
classifier = 'sources'
|
||||
from sourceSets.api.allSource
|
||||
}
|
||||
|
||||
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
|
||||
makeObfSourceJar = true
|
||||
minecraft {
|
||||
mappings channel: 'snapshot', version: '20190307-1.13.1'
|
||||
reobfMappings 'notch'
|
||||
|
||||
runs {
|
||||
client {
|
||||
workingDirectory project.file('run')
|
||||
source sourceSets.launch
|
||||
|
||||
main 'baritone.launch.LaunchTesting'
|
||||
|
||||
environment 'assetIndex', '{asset_index}'
|
||||
environment 'assetDirectory', downloadAssets.output
|
||||
environment 'nativesDirectory', extractNatives.output
|
||||
|
||||
environment 'tweakClass', 'baritone.launch.BaritoneTweaker'
|
||||
|
||||
if (Os.isFamily(Os.FAMILY_MAC)) {
|
||||
jvmArgs "-XstartOnFirstThread"
|
||||
}
|
||||
}
|
||||
|
||||
autoTest {
|
||||
workingDirectory project.file('autotest')
|
||||
source sourceSets.launch
|
||||
|
||||
main 'baritone.launch.LaunchTesting'
|
||||
|
||||
environment 'assetIndex', '{asset_index}'
|
||||
environment 'assetDirectory', downloadAssets.output
|
||||
environment 'nativesDirectory', extractNatives.output
|
||||
|
||||
environment 'tweakClass', 'baritone.launch.BaritoneTweaker'
|
||||
environment 'BARITONE_AUTO_TEST', 'true'
|
||||
|
||||
if (Os.isFamily(Os.FAMILY_MAC)) {
|
||||
jvmArgs "-XstartOnFirstThread"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
maven {
|
||||
name = 'spongepowered-repo'
|
||||
name = 'SpongePowered'
|
||||
url = 'https://repo.spongepowered.org/repository/maven-public/'
|
||||
}
|
||||
|
||||
@@ -91,6 +138,12 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft 'com.github.ImpactDevelopment:Vanilla:1.13.2'
|
||||
|
||||
runtime launchCompile('net.minecraft:launchwrapper:1.12') {
|
||||
exclude module: 'lwjgl'
|
||||
}
|
||||
runtime launchCompile('org.ow2.asm:asm-debug-all:5.2')
|
||||
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
|
||||
@@ -100,6 +153,7 @@ dependencies {
|
||||
exclude module: 'commons-io'
|
||||
exclude module: 'log4j-core'
|
||||
}
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
@@ -145,25 +199,3 @@ task proguard(type: ProguardTask) {
|
||||
task createDist(type: CreateDistTask, dependsOn: proguard)
|
||||
|
||||
build.finalizedBy(createDist)
|
||||
|
||||
install {
|
||||
def jarApiName = String.format("%s-api-%s", rootProject.name, version.toString())
|
||||
def jarApiForgeName = String.format("%s-api-forge-%s", rootProject.name, version.toString())
|
||||
def jarSAName = String.format("%s-standalone-%s", rootProject.name, version.toString())
|
||||
def jarSAForgeName = String.format("%s-standalone-forge-%s", rootProject.name, version.toString())
|
||||
|
||||
artifacts {
|
||||
archives file("$buildDir/libs/"+jarApiName+".jar")
|
||||
archives file("$buildDir/libs/"+jarApiForgeName+".jar")
|
||||
archives file("$buildDir/libs/"+jarSAName+".jar")
|
||||
archives file("$buildDir/libs/"+jarSAForgeName+".jar")
|
||||
}
|
||||
repositories.mavenInstaller {
|
||||
addFilter('api') { artifact, file -> artifact.name == "baritone-api" }
|
||||
addFilter('api-forge') { artifact, file -> artifact.name == "baritone-api-forge" }
|
||||
addFilter('standalone') { artifact, file -> artifact.name == "baritone-standalone" }
|
||||
addFilter('standalone-forge') { artifact, file -> artifact.name == "baritone-standalone-forge" }
|
||||
}
|
||||
}
|
||||
|
||||
install.dependsOn(build)
|
||||
|
||||
@@ -40,17 +40,13 @@ class BaritoneGradleTask extends DefaultTask {
|
||||
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
|
||||
PROGUARD_EXPORT_PATH = "proguard_out.jar",
|
||||
|
||||
TEMP_LIBRARY_DIR = "tempLibraries/",
|
||||
|
||||
ARTIFACT_STANDARD = "%s-%s.jar",
|
||||
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
|
||||
ARTIFACT_API = "%s-api-%s.jar",
|
||||
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
|
||||
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
|
||||
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
|
||||
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
|
||||
|
||||
protected String artifactName, artifactVersion;
|
||||
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, artifactForgeApiPath, artifactForgeStandalonePath, proguardOut;
|
||||
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
|
||||
|
||||
protected void verifyArtifacts() throws IllegalStateException {
|
||||
this.artifactName = getProject().getName();
|
||||
@@ -60,8 +56,6 @@ class BaritoneGradleTask extends DefaultTask {
|
||||
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);
|
||||
|
||||
|
||||
@@ -45,8 +45,6 @@ public class CreateDistTask extends BaritoneGradleTask {
|
||||
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/");
|
||||
@@ -58,11 +56,9 @@ public class CreateDistTask extends BaritoneGradleTask {
|
||||
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, forgeApi, standalone, forgeStandalone, unoptimized)
|
||||
List<String> shasum = Stream.of(api, standalone, unoptimized)
|
||||
.map(path -> sha1(path) + " " + path.getFileName().toString())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
package baritone.gradle.task;
|
||||
|
||||
import baritone.gradle.util.Determinizer;
|
||||
import baritone.gradle.util.MappingType;
|
||||
import baritone.gradle.util.ReobfWrapper;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.gradle.api.plugins.JavaPluginConvention;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
import org.gradle.api.JavaVersion;
|
||||
import org.gradle.api.NamedDomainObjectContainer;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
@@ -38,14 +39,12 @@ import org.gradle.internal.jvm.inspection.DefaultJvmVersionDetector;
|
||||
import org.gradle.process.internal.DefaultExecActionFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
@@ -57,18 +56,12 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
*/
|
||||
public class ProguardTask extends BaritoneGradleTask {
|
||||
|
||||
private static final Pattern TEMP_LIBRARY_PATTERN = Pattern.compile("-libraryjars 'tempLibraries\\/([a-zA-Z0-9/_\\-\\.]+)\\.jar'");
|
||||
|
||||
@Input
|
||||
private String url;
|
||||
|
||||
@Input
|
||||
private String extract;
|
||||
|
||||
private List<String> requiredLibraries;
|
||||
|
||||
private File mixin;
|
||||
|
||||
@TaskAction
|
||||
protected void exec() throws Exception {
|
||||
super.verifyArtifacts();
|
||||
@@ -78,7 +71,6 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
downloadProguard();
|
||||
extractProguard();
|
||||
generateConfigs();
|
||||
acquireDependencies();
|
||||
proguardApi();
|
||||
proguardStandalone();
|
||||
cleanup();
|
||||
@@ -89,7 +81,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
Files.delete(this.artifactUnoptimizedPath);
|
||||
}
|
||||
|
||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
|
||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
|
||||
}
|
||||
|
||||
private void downloadProguard() throws Exception {
|
||||
@@ -209,14 +201,27 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
|
||||
// Setup the template that will be used to derive the API and Standalone configs
|
||||
List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST));
|
||||
template.add(0, "-injars '" + this.artifactPath.toString() + "'");
|
||||
template.add(1, "-outjars '" + this.getTemporaryFile(PROGUARD_EXPORT_PATH) + "'");
|
||||
template.add(0, "-injars " + this.artifactPath.toString());
|
||||
template.add(1, "-outjars " + this.getTemporaryFile(PROGUARD_EXPORT_PATH));
|
||||
|
||||
// Acquire the RT jar using "java -verbose". This doesn't work on Java 9+
|
||||
Process p = new ProcessBuilder(this.getJavaBinPathForProguard(), "-verbose").start();
|
||||
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
|
||||
template.add(2, "-libraryjars '" + out + "'");
|
||||
|
||||
// Discover all of the libraries that we will need to acquire from gradle
|
||||
acquireDependencies().forEach(f -> {
|
||||
if (f.toString().endsWith("-recomp.jar")) {
|
||||
// remove MCP mapped jar
|
||||
return;
|
||||
}
|
||||
if (f.toString().endsWith("client-extra.jar")) {
|
||||
// go from the extra to the original downloaded client
|
||||
f = new File(f.getParentFile(), "client.jar");
|
||||
}
|
||||
template.add(2, "-libraryjars '" + f + "'");
|
||||
});
|
||||
|
||||
// API config doesn't require any changes from the changes that we made to the template
|
||||
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
|
||||
|
||||
@@ -224,165 +229,20 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
List<String> standalone = new ArrayList<>(template);
|
||||
standalone.removeIf(s -> s.contains("# this is the keep api"));
|
||||
Files.write(getTemporaryFile(PROGUARD_STANDALONE_CONFIG), standalone);
|
||||
|
||||
// Discover all of the libraries that we will need to acquire from gradle
|
||||
this.requiredLibraries = new ArrayList<>();
|
||||
template.forEach(line -> {
|
||||
if (!line.startsWith("#")) {
|
||||
Matcher m = TEMP_LIBRARY_PATTERN.matcher(line);
|
||||
if (m.find()) {
|
||||
this.requiredLibraries.add(m.group(1));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void acquireDependencies() throws Exception {
|
||||
|
||||
// Create a map of all of the dependencies that we are able to access in this project
|
||||
// Likely a better way to do this, I just pair the dependency with the first valid configuration
|
||||
Map<String, Pair<Configuration, Dependency>> dependencyLookupMap = new HashMap<>();
|
||||
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config ->
|
||||
config.getAllDependencies().forEach(dependency ->
|
||||
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency))));
|
||||
|
||||
// Create the directory if it doesn't already exist
|
||||
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
|
||||
if (!Files.exists(tempLibraries)) {
|
||||
Files.createDirectory(tempLibraries);
|
||||
}
|
||||
|
||||
// Iterate the required libraries to copy them to tempLibraries
|
||||
for (String lib : this.requiredLibraries) {
|
||||
// copy from the forgegradle cache
|
||||
if (lib.equals("minecraft")) {
|
||||
Path cachedJar = getMinecraftJar();
|
||||
Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar");
|
||||
// TODO: maybe try not to copy every time
|
||||
Files.copy(cachedJar, inTempDir, REPLACE_EXISTING);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find a configuration/dependency pair that matches the desired library
|
||||
Pair<Configuration, Dependency> pair = null;
|
||||
for (Map.Entry<String, Pair<Configuration, Dependency>> entry : dependencyLookupMap.entrySet()) {
|
||||
if (entry.getKey().startsWith(lib)) {
|
||||
pair = entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
// The pair must be non-null
|
||||
Objects.requireNonNull(pair);
|
||||
|
||||
// Find the library jar file, and copy it to tempLibraries
|
||||
for (File file : pair.getLeft().files(pair.getRight())) {
|
||||
if (file.getName().startsWith(lib)) {
|
||||
if (lib.contains("mixin")) {
|
||||
mixin = file;
|
||||
}
|
||||
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mixin == null) {
|
||||
throw new IllegalStateException("Unable to find mixin jar");
|
||||
}
|
||||
}
|
||||
|
||||
// a bunch of epic stuff to get the path to the cached jar
|
||||
private Path getMinecraftJar() throws Exception {
|
||||
MappingType mappingType;
|
||||
try {
|
||||
mappingType = getMappingType();
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to get mapping type, assuming NOTCH.");
|
||||
mappingType = MappingType.NOTCH;
|
||||
}
|
||||
|
||||
String suffix;
|
||||
switch (mappingType) {
|
||||
case NOTCH:
|
||||
suffix = "";
|
||||
break;
|
||||
case SEARGE:
|
||||
suffix = "-srgBin";
|
||||
break;
|
||||
case CUSTOM:
|
||||
throw new IllegalStateException("Custom mappings not supported!");
|
||||
default:
|
||||
throw new IllegalStateException("Unknown mapping type: " + mappingType);
|
||||
}
|
||||
|
||||
DefaultConvention convention = (DefaultConvention) this.getProject().getConvention();
|
||||
Object extension = convention.getAsMap().get("minecraft");
|
||||
Objects.requireNonNull(extension);
|
||||
|
||||
// for some reason cant use Class.forName
|
||||
Class<?> class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass(); // <-- cursed
|
||||
Field f_replacer = class_baseExtension.getDeclaredField("replacer");
|
||||
f_replacer.setAccessible(true);
|
||||
Object replacer = f_replacer.get(extension);
|
||||
Class<?> class_replacementProvider = replacer.getClass();
|
||||
Field replacement_replaceMap = class_replacementProvider.getDeclaredField("replaceMap");
|
||||
replacement_replaceMap.setAccessible(true);
|
||||
|
||||
Map<String, Object> replacements = (Map) replacement_replaceMap.get(replacer);
|
||||
String cacheDir = replacements.get("CACHE_DIR").toString() + "/net/minecraft";
|
||||
String mcVersion = replacements.get("MC_VERSION").toString();
|
||||
String mcpInsert = replacements.get("MAPPING_CHANNEL").toString() + "/" + replacements.get("MAPPING_VERSION").toString();
|
||||
String fullJarName = "minecraft-" + mcVersion + suffix + ".jar";
|
||||
|
||||
String baseDir = String.format("%s/minecraft/%s/", cacheDir, mcVersion);
|
||||
|
||||
String jarPath;
|
||||
if (mappingType == MappingType.SEARGE) {
|
||||
jarPath = String.format("%s/%s/%s", baseDir, mcpInsert, fullJarName);
|
||||
} else {
|
||||
jarPath = baseDir + fullJarName;
|
||||
}
|
||||
jarPath = jarPath
|
||||
.replace("/", File.separator)
|
||||
.replace("\\", File.separator); // hecking regex
|
||||
|
||||
return new File(jarPath).toPath();
|
||||
}
|
||||
|
||||
// throws IllegalStateException if mapping type is ambiguous or it fails to find it
|
||||
private MappingType getMappingType() {
|
||||
// if it fails to find this then its probably a forgegradle version problem
|
||||
Set<Object> reobf = (NamedDomainObjectContainer<Object>) this.getProject().getExtensions().getByName("reobf");
|
||||
|
||||
List<MappingType> mappingTypes = getUsedMappingTypes(reobf);
|
||||
long mappingTypesUsed = mappingTypes.size();
|
||||
if (mappingTypesUsed == 0) {
|
||||
throw new IllegalStateException("Failed to find mapping type (no jar task?)");
|
||||
}
|
||||
if (mappingTypesUsed > 1) {
|
||||
throw new IllegalStateException("Ambiguous mapping type (multiple jars with different mapping types?)");
|
||||
}
|
||||
|
||||
return mappingTypes.get(0);
|
||||
}
|
||||
|
||||
private List<MappingType> getUsedMappingTypes(Set<Object> reobf) {
|
||||
return reobf.stream()
|
||||
.map(ReobfWrapper::new)
|
||||
.map(ReobfWrapper::getMappingType)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
private Stream<File> acquireDependencies() {
|
||||
return getProject().getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().findByName("launch").getRuntimeClasspath().getFiles().stream().filter(File::isFile);
|
||||
}
|
||||
|
||||
private void proguardApi() throws Exception {
|
||||
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
|
||||
}
|
||||
|
||||
private void proguardStandalone() throws Exception {
|
||||
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
|
||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
@@ -405,15 +265,9 @@ public class ProguardTask extends BaritoneGradleTask {
|
||||
Files.delete(this.proguardOut);
|
||||
}
|
||||
|
||||
// Make paths relative to work directory; fixes spaces in path to config, @"" doesn't work
|
||||
Path workingDirectory = getTemporaryFile("");
|
||||
Path proguardJar = workingDirectory.relativize(getTemporaryFile(PROGUARD_JAR));
|
||||
config = workingDirectory.relativize(config);
|
||||
|
||||
// Honestly, if you still have spaces in your path at this point, you're SOL.
|
||||
|
||||
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
|
||||
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
|
||||
.directory(workingDirectory.toFile()) // Set the working directory to the temporary folder]
|
||||
.directory(getTemporaryFile("").toFile()) // Set the working directory to the temporary folder]
|
||||
.start();
|
||||
|
||||
// We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this
|
||||
|
||||
@@ -22,7 +22,10 @@ import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
@@ -36,7 +39,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class Determinizer {
|
||||
|
||||
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
|
||||
public static void determinize(String inputPath, String outputPath) throws IOException {
|
||||
System.out.println("Running Determinizer");
|
||||
System.out.println(" Input path: " + inputPath);
|
||||
System.out.println(" Output path: " + outputPath);
|
||||
@@ -63,30 +66,10 @@ public class Determinizer {
|
||||
if (entry.getName().endsWith(".refmap.json")) {
|
||||
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
|
||||
jos.write(writeSorted(object).getBytes());
|
||||
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && toInclude.isPresent()) { // only replace for forge jar
|
||||
ByteArrayOutputStream cancer = new ByteArrayOutputStream();
|
||||
copy(jarFile.getInputStream(entry), cancer);
|
||||
String manifest = new String(cancer.toByteArray());
|
||||
if (!manifest.contains("baritone.launch.BaritoneTweaker")) {
|
||||
throw new IllegalStateException("unable to replace");
|
||||
}
|
||||
manifest = manifest.replace("baritone.launch.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker");
|
||||
jos.write(manifest.getBytes());
|
||||
} else {
|
||||
copy(jarFile.getInputStream(entry), jos);
|
||||
}
|
||||
}
|
||||
if (toInclude.isPresent()) {
|
||||
try (JarFile mixin = new JarFile(toInclude.get())) {
|
||||
for (JarEntry entry : mixin.stream().sorted(Comparator.comparing(JarEntry::getName)).collect(Collectors.toList())) {
|
||||
if (entry.getName().startsWith("META-INF") && !entry.getName().startsWith("META-INF/services")) {
|
||||
continue;
|
||||
}
|
||||
jos.putNextEntry(entry);
|
||||
copy(mixin.getInputStream(entry), jos);
|
||||
}
|
||||
}
|
||||
}
|
||||
jos.finish();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.gradle.util;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* All credits go to AsmLibGradle and its contributors.
|
||||
*
|
||||
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/ReobfWrapper.java">Original Source</a>
|
||||
*/
|
||||
public class ReobfWrapper {
|
||||
|
||||
private final Object instance;
|
||||
private final Class<?> type;
|
||||
|
||||
public ReobfWrapper(Object instance) {
|
||||
this.instance = instance;
|
||||
Objects.requireNonNull(instance);
|
||||
this.type = instance.getClass();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
try {
|
||||
Field nameField = type.getDeclaredField("name");
|
||||
nameField.setAccessible(true);
|
||||
return (String) nameField.get(this.instance);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public MappingType getMappingType() {
|
||||
try {
|
||||
Field enumField = type.getDeclaredField("mappingType");
|
||||
enumField.setAccessible(true);
|
||||
Enum<?> aEnum = (Enum<?>) enumField.get(this.instance);
|
||||
MappingType mappingType = MappingType.values()[aEnum.ordinal()];
|
||||
if (!aEnum.name().equals(mappingType.name())) {
|
||||
throw new IllegalStateException("ForgeGradle ReobfMappingType is not equivalent to MappingType (version error?)");
|
||||
}
|
||||
return mappingType;
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
scripts/proguard.pro
vendored
57
scripts/proguard.pro
vendored
@@ -1,6 +1,5 @@
|
||||
-keepattributes Signature
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes InnerClasses
|
||||
|
||||
-optimizationpasses 5
|
||||
-verbose
|
||||
@@ -15,6 +14,8 @@
|
||||
|
||||
# lwjgl is weird
|
||||
-dontwarn org.lwjgl.**
|
||||
# also lwjgl lol
|
||||
-dontwarn module-info
|
||||
|
||||
-keep class baritone.api.** { *; } # this is the keep api
|
||||
|
||||
@@ -23,7 +24,6 @@
|
||||
-keep class baritone.api.IBaritoneProvider
|
||||
|
||||
-keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect
|
||||
-keepname class baritone.api.utils.BlockOptionalMeta # this name is exposed to the user, so we need to keep it in all builds
|
||||
|
||||
# Keep any class or member annotated with @KeepName so we dont have to put everything in the script
|
||||
-keep,allowobfuscation @interface baritone.KeepName
|
||||
@@ -42,59 +42,8 @@
|
||||
|
||||
#try to keep usage of schematica in separate classes
|
||||
-keep class baritone.utils.schematic.schematica.**
|
||||
-keep class baritone.utils.schematic.litematica.**
|
||||
#proguard doesnt like it when it cant find our fake schematica classes
|
||||
-dontwarn baritone.utils.schematic.schematica.**
|
||||
-dontwarn baritone.utils.schematic.litematica.**
|
||||
|
||||
# copy all necessary libraries into tempLibraries to build
|
||||
|
||||
# The correct jar will be copied from the forgegradle cache based on the mapping type being compiled with
|
||||
-libraryjars 'tempLibraries/minecraft.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/SimpleTweaker-1.2.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/authlib-1.5.25.jar'
|
||||
-libraryjars 'tempLibraries/codecjorbis-20101023.jar'
|
||||
-libraryjars 'tempLibraries/codecwav-20101023.jar'
|
||||
-libraryjars 'tempLibraries/commons-codec-1.10.jar'
|
||||
-libraryjars 'tempLibraries/commons-compress-1.8.1.jar'
|
||||
-libraryjars 'tempLibraries/commons-io-2.5.jar'
|
||||
-libraryjars 'tempLibraries/commons-lang3-3.5.jar'
|
||||
-libraryjars 'tempLibraries/commons-logging-1.1.3.jar'
|
||||
-libraryjars 'tempLibraries/fastutil-7.1.0.jar'
|
||||
-libraryjars 'tempLibraries/gson-2.8.0.jar'
|
||||
-libraryjars 'tempLibraries/guava-21.0.jar'
|
||||
-libraryjars 'tempLibraries/httpclient-4.3.3.jar'
|
||||
-libraryjars 'tempLibraries/httpcore-4.3.2.jar'
|
||||
-libraryjars 'tempLibraries/icu4j-core-mojang-51.2.jar'
|
||||
-libraryjars 'tempLibraries/jinput-2.0.5.jar'
|
||||
-libraryjars 'tempLibraries/jna-4.4.0.jar'
|
||||
-libraryjars 'tempLibraries/jopt-simple-5.0.3.jar'
|
||||
-libraryjars 'tempLibraries/jsr305-3.0.1.jar'
|
||||
-libraryjars 'tempLibraries/jutils-1.0.0.jar'
|
||||
-libraryjars 'tempLibraries/libraryjavasound-20101123.jar'
|
||||
-libraryjars 'tempLibraries/librarylwjglopenal-20100824.jar'
|
||||
-libraryjars 'tempLibraries/log4j-api-2.8.1.jar'
|
||||
-libraryjars 'tempLibraries/log4j-core-2.8.1.jar'
|
||||
|
||||
# startsWith is used to check the library, and mac/linux differ in which version they use
|
||||
# this is FINE
|
||||
-libraryjars 'tempLibraries/lwjgl-.jar'
|
||||
-libraryjars 'tempLibraries/lwjgl_util-.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
|
||||
-libraryjars 'tempLibraries/oshi-core-1.1.jar'
|
||||
-libraryjars 'tempLibraries/patchy-1.3.9.jar'
|
||||
-libraryjars 'tempLibraries/platform-3.4.0.jar'
|
||||
-libraryjars 'tempLibraries/realms-1.10.22.jar'
|
||||
-libraryjars 'tempLibraries/soundsystem-20120107.jar'
|
||||
-libraryjars 'tempLibraries/text2speech-1.10.3.jar'
|
||||
|
||||
-libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar'
|
||||
-libraryjars 'tempLibraries/launchwrapper-1.11.jar' # TODO why does only 1.11.jar exist?
|
||||
|
||||
|
||||
|
||||
|
||||
# Keep - Applications. Keep all application classes, along with their 'main'
|
||||
@@ -385,5 +334,3 @@
|
||||
public java.lang.String substring(int);
|
||||
public java.lang.String substring(int,int);
|
||||
}
|
||||
|
||||
-printmapping mapping.txt
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
|
||||
package baritone.api;
|
||||
|
||||
import baritone.api.utils.NotificationHelper;
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.api.utils.TypeUtils;
|
||||
import baritone.api.utils.gui.BaritoneToast;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.init.Blocks;
|
||||
@@ -34,7 +32,6 @@ import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@@ -49,11 +46,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> allowBreak = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Blocks that baritone will be allowed to break even with allowBreak set to false
|
||||
*/
|
||||
public final Setting<List<Block>> allowBreakAnyway = new Setting<>(new ArrayList<>());
|
||||
|
||||
/**
|
||||
* Allow Baritone to sprint
|
||||
*/
|
||||
@@ -78,9 +70,9 @@ public final class Settings {
|
||||
public final Setting<Boolean> assumeExternalAutoTool = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Automatically select the best available tool
|
||||
* If this setting is on, no auto tool will occur at all, not at calculation time nor execution time
|
||||
*/
|
||||
public final Setting<Boolean> autoTool = new Setting<>(true);
|
||||
public final Setting<Boolean> disableAutoTool = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* It doesn't actually take twenty ticks to place a block, this cost is so high
|
||||
@@ -107,13 +99,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(3D);
|
||||
|
||||
/**
|
||||
* Don't allow breaking blocks next to liquids.
|
||||
* <p>
|
||||
* Enable if you have mods adding custom fluid physics.
|
||||
*/
|
||||
public final Setting<Boolean> strictLiquidCheck = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
|
||||
* Reliability: questionable.
|
||||
@@ -123,8 +108,6 @@ public final class Settings {
|
||||
/**
|
||||
* Allow Baritone to assume it can walk on still water just like any other block.
|
||||
* This functionality is assumed to be provided by a separate library that might have imported Baritone.
|
||||
* <p>
|
||||
* Note: This will prevent some usage of the frostwalker enchantment, like pillaring up from water.
|
||||
*/
|
||||
public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
|
||||
|
||||
@@ -188,10 +171,10 @@ public final class Settings {
|
||||
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
||||
*/
|
||||
public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
|
||||
Item.getItemFromBlock(Blocks.DIRT),
|
||||
Item.getItemFromBlock(Blocks.COBBLESTONE),
|
||||
Item.getItemFromBlock(Blocks.NETHERRACK),
|
||||
Item.getItemFromBlock(Blocks.STONE)
|
||||
Blocks.DIRT.asItem(),
|
||||
Blocks.COBBLESTONE.asItem(),
|
||||
Blocks.NETHERRACK.asItem(),
|
||||
Blocks.STONE.asItem()
|
||||
)));
|
||||
|
||||
/**
|
||||
@@ -204,28 +187,15 @@ public final class Settings {
|
||||
/**
|
||||
* Blocks that Baritone is not allowed to break
|
||||
*/
|
||||
public final Setting<List<Block>> blocksToDisallowBreaking = new Setting<>(new ArrayList<>(
|
||||
// Leave Empty by Default
|
||||
));
|
||||
|
||||
/**
|
||||
* blocks that baritone shouldn't break, but can if it needs to.
|
||||
*/
|
||||
public final Setting<List<Block>> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet?
|
||||
Blocks.CRAFTING_TABLE,
|
||||
Blocks.FURNACE,
|
||||
Blocks.LIT_FURNACE,
|
||||
Blocks.CHEST,
|
||||
Blocks.TRAPPED_CHEST,
|
||||
Blocks.STANDING_SIGN,
|
||||
Blocks.SIGN,
|
||||
Blocks.WALL_SIGN
|
||||
)));
|
||||
|
||||
/**
|
||||
* this multiplies the break speed, if set above 1 it's "encourage breaking" instead
|
||||
*/
|
||||
public final Setting<Double> avoidBreakingMultiplier = new Setting<>(.1);
|
||||
|
||||
/**
|
||||
* A list of blocks to be treated as if they're air.
|
||||
* <p>
|
||||
@@ -235,40 +205,6 @@ public final class Settings {
|
||||
|
||||
)));
|
||||
|
||||
/**
|
||||
* A list of blocks to be treated as correct.
|
||||
* <p>
|
||||
* If a schematic asks for any block on this list at a certain position, it will be treated as correct, regardless of what it currently is.
|
||||
*/
|
||||
public final Setting<List<Block>> buildSkipBlocks = new Setting<>(new ArrayList<>(Arrays.asList(
|
||||
|
||||
)));
|
||||
|
||||
/**
|
||||
* A mapping of blocks to blocks treated as correct in their position
|
||||
* <p>
|
||||
* If a schematic asks for a block on this mapping, all blocks on the mapped list will be accepted at that location as well
|
||||
* <p>
|
||||
* Syntax same as <a href="https://baritone.leijurv.com/baritone/api/Settings.html#buildSubstitutes">buildSubstitutes</a>
|
||||
*/
|
||||
public final Setting<Map<Block, List<Block>>> buildValidSubstitutes = new Setting<>(new HashMap<>());
|
||||
|
||||
/**
|
||||
* A mapping of blocks to blocks to be built instead
|
||||
* <p>
|
||||
* If a schematic asks for a block on this mapping, Baritone will place the first placeable block in the mapped list
|
||||
* <p>
|
||||
* Usage Syntax:
|
||||
* <pre>
|
||||
* sourceblockA->blockToSubstituteA1,blockToSubstituteA2,...blockToSubstituteAN,sourceBlockB->blockToSubstituteB1,blockToSubstituteB2,...blockToSubstituteBN,...sourceBlockX->blockToSubstituteX1,blockToSubstituteX2...blockToSubstituteXN
|
||||
* </pre>
|
||||
* Example:
|
||||
* <pre>
|
||||
* stone->cobblestone,andesite,oak_planks->birch_planks,acacia_planks,glass
|
||||
* </pre>
|
||||
*/
|
||||
public final Setting<Map<Block, List<Block>>> buildSubstitutes = new Setting<>(new HashMap<>());
|
||||
|
||||
/**
|
||||
* A list of blocks to become air
|
||||
* <p>
|
||||
@@ -283,17 +219,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> buildIgnoreExisting = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* If this is true, the builder will ignore directionality of certain blocks like glazed terracotta.
|
||||
*/
|
||||
public final Setting<Boolean> buildIgnoreDirection = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* A list of names of block properties the builder will ignore.
|
||||
*/
|
||||
public final Setting<List<String>> buildIgnoreProperties = new Setting<>(new ArrayList<>(Arrays.asList(
|
||||
)));
|
||||
|
||||
/**
|
||||
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
|
||||
* <p>
|
||||
@@ -358,6 +283,11 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Integer> rightClickSpeed = new Setting<>(4);
|
||||
|
||||
/**
|
||||
* How many degrees to randomize the yaw every tick. Set to 0 to disable
|
||||
*/
|
||||
public final Setting<Double> randomLooking113 = new Setting<>(2d);
|
||||
|
||||
/**
|
||||
* Block reach distance
|
||||
*/
|
||||
@@ -416,9 +346,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
|
||||
|
||||
/**
|
||||
* Distance to avoid mob spawners.
|
||||
*/
|
||||
public final Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16);
|
||||
|
||||
/**
|
||||
@@ -428,9 +355,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
|
||||
|
||||
/**
|
||||
* Distance to avoid mobs.
|
||||
*/
|
||||
public final Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
|
||||
|
||||
/**
|
||||
@@ -581,17 +505,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
|
||||
|
||||
|
||||
/**
|
||||
* allows baritone to save bed waypoints when interacting with beds
|
||||
*/
|
||||
public final Setting<Boolean> doBedWaypoints = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* allows baritone to save death waypoints
|
||||
*/
|
||||
public final Setting<Boolean> doDeathWaypoints = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing.
|
||||
*/
|
||||
@@ -608,6 +521,13 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Remember the contents of containers (chests, echests, furnaces)
|
||||
* <p>
|
||||
* Really buggy since the packet stuff is multithreaded badly thanks to brady
|
||||
*/
|
||||
public final Setting<Boolean> containerMemory = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Fill in blocks behind you
|
||||
*/
|
||||
@@ -656,12 +576,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> renderGoal = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Render the goal as a sick animated thingy instead of just a box
|
||||
* (also controls animation of GoalXZ if {@link #renderGoalXZBeacon} is enabled)
|
||||
*/
|
||||
public final Setting<Boolean> renderGoalAnimated = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Render selection boxes
|
||||
*/
|
||||
@@ -731,7 +645,7 @@ public final class Settings {
|
||||
|
||||
/**
|
||||
* When GetToBlockProcess or MineProcess fails to calculate a path, instead of just giving up, mark the closest instance
|
||||
* of that block as "unreachable" and go towards the next closest. GetToBlock expands this search to the whole "vein"; MineProcess does not.
|
||||
* of that block as "unreachable" and go towards the next closest. GetToBlock expands this seaarch to the whole "vein"; MineProcess does not.
|
||||
* This is because MineProcess finds individual impossible blocks (like one block in a vein that has gravel on top then lava, so it can't break)
|
||||
* Whereas GetToBlock should blacklist the whole "vein" if it can't get to any of them.
|
||||
*/
|
||||
@@ -786,16 +700,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> censorRanCommands = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Stop using tools just before they are going to break.
|
||||
*/
|
||||
public final Setting<Boolean> itemSaver = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Durability to leave on the tool when using itemSaver
|
||||
*/
|
||||
public final Setting<Integer> itemSaverThreshold = new Setting<>(10);
|
||||
|
||||
/**
|
||||
* Always prefer silk touch tools over regular tools. This will not sacrifice speed, but it will always prefer silk
|
||||
* touch tools over other tools of the same speed. This includes always choosing ANY silk touch tool over your hand.
|
||||
@@ -856,7 +760,7 @@ public final class Settings {
|
||||
public final Setting<Integer> allowOnlyExposedOresDistance = new Setting<>(1);
|
||||
|
||||
/**
|
||||
* When GetToBlock or non-legit Mine doesn't know any locations for the desired block, explore randomly instead of giving up.
|
||||
* When GetToBlock doesn't know any locations for the desired block, explore randomly instead of giving up.
|
||||
*/
|
||||
public final Setting<Boolean> exploreForBlocks = new Setting<>(true);
|
||||
|
||||
@@ -908,11 +812,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> layerOrder = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* How high should the individual layers be?
|
||||
*/
|
||||
public final Setting<Integer> layerHeight = new Setting<>(1);
|
||||
|
||||
/**
|
||||
* Start building the schematic at a specific layer.
|
||||
* Can help on larger builds when schematic wants to break things its already built
|
||||
@@ -924,11 +823,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> skipFailedLayers = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* Only build the selected part of schematics
|
||||
*/
|
||||
public final Setting<Boolean> buildOnlySelection = new Setting<>(false);
|
||||
|
||||
/**
|
||||
* How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely
|
||||
*/
|
||||
@@ -939,13 +833,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Integer> buildRepeatCount = new Setting<>(-1);
|
||||
|
||||
/**
|
||||
* Don't notify schematics that they are moved.
|
||||
* e.g. replacing will replace the same spots for every repetition
|
||||
* Mainly for backward compatibility.
|
||||
*/
|
||||
public final Setting<Boolean> buildRepeatSneaky = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Allow standing above a block while mining it, in BuilderProcess
|
||||
* <p>
|
||||
@@ -1054,7 +941,6 @@ public final class Settings {
|
||||
* Disallow MineBehavior from using X-Ray to see where the ores are. Turn this option on to force it to mine "legit"
|
||||
* where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
|
||||
* couldn't. If you don't want it to look like you're X-Raying, turn this on
|
||||
* This will always explore, regardless of exploreForBlocks
|
||||
*/
|
||||
public final Setting<Boolean> legitMine = new Setting<>(false);
|
||||
|
||||
@@ -1139,21 +1025,7 @@ public final class Settings {
|
||||
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
||||
* {@link Setting#value};
|
||||
*/
|
||||
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(msg -> Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg));
|
||||
|
||||
/**
|
||||
* The function that is called when Baritone will send a desktop notification. This function can be added to
|
||||
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
||||
* {@link Setting#value};
|
||||
*/
|
||||
public final Setting<BiConsumer<String, Boolean>> notifier = new Setting<>(NotificationHelper::notify);
|
||||
|
||||
/**
|
||||
* The function that is called when Baritone will show a toast. This function can be added to
|
||||
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
||||
* {@link Setting#value};
|
||||
*/
|
||||
public final Setting<BiConsumer<ITextComponent, ITextComponent>> toaster = new Setting<>(BaritoneToast::addOrUpdate);
|
||||
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getInstance().ingameGUI.getChatGUI()::printChatMessage);
|
||||
|
||||
/**
|
||||
* The size of the box that is rendered when the current goal is a GoalYLevel
|
||||
@@ -1245,11 +1117,6 @@ public final class Settings {
|
||||
*/
|
||||
public final Setting<Boolean> renderSelectionCorners = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Use sword to mine.
|
||||
*/
|
||||
public final Setting<Boolean> useSwordToMine = new Setting<>(true);
|
||||
|
||||
/**
|
||||
* Desktop notifications
|
||||
*/
|
||||
|
||||
@@ -58,15 +58,6 @@ public interface IPathingBehavior extends IBehavior {
|
||||
return Optional.of(current.getPath().ticksRemainingFrom(start));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the estimated remaining ticks to the current goal.
|
||||
* Given that the return type is an optional, {@link Optional#empty()}
|
||||
* will be returned in the case that there is no current goal.
|
||||
*
|
||||
* @return The estimated remaining ticks to the current goal.
|
||||
*/
|
||||
Optional<Double> estimatedTicksToGoal();
|
||||
|
||||
/**
|
||||
* @return The current pathing goal
|
||||
*/
|
||||
|
||||
@@ -15,29 +15,30 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package fi.dy.masa.litematica.schematic.placement;
|
||||
package baritone.api.cache;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
public class SchematicPlacementUnloaded {
|
||||
protected String name = "?";
|
||||
@Nullable
|
||||
protected File schematicFile;
|
||||
protected BlockPos origin = BlockPos.ORIGIN;
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 9/23/2018
|
||||
*/
|
||||
public interface IContainerMemory {
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
/**
|
||||
* Gets a remembered inventory by its block position.
|
||||
*
|
||||
* @param pos The position of the container block
|
||||
* @return The remembered inventory
|
||||
*/
|
||||
IRememberedInventory getInventoryByPos(BlockPos pos);
|
||||
|
||||
@Nullable
|
||||
public File getSchematicFile() {
|
||||
return this.schematicFile;
|
||||
}
|
||||
|
||||
public BlockPos getOrigin() {
|
||||
return this.origin;
|
||||
}
|
||||
/**
|
||||
* Gets the map of all block positions to their remembered inventories.
|
||||
*
|
||||
* @return Map of block positions to their respective remembered inventories
|
||||
*/
|
||||
Map<BlockPos, IRememberedInventory> getRememberedInventories();
|
||||
}
|
||||
@@ -15,15 +15,25 @@
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.gradle.util;
|
||||
package baritone.api.cache;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* All credits go to AsmLibGradle and its contributors.
|
||||
*
|
||||
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/MappingType.java">Original Source</a>
|
||||
* @author Brady
|
||||
* @since 9/23/2018
|
||||
*/
|
||||
public enum MappingType {
|
||||
SEARGE,
|
||||
NOTCH,
|
||||
CUSTOM // forgegradle
|
||||
public interface IRememberedInventory {
|
||||
|
||||
/**
|
||||
* @return The contents of this inventory
|
||||
*/
|
||||
List<ItemStack> getContents();
|
||||
|
||||
/**
|
||||
* @return The number of slots in this inventory
|
||||
*/
|
||||
int getSize();
|
||||
}
|
||||
@@ -37,4 +37,9 @@ public interface IWorldData {
|
||||
*/
|
||||
IWaypointCollection getWaypoints();
|
||||
|
||||
/**
|
||||
* @return The {@link IContainerMemory} instance
|
||||
* @see IContainerMemory
|
||||
*/
|
||||
IContainerMemory getContainerMemory();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import baritone.api.command.helpers.TabCompleteHelper;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.registry.IRegistry;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -32,7 +33,7 @@ public enum BlockById implements IDatatypeFor<Block> {
|
||||
public Block get(IDatatypeContext ctx) throws CommandException {
|
||||
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
|
||||
Block block;
|
||||
if ((block = Block.REGISTRY.getObject(id)) == Blocks.AIR) {
|
||||
if ((block = IRegistry.BLOCK.get(id)) == Blocks.AIR) {
|
||||
throw new IllegalArgumentException("no block found by that id");
|
||||
}
|
||||
return block;
|
||||
@@ -42,7 +43,7 @@ public enum BlockById implements IDatatypeFor<Block> {
|
||||
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
||||
return new TabCompleteHelper()
|
||||
.append(
|
||||
Block.REGISTRY.getKeys()
|
||||
IRegistry.BLOCK.keySet()
|
||||
.stream()
|
||||
.map(Object::toString)
|
||||
)
|
||||
|
||||
@@ -19,32 +19,20 @@ package baritone.api.command.datatypes;
|
||||
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.helpers.TabCompleteHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.registry.IRegistry;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public enum EntityClassById implements IDatatypeFor<Class<? extends Entity>> {
|
||||
public enum EntityClassById implements IDatatypeFor<EntityType> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public Class<? extends Entity> get(IDatatypeContext ctx) throws CommandException {
|
||||
public EntityType get(IDatatypeContext ctx) throws CommandException {
|
||||
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
|
||||
Class<? extends Entity> entity;
|
||||
try {
|
||||
entity = EntityList.REGISTRY.getObject(id);
|
||||
} catch (NoSuchFieldError e) {
|
||||
// Forge removes EntityList.REGISTRY field and provides the getClass method as a replacement
|
||||
// See https://github.com/MinecraftForge/MinecraftForge/blob/1.12.x/patches/minecraft/net/minecraft/entity/EntityList.java.patch
|
||||
try {
|
||||
entity = (Class<? extends Entity>) EntityList.class.getMethod("getClass", ResourceLocation.class).invoke(null, id);
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("EntityList.REGISTRY does not exist and failed to call the Forge-replacement method", ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity == null) {
|
||||
EntityType entity;
|
||||
if ((entity = IRegistry.ENTITY_TYPE.get(id)) == null) {
|
||||
throw new IllegalArgumentException("no entity found by that id");
|
||||
}
|
||||
return entity;
|
||||
@@ -53,7 +41,7 @@ public enum EntityClassById implements IDatatypeFor<Class<? extends Entity>> {
|
||||
@Override
|
||||
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
||||
return new TabCompleteHelper()
|
||||
.append(EntityList.getEntityNameList().stream().map(Object::toString))
|
||||
.append(IRegistry.ENTITY_TYPE.stream().map(Object::toString))
|
||||
.filterPrefixNamespaced(ctx.getConsumer().getString())
|
||||
.sortAlphabetically()
|
||||
.stream();
|
||||
|
||||
@@ -21,6 +21,7 @@ import baritone.api.IBaritone;
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.helpers.TabCompleteHelper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
@@ -36,14 +37,14 @@ public enum NearbyPlayer implements IDatatypeFor<EntityPlayer> {
|
||||
public EntityPlayer get(IDatatypeContext ctx) throws CommandException {
|
||||
final String username = ctx.getConsumer().getString();
|
||||
return getPlayers(ctx).stream()
|
||||
.filter(s -> s.getName().equalsIgnoreCase(username))
|
||||
.filter(s -> s.getName().getString().equalsIgnoreCase(username))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
||||
return new TabCompleteHelper()
|
||||
.append(getPlayers(ctx).stream().map(EntityPlayer::getName))
|
||||
.append(getPlayers(ctx).stream().map(EntityPlayer::getName).map(ITextComponent::getString))
|
||||
.filterPrefix(ctx.getConsumer().getString())
|
||||
.sortAlphabetically()
|
||||
.stream();
|
||||
|
||||
@@ -26,8 +26,7 @@ import java.util.stream.Stream;
|
||||
|
||||
public enum RelativeCoordinate implements IDatatypePost<Double, Double> {
|
||||
INSTANCE;
|
||||
private static String ScalesAliasRegex = "[kKmM]";
|
||||
private static Pattern PATTERN = Pattern.compile("^(~?)([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)("+ScalesAliasRegex+"?)|)$");
|
||||
private static Pattern PATTERN = Pattern.compile("^(~?)([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)([k-k]?)|)$");
|
||||
|
||||
@Override
|
||||
public Double apply(IDatatypeContext ctx, Double origin) throws CommandException {
|
||||
@@ -42,15 +41,11 @@ public enum RelativeCoordinate implements IDatatypePost<Double, Double> {
|
||||
|
||||
boolean isRelative = !matcher.group(1).isEmpty();
|
||||
|
||||
double offset = matcher.group(2).isEmpty() ? 0 : Double.parseDouble(matcher.group(2).replaceAll(ScalesAliasRegex, ""));
|
||||
|
||||
if (matcher.group(2).toLowerCase().contains("k")) {
|
||||
double offset = matcher.group(2).isEmpty() ? 0 : Double.parseDouble(matcher.group(2).replaceAll("k", ""));
|
||||
|
||||
if (matcher.group(2).contains("k")) {
|
||||
offset *= 1000;
|
||||
}
|
||||
if (matcher.group(2).toLowerCase().contains("m")) {
|
||||
offset *= 1000000;
|
||||
}
|
||||
|
||||
|
||||
if (isRelative) {
|
||||
return origin + offset;
|
||||
|
||||
@@ -253,8 +253,8 @@ public class TabCompleteHelper {
|
||||
public TabCompleteHelper addSettings() {
|
||||
return append(
|
||||
BaritoneAPI.getSettings().allSettings.stream()
|
||||
.filter(s -> !SettingsUtil.javaOnlySetting(s))
|
||||
.map(Settings.Setting::getName)
|
||||
.filter(s -> !s.equalsIgnoreCase("logger"))
|
||||
.sorted(String.CASE_INSENSITIVE_ORDER)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public class Registry<V> {
|
||||
* @param entry The entry to unregister.
|
||||
*/
|
||||
public void unregister(V entry) {
|
||||
if (!registered(entry)) {
|
||||
if (registered(entry)) {
|
||||
return;
|
||||
}
|
||||
_entries.remove(entry);
|
||||
|
||||
@@ -22,7 +22,7 @@ import baritone.api.event.events.type.Cancellable;
|
||||
/**
|
||||
* @author LoganDark
|
||||
*/
|
||||
public class TabCompleteEvent extends Cancellable {
|
||||
public final class TabCompleteEvent extends Cancellable {
|
||||
|
||||
public final String prefix;
|
||||
public String[] completions;
|
||||
|
||||
@@ -18,12 +18,11 @@
|
||||
package baritone.api.event.listener;
|
||||
|
||||
import baritone.api.event.events.*;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.gui.GuiGameOver;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.settings.GameSettings;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.network.Packet;
|
||||
|
||||
@@ -45,7 +44,7 @@ public interface IGameEventListener {
|
||||
* Run once per game tick from before and after the player rotation is sent to the server.
|
||||
*
|
||||
* @param event The event
|
||||
* @see EntityPlayerSP#onUpdate()
|
||||
* @see EntityPlayerSP#tick()
|
||||
*/
|
||||
void onPlayerUpdate(PlayerUpdateEvent event);
|
||||
|
||||
@@ -68,14 +67,11 @@ public interface IGameEventListener {
|
||||
* Runs before and after whenever a chunk is either loaded, unloaded, or populated.
|
||||
*
|
||||
* @param event The event
|
||||
* @see WorldClient#doPreChunk(int, int, boolean)
|
||||
*/
|
||||
void onChunkEvent(ChunkEvent event);
|
||||
|
||||
/**
|
||||
* Runs once per world render pass. Two passes are made when {@link GameSettings#anaglyph} is on.
|
||||
* <p>
|
||||
* <b>Note:</b> {@link GameSettings#anaglyph} has been removed in Minecraft 1.13
|
||||
* Runs once per world render pass.
|
||||
*
|
||||
* @param event The event
|
||||
*/
|
||||
@@ -85,7 +81,7 @@ public interface IGameEventListener {
|
||||
* Runs before and after whenever a new world is loaded
|
||||
*
|
||||
* @param event The event
|
||||
* @see Minecraft#loadWorld(WorldClient, String)
|
||||
* @see Minecraft#loadWorld(WorldClient, GuiScreen)
|
||||
*/
|
||||
void onWorldEvent(WorldEvent event);
|
||||
|
||||
@@ -94,7 +90,6 @@ public interface IGameEventListener {
|
||||
*
|
||||
* @param event The event
|
||||
* @see Packet
|
||||
* @see GenericFutureListener
|
||||
*/
|
||||
void onSendPacket(PacketEvent event);
|
||||
|
||||
@@ -103,7 +98,6 @@ public interface IGameEventListener {
|
||||
*
|
||||
* @param event The event
|
||||
* @see Packet
|
||||
* @see GenericFutureListener
|
||||
*/
|
||||
void onReceivePacket(PacketEvent event);
|
||||
|
||||
@@ -117,10 +111,10 @@ public interface IGameEventListener {
|
||||
void onPlayerRotationMove(RotationMoveEvent event);
|
||||
|
||||
/**
|
||||
* Called whenever the sprint keybind state is checked in {@link EntityPlayerSP#onLivingUpdate}
|
||||
* Called whenever the sprint keybind state is checked in {@link EntityPlayerSP#livingTick}
|
||||
*
|
||||
* @param event The event
|
||||
* @see EntityPlayerSP#onLivingUpdate()
|
||||
* @see EntityPlayerSP#livingTick()
|
||||
*/
|
||||
void onPlayerSprintState(SprintStateEvent event);
|
||||
|
||||
|
||||
@@ -54,18 +54,4 @@ public interface Goal {
|
||||
default double heuristic(BlockPos pos) {
|
||||
return heuristic(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the heuristic at the goal.
|
||||
* i.e. {@code heuristic() == heuristic(x,y,z)}
|
||||
* when {@code isInGoal(x,y,z) == true}
|
||||
* This is needed by {@code PathingBehavior#estimatedTicksToGoal} because
|
||||
* some Goals actually do not have a heuristic of 0 when that condition is met
|
||||
*
|
||||
* @return The estimate number of ticks to satisfy the goal when the goal
|
||||
* is already satisfied
|
||||
*/
|
||||
default double heuristic() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,9 +87,9 @@ public class GoalBlock implements Goal, IGoalRenderPos {
|
||||
public static double calculate(double xDiff, int yDiff, double zDiff) {
|
||||
double heuristic = 0;
|
||||
|
||||
// if yDiff is 1 that means that currentY-goalY==1 which means that we're 1 block above where we should be
|
||||
// therefore going from 0,yDiff,0 to a GoalYLevel of 0 is accurate
|
||||
heuristic += GoalYLevel.calculate(0, yDiff);
|
||||
// if yDiff is 1 that means that pos.getY()-this.y==1 which means that we're 1 block below where we should be
|
||||
// therefore going from 0,0,0 to a GoalYLevel of pos.getY()-this.y is accurate
|
||||
heuristic += GoalYLevel.calculate(yDiff, 0);
|
||||
|
||||
//use the pythagorean and manhattan mixture from GoalXZ
|
||||
heuristic += GoalXZ.calculate(xDiff, zDiff);
|
||||
|
||||
@@ -57,16 +57,6 @@ public class GoalComposite implements Goal {
|
||||
return min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double heuristic() {
|
||||
double min = Double.MAX_VALUE;
|
||||
for (Goal g : goals) {
|
||||
// just take the highest value that is guaranteed to be inside the goal
|
||||
min = Math.min(min, g.heuristic());
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GoalComposite" + Arrays.toString(goals);
|
||||
|
||||
@@ -45,11 +45,6 @@ public class GoalInverted implements Goal {
|
||||
return -origin.heuristic(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double heuristic() {
|
||||
return Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("GoalInverted{%s}", origin.toString());
|
||||
|
||||
@@ -19,8 +19,6 @@ package baritone.api.pathing.goals;
|
||||
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||
import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class GoalNear implements Goal, IGoalRenderPos {
|
||||
@@ -53,34 +51,6 @@ public class GoalNear implements Goal, IGoalRenderPos {
|
||||
return GoalBlock.calculate(xDiff, yDiff, zDiff);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double heuristic() {// TODO less hacky solution
|
||||
int range = (int) Math.ceil(Math.sqrt(rangeSq));
|
||||
DoubleOpenHashSet maybeAlwaysInside = new DoubleOpenHashSet(); // see pull request #1978
|
||||
double minOutside = Double.POSITIVE_INFINITY;
|
||||
for (int dx = -range; dx <= range; dx++) {
|
||||
for (int dy = -range; dy <= range; dy++) {
|
||||
for (int dz = -range; dz <= range; dz++) {
|
||||
double h = heuristic(x + dx, y + dy, z + dz);
|
||||
if (h < minOutside && isInGoal(x + dx, y + dy, z + dz)) {
|
||||
maybeAlwaysInside.add(h);
|
||||
} else {
|
||||
minOutside = Math.min(minOutside, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
double maxInside = Double.NEGATIVE_INFINITY;
|
||||
DoubleIterator it = maybeAlwaysInside.iterator();
|
||||
while (it.hasNext()) {
|
||||
double inside = it.nextDouble();
|
||||
if (inside < minOutside) {
|
||||
maxInside = Math.max(maxInside, inside);
|
||||
}
|
||||
}
|
||||
return maxInside;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getGoalPos() {
|
||||
return new BlockPos(x, y, z);
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
package baritone.api.pathing.goals;
|
||||
|
||||
import baritone.api.utils.SettingsUtil;
|
||||
import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -67,7 +65,7 @@ public class GoalRunAway implements Goal {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double heuristic(int x, int y, int z) {// mostly copied from GoalBlock
|
||||
public double heuristic(int x, int y, int z) {//mostly copied from GoalBlock
|
||||
double min = Double.MAX_VALUE;
|
||||
for (BlockPos p : from) {
|
||||
double h = GoalXZ.calculate(p.getX() - x, p.getZ() - z);
|
||||
@@ -82,48 +80,6 @@ public class GoalRunAway implements Goal {
|
||||
return min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double heuristic() {// TODO less hacky solution
|
||||
int distance = (int) Math.ceil(Math.sqrt(distanceSq));
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
int minZ = Integer.MAX_VALUE;
|
||||
int maxX = Integer.MIN_VALUE;
|
||||
int maxY = Integer.MIN_VALUE;
|
||||
int maxZ = Integer.MIN_VALUE;
|
||||
for (BlockPos p : from) {
|
||||
minX = Math.min(minX, p.getX() - distance);
|
||||
minY = Math.min(minY, p.getY() - distance);
|
||||
minZ = Math.min(minZ, p.getZ() - distance);
|
||||
maxX = Math.max(minX, p.getX() + distance);
|
||||
maxY = Math.max(minY, p.getY() + distance);
|
||||
maxZ = Math.max(minZ, p.getZ() + distance);
|
||||
}
|
||||
DoubleOpenHashSet maybeAlwaysInside = new DoubleOpenHashSet(); // see pull request #1978
|
||||
double minOutside = Double.POSITIVE_INFINITY;
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
double h = heuristic(x, y, z);
|
||||
if (h < minOutside && isInGoal(x, y, z)) {
|
||||
maybeAlwaysInside.add(h);
|
||||
} else {
|
||||
minOutside = Math.min(minOutside, h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
double maxInside = Double.NEGATIVE_INFINITY;
|
||||
DoubleIterator it = maybeAlwaysInside.iterator();
|
||||
while (it.hasNext()) {
|
||||
double inside = it.nextDouble();
|
||||
if (inside < minOutside) {
|
||||
maxInside = Math.max(maxInside, inside);
|
||||
}
|
||||
}
|
||||
return maxInside;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (maintainY != null) {
|
||||
|
||||
@@ -64,11 +64,6 @@ public class GoalStrictDirection implements Goal {
|
||||
return heuristic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double heuristic() {
|
||||
return Double.NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
|
||||
@@ -52,14 +52,12 @@ public interface IBuilderProcess extends IBaritoneProcess {
|
||||
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);
|
||||
File file = new File(new File(Minecraft.getInstance().gameDir, "schematics"), schematicFile);
|
||||
return build(schematicFile, file, origin);
|
||||
}
|
||||
|
||||
void buildOpenSchematic();
|
||||
|
||||
void buildOpenLitematic(int i);
|
||||
|
||||
void pause();
|
||||
|
||||
boolean isPaused();
|
||||
|
||||
@@ -71,11 +71,4 @@ public class CompositeSchematic extends AbstractSchematic {
|
||||
}
|
||||
return entry.schematic.desiredState(x - entry.x, y - entry.y, z - entry.z, current, approxPlaceable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
for (CompositeSchematicEntry entry : schematicArr) {
|
||||
entry.schematic.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package baritone.api.schematic;
|
||||
|
||||
import baritone.api.utils.BlockOptionalMeta;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -32,7 +33,7 @@ public class FillSchematic extends AbstractSchematic {
|
||||
}
|
||||
|
||||
public FillSchematic(int x, int y, int z, IBlockState state) {
|
||||
this(x, y, z, new BlockOptionalMeta(state.getBlock(), state.getBlock().getMetaFromState(state)));
|
||||
this(x, y, z, new BlockOptionalMeta(state.getBlock()));
|
||||
}
|
||||
|
||||
public BlockOptionalMeta getBom() {
|
||||
@@ -43,6 +44,8 @@ public class FillSchematic extends AbstractSchematic {
|
||||
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)) {
|
||||
|
||||
@@ -73,11 +73,6 @@ public interface ISchematic {
|
||||
*/
|
||||
IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable);
|
||||
|
||||
/**
|
||||
* Resets possible caches to avoid wrong behavior when moving the schematic around
|
||||
*/
|
||||
default void reset() {}
|
||||
|
||||
/**
|
||||
* @return The width (X axis length) of this schematic
|
||||
*/
|
||||
|
||||
@@ -31,18 +31,6 @@ public class ReplaceSchematic extends MaskSchematic {
|
||||
this.cache = new Boolean[widthX()][heightY()][lengthZ()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
// it's final, can't use this.cache = new Boolean[widthX()][heightY()][lengthZ()]
|
||||
for (int x = 0; x < cache.length; x++) {
|
||||
for (int y = 0; y < cache[0].length; y++) {
|
||||
for (int z = 0; z < cache[0][0].length; z++) {
|
||||
cache[x][y][z] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {
|
||||
if (cache[x][y][z] == null) {
|
||||
|
||||
@@ -1,89 +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.schematic;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockAir;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SubstituteSchematic extends AbstractSchematic {
|
||||
|
||||
private final ISchematic schematic;
|
||||
private final Map<Block, List<Block>> substitutions;
|
||||
private final Map<IBlockState, Map<Block, IBlockState>> blockStateCache = new HashMap<>();
|
||||
|
||||
public SubstituteSchematic(ISchematic schematic, Map<Block,List<Block>> substitutions) {
|
||||
super(schematic.widthX(), schematic.heightY(), schematic.lengthZ());
|
||||
this.schematic = schematic;
|
||||
this.substitutions = substitutions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inSchematic(int x, int y, int z, IBlockState currentState) {
|
||||
return schematic.inSchematic(x, y, z, currentState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
|
||||
IBlockState desired = schematic.desiredState(x, y, z, current, approxPlaceable);
|
||||
Block desiredBlock = desired.getBlock();
|
||||
if (!substitutions.containsKey(desiredBlock)) {
|
||||
return desired;
|
||||
}
|
||||
List<Block> substitutes = substitutions.get(desiredBlock);
|
||||
if (substitutes.contains(current.getBlock()) && !(current.getBlock() instanceof BlockAir)) {// don't preserve air, it's almost always there and almost never wanted
|
||||
return withBlock(desired, current.getBlock());
|
||||
}
|
||||
for (Block substitute : substitutes) {
|
||||
if (substitute instanceof BlockAir) {
|
||||
return current.getBlock() instanceof BlockAir ? current : Blocks.AIR.getDefaultState(); // can always "place" air
|
||||
}
|
||||
for (IBlockState placeable : approxPlaceable) {
|
||||
if (substitute.equals(placeable.getBlock())) {
|
||||
return withBlock(desired, placeable.getBlock());
|
||||
}
|
||||
}
|
||||
}
|
||||
return substitutes.get(0).getDefaultState();
|
||||
}
|
||||
|
||||
private IBlockState withBlock(IBlockState state, Block block) {
|
||||
if (blockStateCache.containsKey(state) && blockStateCache.get(state).containsKey(block)) {
|
||||
return blockStateCache.get(state).get(block);
|
||||
}
|
||||
Collection<IProperty<?>> properties = state.getPropertyKeys();
|
||||
IBlockState newState = block.getDefaultState();
|
||||
for (IProperty<?> property : properties) {
|
||||
try {
|
||||
newState = copySingleProp(state, newState, property);
|
||||
} catch (IllegalArgumentException e) { //property does not exist for target block
|
||||
}
|
||||
}
|
||||
blockStateCache.computeIfAbsent(state, s -> new HashMap<Block,IBlockState>()).put(block, newState);
|
||||
return newState;
|
||||
}
|
||||
private <T extends Comparable<T>> IBlockState copySingleProp(IBlockState fromState, IBlockState toState, IProperty<T> prop) {
|
||||
return toState.withProperty(prop, fromState.getValue(prop));
|
||||
}
|
||||
}
|
||||
@@ -19,44 +19,32 @@ package baritone.api.utils;
|
||||
|
||||
import baritone.api.utils.accessor.IItemStack;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.registry.IRegistry;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
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);
|
||||
this.block = block;
|
||||
this.blockstates = getStates(block);
|
||||
this.stateHashes = getStateHashes(blockstates);
|
||||
this.stackHashes = getStackHashes(blockstates);
|
||||
}
|
||||
|
||||
public BlockOptionalMeta(@Nonnull String selector) {
|
||||
@@ -67,186 +55,21 @@ public final class BlockOptionalMeta {
|
||||
}
|
||||
|
||||
MatchResult matchResult = matcher.toMatchResult();
|
||||
noMeta = matchResult.group(2) == null;
|
||||
|
||||
ResourceLocation id = new ResourceLocation(matchResult.group(1));
|
||||
|
||||
if (!Block.REGISTRY.containsKey(id)) {
|
||||
if (!IRegistry.BLOCK.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());
|
||||
block = IRegistry.BLOCK.get(id);
|
||||
blockstates = getStates(block);
|
||||
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);
|
||||
}
|
||||
|
||||
public static <C extends Comparable<C>, P extends IProperty<C>> P castToIProperty(Object value) {
|
||||
//noinspection unchecked
|
||||
return (P) value;
|
||||
}
|
||||
|
||||
public static <C extends Comparable<C>, P extends IProperty<C>> C castToIPropertyValue(P iproperty, Object value) {
|
||||
//noinspection unchecked
|
||||
return (C) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the specified blockstate by setting meta-affecting properties which
|
||||
* are not being targeted by the meta parameter to their default values.
|
||||
* <p>
|
||||
* For example, block variant/color is the primary target for the meta value, so properties
|
||||
* such as rotation/facing direction will be set to default values in order to nullify
|
||||
* the effect that they have on the state's meta value.
|
||||
*
|
||||
* @param state The state to normalize
|
||||
* @return The normalized block state
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the target meta value for the specified state. The target meta value is
|
||||
* most often that which is influenced by the variant/color property of the block state.
|
||||
*
|
||||
* @param state The state to check
|
||||
* @return The target meta of the state
|
||||
* @see #normalize(IBlockState)
|
||||
*/
|
||||
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 Set<IBlockState> getStates(@Nonnull Block block) {
|
||||
return new HashSet<>(block.getStateContainer().getValidStates());
|
||||
}
|
||||
|
||||
private static ImmutableSet<Integer> getStateHashes(Set<IBlockState> blockstates) {
|
||||
@@ -262,8 +85,8 @@ public final class BlockOptionalMeta {
|
||||
return ImmutableSet.copyOf(
|
||||
blockstates.stream()
|
||||
.map(state -> new ItemStack(
|
||||
state.getBlock().getItemDropped(state, new Random(), 0),
|
||||
state.getBlock().damageDropped(state)
|
||||
state.getBlock().getItemDropped(state, null, null, 0).asItem(),
|
||||
1
|
||||
))
|
||||
.map(stack -> ((IItemStack) (Object) stack).getBaritoneHash())
|
||||
.toArray(Integer[]::new)
|
||||
@@ -274,10 +97,6 @@ public final class BlockOptionalMeta {
|
||||
return block;
|
||||
}
|
||||
|
||||
public Integer getMeta() {
|
||||
return noMeta ? null : meta;
|
||||
}
|
||||
|
||||
public boolean matches(@Nonnull Block block) {
|
||||
return block == this.block;
|
||||
}
|
||||
@@ -291,21 +110,14 @@ public final class BlockOptionalMeta {
|
||||
//noinspection ConstantConditions
|
||||
int hash = ((IItemStack) (Object) stack).getBaritoneHash();
|
||||
|
||||
if (noMeta) {
|
||||
hash -= stack.getItemDamage();
|
||||
}
|
||||
hash -= stack.getDamage();
|
||||
|
||||
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());
|
||||
return String.format("BlockOptionalMeta{block=%s}", block);
|
||||
}
|
||||
|
||||
public IBlockState getAnyBlockState() {
|
||||
|
||||
@@ -19,6 +19,7 @@ package baritone.api.utils;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.registry.IRegistry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -28,7 +29,7 @@ public class BlockUtils {
|
||||
private static transient Map<String, Block> resourceCache = new HashMap<>();
|
||||
|
||||
public static String blockToString(Block block) {
|
||||
ResourceLocation loc = Block.REGISTRY.getNameForObject(block);
|
||||
ResourceLocation loc = IRegistry.BLOCK.getKey(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?
|
||||
@@ -56,7 +57,7 @@ public class BlockUtils {
|
||||
if (resourceCache.containsKey(name)) {
|
||||
return null; // cached as null
|
||||
}
|
||||
block = Block.getBlockFromName(name.contains(":") ? name : "minecraft:" + name);
|
||||
block = IRegistry.BLOCK.get(ResourceLocation.tryCreate(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;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package baritone.api.utils;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.utils.gui.BaritoneToast;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
@@ -44,7 +45,7 @@ public interface Helper {
|
||||
/**
|
||||
* Instance of the game
|
||||
*/
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
|
||||
static ITextComponent getPrefix() {
|
||||
// Inner text component
|
||||
@@ -70,7 +71,7 @@ public interface Helper {
|
||||
* @param message The message to display in the popup
|
||||
*/
|
||||
default void logToast(ITextComponent title, ITextComponent message) {
|
||||
mc.addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message));
|
||||
mc.addScheduledTask(() -> BaritoneToast.addOrUpdate(mc.getToastGui(), title, message, BaritoneAPI.getSettings().toastTimer.value));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,48 +93,6 @@ public interface Helper {
|
||||
logToast(Helper.getPrefix(), new TextComponentString(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message as a desktop notification
|
||||
*
|
||||
* @param message The message to display in the notification
|
||||
*/
|
||||
default void logNotification(String message) {
|
||||
logNotification(message, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message as a desktop notification
|
||||
*
|
||||
* @param message The message to display in the notification
|
||||
* @param error Whether to log as an error
|
||||
*/
|
||||
default void logNotification(String message, boolean error) {
|
||||
if (BaritoneAPI.getSettings().desktopNotifications.value) {
|
||||
logNotificationDirect(message, error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message as a desktop notification regardless of desktopNotifications
|
||||
* (should only be used for critically important messages)
|
||||
*
|
||||
* @param message The message to display in the notification
|
||||
*/
|
||||
default void logNotificationDirect(String message) {
|
||||
logNotificationDirect(message, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message as a desktop notification regardless of desktopNotifications
|
||||
* (should only be used for critically important messages)
|
||||
*
|
||||
* @param message The message to display in the notification
|
||||
* @param error Whether to log as an error
|
||||
*/
|
||||
default void logNotificationDirect(String message, boolean error) {
|
||||
mc.addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to chat only if chatDebug is on
|
||||
*
|
||||
|
||||
@@ -87,7 +87,7 @@ public interface IPlayerContext {
|
||||
*/
|
||||
default Optional<BlockPos> getSelectedBlock() {
|
||||
RayTraceResult result = objectMouseOver();
|
||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
if (result != null && result.type == RayTraceResult.Type.BLOCK) {
|
||||
return Optional.of(result.getBlockPos());
|
||||
}
|
||||
return Optional.empty();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package baritone.api.utils;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.RayTraceFluidMode;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
@@ -48,7 +49,7 @@ public final class RayTraceUtils {
|
||||
if (wouldSneak) {
|
||||
start = inferSneakingEyePosition(entity);
|
||||
} else {
|
||||
start = entity.getPositionEyes(1.0F); // do whatever is correct
|
||||
start = entity.getEyePosition(1.0F); // do whatever is correct
|
||||
}
|
||||
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
|
||||
Vec3d end = start.add(
|
||||
@@ -56,7 +57,7 @@ public final class RayTraceUtils {
|
||||
direction.y * blockReachDistance,
|
||||
direction.z * blockReachDistance
|
||||
);
|
||||
return entity.world.rayTraceBlocks(start, end, false, false, true);
|
||||
return entity.world.rayTraceBlocks(start, end, RayTraceFluidMode.NEVER, false, true);
|
||||
}
|
||||
|
||||
public static Vec3d inferSneakingEyePosition(Entity entity) {
|
||||
|
||||
@@ -36,6 +36,9 @@ public class Rotation {
|
||||
public Rotation(float yaw, float pitch) {
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
if (Float.isInfinite(yaw) || Float.isNaN(yaw) || Float.isInfinite(pitch) || Float.isNaN(pitch)) {
|
||||
throw new IllegalStateException(yaw + " " + pitch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,13 @@ import net.minecraft.block.BlockFire;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -177,7 +183,7 @@ public final class RotationUtils {
|
||||
if (wouldSneak) {
|
||||
// the concern here is: what if we're looking at it now, but as soon as we start sneaking we no longer are
|
||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, hypothetical, blockReachDistance, true);
|
||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(pos)) {
|
||||
if (result != null && result.type == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(pos)) {
|
||||
return Optional.of(hypothetical); // yes, if we sneaked we would still be looking at the block
|
||||
}
|
||||
} else {
|
||||
@@ -191,11 +197,14 @@ public final class RotationUtils {
|
||||
}
|
||||
|
||||
IBlockState state = entity.world.getBlockState(pos);
|
||||
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
|
||||
VoxelShape shape = state.getShape(entity.world, pos);
|
||||
if (shape.isEmpty()) {
|
||||
shape = VoxelShapes.fullCube();
|
||||
}
|
||||
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
|
||||
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
|
||||
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
|
||||
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
|
||||
double xDiff = shape.getStart(EnumFacing.Axis.X) * sideOffset.x + shape.getEnd(EnumFacing.Axis.X) * (1 - sideOffset.x);
|
||||
double yDiff = shape.getStart(EnumFacing.Axis.Y) * sideOffset.y + shape.getEnd(EnumFacing.Axis.Y) * (1 - sideOffset.y);
|
||||
double zDiff = shape.getStart(EnumFacing.Axis.Z) * sideOffset.z + shape.getEnd(EnumFacing.Axis.Z) * (1 - sideOffset.z);
|
||||
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak);
|
||||
if (possibleRotation.isPresent()) {
|
||||
return possibleRotation;
|
||||
@@ -216,11 +225,11 @@ public final class RotationUtils {
|
||||
* @return The optional rotation
|
||||
*/
|
||||
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) {
|
||||
Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getPositionEyes(1.0F);
|
||||
Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getEyePosition(1.0F);
|
||||
Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
|
||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance, wouldSneak);
|
||||
//System.out.println(result);
|
||||
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
if (result != null && result.type == RayTraceResult.Type.BLOCK) {
|
||||
if (result.getBlockPos().equals(pos)) {
|
||||
return Optional.of(rotation);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,12 @@ package baritone.api.utils;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.Settings;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.util.registry.IRegistry;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.BufferedReader;
|
||||
@@ -35,7 +38,6 @@ import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
@@ -44,13 +46,12 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
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 Path SETTINGS_PATH = Minecraft.getInstance().gameDir.toPath().resolve("baritone").resolve("settings.txt");
|
||||
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
|
||||
private static final String[] JAVA_ONLY_SETTINGS = {"logger", "notifier", "toaster"};
|
||||
|
||||
|
||||
private static boolean isComment(String line) {
|
||||
return line.startsWith("#") || line.startsWith("//");
|
||||
@@ -112,7 +113,7 @@ public class SettingsUtil {
|
||||
System.out.println("NULL SETTING?" + setting.getName());
|
||||
continue;
|
||||
}
|
||||
if (javaOnlySetting(setting)) {
|
||||
if (setting.getName().equals("logger")) {
|
||||
continue; // NO
|
||||
}
|
||||
if (setting.value == setting.defaultValue) {
|
||||
@@ -166,28 +167,13 @@ public class SettingsUtil {
|
||||
}
|
||||
|
||||
public static String settingToString(Settings.Setting setting) throws IllegalStateException {
|
||||
if (javaOnlySetting(setting)) {
|
||||
return setting.getName();
|
||||
if (setting.getName().equals("logger")) {
|
||||
return "logger";
|
||||
}
|
||||
|
||||
return setting.getName() + " " + settingValueToString(setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* This should always be the same as whether the setting can be parsed from or serialized to a string
|
||||
*
|
||||
* @param setting The Setting
|
||||
* @return true if the setting can not be set or read by the user
|
||||
*/
|
||||
public static boolean javaOnlySetting(Settings.Setting setting) {
|
||||
for (String name : JAVA_ONLY_SETTINGS) { // no JAVA_ONLY_SETTINGS.contains(...) because that would be case sensitive
|
||||
if (setting.getName().equalsIgnoreCase(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
|
||||
Settings.Setting setting = settings.byLowerName.get(settingName);
|
||||
if (setting == null) {
|
||||
@@ -250,15 +236,14 @@ public class SettingsUtil {
|
||||
),
|
||||
ITEM(
|
||||
Item.class,
|
||||
str -> Item.getByNameOrId(str.trim()),
|
||||
item -> Item.REGISTRY.getNameForObject(item).toString()
|
||||
str -> IRegistry.ITEM.get(new ResourceLocation(str.trim())),
|
||||
item -> IRegistry.ITEM.getKey(item).toString()
|
||||
),
|
||||
LIST() {
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Parser parser = Parser.getParser(type);
|
||||
|
||||
return Stream.of(raw.split(","))
|
||||
.map(s -> parser.parse(context, s))
|
||||
.collect(Collectors.toList());
|
||||
@@ -278,36 +263,6 @@ public class SettingsUtil {
|
||||
public boolean accepts(Type type) {
|
||||
return List.class.isAssignableFrom(TypeUtils.resolveBaseClass(type));
|
||||
}
|
||||
},
|
||||
MAPPING() {
|
||||
@Override
|
||||
public Object parse(ParserContext context, String raw) {
|
||||
Type keyType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Type valueType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[1];
|
||||
Parser keyParser = Parser.getParser(keyType);
|
||||
Parser valueParser = Parser.getParser(valueType);
|
||||
|
||||
return Stream.of(raw.split(",(?=[^,]*->)"))
|
||||
.map(s -> s.split("->"))
|
||||
.collect(Collectors.toMap(s -> keyParser.parse(context, s[0]), s -> valueParser.parse(context, s[1])));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ParserContext context, Object value) {
|
||||
Type keyType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||
Type valueType = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[1];
|
||||
Parser keyParser = Parser.getParser(keyType);
|
||||
Parser valueParser = Parser.getParser(valueType);
|
||||
|
||||
return ((Map<?,?>) value).entrySet().stream()
|
||||
.map(o -> keyParser.toString(context, o.getKey()) + "->" + valueParser.toString(context, o.getValue()))
|
||||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accepts(Type type) {
|
||||
return Map.class.isAssignableFrom(TypeUtils.resolveBaseClass(type));
|
||||
}
|
||||
};
|
||||
|
||||
private final Class<?> cla$$;
|
||||
|
||||
@@ -20,9 +20,10 @@ package baritone.api.utils;
|
||||
import net.minecraft.block.BlockFire;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
@@ -43,10 +44,16 @@ public final class VecUtils {
|
||||
*/
|
||||
public static Vec3d calculateBlockCenter(World world, BlockPos pos) {
|
||||
IBlockState b = world.getBlockState(pos);
|
||||
AxisAlignedBB bbox = b.getBoundingBox(world, pos);
|
||||
double xDiff = (bbox.minX + bbox.maxX) / 2;
|
||||
double yDiff = (bbox.minY + bbox.maxY) / 2;
|
||||
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
|
||||
VoxelShape shape = b.getCollisionShape(world, pos);
|
||||
if (shape.isEmpty()) {
|
||||
return getBlockPosCenter(pos);
|
||||
}
|
||||
double xDiff = (shape.getStart(EnumFacing.Axis.X) + shape.getEnd(EnumFacing.Axis.X)) / 2;
|
||||
double yDiff = (shape.getStart(EnumFacing.Axis.Y) + shape.getEnd(EnumFacing.Axis.Y)) / 2;
|
||||
double zDiff = (shape.getStart(EnumFacing.Axis.Z) + shape.getEnd(EnumFacing.Axis.Z)) / 2;
|
||||
if (Double.isNaN(xDiff) || Double.isNaN(yDiff) || Double.isNaN(zDiff)) {
|
||||
throw new IllegalStateException(b + " " + pos + " " + shape);
|
||||
}
|
||||
if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
|
||||
yDiff = 0;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class BaritoneToast implements IToast {
|
||||
}
|
||||
|
||||
toastGui.getMinecraft().getTextureManager().bindTexture(new ResourceLocation("textures/gui/toasts.png"));
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 255.0f);
|
||||
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 255.0f);
|
||||
toastGui.drawTexturedModalRect(0, 0, 0, 32, 160, 32);
|
||||
|
||||
if (this.subtitle == null) {
|
||||
@@ -71,8 +71,4 @@ public class BaritoneToast implements IToast {
|
||||
baritonetoast.setDisplayedText(title, subtitle);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addOrUpdate(ITextComponent title, ITextComponent subtitle) {
|
||||
addOrUpdate(net.minecraft.client.Minecraft.getMinecraft().getToastGui(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value);
|
||||
}
|
||||
}
|
||||
|
||||
105
src/launch/java/baritone/launch/LaunchTesting.java
Normal file
105
src/launch/java/baritone/launch/LaunchTesting.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.mojang.authlib.Agent;
|
||||
import com.mojang.authlib.exceptions.AuthenticationException;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Based on GradleStart from ForgeGradle 2.3
|
||||
*
|
||||
* @author Brady
|
||||
* @since 3/11/2019
|
||||
*/
|
||||
public class LaunchTesting {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Map<String, String> arguments = new HashMap<>();
|
||||
|
||||
hackNatives();
|
||||
arguments.put("version", "BaritownedDeveloperEnvironment");
|
||||
arguments.put("assetIndex", System.getenv("assetIndex"));
|
||||
arguments.put("assetsDir", System.getenv().getOrDefault("assetDirectory", "assets"));
|
||||
arguments.put("accessToken", "FML");
|
||||
arguments.put("userProperties", "{}");
|
||||
arguments.put("tweakClass", System.getenv("tweakClass"));
|
||||
String password = System.getenv("password");
|
||||
if (password != null && !password.isEmpty()) {
|
||||
attemptLogin(arguments, System.getenv("username"), System.getenv("password"));
|
||||
}
|
||||
|
||||
List<String> argsArray = new ArrayList<>();
|
||||
arguments.forEach((k, v) -> {
|
||||
argsArray.add("--" + k);
|
||||
argsArray.add(v);
|
||||
});
|
||||
|
||||
Launch.main(argsArray.toArray(new String[0]));
|
||||
}
|
||||
|
||||
private static void hackNatives() {
|
||||
String paths = System.getProperty("java.library.path");
|
||||
String nativesDir = System.getenv().get("nativesDirectory");
|
||||
|
||||
if (Strings.isNullOrEmpty(paths))
|
||||
paths = nativesDir;
|
||||
else
|
||||
paths += File.pathSeparator + nativesDir;
|
||||
|
||||
System.setProperty("java.library.path", paths);
|
||||
|
||||
// hack the classloader now.
|
||||
try {
|
||||
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
|
||||
sysPathsField.setAccessible(true);
|
||||
sysPathsField.set(null, null);
|
||||
} catch (Throwable ignored) {}
|
||||
}
|
||||
|
||||
private static void attemptLogin(Map<String, String> argMap, String username, String password) {
|
||||
YggdrasilUserAuthentication auth = (YggdrasilUserAuthentication) (new YggdrasilAuthenticationService(Proxy.NO_PROXY, "1")).createUserAuthentication(Agent.MINECRAFT);
|
||||
auth.setUsername(username);
|
||||
auth.setPassword(password);
|
||||
|
||||
try {
|
||||
auth.logIn();
|
||||
} catch (AuthenticationException var4) {
|
||||
throw new RuntimeException(var4);
|
||||
}
|
||||
|
||||
argMap.put("accessToken", auth.getAuthenticatedToken());
|
||||
argMap.put("uuid", auth.getSelectedProfile().getId().toString().replace("-", ""));
|
||||
argMap.put("username", auth.getSelectedProfile().getName());
|
||||
argMap.put("userType", auth.getUserType().getName());
|
||||
argMap.put("userProperties", (new GsonBuilder()).registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create().toJson(auth.getUserProperties()));
|
||||
}
|
||||
}
|
||||
@@ -33,11 +33,11 @@ public abstract class MixinBlockStateContainer implements IBlockStateContainer {
|
||||
protected BitArray storage;
|
||||
|
||||
@Shadow
|
||||
protected IBlockStatePalette palette;
|
||||
protected IBlockStatePalette<IBlockState> palette;
|
||||
|
||||
@Override
|
||||
public IBlockState getAtPalette(int index) {
|
||||
return palette.getBlockState(index);
|
||||
return palette.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,7 +28,10 @@ import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL11.GL_ONE;
|
||||
import static org.lwjgl.opengl.GL11.GL_ZERO;
|
||||
import static org.lwjgl.opengl.GL14.GL_CONSTANT_ALPHA;
|
||||
import static org.lwjgl.opengl.GL14.GL_ONE_MINUS_CONSTANT_ALPHA;
|
||||
|
||||
@Mixin(ChunkRenderContainer.class)
|
||||
public class MixinChunkRenderContainer {
|
||||
@@ -41,11 +44,11 @@ public class MixinChunkRenderContainer {
|
||||
)
|
||||
)
|
||||
private BlockPos getPosition(RenderChunk renderChunkIn) {
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer() && Minecraft.getMinecraft().world.getChunk(renderChunkIn.getPosition()).isEmpty()) {
|
||||
GlStateManager.enableAlpha();
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer() && Minecraft.getInstance().world.getChunk(renderChunkIn.getPosition()).isEmpty()) {
|
||||
GlStateManager.enableAlphaTest();
|
||||
GlStateManager.enableBlend();
|
||||
GL14.glBlendColor(0, 0, 0, Baritone.settings().cachedChunksOpacity.value);
|
||||
GlStateManager.tryBlendFuncSeparate(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_ONE, GL_ZERO);
|
||||
GlStateManager.blendFuncSeparate(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_ONE, GL_ZERO);
|
||||
}
|
||||
return renderChunkIn.getPosition();
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public abstract class MixinChunkRenderWorker {
|
||||
)
|
||||
)
|
||||
private boolean isChunkExisting(ChunkRenderWorker worker, BlockPos pos, World world) {
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
|
||||
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||
IPlayerContext ctx = baritone.getPlayerContext();
|
||||
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import baritone.api.event.events.RotationMoveEvent;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -44,9 +45,8 @@ public abstract class MixinEntityLivingBase extends Entity {
|
||||
*/
|
||||
private RotationMoveEvent jumpRotationEvent;
|
||||
|
||||
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
|
||||
super(worldIn);
|
||||
this.jumpRotationEvent = jumpRotationEvent;
|
||||
public MixinEntityLivingBase(EntityType<?> entityTypeIn, World worldIn) {
|
||||
super(entityTypeIn, worldIn);
|
||||
}
|
||||
|
||||
@Inject(
|
||||
|
||||
@@ -58,10 +58,10 @@ public class MixinEntityPlayerSP {
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "onUpdate",
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/entity/EntityPlayerSP.isRiding()Z",
|
||||
target = "net/minecraft/client/entity/EntityPlayerSP.isPassenger()Z",
|
||||
shift = At.Shift.BY,
|
||||
by = -3
|
||||
)
|
||||
@@ -74,7 +74,7 @@ public class MixinEntityPlayerSP {
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "onUpdate",
|
||||
method = "tick",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/entity/EntityPlayerSP.onUpdateWalkingPlayer()V",
|
||||
@@ -90,7 +90,7 @@ public class MixinEntityPlayerSP {
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "onLivingUpdate",
|
||||
method = "livingTick",
|
||||
at = @At(
|
||||
value = "FIELD",
|
||||
target = "net/minecraft/entity/player/PlayerCapabilities.allowFlying:Z"
|
||||
@@ -105,7 +105,7 @@ public class MixinEntityPlayerSP {
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "onLivingUpdate",
|
||||
method = "livingTick",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/client/settings/KeyBinding.isKeyDown()Z"
|
||||
|
||||
@@ -20,24 +20,24 @@ package baritone.launch.mixins;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.RenderEvent;
|
||||
import net.minecraft.client.renderer.EntityRenderer;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(EntityRenderer.class)
|
||||
public class MixinEntityRenderer {
|
||||
@Mixin(GameRenderer.class)
|
||||
public class MixinGameRenderer {
|
||||
|
||||
@Inject(
|
||||
method = "renderWorldPass",
|
||||
method = "updateCameraAndRender(FJ)V",
|
||||
at = @At(
|
||||
value = "INVOKE_STRING",
|
||||
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
|
||||
args = {"ldc=hand"}
|
||||
)
|
||||
)
|
||||
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
||||
private void renderWorldPass(float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
ibaritone.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
|
||||
}
|
||||
99
src/launch/java/baritone/launch/mixins/MixinGuiChat.java
Normal file
99
src/launch/java/baritone/launch/mixins/MixinGuiChat.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.event.events.TabCompleteEvent;
|
||||
import com.mojang.brigadier.context.StringRange;
|
||||
import com.mojang.brigadier.suggestion.Suggestion;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import net.minecraft.client.gui.GuiChat;
|
||||
import net.minecraft.client.gui.GuiTextField;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 10/9/2019
|
||||
*/
|
||||
@Mixin(GuiChat.class)
|
||||
public class MixinGuiChat {
|
||||
|
||||
@Shadow
|
||||
protected GuiTextField inputField;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
protected List<String> commandUsage;
|
||||
|
||||
@Shadow
|
||||
private CompletableFuture<Suggestions> pendingSuggestions;
|
||||
|
||||
@Inject(
|
||||
method = "updateSuggestion",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private void preUpdateSuggestion(CallbackInfo ci) {
|
||||
// Anything that is present in the input text before the cursor position
|
||||
String prefix = this.inputField.getText().substring(0, Math.min(this.inputField.getText().length(), this.inputField.getCursorPosition()));
|
||||
|
||||
TabCompleteEvent event = new TabCompleteEvent(prefix);
|
||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onPreTabComplete(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
ci.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.completions != null) {
|
||||
ci.cancel();
|
||||
|
||||
// TODO: Support populating the command usage
|
||||
this.commandUsage.clear();
|
||||
|
||||
if (event.completions.length == 0) {
|
||||
this.pendingSuggestions = Suggestions.empty();
|
||||
} else {
|
||||
int offset = this.inputField.getText().endsWith(" ")
|
||||
? this.inputField.getCursorPosition()
|
||||
: this.inputField.getText().lastIndexOf(" ") + 1; // If there is no space this is still 0 haha yes
|
||||
|
||||
List<Suggestion> suggestionList = Stream.of(event.completions)
|
||||
.map(s -> new Suggestion(StringRange.between(offset, offset + s.length()), s))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Suggestions suggestions = new Suggestions(
|
||||
StringRange.between(offset, offset + suggestionList.stream().mapToInt(s -> s.getText().length()).max().orElse(0)),
|
||||
suggestionList);
|
||||
|
||||
this.pendingSuggestions = new CompletableFuture<>();
|
||||
this.pendingSuggestions.complete(suggestions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,14 +35,14 @@ public abstract class MixinItemStack implements IItemStack {
|
||||
@Final
|
||||
private Item item;
|
||||
|
||||
@Shadow
|
||||
private int itemDamage;
|
||||
|
||||
@Unique
|
||||
private int baritoneHash;
|
||||
|
||||
@Shadow
|
||||
protected abstract int getDamage();
|
||||
|
||||
private void recalculateHash() {
|
||||
baritoneHash = item == null ? -1 : item.hashCode() + itemDamage;
|
||||
baritoneHash = item == null ? -1 : item.hashCode() + getDamage();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
@@ -54,7 +54,7 @@ public abstract class MixinItemStack implements IItemStack {
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "setItemDamage",
|
||||
method = "setDamage",
|
||||
at = @At("TAIL")
|
||||
)
|
||||
private void onItemDamageSet(CallbackInfo ci) {
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.utils.accessor.IItemTool;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemTool;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(ItemTool.class)
|
||||
public class MixinItemTool implements IItemTool {
|
||||
@Shadow protected Item.ToolMaterial toolMaterial;
|
||||
|
||||
@Override
|
||||
public int getHarvestLevel() {
|
||||
return toolMaterial.getHarvestLevel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -88,10 +88,10 @@ public class MixinMinecraft {
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
|
||||
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Lnet/minecraft/client/gui/GuiScreen;)V",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
||||
private void preLoadWorld(WorldClient world, GuiScreen loadingScreen, CallbackInfo ci) {
|
||||
// If we're unloading the world but one doesn't exist, ignore it
|
||||
if (this.world == null && world == null) {
|
||||
return;
|
||||
@@ -108,10 +108,10 @@ public class MixinMinecraft {
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
|
||||
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Lnet/minecraft/client/gui/GuiScreen;)V",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
||||
private void postLoadWorld(WorldClient world, GuiScreen loadingScreen, CallbackInfo ci) {
|
||||
// still fire event for both null, as that means we've just finished exiting a world
|
||||
|
||||
// mc.world changing is only the primary baritone
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.utils.accessor.INBTTagLongArray;
|
||||
import net.minecraft.nbt.NBTTagLongArray;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
/**
|
||||
* @author rycbar
|
||||
* @since 26.09.2022
|
||||
*/
|
||||
@Mixin(NBTTagLongArray.class)
|
||||
public abstract class MixinNBTTagLongArray implements INBTTagLongArray {
|
||||
|
||||
@Accessor("data")
|
||||
@Override
|
||||
public abstract long[] getLongArray();
|
||||
}
|
||||
@@ -25,10 +25,7 @@ import baritone.api.event.events.type.EventState;
|
||||
import baritone.cache.CachedChunk;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.network.play.server.SPacketBlockChange;
|
||||
import net.minecraft.network.play.server.SPacketChunkData;
|
||||
import net.minecraft.network.play.server.SPacketCombatEvent;
|
||||
import net.minecraft.network.play.server.SPacketMultiBlockChange;
|
||||
import net.minecraft.network.play.server.*;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -46,7 +43,7 @@ public class MixinNetHandlerPlayClient {
|
||||
method = "handleChunkData",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/world/chunk/Chunk.read(Lnet/minecraft/network/PacketBuffer;IZ)V"
|
||||
target = "net/minecraft/client/multiplayer/ChunkProviderClient.func_212474_a(IILnet/minecraft/network/PacketBuffer;IZ)Lnet/minecraft/world/chunk/Chunk;"
|
||||
)
|
||||
)
|
||||
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||
@@ -85,6 +82,36 @@ public class MixinNetHandlerPlayClient {
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "processChunkUnload",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preChunkUnload(SPacketUnloadChunk packet, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
EntityPlayerSP player = ibaritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(EventState.PRE, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "processChunkUnload",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postChunkUnload(SPacketUnloadChunk packet, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
EntityPlayerSP player = ibaritone.getPlayerContext().player();
|
||||
if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(EventState.POST, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "handleBlockChange",
|
||||
at = @At("RETURN")
|
||||
@@ -93,7 +120,7 @@ public class MixinNetHandlerPlayClient {
|
||||
if (!Baritone.settings().repackOnAnyBlockChange.value) {
|
||||
return;
|
||||
}
|
||||
if (!CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(packetIn.getBlockState().getBlock())) {
|
||||
if (!CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(packetIn.getState().getBlock())) {
|
||||
return;
|
||||
}
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
@@ -103,8 +130,8 @@ public class MixinNetHandlerPlayClient {
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
ChunkEvent.Type.POPULATE_FULL,
|
||||
packetIn.getBlockPosition().getX() >> 4,
|
||||
packetIn.getBlockPosition().getZ() >> 4
|
||||
packetIn.getPos().getX() >> 4,
|
||||
packetIn.getPos().getZ() >> 4
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class MixinNetworkManager {
|
||||
method = "dispatchPacket",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
||||
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>> futureListeners, CallbackInfo ci) {
|
||||
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
@@ -69,7 +69,7 @@ public class MixinNetworkManager {
|
||||
method = "dispatchPacket",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
||||
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>> futureListeners, CallbackInfo ci) {
|
||||
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||
return;
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public class MixinNetworkManager {
|
||||
method = "channelRead0",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/network/Packet.processPacket(Lnet/minecraft/network/INetHandler;)V"
|
||||
target = "net/minecraft/network/NetworkManager.processPacket(Lnet/minecraft/network/Packet;Lnet/minecraft/network/INetHandler;)V"
|
||||
)
|
||||
)
|
||||
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
||||
|
||||
@@ -23,8 +23,8 @@ import baritone.api.utils.IPlayerContext;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.chunk.RenderChunk;
|
||||
import net.minecraft.client.renderer.chunk.RenderChunkCache;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.ChunkCache;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -40,43 +40,11 @@ public class MixinRenderChunk {
|
||||
method = "rebuildChunk",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/world/ChunkCache.isEmpty()Z"
|
||||
target = "net/minecraft/client/renderer/chunk/RenderChunkCache.getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/state/IBlockState;"
|
||||
)
|
||||
)
|
||||
private boolean isEmpty(ChunkCache chunkCache) {
|
||||
if (!chunkCache.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
|
||||
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||
IPlayerContext ctx = baritone.getPlayerContext();
|
||||
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
||||
BlockPos position = ((RenderChunk) (Object) this).getPosition();
|
||||
// RenderChunk extends from -1,-1,-1 to +16,+16,+16
|
||||
// then the constructor of ChunkCache extends it one more (presumably to get things like the connected status of fences? idk)
|
||||
// so if ANY of the adjacent chunks are loaded, we are unempty
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
for (int dz = -1; dz <= 1; dz++) {
|
||||
if (baritone.bsi.isLoaded(16 * dx + position.getX(), 16 * dz + position.getZ())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "rebuildChunk",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/world/ChunkCache.getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/state/IBlockState;"
|
||||
)
|
||||
)
|
||||
private IBlockState getBlockState(ChunkCache chunkCache, BlockPos pos) {
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
|
||||
private IBlockState getBlockState(RenderChunkCache chunkCache, BlockPos pos) {
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
|
||||
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||
IPlayerContext ctx = baritone.getPlayerContext();
|
||||
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
||||
|
||||
@@ -17,23 +17,31 @@
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import net.minecraft.client.gui.GuiChat;
|
||||
import baritone.Baritone;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.chunk.RenderChunkCache;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(GuiChat.ChatTabCompleter.class)
|
||||
public abstract class MixinChatTabCompleter extends MixinTabCompleter {
|
||||
@Mixin(RenderChunkCache.class)
|
||||
public class MixinRenderChunkCache {
|
||||
|
||||
@Inject(
|
||||
method = "complete",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
@Redirect(
|
||||
method = "generateCache",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "net/minecraft/world/chunk/Chunk.isEmptyBetween(II)Z"
|
||||
)
|
||||
)
|
||||
private void onComplete(CallbackInfo ci) {
|
||||
if (dontComplete) {
|
||||
ci.cancel();
|
||||
private static boolean isEmpty(Chunk chunk, int yStart, int yEnd) {
|
||||
if (!chunk.isEmptyBetween(yStart, yEnd)) {
|
||||
return false;
|
||||
}
|
||||
if (chunk.isEmpty() && Baritone.settings().renderCachedChunks.value && Minecraft.getInstance().getIntegratedServer() == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -38,9 +38,9 @@ public class MixinRenderList {
|
||||
)
|
||||
)
|
||||
private void popMatrix() {
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
|
||||
// reset the blend func to normal (not dependent on constant alpha)
|
||||
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
GlStateManager.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
}
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(targets = "net.minecraft.block.state.BlockStateContainer$StateImplementation")
|
||||
public abstract class MixinStateImplementation {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private ImmutableMap<IProperty<?>, Comparable<?>> properties;
|
||||
|
||||
/**
|
||||
* Block states are fucking immutable
|
||||
*/
|
||||
@Unique
|
||||
private int hashCode;
|
||||
|
||||
@Inject(
|
||||
method = "<init>*",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void onInit(CallbackInfo ci) {
|
||||
hashCode = properties.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache this instead of using the fucking map every time
|
||||
*
|
||||
* @author LoganDark
|
||||
* @reason Regular IBlockState generates a new hash every fucking time. This is not needed when scanning millions
|
||||
* per second
|
||||
*/
|
||||
@Override
|
||||
@Overwrite
|
||||
public int hashCode() {
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.TabCompleteEvent;
|
||||
import net.minecraft.client.gui.GuiChat;
|
||||
import net.minecraft.client.gui.GuiTextField;
|
||||
import net.minecraft.util.TabCompleter;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(TabCompleter.class)
|
||||
public abstract class MixinTabCompleter {
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
protected GuiTextField textField;
|
||||
|
||||
@Shadow
|
||||
protected boolean requestedCompletions;
|
||||
|
||||
@Shadow
|
||||
public abstract void setCompletions(String... newCompl);
|
||||
|
||||
@Unique
|
||||
protected boolean dontComplete = false;
|
||||
|
||||
@Inject(
|
||||
method = "requestCompletions",
|
||||
at = @At("HEAD"),
|
||||
cancellable = true
|
||||
)
|
||||
private void onRequestCompletions(String prefix, CallbackInfo ci) {
|
||||
if (!((Object) this instanceof GuiChat.ChatTabCompleter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
IBaritone baritone = BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||
|
||||
TabCompleteEvent event = new TabCompleteEvent(prefix);
|
||||
baritone.getGameEventHandler().onPreTabComplete(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
ci.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.completions != null) {
|
||||
ci.cancel();
|
||||
|
||||
this.dontComplete = true;
|
||||
|
||||
try {
|
||||
this.requestedCompletions = true;
|
||||
setCompletions(event.completions);
|
||||
} finally {
|
||||
this.dontComplete = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,9 +38,9 @@ public class MixinVboRenderList {
|
||||
)
|
||||
)
|
||||
private void popMatrix() {
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
|
||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
|
||||
// reset the blend func to normal (not dependent on constant alpha)
|
||||
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
GlStateManager.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||
}
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.launch.mixins;
|
||||
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.event.events.ChunkEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 8/2/2018
|
||||
*/
|
||||
@Mixin(WorldClient.class)
|
||||
public class MixinWorldClient {
|
||||
|
||||
@Inject(
|
||||
method = "doPreChunk",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void preDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.PRE,
|
||||
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||
chunkX,
|
||||
chunkZ
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "doPreChunk",
|
||||
at = @At("RETURN")
|
||||
)
|
||||
private void postDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
|
||||
ibaritone.getGameEventHandler().onChunkEvent(
|
||||
new ChunkEvent(
|
||||
EventState.POST,
|
||||
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||
chunkX,
|
||||
chunkZ
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,27 +11,23 @@
|
||||
"MixinAnvilChunkLoader",
|
||||
"MixinBitArray",
|
||||
"MixinBlockStateContainer",
|
||||
"MixinChatTabCompleter",
|
||||
"MixinChunkProviderClient",
|
||||
"MixinChunkProviderServer",
|
||||
"MixinChunkRenderContainer",
|
||||
"MixinChunkRenderWorker",
|
||||
"MixinEntityLivingBase",
|
||||
"MixinEntityPlayerSP",
|
||||
"MixinEntityRenderer",
|
||||
"MixinGameRenderer",
|
||||
"MixinGuiChat",
|
||||
"MixinGuiScreen",
|
||||
"MixinItemStack",
|
||||
"MixinItemTool",
|
||||
"MixinMinecraft",
|
||||
"MixinNBTTagLongArray",
|
||||
"MixinNetHandlerPlayClient",
|
||||
"MixinNetworkManager",
|
||||
"MixinPlayerControllerMP",
|
||||
"MixinRenderChunk",
|
||||
"MixinRenderChunkCache",
|
||||
"MixinRenderList",
|
||||
"MixinStateImplementation",
|
||||
"MixinTabCompleter",
|
||||
"MixinVboRenderList",
|
||||
"MixinWorldClient"
|
||||
"MixinVboRenderList"
|
||||
]
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class Baritone implements IBaritone {
|
||||
static {
|
||||
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||
|
||||
dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
||||
dir = new File(Minecraft.getInstance().gameDir, "baritone");
|
||||
if (!Files.exists(dir.toPath())) {
|
||||
try {
|
||||
Files.createDirectories(dir.toPath());
|
||||
@@ -68,8 +68,8 @@ public class Baritone implements IBaritone {
|
||||
|
||||
private PathingBehavior pathingBehavior;
|
||||
private LookBehavior lookBehavior;
|
||||
private MemoryBehavior memoryBehavior;
|
||||
private InventoryBehavior inventoryBehavior;
|
||||
private WaypointBehavior waypointBehavior;
|
||||
private InputOverrideHandler inputOverrideHandler;
|
||||
|
||||
private FollowProcess followProcess;
|
||||
@@ -100,9 +100,9 @@ public class Baritone implements IBaritone {
|
||||
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
|
||||
pathingBehavior = new PathingBehavior(this);
|
||||
lookBehavior = new LookBehavior(this);
|
||||
memoryBehavior = new MemoryBehavior(this);
|
||||
inventoryBehavior = new InventoryBehavior(this);
|
||||
inputOverrideHandler = new InputOverrideHandler(this);
|
||||
waypointBehavior = new WaypointBehavior(this);
|
||||
}
|
||||
|
||||
this.pathingControlManager = new PathingControlManager(this);
|
||||
@@ -151,6 +151,10 @@ public class Baritone implements IBaritone {
|
||||
return this.playerContext;
|
||||
}
|
||||
|
||||
public MemoryBehavior getMemoryBehavior() {
|
||||
return this.memoryBehavior;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FollowProcess getFollowProcess() {
|
||||
return this.followProcess;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
package baritone.behavior;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.BaritoneAPI;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.utils.ToolSet;
|
||||
import net.minecraft.block.Block;
|
||||
@@ -113,9 +112,6 @@ public final class InventoryBehavior extends Behavior {
|
||||
if (stack.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (Baritone.settings().itemSaver.value && (stack.getItemDamage() + Baritone.settings().itemSaverThreshold.value) >= stack.getMaxDamage() && stack.getMaxDamage() > 1) {
|
||||
continue;
|
||||
}
|
||||
if (cla$$.isInstance(stack.getItem())) {
|
||||
double speed = ToolSet.calculateSpeedVsBlock(stack, against.getDefaultState()); // takes into account enchants
|
||||
if (speed > bestSpeed) {
|
||||
@@ -138,7 +134,7 @@ public final class InventoryBehavior extends Behavior {
|
||||
|
||||
public boolean selectThrowawayForLocation(boolean select, int x, int y, int z) {
|
||||
IBlockState maybe = baritone.getBuilderProcess().placeAt(x, y, z, baritone.bsi.get0(x, y, z));
|
||||
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && maybe.equals(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(ctx.world(), ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ, stack.getItem().getMetadata(stack.getMetadata()), ctx.player())))) {
|
||||
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && maybe.equals(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(new BlockItemUseContext(new ItemUseContext(ctx.player(), stack, ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ)))))) {
|
||||
return true; // gotem
|
||||
}
|
||||
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && ((ItemBlock) stack.getItem()).getBlock().equals(maybe.getBlock()))) {
|
||||
@@ -153,10 +149,6 @@ public final class InventoryBehavior extends Behavior {
|
||||
}
|
||||
|
||||
public boolean throwaway(boolean select, Predicate<? super ItemStack> desired) {
|
||||
return throwaway(select, desired, Baritone.settings().allowInventory.value);
|
||||
}
|
||||
|
||||
public boolean throwaway(boolean select, Predicate<? super ItemStack> desired, boolean allowInventory) {
|
||||
EntityPlayerSP p = ctx.player();
|
||||
NonNullList<ItemStack> inv = p.inventory.mainInventory;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
@@ -189,19 +181,6 @@ public final class InventoryBehavior extends Behavior {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allowInventory) {
|
||||
for (int i = 9; i < 36; i++) {
|
||||
if (desired.test(inv.get(i))) {
|
||||
swapWithHotBar(i, 7);
|
||||
if (select) {
|
||||
p.inventory.currentItem = 7;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,6 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
|
||||
/**
|
||||
* Target's values are as follows:
|
||||
* <p>
|
||||
* getFirst() -> yaw
|
||||
* getSecond() -> pitch
|
||||
*/
|
||||
private Rotation target;
|
||||
|
||||
@@ -53,6 +50,13 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
||||
@Override
|
||||
public void updateTarget(Rotation target, boolean force) {
|
||||
this.target = target;
|
||||
if (!force) {
|
||||
double rand = Math.random() - 0.5;
|
||||
if (Math.abs(rand) < 0.1) {
|
||||
rand *= 4;
|
||||
}
|
||||
this.target = new Rotation(this.target.getYaw() + (float) (rand * Baritone.settings().randomLooking113.value), this.target.getPitch());
|
||||
}
|
||||
this.force = force || !Baritone.settings().freeLook.value;
|
||||
}
|
||||
|
||||
|
||||
292
src/main/java/baritone/behavior/MemoryBehavior.java
Normal file
292
src/main/java/baritone/behavior/MemoryBehavior.java
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.behavior;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.cache.Waypoint;
|
||||
import baritone.api.event.events.BlockInteractEvent;
|
||||
import baritone.api.event.events.PacketEvent;
|
||||
import baritone.api.event.events.PlayerUpdateEvent;
|
||||
import baritone.api.event.events.TickEvent;
|
||||
import baritone.api.event.events.type.EventState;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.cache.ContainerMemory;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockBed;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.play.client.CPacketCloseWindow;
|
||||
import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock;
|
||||
import net.minecraft.network.play.server.SPacketCloseWindow;
|
||||
import net.minecraft.network.play.server.SPacketOpenWindow;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityLockable;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* doesn't work for horse inventories :^)
|
||||
*
|
||||
* @author Brady
|
||||
* @since 8/6/2018
|
||||
*/
|
||||
public final class MemoryBehavior extends Behavior {
|
||||
|
||||
private final List<FutureInventory> futureInventories = new ArrayList<>(); // this is per-bot
|
||||
|
||||
private Integer enderChestWindowId; // nae nae
|
||||
|
||||
public MemoryBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onTick(TickEvent event) {
|
||||
if (!Baritone.settings().containerMemory.value) {
|
||||
return;
|
||||
}
|
||||
if (event.getType() == TickEvent.Type.OUT) {
|
||||
enderChestWindowId = null;
|
||||
futureInventories.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
|
||||
if (event.getState() == EventState.PRE) {
|
||||
updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onSendPacket(PacketEvent event) {
|
||||
if (!Baritone.settings().containerMemory.value) {
|
||||
return;
|
||||
}
|
||||
Packet p = event.getPacket();
|
||||
|
||||
if (event.getState() == EventState.PRE) {
|
||||
if (p instanceof CPacketPlayerTryUseItemOnBlock) {
|
||||
CPacketPlayerTryUseItemOnBlock packet = event.cast();
|
||||
|
||||
TileEntity tileEntity = ctx.world().getTileEntity(packet.getPos());
|
||||
// if tileEntity is an ender chest, we don't need to do anything. ender chests are treated the same regardless of what coordinate right clicked
|
||||
|
||||
// Ensure the TileEntity is a container of some sort
|
||||
if (tileEntity instanceof TileEntityLockable) {
|
||||
|
||||
TileEntityLockable lockable = (TileEntityLockable) tileEntity;
|
||||
int size = lockable.getSizeInventory();
|
||||
BetterBlockPos position = BetterBlockPos.from(tileEntity.getPos());
|
||||
BetterBlockPos adj = BetterBlockPos.from(neighboringConnectedBlock(position));
|
||||
System.out.println(position + " " + adj);
|
||||
if (adj != null) {
|
||||
size *= 2; // double chest or double trapped chest
|
||||
if (adj.getX() < position.getX() || adj.getZ() < position.getZ()) {
|
||||
position = adj; // standardize on the lower coordinate, regardless of which side of the large chest we right clicked
|
||||
}
|
||||
}
|
||||
|
||||
this.futureInventories.add(new FutureInventory(System.nanoTime() / 1000000L, size, lockable.getGuiID(), position));
|
||||
}
|
||||
}
|
||||
|
||||
if (p instanceof CPacketCloseWindow) {
|
||||
getCurrent().save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onReceivePacket(PacketEvent event) {
|
||||
if (!Baritone.settings().containerMemory.value) {
|
||||
return;
|
||||
}
|
||||
Packet p = event.getPacket();
|
||||
|
||||
if (event.getState() == EventState.PRE) {
|
||||
if (p instanceof SPacketOpenWindow) {
|
||||
SPacketOpenWindow packet = event.cast();
|
||||
// Remove any entries that were created over a second ago, this should make up for INSANE latency
|
||||
futureInventories.removeIf(i -> System.nanoTime() / 1000000L - i.time > 1000);
|
||||
|
||||
System.out.println("Received packet " + packet.getGuiId() + " " + packet.getEntityId() + " " + packet.getSlotCount() + " " + packet.getWindowId());
|
||||
System.out.println(packet.getWindowTitle());
|
||||
if (packet.getWindowTitle() instanceof TextComponentTranslation && ((TextComponentTranslation) packet.getWindowTitle()).getKey().equals("container.enderchest")) {
|
||||
// title is not customized (i.e. this isn't just a renamed shulker)
|
||||
enderChestWindowId = packet.getWindowId();
|
||||
return;
|
||||
}
|
||||
futureInventories.stream()
|
||||
.filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
|
||||
.findFirst().ifPresent(matched -> {
|
||||
// Remove the future inventory
|
||||
futureInventories.remove(matched);
|
||||
|
||||
// Setup the remembered inventory
|
||||
getCurrentContainer().setup(matched.pos, packet.getWindowId(), packet.getSlotCount());
|
||||
});
|
||||
}
|
||||
|
||||
if (p instanceof SPacketCloseWindow) {
|
||||
getCurrent().save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockInteract(BlockInteractEvent event) {
|
||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, BetterBlockPos.from(event.getPos())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerDeath() {
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet()));
|
||||
}
|
||||
|
||||
|
||||
private void updateInventory() {
|
||||
if (!Baritone.settings().containerMemory.value) {
|
||||
return;
|
||||
}
|
||||
int windowId = ctx.player().openContainer.windowId;
|
||||
if (enderChestWindowId != null) {
|
||||
if (windowId == enderChestWindowId) {
|
||||
getCurrent().contents = ctx.player().openContainer.getInventory().subList(0, 27);
|
||||
} else {
|
||||
getCurrent().save();
|
||||
enderChestWindowId = null;
|
||||
}
|
||||
}
|
||||
if (getCurrentContainer() != null) {
|
||||
getCurrentContainer().getInventoryFromWindow(windowId).ifPresent(inventory -> inventory.updateFromOpenWindow(ctx));
|
||||
}
|
||||
}
|
||||
|
||||
private ContainerMemory getCurrentContainer() {
|
||||
if (baritone.getWorldProvider().getCurrentWorld() == null) {
|
||||
return null;
|
||||
}
|
||||
return (ContainerMemory) baritone.getWorldProvider().getCurrentWorld().getContainerMemory();
|
||||
}
|
||||
|
||||
private BlockPos neighboringConnectedBlock(BlockPos in) {
|
||||
BlockStateInterface bsi = baritone.bsi;
|
||||
Block block = bsi.get0(in).getBlock();
|
||||
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
|
||||
return null; // other things that have contents, but can be placed adjacent without combining
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
BlockPos adj = in.offset(EnumFacing.byHorizontalIndex(i));
|
||||
if (bsi.get0(adj).getBlock() == block) {
|
||||
return adj;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* An inventory that we are not yet fully aware of, but are expecting to exist at some point in the future.
|
||||
*/
|
||||
private static final class FutureInventory {
|
||||
|
||||
/**
|
||||
* The time that we initially expected the inventory to be provided, in milliseconds
|
||||
*/
|
||||
private final long time;
|
||||
|
||||
/**
|
||||
* The amount of slots in the inventory
|
||||
*/
|
||||
private final int slots;
|
||||
|
||||
/**
|
||||
* The type of inventory
|
||||
*/
|
||||
private final String type;
|
||||
|
||||
/**
|
||||
* The position of the inventory container
|
||||
*/
|
||||
private final BlockPos pos;
|
||||
|
||||
private FutureInventory(long time, int slots, String type, BlockPos pos) {
|
||||
this.time = time;
|
||||
this.slots = slots;
|
||||
this.type = type;
|
||||
this.pos = pos;
|
||||
// betterblockpos has censoring
|
||||
System.out.println("Future inventory created " + time + " " + slots + " " + type + " " + BetterBlockPos.from(pos));
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<List<ItemStack>> echest() {
|
||||
return Optional.ofNullable(getCurrent().contents).map(Collections::unmodifiableList);
|
||||
}
|
||||
|
||||
public EnderChestMemory getCurrent() {
|
||||
Path path = baritone.getWorldProvider().getCurrentWorld().directory;
|
||||
return EnderChestMemory.getByServerAndPlayer(path.getParent(), ctx.player().getUniqueID());
|
||||
}
|
||||
|
||||
public static class EnderChestMemory {
|
||||
|
||||
private static final Map<Path, EnderChestMemory> memory = new HashMap<>();
|
||||
private final Path enderChest;
|
||||
private List<ItemStack> contents;
|
||||
|
||||
private EnderChestMemory(Path enderChest) {
|
||||
this.enderChest = enderChest;
|
||||
System.out.println("Echest storing in " + enderChest);
|
||||
try {
|
||||
this.contents = ContainerMemory.readItemStacks(Files.readAllBytes(enderChest));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("CANNOT read echest =( =(");
|
||||
this.contents = null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void save() {
|
||||
System.out.println("Saving");
|
||||
if (contents != null) {
|
||||
try {
|
||||
enderChest.getParent().toFile().mkdir();
|
||||
Files.write(enderChest, ContainerMemory.writeItemStacks(contents));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("CANNOT save echest =( =(");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized EnderChestMemory getByServerAndPlayer(Path serverStorage, UUID player) {
|
||||
return memory.computeIfAbsent(serverStorage.resolve("echests").resolve(player.toString()), EnderChestMemory::new);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,10 +52,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
private Goal goal;
|
||||
private CalculationContext context;
|
||||
|
||||
/*eta*/
|
||||
private int ticksElapsedSoFar;
|
||||
private BetterBlockPos startPosition;
|
||||
|
||||
private boolean safeToCancel;
|
||||
private boolean pauseRequestedLastTick;
|
||||
private boolean unpausedLastTick;
|
||||
@@ -99,11 +95,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
baritone.getPathingControlManager().cancelEverything();
|
||||
return;
|
||||
}
|
||||
|
||||
expectedSegmentStart = pathStart();
|
||||
baritone.getPathingControlManager().preTick();
|
||||
tickPath();
|
||||
ticksElapsedSoFar++;
|
||||
dispatchEvents();
|
||||
}
|
||||
|
||||
@@ -378,40 +372,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
return context;
|
||||
}
|
||||
|
||||
public Optional<Double> estimatedTicksToGoal() {
|
||||
BetterBlockPos currentPos = ctx.playerFeet();
|
||||
if (goal == null || currentPos == null || startPosition == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
if (goal.isInGoal(ctx.playerFeet())) {
|
||||
resetEstimatedTicksToGoal();
|
||||
return Optional.of(0.0);
|
||||
}
|
||||
if (ticksElapsedSoFar == 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
double current = goal.heuristic(currentPos.x, currentPos.y, currentPos.z);
|
||||
double start = goal.heuristic(startPosition.x, startPosition.y, startPosition.z);
|
||||
if (current == start) {// can't check above because current and start can be equal even if currentPos and startPosition are not
|
||||
return Optional.empty();
|
||||
}
|
||||
double eta = Math.abs(current - goal.heuristic()) * ticksElapsedSoFar / Math.abs(start - current);
|
||||
return Optional.of(eta);
|
||||
}
|
||||
|
||||
private void resetEstimatedTicksToGoal() {
|
||||
resetEstimatedTicksToGoal(expectedSegmentStart);
|
||||
}
|
||||
|
||||
private void resetEstimatedTicksToGoal(BlockPos start) {
|
||||
resetEstimatedTicksToGoal(new BetterBlockPos(start));
|
||||
}
|
||||
|
||||
private void resetEstimatedTicksToGoal(BetterBlockPos start) {
|
||||
ticksElapsedSoFar = 0;
|
||||
startPosition = start;
|
||||
}
|
||||
|
||||
/**
|
||||
* See issue #209
|
||||
*
|
||||
@@ -508,7 +468,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
||||
if (executor.get().getPath().positions().contains(expectedSegmentStart)) {
|
||||
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
|
||||
current = executor.get();
|
||||
resetEstimatedTicksToGoal(start);
|
||||
} else {
|
||||
logDebug("Warning: discarding orphan path segment with incorrect start");
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.behavior;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.cache.IWaypoint;
|
||||
import baritone.api.cache.Waypoint;
|
||||
import baritone.api.event.events.BlockInteractEvent;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import net.minecraft.block.BlockBed;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.util.text.event.ClickEvent;
|
||||
import net.minecraft.util.text.event.HoverEvent;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
|
||||
|
||||
public class WaypointBehavior extends Behavior {
|
||||
|
||||
|
||||
public WaypointBehavior(Baritone baritone) {
|
||||
super(baritone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockInteract(BlockInteractEvent event) {
|
||||
if (!Baritone.settings().doBedWaypoints.value)
|
||||
return;
|
||||
if (event.getType() == BlockInteractEvent.Type.USE) {
|
||||
BetterBlockPos pos = BetterBlockPos.from(event.getPos());
|
||||
IBlockState state = BlockStateInterface.get(ctx, pos);
|
||||
if (state.getBlock() instanceof BlockBed) {
|
||||
if (state.getValue(BlockBed.PART) == BlockBed.EnumPartType.FOOT) {
|
||||
pos = pos.offset(state.getValue(BlockBed.FACING));
|
||||
}
|
||||
Set<IWaypoint> waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(IWaypoint.Tag.BED);
|
||||
boolean exists = waypoints.stream().map(IWaypoint::getLocation).filter(pos::equals).findFirst().isPresent();
|
||||
if (!exists) {
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerDeath() {
|
||||
if (!Baritone.settings().doDeathWaypoints.value)
|
||||
return;
|
||||
Waypoint deathWaypoint = new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet());
|
||||
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(deathWaypoint);
|
||||
ITextComponent component = new TextComponentString("Death position saved.");
|
||||
component.getStyle()
|
||||
.setColor(TextFormatting.WHITE)
|
||||
.setHoverEvent(new HoverEvent(
|
||||
HoverEvent.Action.SHOW_TEXT,
|
||||
new TextComponentString("Click to goto death")
|
||||
))
|
||||
.setClickEvent(new ClickEvent(
|
||||
ClickEvent.Action.RUN_COMMAND,
|
||||
String.format(
|
||||
"%s%s goto %s @ %d",
|
||||
FORCE_COMMAND_PREFIX,
|
||||
"wp",
|
||||
deathWaypoint.getTag().getName(),
|
||||
deathWaypoint.getCreationTimestamp()
|
||||
)
|
||||
));
|
||||
Helper.HELPER.logDirect(component);
|
||||
}
|
||||
|
||||
}
|
||||
57
src/main/java/baritone/cache/CachedChunk.java
vendored
57
src/main/java/baritone/cache/CachedChunk.java
vendored
@@ -38,23 +38,13 @@ import java.util.Map;
|
||||
public final class CachedChunk {
|
||||
|
||||
public static final ImmutableSet<Block> BLOCKS_TO_KEEP_TRACK_OF = ImmutableSet.of(
|
||||
Blocks.DIAMOND_BLOCK,
|
||||
//Blocks.COAL_ORE,
|
||||
Blocks.COAL_BLOCK,
|
||||
//Blocks.IRON_ORE,
|
||||
Blocks.IRON_BLOCK,
|
||||
//Blocks.GOLD_ORE,
|
||||
Blocks.GOLD_BLOCK,
|
||||
Blocks.EMERALD_ORE,
|
||||
Blocks.EMERALD_BLOCK,
|
||||
|
||||
Blocks.ENDER_CHEST,
|
||||
Blocks.FURNACE,
|
||||
Blocks.CHEST,
|
||||
Blocks.TRAPPED_CHEST,
|
||||
Blocks.END_PORTAL,
|
||||
Blocks.END_PORTAL_FRAME,
|
||||
Blocks.MOB_SPAWNER,
|
||||
Blocks.SPAWNER,
|
||||
Blocks.BARRIER,
|
||||
Blocks.OBSERVER,
|
||||
Blocks.WHITE_SHULKER_BOX,
|
||||
@@ -65,7 +55,7 @@ public final class CachedChunk {
|
||||
Blocks.LIME_SHULKER_BOX,
|
||||
Blocks.PINK_SHULKER_BOX,
|
||||
Blocks.GRAY_SHULKER_BOX,
|
||||
Blocks.SILVER_SHULKER_BOX,
|
||||
Blocks.LIGHT_GRAY_SHULKER_BOX,
|
||||
Blocks.CYAN_SHULKER_BOX,
|
||||
Blocks.PURPLE_SHULKER_BOX,
|
||||
Blocks.BLUE_SHULKER_BOX,
|
||||
@@ -73,25 +63,52 @@ public final class CachedChunk {
|
||||
Blocks.GREEN_SHULKER_BOX,
|
||||
Blocks.RED_SHULKER_BOX,
|
||||
Blocks.BLACK_SHULKER_BOX,
|
||||
Blocks.PORTAL,
|
||||
Blocks.NETHER_PORTAL,
|
||||
Blocks.HOPPER,
|
||||
Blocks.BEACON,
|
||||
Blocks.BREWING_STAND,
|
||||
Blocks.SKULL,
|
||||
|
||||
// TODO: Maybe add a predicate for blocks to keep track of?
|
||||
// This should really not need to happen
|
||||
Blocks.CREEPER_HEAD,
|
||||
Blocks.CREEPER_WALL_HEAD,
|
||||
Blocks.DRAGON_HEAD,
|
||||
Blocks.DRAGON_WALL_HEAD,
|
||||
Blocks.PLAYER_HEAD,
|
||||
Blocks.PLAYER_WALL_HEAD,
|
||||
Blocks.ZOMBIE_HEAD,
|
||||
Blocks.ZOMBIE_WALL_HEAD,
|
||||
Blocks.SKELETON_SKULL,
|
||||
Blocks.SKELETON_WALL_SKULL,
|
||||
Blocks.WITHER_SKELETON_SKULL,
|
||||
Blocks.WITHER_SKELETON_WALL_SKULL,
|
||||
Blocks.ENCHANTING_TABLE,
|
||||
Blocks.ANVIL,
|
||||
Blocks.LIT_FURNACE,
|
||||
Blocks.BED,
|
||||
Blocks.WHITE_BED,
|
||||
Blocks.ORANGE_BED,
|
||||
Blocks.MAGENTA_BED,
|
||||
Blocks.LIGHT_BLUE_BED,
|
||||
Blocks.YELLOW_BED,
|
||||
Blocks.LIME_BED,
|
||||
Blocks.PINK_BED,
|
||||
Blocks.GRAY_BED,
|
||||
Blocks.LIGHT_GRAY_BED,
|
||||
Blocks.CYAN_BED,
|
||||
Blocks.PURPLE_BED,
|
||||
Blocks.BLUE_BED,
|
||||
Blocks.BROWN_BED,
|
||||
Blocks.GREEN_BED,
|
||||
Blocks.RED_BED,
|
||||
Blocks.BLACK_BED,
|
||||
Blocks.DRAGON_EGG,
|
||||
Blocks.JUKEBOX,
|
||||
Blocks.END_GATEWAY,
|
||||
Blocks.WEB,
|
||||
Blocks.COBWEB,
|
||||
Blocks.NETHER_WART,
|
||||
Blocks.LADDER,
|
||||
Blocks.VINE
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* The size of the chunk data in bits. Equal to 16 KiB.
|
||||
* <p>
|
||||
@@ -170,8 +187,8 @@ public final class CachedChunk {
|
||||
|
||||
// we have this exact block, it's a surface block
|
||||
/*System.out.println("Saying that " + x + "," + y + "," + z + " is " + state);
|
||||
if (!Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
|
||||
throw new IllegalStateException("failed " + Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
|
||||
if (!Minecraft.getInstance().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
|
||||
throw new IllegalStateException("failed " + Minecraft.getInstance().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
|
||||
}*/
|
||||
return overview[internalPos];
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
|
||||
private BlockPos guessPosition() {
|
||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||
IWorldData data = ibaritone.getWorldProvider().getCurrentWorld();
|
||||
if (data != null && data.getCachedWorld() == this && ibaritone.getPlayerContext().player() != null) {
|
||||
if (data != null && data.getCachedWorld() == this) {
|
||||
return ibaritone.getPlayerContext().playerFeet();
|
||||
}
|
||||
}
|
||||
|
||||
19
src/main/java/baritone/cache/ChunkPacker.java
vendored
19
src/main/java/baritone/cache/ChunkPacker.java
vendored
@@ -24,9 +24,10 @@ import net.minecraft.block.*;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.chunk.BlockStateContainer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -44,9 +45,9 @@ public final class ChunkPacker {
|
||||
Map<String, List<BlockPos>> specialBlocks = new HashMap<>();
|
||||
BitSet bitSet = new BitSet(CachedChunk.SIZE);
|
||||
try {
|
||||
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||
ChunkSection[] chunkInternalStorageArray = chunk.getSections();
|
||||
for (int y0 = 0; y0 < 16; y0++) {
|
||||
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||
ChunkSection extendedblockstorage = chunkInternalStorageArray[y0];
|
||||
if (extendedblockstorage == null) {
|
||||
// any 16x16x16 area that's all air will have null storage
|
||||
// for example, in an ocean biome, with air from y=64 to y=256
|
||||
@@ -58,7 +59,7 @@ public final class ChunkPacker {
|
||||
// since a bitset is initialized to all zero, and air is saved as zeros
|
||||
continue;
|
||||
}
|
||||
BlockStateContainer bsc = extendedblockstorage.getData();
|
||||
BlockStateContainer<IBlockState> bsc = extendedblockstorage.getData();
|
||||
int yReal = y0 << 4;
|
||||
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
|
||||
// for better cache locality, iterate in that order
|
||||
@@ -105,10 +106,9 @@ public final class ChunkPacker {
|
||||
return new CachedChunk(chunk.x, chunk.z, bitSet, blocks, specialBlocks, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
|
||||
private static PathingBlockType getPathingBlockType(IBlockState state, Chunk chunk, int x, int y, int z) {
|
||||
Block block = state.getBlock();
|
||||
if (block == Blocks.WATER || block == Blocks.FLOWING_WATER) {
|
||||
if (MovementHelper.isWater(state)) {
|
||||
// only water source blocks are plausibly usable, flowing water should be avoid
|
||||
// FLOWING_WATER is a waterfall, it doesn't really matter and caching it as AVOID just makes it look wrong
|
||||
if (MovementHelper.possiblyFlowing(state)) {
|
||||
@@ -123,7 +123,8 @@ public final class ChunkPacker {
|
||||
return PathingBlockType.AVOID;
|
||||
}
|
||||
if (x == 0 || x == 15 || z == 0 || z == 15) {
|
||||
if (BlockLiquid.getSlopeAngle(chunk.getWorld(), new BlockPos(x + (chunk.x << 4), y, z + (chunk.z << 4)), state.getMaterial(), state) == -1000.0F) {
|
||||
Vec3d flow = state.getFluidState().getFlow(chunk.getWorld(), new BlockPos(x + chunk.x << 4, y, z + chunk.z << 4));
|
||||
if (flow.x != 0.0 || flow.z != 0.0) {
|
||||
return PathingBlockType.WATER;
|
||||
}
|
||||
return PathingBlockType.AVOID;
|
||||
@@ -131,14 +132,14 @@ public final class ChunkPacker {
|
||||
return PathingBlockType.WATER;
|
||||
}
|
||||
|
||||
if (MovementHelper.avoidWalkingInto(block) || MovementHelper.isBottomSlab(state)) {
|
||||
if (MovementHelper.avoidWalkingInto(state) || MovementHelper.isBottomSlab(state)) {
|
||||
return PathingBlockType.AVOID;
|
||||
}
|
||||
// We used to do an AABB check here
|
||||
// however, this failed in the nether when you were near a nether fortress
|
||||
// because fences check their adjacent blocks in the world for their fence connection status to determine AABB shape
|
||||
// this caused a nullpointerexception when we saved chunks on unload, because they were unable to check their neighbors
|
||||
if (block == Blocks.AIR || block instanceof BlockTallGrass || block instanceof BlockDoublePlant || block instanceof BlockFlower) {
|
||||
if (block instanceof BlockAir || block instanceof BlockTallGrass || block instanceof BlockDoublePlant || block instanceof BlockFlower) {
|
||||
return PathingBlockType.AIR;
|
||||
}
|
||||
|
||||
|
||||
183
src/main/java/baritone/cache/ContainerMemory.java
vendored
Normal file
183
src/main/java/baritone/cache/ContainerMemory.java
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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.cache;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.cache.IContainerMemory;
|
||||
import baritone.api.cache.IRememberedInventory;
|
||||
import baritone.api.utils.IPlayerContext;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
public class ContainerMemory implements IContainerMemory {
|
||||
|
||||
private final Path saveTo;
|
||||
/**
|
||||
* The current remembered inventories
|
||||
*/
|
||||
private final Map<BlockPos, RememberedInventory> inventories = new HashMap<>();
|
||||
|
||||
|
||||
public ContainerMemory(Path saveTo) {
|
||||
this.saveTo = saveTo;
|
||||
try {
|
||||
read(Files.readAllBytes(saveTo));
|
||||
} catch (NoSuchFileException ignored) {
|
||||
inventories.clear();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
inventories.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void read(byte[] bytes) throws IOException {
|
||||
PacketBuffer in = new PacketBuffer(Unpooled.wrappedBuffer(bytes));
|
||||
int chests = in.readInt();
|
||||
for (int i = 0; i < chests; i++) {
|
||||
int x = in.readInt();
|
||||
int y = in.readInt();
|
||||
int z = in.readInt();
|
||||
RememberedInventory rem = new RememberedInventory();
|
||||
rem.items.addAll(readItemStacks(in));
|
||||
rem.size = rem.items.size();
|
||||
rem.windowId = -1;
|
||||
if (rem.items.isEmpty()) {
|
||||
continue; // this only happens if the list has no elements, not if the list has elements that are all empty item stacks
|
||||
}
|
||||
inventories.put(new BlockPos(x, y, z), rem);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void save() throws IOException {
|
||||
if (!Baritone.settings().containerMemory.value) {
|
||||
return;
|
||||
}
|
||||
ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE);
|
||||
PacketBuffer out = new PacketBuffer(buf);
|
||||
out.writeInt(inventories.size());
|
||||
for (Map.Entry<BlockPos, RememberedInventory> entry : inventories.entrySet()) {
|
||||
out = new PacketBuffer(out.writeInt(entry.getKey().getX()));
|
||||
out = new PacketBuffer(out.writeInt(entry.getKey().getY()));
|
||||
out = new PacketBuffer(out.writeInt(entry.getKey().getZ()));
|
||||
out = writeItemStacks(entry.getValue().getContents(), out);
|
||||
}
|
||||
Files.write(saveTo, out.array());
|
||||
}
|
||||
|
||||
public synchronized void setup(BlockPos pos, int windowId, int slotCount) {
|
||||
RememberedInventory inventory = inventories.computeIfAbsent(pos, x -> new RememberedInventory());
|
||||
inventory.windowId = windowId;
|
||||
inventory.size = slotCount;
|
||||
}
|
||||
|
||||
public synchronized Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
|
||||
return inventories.values().stream().filter(i -> i.windowId == windowId).findFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final synchronized RememberedInventory getInventoryByPos(BlockPos pos) {
|
||||
return inventories.get(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final synchronized Map<BlockPos, IRememberedInventory> getRememberedInventories() {
|
||||
// make a copy since this map is modified from the packet thread
|
||||
return new HashMap<>(inventories);
|
||||
}
|
||||
|
||||
public static List<ItemStack> readItemStacks(byte[] bytes) throws IOException {
|
||||
PacketBuffer in = new PacketBuffer(Unpooled.wrappedBuffer(bytes));
|
||||
return readItemStacks(in);
|
||||
}
|
||||
|
||||
public static List<ItemStack> readItemStacks(PacketBuffer in) throws IOException {
|
||||
int count = in.readInt();
|
||||
List<ItemStack> result = new ArrayList<>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
result.add(in.readItemStack());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] writeItemStacks(List<ItemStack> write) {
|
||||
ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE);
|
||||
PacketBuffer out = new PacketBuffer(buf);
|
||||
out = writeItemStacks(write, out);
|
||||
return out.array();
|
||||
}
|
||||
|
||||
public static PacketBuffer writeItemStacks(List<ItemStack> write, PacketBuffer out2) {
|
||||
PacketBuffer out = out2; // avoid reassigning an argument LOL
|
||||
out = new PacketBuffer(out.writeInt(write.size()));
|
||||
for (ItemStack stack : write) {
|
||||
out = out.writeItemStack(stack);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* An inventory that we are aware of.
|
||||
* <p>
|
||||
* Associated with a {@link BlockPos} in {@link ContainerMemory#inventories}.
|
||||
*/
|
||||
public static class RememberedInventory implements IRememberedInventory {
|
||||
|
||||
/**
|
||||
* The list of items in the inventory
|
||||
*/
|
||||
private final List<ItemStack> items;
|
||||
|
||||
/**
|
||||
* The last known window ID of the inventory
|
||||
*/
|
||||
private int windowId;
|
||||
|
||||
/**
|
||||
* The size of the inventory
|
||||
*/
|
||||
private int size;
|
||||
|
||||
private RememberedInventory() {
|
||||
this.items = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<ItemStack> getContents() {
|
||||
return Collections.unmodifiableList(this.items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public void updateFromOpenWindow(IPlayerContext ctx) {
|
||||
items.clear();
|
||||
items.addAll(ctx.player().openContainer.getInventory().subList(0, size));
|
||||
}
|
||||
}
|
||||
}
|
||||
17
src/main/java/baritone/cache/WorldData.java
vendored
17
src/main/java/baritone/cache/WorldData.java
vendored
@@ -19,6 +19,7 @@ package baritone.cache;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.cache.ICachedWorld;
|
||||
import baritone.api.cache.IContainerMemory;
|
||||
import baritone.api.cache.IWaypointCollection;
|
||||
import baritone.api.cache.IWorldData;
|
||||
|
||||
@@ -34,6 +35,7 @@ public class WorldData implements IWorldData {
|
||||
|
||||
public final CachedWorld cache;
|
||||
private final WaypointCollection waypoints;
|
||||
private final ContainerMemory containerMemory;
|
||||
//public final MapData map;
|
||||
public final Path directory;
|
||||
public final int dimension;
|
||||
@@ -42,6 +44,7 @@ public class WorldData implements IWorldData {
|
||||
this.directory = directory;
|
||||
this.cache = new CachedWorld(directory.resolve("cache"), dimension);
|
||||
this.waypoints = new WaypointCollection(directory.resolve("waypoints"));
|
||||
this.containerMemory = new ContainerMemory(directory.resolve("containers"));
|
||||
this.dimension = dimension;
|
||||
}
|
||||
|
||||
@@ -50,6 +53,15 @@ public class WorldData implements IWorldData {
|
||||
System.out.println("Started saving the world in a new thread");
|
||||
cache.save();
|
||||
});
|
||||
Baritone.getExecutor().execute(() -> {
|
||||
System.out.println("Started saving saved containers in a new thread");
|
||||
try {
|
||||
containerMemory.save();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("Failed to save saved containers");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,4 +73,9 @@ public class WorldData implements IWorldData {
|
||||
public IWaypointCollection getWaypoints() {
|
||||
return this.waypoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IContainerMemory getContainerMemory() {
|
||||
return this.containerMemory;
|
||||
}
|
||||
}
|
||||
|
||||
40
src/main/java/baritone/cache/WorldProvider.java
vendored
40
src/main/java/baritone/cache/WorldProvider.java
vendored
@@ -24,7 +24,7 @@ import baritone.utils.accessor.IAnvilChunkLoader;
|
||||
import baritone.utils.accessor.IChunkProviderServer;
|
||||
import net.minecraft.server.integrated.IntegratedServer;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
|
||||
import java.io.File;
|
||||
@@ -45,11 +45,9 @@ public class WorldProvider implements IWorldProvider, Helper {
|
||||
private static final Map<Path, WorldData> worldCache = new HashMap<>(); // this is how the bots have the same cached world
|
||||
|
||||
private WorldData currentWorld;
|
||||
private World mcWorld; // this let's us detect a broken load/unload hook
|
||||
|
||||
@Override
|
||||
public final WorldData getCurrentWorld() {
|
||||
detectAndHandleBrokenLoading();
|
||||
return this.currentWorld;
|
||||
}
|
||||
|
||||
@@ -58,7 +56,7 @@ public class WorldProvider implements IWorldProvider, Helper {
|
||||
*
|
||||
* @param dimension The ID of the world's dimension
|
||||
*/
|
||||
public final void initWorld(int dimension) {
|
||||
public final void initWorld(DimensionType dimension) {
|
||||
File directory;
|
||||
File readme;
|
||||
|
||||
@@ -80,16 +78,7 @@ public class WorldProvider implements IWorldProvider, Helper {
|
||||
directory = new File(directory, "baritone");
|
||||
readme = directory;
|
||||
} else { // Otherwise, the server must be remote...
|
||||
String folderName;
|
||||
if (mc.getCurrentServerData() != null) {
|
||||
folderName = mc.getCurrentServerData().serverIP;
|
||||
} else {
|
||||
//replaymod causes null currentServerData and false singleplayer.
|
||||
System.out.println("World seems to be a replay. Not loading Baritone cache.");
|
||||
currentWorld = null;
|
||||
mcWorld = mc.world;
|
||||
return;
|
||||
}
|
||||
String folderName = mc.getCurrentServerData().serverIP;
|
||||
if (SystemUtils.IS_OS_WINDOWS) {
|
||||
folderName = folderName.replace(":", "_");
|
||||
}
|
||||
@@ -104,7 +93,7 @@ public class WorldProvider implements IWorldProvider, Helper {
|
||||
} catch (IOException ignored) {}
|
||||
|
||||
// We will actually store the world data in a subfolder: "DIM<id>"
|
||||
Path dir = new File(directory, "DIM" + dimension).toPath();
|
||||
Path dir = new File(directory, "DIM" + dimension.getId()).toPath();
|
||||
if (!Files.exists(dir)) {
|
||||
try {
|
||||
Files.createDirectories(dir);
|
||||
@@ -113,15 +102,13 @@ public class WorldProvider implements IWorldProvider, Helper {
|
||||
|
||||
System.out.println("Baritone world data dir: " + dir);
|
||||
synchronized (worldCache) {
|
||||
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension));
|
||||
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension.getId()));
|
||||
}
|
||||
this.mcWorld = mc.world;
|
||||
}
|
||||
|
||||
public final void closeWorld() {
|
||||
WorldData world = this.currentWorld;
|
||||
this.currentWorld = null;
|
||||
this.mcWorld = null;
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
@@ -129,25 +116,8 @@ public class WorldProvider implements IWorldProvider, Helper {
|
||||
}
|
||||
|
||||
public final void ifWorldLoaded(Consumer<WorldData> currentWorldConsumer) {
|
||||
detectAndHandleBrokenLoading();
|
||||
if (this.currentWorld != null) {
|
||||
currentWorldConsumer.accept(this.currentWorld);
|
||||
}
|
||||
}
|
||||
|
||||
private final void detectAndHandleBrokenLoading() {
|
||||
if (this.mcWorld != mc.world) {
|
||||
if (this.currentWorld != null) {
|
||||
System.out.println("mc.world unloaded unnoticed! Unloading Baritone cache now.");
|
||||
closeWorld();
|
||||
}
|
||||
if (mc.world != null) {
|
||||
System.out.println("mc.world loaded unnoticed! Loading Baritone cache now.");
|
||||
initWorld(mc.world.provider.getDimensionType().getId());
|
||||
}
|
||||
} else if (currentWorld == null && mc.world != null && (mc.isSingleplayer() || mc.getCurrentServerData() != null)) {
|
||||
System.out.println("Retrying to load Baritone cache");
|
||||
initWorld(mc.world.provider.getDimensionType().getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
src/main/java/baritone/cache/WorldScanner.java
vendored
12
src/main/java/baritone/cache/WorldScanner.java
vendored
@@ -28,8 +28,8 @@ import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.ChunkSection;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.IntStream;
|
||||
@@ -72,7 +72,7 @@ public enum WorldScanner implements IWorldScanner {
|
||||
foundChunks = true;
|
||||
int chunkX = xoff + playerChunkX;
|
||||
int chunkZ = zoff + playerChunkZ;
|
||||
Chunk chunk = chunkProvider.getLoadedChunk(chunkX, chunkZ);
|
||||
Chunk chunk = chunkProvider.getChunk(chunkX, chunkZ, false, false);
|
||||
if (chunk == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public enum WorldScanner implements IWorldScanner {
|
||||
}
|
||||
|
||||
ChunkProviderClient chunkProvider = (ChunkProviderClient) ctx.world().getChunkProvider();
|
||||
Chunk chunk = chunkProvider.getLoadedChunk(pos.x, pos.z);
|
||||
Chunk chunk = chunkProvider.getChunk(pos.x, pos.z, false, false);
|
||||
int playerY = ctx.playerFeet().getY();
|
||||
|
||||
if (chunk == null || chunk.isEmpty()) {
|
||||
@@ -134,7 +134,7 @@ public enum WorldScanner implements IWorldScanner {
|
||||
int queued = 0;
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
Chunk chunk = chunkProvider.getLoadedChunk(x, z);
|
||||
Chunk chunk = chunkProvider.getChunk(x, z, false, false);
|
||||
|
||||
if (chunk != null && !chunk.isEmpty()) {
|
||||
queued++;
|
||||
@@ -147,11 +147,11 @@ public enum WorldScanner implements IWorldScanner {
|
||||
}
|
||||
|
||||
private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, BlockOptionalMetaLookup filter, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) {
|
||||
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||
ChunkSection[] chunkInternalStorageArray = chunk.getSections();
|
||||
boolean foundWithinY = false;
|
||||
for (int yIndex = 0; yIndex < 16; yIndex++) {
|
||||
int y0 = coordinateIterationOrder[yIndex];
|
||||
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||
ChunkSection extendedblockstorage = chunkInternalStorageArray[y0];
|
||||
if (extendedblockstorage == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
event.cancel();
|
||||
String commandStr = msg.substring(forceRun ? FORCE_COMMAND_PREFIX.length() : prefix.length());
|
||||
if (!runCommand(commandStr) && !commandStr.trim().isEmpty()) {
|
||||
new CommandNotFoundException(CommandManager.expand(commandStr).getFirst()).handle(null, null);
|
||||
new CommandNotFoundException(CommandManager.expand(commandStr).getA()).handle(null, null);
|
||||
}
|
||||
} else if ((settings.chatControl.value || settings.chatControlAnyway.value) && runCommand(msg)) {
|
||||
event.cancel();
|
||||
@@ -108,9 +108,9 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
return this.runCommand("help");
|
||||
}
|
||||
Tuple<String, List<ICommandArgument>> pair = CommandManager.expand(msg);
|
||||
String command = pair.getFirst();
|
||||
String rest = msg.substring(pair.getFirst().length());
|
||||
ArgConsumer argc = new ArgConsumer(this.manager, pair.getSecond());
|
||||
String command = pair.getA();
|
||||
String rest = msg.substring(pair.getA().length());
|
||||
ArgConsumer argc = new ArgConsumer(this.manager, pair.getB());
|
||||
if (!argc.hasAny()) {
|
||||
Settings.Setting setting = settings.byLowerName.get(command.toLowerCase(Locale.US));
|
||||
if (setting != null) {
|
||||
@@ -124,10 +124,10 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
}
|
||||
} else if (argc.hasExactlyOne()) {
|
||||
for (Settings.Setting setting : settings.allSettings) {
|
||||
if (SettingsUtil.javaOnlySetting(setting)) {
|
||||
if (setting.getName().equals("logger")) {
|
||||
continue;
|
||||
}
|
||||
if (setting.getName().equalsIgnoreCase(pair.getFirst())) {
|
||||
if (setting.getName().equalsIgnoreCase(pair.getA())) {
|
||||
logRanCommand(command, rest);
|
||||
try {
|
||||
this.manager.execute(String.format("set %s %s", setting.getName(), argc.getString()));
|
||||
@@ -138,7 +138,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
}
|
||||
|
||||
// If the command exists, then handle echoing the input
|
||||
if (this.manager.getCommand(pair.getFirst()) != null) {
|
||||
if (this.manager.getCommand(pair.getA()) != null) {
|
||||
logRanCommand(command, rest);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
|
||||
.stream();
|
||||
}
|
||||
Settings.Setting setting = settings.byLowerName.get(argc.getString().toLowerCase(Locale.US));
|
||||
if (setting != null && !SettingsUtil.javaOnlySetting(setting)) {
|
||||
if (setting != null) {
|
||||
if (setting.getValueClass() == Boolean.class) {
|
||||
TabCompleteHelper helper = new TabCompleteHelper();
|
||||
if ((Boolean) setting.value) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import baritone.api.command.datatypes.RelativeFile;
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.exception.CommandInvalidStateException;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import java.io.File;
|
||||
@@ -36,7 +35,7 @@ import java.util.stream.Stream;
|
||||
|
||||
public class BuildCommand extends Command {
|
||||
|
||||
private static final File schematicsDir = new File(Minecraft.getMinecraft().gameDir, "schematics");
|
||||
private static final File schematicsDir = new File(mc.gameDir, "schematics");
|
||||
|
||||
public BuildCommand(IBaritone baritone) {
|
||||
super(baritone, "build");
|
||||
|
||||
@@ -18,33 +18,46 @@
|
||||
package baritone.command.defaults;
|
||||
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.cache.IRememberedInventory;
|
||||
import baritone.api.command.Command;
|
||||
import baritone.api.command.argument.IArgConsumer;
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.exception.CommandInvalidStateException;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class LitematicaCommand extends Command {
|
||||
public class ChestsCommand extends Command {
|
||||
|
||||
public LitematicaCommand(IBaritone baritone) {
|
||||
super(baritone, "litematica");
|
||||
public ChestsCommand(IBaritone baritone) {
|
||||
super(baritone, "chests");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||
int schematic = 0;
|
||||
if (args.hasAny()) {
|
||||
args.requireMax(1);
|
||||
if (args.is(Integer.class)) {
|
||||
schematic = args.getAs(Integer.class) - 1;
|
||||
}
|
||||
args.requireMax(0);
|
||||
Set<Map.Entry<BlockPos, IRememberedInventory>> entries =
|
||||
ctx.worldData().getContainerMemory().getRememberedInventories().entrySet();
|
||||
if (entries.isEmpty()) {
|
||||
throw new CommandInvalidStateException("No remembered inventories");
|
||||
}
|
||||
try {
|
||||
baritone.getBuilderProcess().buildOpenLitematic(schematic);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
logDirect("Pleas provide a valid index.");
|
||||
for (Map.Entry<BlockPos, IRememberedInventory> entry : entries) {
|
||||
// betterblockpos has censoring
|
||||
BetterBlockPos pos = new BetterBlockPos(entry.getKey());
|
||||
IRememberedInventory inv = entry.getValue();
|
||||
logDirect(pos.toString());
|
||||
for (ItemStack item : inv.getContents()) {
|
||||
ITextComponent component = item.getTextComponent();
|
||||
component.appendText(String.format(" x %d", item.getCount()));
|
||||
logDirect(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,17 +68,16 @@ public class LitematicaCommand extends Command {
|
||||
|
||||
@Override
|
||||
public String getShortDesc() {
|
||||
return "Builds the loaded schematic";
|
||||
return "Display remembered inventories";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLongDesc() {
|
||||
return Arrays.asList(
|
||||
"Build a schematic currently open in Litematica.",
|
||||
"The chests command lists remembered inventories, I guess?",
|
||||
"",
|
||||
"Usage:",
|
||||
"> litematica",
|
||||
"> litematica <#>"
|
||||
"> chests"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,12 +38,10 @@ public final class DefaultCommands {
|
||||
new GotoCommand(baritone),
|
||||
new PathCommand(baritone),
|
||||
new ProcCommand(baritone),
|
||||
new ETACommand(baritone),
|
||||
new VersionCommand(baritone),
|
||||
new RepackCommand(baritone),
|
||||
new BuildCommand(baritone),
|
||||
new SchematicaCommand(baritone),
|
||||
new LitematicaCommand(baritone),
|
||||
new ComeCommand(baritone),
|
||||
new AxisCommand(baritone),
|
||||
new ForceCancelCommand(baritone),
|
||||
@@ -52,6 +50,7 @@ public final class DefaultCommands {
|
||||
new TunnelCommand(baritone),
|
||||
new RenderCommand(baritone),
|
||||
new FarmCommand(baritone),
|
||||
new ChestsCommand(baritone),
|
||||
new FollowCommand(baritone),
|
||||
new ExploreFilterCommand(baritone),
|
||||
new ReloadAllCommand(baritone),
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
* Baritone is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Baritone is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package baritone.command.defaults;
|
||||
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.pathing.calc.IPathingControlManager;
|
||||
import baritone.api.process.IBaritoneProcess;
|
||||
import baritone.api.behavior.IPathingBehavior;
|
||||
import baritone.api.command.Command;
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.exception.CommandInvalidStateException;
|
||||
import baritone.api.command.argument.IArgConsumer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ETACommand extends Command {
|
||||
|
||||
public ETACommand(IBaritone baritone) {
|
||||
super(baritone, "eta");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||
args.requireMax(0);
|
||||
IPathingControlManager pathingControlManager = baritone.getPathingControlManager();
|
||||
IBaritoneProcess process = pathingControlManager.mostRecentInControl().orElse(null);
|
||||
if (process == null) {
|
||||
throw new CommandInvalidStateException("No process in control");
|
||||
}
|
||||
IPathingBehavior pathingBehavior = baritone.getPathingBehavior();
|
||||
|
||||
double ticksRemainingInSegment = pathingBehavior.ticksRemainingInSegment().orElse(Double.NaN);
|
||||
double ticksRemainingInGoal = pathingBehavior.estimatedTicksToGoal().orElse(Double.NaN);
|
||||
|
||||
logDirect(String.format(
|
||||
"Next segment: %.1fs (%.0f ticks)\n" +
|
||||
"Goal: %.1fs (%.0f ticks)",
|
||||
ticksRemainingInSegment / 20, // we just assume tps is 20, it isn't worth the effort that is needed to calculate it exactly
|
||||
ticksRemainingInSegment,
|
||||
ticksRemainingInGoal / 20,
|
||||
ticksRemainingInGoal
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> tabComplete(String label, IArgConsumer args) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortDesc() {
|
||||
return "View the current ETA";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLongDesc() {
|
||||
return Arrays.asList(
|
||||
"The ETA command provides information about the estimated time until the next segment.",
|
||||
"and the goal",
|
||||
"",
|
||||
"Be aware that the ETA to your goal is really unprecise",
|
||||
"",
|
||||
"Usage:",
|
||||
"> eta - View ETA, if present"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,6 @@ public class ExecutionControlCommands {
|
||||
|
||||
@Override
|
||||
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
|
||||
baritone.getInputOverrideHandler().clearAllKeys();
|
||||
return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE);
|
||||
}
|
||||
|
||||
@@ -80,7 +79,7 @@ public class ExecutionControlCommands {
|
||||
}
|
||||
}
|
||||
);
|
||||
pauseCommand = new Command(baritone, "pause", "p", "paws") {
|
||||
pauseCommand = new Command(baritone, "pause", "p") {
|
||||
@Override
|
||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||
args.requireMax(0);
|
||||
@@ -113,7 +112,7 @@ public class ExecutionControlCommands {
|
||||
);
|
||||
}
|
||||
};
|
||||
resumeCommand = new Command(baritone, "resume", "r", "unpause", "unpaws") {
|
||||
resumeCommand = new Command(baritone, "resume", "r") {
|
||||
@Override
|
||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||
args.requireMax(0);
|
||||
|
||||
@@ -22,23 +22,15 @@ import baritone.api.command.Command;
|
||||
import baritone.api.command.argument.IArgConsumer;
|
||||
import baritone.api.command.datatypes.BlockById;
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.helpers.TabCompleteHelper;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.cache.CachedChunk;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.util.text.event.ClickEvent;
|
||||
import net.minecraft.util.text.event.HoverEvent;
|
||||
import net.minecraft.util.registry.IRegistry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
|
||||
|
||||
public class FindCommand extends Command {
|
||||
|
||||
public FindCommand(IBaritone baritone) {
|
||||
@@ -47,16 +39,15 @@ public class FindCommand extends Command {
|
||||
|
||||
@Override
|
||||
public void execute(String label, IArgConsumer args) throws CommandException {
|
||||
args.requireMin(1);
|
||||
List<Block> toFind = new ArrayList<>();
|
||||
while (args.hasAny()) {
|
||||
toFind.add(args.getDatatypeFor(BlockById.INSTANCE));
|
||||
}
|
||||
BetterBlockPos origin = ctx.playerFeet();
|
||||
ITextComponent[] components = toFind.stream()
|
||||
toFind.stream()
|
||||
.flatMap(block ->
|
||||
ctx.worldData().getCachedWorld().getLocationsOf(
|
||||
Block.REGISTRY.getNameForObject(block).getPath(),
|
||||
IRegistry.BLOCK.getKey(block).getPath(),
|
||||
Integer.MAX_VALUE,
|
||||
origin.x,
|
||||
origin.y,
|
||||
@@ -64,39 +55,13 @@ public class FindCommand extends Command {
|
||||
).stream()
|
||||
)
|
||||
.map(BetterBlockPos::new)
|
||||
.map(this::positionToComponent)
|
||||
.toArray(ITextComponent[]::new);
|
||||
if (components.length > 0) {
|
||||
Arrays.asList(components).forEach(this::logDirect);
|
||||
} else {
|
||||
logDirect("No positions known, are you sure the blocks are cached?");
|
||||
}
|
||||
}
|
||||
|
||||
private ITextComponent positionToComponent(BetterBlockPos pos) {
|
||||
String positionText = String.format("%s %s %s", pos.x, pos.y, pos.z);
|
||||
String command = String.format("%sgoal %s", FORCE_COMMAND_PREFIX, positionText);
|
||||
ITextComponent baseComponent = new TextComponentString(pos.toString());
|
||||
ITextComponent hoverComponent = new TextComponentString("Click to set goal to this position");
|
||||
baseComponent.getStyle()
|
||||
.setColor(TextFormatting.GRAY)
|
||||
.setInsertion(positionText)
|
||||
.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command))
|
||||
.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hoverComponent));
|
||||
return baseComponent;
|
||||
.map(BetterBlockPos::toString)
|
||||
.forEach(this::logDirect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> tabComplete(String label, IArgConsumer args) throws CommandException {
|
||||
return new TabCompleteHelper()
|
||||
.append(
|
||||
CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.stream()
|
||||
.map(Block.REGISTRY::getNameForObject)
|
||||
.map(Object::toString)
|
||||
)
|
||||
.filterPrefixNamespaced(args.getString())
|
||||
.sortAlphabetically()
|
||||
.stream();
|
||||
public Stream<String> tabComplete(String label, IArgConsumer args) {
|
||||
return args.tabCompleteDatatype(BlockById.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,11 +72,10 @@ public class FindCommand extends Command {
|
||||
@Override
|
||||
public List<String> getLongDesc() {
|
||||
return Arrays.asList(
|
||||
"The find command searches through Baritone's cache and attempts to find the location of the block.",
|
||||
"Tab completion will suggest only cached blocks and uncached blocks can not be found.",
|
||||
"",
|
||||
"",
|
||||
"Usage:",
|
||||
"> find <block> [...] - Try finding the listed blocks"
|
||||
"> "
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,14 +24,14 @@ import baritone.api.command.argument.IArgConsumer;
|
||||
import baritone.api.command.datatypes.EntityClassById;
|
||||
import baritone.api.command.datatypes.IDatatypeFor;
|
||||
import baritone.api.command.datatypes.NearbyPlayer;
|
||||
import baritone.api.command.exception.CommandErrorMessageException;
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.helpers.TabCompleteHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.registry.IRegistry;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
@@ -49,7 +49,7 @@ public class FollowCommand extends Command {
|
||||
FollowGroup group;
|
||||
FollowList list;
|
||||
List<Entity> entities = new ArrayList<>();
|
||||
List<Class<? extends Entity>> classes = new ArrayList<>();
|
||||
List<EntityType> classes = new ArrayList<>();
|
||||
if (args.hasExactlyOne()) {
|
||||
baritone.getFollowProcess().follow((group = args.getEnum(FollowGroup.class)).filter);
|
||||
} else {
|
||||
@@ -58,32 +58,30 @@ public class FollowCommand extends Command {
|
||||
list = args.getEnum(FollowList.class);
|
||||
while (args.hasAny()) {
|
||||
Object gotten = args.getDatatypeFor(list.datatype);
|
||||
if (gotten instanceof Class) {
|
||||
if (gotten instanceof EntityType) {
|
||||
//noinspection unchecked
|
||||
classes.add((Class<? extends Entity>) gotten);
|
||||
} else if (gotten != null) {
|
||||
classes.add((EntityType) gotten);
|
||||
} else {
|
||||
entities.add((Entity) gotten);
|
||||
}
|
||||
}
|
||||
baritone.getFollowProcess().follow(
|
||||
classes.isEmpty()
|
||||
? entities::contains
|
||||
: e -> classes.stream().anyMatch(c -> c.isInstance(e))
|
||||
: e -> classes.stream().anyMatch(c -> c.getEntityClass().isInstance(e))
|
||||
);
|
||||
}
|
||||
if (group != null) {
|
||||
logDirect(String.format("Following all %s", group.name().toLowerCase(Locale.US)));
|
||||
} else {
|
||||
logDirect("Following these types of entities:");
|
||||
if (classes.isEmpty()) {
|
||||
if (entities.isEmpty()) throw new NoEntitiesException();
|
||||
logDirect("Following these entities:");
|
||||
entities.stream()
|
||||
.map(Entity::toString)
|
||||
.forEach(this::logDirect);
|
||||
} else {
|
||||
logDirect("Following these types of entities:");
|
||||
classes.stream()
|
||||
.map(EntityList::getKey)
|
||||
.map(IRegistry.ENTITY_TYPE::getKey)
|
||||
.map(Objects::requireNonNull)
|
||||
.map(ResourceLocation::toString)
|
||||
.forEach(this::logDirect);
|
||||
@@ -158,12 +156,4 @@ public class FollowCommand extends Command {
|
||||
this.datatype = datatype;
|
||||
}
|
||||
}
|
||||
|
||||
public static class NoEntitiesException extends CommandErrorMessageException {
|
||||
|
||||
protected NoEntitiesException() {
|
||||
super("No valid entities in range!");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class RenderCommand extends Command {
|
||||
args.requireMax(0);
|
||||
BetterBlockPos origin = ctx.playerFeet();
|
||||
int renderDistance = (mc.gameSettings.renderDistanceChunks + 1) * 16;
|
||||
mc.renderGlobal.markBlockRangeForRenderUpdate(
|
||||
mc.worldRenderer.markBlockRangeForRenderUpdate(
|
||||
origin.x - renderDistance,
|
||||
0,
|
||||
origin.z - renderDistance,
|
||||
|
||||
@@ -51,7 +51,7 @@ public class SchematicaCommand extends Command {
|
||||
@Override
|
||||
public List<String> getLongDesc() {
|
||||
return Arrays.asList(
|
||||
"Builds the schematic currently open in Schematica.",
|
||||
"Builds the schematica currently open in Schematica.",
|
||||
"",
|
||||
"Usage:",
|
||||
"> schematica"
|
||||
|
||||
@@ -37,9 +37,6 @@ import baritone.api.utils.BetterBlockPos;
|
||||
import baritone.api.utils.BlockOptionalMeta;
|
||||
import baritone.api.utils.BlockOptionalMetaLookup;
|
||||
import baritone.utils.IRenderer;
|
||||
import baritone.utils.BlockStateInterface;
|
||||
import baritone.utils.schematic.StaticSchematic;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
@@ -56,8 +53,6 @@ public class SelCommand extends Command {
|
||||
|
||||
private ISelectionManager manager = baritone.getSelectionManager();
|
||||
private BetterBlockPos pos1 = null;
|
||||
private ISchematic clipboard = null;
|
||||
private Vec3i clipboardOffset = null;
|
||||
|
||||
public SelCommand(IBaritone baritone) {
|
||||
super(baritone, "sel", "selection", "s");
|
||||
@@ -163,56 +158,6 @@ public class SelCommand extends Command {
|
||||
}
|
||||
baritone.getBuilderProcess().build("Fill", composite, origin);
|
||||
logDirect("Filling now");
|
||||
} else if (action == Action.COPY) {
|
||||
BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet();
|
||||
BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos;
|
||||
args.requireMax(0);
|
||||
ISelection[] selections = manager.getSelections();
|
||||
if (selections.length < 1) {
|
||||
throw new CommandInvalidStateException("No selections");
|
||||
}
|
||||
BlockStateInterface bsi = new BlockStateInterface(ctx);
|
||||
BetterBlockPos origin = selections[0].min();
|
||||
CompositeSchematic composite = new CompositeSchematic(0, 0, 0);
|
||||
for (ISelection selection : selections) {
|
||||
BetterBlockPos min = selection.min();
|
||||
origin = new BetterBlockPos(
|
||||
Math.min(origin.x, min.x),
|
||||
Math.min(origin.y, min.y),
|
||||
Math.min(origin.z, min.z)
|
||||
);
|
||||
}
|
||||
for (ISelection selection : selections) {
|
||||
Vec3i size = selection.size();
|
||||
BetterBlockPos min = selection.min();
|
||||
IBlockState[][][] blockstates = new IBlockState[size.getX()][size.getZ()][size.getY()];
|
||||
for (int x = 0; x < size.getX(); x++) {
|
||||
for (int y = 0; y < size.getY(); y++) {
|
||||
for (int z = 0; z < size.getZ(); z++) {
|
||||
blockstates[x][z][y] = bsi.get0(min.x + x, min.y + y, min.z + z);
|
||||
}
|
||||
}
|
||||
}
|
||||
ISchematic schematic = new StaticSchematic(){{
|
||||
states = blockstates;
|
||||
x = size.getX();
|
||||
y = size.getY();
|
||||
z = size.getZ();
|
||||
}};
|
||||
composite.put(schematic, min.x - origin.x, min.y - origin.y, min.z - origin.z);
|
||||
}
|
||||
clipboard = composite;
|
||||
clipboardOffset = origin.subtract(pos);
|
||||
logDirect("Selection copied");
|
||||
} else if (action == Action.PASTE) {
|
||||
BetterBlockPos playerPos = mc.getRenderViewEntity() != null ? BetterBlockPos.from(new BlockPos(mc.getRenderViewEntity())) : ctx.playerFeet();
|
||||
BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, playerPos) : playerPos;
|
||||
args.requireMax(0);
|
||||
if (clipboard == null) {
|
||||
throw new CommandInvalidStateException("You need to copy a selection first");
|
||||
}
|
||||
baritone.getBuilderProcess().build("Fill", clipboard, pos.add(clipboardOffset));
|
||||
logDirect("Building now");
|
||||
} else if (action == Action.EXPAND || action == Action.CONTRACT || action == Action.SHIFT) {
|
||||
args.requireExactly(3);
|
||||
TransformTarget transformTarget = TransformTarget.getByName(args.getString());
|
||||
@@ -307,8 +252,6 @@ public class SelCommand extends Command {
|
||||
"> sel shell/shl [block] - The same as walls, but fills in a ceiling and floor too.",
|
||||
"> sel cleararea/ca - Basically 'set air'.",
|
||||
"> sel replace/r <blocks...> <with> - Replaces blocks with another block.",
|
||||
"> sel copy/cp <x> <y> <z> - Copy the selected area relative to the specified or your position.",
|
||||
"> sel paste/p <x> <y> <z> - Build the copied area relative to the specified or your position.",
|
||||
"",
|
||||
"> sel expand <target> <direction> <blocks> - Expand the targets.",
|
||||
"> sel contract <target> <direction> <blocks> - Contract the targets.",
|
||||
@@ -327,8 +270,6 @@ public class SelCommand extends Command {
|
||||
CLEARAREA("cleararea", "ca"),
|
||||
REPLACE("replace", "r"),
|
||||
EXPAND("expand", "ex"),
|
||||
COPY("copy", "cp"),
|
||||
PASTE("paste", "p"),
|
||||
CONTRACT("contract", "ct"),
|
||||
SHIFT("shift", "sh");
|
||||
private final String[] names;
|
||||
|
||||
@@ -23,7 +23,6 @@ import baritone.api.Settings;
|
||||
import baritone.api.command.Command;
|
||||
import baritone.api.command.argument.IArgConsumer;
|
||||
import baritone.api.command.exception.CommandException;
|
||||
import baritone.api.command.exception.CommandInvalidStateException;
|
||||
import baritone.api.command.exception.CommandInvalidTypeException;
|
||||
import baritone.api.command.helpers.Paginator;
|
||||
import baritone.api.command.helpers.TabCompleteHelper;
|
||||
@@ -41,7 +40,8 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
|
||||
import static baritone.api.utils.SettingsUtil.*;
|
||||
import static baritone.api.utils.SettingsUtil.settingTypeToString;
|
||||
import static baritone.api.utils.SettingsUtil.settingValueToString;
|
||||
|
||||
public class SetCommand extends Command {
|
||||
|
||||
@@ -65,7 +65,7 @@ public class SetCommand extends Command {
|
||||
args.requireMax(1);
|
||||
List<? extends Settings.Setting> toPaginate =
|
||||
(viewModified ? SettingsUtil.modifiedSettings(Baritone.settings()) : Baritone.settings().allSettings).stream()
|
||||
.filter(s -> !javaOnlySetting(s))
|
||||
.filter(s -> !s.getName().equals("logger"))
|
||||
.filter(s -> s.getName().toLowerCase(Locale.US).contains(search.toLowerCase(Locale.US)))
|
||||
.sorted((s1, s2) -> String.CASE_INSENSITIVE_ORDER.compare(s1.getName(), s2.getName()))
|
||||
.collect(Collectors.toList());
|
||||
@@ -88,7 +88,6 @@ public class SetCommand extends Command {
|
||||
hoverComponent.appendText(setting.getName());
|
||||
hoverComponent.appendText(String.format("\nType: %s", settingTypeToString(setting)));
|
||||
hoverComponent.appendText(String.format("\n\nValue:\n%s", settingValueToString(setting)));
|
||||
hoverComponent.appendText(String.format("\n\nDefault Value:\n%s", settingDefaultToString(setting)));
|
||||
String commandSuggestion = Baritone.settings().prefix.value + String.format("set %s ", setting.getName());
|
||||
ITextComponent component = new TextComponentString(setting.getName());
|
||||
component.getStyle().setColor(TextFormatting.GRAY);
|
||||
@@ -129,12 +128,6 @@ public class SetCommand extends Command {
|
||||
if (setting == null) {
|
||||
throw new CommandInvalidTypeException(args.consumed(), "a valid setting");
|
||||
}
|
||||
if (javaOnlySetting(setting)) {
|
||||
// ideally it would act as if the setting didn't exist
|
||||
// but users will see it in Settings.java or its javadoc
|
||||
// so at some point we have to tell them or they will see it as a bug
|
||||
throw new CommandInvalidStateException(String.format("Setting %s can only be used via the api.", setting.getName()));
|
||||
}
|
||||
if (!doingSomething && !args.hasAny()) {
|
||||
logDirect(String.format("Value of setting %s:", setting.getName()));
|
||||
logDirect(settingValueToString(setting));
|
||||
@@ -147,8 +140,7 @@ public class SetCommand extends Command {
|
||||
throw new CommandInvalidTypeException(args.consumed(), "a toggleable setting", "some other setting");
|
||||
}
|
||||
//noinspection unchecked
|
||||
Settings.Setting<Boolean> asBoolSetting = (Settings.Setting<Boolean>) setting;
|
||||
asBoolSetting.value ^= true;
|
||||
((Settings.Setting<Boolean>) setting).value ^= true;
|
||||
logDirect(String.format(
|
||||
"Toggled setting %s to %s",
|
||||
setting.getName(),
|
||||
|
||||
@@ -17,11 +17,9 @@
|
||||
|
||||
package baritone.command.defaults;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.cache.IWaypoint;
|
||||
import baritone.api.cache.Waypoint;
|
||||
import baritone.api.cache.IWorldData;
|
||||
import baritone.api.command.Command;
|
||||
import baritone.api.command.argument.IArgConsumer;
|
||||
import baritone.api.command.datatypes.ForWaypoints;
|
||||
@@ -43,15 +41,12 @@ import net.minecraft.util.text.event.HoverEvent;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
|
||||
|
||||
public class WaypointsCommand extends Command {
|
||||
|
||||
private Map<IWorldData,List<IWaypoint>> deletedWaypoints = new HashMap<>();
|
||||
|
||||
public WaypointsCommand(IBaritone baritone) {
|
||||
super(baritone, "waypoints", "waypoint", "wp");
|
||||
}
|
||||
@@ -130,13 +125,11 @@ public class WaypointsCommand extends Command {
|
||||
);
|
||||
}
|
||||
} else if (action == Action.SAVE) {
|
||||
IWaypoint.Tag tag = args.hasAny() ? IWaypoint.Tag.getByName(args.peekString()) : null;
|
||||
IWaypoint.Tag tag = IWaypoint.Tag.getByName(args.getString());
|
||||
if (tag == null) {
|
||||
tag = IWaypoint.Tag.USER;
|
||||
} else {
|
||||
args.get();
|
||||
throw new CommandInvalidStateException(String.format("'%s' is not a tag ", args.consumedString()));
|
||||
}
|
||||
String name = (args.hasExactlyOne() || args.hasExactly(4)) ? args.getString() : "";
|
||||
String name = args.hasAny() ? args.getString() : "";
|
||||
BetterBlockPos pos = args.hasAny()
|
||||
? args.getDatatypePost(RelativeBlockPos.INSTANCE, ctx.playerFeet())
|
||||
: ctx.playerFeet();
|
||||
@@ -154,42 +147,7 @@ public class WaypointsCommand extends Command {
|
||||
for (IWaypoint waypoint : waypoints) {
|
||||
ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint);
|
||||
}
|
||||
deletedWaypoints.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), k -> new ArrayList<>()).addAll(Arrays.<IWaypoint>asList(waypoints));
|
||||
ITextComponent textComponent = new TextComponentString(String.format("Cleared %d waypoints, click to restore them", waypoints.length));
|
||||
textComponent.getStyle().setClickEvent(new ClickEvent(
|
||||
ClickEvent.Action.RUN_COMMAND,
|
||||
String.format(
|
||||
"%s%s restore @ %s",
|
||||
FORCE_COMMAND_PREFIX,
|
||||
label,
|
||||
Stream.of(waypoints).map(wp -> Long.toString(wp.getCreationTimestamp())).collect(Collectors.joining(" "))
|
||||
)
|
||||
));
|
||||
logDirect(textComponent);
|
||||
} else if (action == Action.RESTORE) {
|
||||
List<IWaypoint> waypoints = new ArrayList<>();
|
||||
List<IWaypoint> deletedWaypoints = this.deletedWaypoints.getOrDefault(baritone.getWorldProvider().getCurrentWorld(), Collections.emptyList());
|
||||
if (args.peekString().equals("@")) {
|
||||
args.get();
|
||||
// no args.requireMin(1) because if the user clears an empty tag there is nothing to restore
|
||||
while (args.hasAny()) {
|
||||
long timestamp = args.getAs(Long.class);
|
||||
for (IWaypoint waypoint : deletedWaypoints) {
|
||||
if (waypoint.getCreationTimestamp() == timestamp) {
|
||||
waypoints.add(waypoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
args.requireExactly(1);
|
||||
int size = deletedWaypoints.size();
|
||||
int amount = Math.min(size, args.getAs(Integer.class));
|
||||
waypoints = new ArrayList<>(deletedWaypoints.subList(size - amount, size));
|
||||
}
|
||||
waypoints.forEach(ForWaypoints.waypoints(this.baritone)::addWaypoint);
|
||||
deletedWaypoints.removeIf(waypoints::contains);
|
||||
logDirect(String.format("Restored %d waypoints", waypoints.size()));
|
||||
logDirect(String.format("Cleared %d waypoints", waypoints.length));
|
||||
} else {
|
||||
IWaypoint[] waypoints = args.getDatatypeFor(ForWaypoints.INSTANCE);
|
||||
IWaypoint waypoint = null;
|
||||
@@ -258,20 +216,6 @@ public class WaypointsCommand extends Command {
|
||||
waypoint.getCreationTimestamp()
|
||||
)
|
||||
));
|
||||
ITextComponent recreateComponent = new TextComponentString("Click to show a command to recreate this waypoint");
|
||||
recreateComponent.getStyle().setClickEvent(new ClickEvent(
|
||||
ClickEvent.Action.SUGGEST_COMMAND,
|
||||
String.format(
|
||||
"%s%s save %s %s %s %s %s",
|
||||
Baritone.settings().prefix.value, // This uses the normal prefix because it is run by the user.
|
||||
label,
|
||||
waypoint.getTag().getName(),
|
||||
waypoint.getName(),
|
||||
waypoint.getLocation().x,
|
||||
waypoint.getLocation().y,
|
||||
waypoint.getLocation().z
|
||||
)
|
||||
));
|
||||
ITextComponent backComponent = new TextComponentString("Click to return to the waypoints list");
|
||||
backComponent.getStyle().setClickEvent(new ClickEvent(
|
||||
ClickEvent.Action.RUN_COMMAND,
|
||||
@@ -283,22 +227,10 @@ public class WaypointsCommand extends Command {
|
||||
));
|
||||
logDirect(deleteComponent);
|
||||
logDirect(goalComponent);
|
||||
logDirect(recreateComponent);
|
||||
logDirect(backComponent);
|
||||
} else if (action == Action.DELETE) {
|
||||
ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint);
|
||||
deletedWaypoints.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), k -> new ArrayList<>()).add(waypoint);
|
||||
ITextComponent textComponent = new TextComponentString("That waypoint has successfully been deleted, click to restore it");
|
||||
textComponent.getStyle().setClickEvent(new ClickEvent(
|
||||
ClickEvent.Action.RUN_COMMAND,
|
||||
String.format(
|
||||
"%s%s restore @ %s",
|
||||
FORCE_COMMAND_PREFIX,
|
||||
label,
|
||||
waypoint.getCreationTimestamp()
|
||||
)
|
||||
));
|
||||
logDirect(textComponent);
|
||||
logDirect("That waypoint has successfully been deleted");
|
||||
} else if (action == Action.GOAL) {
|
||||
Goal goal = new GoalBlock(waypoint.getLocation());
|
||||
baritone.getCustomGoalProcess().setGoal(goal);
|
||||
@@ -330,8 +262,6 @@ public class WaypointsCommand extends Command {
|
||||
.sortAlphabetically()
|
||||
.filterPrefix(args.getString())
|
||||
.stream();
|
||||
} else if (action == Action.RESTORE) {
|
||||
return Stream.empty();
|
||||
} else {
|
||||
return args.tabCompleteDatatype(ForWaypoints.INSTANCE);
|
||||
}
|
||||
@@ -359,19 +289,15 @@ public class WaypointsCommand extends Command {
|
||||
"",
|
||||
"Note that the info, delete, and goal commands let you specify a waypoint by tag. If there is more than one waypoint with a certain tag, then they will let you select which waypoint you mean.",
|
||||
"",
|
||||
"Missing arguments for the save command use the USER tag, creating an unnamed waypoint and your current position as defaults.",
|
||||
"",
|
||||
"Usage:",
|
||||
"> wp [l/list] - List all waypoints.",
|
||||
"> wp <l/list> <tag> - List all waypoints by tag.",
|
||||
"> wp <s/save> - Save an unnamed USER waypoint at your current position",
|
||||
"> wp <s/save> [tag] [name] [pos] - Save a waypoint with the specified tag, name and position.",
|
||||
"> wp <i/info/show> <tag/name> - Show info on a waypoint by tag or name.",
|
||||
"> wp <d/delete> <tag/name> - Delete a waypoint by tag or name.",
|
||||
"> wp <restore> <n> - Restore the last n deleted waypoints.",
|
||||
"> wp <c/clear> <tag> - Delete all waypoints with the specified tag.",
|
||||
"> wp <g/goal> <tag/name> - Set a goal to a waypoint by tag or name.",
|
||||
"> wp <goto> <tag/name> - Set a goal to a waypoint by tag or name and start pathing."
|
||||
"> wp <s/save> <tag> - Save your current position as an unnamed waypoint with the specified tag.",
|
||||
"> wp <s/save> <tag> <name> - Save the waypoint with the specified name.",
|
||||
"> wp <s/save> <tag> <name> <pos> - Save the waypoint with the specified name and position.",
|
||||
"> wp <i/info/show> <tag> - Show info on a waypoint by tag.",
|
||||
"> wp <d/delete> <tag> - Delete a waypoint by tag.",
|
||||
"> wp <g/goal> <tag> - Set a goal to a waypoint by tag.",
|
||||
"> wp <goto> <tag> - Set a goal to a waypoint by tag and start pathing."
|
||||
);
|
||||
}
|
||||
|
||||
@@ -381,7 +307,6 @@ public class WaypointsCommand extends Command {
|
||||
SAVE("save", "s"),
|
||||
INFO("info", "show", "i"),
|
||||
DELETE("delete", "d"),
|
||||
RESTORE("restore"),
|
||||
GOAL("goal", "g"),
|
||||
GOTO("goto");
|
||||
private final String[] names;
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
/**
|
||||
* The default, internal implementation of {@link ICommandManager}
|
||||
*
|
||||
@@ -94,8 +95,8 @@ public class CommandManager implements ICommandManager {
|
||||
@Override
|
||||
public Stream<String> tabComplete(String prefix) {
|
||||
Tuple<String, List<ICommandArgument>> pair = expand(prefix, true);
|
||||
String label = pair.getFirst();
|
||||
List<ICommandArgument> args = pair.getSecond();
|
||||
String label = pair.getA();
|
||||
List<ICommandArgument> args = pair.getB();
|
||||
if (args.isEmpty()) {
|
||||
return new TabCompleteHelper()
|
||||
.addCommands(this.baritone.getCommandManager())
|
||||
@@ -107,8 +108,8 @@ public class CommandManager implements ICommandManager {
|
||||
}
|
||||
|
||||
private ExecutionWrapper from(Tuple<String, List<ICommandArgument>> expanded) {
|
||||
String label = expanded.getFirst();
|
||||
ArgConsumer args = new ArgConsumer(this, expanded.getSecond());
|
||||
String label = expanded.getA();
|
||||
ArgConsumer args = new ArgConsumer(this, expanded.getB());
|
||||
|
||||
ICommand command = this.getCommand(label);
|
||||
return command == null ? null : new ExecutionWrapper(command, label, args);
|
||||
@@ -125,6 +126,7 @@ public class CommandManager implements ICommandManager {
|
||||
}
|
||||
|
||||
private static final class ExecutionWrapper {
|
||||
|
||||
private ICommand command;
|
||||
private String label;
|
||||
private ArgConsumer args;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user