Compare commits

...

56 Commits

Author SHA1 Message Date
Leijurv
3cb4700b16 v1.0.0 2018-10-15 17:21:24 -07:00
Leijurv
94921fe03f update simpletweaker version in proguard too 2018-10-15 17:21:02 -07:00
Leijurv
0202865837 Merge branch 'master' of github.com:cabaletta/baritone 2018-10-15 17:01:35 -07:00
Leijurv
b9b911eb3b add impact link 2018-10-15 17:01:29 -07:00
Brady
54fb2c5f81 Update to SimpleTweaker 1.2 2018-10-15 19:00:52 -05:00
Leijurv
2df97ff986 update install link 2018-10-15 16:55:13 -07:00
Leijurv
4374619ba2 update install and impact information 2018-10-15 16:22:03 -07:00
Leijurv
6b6ebd6968 optimize all imports 2018-10-15 16:16:04 -07:00
Leijurv
b41fdc2bbd remove spammy log prints 2018-10-15 15:39:01 -07:00
Leijurv
3cac37d1a5 cached regions in ram should not expand without bound 2018-10-15 15:19:10 -07:00
Brady
2f7259714a Fix Pathing Thread crash on Forge 2018-10-14 23:46:41 -05:00
Leijurv
c1076461e2 dont jump while using an item, fixes #222 2018-10-14 10:38:47 -07:00
Leijurv
6fdf845349 v0.0.9 2018-10-14 10:27:50 -07:00
Brady
c80b855dab Move a lot of utils to api 2018-10-14 00:55:30 -05:00
Brady
83fc11e75b private static final > private final static 2018-10-14 00:24:59 -05:00
Brady
9654892e54 Make BlockStateInterface.AIR final 2018-10-14 00:23:49 -05:00
Brady
b46fad1442 Fix bad reference 2018-10-13 23:27:11 -05:00
Brady
ff652dbe40 scanLoadedChunks -> scanChunkRadius 2018-10-13 23:15:34 -05:00
leijurv
897483884a fix 2 block parkour failure on lilypads and after descends 2018-10-13 17:01:40 -07:00
Leijurv
ba68990ef8 update codacy badge 2018-10-13 12:36:05 -07:00
Leijurv
de29a6532f privatize 2018-10-13 12:29:14 -07:00
Leijurv
9045791e7f cleanup 2018-10-13 12:28:20 -07:00
Leijurv
ab2fa0ba88 update instructions for new build system 2018-10-12 21:36:41 -07:00
Leijurv
56b67cbc47 no longer needed 2018-10-12 21:21:51 -07:00
leijurv
b6a1608e73 some improvements 2018-10-12 21:19:24 -07:00
Brady
6277c20e4c funny number 2018-10-12 22:15:54 -05:00
Brady
2fc282477d No need to override Read 2018-10-12 22:13:21 -05:00
Brady
917f393f7a Merge pull request #221 from cabaletta/gradle-proguard
Proguard Gradle Build Magic
2018-10-12 21:39:47 -05:00
Brady
045504ecf7 No differences. 100% NONE 2018-10-12 21:38:05 -05:00
Leijurv
7efc0ae8ca fix snow bs 2018-10-12 19:33:03 -07:00
Brady
3958dce341 cancer 2018-10-12 21:31:33 -05:00
Brady
d1a9012deb 2 spaces 2018-10-12 21:24:35 -05:00
Leijurv
dbde993a76 Merge branch 'master' into gradle-proguard 2018-10-12 19:24:18 -07:00
Brady
96c66d2809 CreateDist task 2018-10-12 21:21:16 -05:00
Brady
df1633b2a1 You shouldn't write a json to a jar and treat it like a jar 2018-10-12 20:42:24 -05:00
Brady
24f18f0ac2 Json sorting 2018-10-12 19:47:13 -05:00
Brady
416fea2aa5 Remove unnecessary removeIf usage 2018-10-12 18:10:54 -05:00
Brady
93286a646f Use Gradle Internal Pair 2018-10-12 18:08:15 -05:00
Brady
8fba36c05e Initial Proguard Task meme
Working Determinizer, but it doesn't sort the JSON object keys
time to rek travis
2018-10-12 17:56:09 -05:00
Leijurv
b443be1795 more accurate check 2018-10-12 15:29:25 -07:00
Leijurv
4892192c6c remove unused functions 2018-10-12 15:14:39 -07:00
Leijurv
6b7a8e2bd3 better protection logic, fix placing outside worldborder 2018-10-12 14:34:33 -07:00
Leijurv
c5f5445f4b fix exception when calculating descend from starting position above 256 2018-10-12 14:19:11 -07:00
Leijurv
8a65f43a0b check world border, fixes #218 2018-10-12 14:12:06 -07:00
Leijurv
76e4a1a649 brag about reproducible builds some more 2018-10-11 21:22:46 -07:00
Leijurv
5167c0c886 zip too 2018-10-11 21:12:00 -07:00
Leijurv
9d3d8f6c82 forgot install 2018-10-11 21:05:00 -07:00
Leijurv
7e4a1169af extract, sort, and reinsert refmap json into final jar 2018-10-11 21:04:07 -07:00
Leijurv
773ad89951 refactor problematic area 2018-10-11 20:36:18 -07:00
Leijurv
c2adcdb051 fix 2018-10-11 20:11:35 -07:00
Leijurv
b75bc6d03d comment out until its back online 2018-10-11 20:04:45 -07:00
Leijurv
e3b80f11ad brag about how reproducible our builds are 2018-10-11 20:02:26 -07:00
Leijurv
f33a2ef11b fully automated reproducible space deterministic builds 2018-10-11 18:52:58 -07:00
Brady
130b21f738 Fix issue with user input check that messed up Auto Eat 2018-10-11 18:50:55 -05:00
Leijurv
ee954d6a4e break proguard less 2018-10-11 13:24:23 -07:00
Brady
54215bdb18 Just ONE tweaker
When we make the next release, we need to specify in the setup files that Baritone now requires the SimpleTweaker dependency, and we need to remove the old alternate tweaker references. (Optifine and Forge)
2018-10-11 14:53:20 -05:00
51 changed files with 1359 additions and 691 deletions

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@
run/
autotest/
dist/
# Gradle
build/

View File

@@ -9,7 +9,7 @@ install:
- travis_retry docker build -t cabaletta/baritone .
script:
- docker run --name baritone cabaletta/baritone /bin/sh -c "set -e; /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 128x128x24 -ac +extension GLX +render; sh scripts/build.sh; DISPLAY=:99 BARITONE_AUTO_TEST=true ./gradlew runClient"
- docker run --name baritone cabaletta/baritone /bin/sh -c "set -e; /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 128x128x24 -ac +extension GLX +render; DISPLAY=:99 BARITONE_AUTO_TEST=true ./gradlew runClient"
- docker cp baritone:/code/dist dist
- ls dist
- cat dist/checksums.txt

View File

@@ -13,8 +13,6 @@ RUN apt install --target-release jessie-backports \
RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr2 libxxf86vm1 x11-xserver-utils xfonts-base xserver-common
RUN apt install -qq --force-yes unzip wget
COPY . /code
# this .deb is specially patched to support lwjgl

View File

@@ -1,91 +1 @@
# Integration between Baritone and Impact
Impact 4.4 will have Baritone included on release, however, if you're impatient, you can install Baritone into Impact 4.3 right now!
## An Introduction
There are some basic steps to getting Baritone setup with Impact.
- Acquiring a build of Baritone
- Placing Baritone in the libraries directory
- Modifying the Impact Profile JSON to run baritone
- How to use Baritone
## Acquiring a build of Baritone
There are 3 methods of acquiring a build of Baritone (While it is still in development)
### Official Release (Not always up to date)
https://github.com/cabaletta/baritone/releases
For Impact 4.3, there is no Baritone integration yet, so you will want `baritone-standalone-X.Y.Z.jar`.
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A) and ZeroMemes (73A788379A197567). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by those two public keys of `checksums.txt`.
The build for `baritone-unoptimized-X.Y.Z.jar` is deterministic, and you can verify Travis did it properly by running `scripts/build.sh` yourself and comparing the shasum. The proguarded files (api and standalone) aren't yet reproducible, because proguard annoyingly includes the current timestamp into the final jar.
### Building Baritone yourself
There are a few steps to this
- Clone this repository
- Setup the project as instructed in the README
- Run the ``build`` gradle task. You can either do this using IntelliJ's gradle UI or through a
command line
- Windows: ``gradlew build``
- Mac/Linux: ``./gradlew build``
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
### Cutting Edge Release
If you want to trust @Plutie#9079, you can download an automatically generated build of the latest commit
from his Jenkins server, found <a href="https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/">here</a>.
## Placing Baritone in the libraries directory
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>
that contains all of the dependencies that are required from the game and some mods. This is where we will be
putting baritone.
- Locate the ``libraries`` folder, it should be in the Minecraft Installation Directory
- Create 3 new subdirectories starting from ``libraries``
- ``cabaletta``
- ``baritone``
- ``X.Y.Z``
- Copy the build of Baritone that was acquired earlier, and place it into the ``X.Y.Z`` folder
- The full path should look like ``<Minecraft>/libraries/cabaletta/baritone/X.Y.Z/baritone-X.Y.Z.jar``
## Modifying the Impact Profile JSON to run baritone
The final step is "registering" the Baritone library with Impact, so that it loads on launch.
- Ensure your Minecraft launcher is closed
- Navigate back to the Minecraft Installation Directory
- Find the ``versions`` directory, and open in
- In here there should be a ``1.12.2-Impact_4.3`` folder.
- If you don't have any Impact folder or have a version older than 4.3, you can download Impact <a href="https://impactdevelopment.github.io">here</a>.
- Open the folder and inside there should be a file called ``1.12.2-Impact_4.3.json``
- Open the JSON file with a text editor that supports your system's line endings
- For example, Notepad on Windows likely will NOT work for this. You should instead use a Text Editor like
<a href="https://notepad-plus-plus.org/">Notepad++</a> if you're on Windows. (For other systems, I'm not sure
what would work the best so you may have to do some research.)
- Find the ``libraries`` array in the JSON. It should look something like this.
```
"libraries": [
{
"name": "net.minecraft:launchwrapper:1.12"
},
{
"name": "com.github.ImpactDevelopment:Impact:4.3-1.12.2",
"url": "https://impactdevelopment.github.io/maven/"
},
{
"name": "com.github.ImpactDeveloment:ClientAPI:3.0.2",
"url": "https://impactdevelopment.github.io/maven/"
},
...
```
- Create a new object in the array, between the ``Impact`` and ``ClientAPI`` dependencies preferably.
```
{
"name": "cabaletta:baritone:X.Y.Z"
},
```
- Now find the ``"minecraftArguments": "..."`` text near the top.
- At the very end of the quotes where it says ``--tweakClass clientapi.load.ClientTweaker"``, add on the following so it looks like:
- ``--tweakClass clientapi.load.ClientTweaker --tweakClass baritone.launch.BaritoneTweakerOptifine"``
- If you didn't close your launcher for this step, restart it now.
- You can now launch Impact 4.3 as normal, and Baritone should start up
## How to use Baritone
Instructions on how to use Baritone are limited, and you may have to read a little bit of code (Really nothing much
just plain English), you can view that <a href="https://github.com/cabaletta/baritone#chat-control">here</a>.
Impact 4.4 is out. See <a href="INSTALL.md">INSTALL.md</a>

98
INSTALL.md Normal file
View File

@@ -0,0 +1,98 @@
# Integration between Baritone and Impact
Impact 4.4 has Baritone included.
These instructions apply to Impact 4.3 (and potentially other hacked clients).
## An Introduction
There are some basic steps to getting Baritone setup with Impact.
- Acquiring a build of Baritone
- Placing Baritone in the libraries directory
- Modifying the Impact Profile JSON to run baritone
- How to use Baritone
## Acquiring a build of Baritone
There are 3 methods of acquiring a build of Baritone (While it is still in development)
### Official Release (Not always up to date)
https://github.com/cabaletta/baritone/releases
For Impact 4.3, there is no Baritone integration yet, so you will want `baritone-standalone-X.Y.Z.jar`.
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A) and ZeroMemes (73A788379A197567). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by those two public keys of `checksums.txt`.
The build is fully deterministic and reproducible, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone . && docker run --rm cabaletta/baritone cat /code/dist/checksums.txt` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too).
### Building Baritone yourself
There are a few steps to this
- Clone this repository
- Setup the project as instructed in the README
- Run the ``build`` gradle task. You can either do this using IntelliJ's gradle UI or through a
command line
- Windows: ``gradlew build``
- Mac/Linux: ``./gradlew build``
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
### Cutting Edge Release
If you want to trust @Plutie#9079, you can download an automatically generated build of the latest commit
from his Jenkins server, found <a href="https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/">here</a>.
## Placing Baritone in the libraries directory
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>
that contains all of the dependencies that are required from the game and some mods. This is where we will be
putting baritone.
- Locate the ``libraries`` folder, it should be in the Minecraft Installation Directory
- Create 3 new subdirectories starting from ``libraries``
- ``cabaletta``
- ``baritone``
- ``X.Y.Z``
- Copy the build of Baritone that was acquired earlier, and place it into the ``X.Y.Z`` folder
- The full path should look like ``<Minecraft>/libraries/cabaletta/baritone/X.Y.Z/baritone-X.Y.Z.jar``
## Modifying the Impact Profile JSON to run baritone
The final step is "registering" the Baritone library with Impact, so that it loads on launch.
- Ensure your Minecraft launcher is closed
- Navigate back to the Minecraft Installation Directory
- Find the ``versions`` directory, and open in
- In here there should be a ``1.12.2-Impact_4.3`` folder.
- If you don't have any Impact folder or have a version older than 4.3, you can download Impact <a href="https://impactdevelopment.github.io">here</a>.
- Open the folder and inside there should be a file called ``1.12.2-Impact_4.3.json``
- Open the JSON file with a text editor that supports your system's line endings
- For example, Notepad on Windows likely will NOT work for this. You should instead use a Text Editor like
<a href="https://notepad-plus-plus.org/">Notepad++</a> if you're on Windows. (For other systems, I'm not sure
what would work the best so you may have to do some research.)
- Find the ``libraries`` array in the JSON. It should look something like this.
```
"libraries": [
{
"name": "net.minecraft:launchwrapper:1.12"
},
{
"name": "com.github.ImpactDevelopment:Impact:4.3-1.12.2",
"url": "https://impactdevelopment.github.io/maven/"
},
{
"name": "com.github.ImpactDeveloment:ClientAPI:3.0.2",
"url": "https://impactdevelopment.github.io/maven/"
},
...
```
- Create two new objects in the array, between the ``Impact`` and ``ClientAPI`` dependencies preferably.
```
{
"name": "cabaletta:baritone:X.Y.Z"
},
{
"name": "com.github.ImpactDevelopment:SimpleTweaker:1.1",
"url": "https://impactdevelopment.github.io/maven/"
},
```
- Now find the ``"minecraftArguments": "..."`` text near the top.
- At the very end of the quotes where it says ``--tweakClass clientapi.load.ClientTweaker"``, add on the following so it looks like:
- ``--tweakClass clientapi.load.ClientTweaker --tweakClass baritone.launch.BaritoneTweakerOptifine"``
- If you didn't close your launcher for this step, restart it now.
- You can now launch Impact 4.3 as normal, and Baritone should start up
## How to use Baritone
Instructions on how to use Baritone are limited, and you may have to read a little bit of code (Really nothing much
just plain English), you can view that <a href="https://github.com/cabaletta/baritone#chat-control">here</a>.

View File

@@ -1,18 +1,20 @@
# Baritone
[![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone)
[![License](https://img.shields.io/github/license/cabaletta/baritone.svg)](LICENSE)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/7150d8ccf6094057b1782aa7a8f92d7d)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade)
Unofficial Jenkins: [![Build Status](https://plutiejenkins.leijurv.com/job/baritone/badge/icon)](https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/)
<!-- Unofficial Jenkins: [![Build Status](https://plutiejenkins.leijurv.com/job/baritone/badge/icon)](https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/) -->
A Minecraft pathfinder bot. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4.
Here are some links to help to get started:
- [Features](FEATURES.md)
- [Baritone + Impact](IMPACT.md)
- [Installation](INSTALL.md)
There's also some useful information down below

View File

@@ -1,7 +1,3 @@
import java.util.jar.JarEntry
import java.util.jar.JarFile
import java.util.jar.JarOutputStream
/*
* This file is part of Baritone.
*
@@ -20,7 +16,7 @@ import java.util.jar.JarOutputStream
*/
group 'baritone'
version '0.0.8'
version '1.0.0'
buildscript {
repositories {
@@ -41,6 +37,10 @@ buildscript {
}
}
import baritone.gradle.task.CreateDistTask
import baritone.gradle.task.ProguardTask
apply plugin: 'java'
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
apply plugin: 'org.spongepowered.mixin'
@@ -73,9 +73,15 @@ repositories {
name = 'spongepowered-repo'
url = 'http://repo.spongepowered.org/maven/'
}
maven {
name = 'impactdevelopment-repo'
url = 'https://impactdevelopment.github.io/maven/'
}
}
dependencies {
runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
// Mixin includes a lot of dependencies that are too up-to-date
exclude module: 'launchwrapper'
@@ -98,32 +104,12 @@ jar {
reproducibleFileOrder = true
}
build {
// while "jar" supports preserveFileTimestamps false
// reobfJar doesn't, it just sets all the last modified times to that instant where it runs the reobfuscator
// so we have to set all those last modified times back to zero
doLast {
File jarFile = new File("build/libs/baritone-" + version + ".jar")
JarFile jf = new JarFile(jarFile)
JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File("temp.jar")))
jf.entries().unique { it.name }.sort { it.name }.each {
if (it.name != "META-INF/fml_cache_annotation.json" && it.name != "META-INF/fml_cache_class_versions.json") {
JarEntry clone = new JarEntry(it)
clone.time = 0
jos.putNextEntry(clone)
copy(jf.getInputStream(it), jos)
}
}
jos.finish()
jf.close()
file("temp.jar").renameTo(jarFile)
}
task proguard(type: ProguardTask) {
url 'https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip'
extract 'proguard6.0.3/lib/proguard.jar'
versionManifest 'https://launchermeta.mojang.com/mc/game/version_manifest.json'
}
void copy(InputStream is, OutputStream os) {
byte[] buffer = new byte[1024]
int len = 0
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len)
}
}
task createDist(type: CreateDistTask, dependsOn: proguard)
build.finalizedBy(createDist)

3
buildSrc/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
build/
.gradle/
out/

View File

@@ -15,20 +15,11 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author Brady
* @since 7/31/2018 10:10 PM
*/
public class BaritoneTweakerOptifine extends BaritoneTweaker {
@Override
public final void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
this.args = new ArrayList<>();
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
compile group: 'commons-io', name: 'commons-io', version: '2.6'
}

View File

@@ -0,0 +1,102 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.gradle.task;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.gradle.api.DefaultTask;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
/**
* @author Brady
* @since 10/12/2018
*/
class BaritoneGradleTask extends DefaultTask {
static final JsonParser PARSER = new JsonParser();
static final String
PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar",
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
PROGUARD_CONFIG_DEST = "template.pro",
PROGUARD_API_CONFIG = "api.pro",
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
PROGUARD_EXPORT_PATH = "proguard_out.jar",
VERSION_MANIFEST = "version_manifest.json",
TEMP_LIBRARY_DIR = "tempLibraries/",
ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
String artifactName, artifactVersion;
Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
void verifyArtifacts() throws Exception {
this.artifactName = getProject().getName();
this.artifactVersion = getProject().getVersion().toString();
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
if (!Files.exists(this.artifactPath)) {
throw new Exception("Artifact not found! Run build first!");
}
}
void write(InputStream stream, Path file) throws Exception {
if (Files.exists(file)) {
Files.delete(file);
}
Files.copy(stream, file);
}
String formatVersion(String string) {
return String.format(string, this.artifactName, this.artifactVersion);
}
Path getRelativeFile(String file) {
return Paths.get(new File(file).getAbsolutePath());
}
Path getTemporaryFile(String file) {
return Paths.get(new File(getTemporaryDir(), file).getAbsolutePath());
}
Path getBuildFile(String file) {
return getRelativeFile("build/libs/" + file);
}
JsonElement readJson(List<String> lines) {
return PARSER.parse(String.join("\n", lines));
}
}

View File

@@ -0,0 +1,80 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.gradle.task;
import org.gradle.api.tasks.TaskAction;
import javax.xml.bind.DatatypeConverter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/**
* @author Brady
* @since 10/12/2018
*/
public class CreateDistTask extends BaritoneGradleTask {
private static MessageDigest SHA1_DIGEST;
@TaskAction
protected void exec() throws Exception {
super.verifyArtifacts();
// Define the distribution file paths
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
Path unoptimized = getRelativeFile("dist/" + formatVersion(ARTIFACT_UNOPTIMIZED));
// NIO will not automatically create directories
Path dir = getRelativeFile("dist/");
if (!Files.exists(dir)) {
Files.createDirectory(dir);
}
// Copy build jars to dist/
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
Files.copy(this.artifactStandalonePath, standalone, REPLACE_EXISTING);
Files.copy(this.artifactUnoptimizedPath, unoptimized, REPLACE_EXISTING);
// Calculate all checksums and format them like "shasum"
List<String> shasum = Stream.of(api, standalone, unoptimized)
.map(path -> sha1(path) + " " + path.getFileName().toString())
.collect(Collectors.toList());
// Write the checksums to a file
Files.write(getRelativeFile("dist/checksums.txt"), shasum);
}
private static synchronized String sha1(Path path) {
try {
if (SHA1_DIGEST == null) {
SHA1_DIGEST = MessageDigest.getInstance("SHA-1");
}
return DatatypeConverter.printHexBinary(SHA1_DIGEST.digest(Files.readAllBytes(path))).toLowerCase();
} catch (Exception e) {
// haha no thanks
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,260 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.gradle.task;
import baritone.gradle.util.Determinizer;
import com.google.gson.*;
import org.apache.commons.io.IOUtils;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction;
import org.gradle.internal.Pair;
import java.io.*;
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.zip.ZipEntry;
import java.util.zip.ZipFile;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/**
* @author Brady
* @since 10/11/2018
*/
public class ProguardTask extends BaritoneGradleTask {
private static final Pattern TEMP_LIBRARY_PATTERN = Pattern.compile("-libraryjars 'tempLibraries\\/([a-zA-Z0-9/_\\-\\.]+)\\.jar'");
@Input
private String url;
@Input
private String extract;
@Input
private String versionManifest;
private Map<String, String> versionDownloadMap;
private List<String> requiredLibraries;
@TaskAction
protected void exec() throws Exception {
super.verifyArtifacts();
// "Haha brady why don't you make separate tasks"
processArtifact();
downloadProguard();
extractProguard();
generateConfigs();
downloadVersionManifest();
acquireDependencies();
proguardApi();
proguardStandalone();
cleanup();
}
private void processArtifact() throws Exception {
if (Files.exists(this.artifactUnoptimizedPath)) {
Files.delete(this.artifactUnoptimizedPath);
}
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
}
private void downloadProguard() throws Exception {
Path proguardZip = getTemporaryFile(PROGUARD_ZIP);
if (!Files.exists(proguardZip)) {
write(new URL(this.url).openStream(), proguardZip);
}
}
private void extractProguard() throws Exception {
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
if (!Files.exists(proguardJar)) {
ZipFile zipFile = new ZipFile(getTemporaryFile(PROGUARD_ZIP).toFile());
ZipEntry zipJarEntry = zipFile.getEntry(this.extract);
write(zipFile.getInputStream(zipJarEntry), proguardJar);
zipFile.close();
}
}
private void generateConfigs() throws Exception {
Files.copy(getRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), REPLACE_EXISTING);
// Setup the template that will be used to derive the API and Standalone configs
List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST));
template.add(0, "-injars " + this.artifactPath.toString());
template.add(1, "-outjars " + this.getTemporaryFile(PROGUARD_EXPORT_PATH));
// Acquire the RT jar using "java -verbose". This doesn't work on Java 9+
Process p = new ProcessBuilder("java", "-verbose").start();
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
template.add(2, "-libraryjars '" + out + "'");
// API config doesn't require any changes from the changes that we made to the template
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
// For the Standalone config, don't keep the API package
List<String> standalone = new ArrayList<>(template);
standalone.removeIf(s -> s.contains("# this is the keep api"));
Files.write(getTemporaryFile(PROGUARD_STANDALONE_CONFIG), standalone);
// Discover all of the libraries that we will need to acquire from gradle
this.requiredLibraries = new ArrayList<>();
template.forEach(line -> {
if (!line.startsWith("#")) {
Matcher m = TEMP_LIBRARY_PATTERN.matcher(line);
if (m.find()) {
this.requiredLibraries.add(m.group(1));
}
}
});
}
private void downloadVersionManifest() throws Exception {
Path manifestJson = getTemporaryFile(VERSION_MANIFEST);
write(new URL(this.versionManifest).openStream(), manifestJson);
// Place all the versions in the map with their download URL
this.versionDownloadMap = new HashMap<>();
JsonObject json = readJson(Files.readAllLines(manifestJson)).getAsJsonObject();
JsonArray versions = json.getAsJsonArray("versions");
versions.forEach(element -> {
JsonObject object = element.getAsJsonObject();
this.versionDownloadMap.put(object.get("id").getAsString(), object.get("url").getAsString());
});
}
private void acquireDependencies() throws Exception {
// Create a map of all of the dependencies that we are able to access in this project
// 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) {
// Download the version jar from the URL acquired from the version manifest
if (lib.startsWith("minecraft")) {
String version = lib.split("-")[1];
Path versionJar = getTemporaryFile("tempLibraries/" + lib + ".jar");
if (!Files.exists(versionJar)) {
JsonObject versionJson = PARSER.parse(new InputStreamReader(new URL(this.versionDownloadMap.get(version)).openStream())).getAsJsonObject();
String url = versionJson.getAsJsonObject("downloads").getAsJsonObject("client").getAsJsonPrimitive("url").getAsString();
write(new URL(url).openStream(), versionJar);
}
continue;
}
// Find a configuration/dependency pair that matches the desired library
Pair<Configuration, Dependency> pair = null;
for (Map.Entry<String, Pair<Configuration, Dependency>> entry : dependencyLookupMap.entrySet()) {
if (entry.getKey().startsWith(lib)) {
pair = entry.getValue();
}
}
// The pair must be non-null
Objects.requireNonNull(pair);
// Find the library jar file, and copy it to tempLibraries
for (File file : pair.getLeft().files(pair.getRight())) {
if (file.getName().startsWith(lib)) {
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
}
}
}
}
private void proguardApi() throws Exception {
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
}
private void proguardStandalone() throws Exception {
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
}
private void cleanup() {
try {
Files.delete(this.proguardOut);
} catch (IOException ignored) {}
}
public void setUrl(String url) {
this.url = url;
}
public void setExtract(String extract) {
this.extract = extract;
}
public void setVersionManifest(String versionManifest) {
this.versionManifest = versionManifest;
}
private void runProguard(Path config) throws Exception {
// Delete the existing proguard output file. Proguard probably handles this already, but why not do it ourselves
if (Files.exists(this.proguardOut)) {
Files.delete(this.proguardOut);
}
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
.directory(getTemporaryFile("").toFile()) // Set the working directory to the temporary folder]
.start();
// We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this
this.printOutputLog(p.getInputStream());
this.printOutputLog(p.getErrorStream());
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
int exitCode = p.waitFor();
if (exitCode != 0) {
throw new Exception("Proguard exited with code " + exitCode);
}
}
private void printOutputLog(InputStream stream) {
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (final Exception e) {
e.printStackTrace();
}
}).start();
}
}

View File

@@ -0,0 +1,143 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.gradle.util;
import com.google.gson.*;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.stream.Collectors;
/**
* Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 0.
* This makes the build 100% reproducible since the timestamp when you built it no longer affects the final file.
*
* @author leijurv
*/
public class Determinizer {
public static void determinize(String inputPath, String outputPath) throws IOException {
System.out.println("Running Determinizer");
System.out.println(" Input path: " + inputPath);
System.out.println(" Output path: " + outputPath);
try (
JarFile jarFile = new JarFile(new File(inputPath));
JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File(outputPath)))
) {
List<JarEntry> entries = jarFile.stream()
.sorted(Comparator.comparing(JarEntry::getName))
.collect(Collectors.toList());
for (JarEntry entry : entries) {
if (entry.getName().equals("META-INF/fml_cache_annotation.json")) {
continue;
}
if (entry.getName().equals("META-INF/fml_cache_class_versions.json")) {
continue;
}
JarEntry clone = new JarEntry(entry.getName());
clone.setTime(42069);
jos.putNextEntry(clone);
if (entry.getName().endsWith(".refmap.json")) {
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
jos.write(writeSorted(object).getBytes());
} else {
copy(jarFile.getInputStream(entry), jos);
}
}
jos.finish();
}
}
private static void copy(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
}
private static String writeSorted(JsonObject in) throws IOException {
StringWriter writer = new StringWriter();
JsonWriter jw = new JsonWriter(writer);
ORDERED_JSON_WRITER.write(jw, in);
return writer.toString() + "\n";
}
/**
* All credits go to GSON and its contributors. GSON is licensed under the Apache 2.0 License.
* This implementation has been modified to write {@link JsonObject} keys in order.
*
* @see <a href="https://github.com/google/gson/blob/master/LICENSE">GSON License</a>
* @see <a href="https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java#L698">Original Source</a>
*/
private static final TypeAdapter<JsonElement> ORDERED_JSON_WRITER = new TypeAdapter<JsonElement>() {
@Override
public JsonElement read(JsonReader in) {
return null;
}
@Override
public void write(JsonWriter out, JsonElement value) throws IOException {
if (value == null || value.isJsonNull()) {
out.nullValue();
} else if (value.isJsonPrimitive()) {
JsonPrimitive primitive = value.getAsJsonPrimitive();
if (primitive.isNumber()) {
out.value(primitive.getAsNumber());
} else if (primitive.isBoolean()) {
out.value(primitive.getAsBoolean());
} else {
out.value(primitive.getAsString());
}
} else if (value.isJsonArray()) {
out.beginArray();
for (JsonElement e : value.getAsJsonArray()) {
write(out, e);
}
out.endArray();
} else if (value.isJsonObject()) {
out.beginObject();
List<Map.Entry<String, JsonElement>> entries = new ArrayList<>(value.getAsJsonObject().entrySet());
entries.sort(Comparator.comparing(Map.Entry::getKey));
for (Map.Entry<String, JsonElement> e : entries) {
out.name(e.getKey());
write(out, e.getValue());
}
out.endObject();
} else {
throw new IllegalArgumentException("Couldn't write " + value.getClass());
}
}
};
}

View File

@@ -1,27 +0,0 @@
#!/bin/sh
set -e # this makes the whole script fail immediately if any one of these commands fails
./gradlew build
export VERSION=$(cat build.gradle | grep "version '" | cut -d "'" -f 2-2)
wget -nv https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip
unzip proguard6.0.3.zip 2>&1 > /dev/null
cd build/libs
echo "-injars 'baritone-$VERSION.jar'" >> api.pro # insert current version
cat ../../scripts/proguard.pro | grep -v "this is the rt jar" | grep -v "\-injars" >> api.pro # remove default rt jar and injar lines
echo "-libraryjars '$(java -verbose 2>/dev/null | sed -ne '1 s/\[Opened \(.*\)\]/\1/p')'" >> api.pro # insert correct rt.jar location
tail api.pro # debug, print out what the previous two commands generated
cat api.pro | grep -v "this is the keep api" > standalone.pro # standalone doesn't keep baritone api
#instead of downloading these jars from my dropbox in a zip, just assume gradle's already got them for us
mkdir -p tempLibraries
cat ../../scripts/proguard.pro | grep tempLibraries | grep .jar | cut -d "/" -f 2- | cut -d "'" -f -1 | xargs -n1 -I{} bash -c "find ~/.gradle -name {}" | tee /dev/stderr | xargs -n1 -I{} cp {} tempLibraries
mkdir ../../dist
java -jar ../../proguard6.0.3/lib/proguard.jar @api.pro
mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-api-$VERSION.jar
java -jar ../../proguard6.0.3/lib/proguard.jar @standalone.pro
mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-standalone-$VERSION.jar
mv baritone-$VERSION.jar ../../dist/baritone-unoptimized-$VERSION.jar
cd ../../dist
shasum * | tee checksums.txt
cd ..

19
scripts/proguard.pro vendored
View File

@@ -1,7 +1,3 @@
-injars baritone-0.0.8.jar
-outjars Obfuscated
-keepattributes Signature
-keepattributes *Annotation*
@@ -29,10 +25,11 @@
-keep class baritone.launch.** { *; }
# copy all necessary libraries into tempLibraries to build
-libraryjars '/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/rt.jar' # this is the rt jar
-libraryjars 'tempLibraries/minecraft-1.12.2.jar'
-libraryjars 'tempLibraries/SimpleTweaker-1.2.jar'
-libraryjars 'tempLibraries/authlib-1.5.25.jar'
-libraryjars 'tempLibraries/codecjorbis-20101023.jar'
-libraryjars 'tempLibraries/codecwav-20101023.jar'
@@ -47,7 +44,6 @@
-libraryjars 'tempLibraries/httpclient-4.3.3.jar'
-libraryjars 'tempLibraries/httpcore-4.3.2.jar'
-libraryjars 'tempLibraries/icu4j-core-mojang-51.2.jar'
-libraryjars 'tempLibraries/java-objc-bridge-1.0.0.jar'
-libraryjars 'tempLibraries/jinput-2.0.5.jar'
-libraryjars 'tempLibraries/jna-4.4.0.jar'
-libraryjars 'tempLibraries/jopt-simple-5.0.3.jar'
@@ -58,13 +54,10 @@
-libraryjars 'tempLibraries/log4j-api-2.8.1.jar'
-libraryjars 'tempLibraries/log4j-core-2.8.1.jar'
# linux / travis
-libraryjars 'tempLibraries/lwjgl-2.9.4-nightly-20150209.jar'
-libraryjars 'tempLibraries/lwjgl_util-2.9.4-nightly-20150209.jar'
# mac
#-libraryjars 'tempLibraries/lwjgl_util-2.9.2-nightly-20140822.jar'
#-libraryjars 'tempLibraries/lwjgl-2.9.2-nightly-20140822.jar'
# startsWith is used to check the library, and mac/linux differ in which version they use
# this is FINE
-libraryjars 'tempLibraries/lwjgl-.jar'
-libraryjars 'tempLibraries/lwjgl_util-.jar'
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
-libraryjars 'tempLibraries/oshi-core-1.1.jar'

View File

@@ -36,8 +36,8 @@ import java.util.ServiceLoader;
*/
public final class BaritoneAPI {
private final static IBaritoneProvider baritone;
private final static Settings settings;
private static final IBaritoneProvider baritone;
private static final Settings settings;
static {
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);

View File

@@ -17,9 +17,9 @@
package baritone.api.behavior;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.path.IPathExecutor;
import java.util.Optional;

View File

@@ -38,5 +38,5 @@ public interface IWorldScanner {
* @param maxSearchRadius The maximum chunk search radius
* @return The matching block positions
*/
List<BlockPos> scanLoadedChunks(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
List<BlockPos> scanChunkRadius(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
}

View File

@@ -15,22 +15,29 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
package baritone.api.utils;
import baritone.api.utils.Rotation;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import static baritone.behavior.LookBehaviorUtils.calcVec3dFromRotation;
import java.util.Optional;
/**
* @author Brady
* @since 8/25/2018
*/
public final class RayTraceUtils implements Helper {
public final class RayTraceUtils {
private RayTraceUtils() {}
/**
* The {@link Minecraft} instance
*/
private static final Minecraft mc = Minecraft.getMinecraft();
/**
* Simulates a "vanilla" raytrace. A RayTraceResult returned by this method
* will be that of the next render pass given that the local player's yaw and
@@ -72,7 +79,7 @@ public final class RayTraceUtils implements Helper {
public static RayTraceResult rayTraceTowards(Rotation rotation) {
double blockReachDistance = mc.playerController.getBlockReachDistance();
Vec3d start = mc.player.getPositionEyes(1.0F);
Vec3d direction = calcVec3dFromRotation(rotation);
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
Vec3d end = start.add(
direction.x * blockReachDistance,
direction.y * blockReachDistance,
@@ -80,4 +87,28 @@ public final class RayTraceUtils implements Helper {
);
return mc.world.rayTraceBlocks(start, end, false, false, true);
}
/**
* Returns the block that the crosshair is currently placed over. Updated once per render tick.
*
* @return The position of the highlighted block
*/
public static Optional<BlockPos> getSelectedBlock() {
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(mc.objectMouseOver.getBlockPos());
}
return Optional.empty();
}
/**
* Returns the entity that the crosshair is currently placed over. Updated once per render tick.
*
* @return The entity
*/
public static Optional<Entity> getSelectedEntity() {
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(mc.objectMouseOver.entityHit);
}
return Optional.empty();
}
}

View File

@@ -17,6 +17,14 @@
package baritone.api.utils;
import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.*;
import java.util.Optional;
/**
* @author Brady
* @since 9/25/2018
@@ -25,6 +33,33 @@ public final class RotationUtils {
private RotationUtils() {}
/**
* The {@link Minecraft} instance
*/
private static final Minecraft mc = Minecraft.getMinecraft();
/**
* Constant that a degree value is multiplied by to get the equivalent radian value
*/
public static final double DEG_TO_RAD = Math.PI / 180.0;
/**
* Constant that a radian value is multiplied by to get the equivalent degree value
*/
public static final double RAD_TO_DEG = 180.0 / Math.PI;
/**
* Offsets from the root block position to the center of each side.
*/
private static final Vec3d[] BLOCK_SIDE_MULTIPLIERS = new Vec3d[]{
new Vec3d(0.5, 0, 0.5), // Down
new Vec3d(0.5, 1, 0.5), // Up
new Vec3d(0.5, 0.5, 0), // North
new Vec3d(0.5, 0.5, 1), // South
new Vec3d(0, 0.5, 0.5), // West
new Vec3d(1, 0.5, 0.5) // East
};
/**
* Clamps the specified pitch value between -90 and 90.
*
@@ -51,4 +86,156 @@ public final class RotationUtils {
}
return newYaw;
}
/**
* Calculates the rotation from BlockPos<sub>dest</sub> to BlockPos<sub>orig</sub>
*
* @param orig The origin position
* @param dest The destination position
* @return The rotation from the origin to the destination
*/
public static Rotation calcRotationFromCoords(BlockPos orig, BlockPos dest) {
return calcRotationFromVec3d(new Vec3d(orig), new Vec3d(dest));
}
/**
* Wraps the target angles to a relative value from the current angles. This is done by
* subtracting the current from the target, normalizing it, and then adding the current
* angles back to it.
*
* @param current The current angles
* @param target The target angles
* @return The wrapped angles
*/
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
return target.subtract(current).normalize().add(current);
}
/**
* Calculates the rotation from Vec<sub>dest</sub> to Vec<sub>orig</sub> and makes the
* return value relative to the specified current rotations.
*
* @param orig The origin position
* @param dest The destination position
* @param current The current rotations
* @return The rotation from the origin to the destination
* @see #wrapAnglesToRelative(Rotation, Rotation)
*/
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest, Rotation current) {
return wrapAnglesToRelative(current, calcRotationFromVec3d(orig, dest));
}
/**
* Calculates the rotation from Vec<sub>dest</sub> to Vec<sub>orig</sub>
*
* @param orig The origin position
* @param dest The destination position
* @return The rotation from the origin to the destination
*/
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
double[] delta = {orig.x - dest.x, orig.y - dest.y, orig.z - dest.z};
double yaw = MathHelper.atan2(delta[0], -delta[2]);
double dist = Math.sqrt(delta[0] * delta[0] + delta[2] * delta[2]);
double pitch = MathHelper.atan2(delta[1], dist);
return new Rotation(
(float) (yaw * RAD_TO_DEG),
(float) (pitch * RAD_TO_DEG)
);
}
/**
* Calculates the look vector for the specified yaw/pitch rotations.
*
* @param rotation The input rotation
* @return Look vector for the rotation
*/
public static Vec3d calcVec3dFromRotation(Rotation rotation) {
float f = MathHelper.cos(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
float f1 = MathHelper.sin(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
float f2 = -MathHelper.cos(-rotation.getPitch() * (float) DEG_TO_RAD);
float f3 = MathHelper.sin(-rotation.getPitch() * (float) DEG_TO_RAD);
return new Vec3d((double) (f1 * f2), (double) f3, (double) (f * f2));
}
/**
* Determines if the specified entity is able to reach the center of any of the sides
* of the specified block. It first checks if the block center is reachable, and if so,
* that rotation will be returned. If not, it will return the first center of a given
* side that is reachable. The return type will be {@link Optional#empty()} if the entity is
* unable to reach any of the sides of the block.
*
* @param entity The viewing entity
* @param pos The target block position
* @return The optional rotation
*/
public static Optional<Rotation> reachable(Entity entity, BlockPos pos) {
if (pos.equals(RayTraceUtils.getSelectedBlock().orElse(null))) {
/*
* why add 0.0001?
* to indicate that we actually have a desired pitch
* the way we indicate that the pitch can be whatever and we only care about the yaw
* is by setting the desired pitch to the current pitch
* setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's
* just what it currently is
*/
return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F));
}
Optional<Rotation> possibleRotation = reachableCenter(entity, pos);
//System.out.println("center: " + possibleRotation);
if (possibleRotation.isPresent()) {
return possibleRotation;
}
IBlockState state = mc.world.getBlockState(pos);
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff));
if (possibleRotation.isPresent()) {
return possibleRotation;
}
}
return Optional.empty();
}
/**
* Determines if the specified entity is able to reach the specified block with
* the given offsetted position. The return type will be {@link Optional#empty()} if
* the entity is unable to reach the block with the offset applied.
*
* @param entity The viewing entity
* @param pos The target block position
* @param offsetPos The position of the block with the offset applied.
* @return The optional rotation
*/
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos) {
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos);
RayTraceResult result = RayTraceUtils.rayTraceTowards(rotation);
//System.out.println(result);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
if (result.getBlockPos().equals(pos)) {
return Optional.of(rotation);
}
if (entity.world.getBlockState(pos).getBlock() instanceof BlockFire) {
if (result.getBlockPos().equals(pos.down())) {
return Optional.of(rotation);
}
}
}
return Optional.empty();
}
/**
* Determines if the specified entity is able to reach the specified block where it is
* looking at the direct center of it's hitbox.
*
* @param entity The viewing entity
* @param pos The target block position
* @return The optional rotation
*/
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos) {
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(pos));
}
}

View File

@@ -31,6 +31,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SettingsUtil {
private static final File settingsFile = new File(new File(Minecraft.getMinecraft().gameDir, "baritone"), "settings.txt");
private static final Map<Class<?>, SettingsIO> map;

View File

@@ -0,0 +1,126 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils;
import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
/**
* @author Brady
* @since 10/13/2018
*/
public final class VecUtils {
private VecUtils() {}
/**
* The {@link Minecraft} instance
*/
private static final Minecraft mc = Minecraft.getMinecraft();
/**
* Calculates the center of the block at the specified position's bounding box
*
* @see #getBlockPosCenter(BlockPos)
*
* @param pos The block position
* @return The center of the block's bounding box
*/
public static Vec3d calculateBlockCenter(BlockPos pos) {
IBlockState b = mc.world.getBlockState(pos);
AxisAlignedBB bbox = b.getBoundingBox(mc.world, pos);
double xDiff = (bbox.minX + bbox.maxX) / 2;
double yDiff = (bbox.minY + bbox.maxY) / 2;
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
yDiff = 0;
}
return new Vec3d(
pos.getX() + xDiff,
pos.getY() + yDiff,
pos.getZ() + zDiff
);
}
/**
* Gets the assumed center position of the given block position.
* This is done by adding 0.5 to the X, Y, and Z axes.
* <p>
* TODO: We may want to consider replacing many usages of this method with #calculateBlockCenter(BlockPos)
*
* @see #calculateBlockCenter(BlockPos)
*
* @param pos The block position
* @return The assumed center of the position
*/
public static Vec3d getBlockPosCenter(BlockPos pos) {
return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
}
/**
* Gets the distance from the specified position to the assumed center of the specified block position.
*
* @see #getBlockPosCenter(BlockPos)
*
* @param pos The block position
* @param x The x pos
* @param y The y pos
* @param z The z pos
* @return The distance from the assumed block center to the position
*/
public static double distanceToCenter(BlockPos pos, double x, double y, double z) {
Vec3d center = getBlockPosCenter(pos);
double xdiff = x - center.x;
double ydiff = y - center.y;
double zdiff = z - center.z;
return Math.sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
}
/**
* Gets the distance from the specified entity's position to the assumed
* center of the specified block position.
*
* @see #getBlockPosCenter(BlockPos)
*
* @param entity The entity
* @param pos The block position
* @return The distance from the entity to the block's assumed center
*/
public static double entityDistanceToCenter(Entity entity, BlockPos pos) {
return distanceToCenter(pos, entity.posX, entity.posY, entity.posZ);
}
/**
* Gets the distance from the specified entity's position to the assumed
* center of the specified block position, ignoring the Y axis.
*
* @see #getBlockPosCenter(BlockPos)
*
* @param entity The entity
* @param pos The block position
* @return The horizontal distance from the entity to the block's assumed center
*/
public static double entityFlatDistanceToCenter(Entity entity, BlockPos pos) {
return distanceToCenter(pos, entity.posX, pos.getY() + 0.5, entity.posZ);
}
}

View File

@@ -17,61 +17,39 @@
package baritone.launch;
import net.minecraft.launchwrapper.ITweaker;
import io.github.impactdevelopment.simpletweaker.SimpleTweaker;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.spongepowered.asm.launch.MixinBootstrap;
import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.asm.mixin.Mixins;
import org.spongepowered.tools.obfuscation.mcp.ObfuscationServiceMCP;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author Brady
* @since 7/31/2018 9:59 PM
*/
public class BaritoneTweaker implements ITweaker {
List<String> args;
@Override
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
this.args = new ArrayList<>(args);
if (gameDir != null) {
addArg("gameDir", gameDir.getAbsolutePath());
}
if (assetsDir != null) {
addArg("assetsDir", assetsDir.getAbsolutePath());
}
if (profile != null) {
addArg("version", profile);
}
}
public class BaritoneTweaker extends SimpleTweaker {
@Override
public void injectIntoClassLoader(LaunchClassLoader classLoader) {
super.injectIntoClassLoader(classLoader);
MixinBootstrap.init();
// noinspection unchecked
List<String> tweakClasses = (List<String>) Launch.blackboard.get("TweakClasses");
String obfuscation = ObfuscationServiceMCP.NOTCH;
if (tweakClasses.stream().anyMatch(s -> s.contains("net.minecraftforge.fml.common.launcher"))) {
obfuscation = ObfuscationServiceMCP.SEARGE;
}
MixinEnvironment.getDefaultEnvironment().setSide(MixinEnvironment.Side.CLIENT);
MixinEnvironment.getDefaultEnvironment().setObfuscationContext(ObfuscationServiceMCP.NOTCH);
MixinEnvironment.getDefaultEnvironment().setObfuscationContext(obfuscation);
Mixins.addConfiguration("mixins.baritone.json");
}
@Override
public final String getLaunchTarget() {
return "net.minecraft.client.main.Main";
}
@Override
public final String[] getLaunchArguments() {
return this.args.toArray(new String[0]);
}
private void addArg(String label, String value) {
if (!args.contains("--" + label) && value != null) {
this.args.add("--" + label);
this.args.add(value);
}
}
}

View File

@@ -1,44 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.spongepowered.asm.mixin.MixinEnvironment;
import org.spongepowered.tools.obfuscation.mcp.ObfuscationServiceMCP;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* @author Brady
* @since 7/31/2018 10:09 PM
*/
public class BaritoneTweakerForge extends BaritoneTweaker {
@Override
public final void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
this.args = new ArrayList<>();
}
@Override
public final void injectIntoClassLoader(LaunchClassLoader classLoader) {
super.injectIntoClassLoader(classLoader);
MixinEnvironment.getDefaultEnvironment().setObfuscationContext(ObfuscationServiceMCP.SEARGE);
}
}

View File

@@ -147,7 +147,7 @@ public class MixinMinecraft {
)
)
private boolean isAllowUserInput(GuiScreen screen) {
return (PathingBehavior.INSTANCE.getCurrent() != null && player != null) || screen.allowUserInput;
return (PathingBehavior.INSTANCE.getCurrent() != null && PathingBehavior.INSTANCE.isEnabled() && player != null) || screen.allowUserInput;
}
@Inject(

View File

@@ -1,139 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.api.utils.Rotation;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.RayTraceUtils;
import baritone.utils.Utils;
import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.*;
import java.util.Optional;
import static baritone.utils.Utils.DEG_TO_RAD;
public final class LookBehaviorUtils implements Helper {
/**
* Offsets from the root block position to the center of each side.
*/
private static final Vec3d[] BLOCK_SIDE_MULTIPLIERS = new Vec3d[]{
new Vec3d(0.5, 0, 0.5), // Down
new Vec3d(0.5, 1, 0.5), // Up
new Vec3d(0.5, 0.5, 0), // North
new Vec3d(0.5, 0.5, 1), // South
new Vec3d(0, 0.5, 0.5), // West
new Vec3d(1, 0.5, 0.5) // East
};
/**
* Calculates a vector given a rotation array
*
* @param rotation {@link LookBehavior#target}
* @return vector of the rotation
*/
public static Vec3d calcVec3dFromRotation(Rotation rotation) {
float f = MathHelper.cos(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
float f1 = MathHelper.sin(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
float f2 = -MathHelper.cos(-rotation.getPitch() * (float) DEG_TO_RAD);
float f3 = MathHelper.sin(-rotation.getPitch() * (float) DEG_TO_RAD);
return new Vec3d((double) (f1 * f2), (double) f3, (double) (f * f2));
}
public static Optional<Rotation> reachable(BlockPos pos) {
if (pos.equals(getSelectedBlock().orElse(null))) {
/*
* why add 0.0001?
* to indicate that we actually have a desired pitch
* the way we indicate that the pitch can be whatever and we only care about the yaw
* is by setting the desired pitch to the current pitch
* setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's
* just what it currently is
*/
return Optional.of(new Rotation(mc.player.rotationYaw, mc.player.rotationPitch + 0.0001f));
}
Optional<Rotation> possibleRotation = reachableCenter(pos);
//System.out.println("center: " + possibleRotation);
if (possibleRotation.isPresent()) {
return possibleRotation;
}
IBlockState state = BlockStateInterface.get(pos);
AxisAlignedBB aabb = state.getBoundingBox(mc.world, pos);
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
possibleRotation = reachableOffset(pos, new Vec3d(pos).add(xDiff, yDiff, zDiff));
if (possibleRotation.isPresent()) {
return possibleRotation;
}
}
return Optional.empty();
}
/**
* Checks if coordinate is reachable with the given block-face rotation offset
*
* @param pos
* @param offsetPos
* @return
*/
protected static Optional<Rotation> reachableOffset(BlockPos pos, Vec3d offsetPos) {
Rotation rotation = Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F), offsetPos);
RayTraceResult result = RayTraceUtils.rayTraceTowards(rotation);
System.out.println(result);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
if (result.getBlockPos().equals(pos)) {
return Optional.of(rotation);
}
if (BlockStateInterface.get(pos).getBlock() instanceof BlockFire) {
if (result.getBlockPos().equals(pos.down())) {
return Optional.of(rotation);
}
}
}
return Optional.empty();
}
/**
* Checks if center of block at coordinate is reachable
*
* @param pos
* @return
*/
protected static Optional<Rotation> reachableCenter(BlockPos pos) {
return reachableOffset(pos, Utils.calcCenterFromCoords(pos, mc.world));
}
/**
* The currently highlighted block.
* Updated once a tick by Minecraft.
*
* @return the position of the highlighted block
*/
public static Optional<BlockPos> getSelectedBlock() {
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(mc.objectMouseOver.getBlockPos());
}
return Optional.empty();
}
}

View File

@@ -110,28 +110,30 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
locationsCache = locs;
}
public GoalComposite coalesce(List<BlockPos> locs) {
return new GoalComposite(locs.stream().map(loc -> {
if (!Baritone.settings().forceInternalMining.get()) {
public Goal coalesce(BlockPos loc, List<BlockPos> locs) {
if (!Baritone.settings().forceInternalMining.get()) {
return new GoalTwoBlocks(loc);
}
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
if (upwardGoal) {
if (downwardGoal) {
return new GoalTwoBlocks(loc);
} else {
return new GoalBlock(loc);
}
} else {
if (downwardGoal) {
return new GoalBlock(loc.down());
} else {
return new GoalTwoBlocks(loc);
}
}
}
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
if (upwardGoal) {
if (downwardGoal) {
return new GoalTwoBlocks(loc);
} else {
return new GoalBlock(loc);
}
} else {
if (downwardGoal) {
return new GoalBlock(loc.down());
} else {
return new GoalTwoBlocks(loc);
}
}
}).toArray(Goal[]::new));
public GoalComposite coalesce(List<BlockPos> locs) {
return new GoalComposite(locs.stream().map(loc -> coalesce(loc, locs)).toArray(Goal[]::new));
}
public List<BlockPos> scanFor(List<Block> mining, int max) {
@@ -151,7 +153,7 @@ public final class MineBehavior extends Behavior implements IMineBehavior, Helpe
}
if (!uninteresting.isEmpty()) {
//long before = System.currentTimeMillis();
locs.addAll(WorldScanner.INSTANCE.scanLoadedChunks(uninteresting, max, 10, 26));
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
}
return prune(locs, mining, max);

View File

@@ -319,6 +319,21 @@ public final class CachedRegion implements ICachedRegion {
}
}
public synchronized final CachedChunk mostRecentlyModified() {
CachedChunk recent = null;
for (int x = 0; x < 32; x++) {
for (int z = 0; z < 32; z++) {
if (this.chunks[x][z] == null) {
continue;
}
if (recent == null || this.chunks[x][z].cacheTimestamp > recent.cacheTimestamp) {
recent = this.chunks[x][z];
}
}
}
return recent;
}
/**
* @return The region x coordinate
*/

View File

@@ -147,6 +147,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
region.removeExpired();
}
}); // even if we aren't saving to disk, still delete expired old chunks from RAM
prune();
return;
}
long start = System.nanoTime() / 1000000L;
@@ -157,6 +158,47 @@ public final class CachedWorld implements ICachedWorld, Helper {
});
long now = System.nanoTime() / 1000000L;
System.out.println("World save took " + (now - start) + "ms");
prune();
}
/**
* Delete regions that are too far from the player
*/
private synchronized void prune() {
BlockPos pruneCenter = guessPosition();
for (CachedRegion region : allRegions()) {
int distX = (region.getX() * 512 + 256) - pruneCenter.getX();
int distZ = (region.getZ() * 512 + 256) - pruneCenter.getZ();
double dist = Math.sqrt(distX * distX + distZ * distZ);
if (dist > 1024) {
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
cachedRegions.remove(getRegionID(region.getX(), region.getZ()));
}
}
}
/**
* If we are still in this world and dimension, return player feet, otherwise return most recently modified chunk
*/
private BlockPos guessPosition() {
WorldData data = WorldProvider.INSTANCE.getCurrentWorld();
if (data != null && data.getCachedWorld() == this) {
return playerFeet();
}
CachedChunk mostRecentlyModified = null;
for (CachedRegion region : allRegions()) {
CachedChunk ch = region.mostRecentlyModified();
if (ch == null) {
continue;
}
if (mostRecentlyModified == null || mostRecentlyModified.cacheTimestamp < ch.cacheTimestamp) {
mostRecentlyModified = ch;
}
}
if (mostRecentlyModified == null) {
return new BlockPos(0, 0, 0);
}
return new BlockPos(mostRecentlyModified.x * 16 + 8, 0, mostRecentlyModified.z * 16 + 8);
}
private synchronized List<CachedRegion> allRegions() {

View File

@@ -35,7 +35,7 @@ public enum WorldScanner implements IWorldScanner, Helper {
INSTANCE;
@Override
public List<BlockPos> scanLoadedChunks(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) {
public List<BlockPos> scanChunkRadius(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius) {
if (blocks.contains(null)) {
throw new IllegalStateException("Invalid block name should have been caught earlier: " + blocks.toString());
}

View File

@@ -18,15 +18,16 @@
package baritone.pathing.calc;
import baritone.Baritone;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.pathing.calc.IPath;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.calc.openset.BinaryHeapOpenSet;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Moves;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.pathing.BetterWorldBorder;
import baritone.utils.pathing.MutableMoveResult;
import java.util.HashSet;
@@ -63,6 +64,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
CalculationContext calcContext = new CalculationContext();
MutableMoveResult res = new MutableMoveResult();
HashSet<Long> favored = favoredPositions.orElse(null);
BetterWorldBorder worldBorder = new BetterWorldBorder(world().getWorldBorder());
BlockStateInterface.clearCachedChunk();
long startTime = System.nanoTime() / 1000000L;
boolean slowPath = Baritone.settings().slowPath.get();
@@ -106,6 +108,12 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
continue;
}
}
if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) {
continue;
}
if (currentNode.y + moves.yOffset > 256 || currentNode.y + moves.yOffset < 0) {
continue;
}
res.reset();
moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z, res);
numMovementsConsidered++;
@@ -113,6 +121,12 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
if (actionCost >= ActionCosts.COST_INF) {
continue;
}
if (actionCost <= 0) {
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
}
if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218
continue;
}
// check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation
if (!moves.dynamicXZ && (res.x != newX || res.z != newZ)) {
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
@@ -120,9 +134,6 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) {
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
}
if (actionCost <= 0) {
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
}
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
if (favoring && favored.contains(hashCode)) {
// see issue #18

View File

@@ -18,9 +18,9 @@
package baritone.pathing.calc;
import baritone.Baritone;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.calc.IPath;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.Optional;

View File

@@ -17,9 +17,9 @@
package baritone.pathing.calc;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.calc.IPath;
import baritone.api.utils.BetterBlockPos;
import java.util.Collections;

View File

@@ -18,9 +18,9 @@
package baritone.pathing.calc;
import baritone.api.BaritoneAPI;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.calc.IPath;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves;

View File

@@ -21,6 +21,7 @@ import baritone.Baritone;
import baritone.api.pathing.movement.ActionCosts;
import baritone.utils.Helper;
import baritone.utils.ToolSet;
import baritone.utils.pathing.BetterWorldBorder;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Items;
@@ -44,6 +45,7 @@ public class CalculationContext implements Helper {
private final int maxFallHeightBucket;
private final double waterWalkSpeed;
private final double breakBlockAdditionalCost;
private final BetterWorldBorder worldBorder;
public CalculationContext() {
this(new ToolSet());
@@ -68,6 +70,32 @@ public class CalculationContext implements Helper {
// why cache these things here, why not let the movements just get directly from settings?
// because if some movements are calculated one way and others are calculated another way,
// then you get a wildly inconsistent path that isn't optimal for either scenario.
this.worldBorder = new BetterWorldBorder(world().getWorldBorder());
}
public boolean canPlaceThrowawayAt(int x, int y, int z) {
if (!hasThrowaway()) { // only true if allowPlace is true, see constructor
return false;
}
if (isPossiblyProtected(x, y, z)) {
return false;
}
return worldBorder.canPlaceAt(x, z); // TODO perhaps MovementHelper.canPlaceAgainst could also use this?
}
public boolean canBreakAt(int x, int y, int z) {
if (!allowBreak()) {
return false;
}
if (isPossiblyProtected(x, y, z)) {
return false;
}
return true;
}
public boolean isPossiblyProtected(int x, int y, int z) {
// TODO more protection logic here; see #220
return false;
}
public ToolSet getToolSet() {

View File

@@ -22,9 +22,13 @@ import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.VecUtils;
import baritone.behavior.LookBehavior;
import baritone.behavior.LookBehaviorUtils;
import baritone.utils.*;
import baritone.utils.BlockBreakHelper;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.InputOverrideHandler;
import net.minecraft.block.BlockLiquid;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
@@ -171,7 +175,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
for (BetterBlockPos blockPos : positionsToBreak) {
if (!MovementHelper.canWalkThrough(blockPos) && !(BlockStateInterface.getBlock(blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try
somethingInTheWay = true;
Optional<Rotation> reachable = LookBehaviorUtils.reachable(blockPos);
Optional<Rotation> reachable = RotationUtils.reachable(player(), blockPos);
if (reachable.isPresent()) {
MovementHelper.switchToBestToolFor(BlockStateInterface.get(blockPos));
state.setTarget(new MovementState.MovementTarget(reachable.get(), true)).setInput(Input.CLICK_LEFT, true);
@@ -181,8 +185,8 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
//i'm doing it anyway
//i dont care if theres snow in the way!!!!!!!
//you dont own me!!!!
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
Utils.getBlockPosCenter(blockPos)), true)
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(player().getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(blockPos)), true)
).setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
return false;
}

View File

@@ -19,28 +19,25 @@ package baritone.pathing.movement;
import baritone.Baritone;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehaviorUtils;
import baritone.api.utils.*;
import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.utils.*;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.InputOverrideHandler;
import baritone.utils.ToolSet;
import net.minecraft.block.*;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.Optional;
/**
* Static helpers for cost calculation
*
@@ -48,10 +45,6 @@ import java.util.Optional;
*/
public interface MovementHelper extends ActionCosts, Helper {
static boolean avoidBreaking(BetterBlockPos pos, IBlockState state) {
return avoidBreaking(pos.x, pos.y, pos.z, state);
}
static boolean avoidBreaking(int x, int y, int z, IBlockState state) {
Block b = state.getBlock();
return b == Blocks.ICE // ice becomes water, and water can mess up the path
@@ -74,10 +67,6 @@ public interface MovementHelper extends ActionCosts, Helper {
return canWalkThrough(pos.x, pos.y, pos.z, BlockStateInterface.get(pos));
}
static boolean canWalkThrough(BetterBlockPos pos, IBlockState state) {
return canWalkThrough(pos.x, pos.y, pos.z, state);
}
static boolean canWalkThrough(int x, int y, int z) {
return canWalkThrough(x, y, z, BlockStateInterface.get(x, y, z));
}
@@ -107,7 +96,9 @@ public interface MovementHelper extends ActionCosts, Helper {
return true;
}
if (snow) {
return state.getValue(BlockSnow.LAYERS) < 5; // see BlockSnow.isPassable
// the check in BlockSnow.isPassable is layers < 5
// while actually, we want < 3 because 3 or greater makes it impassable in a 2 high ceiling
return state.getValue(BlockSnow.LAYERS) < 3;
}
if (trapdoor) {
return !state.getValue(BlockTrapDoor.OPEN); // see BlockTrapDoor.isPassable
@@ -139,10 +130,6 @@ public interface MovementHelper extends ActionCosts, Helper {
*
* @return
*/
static boolean fullyPassable(BlockPos pos) {
return fullyPassable(BlockStateInterface.get(pos));
}
static boolean fullyPassable(int x, int y, int z) {
return fullyPassable(BlockStateInterface.get(x, y, z));
}
@@ -170,10 +157,6 @@ public interface MovementHelper extends ActionCosts, Helper {
return block.isPassable(null, null);
}
static boolean isReplacable(BlockPos pos, IBlockState state) {
return isReplacable(pos.getX(), pos.getY(), pos.getZ(), state);
}
static boolean isReplacable(int x, int y, int z, IBlockState state) {
// for MovementTraverse and MovementAscend
// block double plant defaults to true when the block doesn't match, so don't need to check that case
@@ -197,7 +180,7 @@ public interface MovementHelper extends ActionCosts, Helper {
BlockDoublePlant.EnumPlantType kek = state.getValue(BlockDoublePlant.VARIANT);
return kek == BlockDoublePlant.EnumPlantType.FERN || kek == BlockDoublePlant.EnumPlantType.GRASS;
}
return state.getBlock().isReplaceable(null, null);
return state.getMaterial().isReplaceable();
}
static boolean isDoorPassable(BlockPos doorPos, BlockPos playerPos) {
@@ -343,15 +326,6 @@ public interface MovementHelper extends ActionCosts, Helper {
return state.isBlockNormalCube();
}
static double getMiningDurationTicks(CalculationContext context, BetterBlockPos position, boolean includeFalling) {
IBlockState state = BlockStateInterface.get(position);
return getMiningDurationTicks(context, position.x, position.y, position.z, state, includeFalling);
}
static double getMiningDurationTicks(CalculationContext context, BetterBlockPos position, IBlockState state, boolean includeFalling) {
return getMiningDurationTicks(context, position.x, position.y, position.z, state, includeFalling);
}
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) {
return getMiningDurationTicks(context, x, y, z, BlockStateInterface.get(x, y, z), includeFalling);
}
@@ -359,7 +333,7 @@ public interface MovementHelper extends ActionCosts, Helper {
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state, boolean includeFalling) {
Block block = state.getBlock();
if (!canWalkThrough(x, y, z, state)) {
if (!context.allowBreak()) {
if (!context.canBreakAt(x, y, z)) {
return COST_INF;
}
if (avoidBreaking(x, y, z, state)) {
@@ -397,23 +371,11 @@ public interface MovementHelper extends ActionCosts, Helper {
return isBottomSlab(BlockStateInterface.get(pos));
}
/**
* The entity the player is currently looking at
*
* @return the entity object
*/
static Optional<Entity> whatEntityAmILookingAt() {
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(mc.objectMouseOver.entityHit);
}
return Optional.empty();
}
/**
* AutoTool
*/
static void switchToBestTool() {
LookBehaviorUtils.getSelectedBlock().ifPresent(pos -> {
RayTraceUtils.getSelectedBlock().ifPresent(pos -> {
IBlockState state = BlockStateInterface.get(pos);
if (state.getBlock().equals(Blocks.AIR)) {
return;
@@ -479,8 +441,8 @@ public interface MovementHelper extends ActionCosts, Helper {
static void moveTowards(MovementState state, BlockPos pos) {
state.setTarget(new MovementTarget(
new Rotation(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
Utils.getBlockPosCenter(pos),
new Rotation(RotationUtils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(pos),
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)).getYaw(), mc.player.rotationPitch),
false
)).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);

View File

@@ -84,9 +84,6 @@ public class MovementState {
/**
* Yaw and pitch angles that must be matched
* <p>
* getFirst() -> YAW
* getSecond() -> PITCH
*/
public Rotation rotation;

View File

@@ -148,7 +148,7 @@ public enum Moves {
}
},
DESCEND_EAST(+1, 0, 0, false, true) {
DESCEND_EAST(+1, -1, 0, false, true) {
@Override
public Movement apply0(BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult();
@@ -166,7 +166,7 @@ public enum Moves {
}
},
DESCEND_WEST(-1, 0, 0, false, true) {
DESCEND_WEST(-1, -1, 0, false, true) {
@Override
public Movement apply0(BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult();
@@ -184,7 +184,7 @@ public enum Moves {
}
},
DESCEND_NORTH(0, 0, -1, false, true) {
DESCEND_NORTH(0, -1, -1, false, true) {
@Override
public Movement apply0(BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult();
@@ -202,7 +202,7 @@ public enum Moves {
}
},
DESCEND_SOUTH(0, 0, +1, false, true) {
DESCEND_SOUTH(0, -1, +1, false, true) {
@Override
public Movement apply0(BetterBlockPos src) {
MutableMoveResult res = new MutableMoveResult();

View File

@@ -20,14 +20,14 @@ package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.behavior.LookBehaviorUtils;
import baritone.api.utils.RayTraceUtils;
import baritone.api.utils.RotationUtils;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.Utils;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@@ -72,7 +72,7 @@ public class MovementAscend extends Movement {
}
boolean hasToPlace = false;
if (!MovementHelper.canWalkOn(destX, y, destZ, toPlace)) {
if (!context.hasThrowaway()) {
if (!context.canPlaceThrowawayAt(destX, y, destZ)) {
return COST_INF;
}
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y, destZ, toPlace)) {
@@ -181,10 +181,10 @@ public class MovementAscend extends Movement {
double faceX = (dest.getX() + anAgainst.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + anAgainst.getY()) * 0.5D;
double faceZ = (dest.getZ() + anAgainst.getZ() + 1.0D) * 0.5D;
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
LookBehaviorUtils.getSelectedBlock().ifPresent(selectedBlock -> {
RayTraceUtils.getSelectedBlock().ifPresent(selectedBlock -> {
if (Objects.equals(selectedBlock, anAgainst) && selectedBlock.offset(side).equals(positionToPlace)) {
ticksWithoutPlacement++;
state.setInput(InputOverrideHandler.Input.SNEAK, true);
@@ -198,7 +198,7 @@ public class MovementAscend extends Movement {
} else {
state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true); // break whatever replaceable block is in the way
}
System.out.println("Trying to look at " + anAgainst + ", actually looking at" + selectedBlock);
//System.out.println("Trying to look at " + anAgainst + ", actually looking at" + selectedBlock);
});
return state;
}

View File

@@ -187,9 +187,9 @@ public class MovementDescend extends Movement {
if (BlockStateInterface.isLiquid(dest) || player().posY - playerFeet.getY() < 0.094) { // lilypads
// Wait until we're actually on the ground before saying we're done because sometimes we continue to fall if the next action starts immediately
return state.setStatus(MovementStatus.SUCCESS);
} else {
System.out.println(player().posY + " " + playerFeet.getY() + " " + (player().posY - playerFeet.getY()));
}
}/* else {
// System.out.println(player().posY + " " + playerFeet.getY() + " " + (player().posY - playerFeet.getY()));
}*/
}
double diffX = player().posX - (dest.getX() + 0.5);
double diffZ = player().posZ - (dest.getZ() + 0.5);

View File

@@ -19,8 +19,7 @@ package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.api.utils.*;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
@@ -28,8 +27,6 @@ import baritone.pathing.movement.MovementState;
import baritone.pathing.movement.MovementState.MovementTarget;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.RayTraceUtils;
import baritone.utils.Utils;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Items;
@@ -85,7 +82,7 @@ public class MovementFall extends Movement {
if (targetRotation != null) {
state.setTarget(new MovementTarget(targetRotation, true));
} else {
state.setTarget(new MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.getBlockPosCenter(dest)), false));
state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
}
if (playerFeet.equals(dest) && (player().posY - playerFeet.getY() < 0.094 || BlockStateInterface.isWater(dest))) { // 0.094 because lilypads
if (BlockStateInterface.isWater(dest)) {
@@ -105,7 +102,7 @@ public class MovementFall extends Movement {
return state.setStatus(MovementStatus.SUCCESS);
}
}
Vec3d destCenter = Utils.getBlockPosCenter(dest); // we are moving to the 0.5 center not the edge (like if we were falling on a ladder)
Vec3d destCenter = VecUtils.getBlockPosCenter(dest); // we are moving to the 0.5 center not the edge (like if we were falling on a ladder)
if (Math.abs(player().posX - destCenter.x) > 0.15 || Math.abs(player().posZ - destCenter.z) > 0.15) {
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
}

View File

@@ -20,13 +20,16 @@ package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.RayTraceUtils;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehaviorUtils;
import baritone.api.utils.RotationUtils;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.*;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.InputOverrideHandler;
import baritone.utils.pathing.MutableMoveResult;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
@@ -118,7 +121,7 @@ public class MovementParkour extends Movement {
int destX = x + 4 * xDiff;
int destZ = z + 4 * zDiff;
IBlockState toPlace = BlockStateInterface.get(destX, y - 1, destZ);
if (!context.hasThrowaway()) {
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
return;
}
if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) {
@@ -178,6 +181,10 @@ public class MovementParkour extends Movement {
if (state.getStatus() != MovementStatus.RUNNING) {
return state;
}
if (player().isHandActive()) {
logDebug("Pausing parkour since hand is active");
return state;
}
if (dist >= 4) {
state.setInput(InputOverrideHandler.Input.SPRINT, true);
}
@@ -209,12 +216,12 @@ public class MovementParkour extends Movement {
double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + against1.getY()) * 0.5D;
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
Rotation place = Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations());
Rotation place = RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations());
RayTraceResult res = RayTraceUtils.rayTraceTowards(place);
if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(dest.down())) {
state.setTarget(new MovementState.MovementTarget(place, true));
}
LookBehaviorUtils.getSelectedBlock().ifPresent(selectedBlock -> {
RayTraceUtils.getSelectedBlock().ifPresent(selectedBlock -> {
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
if (Objects.equals(selectedBlock, against1) && selectedBlock.offset(side).equals(dest.down())) {
state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
@@ -223,9 +230,17 @@ public class MovementParkour extends Movement {
}
}
}
if (dist == 3) { // this is a 2 block gap, dest = src + direction * 3
double xDiff = (src.x + 0.5) - player().posX;
double zDiff = (src.z + 0.5) - player().posZ;
double distFromStart = Math.max(Math.abs(xDiff), Math.abs(zDiff));
if (distFromStart < 0.7) {
return state;
}
}
state.setInput(InputOverrideHandler.Input.JUMP, true);
} else if(!playerFeet().equals(dest.offset(direction, -1))) {
} else if (!playerFeet().equals(dest.offset(direction, -1))) {
state.setInput(InputOverrideHandler.Input.SPRINT, false);
if (playerFeet().equals(src.offset(direction, -1))) {
MovementHelper.moveTowards(state, src);

View File

@@ -20,13 +20,14 @@ package baritone.pathing.movement.movements;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.api.utils.RotationUtils;
import baritone.api.utils.VecUtils;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.Utils;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@@ -76,7 +77,7 @@ public class MovementPillar extends Movement {
return LADDER_UP_ONE_COST;
}
}
if (!context.hasThrowaway() && !ladder) {
if (!ladder && !context.canPlaceThrowawayAt(x, y, z)) {
return COST_INF;
}
double hardness = MovementHelper.getMiningDurationTicks(context, x, y + 2, z, toBreak, true);
@@ -149,8 +150,8 @@ public class MovementPillar extends Movement {
IBlockState fromDown = BlockStateInterface.get(src);
if (BlockStateInterface.isWater(fromDown.getBlock()) && BlockStateInterface.isWater(dest)) {
// stay centered while swimming up a water column
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.getBlockPosCenter(dest)), false));
Vec3d destCenter = Utils.getBlockPosCenter(dest);
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.getBlockPosCenter(dest)), false));
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
if (Math.abs(player().posX - destCenter.x) > 0.2 || Math.abs(player().posZ - destCenter.z) > 0.2) {
state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
}
@@ -162,8 +163,8 @@ public class MovementPillar extends Movement {
boolean ladder = fromDown.getBlock() instanceof BlockLadder || fromDown.getBlock() instanceof BlockVine;
boolean vine = fromDown.getBlock() instanceof BlockVine;
if (!ladder) {
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
Utils.getBlockPosCenter(positionToPlace),
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(mc.player.getPositionEyes(1.0F),
VecUtils.getBlockPosCenter(positionToPlace),
new Rotation(mc.player.rotationYaw, mc.player.rotationPitch)), true));
}

View File

@@ -19,16 +19,13 @@ package baritone.pathing.movement.movements;
import baritone.Baritone;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Rotation;
import baritone.behavior.LookBehaviorUtils;
import baritone.api.utils.*;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.MovementState;
import baritone.utils.BlockStateInterface;
import baritone.utils.InputOverrideHandler;
import baritone.utils.Utils;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
@@ -108,7 +105,7 @@ public class MovementTraverse extends Movement {
if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) {
return COST_INF;
}
if (!context.hasThrowaway()) {
if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) {
return COST_INF;
}
double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb0, false);
@@ -169,7 +166,7 @@ public class MovementTraverse extends Movement {
// combine the yaw to the center of the destination, and the pitch to the specific block we're trying to break
// it's safe to do this since the two blocks we break (in a traverse) are right on top of each other and so will have the same yaw
float yawToDest = Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(dest, world())).getYaw();
float yawToDest = RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.calculateBlockCenter(dest)).getYaw();
float pitchToBreak = state.getTarget().getRotation().get().getPitch();
state.setTarget(new MovementState.MovementTarget(new Rotation(yawToDest, pitchToBreak), true));
@@ -194,7 +191,7 @@ public class MovementTraverse extends Movement {
}
if (isDoorActuallyBlockingUs) {
if (!(Blocks.IRON_DOOR.equals(pb0.getBlock()) || Blocks.IRON_DOOR.equals(pb1.getBlock()))) {
return state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(positionsToBreak[0], world())), true))
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.calculateBlockCenter(positionsToBreak[0])), true))
.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
}
@@ -209,7 +206,7 @@ public class MovementTraverse extends Movement {
}
if (blocked != null) {
return state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), Utils.calcCenterFromCoords(blocked, world())), true))
return state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), VecUtils.calculateBlockCenter(blocked)), true))
.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
}
@@ -267,16 +264,16 @@ public class MovementTraverse extends Movement {
double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D;
double faceY = (dest.getY() + against1.getY()) * 0.5D;
double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D;
state.setTarget(new MovementState.MovementTarget(Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations()), true));
EnumFacing side = Minecraft.getMinecraft().objectMouseOver.sideHit;
if (Objects.equals(LookBehaviorUtils.getSelectedBlock().orElse(null), against1) && (Minecraft.getMinecraft().player.isSneaking() || Baritone.settings().assumeSafeWalk.get())) {
if (LookBehaviorUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), against1) && (Minecraft.getMinecraft().player.isSneaking() || Baritone.settings().assumeSafeWalk.get())) {
if (RayTraceUtils.getSelectedBlock().get().offset(side).equals(positionToPlace)) {
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true);
}
// wrong side?
}
System.out.println("Trying to look at " + against1 + ", actually looking at" + LookBehaviorUtils.getSelectedBlock());
//System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock());
return state.setInput(InputOverrideHandler.Input.CLICK_LEFT, true);
}
}
@@ -296,18 +293,18 @@ public class MovementTraverse extends Movement {
// faceX, faceY, faceZ is the middle of the face between from and to
BlockPos goalLook = src.down(); // this is the block we were just standing on, and the one we want to place against
Rotation backToFace = Utils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations());
Rotation backToFace = RotationUtils.calcRotationFromVec3d(playerHead(), new Vec3d(faceX, faceY, faceZ), playerRotations());
float pitch = backToFace.getPitch();
double dist = Math.max(Math.abs(player().posX - faceX), Math.abs(player().posZ - faceZ));
if (dist < 0.29) {
float yaw = Utils.calcRotationFromVec3d(Utils.getBlockPosCenter(dest), playerHead(), playerRotations()).getYaw();
float yaw = RotationUtils.calcRotationFromVec3d(VecUtils.getBlockPosCenter(dest), playerHead(), playerRotations()).getYaw();
state.setTarget(new MovementState.MovementTarget(new Rotation(yaw, pitch), true));
state.setInput(InputOverrideHandler.Input.MOVE_BACK, true);
} else {
state.setTarget(new MovementState.MovementTarget(backToFace, true));
}
state.setInput(InputOverrideHandler.Input.SNEAK, true);
if (Objects.equals(LookBehaviorUtils.getSelectedBlock().orElse(null), goalLook)) {
if (Objects.equals(RayTraceUtils.getSelectedBlock().orElse(null), goalLook)) {
return state.setInput(InputOverrideHandler.Input.CLICK_RIGHT, true); // wait to right click until we are able to place
}
// Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt());

View File

@@ -25,11 +25,15 @@ import baritone.api.pathing.movement.IMovement;
import baritone.api.pathing.movement.MovementStatus;
import baritone.api.pathing.path.IPathExecutor;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.VecUtils;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.movements.*;
import baritone.utils.*;
import baritone.utils.BlockBreakHelper;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import baritone.utils.InputOverrideHandler;
import net.minecraft.init.Blocks;
import net.minecraft.util.Tuple;
import net.minecraft.util.math.BlockPos;
@@ -122,7 +126,7 @@ public class PathExecutor implements IPathExecutor, Helper {
if (i - pathPosition > 2) {
logDebug("Skipping forward " + (i - pathPosition) + " steps, to " + i);
}
System.out.println("Double skip sundae");
//System.out.println("Double skip sundae");
pathPosition = i - 1;
onChangeInPathPosition();
return false;
@@ -279,7 +283,7 @@ public class PathExecutor implements IPathExecutor, Helper {
double best = -1;
BlockPos bestPos = null;
for (BlockPos pos : path.positions()) {
double dist = Utils.playerDistanceToCenter(pos);
double dist = VecUtils.entityDistanceToCenter(player(), pos);
if (dist < best || best == -1) {
best = dist;
bestPos = pos;
@@ -327,7 +331,7 @@ public class PathExecutor implements IPathExecutor, Helper {
// when we're midair in the middle of a fall, we're very far from both the beginning and the end, but we aren't actually off path
if (path.movements().get(pathPosition) instanceof MovementFall) {
BlockPos fallDest = path.positions().get(pathPosition + 1); // .get(pathPosition) is the block we fell off of
if (Utils.playerFlatDistanceToCenter(fallDest) < leniency) { // ignore Y by using flat distance
if (VecUtils.entityFlatDistanceToCenter(player(), fallDest) < leniency) { // ignore Y by using flat distance
return false;
}
return true;

View File

@@ -38,7 +38,7 @@ public class BlockStateInterface implements Helper {
private static Chunk prev = null;
private static CachedRegion prevCached = null;
private static IBlockState AIR = Blocks.AIR.getDefaultState();
private static final IBlockState AIR = Blocks.AIR.getDefaultState();
public static IBlockState get(BlockPos pos) {
return get(pos.getX(), pos.getY(), pos.getZ());

View File

@@ -23,6 +23,7 @@ import baritone.api.cache.IWaypoint;
import baritone.api.event.events.ChatEvent;
import baritone.api.pathing.goals.*;
import baritone.api.pathing.movement.ActionCosts;
import baritone.api.utils.RayTraceUtils;
import baritone.api.utils.SettingsUtil;
import baritone.behavior.Behavior;
import baritone.behavior.FollowBehavior;
@@ -33,7 +34,6 @@ import baritone.cache.Waypoint;
import baritone.cache.WorldProvider;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.movement.Moves;
import net.minecraft.block.Block;
import net.minecraft.client.multiplayer.ChunkProviderClient;
@@ -255,7 +255,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
String name = msg.substring(6).trim();
Optional<Entity> toFollow = Optional.empty();
if (name.length() == 0) {
toFollow = MovementHelper.whatEntityAmILookingAt();
toFollow = RayTraceUtils.getSelectedEntity();
} else {
for (EntityPlayer pl : world().playerEntities) {
String theirName = pl.getName().trim().toLowerCase();

View File

@@ -86,8 +86,8 @@ public interface Helper {
*/
default void logDebug(String message) {
if (!Baritone.settings().chatDebug.get()) {
System.out.println("Suppressed debug message:");
System.out.println(message);
//System.out.println("Suppressed debug message:");
//System.out.println(message);
return;
}
logDirect(message);

View File

@@ -1,133 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils;
import baritone.api.utils.Rotation;
import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import static baritone.utils.Helper.HELPER;
/**
* @author Brady
* @since 8/1/2018 12:56 AM
*/
public final class Utils {
/**
* Constant that a degree value is multiplied by to get the equivalent radian value
*/
public static final double DEG_TO_RAD = Math.PI / 180.0;
/**
* Constant that a radian value is multiplied by to get the equivalent degree value
*/
public static final double RAD_TO_DEG = 180.0 / Math.PI;
public static Rotation calcRotationFromCoords(BlockPos orig, BlockPos dest) {
return calcRotationFromVec3d(vec3dFromBlockPos(orig), vec3dFromBlockPos(dest));
}
/**
* Calculates rotation to given Vec<sub>dest</sub> from Vec<sub>orig</sub>
*
* @param orig
* @param dest
* @return Rotation {@link Rotation}
*/
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest) {
double[] delta = {orig.x - dest.x, orig.y - dest.y, orig.z - dest.z};
double yaw = MathHelper.atan2(delta[0], -delta[2]);
double dist = Math.sqrt(delta[0] * delta[0] + delta[2] * delta[2]);
double pitch = MathHelper.atan2(delta[1], dist);
return new Rotation(
(float) radToDeg(yaw),
(float) radToDeg(pitch)
);
}
/**
* Calculates rotation to given Vec<sub>dest</sub> from Vec<sub>orig</sub>
*
* @param orig
* @param dest
* @return Rotation {@link Rotation}
*/
public static Rotation calcRotationFromVec3d(Vec3d orig, Vec3d dest, Rotation current) {
return wrapAnglesToRelative(current, calcRotationFromVec3d(orig, dest));
}
public static Vec3d calcCenterFromCoords(BlockPos orig, World world) {
IBlockState b = BlockStateInterface.get(orig);
AxisAlignedBB bbox = b.getBoundingBox(world, orig);
double xDiff = (bbox.minX + bbox.maxX) / 2;
double yDiff = (bbox.minY + bbox.maxY) / 2;
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
yDiff = 0;
}
return new Vec3d(
orig.getX() + xDiff,
orig.getY() + yDiff,
orig.getZ() + zDiff
);
}
public static Vec3d getBlockPosCenter(BlockPos pos) {
return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
}
public static Rotation wrapAnglesToRelative(Rotation current, Rotation target) {
return target.subtract(current).normalize().add(current);
}
public static Vec3d vec3dFromBlockPos(BlockPos orig) {
return new Vec3d(orig.getX() + 0.0D, orig.getY() + 0.0D, orig.getZ() + 0.0D);
}
public static double distanceToCenter(BlockPos pos, double x, double y, double z) {
double xdiff = x - (pos.getX() + 0.5D);
double ydiff = y - (pos.getY() + 0.5D);
double zdiff = z - (pos.getZ() + 0.5D);
return Math.sqrt(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
}
public static double playerDistanceToCenter(BlockPos pos) {
EntityPlayerSP player = HELPER.player();
return distanceToCenter(pos, player.posX, player.posY, player.posZ);
}
public static double playerFlatDistanceToCenter(BlockPos pos) {
EntityPlayerSP player = HELPER.player();
return distanceToCenter(pos, player.posX, pos.getY() + 0.5, player.posZ);
}
public static double degToRad(double deg) {
return deg * DEG_TO_RAD;
}
public static double radToDeg(double rad) {
return rad * RAD_TO_DEG;
}
}

View File

@@ -0,0 +1,46 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils.pathing;
import baritone.utils.Helper;
import net.minecraft.world.border.WorldBorder;
public class BetterWorldBorder implements Helper {
private final double minX;
private final double maxX;
private final double minZ;
private final double maxZ;
public BetterWorldBorder(WorldBorder border) {
this.minX = border.minX();
this.maxX = border.maxX();
this.minZ = border.minZ();
this.maxZ = border.maxZ();
}
public boolean entirelyContains(int x, int z) {
return x + 1 > minX && x < maxX && z + 1 > minZ && z < maxZ;
}
public boolean canPlaceAt(int x, int z) {
// move it in 1 block on all sides
// because we can't place a block at the very edge against a block outside the border
// it won't let us right click it
return x > minX && x + 1 < maxX && z > minZ && z + 1 < maxZ;
}
}