Compare commits
99 Commits
1.13.2
..
bot-system
| Author | SHA1 | Date | |
|---|---|---|---|
| 9a33c5cd9f | |||
| 9f5f275a17 | |||
| ac4895823e | |||
| 62cea04080 | |||
| d772a97a0b | |||
| 7af0ed6ea1 | |||
| fe3f3a66ce | |||
| 9c5f82c814 | |||
| 7c66762f48 | |||
| 830c8190de | |||
| 47b258d7a4 | |||
| df80858c49 | |||
| 5dec544802 | |||
| 494c056613 | |||
| c0e947f016 | |||
| c6ce5ea160 | |||
| 7b2930d5e5 | |||
| 44ca284717 | |||
| 380a645a6c | |||
| 0249bd5dd7 | |||
| 8cd8a95763 | |||
| 029a2b7f3e | |||
| 767d0c8ec1 | |||
| 8febed2e42 | |||
| 37b1604e5d | |||
| 82d15570f3 | |||
| 2c2c420b3a | |||
| 1422b0a149 | |||
| 6b6dd916b4 | |||
| 11e44acf65 | |||
| 16fec4a1a0 | |||
| bbded21afb | |||
| 5ae4f23886 | |||
| f222980a1a | |||
| c57f65f832 | |||
| 85a6ec022e | |||
| c1032da828 | |||
| e0d894d296 | |||
| 27c818f873 | |||
| fdd758bc90 | |||
| 3a2620192b | |||
| c423d5f575 | |||
| 81a9b71429 | |||
| 81ecc209d3 | |||
| 0dc67593bb | |||
| 2e180e81ed | |||
| 0b11057449 | |||
| 186652a8d8 | |||
| 168c151901 | |||
| 18d8cfb6de | |||
| f99befd307 | |||
| 9ad35dbf28 | |||
| dfb49179c5 | |||
| 3c913a7b85 | |||
| f01cf669e8 | |||
| 2d87033f49 | |||
| f014e42aa4 | |||
| 46de72e28c | |||
| 3d5cf9772e | |||
| 7cb38352ac | |||
| 42c78337c7 | |||
| 0f81212f17 | |||
| ad0041c2c5 | |||
| 19e7585cd2 | |||
| 3aeb29ab22 | |||
| 8dfe5dfd32 | |||
| 90236962c4 | |||
| 2e9e8c1ea1 | |||
| 4bf659e14e | |||
| ceca258867 | |||
| abda4b3a31 | |||
| 98664540e2 | |||
| 484dac66b7 | |||
| 40282cd140 | |||
| 41c74cb08c | |||
| 7c92817801 | |||
| 1d56585c67 | |||
| a4ac9c6f8d | |||
| 42d15a7b93 | |||
| 335c97bae6 | |||
| 8a8afddce3 | |||
| c3f6ee87b3 | |||
| f45fb3cd8c | |||
| 71c7ed54e5 | |||
| 4f978be2a2 | |||
| 133d956b3a | |||
| 095e452632 | |||
| 047d7f06b8 | |||
| 09a119c4ca | |||
| 746e1f6652 | |||
| 1d22cf63f0 | |||
| d4b3e71694 | |||
| a08b406af9 | |||
| 1afd367e53 | |||
| 59e920b7b1 | |||
| 79d230d924 | |||
| 29cf79fe17 | |||
| 8e75817e29 | |||
| c6bd3f4f00 |
@@ -11,8 +11,6 @@ build/
|
|||||||
classes/
|
classes/
|
||||||
*.class
|
*.class
|
||||||
|
|
||||||
/out
|
|
||||||
|
|
||||||
# IntelliJ Files
|
# IntelliJ Files
|
||||||
.idea/
|
.idea/
|
||||||
*.iml
|
*.iml
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ install:
|
|||||||
|
|
||||||
script:
|
script:
|
||||||
- docker run --rm cabaletta/baritone ./gradlew javadoc
|
- docker run --rm cabaletta/baritone ./gradlew javadoc
|
||||||
- docker run --name baritone cabaletta/baritone /bin/sh -c "/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 runAutoTest; cat /code/autotest/success"
|
- 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
|
- docker cp baritone:/code/dist dist
|
||||||
- ls dist
|
- ls dist
|
||||||
- cat dist/checksums.txt
|
- cat dist/checksums.txt
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
# Baritone Comms Protocol
|
||||||
|
|
||||||
|
## Data Types
|
||||||
|
|
||||||
|
| Name | Descriptor | Java |
|
||||||
|
|------------|-----------------------------------------------------------|-----------------------------|
|
||||||
|
| coordinate | Big endian 8-byte floating point number | [readDouble], [writeDouble] |
|
||||||
|
| string | unsigned short (length) followed by UTF-8 character bytes | [readUTF], [writeUTF] |
|
||||||
|
|
||||||
|
## Inbound
|
||||||
|
|
||||||
|
Allows the server to execute a chat command on behalf of the client's player
|
||||||
|
|
||||||
|
### Chat
|
||||||
|
|
||||||
|
| Name | Type |
|
||||||
|
|---------|--------|
|
||||||
|
| Message | string |
|
||||||
|
|
||||||
|
## Outbound
|
||||||
|
|
||||||
|
Update the player position with the server
|
||||||
|
|
||||||
|
### Status
|
||||||
|
|
||||||
|
| Name | Type |
|
||||||
|
|------|------------|
|
||||||
|
| X | coordinate |
|
||||||
|
| Y | coordinate |
|
||||||
|
| Z | coordinate |
|
||||||
|
|
||||||
|
<!-- External links -->
|
||||||
|
[readUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readUTF()
|
||||||
|
[writeUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeUTF(java.lang.String)
|
||||||
|
[readDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readDouble()
|
||||||
|
[writeDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeDouble(double)
|
||||||
+13
-68
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
group 'baritone'
|
group 'baritone'
|
||||||
version '1.3.6'
|
version '1.2.10'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
@@ -25,24 +25,24 @@ buildscript {
|
|||||||
url = 'http://files.minecraftforge.net/maven'
|
url = 'http://files.minecraftforge.net/maven'
|
||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
name = 'impactdevelopment-repo'
|
name = 'SpongePowered'
|
||||||
url = 'https://impactdevelopment.github.io/maven/'
|
url = 'http://repo.spongepowered.org/maven'
|
||||||
}
|
}
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath group: 'com.github.ImpactDevelopment', name: 'ForgeGradle', version: '3.0.115'
|
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||||
classpath group: 'com.github.ImpactDevelopment', name: 'MixinGradle', version: '0.6.2'
|
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
import baritone.gradle.task.CreateDistTask
|
import baritone.gradle.task.CreateDistTask
|
||||||
import baritone.gradle.task.ProguardTask
|
import baritone.gradle.task.ProguardTask
|
||||||
import org.apache.tools.ant.taskdefs.condition.Os
|
|
||||||
|
|
||||||
apply plugin: 'java'
|
apply plugin: 'java'
|
||||||
apply plugin: 'net.minecraftforge.gradle'
|
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
|
||||||
apply plugin: 'org.spongepowered.mixin'
|
apply plugin: 'org.spongepowered.mixin'
|
||||||
|
|
||||||
sourceCompatibility = targetCompatibility = '1.8'
|
sourceCompatibility = targetCompatibility = '1.8'
|
||||||
@@ -52,19 +52,8 @@ compileJava {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
api {
|
|
||||||
compileClasspath += main.compileClasspath
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
compileClasspath += api.output
|
|
||||||
}
|
|
||||||
test {
|
|
||||||
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
|
||||||
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
|
||||||
}
|
|
||||||
launch {
|
launch {
|
||||||
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
||||||
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
|
|
||||||
}
|
}
|
||||||
|
|
||||||
schematica_api {
|
schematica_api {
|
||||||
@@ -76,51 +65,14 @@ sourceSets {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task sourceJar(type: Jar, dependsOn: classes) {
|
|
||||||
classifier = 'sources'
|
|
||||||
from sourceSets.api.allSource
|
|
||||||
}
|
|
||||||
|
|
||||||
minecraft {
|
minecraft {
|
||||||
mappings channel: 'snapshot', version: '20190307-1.13.1'
|
version = '1.12.2'
|
||||||
reobfMappings 'notch'
|
mappings = 'stable_39'
|
||||||
|
tweakClass = 'baritone.launch.BaritoneTweaker'
|
||||||
|
runDir = 'run'
|
||||||
|
|
||||||
runs {
|
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
|
||||||
client {
|
makeObfSourceJar = true
|
||||||
workingDirectory project.file('run')
|
|
||||||
source sourceSets.launch
|
|
||||||
|
|
||||||
main 'baritone.launch.LaunchTesting'
|
|
||||||
|
|
||||||
environment 'assetIndex', '{asset_index}'
|
|
||||||
environment 'assetDirectory', downloadAssets.output
|
|
||||||
environment 'nativesDirectory', extractNatives.output
|
|
||||||
|
|
||||||
environment 'tweakClass', 'baritone.launch.BaritoneTweaker'
|
|
||||||
|
|
||||||
if (Os.isFamily(Os.FAMILY_MAC)) {
|
|
||||||
jvmArgs "-XstartOnFirstThread"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
autoTest {
|
|
||||||
workingDirectory project.file('autotest')
|
|
||||||
source sourceSets.launch
|
|
||||||
|
|
||||||
main 'baritone.launch.LaunchTesting'
|
|
||||||
|
|
||||||
environment 'assetIndex', '{asset_index}'
|
|
||||||
environment 'assetDirectory', downloadAssets.output
|
|
||||||
environment 'nativesDirectory', extractNatives.output
|
|
||||||
|
|
||||||
environment 'tweakClass', 'baritone.launch.BaritoneTweaker'
|
|
||||||
environment 'BARITONE_AUTO_TEST', 'true'
|
|
||||||
|
|
||||||
if (Os.isFamily(Os.FAMILY_MAC)) {
|
|
||||||
jvmArgs "-XstartOnFirstThread"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@@ -138,12 +90,6 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft 'com.github.ImpactDevelopment:Vanilla:1.13.2'
|
|
||||||
|
|
||||||
runtime launchCompile('net.minecraft:launchwrapper:1.12') {
|
|
||||||
exclude module: 'lwjgl'
|
|
||||||
}
|
|
||||||
runtime launchCompile('org.ow2.asm:asm-debug-all:5.2')
|
|
||||||
runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
|
runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
|
||||||
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
|
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
|
||||||
// Mixin includes a lot of dependencies that are too up-to-date
|
// Mixin includes a lot of dependencies that are too up-to-date
|
||||||
@@ -153,7 +99,6 @@ dependencies {
|
|||||||
exclude module: 'commons-io'
|
exclude module: 'commons-io'
|
||||||
exclude module: 'log4j-core'
|
exclude module: 'log4j-core'
|
||||||
}
|
}
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,13 +40,17 @@ class BaritoneGradleTask extends DefaultTask {
|
|||||||
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
|
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
|
||||||
PROGUARD_EXPORT_PATH = "proguard_out.jar",
|
PROGUARD_EXPORT_PATH = "proguard_out.jar",
|
||||||
|
|
||||||
|
TEMP_LIBRARY_DIR = "tempLibraries/",
|
||||||
|
|
||||||
ARTIFACT_STANDARD = "%s-%s.jar",
|
ARTIFACT_STANDARD = "%s-%s.jar",
|
||||||
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
|
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
|
||||||
ARTIFACT_API = "%s-api-%s.jar",
|
ARTIFACT_API = "%s-api-%s.jar",
|
||||||
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
|
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
|
||||||
|
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
|
||||||
|
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
|
||||||
|
|
||||||
protected String artifactName, artifactVersion;
|
protected String artifactName, artifactVersion;
|
||||||
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
|
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, artifactForgeApiPath, artifactForgeStandalonePath, proguardOut;
|
||||||
|
|
||||||
protected void verifyArtifacts() throws IllegalStateException {
|
protected void verifyArtifacts() throws IllegalStateException {
|
||||||
this.artifactName = getProject().getName();
|
this.artifactName = getProject().getName();
|
||||||
@@ -56,6 +60,8 @@ class BaritoneGradleTask extends DefaultTask {
|
|||||||
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
|
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
|
||||||
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
|
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
|
||||||
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
|
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
|
||||||
|
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
|
||||||
|
this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE));
|
||||||
|
|
||||||
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
|
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ public class CreateDistTask extends BaritoneGradleTask {
|
|||||||
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
|
Path api = getRelativeFile("dist/" + formatVersion(ARTIFACT_API));
|
||||||
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
|
Path standalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_STANDALONE));
|
||||||
Path unoptimized = getRelativeFile("dist/" + formatVersion(ARTIFACT_UNOPTIMIZED));
|
Path unoptimized = getRelativeFile("dist/" + formatVersion(ARTIFACT_UNOPTIMIZED));
|
||||||
|
Path forgeApi = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE_API));
|
||||||
|
Path forgeStandalone = getRelativeFile("dist/" + formatVersion(ARTIFACT_FORGE_STANDALONE));
|
||||||
|
|
||||||
// NIO will not automatically create directories
|
// NIO will not automatically create directories
|
||||||
Path dir = getRelativeFile("dist/");
|
Path dir = getRelativeFile("dist/");
|
||||||
@@ -56,9 +58,11 @@ public class CreateDistTask extends BaritoneGradleTask {
|
|||||||
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
|
Files.copy(this.artifactApiPath, api, REPLACE_EXISTING);
|
||||||
Files.copy(this.artifactStandalonePath, standalone, REPLACE_EXISTING);
|
Files.copy(this.artifactStandalonePath, standalone, REPLACE_EXISTING);
|
||||||
Files.copy(this.artifactUnoptimizedPath, unoptimized, REPLACE_EXISTING);
|
Files.copy(this.artifactUnoptimizedPath, unoptimized, REPLACE_EXISTING);
|
||||||
|
Files.copy(this.artifactForgeApiPath, forgeApi, REPLACE_EXISTING);
|
||||||
|
Files.copy(this.artifactForgeStandalonePath, forgeStandalone, REPLACE_EXISTING);
|
||||||
|
|
||||||
// Calculate all checksums and format them like "shasum"
|
// Calculate all checksums and format them like "shasum"
|
||||||
List<String> shasum = Stream.of(api, standalone, unoptimized)
|
List<String> shasum = Stream.of(api, forgeApi, standalone, forgeStandalone, unoptimized)
|
||||||
.map(path -> sha1(path) + " " + path.getFileName().toString())
|
.map(path -> sha1(path) + " " + path.getFileName().toString())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
|||||||
@@ -18,18 +18,27 @@
|
|||||||
package baritone.gradle.task;
|
package baritone.gradle.task;
|
||||||
|
|
||||||
import baritone.gradle.util.Determinizer;
|
import baritone.gradle.util.Determinizer;
|
||||||
|
import baritone.gradle.util.MappingType;
|
||||||
|
import baritone.gradle.util.ReobfWrapper;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.gradle.api.plugins.JavaPluginConvention;
|
import org.gradle.api.NamedDomainObjectContainer;
|
||||||
|
import org.gradle.api.artifacts.Configuration;
|
||||||
|
import org.gradle.api.artifacts.Dependency;
|
||||||
|
import org.gradle.api.internal.plugins.DefaultConvention;
|
||||||
import org.gradle.api.tasks.Input;
|
import org.gradle.api.tasks.Input;
|
||||||
import org.gradle.api.tasks.TaskAction;
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
import org.gradle.internal.Pair;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.stream.Stream;
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
|
|
||||||
@@ -41,12 +50,18 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
|||||||
*/
|
*/
|
||||||
public class ProguardTask extends BaritoneGradleTask {
|
public class ProguardTask extends BaritoneGradleTask {
|
||||||
|
|
||||||
|
private static final Pattern TEMP_LIBRARY_PATTERN = Pattern.compile("-libraryjars 'tempLibraries\\/([a-zA-Z0-9/_\\-\\.]+)\\.jar'");
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
private String extract;
|
private String extract;
|
||||||
|
|
||||||
|
private List<String> requiredLibraries;
|
||||||
|
|
||||||
|
private File mixin;
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
protected void exec() throws Exception {
|
protected void exec() throws Exception {
|
||||||
super.verifyArtifacts();
|
super.verifyArtifacts();
|
||||||
@@ -56,6 +71,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
downloadProguard();
|
downloadProguard();
|
||||||
extractProguard();
|
extractProguard();
|
||||||
generateConfigs();
|
generateConfigs();
|
||||||
|
acquireDependencies();
|
||||||
proguardApi();
|
proguardApi();
|
||||||
proguardStandalone();
|
proguardStandalone();
|
||||||
cleanup();
|
cleanup();
|
||||||
@@ -66,7 +82,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
Files.delete(this.artifactUnoptimizedPath);
|
Files.delete(this.artifactUnoptimizedPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString());
|
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void downloadProguard() throws Exception {
|
private void downloadProguard() throws Exception {
|
||||||
@@ -98,19 +114,7 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
Process p = new ProcessBuilder("java", "-verbose").start();
|
Process p = new ProcessBuilder("java", "-verbose").start();
|
||||||
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
|
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
|
||||||
template.add(2, "-libraryjars '" + out + "'");
|
template.add(2, "-libraryjars '" + out + "'");
|
||||||
|
template.add(3, "-libraryjars '" + Paths.get(out).resolveSibling("jce.jar") + "'");
|
||||||
// Discover all of the libraries that we will need to acquire from gradle
|
|
||||||
acquireDependencies().forEach(f -> {
|
|
||||||
if (f.toString().endsWith("-recomp.jar")) {
|
|
||||||
// remove MCP mapped jar
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (f.toString().endsWith("client-extra.jar")) {
|
|
||||||
// go from the extra to the original downloaded client
|
|
||||||
f = new File(f.getParentFile(), "client.jar");
|
|
||||||
}
|
|
||||||
template.add(2, "-libraryjars '" + f + "'");
|
|
||||||
});
|
|
||||||
|
|
||||||
// API config doesn't require any changes from the changes that we made to the template
|
// API config doesn't require any changes from the changes that we made to the template
|
||||||
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
|
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
|
||||||
@@ -119,20 +123,165 @@ public class ProguardTask extends BaritoneGradleTask {
|
|||||||
List<String> standalone = new ArrayList<>(template);
|
List<String> standalone = new ArrayList<>(template);
|
||||||
standalone.removeIf(s -> s.contains("# this is the keep api"));
|
standalone.removeIf(s -> s.contains("# this is the keep api"));
|
||||||
Files.write(getTemporaryFile(PROGUARD_STANDALONE_CONFIG), standalone);
|
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 Stream<File> acquireDependencies() {
|
private void acquireDependencies() throws Exception {
|
||||||
return getProject().getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().findByName("launch").getRuntimeClasspath().getFiles().stream().filter(File::isFile);
|
|
||||||
|
// Create a map of all of the dependencies that we are able to access in this project
|
||||||
|
// Likely a better way to do this, I just pair the dependency with the first valid configuration
|
||||||
|
Map<String, Pair<Configuration, Dependency>> dependencyLookupMap = new HashMap<>();
|
||||||
|
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config ->
|
||||||
|
config.getAllDependencies().forEach(dependency ->
|
||||||
|
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency))));
|
||||||
|
|
||||||
|
// Create the directory if it doesn't already exist
|
||||||
|
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
|
||||||
|
if (!Files.exists(tempLibraries)) {
|
||||||
|
Files.createDirectory(tempLibraries);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate the required libraries to copy them to tempLibraries
|
||||||
|
for (String lib : this.requiredLibraries) {
|
||||||
|
// copy from the forgegradle cache
|
||||||
|
if (lib.equals("minecraft")) {
|
||||||
|
Path cachedJar = getMinecraftJar();
|
||||||
|
Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar");
|
||||||
|
// TODO: maybe try not to copy every time
|
||||||
|
Files.copy(cachedJar, inTempDir, REPLACE_EXISTING);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a configuration/dependency pair that matches the desired library
|
||||||
|
Pair<Configuration, Dependency> pair = null;
|
||||||
|
for (Map.Entry<String, Pair<Configuration, Dependency>> entry : dependencyLookupMap.entrySet()) {
|
||||||
|
if (entry.getKey().startsWith(lib)) {
|
||||||
|
pair = entry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The pair must be non-null
|
||||||
|
Objects.requireNonNull(pair);
|
||||||
|
|
||||||
|
// Find the library jar file, and copy it to tempLibraries
|
||||||
|
for (File file : pair.getLeft().files(pair.getRight())) {
|
||||||
|
if (file.getName().startsWith(lib)) {
|
||||||
|
if (lib.contains("mixin")) {
|
||||||
|
mixin = file;
|
||||||
|
}
|
||||||
|
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mixin == null) {
|
||||||
|
throw new IllegalStateException("Unable to find mixin jar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// a bunch of epic stuff to get the path to the cached jar
|
||||||
|
private Path getMinecraftJar() throws Exception {
|
||||||
|
MappingType mappingType;
|
||||||
|
try {
|
||||||
|
mappingType = getMappingType();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("Failed to get mapping type, assuming NOTCH.");
|
||||||
|
mappingType = MappingType.NOTCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
String suffix;
|
||||||
|
switch (mappingType) {
|
||||||
|
case NOTCH:
|
||||||
|
suffix = "";
|
||||||
|
break;
|
||||||
|
case SEARGE:
|
||||||
|
suffix = "-srgBin";
|
||||||
|
break;
|
||||||
|
case CUSTOM:
|
||||||
|
throw new IllegalStateException("Custom mappings not supported!");
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unknown mapping type: " + mappingType);
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultConvention convention = (DefaultConvention) this.getProject().getConvention();
|
||||||
|
Object extension = convention.getAsMap().get("minecraft");
|
||||||
|
Objects.requireNonNull(extension);
|
||||||
|
|
||||||
|
// for some reason cant use Class.forName
|
||||||
|
Class<?> class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass(); // <-- cursed
|
||||||
|
Field f_replacer = class_baseExtension.getDeclaredField("replacer");
|
||||||
|
f_replacer.setAccessible(true);
|
||||||
|
Object replacer = f_replacer.get(extension);
|
||||||
|
Class<?> class_replacementProvider = replacer.getClass();
|
||||||
|
Field replacement_replaceMap = class_replacementProvider.getDeclaredField("replaceMap");
|
||||||
|
replacement_replaceMap.setAccessible(true);
|
||||||
|
|
||||||
|
Map<String, Object> replacements = (Map) replacement_replaceMap.get(replacer);
|
||||||
|
String cacheDir = replacements.get("CACHE_DIR").toString() + "/net/minecraft";
|
||||||
|
String mcVersion = replacements.get("MC_VERSION").toString();
|
||||||
|
String mcpInsert = replacements.get("MAPPING_CHANNEL").toString() + "/" + replacements.get("MAPPING_VERSION").toString();
|
||||||
|
String fullJarName = "minecraft-" + mcVersion + suffix + ".jar";
|
||||||
|
|
||||||
|
String baseDir = String.format("%s/minecraft/%s/", cacheDir, mcVersion);
|
||||||
|
|
||||||
|
String jarPath;
|
||||||
|
if (mappingType == MappingType.SEARGE) {
|
||||||
|
jarPath = String.format("%s/%s/%s", baseDir, mcpInsert, fullJarName);
|
||||||
|
} else {
|
||||||
|
jarPath = baseDir + fullJarName;
|
||||||
|
}
|
||||||
|
jarPath = jarPath
|
||||||
|
.replace("/", File.separator)
|
||||||
|
.replace("\\", File.separator); // hecking regex
|
||||||
|
|
||||||
|
return new File(jarPath).toPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
// throws IllegalStateException if mapping type is ambiguous or it fails to find it
|
||||||
|
private MappingType getMappingType() {
|
||||||
|
// if it fails to find this then its probably a forgegradle version problem
|
||||||
|
Set<Object> reobf = (NamedDomainObjectContainer<Object>) this.getProject().getExtensions().getByName("reobf");
|
||||||
|
|
||||||
|
List<MappingType> mappingTypes = getUsedMappingTypes(reobf);
|
||||||
|
long mappingTypesUsed = mappingTypes.size();
|
||||||
|
if (mappingTypesUsed == 0) {
|
||||||
|
throw new IllegalStateException("Failed to find mapping type (no jar task?)");
|
||||||
|
}
|
||||||
|
if (mappingTypesUsed > 1) {
|
||||||
|
throw new IllegalStateException("Ambiguous mapping type (multiple jars with different mapping types?)");
|
||||||
|
}
|
||||||
|
|
||||||
|
return mappingTypes.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MappingType> getUsedMappingTypes(Set<Object> reobf) {
|
||||||
|
return reobf.stream()
|
||||||
|
.map(ReobfWrapper::new)
|
||||||
|
.map(ReobfWrapper::getMappingType)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void proguardApi() throws Exception {
|
private void proguardApi() throws Exception {
|
||||||
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
|
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
|
||||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString());
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
|
||||||
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void proguardStandalone() throws Exception {
|
private void proguardStandalone() throws Exception {
|
||||||
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
|
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
|
||||||
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString());
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
|
||||||
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanup() {
|
private void cleanup() {
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ import com.google.gson.stream.JsonReader;
|
|||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.jar.JarOutputStream;
|
import java.util.jar.JarOutputStream;
|
||||||
@@ -39,7 +36,7 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
public class Determinizer {
|
public class Determinizer {
|
||||||
|
|
||||||
public static void determinize(String inputPath, String outputPath) throws IOException {
|
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
|
||||||
System.out.println("Running Determinizer");
|
System.out.println("Running Determinizer");
|
||||||
System.out.println(" Input path: " + inputPath);
|
System.out.println(" Input path: " + inputPath);
|
||||||
System.out.println(" Output path: " + outputPath);
|
System.out.println(" Output path: " + outputPath);
|
||||||
@@ -66,10 +63,30 @@ public class Determinizer {
|
|||||||
if (entry.getName().endsWith(".refmap.json")) {
|
if (entry.getName().endsWith(".refmap.json")) {
|
||||||
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
|
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
|
||||||
jos.write(writeSorted(object).getBytes());
|
jos.write(writeSorted(object).getBytes());
|
||||||
|
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && toInclude.isPresent()) { // only replace for forge jar
|
||||||
|
ByteArrayOutputStream cancer = new ByteArrayOutputStream();
|
||||||
|
copy(jarFile.getInputStream(entry), cancer);
|
||||||
|
String manifest = new String(cancer.toByteArray());
|
||||||
|
if (!manifest.contains("baritone.launch.BaritoneTweaker")) {
|
||||||
|
throw new IllegalStateException("unable to replace");
|
||||||
|
}
|
||||||
|
manifest = manifest.replace("baritone.launch.BaritoneTweaker", "org.spongepowered.asm.launch.MixinTweaker");
|
||||||
|
jos.write(manifest.getBytes());
|
||||||
} else {
|
} else {
|
||||||
copy(jarFile.getInputStream(entry), jos);
|
copy(jarFile.getInputStream(entry), jos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (toInclude.isPresent()) {
|
||||||
|
try (JarFile mixin = new JarFile(toInclude.get())) {
|
||||||
|
for (JarEntry entry : mixin.stream().sorted(Comparator.comparing(JarEntry::getName)).collect(Collectors.toList())) {
|
||||||
|
if (entry.getName().startsWith("META-INF") && !entry.getName().startsWith("META-INF/services")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
jos.putNextEntry(entry);
|
||||||
|
copy(mixin.getInputStream(entry), jos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
jos.finish();
|
jos.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.gradle.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All credits go to AsmLibGradle and its contributors.
|
||||||
|
*
|
||||||
|
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/MappingType.java">Original Source</a>
|
||||||
|
*/
|
||||||
|
public enum MappingType {
|
||||||
|
SEARGE,
|
||||||
|
NOTCH,
|
||||||
|
CUSTOM // forgegradle
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.gradle.util;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All credits go to AsmLibGradle and its contributors.
|
||||||
|
*
|
||||||
|
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/ReobfWrapper.java">Original Source</a>
|
||||||
|
*/
|
||||||
|
public class ReobfWrapper {
|
||||||
|
|
||||||
|
private final Object instance;
|
||||||
|
private final Class<?> type;
|
||||||
|
|
||||||
|
public ReobfWrapper(Object instance) {
|
||||||
|
this.instance = instance;
|
||||||
|
Objects.requireNonNull(instance);
|
||||||
|
this.type = instance.getClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
try {
|
||||||
|
Field nameField = type.getDeclaredField("name");
|
||||||
|
nameField.setAccessible(true);
|
||||||
|
return (String) nameField.get(this.instance);
|
||||||
|
} catch (ReflectiveOperationException ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MappingType getMappingType() {
|
||||||
|
try {
|
||||||
|
Field enumField = type.getDeclaredField("mappingType");
|
||||||
|
enumField.setAccessible(true);
|
||||||
|
Enum<?> aEnum = (Enum<?>) enumField.get(this.instance);
|
||||||
|
MappingType mappingType = MappingType.values()[aEnum.ordinal()];
|
||||||
|
if (!aEnum.name().equals(mappingType.name())) {
|
||||||
|
throw new IllegalStateException("ForgeGradle ReobfMappingType is not equivalent to MappingType (version error?)");
|
||||||
|
}
|
||||||
|
return mappingType;
|
||||||
|
} catch (ReflectiveOperationException ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+49
-2
@@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
# lwjgl is weird
|
# lwjgl is weird
|
||||||
-dontwarn org.lwjgl.**
|
-dontwarn org.lwjgl.**
|
||||||
# also lwjgl lol
|
|
||||||
-dontwarn module-info
|
|
||||||
|
|
||||||
-keep class baritone.api.** { *; } # this is the keep api
|
-keep class baritone.api.** { *; } # this is the keep api
|
||||||
|
|
||||||
@@ -38,6 +36,55 @@
|
|||||||
#proguard doesnt like it when it cant find our fake schematica classes
|
#proguard doesnt like it when it cant find our fake schematica classes
|
||||||
-dontwarn baritone.utils.schematic.schematica.**
|
-dontwarn baritone.utils.schematic.schematica.**
|
||||||
|
|
||||||
|
# copy all necessary libraries into tempLibraries to build
|
||||||
|
|
||||||
|
# The correct jar will be copied from the forgegradle cache based on the mapping type being compiled with
|
||||||
|
-libraryjars 'tempLibraries/minecraft.jar'
|
||||||
|
|
||||||
|
-libraryjars 'tempLibraries/SimpleTweaker-1.2.jar'
|
||||||
|
|
||||||
|
-libraryjars 'tempLibraries/authlib-1.5.25.jar'
|
||||||
|
-libraryjars 'tempLibraries/codecjorbis-20101023.jar'
|
||||||
|
-libraryjars 'tempLibraries/codecwav-20101023.jar'
|
||||||
|
-libraryjars 'tempLibraries/commons-codec-1.10.jar'
|
||||||
|
-libraryjars 'tempLibraries/commons-compress-1.8.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/commons-io-2.5.jar'
|
||||||
|
-libraryjars 'tempLibraries/commons-lang3-3.5.jar'
|
||||||
|
-libraryjars 'tempLibraries/commons-logging-1.1.3.jar'
|
||||||
|
-libraryjars 'tempLibraries/fastutil-7.1.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/gson-2.8.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/guava-21.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/httpclient-4.3.3.jar'
|
||||||
|
-libraryjars 'tempLibraries/httpcore-4.3.2.jar'
|
||||||
|
-libraryjars 'tempLibraries/icu4j-core-mojang-51.2.jar'
|
||||||
|
-libraryjars 'tempLibraries/jinput-2.0.5.jar'
|
||||||
|
-libraryjars 'tempLibraries/jna-4.4.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/jopt-simple-5.0.3.jar'
|
||||||
|
-libraryjars 'tempLibraries/jsr305-3.0.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/jutils-1.0.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/libraryjavasound-20101123.jar'
|
||||||
|
-libraryjars 'tempLibraries/librarylwjglopenal-20100824.jar'
|
||||||
|
-libraryjars 'tempLibraries/log4j-api-2.8.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/log4j-core-2.8.1.jar'
|
||||||
|
|
||||||
|
# startsWith is used to check the library, and mac/linux differ in which version they use
|
||||||
|
# this is FINE
|
||||||
|
-libraryjars 'tempLibraries/lwjgl-.jar'
|
||||||
|
-libraryjars 'tempLibraries/lwjgl_util-.jar'
|
||||||
|
|
||||||
|
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
|
||||||
|
-libraryjars 'tempLibraries/oshi-core-1.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/patchy-1.1.jar'
|
||||||
|
-libraryjars 'tempLibraries/platform-3.4.0.jar'
|
||||||
|
-libraryjars 'tempLibraries/realms-1.10.22.jar'
|
||||||
|
-libraryjars 'tempLibraries/soundsystem-20120107.jar'
|
||||||
|
-libraryjars 'tempLibraries/text2speech-1.10.3.jar'
|
||||||
|
|
||||||
|
-libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar'
|
||||||
|
-libraryjars 'tempLibraries/launchwrapper-1.11.jar' # TODO why does only 1.11.jar exist?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Keep - Applications. Keep all application classes, along with their 'main'
|
# Keep - Applications. Keep all application classes, along with their 'main'
|
||||||
# methods.
|
# methods.
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package baritone.api;
|
package baritone.api;
|
||||||
|
|
||||||
|
import baritone.api.bot.IUserManager;
|
||||||
import baritone.api.cache.IWorldScanner;
|
import baritone.api.cache.IWorldScanner;
|
||||||
import baritone.api.command.ICommand;
|
import baritone.api.command.ICommand;
|
||||||
import baritone.api.command.ICommandSystem;
|
import baritone.api.command.ICommandSystem;
|
||||||
@@ -69,13 +70,18 @@ public interface IBaritoneProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link IWorldScanner} instance. This is not a type returned by
|
* Returns the {@link IWorldScanner} instance. This is not a type returned by a
|
||||||
* {@link IBaritone} implementation, because it is not linked with {@link IBaritone}.
|
* {@link IBaritone} implementation because it is not linked with {@link IBaritone}.
|
||||||
*
|
*
|
||||||
* @return The {@link IWorldScanner} instance.
|
* @return The {@link IWorldScanner} instance.
|
||||||
*/
|
*/
|
||||||
IWorldScanner getWorldScanner();
|
IWorldScanner getWorldScanner();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link IUserManager} instance.
|
||||||
|
*/
|
||||||
|
IUserManager getUserManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link ICommandSystem} instance. This is not bound to a specific {@link IBaritone}
|
* Returns the {@link ICommandSystem} instance. This is not bound to a specific {@link IBaritone}
|
||||||
* instance because {@link ICommandSystem} itself controls global behavior for {@link ICommand}s.
|
* instance because {@link ICommandSystem} itself controls global behavior for {@link ICommand}s.
|
||||||
|
|||||||
@@ -158,10 +158,10 @@ public final class Settings {
|
|||||||
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
* Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
|
||||||
*/
|
*/
|
||||||
public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
|
public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
|
||||||
Blocks.DIRT.asItem(),
|
Item.getItemFromBlock(Blocks.DIRT),
|
||||||
Blocks.COBBLESTONE.asItem(),
|
Item.getItemFromBlock(Blocks.COBBLESTONE),
|
||||||
Blocks.NETHERRACK.asItem(),
|
Item.getItemFromBlock(Blocks.NETHERRACK),
|
||||||
Blocks.STONE.asItem()
|
Item.getItemFromBlock(Blocks.STONE)
|
||||||
)));
|
)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,9 +177,10 @@ public final class Settings {
|
|||||||
public final Setting<List<Block>> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet?
|
public final Setting<List<Block>> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet?
|
||||||
Blocks.CRAFTING_TABLE,
|
Blocks.CRAFTING_TABLE,
|
||||||
Blocks.FURNACE,
|
Blocks.FURNACE,
|
||||||
|
Blocks.LIT_FURNACE,
|
||||||
Blocks.CHEST,
|
Blocks.CHEST,
|
||||||
Blocks.TRAPPED_CHEST,
|
Blocks.TRAPPED_CHEST,
|
||||||
Blocks.SIGN,
|
Blocks.STANDING_SIGN,
|
||||||
Blocks.WALL_SIGN
|
Blocks.WALL_SIGN
|
||||||
)));
|
)));
|
||||||
|
|
||||||
@@ -261,11 +262,6 @@ public final class Settings {
|
|||||||
*/
|
*/
|
||||||
public final Setting<Integer> rightClickSpeed = new Setting<>(4);
|
public final Setting<Integer> rightClickSpeed = new Setting<>(4);
|
||||||
|
|
||||||
/**
|
|
||||||
* How many degrees to randomize the yaw every tick. Set to 0 to disable
|
|
||||||
*/
|
|
||||||
public final Setting<Double> randomLooking113 = new Setting<>(2d);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Block reach distance
|
* Block reach distance
|
||||||
*/
|
*/
|
||||||
@@ -958,7 +954,7 @@ public final class Settings {
|
|||||||
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
|
||||||
* {@link Setting#value};
|
* {@link Setting#value};
|
||||||
*/
|
*/
|
||||||
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getInstance().ingameGUI.getChatGUI()::printChatMessage);
|
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The size of the box that is rendered when the current goal is a GoalYLevel
|
* The size of the box that is rendered when the current goal is a GoalYLevel
|
||||||
|
|||||||
@@ -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.api.bot;
|
||||||
|
|
||||||
|
import baritone.api.IBaritone;
|
||||||
|
import baritone.api.utils.IPlayerController;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.network.INetHandler;
|
||||||
|
import net.minecraft.network.NetworkManager;
|
||||||
|
import net.minecraft.network.play.INetHandlerPlayClient;
|
||||||
|
import net.minecraft.util.Session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 10/23/2018
|
||||||
|
*/
|
||||||
|
public interface IBaritoneUser {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The network manager that is responsible for the current connection.
|
||||||
|
*/
|
||||||
|
NetworkManager getNetworkManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current play network handler. Can also be acquired via
|
||||||
|
* {@link NetworkManager#getNetHandler()} from {@link #getNetworkManager()},
|
||||||
|
* and checking if the {@link INetHandler} is an instance of {@link INetHandlerPlayClient}.
|
||||||
|
*
|
||||||
|
* @return The current play network handler
|
||||||
|
*/
|
||||||
|
INetHandlerPlayClient getConnection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The locally managed entity for this user.
|
||||||
|
*/
|
||||||
|
EntityPlayerSP getEntity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The bot player controller
|
||||||
|
*/
|
||||||
|
IPlayerController getPlayerController();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user login session. Should never be {@code null}, as this should be set when the
|
||||||
|
* user is constructed.
|
||||||
|
*
|
||||||
|
* @return This users's login session
|
||||||
|
*/
|
||||||
|
Session getSession();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the game profile for the account represented by this user.
|
||||||
|
*
|
||||||
|
* @return This users's profile.
|
||||||
|
*/
|
||||||
|
GameProfile getProfile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The manager that spawned this {@link IBaritoneUser}.
|
||||||
|
*/
|
||||||
|
IUserManager getManager();
|
||||||
|
|
||||||
|
IBaritone getBaritone();
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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.bot;
|
||||||
|
|
||||||
|
import baritone.api.bot.connect.IConnectionResult;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import net.minecraft.util.Session;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 1/17/2019
|
||||||
|
*/
|
||||||
|
public interface IUserManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects a new user with the specified {@link Session} to the current server.
|
||||||
|
*
|
||||||
|
* @param session The user session
|
||||||
|
* @return The result of the attempted connection
|
||||||
|
*/
|
||||||
|
IConnectionResult connect(Session session);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects the specified {@link IBaritoneUser} from its current server.
|
||||||
|
*
|
||||||
|
* @param user The user to disconnect
|
||||||
|
*/
|
||||||
|
void disconnect(IBaritoneUser user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the {@link IBaritoneUser} associated with the specified {@link GameProfile}
|
||||||
|
*
|
||||||
|
* @param profile The game profile of the user
|
||||||
|
* @return The user, {@link Optional#empty()} if no match or {@code profile} is {@code null}
|
||||||
|
*/
|
||||||
|
default Optional<IBaritoneUser> getUserByProfile(GameProfile profile) {
|
||||||
|
return profile == null ? Optional.empty() : users().stream().filter(user -> user.getProfile().equals(profile)).findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the {@link IBaritoneUser} associated with the specified {@link UUID}
|
||||||
|
*
|
||||||
|
* @param uuid The uuid of the user
|
||||||
|
* @return The user, {@link Optional#empty()} if no match or {@code uuid} is {@code null}
|
||||||
|
*/
|
||||||
|
default Optional<IBaritoneUser> getUserByUUID(UUID uuid) {
|
||||||
|
return uuid == null ? Optional.empty() : users().stream().filter(user -> user.getProfile().getId().equals(uuid)).findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return All of the users held by this manager
|
||||||
|
*/
|
||||||
|
List<IBaritoneUser> users();
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.bot.connect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/6/2018
|
||||||
|
*/
|
||||||
|
public enum ConnectionStatus {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The local player is not connected to a server, therefore, there is no target server to connect to.
|
||||||
|
*/
|
||||||
|
NO_CURRENT_CONNECTION,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The IP of the targetted address to connect to could not be resolved.
|
||||||
|
*/
|
||||||
|
CANT_RESOLVE_HOST,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection initialization failed.
|
||||||
|
*/
|
||||||
|
CONNECTION_FAILED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The connection was a success
|
||||||
|
*/
|
||||||
|
SUCCESS
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.api.bot.connect;
|
||||||
|
|
||||||
|
import baritone.api.bot.IBaritoneUser;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 1/17/2019
|
||||||
|
*/
|
||||||
|
public interface IConnectionResult {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The actual status of the connection attempt.
|
||||||
|
* @see ConnectionStatus
|
||||||
|
*/
|
||||||
|
ConnectionStatus getStatus();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user that was created in this connection this result reflects, if
|
||||||
|
* {@link #getStatus()} is {@link ConnectionStatus#SUCCESS}, otherwise it will
|
||||||
|
* return {@link Optional#empty()}.
|
||||||
|
*
|
||||||
|
* @return The user created in the connection
|
||||||
|
*/
|
||||||
|
Optional<IBaritoneUser> getUser();
|
||||||
|
}
|
||||||
@@ -22,7 +22,6 @@ import baritone.api.command.exception.CommandException;
|
|||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.registry.IRegistry;
|
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@@ -33,7 +32,7 @@ public enum BlockById implements IDatatypeFor<Block> {
|
|||||||
public Block get(IDatatypeContext ctx) throws CommandException {
|
public Block get(IDatatypeContext ctx) throws CommandException {
|
||||||
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
|
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
|
||||||
Block block;
|
Block block;
|
||||||
if ((block = IRegistry.BLOCK.get(id)) == Blocks.AIR) {
|
if ((block = Block.REGISTRY.getObject(id)) == Blocks.AIR) {
|
||||||
throw new IllegalArgumentException("no block found by that id");
|
throw new IllegalArgumentException("no block found by that id");
|
||||||
}
|
}
|
||||||
return block;
|
return block;
|
||||||
@@ -43,7 +42,7 @@ public enum BlockById implements IDatatypeFor<Block> {
|
|||||||
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
||||||
return new TabCompleteHelper()
|
return new TabCompleteHelper()
|
||||||
.append(
|
.append(
|
||||||
IRegistry.BLOCK.keySet()
|
Block.REGISTRY.getKeys()
|
||||||
.stream()
|
.stream()
|
||||||
.map(Object::toString)
|
.map(Object::toString)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -17,22 +17,22 @@
|
|||||||
|
|
||||||
package baritone.api.command.datatypes;
|
package baritone.api.command.datatypes;
|
||||||
|
|
||||||
import baritone.api.command.exception.CommandException;
|
|
||||||
import baritone.api.command.helpers.TabCompleteHelper;
|
import baritone.api.command.helpers.TabCompleteHelper;
|
||||||
import net.minecraft.entity.EntityType;
|
import baritone.api.command.exception.CommandException;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityList;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.registry.IRegistry;
|
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public enum EntityClassById implements IDatatypeFor<EntityType> {
|
public enum EntityClassById implements IDatatypeFor<Class<? extends Entity>> {
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityType get(IDatatypeContext ctx) throws CommandException {
|
public Class<? extends Entity> get(IDatatypeContext ctx) throws CommandException {
|
||||||
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
|
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
|
||||||
EntityType entity;
|
Class<? extends Entity> entity;
|
||||||
if ((entity = IRegistry.ENTITY_TYPE.get(id)) == null) {
|
if ((entity = EntityList.REGISTRY.getObject(id)) == null) {
|
||||||
throw new IllegalArgumentException("no entity found by that id");
|
throw new IllegalArgumentException("no entity found by that id");
|
||||||
}
|
}
|
||||||
return entity;
|
return entity;
|
||||||
@@ -41,7 +41,7 @@ public enum EntityClassById implements IDatatypeFor<EntityType> {
|
|||||||
@Override
|
@Override
|
||||||
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
||||||
return new TabCompleteHelper()
|
return new TabCompleteHelper()
|
||||||
.append(IRegistry.ENTITY_TYPE.stream().map(Object::toString))
|
.append(EntityList.getEntityNameList().stream().map(Object::toString))
|
||||||
.filterPrefixNamespaced(ctx.getConsumer().getString())
|
.filterPrefixNamespaced(ctx.getConsumer().getString())
|
||||||
.sortAlphabetically()
|
.sortAlphabetically()
|
||||||
.stream();
|
.stream();
|
||||||
|
|||||||
@@ -18,10 +18,9 @@
|
|||||||
package baritone.api.command.datatypes;
|
package baritone.api.command.datatypes;
|
||||||
|
|
||||||
import baritone.api.IBaritone;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.command.exception.CommandException;
|
|
||||||
import baritone.api.command.helpers.TabCompleteHelper;
|
import baritone.api.command.helpers.TabCompleteHelper;
|
||||||
|
import baritone.api.command.exception.CommandException;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -37,14 +36,14 @@ public enum NearbyPlayer implements IDatatypeFor<EntityPlayer> {
|
|||||||
public EntityPlayer get(IDatatypeContext ctx) throws CommandException {
|
public EntityPlayer get(IDatatypeContext ctx) throws CommandException {
|
||||||
final String username = ctx.getConsumer().getString();
|
final String username = ctx.getConsumer().getString();
|
||||||
return getPlayers(ctx).stream()
|
return getPlayers(ctx).stream()
|
||||||
.filter(s -> s.getName().getString().equalsIgnoreCase(username))
|
.filter(s -> s.getName().equalsIgnoreCase(username))
|
||||||
.findFirst().orElse(null);
|
.findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
|
||||||
return new TabCompleteHelper()
|
return new TabCompleteHelper()
|
||||||
.append(getPlayers(ctx).stream().map(EntityPlayer::getName).map(ITextComponent::getString))
|
.append(getPlayers(ctx).stream().map(EntityPlayer::getName))
|
||||||
.filterPrefix(ctx.getConsumer().getString())
|
.filterPrefix(ctx.getConsumer().getString())
|
||||||
.sortAlphabetically()
|
.sortAlphabetically()
|
||||||
.stream();
|
.stream();
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public enum RelativeGoalXZ implements IDatatypePost<GoalXZ, BetterBlockPos> {
|
|||||||
final IArgConsumer consumer = ctx.getConsumer();
|
final IArgConsumer consumer = ctx.getConsumer();
|
||||||
return new GoalXZ(
|
return new GoalXZ(
|
||||||
MathHelper.floor(consumer.getDatatypePost(RelativeCoordinate.INSTANCE, (double) origin.x)),
|
MathHelper.floor(consumer.getDatatypePost(RelativeCoordinate.INSTANCE, (double) origin.x)),
|
||||||
MathHelper.floor(consumer.getDatatypePost(RelativeCoordinate.INSTANCE, (double) origin.z))
|
MathHelper.floor(consumer.getDatatypePost(RelativeCoordinate.INSTANCE, (double) origin.y))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import baritone.api.event.events.type.Overrideable;
|
|||||||
/**
|
/**
|
||||||
* @author LoganDark
|
* @author LoganDark
|
||||||
*/
|
*/
|
||||||
public final class TabCompleteEvent extends Cancellable {
|
public class TabCompleteEvent extends Cancellable {
|
||||||
|
|
||||||
public final String prefix;
|
public final String prefix;
|
||||||
public String[] completions;
|
public String[] completions;
|
||||||
|
|||||||
@@ -18,11 +18,12 @@
|
|||||||
package baritone.api.event.listener;
|
package baritone.api.event.listener;
|
||||||
|
|
||||||
import baritone.api.event.events.*;
|
import baritone.api.event.events.*;
|
||||||
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.client.gui.GuiGameOver;
|
import net.minecraft.client.gui.GuiGameOver;
|
||||||
import net.minecraft.client.gui.GuiScreen;
|
|
||||||
import net.minecraft.client.multiplayer.WorldClient;
|
import net.minecraft.client.multiplayer.WorldClient;
|
||||||
|
import net.minecraft.client.settings.GameSettings;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ public interface IGameEventListener {
|
|||||||
* Run once per game tick from before and after the player rotation is sent to the server.
|
* Run once per game tick from before and after the player rotation is sent to the server.
|
||||||
*
|
*
|
||||||
* @param event The event
|
* @param event The event
|
||||||
* @see EntityPlayerSP#tick()
|
* @see EntityPlayerSP#onUpdate()
|
||||||
*/
|
*/
|
||||||
void onPlayerUpdate(PlayerUpdateEvent event);
|
void onPlayerUpdate(PlayerUpdateEvent event);
|
||||||
|
|
||||||
@@ -67,11 +68,14 @@ public interface IGameEventListener {
|
|||||||
* Runs before and after whenever a chunk is either loaded, unloaded, or populated.
|
* Runs before and after whenever a chunk is either loaded, unloaded, or populated.
|
||||||
*
|
*
|
||||||
* @param event The event
|
* @param event The event
|
||||||
|
* @see WorldClient#doPreChunk(int, int, boolean)
|
||||||
*/
|
*/
|
||||||
void onChunkEvent(ChunkEvent event);
|
void onChunkEvent(ChunkEvent event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs once per world render pass.
|
* Runs once per world render pass. Two passes are made when {@link GameSettings#anaglyph} is on.
|
||||||
|
* <p>
|
||||||
|
* <b>Note:</b> {@link GameSettings#anaglyph} has been removed in Minecraft 1.13
|
||||||
*
|
*
|
||||||
* @param event The event
|
* @param event The event
|
||||||
*/
|
*/
|
||||||
@@ -81,7 +85,7 @@ public interface IGameEventListener {
|
|||||||
* Runs before and after whenever a new world is loaded
|
* Runs before and after whenever a new world is loaded
|
||||||
*
|
*
|
||||||
* @param event The event
|
* @param event The event
|
||||||
* @see Minecraft#loadWorld(WorldClient, GuiScreen)
|
* @see Minecraft#loadWorld(WorldClient, String)
|
||||||
*/
|
*/
|
||||||
void onWorldEvent(WorldEvent event);
|
void onWorldEvent(WorldEvent event);
|
||||||
|
|
||||||
@@ -90,6 +94,7 @@ public interface IGameEventListener {
|
|||||||
*
|
*
|
||||||
* @param event The event
|
* @param event The event
|
||||||
* @see Packet
|
* @see Packet
|
||||||
|
* @see GenericFutureListener
|
||||||
*/
|
*/
|
||||||
void onSendPacket(PacketEvent event);
|
void onSendPacket(PacketEvent event);
|
||||||
|
|
||||||
@@ -98,6 +103,7 @@ public interface IGameEventListener {
|
|||||||
*
|
*
|
||||||
* @param event The event
|
* @param event The event
|
||||||
* @see Packet
|
* @see Packet
|
||||||
|
* @see GenericFutureListener
|
||||||
*/
|
*/
|
||||||
void onReceivePacket(PacketEvent event);
|
void onReceivePacket(PacketEvent event);
|
||||||
|
|
||||||
@@ -111,10 +117,10 @@ public interface IGameEventListener {
|
|||||||
void onPlayerRotationMove(RotationMoveEvent event);
|
void onPlayerRotationMove(RotationMoveEvent event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called whenever the sprint keybind state is checked in {@link EntityPlayerSP#livingTick}
|
* Called whenever the sprint keybind state is checked in {@link EntityPlayerSP#onLivingUpdate}
|
||||||
*
|
*
|
||||||
* @param event The event
|
* @param event The event
|
||||||
* @see EntityPlayerSP#livingTick()
|
* @see EntityPlayerSP#onLivingUpdate()
|
||||||
*/
|
*/
|
||||||
void onPlayerSprintState(SprintStateEvent event);
|
void onPlayerSprintState(SprintStateEvent event);
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public interface IPath {
|
|||||||
* Returns the estimated number of ticks to complete the path from the given node index.
|
* Returns the estimated number of ticks to complete the path from the given node index.
|
||||||
*
|
*
|
||||||
* @param pathPosition The index of the node we're calculating from
|
* @param pathPosition The index of the node we're calculating from
|
||||||
* @return The estimated number of ticks remaining frm the given position
|
* @return The estimated number of ticks remaining from the given position
|
||||||
*/
|
*/
|
||||||
default double ticksRemainingFrom(int pathPosition) {
|
default double ticksRemainingFrom(int pathPosition) {
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
@@ -117,6 +117,15 @@ public interface IPath {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the estimated amount of time needed to complete this path from start to finish
|
||||||
|
*
|
||||||
|
* @return The estimated amount of time, in ticks
|
||||||
|
*/
|
||||||
|
default double totalTicks() {
|
||||||
|
return ticksRemainingFrom(0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cuts off this path at the loaded chunk border, and returns the resulting path. Default
|
* Cuts off this path at the loaded chunk border, and returns the resulting path. Default
|
||||||
* implementation just returns this path, without the intended functionality.
|
* implementation just returns this path, without the intended functionality.
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public interface IBuilderProcess extends IBaritoneProcess {
|
|||||||
boolean build(String name, File schematic, Vec3i origin);
|
boolean build(String name, File schematic, Vec3i origin);
|
||||||
|
|
||||||
default boolean build(String schematicFile, BlockPos origin) {
|
default boolean build(String schematicFile, BlockPos origin) {
|
||||||
File file = new File(new File(Minecraft.getInstance().gameDir, "schematics"), schematicFile);
|
File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile);
|
||||||
return build(schematicFile, file, origin);
|
return build(schematicFile, file, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class FillSchematic extends AbstractSchematic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FillSchematic(int x, int y, int z, IBlockState state) {
|
public FillSchematic(int x, int y, int z, IBlockState state) {
|
||||||
this(x, y, z, new BlockOptionalMeta(state.getBlock()));
|
this(x, y, z, new BlockOptionalMeta(state.getBlock(), state.getBlock().getMetaFromState(state)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockOptionalMeta getBom() {
|
public BlockOptionalMeta getBom() {
|
||||||
|
|||||||
@@ -20,36 +20,45 @@ package baritone.api.utils;
|
|||||||
import baritone.api.utils.accessor.IItemStack;
|
import baritone.api.utils.accessor.IItemStack;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
|
import net.minecraft.block.properties.IProperty;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.state.IProperty;
|
|
||||||
import net.minecraft.state.properties.*;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.registry.IRegistry;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.regex.MatchResult;
|
import java.util.regex.MatchResult;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public final class BlockOptionalMeta {
|
public final class BlockOptionalMeta {
|
||||||
|
|
||||||
private final Block block;
|
private final Block block;
|
||||||
|
private final int meta;
|
||||||
|
private final boolean noMeta;
|
||||||
private final Set<IBlockState> blockstates;
|
private final Set<IBlockState> blockstates;
|
||||||
private final ImmutableSet<Integer> stateHashes;
|
private final ImmutableSet<Integer> stateHashes;
|
||||||
private final ImmutableSet<Integer> stackHashes;
|
private final ImmutableSet<Integer> stackHashes;
|
||||||
private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$");
|
private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$");
|
||||||
|
private static final Map<Object, Object> normalizations;
|
||||||
|
|
||||||
public BlockOptionalMeta(@Nonnull Block block) {
|
public BlockOptionalMeta(@Nonnull Block block, @Nullable Integer meta) {
|
||||||
this.block = block;
|
this.block = block;
|
||||||
this.blockstates = getStates(block);
|
this.noMeta = meta == null;
|
||||||
|
this.meta = noMeta ? 0 : meta;
|
||||||
|
this.blockstates = getStates(block, meta);
|
||||||
this.stateHashes = getStateHashes(blockstates);
|
this.stateHashes = getStateHashes(blockstates);
|
||||||
this.stackHashes = getStackHashes(blockstates);
|
this.stackHashes = getStackHashes(blockstates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockOptionalMeta(@Nonnull Block block) {
|
||||||
|
this(block, null);
|
||||||
|
}
|
||||||
|
|
||||||
public BlockOptionalMeta(@Nonnull String selector) {
|
public BlockOptionalMeta(@Nonnull String selector) {
|
||||||
Matcher matcher = pattern.matcher(selector);
|
Matcher matcher = pattern.matcher(selector);
|
||||||
|
|
||||||
@@ -58,21 +67,187 @@ public final class BlockOptionalMeta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MatchResult matchResult = matcher.toMatchResult();
|
MatchResult matchResult = matcher.toMatchResult();
|
||||||
|
noMeta = matchResult.group(2) == null;
|
||||||
|
|
||||||
ResourceLocation id = new ResourceLocation(matchResult.group(1));
|
ResourceLocation id = new ResourceLocation(matchResult.group(1));
|
||||||
|
|
||||||
if (!IRegistry.BLOCK.containsKey(id)) {
|
if (!Block.REGISTRY.containsKey(id)) {
|
||||||
throw new IllegalArgumentException("Invalid block ID");
|
throw new IllegalArgumentException("Invalid block ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
block = IRegistry.BLOCK.get(id);
|
block = Block.REGISTRY.getObject(id);
|
||||||
blockstates = getStates(block);
|
meta = noMeta ? 0 : Integer.parseInt(matchResult.group(2));
|
||||||
|
blockstates = getStates(block, getMeta());
|
||||||
stateHashes = getStateHashes(blockstates);
|
stateHashes = getStateHashes(blockstates);
|
||||||
stackHashes = getStackHashes(blockstates);
|
stackHashes = getStackHashes(blockstates);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<IBlockState> getStates(@Nonnull Block block) {
|
static {
|
||||||
return new HashSet<>(block.getStateContainer().getValidStates());
|
Map<Object, Object> _normalizations = new HashMap<>();
|
||||||
|
Consumer<Enum> put = instance -> _normalizations.put(instance.getClass(), instance);
|
||||||
|
put.accept(EnumFacing.NORTH);
|
||||||
|
put.accept(EnumFacing.Axis.Y);
|
||||||
|
put.accept(BlockLog.EnumAxis.Y);
|
||||||
|
put.accept(BlockStairs.EnumHalf.BOTTOM);
|
||||||
|
put.accept(BlockStairs.EnumShape.STRAIGHT);
|
||||||
|
put.accept(BlockLever.EnumOrientation.DOWN_X);
|
||||||
|
put.accept(BlockDoublePlant.EnumBlockHalf.LOWER);
|
||||||
|
put.accept(BlockSlab.EnumBlockHalf.BOTTOM);
|
||||||
|
put.accept(BlockDoor.EnumDoorHalf.LOWER);
|
||||||
|
put.accept(BlockDoor.EnumHingePosition.LEFT);
|
||||||
|
put.accept(BlockBed.EnumPartType.HEAD);
|
||||||
|
put.accept(BlockRailBase.EnumRailDirection.NORTH_SOUTH);
|
||||||
|
put.accept(BlockTrapDoor.DoorHalf.BOTTOM);
|
||||||
|
_normalizations.put(BlockBanner.ROTATION, 0);
|
||||||
|
_normalizations.put(BlockBed.OCCUPIED, false);
|
||||||
|
_normalizations.put(BlockBrewingStand.HAS_BOTTLE[0], false);
|
||||||
|
_normalizations.put(BlockBrewingStand.HAS_BOTTLE[1], false);
|
||||||
|
_normalizations.put(BlockBrewingStand.HAS_BOTTLE[2], false);
|
||||||
|
_normalizations.put(BlockButton.POWERED, false);
|
||||||
|
// _normalizations.put(BlockCactus.AGE, 0);
|
||||||
|
// _normalizations.put(BlockCauldron.LEVEL, 0);
|
||||||
|
// _normalizations.put(BlockChorusFlower.AGE, 0);
|
||||||
|
_normalizations.put(BlockChorusPlant.NORTH, false);
|
||||||
|
_normalizations.put(BlockChorusPlant.EAST, false);
|
||||||
|
_normalizations.put(BlockChorusPlant.SOUTH, false);
|
||||||
|
_normalizations.put(BlockChorusPlant.WEST, false);
|
||||||
|
_normalizations.put(BlockChorusPlant.UP, false);
|
||||||
|
_normalizations.put(BlockChorusPlant.DOWN, false);
|
||||||
|
// _normalizations.put(BlockCocoa.AGE, 0);
|
||||||
|
// _normalizations.put(BlockCrops.AGE, 0);
|
||||||
|
_normalizations.put(BlockDirt.SNOWY, false);
|
||||||
|
_normalizations.put(BlockDoor.OPEN, false);
|
||||||
|
_normalizations.put(BlockDoor.POWERED, false);
|
||||||
|
// _normalizations.put(BlockFarmland.MOISTURE, 0);
|
||||||
|
_normalizations.put(BlockFence.NORTH, false);
|
||||||
|
_normalizations.put(BlockFence.EAST, false);
|
||||||
|
_normalizations.put(BlockFence.WEST, false);
|
||||||
|
_normalizations.put(BlockFence.SOUTH, false);
|
||||||
|
// _normalizations.put(BlockFenceGate.POWERED, false);
|
||||||
|
// _normalizations.put(BlockFenceGate.IN_WALL, false);
|
||||||
|
_normalizations.put(BlockFire.AGE, 0);
|
||||||
|
_normalizations.put(BlockFire.NORTH, false);
|
||||||
|
_normalizations.put(BlockFire.EAST, false);
|
||||||
|
_normalizations.put(BlockFire.SOUTH, false);
|
||||||
|
_normalizations.put(BlockFire.WEST, false);
|
||||||
|
_normalizations.put(BlockFire.UPPER, false);
|
||||||
|
// _normalizations.put(BlockFrostedIce.AGE, 0);
|
||||||
|
_normalizations.put(BlockGrass.SNOWY, false);
|
||||||
|
// _normalizations.put(BlockHopper.ENABLED, true);
|
||||||
|
// _normalizations.put(BlockLever.POWERED, false);
|
||||||
|
// _normalizations.put(BlockLiquid.LEVEL, 0);
|
||||||
|
// _normalizations.put(BlockMycelium.SNOWY, false);
|
||||||
|
// _normalizations.put(BlockNetherWart.AGE, false);
|
||||||
|
_normalizations.put(BlockLeaves.CHECK_DECAY, false);
|
||||||
|
// _normalizations.put(BlockLeaves.DECAYABLE, false);
|
||||||
|
// _normalizations.put(BlockObserver.POWERED, false);
|
||||||
|
_normalizations.put(BlockPane.NORTH, false);
|
||||||
|
_normalizations.put(BlockPane.EAST, false);
|
||||||
|
_normalizations.put(BlockPane.WEST, false);
|
||||||
|
_normalizations.put(BlockPane.SOUTH, false);
|
||||||
|
// _normalizations.put(BlockPistonBase.EXTENDED, false);
|
||||||
|
// _normalizations.put(BlockPressurePlate.POWERED, false);
|
||||||
|
// _normalizations.put(BlockPressurePlateWeighted.POWER, false);
|
||||||
|
_normalizations.put(BlockQuartz.EnumType.LINES_X, BlockQuartz.EnumType.LINES_Y);
|
||||||
|
_normalizations.put(BlockQuartz.EnumType.LINES_Z, BlockQuartz.EnumType.LINES_Y);
|
||||||
|
// _normalizations.put(BlockRailDetector.POWERED, false);
|
||||||
|
// _normalizations.put(BlockRailPowered.POWERED, false);
|
||||||
|
_normalizations.put(BlockRedstoneWire.NORTH, false);
|
||||||
|
_normalizations.put(BlockRedstoneWire.EAST, false);
|
||||||
|
_normalizations.put(BlockRedstoneWire.SOUTH, false);
|
||||||
|
_normalizations.put(BlockRedstoneWire.WEST, false);
|
||||||
|
// _normalizations.put(BlockReed.AGE, false);
|
||||||
|
_normalizations.put(BlockSapling.STAGE, 0);
|
||||||
|
_normalizations.put(BlockSkull.NODROP, false);
|
||||||
|
_normalizations.put(BlockStandingSign.ROTATION, 0);
|
||||||
|
_normalizations.put(BlockStem.AGE, 0);
|
||||||
|
_normalizations.put(BlockTripWire.NORTH, false);
|
||||||
|
_normalizations.put(BlockTripWire.EAST, false);
|
||||||
|
_normalizations.put(BlockTripWire.WEST, false);
|
||||||
|
_normalizations.put(BlockTripWire.SOUTH, false);
|
||||||
|
_normalizations.put(BlockVine.NORTH, false);
|
||||||
|
_normalizations.put(BlockVine.EAST, false);
|
||||||
|
_normalizations.put(BlockVine.SOUTH, false);
|
||||||
|
_normalizations.put(BlockVine.WEST, false);
|
||||||
|
_normalizations.put(BlockVine.UP, false);
|
||||||
|
_normalizations.put(BlockWall.UP, false);
|
||||||
|
_normalizations.put(BlockWall.NORTH, false);
|
||||||
|
_normalizations.put(BlockWall.EAST, false);
|
||||||
|
_normalizations.put(BlockWall.WEST, false);
|
||||||
|
_normalizations.put(BlockWall.SOUTH, false);
|
||||||
|
normalizations = Collections.unmodifiableMap(_normalizations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <C extends Comparable<C>, P extends IProperty<C>> P castToIProperty(Object value) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (P) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <C extends Comparable<C>, P extends IProperty<C>> C castToIPropertyValue(P iproperty, Object value) {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (C) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes the specified blockstate by setting meta-affecting properties which
|
||||||
|
* are not being targeted by the meta parameter to their default values.
|
||||||
|
* <p>
|
||||||
|
* For example, block variant/color is the primary target for the meta value, so properties
|
||||||
|
* such as rotation/facing direction will be set to default values in order to nullify
|
||||||
|
* the effect that they have on the state's meta value.
|
||||||
|
*
|
||||||
|
* @param state The state to normalize
|
||||||
|
* @return The normalized block state
|
||||||
|
*/
|
||||||
|
public static IBlockState normalize(IBlockState state) {
|
||||||
|
IBlockState newState = state;
|
||||||
|
|
||||||
|
for (IProperty<?> property : state.getProperties().keySet()) {
|
||||||
|
Class<?> valueClass = property.getValueClass();
|
||||||
|
if (normalizations.containsKey(property)) {
|
||||||
|
try {
|
||||||
|
newState = newState.withProperty(
|
||||||
|
castToIProperty(property),
|
||||||
|
castToIPropertyValue(property, normalizations.get(property))
|
||||||
|
);
|
||||||
|
} catch (IllegalArgumentException ignored) {}
|
||||||
|
} else if (normalizations.containsKey(state.getValue(property))) {
|
||||||
|
try {
|
||||||
|
newState = newState.withProperty(
|
||||||
|
castToIProperty(property),
|
||||||
|
castToIPropertyValue(property, normalizations.get(state.getValue(property)))
|
||||||
|
);
|
||||||
|
} catch (IllegalArgumentException ignored) {}
|
||||||
|
} else if (normalizations.containsKey(valueClass)) {
|
||||||
|
try {
|
||||||
|
newState = newState.withProperty(
|
||||||
|
castToIProperty(property),
|
||||||
|
castToIPropertyValue(property, normalizations.get(valueClass))
|
||||||
|
);
|
||||||
|
} catch (IllegalArgumentException ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate the target meta value for the specified state. The target meta value is
|
||||||
|
* most often that which is influenced by the variant/color property of the block state.
|
||||||
|
*
|
||||||
|
* @see #normalize(IBlockState)
|
||||||
|
*
|
||||||
|
* @param state The state to check
|
||||||
|
* @return The target meta of the state
|
||||||
|
*/
|
||||||
|
public static int stateMeta(IBlockState state) {
|
||||||
|
return state.getBlock().getMetaFromState(normalize(state));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<IBlockState> getStates(@Nonnull Block block, @Nullable Integer meta) {
|
||||||
|
return block.getBlockState().getValidStates().stream()
|
||||||
|
.filter(blockstate -> meta == null || stateMeta(blockstate) == meta)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ImmutableSet<Integer> getStateHashes(Set<IBlockState> blockstates) {
|
private static ImmutableSet<Integer> getStateHashes(Set<IBlockState> blockstates) {
|
||||||
@@ -88,8 +263,8 @@ public final class BlockOptionalMeta {
|
|||||||
return ImmutableSet.copyOf(
|
return ImmutableSet.copyOf(
|
||||||
blockstates.stream()
|
blockstates.stream()
|
||||||
.map(state -> new ItemStack(
|
.map(state -> new ItemStack(
|
||||||
state.getBlock().getItemDropped(state, null, null, 0).asItem(),
|
state.getBlock().getItemDropped(state, new Random(), 0),
|
||||||
1
|
state.getBlock().damageDropped(state)
|
||||||
))
|
))
|
||||||
.map(stack -> ((IItemStack) (Object) stack).getBaritoneHash())
|
.map(stack -> ((IItemStack) (Object) stack).getBaritoneHash())
|
||||||
.toArray(Integer[]::new)
|
.toArray(Integer[]::new)
|
||||||
@@ -100,6 +275,10 @@ public final class BlockOptionalMeta {
|
|||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getMeta() {
|
||||||
|
return noMeta ? null : meta;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean matches(@Nonnull Block block) {
|
public boolean matches(@Nonnull Block block) {
|
||||||
return block == this.block;
|
return block == this.block;
|
||||||
}
|
}
|
||||||
@@ -113,14 +292,21 @@ public final class BlockOptionalMeta {
|
|||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
int hash = ((IItemStack) (Object) stack).getBaritoneHash();
|
int hash = ((IItemStack) (Object) stack).getBaritoneHash();
|
||||||
|
|
||||||
hash -= stack.getDamage();
|
if (noMeta) {
|
||||||
|
hash -= stack.getItemDamage();
|
||||||
|
}
|
||||||
|
|
||||||
return stackHashes.contains(hash);
|
return stackHashes.contains(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("BlockOptionalMeta{block=%s}", block);
|
return String.format("BlockOptionalMeta{block=%s,meta=%s}", block, getMeta());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IBlockState blockStateFromStack(ItemStack stack) {
|
||||||
|
//noinspection deprecation
|
||||||
|
return Block.getBlockFromItem(stack.getItem()).getStateFromMeta(stack.getMetadata());
|
||||||
}
|
}
|
||||||
|
|
||||||
public IBlockState getAnyBlockState() {
|
public IBlockState getAnyBlockState() {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package baritone.api.utils;
|
|||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.registry.IRegistry;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -29,7 +28,7 @@ public class BlockUtils {
|
|||||||
private static transient Map<String, Block> resourceCache = new HashMap<>();
|
private static transient Map<String, Block> resourceCache = new HashMap<>();
|
||||||
|
|
||||||
public static String blockToString(Block block) {
|
public static String blockToString(Block block) {
|
||||||
ResourceLocation loc = IRegistry.BLOCK.getKey(block);
|
ResourceLocation loc = Block.REGISTRY.getNameForObject(block);
|
||||||
String name = loc.getPath(); // normally, only write the part after the minecraft:
|
String name = loc.getPath(); // normally, only write the part after the minecraft:
|
||||||
if (!loc.getNamespace().equals("minecraft")) {
|
if (!loc.getNamespace().equals("minecraft")) {
|
||||||
// Baritone is running on top of forge with mods installed, perhaps?
|
// Baritone is running on top of forge with mods installed, perhaps?
|
||||||
@@ -57,7 +56,7 @@ public class BlockUtils {
|
|||||||
if (resourceCache.containsKey(name)) {
|
if (resourceCache.containsKey(name)) {
|
||||||
return null; // cached as null
|
return null; // cached as null
|
||||||
}
|
}
|
||||||
block = IRegistry.BLOCK.get(ResourceLocation.tryCreate(name.contains(":") ? name : "minecraft:" + name));
|
block = Block.getBlockFromName(name.contains(":") ? name : "minecraft:" + name);
|
||||||
Map<String, Block> copy = new HashMap<>(resourceCache); // read only copy is safe, wont throw concurrentmodification
|
Map<String, Block> copy = new HashMap<>(resourceCache); // read only copy is safe, wont throw concurrentmodification
|
||||||
copy.put(name, block);
|
copy.put(name, block);
|
||||||
resourceCache = copy;
|
resourceCache = copy;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public interface Helper {
|
|||||||
/**
|
/**
|
||||||
* Instance of the game
|
* Instance of the game
|
||||||
*/
|
*/
|
||||||
Minecraft mc = Minecraft.getInstance();
|
Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
|
||||||
static ITextComponent getPrefix() {
|
static ITextComponent getPrefix() {
|
||||||
// Inner text component
|
// Inner text component
|
||||||
@@ -84,7 +84,7 @@ public interface Helper {
|
|||||||
component.appendSibling(getPrefix());
|
component.appendSibling(getPrefix());
|
||||||
component.appendSibling(new TextComponentString(" "));
|
component.appendSibling(new TextComponentString(" "));
|
||||||
Arrays.asList(components).forEach(component::appendSibling);
|
Arrays.asList(components).forEach(component::appendSibling);
|
||||||
mc.addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component));
|
Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ public interface IPlayerContext {
|
|||||||
*/
|
*/
|
||||||
default Optional<BlockPos> getSelectedBlock() {
|
default Optional<BlockPos> getSelectedBlock() {
|
||||||
RayTraceResult result = objectMouseOver();
|
RayTraceResult result = objectMouseOver();
|
||||||
if (result != null && result.type == RayTraceResult.Type.BLOCK) {
|
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||||
return Optional.of(result.getBlockPos());
|
return Optional.of(result.getBlockPos());
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
@@ -101,8 +101,8 @@ public interface IPlayerContext {
|
|||||||
*/
|
*/
|
||||||
default Optional<Entity> getSelectedEntity() {
|
default Optional<Entity> getSelectedEntity() {
|
||||||
RayTraceResult result = objectMouseOver();
|
RayTraceResult result = objectMouseOver();
|
||||||
if (result != null && result.type == RayTraceResult.Type.ENTITY) {
|
if (result != null && result.typeOfHit == RayTraceResult.Type.ENTITY) {
|
||||||
return Optional.of(result.entity);
|
return Optional.of(result.entityHit);
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ public interface IPlayerController {
|
|||||||
|
|
||||||
ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player);
|
ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player);
|
||||||
|
|
||||||
|
void setGameType(GameType type);
|
||||||
|
|
||||||
GameType getGameType();
|
GameType getGameType();
|
||||||
|
|
||||||
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);
|
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package baritone.api.utils;
|
package baritone.api.utils;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.RayTraceFluidMode;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
@@ -41,13 +40,13 @@ public final class RayTraceUtils {
|
|||||||
* @return The calculated raytrace result
|
* @return The calculated raytrace result
|
||||||
*/
|
*/
|
||||||
public static RayTraceResult rayTraceTowards(Entity entity, Rotation rotation, double blockReachDistance) {
|
public static RayTraceResult rayTraceTowards(Entity entity, Rotation rotation, double blockReachDistance) {
|
||||||
Vec3d start = entity.getEyePosition(1.0F);
|
Vec3d start = entity.getPositionEyes(1.0F);
|
||||||
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
|
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
|
||||||
Vec3d end = start.add(
|
Vec3d end = start.add(
|
||||||
direction.x * blockReachDistance,
|
direction.x * blockReachDistance,
|
||||||
direction.y * blockReachDistance,
|
direction.y * blockReachDistance,
|
||||||
direction.z * blockReachDistance
|
direction.z * blockReachDistance
|
||||||
);
|
);
|
||||||
return entity.world.rayTraceBlocks(start, end, RayTraceFluidMode.NEVER, false, true);
|
return entity.world.rayTraceBlocks(start, end, false, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,9 +36,6 @@ public class Rotation {
|
|||||||
public Rotation(float yaw, float pitch) {
|
public Rotation(float yaw, float pitch) {
|
||||||
this.yaw = yaw;
|
this.yaw = yaw;
|
||||||
this.pitch = pitch;
|
this.pitch = pitch;
|
||||||
if (Float.isInfinite(yaw) || Float.isNaN(yaw) || Float.isInfinite(pitch) || Float.isNaN(pitch)) {
|
|
||||||
throw new IllegalStateException(yaw + " " + pitch);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -23,13 +23,7 @@ import net.minecraft.block.BlockFire;
|
|||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
|
||||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -180,14 +174,11 @@ public final class RotationUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IBlockState state = entity.world.getBlockState(pos);
|
IBlockState state = entity.world.getBlockState(pos);
|
||||||
VoxelShape shape = state.getShape(entity.world, pos);
|
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
|
||||||
if (shape.isEmpty()) {
|
|
||||||
shape = VoxelShapes.fullCube();
|
|
||||||
}
|
|
||||||
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
|
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
|
||||||
double xDiff = shape.getStart(EnumFacing.Axis.X) * sideOffset.x + shape.getEnd(EnumFacing.Axis.X) * (1 - sideOffset.x);
|
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
|
||||||
double yDiff = shape.getStart(EnumFacing.Axis.Y) * sideOffset.y + shape.getEnd(EnumFacing.Axis.Y) * (1 - sideOffset.y);
|
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
|
||||||
double zDiff = shape.getStart(EnumFacing.Axis.Z) * sideOffset.z + shape.getEnd(EnumFacing.Axis.Z) * (1 - sideOffset.z);
|
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
|
||||||
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance);
|
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance);
|
||||||
if (possibleRotation.isPresent()) {
|
if (possibleRotation.isPresent()) {
|
||||||
return possibleRotation;
|
return possibleRotation;
|
||||||
@@ -208,10 +199,10 @@ public final class RotationUtils {
|
|||||||
* @return The optional rotation
|
* @return The optional rotation
|
||||||
*/
|
*/
|
||||||
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
|
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
|
||||||
Rotation rotation = calcRotationFromVec3d(entity.getEyePosition(1.0F), offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
|
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
|
||||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
|
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
|
||||||
//System.out.println(result);
|
//System.out.println(result);
|
||||||
if (result != null && result.type == RayTraceResult.Type.BLOCK) {
|
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||||
if (result.getBlockPos().equals(pos)) {
|
if (result.getBlockPos().equals(pos)) {
|
||||||
return Optional.of(rotation);
|
return Optional.of(rotation);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,9 @@ package baritone.api.utils;
|
|||||||
import baritone.api.BaritoneAPI;
|
import baritone.api.BaritoneAPI;
|
||||||
import baritone.api.Settings;
|
import baritone.api.Settings;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.math.Vec3i;
|
import net.minecraft.util.math.Vec3i;
|
||||||
import net.minecraft.util.registry.IRegistry;
|
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
@@ -46,13 +43,13 @@ import java.util.regex.Pattern;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static net.minecraft.client.Minecraft.getMinecraft;
|
||||||
|
|
||||||
public class SettingsUtil {
|
public class SettingsUtil {
|
||||||
|
|
||||||
private static final Path SETTINGS_PATH = Minecraft.getInstance().gameDir.toPath().resolve("baritone").resolve("settings.txt");
|
private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt");
|
||||||
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
|
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
|
||||||
|
|
||||||
|
|
||||||
private static boolean isComment(String line) {
|
private static boolean isComment(String line) {
|
||||||
return line.startsWith("#") || line.startsWith("//");
|
return line.startsWith("#") || line.startsWith("//");
|
||||||
}
|
}
|
||||||
@@ -236,14 +233,15 @@ public class SettingsUtil {
|
|||||||
),
|
),
|
||||||
ITEM(
|
ITEM(
|
||||||
Item.class,
|
Item.class,
|
||||||
str -> IRegistry.ITEM.get(new ResourceLocation(str.trim())),
|
str -> Item.getByNameOrId(str.trim()),
|
||||||
item -> IRegistry.ITEM.getKey(item).toString()
|
item -> Item.REGISTRY.getNameForObject(item).toString()
|
||||||
),
|
),
|
||||||
LIST() {
|
LIST() {
|
||||||
@Override
|
@Override
|
||||||
public Object parse(ParserContext context, String raw) {
|
public Object parse(ParserContext context, String raw) {
|
||||||
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
Type type = ((ParameterizedType) context.getSetting().getType()).getActualTypeArguments()[0];
|
||||||
Parser parser = Parser.getParser(type);
|
Parser parser = Parser.getParser(type);
|
||||||
|
|
||||||
return Stream.of(raw.split(","))
|
return Stream.of(raw.split(","))
|
||||||
.map(s -> parser.parse(context, s))
|
.map(s -> parser.parse(context, s))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|||||||
@@ -20,10 +20,9 @@ package baritone.api.utils;
|
|||||||
import net.minecraft.block.BlockFire;
|
import net.minecraft.block.BlockFire;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,16 +43,10 @@ public final class VecUtils {
|
|||||||
*/
|
*/
|
||||||
public static Vec3d calculateBlockCenter(World world, BlockPos pos) {
|
public static Vec3d calculateBlockCenter(World world, BlockPos pos) {
|
||||||
IBlockState b = world.getBlockState(pos);
|
IBlockState b = world.getBlockState(pos);
|
||||||
VoxelShape shape = b.getCollisionShape(world, pos);
|
AxisAlignedBB bbox = b.getBoundingBox(world, pos);
|
||||||
if (shape.isEmpty()) {
|
double xDiff = (bbox.minX + bbox.maxX) / 2;
|
||||||
return getBlockPosCenter(pos);
|
double yDiff = (bbox.minY + bbox.maxY) / 2;
|
||||||
}
|
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
|
||||||
double xDiff = (shape.getStart(EnumFacing.Axis.X) + shape.getEnd(EnumFacing.Axis.X)) / 2;
|
|
||||||
double yDiff = (shape.getStart(EnumFacing.Axis.Y) + shape.getEnd(EnumFacing.Axis.Y)) / 2;
|
|
||||||
double zDiff = (shape.getStart(EnumFacing.Axis.Z) + shape.getEnd(EnumFacing.Axis.Z)) / 2;
|
|
||||||
if (Double.isNaN(xDiff) || Double.isNaN(yDiff) || Double.isNaN(zDiff)) {
|
|
||||||
throw new IllegalStateException(b + " " + pos + " " + shape);
|
|
||||||
}
|
|
||||||
if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
|
if (b.getBlock() instanceof BlockFire) {//look at bottom of fire when putting it out
|
||||||
yDiff = 0;
|
yDiff = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,105 +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 com.google.common.base.Strings;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.mojang.authlib.Agent;
|
|
||||||
import com.mojang.authlib.exceptions.AuthenticationException;
|
|
||||||
import com.mojang.authlib.properties.PropertyMap;
|
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication;
|
|
||||||
import net.minecraft.launchwrapper.Launch;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.Proxy;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Based on GradleStart from ForgeGradle 2.3
|
|
||||||
*
|
|
||||||
* @author Brady
|
|
||||||
* @since 3/11/2019
|
|
||||||
*/
|
|
||||||
public class LaunchTesting {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Map<String, String> arguments = new HashMap<>();
|
|
||||||
|
|
||||||
hackNatives();
|
|
||||||
arguments.put("version", "BaritownedDeveloperEnvironment");
|
|
||||||
arguments.put("assetIndex", System.getenv("assetIndex"));
|
|
||||||
arguments.put("assetsDir", System.getenv().getOrDefault("assetDirectory", "assets"));
|
|
||||||
arguments.put("accessToken", "FML");
|
|
||||||
arguments.put("userProperties", "{}");
|
|
||||||
arguments.put("tweakClass", System.getenv("tweakClass"));
|
|
||||||
String password = System.getenv("password");
|
|
||||||
if (password != null && !password.isEmpty()) {
|
|
||||||
attemptLogin(arguments, System.getenv("username"), System.getenv("password"));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> argsArray = new ArrayList<>();
|
|
||||||
arguments.forEach((k, v) -> {
|
|
||||||
argsArray.add("--" + k);
|
|
||||||
argsArray.add(v);
|
|
||||||
});
|
|
||||||
|
|
||||||
Launch.main(argsArray.toArray(new String[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void hackNatives() {
|
|
||||||
String paths = System.getProperty("java.library.path");
|
|
||||||
String nativesDir = System.getenv().get("nativesDirectory");
|
|
||||||
|
|
||||||
if (Strings.isNullOrEmpty(paths))
|
|
||||||
paths = nativesDir;
|
|
||||||
else
|
|
||||||
paths += File.pathSeparator + nativesDir;
|
|
||||||
|
|
||||||
System.setProperty("java.library.path", paths);
|
|
||||||
|
|
||||||
// hack the classloader now.
|
|
||||||
try {
|
|
||||||
final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
|
|
||||||
sysPathsField.setAccessible(true);
|
|
||||||
sysPathsField.set(null, null);
|
|
||||||
} catch (Throwable ignored) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void attemptLogin(Map<String, String> argMap, String username, String password) {
|
|
||||||
YggdrasilUserAuthentication auth = (YggdrasilUserAuthentication) (new YggdrasilAuthenticationService(Proxy.NO_PROXY, "1")).createUserAuthentication(Agent.MINECRAFT);
|
|
||||||
auth.setUsername(username);
|
|
||||||
auth.setPassword(password);
|
|
||||||
|
|
||||||
try {
|
|
||||||
auth.logIn();
|
|
||||||
} catch (AuthenticationException var4) {
|
|
||||||
throw new RuntimeException(var4);
|
|
||||||
}
|
|
||||||
|
|
||||||
argMap.put("accessToken", auth.getAuthenticatedToken());
|
|
||||||
argMap.put("uuid", auth.getSelectedProfile().getId().toString().replace("-", ""));
|
|
||||||
argMap.put("username", auth.getSelectedProfile().getName());
|
|
||||||
argMap.put("userType", auth.getUserType().getName());
|
|
||||||
argMap.put("userProperties", (new GsonBuilder()).registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create().toJson(auth.getUserProperties()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -33,11 +33,11 @@ public abstract class MixinBlockStateContainer implements IBlockStateContainer {
|
|||||||
protected BitArray storage;
|
protected BitArray storage;
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
protected IBlockStatePalette<IBlockState> palette;
|
protected IBlockStatePalette palette;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBlockState getAtPalette(int index) {
|
public IBlockState getAtPalette(int index) {
|
||||||
return palette.get(index);
|
return palette.getBlockState(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+12
-20
@@ -17,31 +17,23 @@
|
|||||||
|
|
||||||
package baritone.launch.mixins;
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
import baritone.Baritone;
|
import net.minecraft.client.gui.GuiChat;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.renderer.chunk.RenderChunkCache;
|
|
||||||
import net.minecraft.world.chunk.Chunk;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(RenderChunkCache.class)
|
@Mixin(GuiChat.ChatTabCompleter.class)
|
||||||
public class MixinRenderChunkCache {
|
public abstract class MixinChatTabCompleter extends MixinTabCompleter {
|
||||||
|
|
||||||
@Redirect(
|
@Inject(
|
||||||
method = "generateCache",
|
method = "complete",
|
||||||
at = @At(
|
at = @At("HEAD"),
|
||||||
value = "INVOKE",
|
cancellable = true
|
||||||
target = "net/minecraft/world/chunk/Chunk.isEmptyBetween(II)Z"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
private static boolean isEmpty(Chunk chunk, int yStart, int yEnd) {
|
private void onComplete(CallbackInfo ci) {
|
||||||
if (!chunk.isEmptyBetween(yStart, yEnd)) {
|
if (dontComplete) {
|
||||||
return false;
|
ci.cancel();
|
||||||
}
|
}
|
||||||
if (chunk.isEmpty() && Baritone.settings().renderCachedChunks.value && Minecraft.getInstance().getIntegratedServer() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,10 +28,7 @@ import org.spongepowered.asm.mixin.Mixin;
|
|||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL11.GL_ONE;
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
import static org.lwjgl.opengl.GL11.GL_ZERO;
|
|
||||||
import static org.lwjgl.opengl.GL14.GL_CONSTANT_ALPHA;
|
|
||||||
import static org.lwjgl.opengl.GL14.GL_ONE_MINUS_CONSTANT_ALPHA;
|
|
||||||
|
|
||||||
@Mixin(ChunkRenderContainer.class)
|
@Mixin(ChunkRenderContainer.class)
|
||||||
public class MixinChunkRenderContainer {
|
public class MixinChunkRenderContainer {
|
||||||
@@ -44,11 +41,11 @@ public class MixinChunkRenderContainer {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private BlockPos getPosition(RenderChunk renderChunkIn) {
|
private BlockPos getPosition(RenderChunk renderChunkIn) {
|
||||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer() && Minecraft.getInstance().world.getChunk(renderChunkIn.getPosition()).isEmpty()) {
|
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer() && Minecraft.getMinecraft().world.getChunk(renderChunkIn.getPosition()).isEmpty()) {
|
||||||
GlStateManager.enableAlphaTest();
|
GlStateManager.enableAlpha();
|
||||||
GlStateManager.enableBlend();
|
GlStateManager.enableBlend();
|
||||||
GL14.glBlendColor(0, 0, 0, Baritone.settings().cachedChunksOpacity.value);
|
GL14.glBlendColor(0, 0, 0, Baritone.settings().cachedChunksOpacity.value);
|
||||||
GlStateManager.blendFuncSeparate(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_ONE, GL_ZERO);
|
GlStateManager.tryBlendFuncSeparate(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA, GL_ONE, GL_ZERO);
|
||||||
}
|
}
|
||||||
return renderChunkIn.getPosition();
|
return renderChunkIn.getPosition();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public abstract class MixinChunkRenderWorker {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private boolean isChunkExisting(ChunkRenderWorker worker, BlockPos pos, World world) {
|
private boolean isChunkExisting(ChunkRenderWorker worker, BlockPos pos, World world) {
|
||||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
|
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
|
||||||
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||||
IPlayerContext ctx = baritone.getPlayerContext();
|
IPlayerContext ctx = baritone.getPlayerContext();
|
||||||
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import baritone.api.event.events.RotationMoveEvent;
|
|||||||
import net.minecraft.client.entity.EntityPlayerSP;
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.EntityType;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -45,8 +44,9 @@ public abstract class MixinEntityLivingBase extends Entity {
|
|||||||
*/
|
*/
|
||||||
private RotationMoveEvent jumpRotationEvent;
|
private RotationMoveEvent jumpRotationEvent;
|
||||||
|
|
||||||
public MixinEntityLivingBase(EntityType<?> entityTypeIn, World worldIn) {
|
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
|
||||||
super(entityTypeIn, worldIn);
|
super(worldIn);
|
||||||
|
this.jumpRotationEvent = jumpRotationEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ public class MixinEntityPlayerSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "tick",
|
method = "onUpdate",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "net/minecraft/client/entity/EntityPlayerSP.isPassenger()Z",
|
target = "net/minecraft/client/entity/EntityPlayerSP.isRiding()Z",
|
||||||
shift = At.Shift.BY,
|
shift = At.Shift.BY,
|
||||||
by = -3
|
by = -3
|
||||||
)
|
)
|
||||||
@@ -74,7 +74,7 @@ public class MixinEntityPlayerSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "tick",
|
method = "onUpdate",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "net/minecraft/client/entity/EntityPlayerSP.onUpdateWalkingPlayer()V",
|
target = "net/minecraft/client/entity/EntityPlayerSP.onUpdateWalkingPlayer()V",
|
||||||
@@ -90,7 +90,7 @@ public class MixinEntityPlayerSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(
|
@Redirect(
|
||||||
method = "livingTick",
|
method = "onLivingUpdate",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "FIELD",
|
value = "FIELD",
|
||||||
target = "net/minecraft/entity/player/PlayerCapabilities.allowFlying:Z"
|
target = "net/minecraft/entity/player/PlayerCapabilities.allowFlying:Z"
|
||||||
@@ -105,7 +105,7 @@ public class MixinEntityPlayerSP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(
|
@Redirect(
|
||||||
method = "livingTick",
|
method = "onLivingUpdate",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "net/minecraft/client/settings/KeyBinding.isKeyDown()Z"
|
target = "net/minecraft/client/settings/KeyBinding.isKeyDown()Z"
|
||||||
|
|||||||
+5
-5
@@ -20,24 +20,24 @@ package baritone.launch.mixins;
|
|||||||
import baritone.api.BaritoneAPI;
|
import baritone.api.BaritoneAPI;
|
||||||
import baritone.api.IBaritone;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.event.events.RenderEvent;
|
import baritone.api.event.events.RenderEvent;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
import net.minecraft.client.renderer.EntityRenderer;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(GameRenderer.class)
|
@Mixin(EntityRenderer.class)
|
||||||
public class MixinGameRenderer {
|
public class MixinEntityRenderer {
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "updateCameraAndRender(FJ)V",
|
method = "renderWorldPass",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE_STRING",
|
value = "INVOKE_STRING",
|
||||||
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
|
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
|
||||||
args = {"ldc=hand"}
|
args = {"ldc=hand"}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void renderWorldPass(float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
|
||||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
ibaritone.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
|
ibaritone.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
|
||||||
}
|
}
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of Baritone.
|
|
||||||
*
|
|
||||||
* Baritone is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Baritone is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package baritone.launch.mixins;
|
|
||||||
|
|
||||||
import baritone.api.BaritoneAPI;
|
|
||||||
import baritone.api.event.events.TabCompleteEvent;
|
|
||||||
import com.mojang.brigadier.context.StringRange;
|
|
||||||
import com.mojang.brigadier.suggestion.Suggestion;
|
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
|
||||||
import net.minecraft.client.gui.GuiChat;
|
|
||||||
import net.minecraft.client.gui.GuiTextField;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Brady
|
|
||||||
* @since 10/9/2019
|
|
||||||
*/
|
|
||||||
@Mixin(GuiChat.class)
|
|
||||||
public class MixinGuiChat {
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
protected GuiTextField inputField;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
protected List<String> commandUsage;
|
|
||||||
|
|
||||||
@Shadow
|
|
||||||
private CompletableFuture<Suggestions> pendingSuggestions;
|
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "updateSuggestion",
|
|
||||||
at = @At("HEAD"),
|
|
||||||
cancellable = true
|
|
||||||
)
|
|
||||||
private void preUpdateSuggestion(CallbackInfo ci) {
|
|
||||||
// Anything that is present in the input text before the cursor position
|
|
||||||
String prefix = this.inputField.getText().substring(0, Math.min(this.inputField.getText().length(), this.inputField.getCursorPosition()));
|
|
||||||
|
|
||||||
TabCompleteEvent event = new TabCompleteEvent(prefix);
|
|
||||||
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onPreTabComplete(event);
|
|
||||||
|
|
||||||
if (event.isCancelled()) {
|
|
||||||
ci.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.completions != null) {
|
|
||||||
ci.cancel();
|
|
||||||
|
|
||||||
// TODO: Support populating the command usage
|
|
||||||
this.commandUsage.clear();
|
|
||||||
|
|
||||||
if (event.completions.length == 0) {
|
|
||||||
this.pendingSuggestions = Suggestions.empty();
|
|
||||||
} else {
|
|
||||||
int offset = this.inputField.getText().endsWith(" ")
|
|
||||||
? this.inputField.getCursorPosition()
|
|
||||||
: this.inputField.getText().lastIndexOf(" ") + 1; // If there is no space this is still 0 haha yes
|
|
||||||
|
|
||||||
List<Suggestion> suggestionList = Stream.of(event.completions)
|
|
||||||
.map(s -> new Suggestion(StringRange.between(offset, offset + s.length()), s))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
Suggestions suggestions = new Suggestions(
|
|
||||||
StringRange.between(offset, offset + suggestionList.stream().mapToInt(s -> s.getText().length()).max().orElse(0)),
|
|
||||||
suggestionList);
|
|
||||||
|
|
||||||
this.pendingSuggestions = new CompletableFuture<>();
|
|
||||||
this.pendingSuggestions.complete(suggestions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -35,14 +35,14 @@ public abstract class MixinItemStack implements IItemStack {
|
|||||||
@Final
|
@Final
|
||||||
private Item item;
|
private Item item;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private int itemDamage;
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
private int baritoneHash;
|
private int baritoneHash;
|
||||||
|
|
||||||
@Shadow
|
|
||||||
protected abstract int getDamage();
|
|
||||||
|
|
||||||
private void recalculateHash() {
|
private void recalculateHash() {
|
||||||
baritoneHash = item == null ? -1 : item.hashCode() + getDamage();
|
baritoneHash = item == null ? -1 : item.hashCode() + itemDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
@@ -54,7 +54,7 @@ public abstract class MixinItemStack implements IItemStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "setDamage",
|
method = "setItemDamage",
|
||||||
at = @At("TAIL")
|
at = @At("TAIL")
|
||||||
)
|
)
|
||||||
private void onItemDamageSet(CallbackInfo ci) {
|
private void onItemDamageSet(CallbackInfo ci) {
|
||||||
|
|||||||
@@ -100,10 +100,10 @@ public class MixinMinecraft {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Lnet/minecraft/client/gui/GuiScreen;)V",
|
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
|
||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
)
|
)
|
||||||
private void preLoadWorld(WorldClient world, GuiScreen loadingScreen, CallbackInfo ci) {
|
private void preLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
||||||
// If we're unloading the world but one doesn't exist, ignore it
|
// If we're unloading the world but one doesn't exist, ignore it
|
||||||
if (this.world == null && world == null) {
|
if (this.world == null && world == null) {
|
||||||
return;
|
return;
|
||||||
@@ -120,10 +120,10 @@ public class MixinMinecraft {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Lnet/minecraft/client/gui/GuiScreen;)V",
|
method = "loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V",
|
||||||
at = @At("RETURN")
|
at = @At("RETURN")
|
||||||
)
|
)
|
||||||
private void postLoadWorld(WorldClient world, GuiScreen loadingScreen, CallbackInfo ci) {
|
private void postLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
|
||||||
// still fire event for both null, as that means we've just finished exiting a world
|
// still fire event for both null, as that means we've just finished exiting a world
|
||||||
|
|
||||||
// mc.world changing is only the primary baritone
|
// mc.world changing is only the primary baritone
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import baritone.api.event.events.type.EventState;
|
|||||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||||
import net.minecraft.network.play.server.SPacketChunkData;
|
import net.minecraft.network.play.server.SPacketChunkData;
|
||||||
import net.minecraft.network.play.server.SPacketCombatEvent;
|
import net.minecraft.network.play.server.SPacketCombatEvent;
|
||||||
import net.minecraft.network.play.server.SPacketUnloadChunk;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
@@ -41,7 +40,7 @@ public class MixinNetHandlerPlayClient {
|
|||||||
method = "handleChunkData",
|
method = "handleChunkData",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "net/minecraft/client/multiplayer/ChunkProviderClient.func_212474_a(IILnet/minecraft/network/PacketBuffer;IZ)Lnet/minecraft/world/chunk/Chunk;"
|
target = "net/minecraft/world/chunk/Chunk.read(Lnet/minecraft/network/PacketBuffer;IZ)V"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
|
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
|
||||||
@@ -78,34 +77,6 @@ public class MixinNetHandlerPlayClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "processChunkUnload",
|
|
||||||
at = @At("HEAD")
|
|
||||||
)
|
|
||||||
private void preChunkUnload(SPacketUnloadChunk packet, CallbackInfo ci) {
|
|
||||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
|
||||||
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
|
|
||||||
ibaritone.getGameEventHandler().onChunkEvent(
|
|
||||||
new ChunkEvent(EventState.PRE, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(
|
|
||||||
method = "processChunkUnload",
|
|
||||||
at = @At("RETURN")
|
|
||||||
)
|
|
||||||
private void postChunkUnload(SPacketUnloadChunk packet, CallbackInfo ci) {
|
|
||||||
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
|
||||||
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
|
|
||||||
ibaritone.getGameEventHandler().onChunkEvent(
|
|
||||||
new ChunkEvent(EventState.POST, ChunkEvent.Type.UNLOAD, packet.getX(), packet.getZ())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(
|
@Inject(
|
||||||
method = "handleCombatEvent",
|
method = "handleCombatEvent",
|
||||||
at = @At(
|
at = @At(
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public class MixinNetworkManager {
|
|||||||
method = "dispatchPacket",
|
method = "dispatchPacket",
|
||||||
at = @At("HEAD")
|
at = @At("HEAD")
|
||||||
)
|
)
|
||||||
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>> futureListeners, CallbackInfo ci) {
|
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
||||||
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ public class MixinNetworkManager {
|
|||||||
method = "dispatchPacket",
|
method = "dispatchPacket",
|
||||||
at = @At("RETURN")
|
at = @At("RETURN")
|
||||||
)
|
)
|
||||||
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>> futureListeners, CallbackInfo ci) {
|
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
|
||||||
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ public class MixinNetworkManager {
|
|||||||
method = "channelRead0",
|
method = "channelRead0",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "net/minecraft/network/NetworkManager.processPacket(Lnet/minecraft/network/Packet;Lnet/minecraft/network/INetHandler;)V"
|
target = "net/minecraft/network/Packet.processPacket(Lnet/minecraft/network/INetHandler;)V"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ import baritone.api.utils.IPlayerContext;
|
|||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.chunk.RenderChunk;
|
import net.minecraft.client.renderer.chunk.RenderChunk;
|
||||||
import net.minecraft.client.renderer.chunk.RenderChunkCache;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.ChunkCache;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
@@ -40,11 +40,43 @@ public class MixinRenderChunk {
|
|||||||
method = "rebuildChunk",
|
method = "rebuildChunk",
|
||||||
at = @At(
|
at = @At(
|
||||||
value = "INVOKE",
|
value = "INVOKE",
|
||||||
target = "net/minecraft/client/renderer/chunk/RenderChunkCache.getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/state/IBlockState;"
|
target = "net/minecraft/world/ChunkCache.isEmpty()Z"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private IBlockState getBlockState(RenderChunkCache chunkCache, BlockPos pos) {
|
private boolean isEmpty(ChunkCache chunkCache) {
|
||||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
|
if (!chunkCache.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
|
||||||
|
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||||
|
IPlayerContext ctx = baritone.getPlayerContext();
|
||||||
|
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
||||||
|
BlockPos position = ((RenderChunk) (Object) this).getPosition();
|
||||||
|
// RenderChunk extends from -1,-1,-1 to +16,+16,+16
|
||||||
|
// then the constructor of ChunkCache extends it one more (presumably to get things like the connected status of fences? idk)
|
||||||
|
// so if ANY of the adjacent chunks are loaded, we are unempty
|
||||||
|
for (int dx = -1; dx <= 1; dx++) {
|
||||||
|
for (int dz = -1; dz <= 1; dz++) {
|
||||||
|
if (baritone.bsi.isLoaded(16 * dx + position.getX(), 16 * dz + position.getZ())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(
|
||||||
|
method = "rebuildChunk",
|
||||||
|
at = @At(
|
||||||
|
value = "INVOKE",
|
||||||
|
target = "net/minecraft/world/ChunkCache.getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/state/IBlockState;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
private IBlockState getBlockState(ChunkCache chunkCache, BlockPos pos) {
|
||||||
|
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
|
||||||
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
Baritone baritone = (Baritone) BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||||
IPlayerContext ctx = baritone.getPlayerContext();
|
IPlayerContext ctx = baritone.getPlayerContext();
|
||||||
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
if (ctx.player() != null && ctx.world() != null && baritone.bsi != null) {
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ public class MixinRenderList {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void popMatrix() {
|
private void popMatrix() {
|
||||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
|
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
|
||||||
// reset the blend func to normal (not dependent on constant alpha)
|
// reset the blend func to normal (not dependent on constant alpha)
|
||||||
GlStateManager.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||||
}
|
}
|
||||||
GlStateManager.popMatrix();
|
GlStateManager.popMatrix();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import net.minecraft.block.properties.IProperty;
|
||||||
|
import org.spongepowered.asm.mixin.*;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(targets = "net.minecraft.block.state.BlockStateContainer$StateImplementation")
|
||||||
|
public abstract class MixinStateImplementation {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private ImmutableMap<IProperty<?>, Comparable<?>> properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block states are fucking immutable
|
||||||
|
*/
|
||||||
|
@Unique
|
||||||
|
private int hashCode;
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "<init>*",
|
||||||
|
at = @At("RETURN")
|
||||||
|
)
|
||||||
|
private void onInit(CallbackInfo ci) {
|
||||||
|
hashCode = properties.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache this instead of using the fucking map every time
|
||||||
|
*
|
||||||
|
* @author LoganDark
|
||||||
|
* @reason Regular IBlockState generates a new hash every fucking time. This is not needed when scanning millions
|
||||||
|
* per second
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Overwrite
|
||||||
|
public int hashCode() {
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
|
import baritone.api.event.events.TabCompleteEvent;
|
||||||
|
import net.minecraft.client.gui.GuiChat;
|
||||||
|
import net.minecraft.client.gui.GuiTextField;
|
||||||
|
import net.minecraft.util.TabCompleter;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(TabCompleter.class)
|
||||||
|
public abstract class MixinTabCompleter {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
protected GuiTextField textField;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
protected boolean requestedCompletions;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract void setCompletions(String... newCompl);
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
protected boolean dontComplete = false;
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "requestCompletions",
|
||||||
|
at = @At("HEAD"),
|
||||||
|
cancellable = true
|
||||||
|
)
|
||||||
|
private void onRequestCompletions(String prefix, CallbackInfo ci) {
|
||||||
|
if (!((Object) this instanceof GuiChat.ChatTabCompleter)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IBaritone baritone = BaritoneAPI.getProvider().getPrimaryBaritone();
|
||||||
|
|
||||||
|
TabCompleteEvent event = new TabCompleteEvent(prefix);
|
||||||
|
baritone.getGameEventHandler().onPreTabComplete(event);
|
||||||
|
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
ci.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.completions != null) {
|
||||||
|
ci.cancel();
|
||||||
|
|
||||||
|
this.dontComplete = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.requestedCompletions = true;
|
||||||
|
setCompletions(event.completions);
|
||||||
|
} finally {
|
||||||
|
this.dontComplete = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,9 +38,9 @@ public class MixinVboRenderList {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
private void popMatrix() {
|
private void popMatrix() {
|
||||||
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getInstance().isSingleplayer()) {
|
if (Baritone.settings().renderCachedChunks.value && !Minecraft.getMinecraft().isSingleplayer()) {
|
||||||
// reset the blend func to normal (not dependent on constant alpha)
|
// reset the blend func to normal (not dependent on constant alpha)
|
||||||
GlStateManager.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
|
||||||
}
|
}
|
||||||
GlStateManager.popMatrix();
|
GlStateManager.popMatrix();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of Baritone.
|
||||||
|
*
|
||||||
|
* Baritone is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Baritone is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.launch.mixins;
|
||||||
|
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
|
import baritone.api.event.events.ChunkEvent;
|
||||||
|
import baritone.api.event.events.type.EventState;
|
||||||
|
import net.minecraft.client.multiplayer.WorldClient;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 8/2/2018
|
||||||
|
*/
|
||||||
|
@Mixin(WorldClient.class)
|
||||||
|
public class MixinWorldClient {
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "doPreChunk",
|
||||||
|
at = @At("HEAD")
|
||||||
|
)
|
||||||
|
private void preDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
||||||
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
|
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
|
||||||
|
ibaritone.getGameEventHandler().onChunkEvent(
|
||||||
|
new ChunkEvent(
|
||||||
|
EventState.PRE,
|
||||||
|
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||||
|
chunkX,
|
||||||
|
chunkZ
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "doPreChunk",
|
||||||
|
at = @At("RETURN")
|
||||||
|
)
|
||||||
|
private void postDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
|
||||||
|
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
|
||||||
|
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
|
||||||
|
ibaritone.getGameEventHandler().onChunkEvent(
|
||||||
|
new ChunkEvent(
|
||||||
|
EventState.POST,
|
||||||
|
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
|
||||||
|
chunkX,
|
||||||
|
chunkZ
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,14 +11,14 @@
|
|||||||
"MixinAnvilChunkLoader",
|
"MixinAnvilChunkLoader",
|
||||||
"MixinBitArray",
|
"MixinBitArray",
|
||||||
"MixinBlockStateContainer",
|
"MixinBlockStateContainer",
|
||||||
|
"MixinChatTabCompleter",
|
||||||
"MixinChunkProviderClient",
|
"MixinChunkProviderClient",
|
||||||
"MixinChunkProviderServer",
|
"MixinChunkProviderServer",
|
||||||
"MixinChunkRenderContainer",
|
"MixinChunkRenderContainer",
|
||||||
"MixinChunkRenderWorker",
|
"MixinChunkRenderWorker",
|
||||||
"MixinEntityLivingBase",
|
"MixinEntityLivingBase",
|
||||||
"MixinEntityPlayerSP",
|
"MixinEntityPlayerSP",
|
||||||
"MixinGameRenderer",
|
"MixinEntityRenderer",
|
||||||
"MixinGuiChat",
|
|
||||||
"MixinGuiScreen",
|
"MixinGuiScreen",
|
||||||
"MixinItemStack",
|
"MixinItemStack",
|
||||||
"MixinMinecraft",
|
"MixinMinecraft",
|
||||||
@@ -26,8 +26,10 @@
|
|||||||
"MixinNetworkManager",
|
"MixinNetworkManager",
|
||||||
"MixinPlayerControllerMP",
|
"MixinPlayerControllerMP",
|
||||||
"MixinRenderChunk",
|
"MixinRenderChunk",
|
||||||
"MixinRenderChunkCache",
|
|
||||||
"MixinRenderList",
|
"MixinRenderList",
|
||||||
"MixinVboRenderList"
|
"MixinStateImplementation",
|
||||||
|
"MixinTabCompleter",
|
||||||
|
"MixinVboRenderList",
|
||||||
|
"MixinWorldClient"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -25,12 +25,11 @@ import baritone.api.utils.Helper;
|
|||||||
import baritone.api.utils.IPlayerContext;
|
import baritone.api.utils.IPlayerContext;
|
||||||
import baritone.behavior.*;
|
import baritone.behavior.*;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
|
import baritone.command.manager.CommandManager;
|
||||||
import baritone.event.GameEventHandler;
|
import baritone.event.GameEventHandler;
|
||||||
import baritone.process.*;
|
import baritone.process.*;
|
||||||
import baritone.selection.SelectionManager;
|
import baritone.selection.SelectionManager;
|
||||||
import baritone.utils.*;
|
import baritone.utils.*;
|
||||||
import baritone.command.manager.CommandManager;
|
|
||||||
import baritone.utils.player.PrimaryPlayerContext;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -53,7 +52,7 @@ public class Baritone implements IBaritone {
|
|||||||
static {
|
static {
|
||||||
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
|
||||||
|
|
||||||
dir = new File(Minecraft.getInstance().gameDir, "baritone");
|
dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
|
||||||
if (!Files.exists(dir.toPath())) {
|
if (!Files.exists(dir.toPath())) {
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(dir.toPath());
|
Files.createDirectories(dir.toPath());
|
||||||
@@ -87,11 +86,11 @@ public class Baritone implements IBaritone {
|
|||||||
|
|
||||||
public BlockStateInterface bsi;
|
public BlockStateInterface bsi;
|
||||||
|
|
||||||
Baritone() {
|
public Baritone(IPlayerContext playerContext) {
|
||||||
this.gameEventHandler = new GameEventHandler(this);
|
this.gameEventHandler = new GameEventHandler(this);
|
||||||
|
|
||||||
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
|
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
|
||||||
this.playerContext = PrimaryPlayerContext.INSTANCE;
|
this.playerContext = playerContext;
|
||||||
|
|
||||||
{
|
{
|
||||||
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
|
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
|
||||||
@@ -234,4 +233,4 @@ public class Baritone implements IBaritone {
|
|||||||
public static Executor getExecutor() {
|
public static Executor getExecutor() {
|
||||||
return threadPool;
|
return threadPool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,15 +19,19 @@ package baritone;
|
|||||||
|
|
||||||
import baritone.api.IBaritone;
|
import baritone.api.IBaritone;
|
||||||
import baritone.api.IBaritoneProvider;
|
import baritone.api.IBaritoneProvider;
|
||||||
|
import baritone.api.bot.IBaritoneUser;
|
||||||
|
import baritone.api.bot.IUserManager;
|
||||||
import baritone.api.cache.IWorldScanner;
|
import baritone.api.cache.IWorldScanner;
|
||||||
import baritone.api.command.ICommandSystem;
|
import baritone.api.command.ICommandSystem;
|
||||||
|
import baritone.bot.UserManager;
|
||||||
import baritone.api.schematic.ISchematicSystem;
|
import baritone.api.schematic.ISchematicSystem;
|
||||||
import baritone.command.BaritoneChatControl;
|
import baritone.command.BaritoneChatControl;
|
||||||
import baritone.cache.WorldScanner;
|
import baritone.cache.WorldScanner;
|
||||||
import baritone.command.CommandSystem;
|
import baritone.command.CommandSystem;
|
||||||
|
import baritone.utils.player.PrimaryPlayerContext;
|
||||||
import baritone.utils.schematic.SchematicSystem;
|
import baritone.utils.schematic.SchematicSystem;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,11 +41,9 @@ import java.util.List;
|
|||||||
public final class BaritoneProvider implements IBaritoneProvider {
|
public final class BaritoneProvider implements IBaritoneProvider {
|
||||||
|
|
||||||
private final Baritone primary;
|
private final Baritone primary;
|
||||||
private final List<IBaritone> all;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
this.primary = new Baritone();
|
this.primary = new Baritone(PrimaryPlayerContext.INSTANCE);
|
||||||
this.all = Collections.singletonList(this.primary);
|
|
||||||
|
|
||||||
// Setup chat control, just for the primary instance
|
// Setup chat control, just for the primary instance
|
||||||
new BaritoneChatControl(this.primary);
|
new BaritoneChatControl(this.primary);
|
||||||
@@ -54,7 +56,12 @@ public final class BaritoneProvider implements IBaritoneProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IBaritone> getAllBaritones() {
|
public List<IBaritone> getAllBaritones() {
|
||||||
return all;
|
List<IBaritone> baritones = new ArrayList<>();
|
||||||
|
baritones.add(getPrimaryBaritone());
|
||||||
|
for (IBaritoneUser ibu : UserManager.INSTANCE.users()) {
|
||||||
|
baritones.add(ibu.getBaritone());
|
||||||
|
}
|
||||||
|
return baritones;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -62,6 +69,11 @@ public final class BaritoneProvider implements IBaritoneProvider {
|
|||||||
return WorldScanner.INSTANCE;
|
return WorldScanner.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IUserManager getUserManager() {
|
||||||
|
return UserManager.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICommandSystem getCommandSystem() {
|
public ICommandSystem getCommandSystem() {
|
||||||
return CommandSystem.INSTANCE;
|
return CommandSystem.INSTANCE;
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public final class InventoryBehavior extends Behavior {
|
|||||||
|
|
||||||
public boolean selectThrowawayForLocation(boolean select, int x, int y, int z) {
|
public boolean selectThrowawayForLocation(boolean select, int x, int y, int z) {
|
||||||
IBlockState maybe = baritone.getBuilderProcess().placeAt(x, y, z, baritone.bsi.get0(x, y, z));
|
IBlockState maybe = baritone.getBuilderProcess().placeAt(x, y, z, baritone.bsi.get0(x, y, z));
|
||||||
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && maybe.equals(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(new BlockItemUseContext(new ItemUseContext(ctx.player(), stack, ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ)))))) {
|
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && maybe.equals(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(ctx.world(), ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ, stack.getItem().getMetadata(stack.getMetadata()), ctx.player())))) {
|
||||||
return true; // gotem
|
return true; // gotem
|
||||||
}
|
}
|
||||||
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && ((ItemBlock) stack.getItem()).getBlock().equals(maybe.getBlock()))) {
|
if (maybe != null && throwaway(select, stack -> stack.getItem() instanceof ItemBlock && ((ItemBlock) stack.getItem()).getBlock().equals(maybe.getBlock()))) {
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Target's values are as follows:
|
* Target's values are as follows:
|
||||||
|
* <p>
|
||||||
|
* getFirst() -> yaw
|
||||||
|
* getSecond() -> pitch
|
||||||
*/
|
*/
|
||||||
private Rotation target;
|
private Rotation target;
|
||||||
|
|
||||||
@@ -50,13 +53,6 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
|
|||||||
@Override
|
@Override
|
||||||
public void updateTarget(Rotation target, boolean force) {
|
public void updateTarget(Rotation target, boolean force) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
if (!force) {
|
|
||||||
double rand = Math.random() - 0.5;
|
|
||||||
if (Math.abs(rand) < 0.1) {
|
|
||||||
rand *= 4;
|
|
||||||
}
|
|
||||||
this.target = new Rotation(this.target.getYaw() + (float) (rand * Baritone.settings().randomLooking113.value), this.target.getPitch());
|
|
||||||
}
|
|
||||||
this.force = force || !Baritone.settings().freeLook.value;
|
this.force = force || !Baritone.settings().freeLook.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import net.minecraft.block.BlockBed;
|
|||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
|
import net.minecraft.network.play.client.CPacketClickWindow;
|
||||||
import net.minecraft.network.play.client.CPacketCloseWindow;
|
import net.minecraft.network.play.client.CPacketCloseWindow;
|
||||||
import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock;
|
import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock;
|
||||||
import net.minecraft.network.play.server.SPacketCloseWindow;
|
import net.minecraft.network.play.server.SPacketCloseWindow;
|
||||||
@@ -117,6 +118,11 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
if (p instanceof CPacketCloseWindow) {
|
if (p instanceof CPacketCloseWindow) {
|
||||||
getCurrent().save();
|
getCurrent().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p instanceof CPacketClickWindow) {
|
||||||
|
CPacketClickWindow c = event.cast();
|
||||||
|
System.out.println("CLICK " + c.getWindowId() + " " + c.getSlotId() + " " + c.getUsedButton() + " " + c.getClickType());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,9 +160,21 @@ public final class MemoryBehavior extends Behavior {
|
|||||||
if (p instanceof SPacketCloseWindow) {
|
if (p instanceof SPacketCloseWindow) {
|
||||||
getCurrent().save();
|
getCurrent().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apparently doesn't happen
|
||||||
|
/*if (p instanceof SPacketWindowItems) {
|
||||||
|
SPacketWindowItems meme = (SPacketWindowItems) p;
|
||||||
|
if (meme.getWindowId() == ctx.player().openContainer.windowId && enderChestWindowId != null && meme.getWindowId() == enderChestWindowId) {
|
||||||
|
System.out.println("RECEIVED GUARANTEED ECHEST CONTENTS" + meme.getItemStacks());
|
||||||
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean eChestOpen() {
|
||||||
|
return enderChestWindowId != null && ctx.player().openContainer.windowId == enderChestWindowId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockInteract(BlockInteractEvent event) {
|
public void onBlockInteract(BlockInteractEvent event) {
|
||||||
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
|
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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.bot;
|
||||||
|
|
||||||
|
import baritone.Baritone;
|
||||||
|
import baritone.api.IBaritone;
|
||||||
|
import baritone.api.bot.IBaritoneUser;
|
||||||
|
import baritone.api.bot.IUserManager;
|
||||||
|
import baritone.api.utils.IPlayerController;
|
||||||
|
import baritone.bot.spec.BotWorld;
|
||||||
|
import baritone.bot.spec.EntityBot;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import net.minecraft.network.NetworkManager;
|
||||||
|
import net.minecraft.network.play.INetHandlerPlayClient;
|
||||||
|
import net.minecraft.util.Session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link IBaritoneUser}
|
||||||
|
*
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/6/2018
|
||||||
|
*/
|
||||||
|
public class BaritoneUser implements IBaritoneUser {
|
||||||
|
|
||||||
|
private final UserManager manager;
|
||||||
|
private final NetworkManager networkManager;
|
||||||
|
private final Session session;
|
||||||
|
|
||||||
|
private GameProfile profile;
|
||||||
|
private INetHandlerPlayClient netHandlerPlayClient;
|
||||||
|
|
||||||
|
private BotWorld world;
|
||||||
|
private EntityBot player;
|
||||||
|
private IPlayerController playerController;
|
||||||
|
|
||||||
|
private final Baritone baritone;
|
||||||
|
|
||||||
|
BaritoneUser(UserManager manager, NetworkManager networkManager, Session session) {
|
||||||
|
this.manager = manager;
|
||||||
|
this.networkManager = networkManager;
|
||||||
|
this.session = session;
|
||||||
|
this.baritone = new Baritone(new BotPlayerContext(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLoginSuccess(GameProfile profile, INetHandlerPlayClient netHandlerPlayClient) {
|
||||||
|
this.profile = profile;
|
||||||
|
this.netHandlerPlayClient = netHandlerPlayClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onWorldLoad(BotWorld world, EntityBot player, IPlayerController playerController) {
|
||||||
|
this.world = world;
|
||||||
|
this.player = player;
|
||||||
|
this.playerController = playerController;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NetworkManager getNetworkManager() {
|
||||||
|
return this.networkManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public INetHandlerPlayClient getConnection() {
|
||||||
|
return this.netHandlerPlayClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityBot getEntity() {
|
||||||
|
return this.player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPlayerController getPlayerController() {
|
||||||
|
return this.playerController;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Session getSession() {
|
||||||
|
return this.session;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GameProfile getProfile() {
|
||||||
|
return this.profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserManager getManager() {
|
||||||
|
return this.manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBaritone getBaritone() {
|
||||||
|
return baritone;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.bot;
|
||||||
|
|
||||||
|
import baritone.api.bot.IBaritoneUser;
|
||||||
|
import baritone.api.cache.IWorldData;
|
||||||
|
import baritone.api.utils.IPlayerContext;
|
||||||
|
import baritone.api.utils.IPlayerController;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class BotPlayerContext implements IPlayerContext {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The backing {@link IBaritoneUser}
|
||||||
|
*/
|
||||||
|
private final IBaritoneUser bot;
|
||||||
|
|
||||||
|
public BotPlayerContext(IBaritoneUser bot) {
|
||||||
|
this.bot = bot;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityPlayerSP player() {
|
||||||
|
if (bot.getEntity() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return bot.getEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPlayerController playerController() {
|
||||||
|
if (bot.getEntity() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return bot.getPlayerController();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public World world() {
|
||||||
|
if (bot.getEntity() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return bot.getEntity().world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IWorldData worldData() {
|
||||||
|
return bot.getBaritone().getWorldProvider().getCurrentWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RayTraceResult objectMouseOver() {
|
||||||
|
Entity entity = this.bot.getEntity();
|
||||||
|
|
||||||
|
if (entity != null) {
|
||||||
|
double blockReachDistance = this.bot.getPlayerController().getBlockReachDistance();
|
||||||
|
return entity.rayTrace(blockReachDistance, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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.bot;
|
||||||
|
|
||||||
|
import baritone.bot.spec.BotWorld;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import net.minecraft.world.GameType;
|
||||||
|
import net.minecraft.world.WorldSettings;
|
||||||
|
import net.minecraft.world.WorldType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/7/2018
|
||||||
|
*/
|
||||||
|
public class BotWorldProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic world settings for a typical survival world.
|
||||||
|
*/
|
||||||
|
private static final WorldSettings GENERIC_WORLD_SETTINGS = new WorldSettings(0L, GameType.SURVIVAL, true, false, WorldType.DEFAULT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All of the dimensions mapped to their respective worlds.
|
||||||
|
*/
|
||||||
|
private final Int2ObjectMap<BotWorld> worlds = new Int2ObjectArrayMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets or creates the {@link BotWorld} for the specified dimension
|
||||||
|
*
|
||||||
|
* @param dimension The dimension id
|
||||||
|
* @return The world
|
||||||
|
*/
|
||||||
|
public BotWorld getWorld(int dimension) {
|
||||||
|
return worlds.computeIfAbsent(dimension, this::createWorldForDim);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link BotWorld} for the given dimension id.
|
||||||
|
*
|
||||||
|
* @param dimension The dimension id
|
||||||
|
* @return The new world
|
||||||
|
*/
|
||||||
|
private BotWorld createWorldForDim(int dimension) {
|
||||||
|
return new BotWorld(GENERIC_WORLD_SETTINGS, dimension);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
this.worlds.forEach((dim, world) -> world.updateEntities());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
* 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.bot;
|
||||||
|
|
||||||
|
import baritone.api.BaritoneAPI;
|
||||||
|
import baritone.api.bot.IBaritoneUser;
|
||||||
|
import baritone.api.bot.IUserManager;
|
||||||
|
import baritone.api.bot.connect.IConnectionResult;
|
||||||
|
import baritone.api.event.events.TickEvent;
|
||||||
|
import baritone.api.event.events.type.EventState;
|
||||||
|
import baritone.api.event.listener.AbstractGameEventListener;
|
||||||
|
import baritone.api.utils.Helper;
|
||||||
|
import baritone.bot.connect.ConnectionResult;
|
||||||
|
import baritone.bot.handler.BotNetHandlerLoginClient;
|
||||||
|
import net.minecraft.client.multiplayer.ServerAddress;
|
||||||
|
import net.minecraft.client.multiplayer.ServerData;
|
||||||
|
import net.minecraft.network.EnumConnectionState;
|
||||||
|
import net.minecraft.network.NetworkManager;
|
||||||
|
import net.minecraft.network.handshake.client.C00Handshake;
|
||||||
|
import net.minecraft.network.login.client.CPacketLoginStart;
|
||||||
|
import net.minecraft.util.Session;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
import static baritone.api.bot.connect.ConnectionStatus.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/6/2018
|
||||||
|
*/
|
||||||
|
public final class UserManager implements IUserManager, Helper {
|
||||||
|
|
||||||
|
public static final UserManager INSTANCE = new UserManager();
|
||||||
|
|
||||||
|
private final List<IBaritoneUser> users = new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
private final BotWorldProvider worldProvider;
|
||||||
|
|
||||||
|
private UserManager() {
|
||||||
|
// Setup an event listener that automatically disconnects bots when we're not in-game
|
||||||
|
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().registerEventListener(new AbstractGameEventListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onTick(TickEvent event) {
|
||||||
|
if (event.getState() == EventState.PRE) {
|
||||||
|
if (event.getType() == TickEvent.Type.OUT)
|
||||||
|
UserManager.this.users.forEach(UserManager.this::disconnect);
|
||||||
|
|
||||||
|
UserManager.this.worldProvider.tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.worldProvider = new BotWorldProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects a new user with the specified {@link Session} to the current server.
|
||||||
|
*
|
||||||
|
* @param session The user session
|
||||||
|
* @return The result of the attempted connection
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final IConnectionResult connect(Session session) {
|
||||||
|
ServerData data = mc.getCurrentServerData();
|
||||||
|
if (data == null) {
|
||||||
|
return ConnectionResult.failed(NO_CURRENT_CONNECTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to the server from the parsed server data
|
||||||
|
return connect0(session, ServerAddress.fromString(data.serverIP));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects a new user with the specified {@link Session} to the specified server.
|
||||||
|
* <p>
|
||||||
|
* Hi Mickey :)
|
||||||
|
*
|
||||||
|
* @param session The user session
|
||||||
|
* @param address The address of the server to connect to
|
||||||
|
* @return The result of the attempted connection
|
||||||
|
*/
|
||||||
|
private IConnectionResult connect0(Session session, ServerAddress address) {
|
||||||
|
InetAddress inetAddress;
|
||||||
|
|
||||||
|
try {
|
||||||
|
inetAddress = InetAddress.getByName(address.getIP());
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
return ConnectionResult.failed(CANT_RESOLVE_HOST);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Initialize Connection
|
||||||
|
NetworkManager networkManager = NetworkManager.createNetworkManagerAndConnect(
|
||||||
|
inetAddress,
|
||||||
|
address.getPort(),
|
||||||
|
mc.gameSettings.isUsingNativeTransport()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create User
|
||||||
|
BaritoneUser user = new BaritoneUser(this, networkManager, session);
|
||||||
|
this.users.add(user);
|
||||||
|
|
||||||
|
// Setup login handler and send connection packets
|
||||||
|
networkManager.setNetHandler(new BotNetHandlerLoginClient(networkManager, user));
|
||||||
|
networkManager.sendPacket(new C00Handshake(address.getIP(), address.getPort(), EnumConnectionState.LOGIN));
|
||||||
|
networkManager.sendPacket(new CPacketLoginStart(session.getProfile()));
|
||||||
|
|
||||||
|
return ConnectionResult.success(user);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ConnectionResult.failed(CONNECTION_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the manager of an {@link IBaritoneUser} disconnect, and
|
||||||
|
* removes the {@link IBaritoneUser} from the list of users.
|
||||||
|
*
|
||||||
|
* @param user The user that disconnected
|
||||||
|
* @param state The connection state at the time of disconnect
|
||||||
|
*/
|
||||||
|
public final void notifyDisconnect(IBaritoneUser user, EnumConnectionState state) {
|
||||||
|
this.users.remove(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The bot world provider
|
||||||
|
*/
|
||||||
|
public final BotWorldProvider getWorldProvider() {
|
||||||
|
return this.worldProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void disconnect(IBaritoneUser user) {
|
||||||
|
// It's probably fine to pass null to this, because the handlers aren't doing anything with it
|
||||||
|
// noinspection ConstantConditions
|
||||||
|
user.getNetworkManager().closeChannel(null);
|
||||||
|
this.users.remove(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final List<IBaritoneUser> users() {
|
||||||
|
return Collections.unmodifiableList(this.users);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* 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.bot.connect;
|
||||||
|
|
||||||
|
import baritone.api.bot.IBaritoneUser;
|
||||||
|
import baritone.api.bot.connect.ConnectionStatus;
|
||||||
|
import baritone.api.bot.connect.IConnectionResult;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static baritone.api.bot.connect.ConnectionStatus.SUCCESS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/6/2018
|
||||||
|
*/
|
||||||
|
public final class ConnectionResult implements IConnectionResult {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The result status
|
||||||
|
*/
|
||||||
|
private final ConnectionStatus status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user created, if the status is {@link ConnectionStatus#SUCCESS}
|
||||||
|
*/
|
||||||
|
private final IBaritoneUser user;
|
||||||
|
|
||||||
|
private ConnectionResult(ConnectionStatus status, IBaritoneUser user) {
|
||||||
|
this.status = status;
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConnectionStatus getStatus() {
|
||||||
|
return this.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<IBaritoneUser> getUser() {
|
||||||
|
return Optional.ofNullable(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new failed {@link ConnectionResult}.
|
||||||
|
*
|
||||||
|
* @param status The failed connection status
|
||||||
|
* @return The connection result
|
||||||
|
* @throws IllegalArgumentException if {@code status} is {@link ConnectionStatus#SUCCESS}
|
||||||
|
*/
|
||||||
|
public static ConnectionResult failed(ConnectionStatus status) {
|
||||||
|
if (status == SUCCESS) {
|
||||||
|
throw new IllegalArgumentException("Status must be a failure type");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ConnectionResult(status, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new success {@link ConnectionResult}.
|
||||||
|
*
|
||||||
|
* @param user The user created
|
||||||
|
* @return The connection result
|
||||||
|
* @throws IllegalArgumentException if {@code user} is {@code null}
|
||||||
|
*/
|
||||||
|
public static ConnectionResult success(IBaritoneUser user) {
|
||||||
|
Objects.requireNonNull(user);
|
||||||
|
|
||||||
|
return new ConnectionResult(SUCCESS, user);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* 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.bot.handler;
|
||||||
|
|
||||||
|
import baritone.bot.BaritoneUser;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import com.mojang.authlib.exceptions.AuthenticationException;
|
||||||
|
import com.mojang.authlib.exceptions.AuthenticationUnavailableException;
|
||||||
|
import com.mojang.authlib.exceptions.InvalidCredentialsException;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.network.NetHandlerLoginClient;
|
||||||
|
import net.minecraft.network.EnumConnectionState;
|
||||||
|
import net.minecraft.network.NetworkManager;
|
||||||
|
import net.minecraft.network.login.client.CPacketEncryptionResponse;
|
||||||
|
import net.minecraft.network.login.server.SPacketEncryptionRequest;
|
||||||
|
import net.minecraft.network.login.server.SPacketLoginSuccess;
|
||||||
|
import net.minecraft.util.CryptManager;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraft.util.text.TextComponentTranslation;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the login stage when connecting to a server.
|
||||||
|
*
|
||||||
|
* @author Brady
|
||||||
|
* @since 10/29/2018
|
||||||
|
*/
|
||||||
|
public class BotNetHandlerLoginClient extends NetHandlerLoginClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link NetworkManager} that is managing the connection with the server.
|
||||||
|
*/
|
||||||
|
private final NetworkManager networkManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Minecraft} game instance
|
||||||
|
*/
|
||||||
|
private final Minecraft mc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bot of this connection
|
||||||
|
*/
|
||||||
|
private final BaritoneUser user;
|
||||||
|
|
||||||
|
public BotNetHandlerLoginClient(NetworkManager networkManager, BaritoneUser user) {
|
||||||
|
super(networkManager, Minecraft.getMinecraft(), null);
|
||||||
|
this.networkManager = networkManager;
|
||||||
|
this.mc = Minecraft.getMinecraft();
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEncryptionRequest(SPacketEncryptionRequest packetIn) {
|
||||||
|
SecretKey secretkey = CryptManager.createNewSharedKey();
|
||||||
|
PublicKey publicKey = packetIn.getPublicKey();
|
||||||
|
|
||||||
|
// Setup joinServer payload info
|
||||||
|
GameProfile profile = this.user.getSession().getProfile();
|
||||||
|
String authenticationToken = this.user.getSession().getToken();
|
||||||
|
String serverId = new BigInteger(CryptManager.getServerIdHash(packetIn.getServerId(), publicKey, secretkey)).toString(16);
|
||||||
|
|
||||||
|
if (this.mc.getCurrentServerData() != null && this.mc.getCurrentServerData().isOnLAN()) {
|
||||||
|
try {
|
||||||
|
this.mc.getSessionService().joinServer(profile, authenticationToken, serverId);
|
||||||
|
} catch (AuthenticationException e) {
|
||||||
|
// Couldn't connect to auth servers but will continue to join LAN
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
this.mc.getSessionService().joinServer(profile, authenticationToken, serverId);
|
||||||
|
} catch (AuthenticationUnavailableException e) {
|
||||||
|
this.networkManager.closeChannel(new TextComponentTranslation("disconnect.loginFailedInfo", new TextComponentTranslation("disconnect.loginFailedInfo.serversUnavailable")));
|
||||||
|
return;
|
||||||
|
} catch (InvalidCredentialsException e) {
|
||||||
|
this.networkManager.closeChannel(new TextComponentTranslation("disconnect.loginFailedInfo", new TextComponentTranslation("disconnect.loginFailedInfo.invalidSession")));
|
||||||
|
return;
|
||||||
|
} catch (AuthenticationException e) {
|
||||||
|
this.networkManager.closeChannel(new TextComponentTranslation("disconnect.loginFailedInfo", e.getMessage()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// noinspection unchecked
|
||||||
|
this.networkManager.sendPacket(new CPacketEncryptionResponse(secretkey, publicKey, packetIn.getVerifyToken()),
|
||||||
|
future -> BotNetHandlerLoginClient.this.networkManager.enableEncryption(secretkey));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleLoginSuccess(SPacketLoginSuccess packetIn) {
|
||||||
|
this.networkManager.setConnectionState(EnumConnectionState.PLAY);
|
||||||
|
this.networkManager.setNetHandler(new BotNetHandlerPlayClient(this.networkManager, this.user, Minecraft.getMinecraft(), packetIn.getProfile()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnect(@Nonnull ITextComponent reason) {
|
||||||
|
// It's important that we don't call the superclass method because that would mess up GUIs and make us upset
|
||||||
|
this.user.getManager().notifyDisconnect(this.user, EnumConnectionState.LOGIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,706 @@
|
|||||||
|
/*
|
||||||
|
* 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.bot.handler;
|
||||||
|
|
||||||
|
import baritone.api.utils.Helper;
|
||||||
|
import baritone.bot.BaritoneUser;
|
||||||
|
import baritone.bot.spec.BotPlayerController;
|
||||||
|
import baritone.bot.spec.BotWorld;
|
||||||
|
import baritone.bot.spec.EntityBot;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.client.multiplayer.ClientAdvancementManager;
|
||||||
|
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||||
|
import net.minecraft.client.util.RecipeBookClient;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
|
import net.minecraft.entity.player.PlayerCapabilities;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.network.EnumConnectionState;
|
||||||
|
import net.minecraft.network.NetworkManager;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.network.PacketThreadUtil;
|
||||||
|
import net.minecraft.network.play.INetHandlerPlayClient;
|
||||||
|
import net.minecraft.network.play.client.*;
|
||||||
|
import net.minecraft.network.play.server.*;
|
||||||
|
import net.minecraft.potion.Potion;
|
||||||
|
import net.minecraft.potion.PotionEffect;
|
||||||
|
import net.minecraft.stats.StatisticsManager;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
|
import net.minecraft.util.EnumHandSide;
|
||||||
|
import net.minecraft.util.IThreadListener;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraft.world.Explosion;
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
// Notes
|
||||||
|
// - Make some sort of system that prevents repetition of entity info updating
|
||||||
|
// - For some packets, such as ones that modify position, we can check if the existing server state matches the packet proposed state
|
||||||
|
// - For other things, we'll actually need the system
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class would effectively operate the same if we directly implemented {@link INetHandlerPlayClient},
|
||||||
|
* however, the {@link EntityPlayerSP} constructor requires an actual implementation of
|
||||||
|
* {@link NetHandlerPlayClient} in order to access the {@link GameProfile}.
|
||||||
|
*
|
||||||
|
* @author Brady
|
||||||
|
* @since 10/22/2018
|
||||||
|
*/
|
||||||
|
public class BotNetHandlerPlayClient extends NetHandlerPlayClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link NetworkManager} that is managing the connection with the server.
|
||||||
|
*/
|
||||||
|
private final NetworkManager networkManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the {@link Minecraft} game instance, however, to prevent unwanted references
|
||||||
|
* to the game instance fields, we refer to it as a {@link IThreadListener}.
|
||||||
|
*/
|
||||||
|
private final IThreadListener client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bot of this connection
|
||||||
|
*/
|
||||||
|
private final BaritoneUser user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bot entity
|
||||||
|
*/
|
||||||
|
private EntityBot player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current world.
|
||||||
|
*/
|
||||||
|
private BotWorld world;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current player controller
|
||||||
|
*/
|
||||||
|
private BotPlayerController playerController;
|
||||||
|
|
||||||
|
public BotNetHandlerPlayClient(NetworkManager networkManager, BaritoneUser user, Minecraft client, GameProfile profile) {
|
||||||
|
// noinspection ConstantConditions
|
||||||
|
super(client, null, networkManager, profile);
|
||||||
|
this.networkManager = networkManager;
|
||||||
|
this.client = client;
|
||||||
|
this.user = user;
|
||||||
|
|
||||||
|
// Notify the user that we're ingame
|
||||||
|
this.user.onLoginSuccess(profile, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSpawnObject(@Nonnull SPacketSpawnObject packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSpawnExperienceOrb(@Nonnull SPacketSpawnExperienceOrb packetIn) { /* We will want to know this if we want Tenor to collect XP */ }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSpawnGlobalEntity(@Nonnull SPacketSpawnGlobalEntity packetIn) { /* Only lightning bolts, this may change in the future */ }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSpawnMob(@Nonnull SPacketSpawnMob packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleScoreboardObjective(@Nonnull SPacketScoreboardObjective packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSpawnPainting(@Nonnull SPacketSpawnPainting packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSpawnPlayer(@Nonnull SPacketSpawnPlayer packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleAnimation(@Nonnull SPacketAnimation packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
Entity entity = this.world.getEntityByID(packetIn.getEntityID());
|
||||||
|
if (entity != null) {
|
||||||
|
switch (packetIn.getAnimationType()) {
|
||||||
|
case 0: {
|
||||||
|
((EntityLivingBase) entity).swingArm(EnumHand.MAIN_HAND);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
entity.performHurtAnimation();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
((EntityPlayer) entity).wakeUpPlayer(false, false, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
((EntityLivingBase) entity).swingArm(EnumHand.OFF_HAND);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleStatistics(@Nonnull SPacketStatistics packetIn) { /* Lol global bot stats when?? */ }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleRecipeBook(@Nonnull SPacketRecipeBook packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleBlockBreakAnim(@Nonnull SPacketBlockBreakAnim packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSignEditorOpen(@Nonnull SPacketSignEditorOpen packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleUpdateTileEntity(@Nonnull SPacketUpdateTileEntity packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleBlockAction(@Nonnull SPacketBlockAction packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleBlockChange(@Nonnull SPacketBlockChange packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
this.world.setBlockState(packetIn.getBlockPosition(), packetIn.getBlockState());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleChat(@Nonnull SPacketChat packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleTabComplete(@Nonnull SPacketTabComplete packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMultiBlockChange(@Nonnull SPacketMultiBlockChange packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
for (SPacketMultiBlockChange.BlockUpdateData data : packetIn.getChangedBlocks()) {
|
||||||
|
this.world.setBlockState(data.getPos(), data.getBlockState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMaps(@Nonnull SPacketMaps packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleConfirmTransaction(@Nonnull SPacketConfirmTransaction packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCloseWindow(@Nonnull SPacketCloseWindow packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
this.player.closeScreenAndDropStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleWindowItems(@Nonnull SPacketWindowItems packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
(packetIn.getWindowId() == 0 ? this.player.inventoryContainer : this.player.openContainer).setAll(packetIn.getItemStacks());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleOpenWindow(@Nonnull SPacketOpenWindow packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleWindowProperty(@Nonnull SPacketWindowProperty packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSetSlot(@Nonnull SPacketSetSlot packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
ItemStack stack = packetIn.getStack();
|
||||||
|
int slot = packetIn.getSlot();
|
||||||
|
|
||||||
|
switch (packetIn.getWindowId()) {
|
||||||
|
case -1: {
|
||||||
|
this.player.inventory.setItemStack(stack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case -2: {
|
||||||
|
this.player.inventory.setInventorySlotContents(slot, stack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
if (packetIn.getWindowId() == 0 && packetIn.getSlot() >= 36 && slot < 45) {
|
||||||
|
this.player.inventoryContainer.putStackInSlot(slot, stack);
|
||||||
|
} else if (packetIn.getWindowId() == this.player.openContainer.windowId && packetIn.getWindowId() != 0) {
|
||||||
|
this.player.openContainer.putStackInSlot(slot, stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCustomPayload(@Nonnull SPacketCustomPayload packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleDisconnect(@Nonnull SPacketDisconnect packetIn) {
|
||||||
|
this.networkManager.closeChannel(packetIn.getReason());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleUseBed(@Nonnull SPacketUseBed packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEntityStatus(@Nonnull SPacketEntityStatus packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEntityAttach(@Nonnull SPacketEntityAttach packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSetPassengers(@Nonnull SPacketSetPassengers packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleExplosion(@Nonnull SPacketExplosion packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
// noinspection ConstantConditions
|
||||||
|
new Explosion(this.world, null, packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getStrength(), packetIn.getAffectedBlockPositions()).doExplosionB(true);
|
||||||
|
this.player.motionX += (double) packetIn.getMotionX();
|
||||||
|
this.player.motionY += (double) packetIn.getMotionY();
|
||||||
|
this.player.motionZ += (double) packetIn.getMotionZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleChangeGameState(@Nonnull SPacketChangeGameState packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleKeepAlive(@Nonnull SPacketKeepAlive packetIn) {
|
||||||
|
this.networkManager.sendPacket(new CPacketKeepAlive(packetIn.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleChunkData(@Nonnull SPacketChunkData packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
if (packetIn.isFullChunk()) {
|
||||||
|
this.world.doPreChunk(packetIn.getChunkX(), packetIn.getChunkZ(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Chunk chunk = this.world.getChunk(packetIn.getChunkX(), packetIn.getChunkZ());
|
||||||
|
chunk.read(packetIn.getReadBuffer(), packetIn.getExtractedSize(), packetIn.isFullChunk());
|
||||||
|
|
||||||
|
for (NBTTagCompound tag : packetIn.getTileEntityTags()) {
|
||||||
|
BlockPos pos = new BlockPos(tag.getInteger("x"), tag.getInteger("y"), tag.getInteger("z"));
|
||||||
|
TileEntity tileEntity = this.world.getTileEntity(pos);
|
||||||
|
|
||||||
|
if (tileEntity != null) {
|
||||||
|
tileEntity.readFromNBT(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processChunkUnload(@Nonnull SPacketUnloadChunk packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
// TODO Unload chunks
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEffect(@Nonnull SPacketEffect packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleJoinGame(@Nonnull SPacketJoinGame packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
this.playerController = new BotPlayerController(this.user);
|
||||||
|
this.world = this.user.getManager().getWorldProvider().getWorld(packetIn.getDimension());
|
||||||
|
this.player = new EntityBot(this.user, (Minecraft) this.client, this.world, this, new StatisticsManager(), new RecipeBookClient());
|
||||||
|
this.user.onWorldLoad(this.world, this.player, this.playerController);
|
||||||
|
this.player.preparePlayerToSpawn();
|
||||||
|
this.world.spawnEntity(this.player);
|
||||||
|
this.player.setEntityId(packetIn.getPlayerId());
|
||||||
|
this.player.dimension = packetIn.getDimension();
|
||||||
|
this.playerController.setGameType(packetIn.getGameType());
|
||||||
|
packetIn.getGameType().configurePlayerCapabilities(this.player.capabilities);
|
||||||
|
|
||||||
|
this.networkManager.sendPacket(new CPacketClientSettings("en_us", 8, EntityPlayer.EnumChatVisibility.FULL, true, 0, EnumHandSide.RIGHT));
|
||||||
|
this.networkManager.sendPacket(new CPacketCustomPayload("MC|Brand", new PacketBuffer(Unpooled.buffer()).writeString("vanilla")));
|
||||||
|
|
||||||
|
this.world.registerBot(packetIn.getPlayerId(), this.player);
|
||||||
|
|
||||||
|
Helper.HELPER.logDirect("Initialized Player and World");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEntityMovement(@Nonnull SPacketEntity packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handlePlayerPosLook(@Nonnull SPacketPlayerPosLook packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
EntityPlayer player = this.player;
|
||||||
|
double d0 = packetIn.getX();
|
||||||
|
double d1 = packetIn.getY();
|
||||||
|
double d2 = packetIn.getZ();
|
||||||
|
float f = packetIn.getYaw();
|
||||||
|
float f1 = packetIn.getPitch();
|
||||||
|
|
||||||
|
if (packetIn.getFlags().contains(SPacketPlayerPosLook.EnumFlags.X)) {
|
||||||
|
d0 += player.posX;
|
||||||
|
} else {
|
||||||
|
player.motionX = 0.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packetIn.getFlags().contains(SPacketPlayerPosLook.EnumFlags.Y)) {
|
||||||
|
d1 += player.posY;
|
||||||
|
} else {
|
||||||
|
player.motionY = 0.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packetIn.getFlags().contains(SPacketPlayerPosLook.EnumFlags.Z)) {
|
||||||
|
d2 += player.posZ;
|
||||||
|
} else {
|
||||||
|
player.motionZ = 0.0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packetIn.getFlags().contains(SPacketPlayerPosLook.EnumFlags.X_ROT)) {
|
||||||
|
f1 += player.rotationPitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packetIn.getFlags().contains(SPacketPlayerPosLook.EnumFlags.Y_ROT)) {
|
||||||
|
f += player.rotationYaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.setPositionAndRotation(d0, d1, d2, f, f1);
|
||||||
|
this.networkManager.sendPacket(new CPacketConfirmTeleport(packetIn.getTeleportId()));
|
||||||
|
this.networkManager.sendPacket(new CPacketPlayer.PositionRotation(player.posX, player.getEntityBoundingBox().minY, player.posZ, player.rotationYaw, player.rotationPitch, false));
|
||||||
|
|
||||||
|
this.player.prevPosX = this.player.posX;
|
||||||
|
this.player.prevPosY = this.player.posY;
|
||||||
|
this.player.prevPosZ = this.player.posZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleParticles(@Nonnull SPacketParticles packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handlePlayerAbilities(@Nonnull SPacketPlayerAbilities packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
PlayerCapabilities c = this.player.capabilities;
|
||||||
|
c.disableDamage = packetIn.isInvulnerable();
|
||||||
|
c.isFlying = packetIn.isFlying();
|
||||||
|
c.allowFlying = packetIn.isAllowFlying();
|
||||||
|
c.isCreativeMode = packetIn.isCreativeMode();
|
||||||
|
c.setFlySpeed(packetIn.getFlySpeed());
|
||||||
|
c.setPlayerWalkSpeed(packetIn.getWalkSpeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handlePlayerListItem(@Nonnull SPacketPlayerListItem packetIn) {
|
||||||
|
// okay now this is awesome
|
||||||
|
super.handlePlayerListItem(packetIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleDestroyEntities(@Nonnull SPacketDestroyEntities packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
for (int i = 0; i < packetIn.getEntityIDs().length; ++i) {
|
||||||
|
this.world.removeEntityFromWorld(packetIn.getEntityIDs()[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleRemoveEntityEffect(@Nonnull SPacketRemoveEntityEffect packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
Entity entity = packetIn.getEntity(this.world);
|
||||||
|
if (entity instanceof EntityLivingBase) {
|
||||||
|
((EntityLivingBase) entity).removeActivePotionEffect(packetIn.getPotion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleRespawn(@Nonnull SPacketRespawn packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
if (packetIn.getDimensionID() != this.player.dimension) {
|
||||||
|
this.world.removeEntity(this.player);
|
||||||
|
this.world = this.user.getManager().getWorldProvider().getWorld(packetIn.getDimensionID());
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityBot prev = this.player;
|
||||||
|
|
||||||
|
this.player = new EntityBot(this.user, (Minecraft) this.client, this.world, this, prev.getStatFileWriter(), prev.getRecipeBook());
|
||||||
|
this.user.onWorldLoad(this.world, this.player, this.playerController);
|
||||||
|
// noinspection ConstantConditions
|
||||||
|
this.player.getDataManager().setEntryValues(prev.getDataManager().getAll());
|
||||||
|
this.player.preparePlayerToSpawn();
|
||||||
|
this.world.spawnEntity(this.player);
|
||||||
|
this.player.setEntityId(prev.getEntityId());
|
||||||
|
this.player.dimension = packetIn.getDimensionID();
|
||||||
|
this.player.setServerBrand(prev.getServerBrand());
|
||||||
|
this.playerController.setGameType(packetIn.getGameType());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEntityHeadLook(@Nonnull SPacketEntityHeadLook packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleHeldItemChange(@Nonnull SPacketHeldItemChange packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
if (InventoryPlayer.isHotbar(packetIn.getHeldItemHotbarIndex())) {
|
||||||
|
this.player.inventory.currentItem = packetIn.getHeldItemHotbarIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleDisplayObjective(@Nonnull SPacketDisplayObjective packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEntityMetadata(@Nonnull SPacketEntityMetadata packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
Entity entity = this.world.getEntityByID(packetIn.getEntityId());
|
||||||
|
if (entity != null && packetIn.getDataManagerEntries() != null) {
|
||||||
|
entity.getDataManager().setEntryValues(packetIn.getDataManagerEntries());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEntityVelocity(@Nonnull SPacketEntityVelocity packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
Entity entity = this.world.getEntityByID(packetIn.getEntityID());
|
||||||
|
if (entity != null) {
|
||||||
|
entity.setVelocity(
|
||||||
|
(double) packetIn.getMotionX() / 8000.0D,
|
||||||
|
(double) packetIn.getMotionY() / 8000.0D,
|
||||||
|
(double) packetIn.getMotionZ() / 8000.0D
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEntityEquipment(@Nonnull SPacketEntityEquipment packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
Entity entity = this.world.getEntityByID(packetIn.getEntityID());
|
||||||
|
if (entity != null) {
|
||||||
|
entity.setItemStackToSlot(packetIn.getEquipmentSlot(), packetIn.getItemStack());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSetExperience(@Nonnull SPacketSetExperience packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
this.player.setXPStats(packetIn.getExperienceBar(), packetIn.getTotalExperience(), packetIn.getLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleUpdateHealth(@Nonnull SPacketUpdateHealth packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
this.player.setPlayerSPHealth(packetIn.getHealth());
|
||||||
|
this.player.getFoodStats().setFoodLevel(packetIn.getFoodLevel());
|
||||||
|
this.player.getFoodStats().setFoodSaturationLevel(packetIn.getSaturationLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleTeams(@Nonnull SPacketTeams packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleUpdateScore(@Nonnull SPacketUpdateScore packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSpawnPosition(@Nonnull SPacketSpawnPosition packetIn) { /* We probably don't need to know this, the server handles everything related to spawn psoition? */ }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleTimeUpdate(@Nonnull SPacketTimeUpdate packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
this.world.setTotalWorldTime(packetIn.getTotalWorldTime());
|
||||||
|
this.world.setWorldTime(packetIn.getWorldTime());
|
||||||
|
|
||||||
|
// TODO: Calculate World TPS
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSoundEffect(@Nonnull SPacketSoundEffect packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCustomSound(@Nonnull SPacketCustomSound packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCollectItem(@Nonnull SPacketCollectItem packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEntityTeleport(@Nonnull SPacketEntityTeleport packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEntityProperties(@Nonnull SPacketEntityProperties packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEntityEffect(@Nonnull SPacketEntityEffect packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
Entity entity = this.world.getEntityByID(packetIn.getEntityId());
|
||||||
|
|
||||||
|
if (entity instanceof EntityLivingBase) {
|
||||||
|
Potion potion = Potion.getPotionById(packetIn.getEffectId());
|
||||||
|
|
||||||
|
if (potion != null) {
|
||||||
|
PotionEffect effect = new PotionEffect(potion, packetIn.getDuration(), packetIn.getAmplifier(), packetIn.getIsAmbient(), packetIn.doesShowParticles());
|
||||||
|
effect.setPotionDurationMax(packetIn.isMaxDuration());
|
||||||
|
((EntityLivingBase) entity).addPotionEffect(effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCombatEvent(@Nonnull SPacketCombatEvent packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
// We only care if we died
|
||||||
|
if (packetIn.eventType == SPacketCombatEvent.Event.ENTITY_DIED) {
|
||||||
|
if (packetIn.playerId == this.player.getEntityId()) {
|
||||||
|
// Perform an instantaneous respawn
|
||||||
|
this.networkManager.sendPacket(new CPacketClientStatus(CPacketClientStatus.State.PERFORM_RESPAWN));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleServerDifficulty(@Nonnull SPacketServerDifficulty packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCamera(SPacketCamera packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleWorldBorder(@Nonnull SPacketWorldBorder packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
packetIn.apply(this.world.getWorldBorder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleTitle(@Nonnull SPacketTitle packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handlePlayerListHeaderFooter(@Nonnull SPacketPlayerListHeaderFooter packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleResourcePack(@Nonnull SPacketResourcePackSend packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
// Lie to the server and tell them we accepted it in response
|
||||||
|
this.networkManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.ACCEPTED));
|
||||||
|
this.networkManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.SUCCESSFULLY_LOADED));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleUpdateBossInfo(@Nonnull SPacketUpdateBossInfo packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleCooldown(@Nonnull SPacketCooldown packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
|
||||||
|
if (packetIn.getTicks() == 0) { // There is no cooldown
|
||||||
|
this.player.getCooldownTracker().removeCooldown(packetIn.getItem());
|
||||||
|
} else {
|
||||||
|
this.player.getCooldownTracker().setCooldown(packetIn.getItem(), packetIn.getTicks());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMoveVehicle(@Nonnull SPacketMoveVehicle packetIn) {
|
||||||
|
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
|
||||||
|
/* Atm Baritone doesn't even work on vehicles that well at all, so this is a major TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleAdvancementInfo(@Nonnull SPacketAdvancementInfo packetIn) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleSelectAdvancementsTab(@Nonnull SPacketSelectAdvancementsTab packetIn) { /* Lol global bot achievements when? */ }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void func_194307_a(@Nonnull SPacketPlaceGhostRecipe p_194307_1_) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnect(@Nonnull ITextComponent reason) {
|
||||||
|
// TODO Maybe more world unloadinde
|
||||||
|
this.world.removeEntity(this.player);
|
||||||
|
this.user.getManager().notifyDisconnect(this.user, EnumConnectionState.PLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public ClientAdvancementManager getAdvancementManager() {
|
||||||
|
throw new UnsupportedOperationException("This method shouldn't have been called; That is unepic!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityBot player() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BotWorld world() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.bot.spec;
|
||||||
|
|
||||||
|
import baritone.api.bot.IBaritoneUser;
|
||||||
|
import baritone.api.utils.IPlayerController;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockCommandBlock;
|
||||||
|
import net.minecraft.block.BlockStructure;
|
||||||
|
import net.minecraft.block.material.Material;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.inventory.ClickType;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.network.play.client.CPacketClickWindow;
|
||||||
|
import net.minecraft.network.play.client.CPacketHeldItemChange;
|
||||||
|
import net.minecraft.network.play.client.CPacketPlayerDigging;
|
||||||
|
import net.minecraft.util.EnumActionResult;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.GameType;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/14/2018
|
||||||
|
*/
|
||||||
|
public class BotPlayerController implements IPlayerController {
|
||||||
|
|
||||||
|
private final IBaritoneUser user;
|
||||||
|
private GameType gameType;
|
||||||
|
|
||||||
|
private BlockPos currentBlock;
|
||||||
|
private ItemStack currentHittingItem;
|
||||||
|
private boolean hittingBlock;
|
||||||
|
private float blockDamage;
|
||||||
|
private int blockHitDelay;
|
||||||
|
private int heldItemServer;
|
||||||
|
|
||||||
|
public BotPlayerController(IBaritoneUser user) {
|
||||||
|
this.user = user;
|
||||||
|
this.currentHittingItem = ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPlayerDamageBlock(BlockPos pos, EnumFacing side) {
|
||||||
|
this.syncHeldItem();
|
||||||
|
|
||||||
|
EntityPlayerSP player = this.user.getEntity();
|
||||||
|
World world = player.world;
|
||||||
|
|
||||||
|
if (this.blockHitDelay > 0) {
|
||||||
|
this.blockHitDelay--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isHittingPosition(pos)) {
|
||||||
|
return this.clickBlock(pos, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
IBlockState state = world.getBlockState(pos);
|
||||||
|
|
||||||
|
if (state.getMaterial() == Material.AIR) {
|
||||||
|
this.hittingBlock = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.blockDamage += state.getPlayerRelativeBlockHardness(player, world, pos);
|
||||||
|
|
||||||
|
if (this.blockDamage >= 1.0F) {
|
||||||
|
this.hittingBlock = false;
|
||||||
|
this.blockDamage = 0.0F;
|
||||||
|
this.blockHitDelay = 5;
|
||||||
|
|
||||||
|
player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.STOP_DESTROY_BLOCK, pos, side));
|
||||||
|
this.handleBreak(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
world.sendBlockBreakProgress(player.getEntityId(), this.currentBlock, (int) (this.blockDamage * 10.0F) - 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetBlockRemoving() {
|
||||||
|
if (this.hittingBlock) {
|
||||||
|
this.hittingBlock = false;
|
||||||
|
this.blockDamage = 0.0F;
|
||||||
|
this.user.getEntity().resetCooldown();
|
||||||
|
this.user.getEntity().connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.ABORT_DESTROY_BLOCK, this.currentBlock, EnumFacing.DOWN));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player) {
|
||||||
|
short transactionID = player.openContainer.getNextTransactionID(player.inventory);
|
||||||
|
ItemStack stack = player.openContainer.slotClick(slotId, mouseButton, type, player);
|
||||||
|
this.user.getEntity().connection.sendPacket(new CPacketClickWindow(windowId, slotId, mouseButton, type, stack, transactionID));
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setGameType(GameType type) {
|
||||||
|
this.gameType = type;
|
||||||
|
this.gameType.configurePlayerCapabilities(this.user.getEntity().capabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GameType getGameType() {
|
||||||
|
return this.gameType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean clickBlock(BlockPos pos, EnumFacing side) {
|
||||||
|
EntityPlayerSP player = this.user.getEntity();
|
||||||
|
World world = player.world;
|
||||||
|
|
||||||
|
if (!canBreak(player, pos)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.hittingBlock || !this.isHittingPosition(pos)) {
|
||||||
|
if (this.hittingBlock) {
|
||||||
|
player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.ABORT_DESTROY_BLOCK, this.currentBlock, side));
|
||||||
|
}
|
||||||
|
|
||||||
|
IBlockState state = world.getBlockState(pos);
|
||||||
|
player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.START_DESTROY_BLOCK, pos, side));
|
||||||
|
|
||||||
|
if (state.getMaterial() != Material.AIR) {
|
||||||
|
if (this.blockDamage == 0.0F) {
|
||||||
|
state.getBlock().onBlockClicked(world, pos, player);
|
||||||
|
}
|
||||||
|
if (state.getPlayerRelativeBlockHardness(player, player.world, pos) >= 1.0F) {
|
||||||
|
this.handleBreak(pos);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.hittingBlock = true;
|
||||||
|
this.currentBlock = pos;
|
||||||
|
this.blockDamage = 0.0F;
|
||||||
|
this.currentHittingItem = player.getHeldItemMainhand();
|
||||||
|
world.sendBlockBreakProgress(player.getEntityId(), this.currentBlock, (int) (this.blockDamage * 10.0F) - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleBreak(BlockPos pos) {
|
||||||
|
EntityPlayerSP player = this.user.getEntity();
|
||||||
|
World world = player.world;
|
||||||
|
|
||||||
|
IBlockState state = world.getBlockState(pos);
|
||||||
|
Block block = state.getBlock();
|
||||||
|
|
||||||
|
if ((block instanceof BlockCommandBlock || block instanceof BlockStructure) && !player.canUseCommandBlock()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state.getMaterial() == Material.AIR) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
block.onBlockHarvested(world, pos, state, player);
|
||||||
|
|
||||||
|
if (world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11)) {
|
||||||
|
block.onPlayerDestroy(world, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentBlock = new BlockPos(this.currentBlock.getX(), -1, this.currentBlock.getZ());
|
||||||
|
|
||||||
|
ItemStack stack = player.getHeldItemMainhand();
|
||||||
|
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
stack.onBlockDestroyed(world, state, pos, player);
|
||||||
|
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
player.setHeldItem(EnumHand.MAIN_HAND, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canBreak(EntityPlayer player, BlockPos pos) {
|
||||||
|
if (this.gameType.isCreative() || this.gameType == GameType.SPECTATOR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player.world.getWorldBorder().contains(pos)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.gameType.hasLimitedInteractions() && !player.isAllowEdit()) {
|
||||||
|
ItemStack stack = player.getHeldItemMainhand();
|
||||||
|
return !stack.isEmpty() && stack.canDestroy(player.world.getBlockState(pos).getBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isHittingPosition(BlockPos pos) {
|
||||||
|
ItemStack stack = this.user.getEntity().getHeldItemMainhand();
|
||||||
|
boolean itemUnchanged = this.currentHittingItem.isEmpty() && stack.isEmpty();
|
||||||
|
|
||||||
|
if (!this.currentHittingItem.isEmpty() && !stack.isEmpty()) {
|
||||||
|
itemUnchanged = stack.getItem() == this.currentHittingItem.getItem()
|
||||||
|
&& ItemStack.areItemStackTagsEqual(stack, this.currentHittingItem)
|
||||||
|
&& (stack.isItemStackDamageable() || stack.getMetadata() == this.currentHittingItem.getMetadata());
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos.equals(this.currentBlock) && itemUnchanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syncHeldItem() {
|
||||||
|
int heldItemClient = this.user.getEntity().inventory.currentItem;
|
||||||
|
|
||||||
|
if (heldItemClient != this.heldItemServer) {
|
||||||
|
this.heldItemServer = heldItemClient;
|
||||||
|
this.user.getEntity().connection.sendPacket(new CPacketHeldItemChange(this.heldItemServer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasBrokenBlock() {
|
||||||
|
return this.currentBlock.getY() == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand) {
|
||||||
|
throw new AbstractMethodError("Lol");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EnumActionResult processRightClick(EntityPlayerSP player, World world, EnumHand hand) {
|
||||||
|
throw new AbstractMethodError("Lol");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHittingBlock(boolean hittingBlock) {
|
||||||
|
this.hittingBlock = hittingBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* 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.bot.spec;
|
||||||
|
|
||||||
|
import net.minecraft.client.multiplayer.ChunkProviderClient;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.profiler.Profiler;
|
||||||
|
import net.minecraft.world.DimensionType;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.WorldSettings;
|
||||||
|
import net.minecraft.world.chunk.IChunkProvider;
|
||||||
|
import net.minecraft.world.storage.SaveHandlerMP;
|
||||||
|
import net.minecraft.world.storage.WorldInfo;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 11/7/2018
|
||||||
|
*/
|
||||||
|
public class BotWorld extends World {
|
||||||
|
|
||||||
|
private static Profiler BOT_WORLD_PROFILER = new Profiler();
|
||||||
|
private static int worldNum = 0;
|
||||||
|
|
||||||
|
private ChunkProviderClient chunkProviderClient;
|
||||||
|
|
||||||
|
public BotWorld(WorldSettings settings, int dimension) {
|
||||||
|
super(
|
||||||
|
new SaveHandlerMP(),
|
||||||
|
new WorldInfo(settings, "BotWorld" + ++worldNum),
|
||||||
|
DimensionType.getById(dimension).createDimension(),
|
||||||
|
BOT_WORLD_PROFILER,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
this.provider.setWorld(this);
|
||||||
|
this.chunkProvider = this.createChunkProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nonnull
|
||||||
|
protected IChunkProvider createChunkProvider() {
|
||||||
|
return (this.chunkProviderClient = new ChunkProviderClient(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isChunkLoaded(int x, int z, boolean allowEmpty) {
|
||||||
|
return allowEmpty || !this.chunkProviderClient.provideChunk(x, z).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerBot(int entityID, EntityBot entity) {
|
||||||
|
this.entitiesById.addKey(entityID, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeEntityFromWorld(int entityID) {
|
||||||
|
Entity entity = this.entitiesById.removeObject(entityID);
|
||||||
|
if (entity != null) {
|
||||||
|
this.removeEntity(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doPreChunk(int chunkX, int chunkZ, boolean loadChunk) {
|
||||||
|
if (loadChunk) {
|
||||||
|
this.chunkProviderClient.loadChunk(chunkX, chunkZ);
|
||||||
|
} else {
|
||||||
|
this.chunkProviderClient.unloadChunk(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* 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.bot.spec;
|
||||||
|
|
||||||
|
import baritone.api.bot.IBaritoneUser;
|
||||||
|
import baritone.utils.PlayerMovementInput;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.EntityPlayerSP;
|
||||||
|
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||||
|
import net.minecraft.client.network.NetworkPlayerInfo;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.IMerchant;
|
||||||
|
import net.minecraft.entity.passive.AbstractHorse;
|
||||||
|
import net.minecraft.inventory.IInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.stats.RecipeBook;
|
||||||
|
import net.minecraft.stats.StatisticsManager;
|
||||||
|
import net.minecraft.tileentity.CommandBlockBaseLogic;
|
||||||
|
import net.minecraft.tileentity.TileEntityCommandBlock;
|
||||||
|
import net.minecraft.tileentity.TileEntitySign;
|
||||||
|
import net.minecraft.tileentity.TileEntityStructure;
|
||||||
|
import net.minecraft.util.EnumHand;
|
||||||
|
import net.minecraft.util.text.ITextComponent;
|
||||||
|
import net.minecraft.world.GameType;
|
||||||
|
import net.minecraft.world.IInteractionObject;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
// Some Notes:
|
||||||
|
// startRiding references the sound manager
|
||||||
|
// onUpdateWalkingPlayer references the gameSettings autoJump flag
|
||||||
|
// notifyDataManagerChange references the sound manager
|
||||||
|
// onLivingUpdate makes a lot of references to mc fields
|
||||||
|
// - playerController
|
||||||
|
// - currentScreen
|
||||||
|
// - gameSettings
|
||||||
|
// - tutorial
|
||||||
|
// What needs to be considered
|
||||||
|
// - The server tells us what our entity id should be, the bot entity should respect this.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brady
|
||||||
|
* @since 10/23/2018
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("EntityConstructor")
|
||||||
|
public class EntityBot extends EntityPlayerSP {
|
||||||
|
|
||||||
|
private final IBaritoneUser user;
|
||||||
|
private NetworkPlayerInfo playerInfo;
|
||||||
|
|
||||||
|
public EntityBot(IBaritoneUser user, Minecraft mc, World world, NetHandlerPlayClient netHandlerPlayClient, StatisticsManager statisticsManager, RecipeBook recipeBook) {
|
||||||
|
super(mc, world, netHandlerPlayClient, statisticsManager, recipeBook);
|
||||||
|
this.user = user;
|
||||||
|
this.movementInput = new PlayerMovementInput(this.user.getBaritone().getInputOverrideHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeScreenAndDropStack() {
|
||||||
|
this.inventory.setItemStack(ItemStack.EMPTY);
|
||||||
|
|
||||||
|
// EntityPlayer#closeScreen
|
||||||
|
this.openContainer = this.inventoryContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendStatusMessage(ITextComponent chatComponent, boolean actionBar) {
|
||||||
|
// TODO: Custom message handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(ITextComponent component) {
|
||||||
|
// TODO: Custom message handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void openEditSign(TileEntitySign signTile) {
|
||||||
|
// TODO: Custom GUI handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayGuiEditCommandCart(CommandBlockBaseLogic commandBlock) {
|
||||||
|
// TODO: Custom GUI handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayGuiCommandBlock(TileEntityCommandBlock commandBlock) {
|
||||||
|
// TODO: Custom GUI handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void openEditStructure(TileEntityStructure structure) {
|
||||||
|
// TODO: Custom GUI handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void openBook(ItemStack stack, EnumHand hand) {
|
||||||
|
// TODO: Custom GUI handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayGUIChest(IInventory chestInventory) {
|
||||||
|
// TODO: Custom GUI handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void openGuiHorseInventory(AbstractHorse horse, IInventory inventoryIn) {
|
||||||
|
// TODO: Custom GUI handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayGui(IInteractionObject guiOwner) {
|
||||||
|
// TODO: Custom GUI handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayVillagerTradeGui(IMerchant villager) {
|
||||||
|
// TODO: Custom GUI handling
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCriticalHit(Entity entityHit) {
|
||||||
|
// Don't render
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnchantmentCritical(Entity entityHit) {
|
||||||
|
// Don't render
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isCurrentViewEntity() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSpectator() {
|
||||||
|
NetworkPlayerInfo networkplayerinfo = this.connection.getPlayerInfo(this.getGameProfile().getId());
|
||||||
|
// noinspection ConstantConditions
|
||||||
|
return networkplayerinfo != null && networkplayerinfo.getGameType() == GameType.SPECTATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCreative() {
|
||||||
|
NetworkPlayerInfo networkplayerinfo = this.connection.getPlayerInfo(this.getGameProfile().getId());
|
||||||
|
// noinspection ConstantConditions
|
||||||
|
return networkplayerinfo != null && networkplayerinfo.getGameType() == GameType.CREATIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
protected NetworkPlayerInfo getPlayerInfo() {
|
||||||
|
return this.playerInfo == null ? (this.playerInfo = this.connection.getPlayerInfo(this.getUniqueID())) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
-37
@@ -38,13 +38,23 @@ import java.util.Map;
|
|||||||
public final class CachedChunk {
|
public final class CachedChunk {
|
||||||
|
|
||||||
public static final ImmutableSet<Block> BLOCKS_TO_KEEP_TRACK_OF = ImmutableSet.of(
|
public static final ImmutableSet<Block> BLOCKS_TO_KEEP_TRACK_OF = ImmutableSet.of(
|
||||||
|
Blocks.DIAMOND_BLOCK,
|
||||||
|
//Blocks.COAL_ORE,
|
||||||
|
Blocks.COAL_BLOCK,
|
||||||
|
//Blocks.IRON_ORE,
|
||||||
|
Blocks.IRON_BLOCK,
|
||||||
|
//Blocks.GOLD_ORE,
|
||||||
|
Blocks.GOLD_BLOCK,
|
||||||
|
Blocks.EMERALD_ORE,
|
||||||
|
Blocks.EMERALD_BLOCK,
|
||||||
|
|
||||||
Blocks.ENDER_CHEST,
|
Blocks.ENDER_CHEST,
|
||||||
Blocks.FURNACE,
|
Blocks.FURNACE,
|
||||||
Blocks.CHEST,
|
Blocks.CHEST,
|
||||||
Blocks.TRAPPED_CHEST,
|
Blocks.TRAPPED_CHEST,
|
||||||
Blocks.END_PORTAL,
|
Blocks.END_PORTAL,
|
||||||
Blocks.END_PORTAL_FRAME,
|
Blocks.END_PORTAL_FRAME,
|
||||||
Blocks.SPAWNER,
|
Blocks.MOB_SPAWNER,
|
||||||
Blocks.BARRIER,
|
Blocks.BARRIER,
|
||||||
Blocks.OBSERVER,
|
Blocks.OBSERVER,
|
||||||
Blocks.WHITE_SHULKER_BOX,
|
Blocks.WHITE_SHULKER_BOX,
|
||||||
@@ -55,7 +65,7 @@ public final class CachedChunk {
|
|||||||
Blocks.LIME_SHULKER_BOX,
|
Blocks.LIME_SHULKER_BOX,
|
||||||
Blocks.PINK_SHULKER_BOX,
|
Blocks.PINK_SHULKER_BOX,
|
||||||
Blocks.GRAY_SHULKER_BOX,
|
Blocks.GRAY_SHULKER_BOX,
|
||||||
Blocks.LIGHT_GRAY_SHULKER_BOX,
|
Blocks.SILVER_SHULKER_BOX,
|
||||||
Blocks.CYAN_SHULKER_BOX,
|
Blocks.CYAN_SHULKER_BOX,
|
||||||
Blocks.PURPLE_SHULKER_BOX,
|
Blocks.PURPLE_SHULKER_BOX,
|
||||||
Blocks.BLUE_SHULKER_BOX,
|
Blocks.BLUE_SHULKER_BOX,
|
||||||
@@ -63,52 +73,25 @@ public final class CachedChunk {
|
|||||||
Blocks.GREEN_SHULKER_BOX,
|
Blocks.GREEN_SHULKER_BOX,
|
||||||
Blocks.RED_SHULKER_BOX,
|
Blocks.RED_SHULKER_BOX,
|
||||||
Blocks.BLACK_SHULKER_BOX,
|
Blocks.BLACK_SHULKER_BOX,
|
||||||
Blocks.NETHER_PORTAL,
|
Blocks.PORTAL,
|
||||||
Blocks.HOPPER,
|
Blocks.HOPPER,
|
||||||
Blocks.BEACON,
|
Blocks.BEACON,
|
||||||
Blocks.BREWING_STAND,
|
Blocks.BREWING_STAND,
|
||||||
|
Blocks.SKULL,
|
||||||
// TODO: Maybe add a predicate for blocks to keep track of?
|
|
||||||
// This should really not need to happen
|
|
||||||
Blocks.CREEPER_HEAD,
|
|
||||||
Blocks.CREEPER_WALL_HEAD,
|
|
||||||
Blocks.DRAGON_HEAD,
|
|
||||||
Blocks.DRAGON_WALL_HEAD,
|
|
||||||
Blocks.PLAYER_HEAD,
|
|
||||||
Blocks.PLAYER_WALL_HEAD,
|
|
||||||
Blocks.ZOMBIE_HEAD,
|
|
||||||
Blocks.ZOMBIE_WALL_HEAD,
|
|
||||||
Blocks.SKELETON_SKULL,
|
|
||||||
Blocks.SKELETON_WALL_SKULL,
|
|
||||||
Blocks.WITHER_SKELETON_SKULL,
|
|
||||||
Blocks.WITHER_SKELETON_WALL_SKULL,
|
|
||||||
Blocks.ENCHANTING_TABLE,
|
Blocks.ENCHANTING_TABLE,
|
||||||
Blocks.ANVIL,
|
Blocks.ANVIL,
|
||||||
Blocks.WHITE_BED,
|
Blocks.LIT_FURNACE,
|
||||||
Blocks.ORANGE_BED,
|
Blocks.BED,
|
||||||
Blocks.MAGENTA_BED,
|
|
||||||
Blocks.LIGHT_BLUE_BED,
|
|
||||||
Blocks.YELLOW_BED,
|
|
||||||
Blocks.LIME_BED,
|
|
||||||
Blocks.PINK_BED,
|
|
||||||
Blocks.GRAY_BED,
|
|
||||||
Blocks.LIGHT_GRAY_BED,
|
|
||||||
Blocks.CYAN_BED,
|
|
||||||
Blocks.PURPLE_BED,
|
|
||||||
Blocks.BLUE_BED,
|
|
||||||
Blocks.BROWN_BED,
|
|
||||||
Blocks.GREEN_BED,
|
|
||||||
Blocks.RED_BED,
|
|
||||||
Blocks.BLACK_BED,
|
|
||||||
Blocks.DRAGON_EGG,
|
Blocks.DRAGON_EGG,
|
||||||
Blocks.JUKEBOX,
|
Blocks.JUKEBOX,
|
||||||
Blocks.END_GATEWAY,
|
Blocks.END_GATEWAY,
|
||||||
Blocks.COBWEB,
|
Blocks.WEB,
|
||||||
Blocks.NETHER_WART,
|
Blocks.NETHER_WART,
|
||||||
Blocks.LADDER,
|
Blocks.LADDER,
|
||||||
Blocks.VINE
|
Blocks.VINE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The size of the chunk data in bits. Equal to 16 KiB.
|
* The size of the chunk data in bits. Equal to 16 KiB.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -187,8 +170,8 @@ public final class CachedChunk {
|
|||||||
|
|
||||||
// we have this exact block, it's a surface block
|
// we have this exact block, it's a surface block
|
||||||
/*System.out.println("Saying that " + x + "," + y + "," + z + " is " + state);
|
/*System.out.println("Saying that " + x + "," + y + "," + z + " is " + state);
|
||||||
if (!Minecraft.getInstance().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
|
if (!Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock().equals(state.getBlock())) {
|
||||||
throw new IllegalStateException("failed " + Minecraft.getInstance().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
|
throw new IllegalStateException("failed " + Minecraft.getMinecraft().world.getBlockState(new BlockPos(x + this.x * 16, y, z + this.z * 16)).getBlock() + " " + state.getBlock() + " " + (x + this.x * 16) + " " + y + " " + (z + this.z * 16));
|
||||||
}*/
|
}*/
|
||||||
return overview[internalPos];
|
return overview[internalPos];
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-10
@@ -24,10 +24,9 @@ import net.minecraft.block.*;
|
|||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.chunk.BlockStateContainer;
|
import net.minecraft.world.chunk.BlockStateContainer;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraft.world.chunk.ChunkSection;
|
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -45,9 +44,9 @@ public final class ChunkPacker {
|
|||||||
Map<String, List<BlockPos>> specialBlocks = new HashMap<>();
|
Map<String, List<BlockPos>> specialBlocks = new HashMap<>();
|
||||||
BitSet bitSet = new BitSet(CachedChunk.SIZE);
|
BitSet bitSet = new BitSet(CachedChunk.SIZE);
|
||||||
try {
|
try {
|
||||||
ChunkSection[] chunkInternalStorageArray = chunk.getSections();
|
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||||
for (int y0 = 0; y0 < 16; y0++) {
|
for (int y0 = 0; y0 < 16; y0++) {
|
||||||
ChunkSection extendedblockstorage = chunkInternalStorageArray[y0];
|
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||||
if (extendedblockstorage == null) {
|
if (extendedblockstorage == null) {
|
||||||
// any 16x16x16 area that's all air will have null storage
|
// any 16x16x16 area that's all air will have null storage
|
||||||
// for example, in an ocean biome, with air from y=64 to y=256
|
// for example, in an ocean biome, with air from y=64 to y=256
|
||||||
@@ -59,7 +58,7 @@ public final class ChunkPacker {
|
|||||||
// since a bitset is initialized to all zero, and air is saved as zeros
|
// since a bitset is initialized to all zero, and air is saved as zeros
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
BlockStateContainer<IBlockState> bsc = extendedblockstorage.getData();
|
BlockStateContainer bsc = extendedblockstorage.getData();
|
||||||
int yReal = y0 << 4;
|
int yReal = y0 << 4;
|
||||||
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
|
// the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x;
|
||||||
// for better cache locality, iterate in that order
|
// for better cache locality, iterate in that order
|
||||||
@@ -106,9 +105,10 @@ public final class ChunkPacker {
|
|||||||
return new CachedChunk(chunk.x, chunk.z, bitSet, blocks, specialBlocks, System.currentTimeMillis());
|
return new CachedChunk(chunk.x, chunk.z, bitSet, blocks, specialBlocks, System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static PathingBlockType getPathingBlockType(IBlockState state, Chunk chunk, int x, int y, int z) {
|
private static PathingBlockType getPathingBlockType(IBlockState state, Chunk chunk, int x, int y, int z) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (MovementHelper.isWater(state)) {
|
if (block == Blocks.WATER || block == Blocks.FLOWING_WATER) {
|
||||||
// only water source blocks are plausibly usable, flowing water should be avoid
|
// only water source blocks are plausibly usable, flowing water should be avoid
|
||||||
// FLOWING_WATER is a waterfall, it doesn't really matter and caching it as AVOID just makes it look wrong
|
// FLOWING_WATER is a waterfall, it doesn't really matter and caching it as AVOID just makes it look wrong
|
||||||
if (MovementHelper.possiblyFlowing(state)) {
|
if (MovementHelper.possiblyFlowing(state)) {
|
||||||
@@ -123,8 +123,7 @@ public final class ChunkPacker {
|
|||||||
return PathingBlockType.AVOID;
|
return PathingBlockType.AVOID;
|
||||||
}
|
}
|
||||||
if (x == 0 || x == 15 || z == 0 || z == 15) {
|
if (x == 0 || x == 15 || z == 0 || z == 15) {
|
||||||
Vec3d flow = state.getFluidState().getFlow(chunk.getWorld(), new BlockPos(x + chunk.x << 4, y, z + chunk.z << 4));
|
if (BlockLiquid.getSlopeAngle(chunk.getWorld(), new BlockPos(x + chunk.x << 4, y, z + chunk.z << 4), state.getMaterial(), state) == -1000.0F) {
|
||||||
if (flow.x != 0.0 || flow.z != 0.0) {
|
|
||||||
return PathingBlockType.WATER;
|
return PathingBlockType.WATER;
|
||||||
}
|
}
|
||||||
return PathingBlockType.AVOID;
|
return PathingBlockType.AVOID;
|
||||||
@@ -132,14 +131,14 @@ public final class ChunkPacker {
|
|||||||
return PathingBlockType.WATER;
|
return PathingBlockType.WATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MovementHelper.avoidWalkingInto(state) || MovementHelper.isBottomSlab(state)) {
|
if (MovementHelper.avoidWalkingInto(block) || MovementHelper.isBottomSlab(state)) {
|
||||||
return PathingBlockType.AVOID;
|
return PathingBlockType.AVOID;
|
||||||
}
|
}
|
||||||
// We used to do an AABB check here
|
// We used to do an AABB check here
|
||||||
// however, this failed in the nether when you were near a nether fortress
|
// however, this failed in the nether when you were near a nether fortress
|
||||||
// because fences check their adjacent blocks in the world for their fence connection status to determine AABB shape
|
// because fences check their adjacent blocks in the world for their fence connection status to determine AABB shape
|
||||||
// this caused a nullpointerexception when we saved chunks on unload, because they were unable to check their neighbors
|
// this caused a nullpointerexception when we saved chunks on unload, because they were unable to check their neighbors
|
||||||
if (block instanceof BlockAir || block instanceof BlockTallGrass || block instanceof BlockDoublePlant || block instanceof BlockFlower) {
|
if (block == Blocks.AIR || block instanceof BlockTallGrass || block instanceof BlockDoublePlant || block instanceof BlockFlower) {
|
||||||
return PathingBlockType.AIR;
|
return PathingBlockType.AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -24,7 +24,6 @@ import baritone.utils.accessor.IAnvilChunkLoader;
|
|||||||
import baritone.utils.accessor.IChunkProviderServer;
|
import baritone.utils.accessor.IChunkProviderServer;
|
||||||
import net.minecraft.server.integrated.IntegratedServer;
|
import net.minecraft.server.integrated.IntegratedServer;
|
||||||
import net.minecraft.world.WorldServer;
|
import net.minecraft.world.WorldServer;
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -56,7 +55,7 @@ public class WorldProvider implements IWorldProvider, Helper {
|
|||||||
*
|
*
|
||||||
* @param dimension The ID of the world's dimension
|
* @param dimension The ID of the world's dimension
|
||||||
*/
|
*/
|
||||||
public final void initWorld(DimensionType dimension) {
|
public final void initWorld(int dimension) {
|
||||||
File directory;
|
File directory;
|
||||||
File readme;
|
File readme;
|
||||||
|
|
||||||
@@ -93,7 +92,7 @@ public class WorldProvider implements IWorldProvider, Helper {
|
|||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
|
|
||||||
// We will actually store the world data in a subfolder: "DIM<id>"
|
// We will actually store the world data in a subfolder: "DIM<id>"
|
||||||
Path dir = new File(directory, "DIM" + dimension.getId()).toPath();
|
Path dir = new File(directory, "DIM" + dimension).toPath();
|
||||||
if (!Files.exists(dir)) {
|
if (!Files.exists(dir)) {
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(dir);
|
Files.createDirectories(dir);
|
||||||
@@ -102,7 +101,7 @@ public class WorldProvider implements IWorldProvider, Helper {
|
|||||||
|
|
||||||
System.out.println("Baritone world data dir: " + dir);
|
System.out.println("Baritone world data dir: " + dir);
|
||||||
synchronized (worldCache) {
|
synchronized (worldCache) {
|
||||||
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension.getId()));
|
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -28,8 +28,8 @@ import net.minecraft.client.multiplayer.ChunkProviderClient;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.ChunkPos;
|
import net.minecraft.util.math.ChunkPos;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraft.world.chunk.ChunkSection;
|
|
||||||
import net.minecraft.world.chunk.IChunkProvider;
|
import net.minecraft.world.chunk.IChunkProvider;
|
||||||
|
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
@@ -72,7 +72,7 @@ public enum WorldScanner implements IWorldScanner {
|
|||||||
foundChunks = true;
|
foundChunks = true;
|
||||||
int chunkX = xoff + playerChunkX;
|
int chunkX = xoff + playerChunkX;
|
||||||
int chunkZ = zoff + playerChunkZ;
|
int chunkZ = zoff + playerChunkZ;
|
||||||
Chunk chunk = chunkProvider.getChunk(chunkX, chunkZ, false, false);
|
Chunk chunk = chunkProvider.getLoadedChunk(chunkX, chunkZ);
|
||||||
if (chunk == null) {
|
if (chunk == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ public enum WorldScanner implements IWorldScanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ChunkProviderClient chunkProvider = (ChunkProviderClient) ctx.world().getChunkProvider();
|
ChunkProviderClient chunkProvider = (ChunkProviderClient) ctx.world().getChunkProvider();
|
||||||
Chunk chunk = chunkProvider.getChunk(pos.x, pos.z, false, false);
|
Chunk chunk = chunkProvider.getLoadedChunk(pos.x, pos.z);
|
||||||
int playerY = ctx.playerFeet().getY();
|
int playerY = ctx.playerFeet().getY();
|
||||||
|
|
||||||
if (chunk == null || chunk.isEmpty()) {
|
if (chunk == null || chunk.isEmpty()) {
|
||||||
@@ -134,7 +134,7 @@ public enum WorldScanner implements IWorldScanner {
|
|||||||
int queued = 0;
|
int queued = 0;
|
||||||
for (int x = minX; x <= maxX; x++) {
|
for (int x = minX; x <= maxX; x++) {
|
||||||
for (int z = minZ; z <= maxZ; z++) {
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
Chunk chunk = chunkProvider.getChunk(x, z, false, false);
|
Chunk chunk = chunkProvider.getLoadedChunk(x, z);
|
||||||
|
|
||||||
if (chunk != null && !chunk.isEmpty()) {
|
if (chunk != null && !chunk.isEmpty()) {
|
||||||
queued++;
|
queued++;
|
||||||
@@ -147,11 +147,11 @@ public enum WorldScanner implements IWorldScanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, BlockOptionalMetaLookup filter, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) {
|
private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, BlockOptionalMetaLookup filter, Collection<BlockPos> result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) {
|
||||||
ChunkSection[] chunkInternalStorageArray = chunk.getSections();
|
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||||
boolean foundWithinY = false;
|
boolean foundWithinY = false;
|
||||||
for (int yIndex = 0; yIndex < 16; yIndex++) {
|
for (int yIndex = 0; yIndex < 16; yIndex++) {
|
||||||
int y0 = coordinateIterationOrder[yIndex];
|
int y0 = coordinateIterationOrder[yIndex];
|
||||||
ChunkSection extendedblockstorage = chunkInternalStorageArray[y0];
|
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||||
if (extendedblockstorage == null) {
|
if (extendedblockstorage == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class BaritoneChatControl implements Helper, AbstractGameEventListener {
|
|||||||
event.cancel();
|
event.cancel();
|
||||||
String commandStr = msg.substring(forceRun ? FORCE_COMMAND_PREFIX.length() : prefix.length());
|
String commandStr = msg.substring(forceRun ? FORCE_COMMAND_PREFIX.length() : prefix.length());
|
||||||
if (!runCommand(commandStr) && !commandStr.trim().isEmpty()) {
|
if (!runCommand(commandStr) && !commandStr.trim().isEmpty()) {
|
||||||
new CommandNotFoundException(CommandManager.expand(commandStr).getA()).handle(null, null);
|
new CommandNotFoundException(CommandManager.expand(commandStr).getFirst()).handle(null, null);
|
||||||
}
|
}
|
||||||
} else if ((settings.chatControl.value || settings.chatControlAnyway.value) && runCommand(msg)) {
|
} else if ((settings.chatControl.value || settings.chatControlAnyway.value) && runCommand(msg)) {
|
||||||
event.cancel();
|
event.cancel();
|
||||||
@@ -108,9 +108,9 @@ public class BaritoneChatControl implements Helper, AbstractGameEventListener {
|
|||||||
return this.runCommand("help");
|
return this.runCommand("help");
|
||||||
}
|
}
|
||||||
Tuple<String, List<ICommandArgument>> pair = CommandManager.expand(msg);
|
Tuple<String, List<ICommandArgument>> pair = CommandManager.expand(msg);
|
||||||
String command = pair.getA();
|
String command = pair.getFirst();
|
||||||
String rest = msg.substring(pair.getA().length());
|
String rest = msg.substring(pair.getFirst().length());
|
||||||
ArgConsumer argc = new ArgConsumer(this.manager, pair.getB());
|
ArgConsumer argc = new ArgConsumer(this.manager, pair.getSecond());
|
||||||
if (!argc.hasAny()) {
|
if (!argc.hasAny()) {
|
||||||
Settings.Setting setting = settings.byLowerName.get(command.toLowerCase(Locale.US));
|
Settings.Setting setting = settings.byLowerName.get(command.toLowerCase(Locale.US));
|
||||||
if (setting != null) {
|
if (setting != null) {
|
||||||
@@ -127,7 +127,7 @@ public class BaritoneChatControl implements Helper, AbstractGameEventListener {
|
|||||||
if (setting.getName().equals("logger")) {
|
if (setting.getName().equals("logger")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (setting.getName().equalsIgnoreCase(pair.getA())) {
|
if (setting.getName().equalsIgnoreCase(pair.getFirst())) {
|
||||||
logRanCommand(command, rest);
|
logRanCommand(command, rest);
|
||||||
try {
|
try {
|
||||||
this.manager.execute(String.format("set %s %s", setting.getName(), argc.getString()));
|
this.manager.execute(String.format("set %s %s", setting.getName(), argc.getString()));
|
||||||
@@ -138,7 +138,7 @@ public class BaritoneChatControl implements Helper, AbstractGameEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the command exists, then handle echoing the input
|
// If the command exists, then handle echoing the input
|
||||||
if (this.manager.getCommand(pair.getA()) != null) {
|
if (this.manager.getCommand(pair.getFirst()) != null) {
|
||||||
logRanCommand(command, rest);
|
logRanCommand(command, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public class BuildCommand extends Command {
|
public class BuildCommand extends Command {
|
||||||
|
|
||||||
private static final File schematicsDir = new File(mc.gameDir, "schematics");
|
private static final File schematicsDir = new File(Minecraft.getMinecraft().gameDir, "schematics");
|
||||||
|
|
||||||
public BuildCommand(IBaritone baritone) {
|
public BuildCommand(IBaritone baritone) {
|
||||||
super(baritone, "build");
|
super(baritone, "build");
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import baritone.api.command.datatypes.BlockById;
|
|||||||
import baritone.api.command.exception.CommandException;
|
import baritone.api.command.exception.CommandException;
|
||||||
import baritone.api.command.argument.IArgConsumer;
|
import baritone.api.command.argument.IArgConsumer;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.util.registry.IRegistry;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -47,7 +46,7 @@ public class FindCommand extends Command {
|
|||||||
toFind.stream()
|
toFind.stream()
|
||||||
.flatMap(block ->
|
.flatMap(block ->
|
||||||
ctx.worldData().getCachedWorld().getLocationsOf(
|
ctx.worldData().getCachedWorld().getLocationsOf(
|
||||||
IRegistry.BLOCK.getKey(block).getPath(),
|
Block.REGISTRY.getNameForObject(block).getPath(),
|
||||||
Integer.MAX_VALUE,
|
Integer.MAX_VALUE,
|
||||||
origin.x,
|
origin.x,
|
||||||
origin.y,
|
origin.y,
|
||||||
|
|||||||
@@ -26,11 +26,10 @@ import baritone.api.command.exception.CommandException;
|
|||||||
import baritone.api.command.argument.IArgConsumer;
|
import baritone.api.command.argument.IArgConsumer;
|
||||||
import baritone.api.command.helpers.TabCompleteHelper;
|
import baritone.api.command.helpers.TabCompleteHelper;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityList;
|
||||||
import net.minecraft.entity.EntityLiving;
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityType;
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.registry.IRegistry;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
@@ -48,7 +47,7 @@ public class FollowCommand extends Command {
|
|||||||
FollowGroup group;
|
FollowGroup group;
|
||||||
FollowList list;
|
FollowList list;
|
||||||
List<Entity> entities = new ArrayList<>();
|
List<Entity> entities = new ArrayList<>();
|
||||||
List<EntityType> classes = new ArrayList<>();
|
List<Class<? extends Entity>> classes = new ArrayList<>();
|
||||||
if (args.hasExactlyOne()) {
|
if (args.hasExactlyOne()) {
|
||||||
baritone.getFollowProcess().follow((group = args.getEnum(FollowGroup.class)).filter);
|
baritone.getFollowProcess().follow((group = args.getEnum(FollowGroup.class)).filter);
|
||||||
} else {
|
} else {
|
||||||
@@ -57,9 +56,9 @@ public class FollowCommand extends Command {
|
|||||||
list = args.getEnum(FollowList.class);
|
list = args.getEnum(FollowList.class);
|
||||||
while (args.hasAny()) {
|
while (args.hasAny()) {
|
||||||
Object gotten = args.getDatatypeFor(list.datatype);
|
Object gotten = args.getDatatypeFor(list.datatype);
|
||||||
if (gotten instanceof EntityType) {
|
if (gotten instanceof Class) {
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
classes.add((EntityType) gotten);
|
classes.add((Class<? extends Entity>) gotten);
|
||||||
} else {
|
} else {
|
||||||
entities.add((Entity) gotten);
|
entities.add((Entity) gotten);
|
||||||
}
|
}
|
||||||
@@ -67,7 +66,7 @@ public class FollowCommand extends Command {
|
|||||||
baritone.getFollowProcess().follow(
|
baritone.getFollowProcess().follow(
|
||||||
classes.isEmpty()
|
classes.isEmpty()
|
||||||
? entities::contains
|
? entities::contains
|
||||||
: e -> classes.stream().anyMatch(c -> c.getEntityClass().isInstance(e))
|
: e -> classes.stream().anyMatch(c -> c.isInstance(e))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (group != null) {
|
if (group != null) {
|
||||||
@@ -80,7 +79,7 @@ public class FollowCommand extends Command {
|
|||||||
.forEach(this::logDirect);
|
.forEach(this::logDirect);
|
||||||
} else {
|
} else {
|
||||||
classes.stream()
|
classes.stream()
|
||||||
.map(IRegistry.ENTITY_TYPE::getKey)
|
.map(EntityList::getKey)
|
||||||
.map(Objects::requireNonNull)
|
.map(Objects::requireNonNull)
|
||||||
.map(ResourceLocation::toString)
|
.map(ResourceLocation::toString)
|
||||||
.forEach(this::logDirect);
|
.forEach(this::logDirect);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class RenderCommand extends Command {
|
|||||||
args.requireMax(0);
|
args.requireMax(0);
|
||||||
BetterBlockPos origin = ctx.playerFeet();
|
BetterBlockPos origin = ctx.playerFeet();
|
||||||
int renderDistance = (mc.gameSettings.renderDistanceChunks + 1) * 16;
|
int renderDistance = (mc.gameSettings.renderDistanceChunks + 1) * 16;
|
||||||
mc.worldRenderer.markBlockRangeForRenderUpdate(
|
mc.renderGlobal.markBlockRangeForRenderUpdate(
|
||||||
origin.x - renderDistance,
|
origin.x - renderDistance,
|
||||||
0,
|
0,
|
||||||
origin.z - renderDistance,
|
origin.z - renderDistance,
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ import baritone.api.command.ICommand;
|
|||||||
import baritone.api.command.argument.ICommandArgument;
|
import baritone.api.command.argument.ICommandArgument;
|
||||||
import baritone.api.command.exception.CommandUnhandledException;
|
import baritone.api.command.exception.CommandUnhandledException;
|
||||||
import baritone.api.command.exception.ICommandException;
|
import baritone.api.command.exception.ICommandException;
|
||||||
|
import baritone.command.argument.ArgConsumer;
|
||||||
import baritone.api.command.helpers.TabCompleteHelper;
|
import baritone.api.command.helpers.TabCompleteHelper;
|
||||||
import baritone.api.command.manager.ICommandManager;
|
import baritone.api.command.manager.ICommandManager;
|
||||||
import baritone.api.command.registry.Registry;
|
import baritone.api.command.registry.Registry;
|
||||||
import baritone.command.argument.ArgConsumer;
|
|
||||||
import baritone.command.argument.CommandArguments;
|
import baritone.command.argument.CommandArguments;
|
||||||
import baritone.command.defaults.DefaultCommands;
|
import baritone.command.defaults.DefaultCommands;
|
||||||
import net.minecraft.util.Tuple;
|
import net.minecraft.util.Tuple;
|
||||||
@@ -35,7 +35,6 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default, internal implementation of {@link ICommandManager}
|
* The default, internal implementation of {@link ICommandManager}
|
||||||
*
|
*
|
||||||
@@ -95,8 +94,8 @@ public class CommandManager implements ICommandManager {
|
|||||||
@Override
|
@Override
|
||||||
public Stream<String> tabComplete(String prefix) {
|
public Stream<String> tabComplete(String prefix) {
|
||||||
Tuple<String, List<ICommandArgument>> pair = expand(prefix, true);
|
Tuple<String, List<ICommandArgument>> pair = expand(prefix, true);
|
||||||
String label = pair.getA();
|
String label = pair.getFirst();
|
||||||
List<ICommandArgument> args = pair.getB();
|
List<ICommandArgument> args = pair.getSecond();
|
||||||
if (args.isEmpty()) {
|
if (args.isEmpty()) {
|
||||||
return new TabCompleteHelper()
|
return new TabCompleteHelper()
|
||||||
.addCommands(this.baritone.getCommandManager())
|
.addCommands(this.baritone.getCommandManager())
|
||||||
@@ -108,8 +107,8 @@ public class CommandManager implements ICommandManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ExecutionWrapper from(Tuple<String, List<ICommandArgument>> expanded) {
|
private ExecutionWrapper from(Tuple<String, List<ICommandArgument>> expanded) {
|
||||||
String label = expanded.getA();
|
String label = expanded.getFirst();
|
||||||
ArgConsumer args = new ArgConsumer(this, expanded.getB());
|
ArgConsumer args = new ArgConsumer(this, expanded.getSecond());
|
||||||
|
|
||||||
ICommand command = this.getCommand(label);
|
ICommand command = this.getCommand(label);
|
||||||
return command == null ? null : new ExecutionWrapper(command, label, args);
|
return command == null ? null : new ExecutionWrapper(command, label, args);
|
||||||
@@ -126,7 +125,6 @@ public class CommandManager implements ICommandManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final class ExecutionWrapper {
|
private static final class ExecutionWrapper {
|
||||||
|
|
||||||
private ICommand command;
|
private ICommand command;
|
||||||
private String label;
|
private String label;
|
||||||
private ArgConsumer args;
|
private ArgConsumer args;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import baritone.api.event.events.*;
|
|||||||
import baritone.api.event.events.type.EventState;
|
import baritone.api.event.events.type.EventState;
|
||||||
import baritone.api.event.listener.IEventBus;
|
import baritone.api.event.listener.IEventBus;
|
||||||
import baritone.api.event.listener.IGameEventListener;
|
import baritone.api.event.listener.IGameEventListener;
|
||||||
|
import baritone.bot.UserManager;
|
||||||
import baritone.api.utils.Helper;
|
import baritone.api.utils.Helper;
|
||||||
import baritone.cache.WorldProvider;
|
import baritone.cache.WorldProvider;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
@@ -29,6 +30,7 @@ import net.minecraft.world.World;
|
|||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,6 +68,9 @@ public final class GameEventHandler implements IEventBus, Helper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onSendChatMessage(ChatEvent event) {
|
public final void onSendChatMessage(ChatEvent event) {
|
||||||
|
// Ensure UserManager is created to prevent a ConcurrentModificationException
|
||||||
|
Objects.requireNonNull(UserManager.INSTANCE);
|
||||||
|
|
||||||
listeners.forEach(l -> l.onSendChatMessage(event));
|
listeners.forEach(l -> l.onSendChatMessage(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +94,7 @@ public final class GameEventHandler implements IEventBus, Helper {
|
|||||||
// to make sure the chunk being unloaded is already loaded.
|
// to make sure the chunk being unloaded is already loaded.
|
||||||
boolean isPreUnload = state == EventState.PRE
|
boolean isPreUnload = state == EventState.PRE
|
||||||
&& type == ChunkEvent.Type.UNLOAD
|
&& type == ChunkEvent.Type.UNLOAD
|
||||||
&& world.getChunkProvider().getChunk(event.getX(), event.getZ(), false, false) != null;
|
&& world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
|
||||||
|
|
||||||
if (isPostPopulate || isPreUnload) {
|
if (isPostPopulate || isPreUnload) {
|
||||||
baritone.getWorldProvider().ifWorldLoaded(worldData -> {
|
baritone.getWorldProvider().ifWorldLoaded(worldData -> {
|
||||||
@@ -114,7 +119,7 @@ public final class GameEventHandler implements IEventBus, Helper {
|
|||||||
if (event.getState() == EventState.POST) {
|
if (event.getState() == EventState.POST) {
|
||||||
cache.closeWorld();
|
cache.closeWorld();
|
||||||
if (event.getWorld() != null) {
|
if (event.getWorld() != null) {
|
||||||
cache.initWorld(event.getWorld().getDimension().getType());
|
cache.initWorld(event.getWorld().provider.getDimensionType().getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public class CalculationContext {
|
|||||||
this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread);
|
this.bsi = new BlockStateInterface(world, worldData, forUseOnAnotherThread);
|
||||||
this.toolSet = new ToolSet(player);
|
this.toolSet = new ToolSet(player);
|
||||||
this.hasThrowaway = Baritone.settings().allowPlace.value && ((Baritone) baritone).getInventoryBehavior().hasGenericThrowaway();
|
this.hasThrowaway = Baritone.settings().allowPlace.value && ((Baritone) baritone).getInventoryBehavior().hasGenericThrowaway();
|
||||||
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.getDimension().isNether();
|
this.hasWaterBucket = Baritone.settings().allowWaterBucketFall.value && InventoryPlayer.isHotbar(player.inventory.getSlotFor(STACK_BUCKET_WATER)) && !world.provider.isNether();
|
||||||
this.canSprint = Baritone.settings().allowSprint.value && player.getFoodStats().getFoodLevel() > 6;
|
this.canSprint = Baritone.settings().allowSprint.value && player.getFoodStats().getFoodLevel() > 6;
|
||||||
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.value;
|
this.placeBlockCost = Baritone.settings().blockPlacementPenalty.value;
|
||||||
this.allowBreak = Baritone.settings().allowBreak.value;
|
this.allowBreak = Baritone.settings().allowBreak.value;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import baritone.api.utils.*;
|
|||||||
import baritone.api.utils.input.Input;
|
import baritone.api.utils.input.Input;
|
||||||
import baritone.behavior.PathingBehavior;
|
import baritone.behavior.PathingBehavior;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
|
import net.minecraft.block.BlockLiquid;
|
||||||
import net.minecraft.entity.item.EntityFallingBlock;
|
import net.minecraft.entity.item.EntityFallingBlock;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
@@ -122,7 +123,7 @@ public abstract class Movement implements IMovement, MovementHelper {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MovementStatus update() {
|
public MovementStatus update() {
|
||||||
ctx.player().abilities.isFlying = false;
|
ctx.player().capabilities.isFlying = false;
|
||||||
currentState = updateState(currentState);
|
currentState = updateState(currentState);
|
||||||
if (MovementHelper.isLiquid(ctx, ctx.playerFeet())) {
|
if (MovementHelper.isLiquid(ctx, ctx.playerFeet())) {
|
||||||
currentState.setInput(Input.JUMP, true);
|
currentState.setInput(Input.JUMP, true);
|
||||||
@@ -160,7 +161,7 @@ public abstract class Movement implements IMovement, MovementHelper {
|
|||||||
if (!ctx.world().getEntitiesWithinAABB(EntityFallingBlock.class, new AxisAlignedBB(0, 0, 0, 1, 1.1, 1).offset(blockPos)).isEmpty() && Baritone.settings().pauseMiningForFallingBlocks.value) {
|
if (!ctx.world().getEntitiesWithinAABB(EntityFallingBlock.class, new AxisAlignedBB(0, 0, 0, 1, 1.1, 1).offset(blockPos)).isEmpty() && Baritone.settings().pauseMiningForFallingBlocks.value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.canWalkThrough(ctx, blockPos)) { // can't break air, so don't try
|
if (!MovementHelper.canWalkThrough(ctx, blockPos) && !(BlockStateInterface.getBlock(ctx, blockPos) instanceof BlockLiquid)) { // can't break liquid, so don't try
|
||||||
somethingInTheWay = true;
|
somethingInTheWay = true;
|
||||||
MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, blockPos));
|
MovementHelper.switchToBestToolFor(ctx, BlockStateInterface.get(ctx, blockPos));
|
||||||
Optional<Rotation> reachable = RotationUtils.reachable(ctx.player(), blockPos, ctx.playerController().getBlockReachDistance());
|
Optional<Rotation> reachable = RotationUtils.reachable(ctx.player(), blockPos, ctx.playerController().getBlockReachDistance());
|
||||||
@@ -176,7 +177,7 @@ public abstract class Movement implements IMovement, MovementHelper {
|
|||||||
//i'm doing it anyway
|
//i'm doing it anyway
|
||||||
//i dont care if theres snow in the way!!!!!!!
|
//i dont care if theres snow in the way!!!!!!!
|
||||||
//you dont own me!!!!
|
//you dont own me!!!!
|
||||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.player().getEyePosition(1.0F),
|
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
|
||||||
VecUtils.getBlockPosCenter(blockPos), ctx.playerRotations()), true)
|
VecUtils.getBlockPosCenter(blockPos), ctx.playerRotations()), true)
|
||||||
);
|
);
|
||||||
// don't check selectedblock on this one, this is a fallback when we can't see any face directly, it's intended to be breaking the "incorrect" block
|
// don't check selectedblock on this one, this is a fallback when we can't see any face directly, it's intended to be breaking the "incorrect" block
|
||||||
|
|||||||
@@ -28,21 +28,14 @@ import baritone.pathing.movement.MovementState.MovementTarget;
|
|||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.ToolSet;
|
import baritone.utils.ToolSet;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
|
import net.minecraft.block.properties.PropertyBool;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.fluid.FlowingFluid;
|
|
||||||
import net.minecraft.fluid.Fluid;
|
|
||||||
import net.minecraft.fluid.IFluidState;
|
|
||||||
import net.minecraft.fluid.WaterFluid;
|
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.init.Fluids;
|
|
||||||
import net.minecraft.pathfinding.PathType;
|
|
||||||
import net.minecraft.state.BooleanProperty;
|
|
||||||
import net.minecraft.state.properties.SlabType;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockAccess;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -80,7 +73,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
&& BlockFalling.canFallThrough(bsi.get0(x, y - 1, z))) { // and if it would fall (i.e. it's unsupported)
|
&& BlockFalling.canFallThrough(bsi.get0(x, y - 1, z))) { // and if it would fall (i.e. it's unsupported)
|
||||||
return true; // dont break a block that is adjacent to unsupported gravel because it can cause really weird stuff
|
return true; // dont break a block that is adjacent to unsupported gravel because it can cause really weird stuff
|
||||||
}
|
}
|
||||||
return !state.getFluidState().isEmpty();
|
return block instanceof BlockLiquid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canWalkThrough(IPlayerContext ctx, BetterBlockPos pos) {
|
static boolean canWalkThrough(IPlayerContext ctx, BetterBlockPos pos) {
|
||||||
@@ -93,10 +86,10 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
|
|
||||||
static boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
static boolean canWalkThrough(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block instanceof BlockAir) { // early return for most common case
|
if (block == Blocks.AIR) { // early return for most common case
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.COBWEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof BlockAbstractSkull || block == Blocks.BUBBLE_COLUMN || block instanceof BlockShulkerBox || block instanceof BlockSlab || block instanceof BlockTrapDoor) {
|
if (block == Blocks.FIRE || block == Blocks.TRIPWIRE || block == Blocks.WEB || block == Blocks.END_PORTAL || block == Blocks.COCOA || block instanceof BlockSkull || block instanceof BlockTrapDoor) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (Baritone.settings().blocksToAvoid.value.contains(block)) {
|
if (Baritone.settings().blocksToAvoid.value.contains(block)) {
|
||||||
@@ -108,10 +101,10 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
// be opened by just interacting.
|
// be opened by just interacting.
|
||||||
return block != Blocks.IRON_DOOR;
|
return block != Blocks.IRON_DOOR;
|
||||||
}
|
}
|
||||||
if (block instanceof BlockCarpet) {
|
if (block == Blocks.CARPET) {
|
||||||
return canWalkOn(bsi, x, y - 1, z);
|
return canWalkOn(bsi, x, y - 1, z);
|
||||||
}
|
}
|
||||||
if (block instanceof BlockSnowLayer) {
|
if (block instanceof BlockSnow) {
|
||||||
// we've already checked doors and fence gates
|
// we've already checked doors and fence gates
|
||||||
// so the only remaining dynamic isPassables are snow and trapdoor
|
// so the only remaining dynamic isPassables are snow and trapdoor
|
||||||
// if they're cached as a top block, we don't know their metadata
|
// if they're cached as a top block, we don't know their metadata
|
||||||
@@ -121,7 +114,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
}
|
}
|
||||||
// the check in BlockSnow.isPassable is layers < 5
|
// 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
|
// while actually, we want < 3 because 3 or greater makes it impassable in a 2 high ceiling
|
||||||
if (state.get(BlockSnowLayer.LAYERS) >= 3) {
|
if (state.getValue(BlockSnow.LAYERS) >= 3) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// ok, it's low enough we could walk through it, but is it supported?
|
// ok, it's low enough we could walk through it, but is it supported?
|
||||||
@@ -130,21 +123,18 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
if (isFlowing(x, y, z, state, bsi)) {
|
if (isFlowing(x, y, z, state, bsi)) {
|
||||||
return false; // Don't walk through flowing liquids
|
return false; // Don't walk through flowing liquids
|
||||||
}
|
}
|
||||||
IFluidState fluidState = state.getFluidState();
|
if (block instanceof BlockLiquid) {
|
||||||
if (fluidState.getFluid() instanceof WaterFluid) {
|
|
||||||
if (Baritone.settings().assumeWalkOnWater.value) {
|
if (Baritone.settings().assumeWalkOnWater.value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
IBlockState up = bsi.get0(x, y + 1, z);
|
IBlockState up = bsi.get0(x, y + 1, z);
|
||||||
if (!up.getFluidState().isEmpty() || up.getBlock() instanceof BlockLilyPad) {
|
if (up.getBlock() instanceof BlockLiquid || up.getBlock() instanceof BlockLilyPad) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return block == Blocks.WATER || block == Blocks.FLOWING_WATER;
|
||||||
}
|
}
|
||||||
// every block that overrides isPassable with anything more complicated than a "return true;" or "return false;"
|
|
||||||
// has already been accounted for above
|
return block.isPassable(bsi.access, bsi.isPassableBlockPos.setPos(x, y, z));
|
||||||
// therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null
|
|
||||||
return state.allowsMovement(bsi.access, BlockPos.ORIGIN, PathType.LAND); // workaround for future compatibility =P
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,30 +159,29 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return fullyPassable(ctx.world(), pos, ctx.world().getBlockState(pos));
|
return fullyPassable(ctx.world(), pos, ctx.world().getBlockState(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean fullyPassable(IBlockReader access, BlockPos pos, IBlockState state) {
|
static boolean fullyPassable(IBlockAccess access, BlockPos pos, IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block instanceof BlockAir) { // early return for most common case
|
if (block == Blocks.AIR) { // early return for most common case
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// exceptions - blocks that are isPassable true, but we can't actually jump through
|
// exceptions - blocks that are isPassable true, but we can't actually jump through
|
||||||
if (block == Blocks.FIRE
|
if (block == Blocks.FIRE
|
||||||
|| block == Blocks.TRIPWIRE
|
|| block == Blocks.TRIPWIRE
|
||||||
|| block == Blocks.COBWEB
|
|| block == Blocks.WEB
|
||||||
|| block == Blocks.VINE
|
|| block == Blocks.VINE
|
||||||
|| block == Blocks.LADDER
|
|| block == Blocks.LADDER
|
||||||
|| block == Blocks.COCOA
|
|| block == Blocks.COCOA
|
||||||
|| block instanceof BlockDoor
|
|| block instanceof BlockDoor
|
||||||
|| block instanceof BlockFenceGate
|
|| block instanceof BlockFenceGate
|
||||||
|| block instanceof BlockSnow
|
|| block instanceof BlockSnow
|
||||||
|| !state.getFluidState().isEmpty()
|
|| block instanceof BlockLiquid
|
||||||
|| block instanceof BlockTrapDoor
|
|| block instanceof BlockTrapDoor
|
||||||
|| block instanceof BlockEndPortal
|
|| block instanceof BlockEndPortal
|
||||||
|| block instanceof BlockSkull
|
|| block instanceof BlockSkull) {
|
||||||
|| block instanceof BlockShulkerBox) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
|
// door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters
|
||||||
return state.allowsMovement(access, pos, PathType.LAND);
|
return block.isPassable(access, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isReplaceable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
|
static boolean isReplaceable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
|
||||||
@@ -207,19 +196,20 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block instanceof BlockAir) {
|
if (block == Blocks.AIR || isWater(block)) {
|
||||||
// early return for common cases hehe
|
// early return for common cases hehe
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block instanceof BlockSnowLayer) {
|
if (block instanceof BlockSnow) {
|
||||||
// as before, default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
|
// as before, default to true (mostly because it would otherwise make long distance pathing through snowy biomes impossible)
|
||||||
if (!bsi.worldContainsLoadedChunk(x, z)) {
|
if (!bsi.worldContainsLoadedChunk(x, z)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return state.get(BlockSnowLayer.LAYERS) == 1;
|
return state.getValue(BlockSnow.LAYERS) == 1;
|
||||||
}
|
}
|
||||||
if (block == Blocks.LARGE_FERN || block == Blocks.TALL_GRASS) {
|
if (block instanceof BlockDoublePlant) {
|
||||||
return true;
|
BlockDoublePlant.EnumPlantType kek = state.getValue(BlockDoublePlant.VARIANT);
|
||||||
|
return kek == BlockDoublePlant.EnumPlantType.FERN || kek == BlockDoublePlant.EnumPlantType.GRASS;
|
||||||
}
|
}
|
||||||
return state.getMaterial().isReplaceable();
|
return state.getMaterial().isReplaceable();
|
||||||
}
|
}
|
||||||
@@ -252,16 +242,16 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.get(BlockFenceGate.OPEN);
|
return state.getValue(BlockFenceGate.OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isHorizontalBlockPassable(BlockPos blockPos, IBlockState blockState, BlockPos playerPos, BooleanProperty propertyOpen) {
|
static boolean isHorizontalBlockPassable(BlockPos blockPos, IBlockState blockState, BlockPos playerPos, PropertyBool propertyOpen) {
|
||||||
if (playerPos.equals(blockPos)) {
|
if (playerPos.equals(blockPos)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumFacing.Axis facing = blockState.get(BlockHorizontal.HORIZONTAL_FACING).getAxis();
|
EnumFacing.Axis facing = blockState.getValue(BlockHorizontal.FACING).getAxis();
|
||||||
boolean open = blockState.get(propertyOpen);
|
boolean open = blockState.getValue(propertyOpen);
|
||||||
|
|
||||||
EnumFacing.Axis playerFacing;
|
EnumFacing.Axis playerFacing;
|
||||||
if (playerPos.north().equals(blockPos) || playerPos.south().equals(blockPos)) {
|
if (playerPos.north().equals(blockPos) || playerPos.south().equals(blockPos)) {
|
||||||
@@ -275,15 +265,13 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
return (facing == playerFacing) == open;
|
return (facing == playerFacing) == open;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean avoidWalkingInto(IBlockState state) {
|
static boolean avoidWalkingInto(Block block) {
|
||||||
Block block = state.getBlock();
|
return block instanceof BlockLiquid
|
||||||
return !state.getFluidState().isEmpty()
|
|| block == Blocks.MAGMA
|
||||||
|| block == Blocks.MAGMA_BLOCK
|
|
||||||
|| block == Blocks.CACTUS
|
|| block == Blocks.CACTUS
|
||||||
|| block == Blocks.FIRE
|
|| block == Blocks.FIRE
|
||||||
|| block == Blocks.END_PORTAL
|
|| block == Blocks.END_PORTAL
|
||||||
|| block == Blocks.COBWEB
|
|| block == Blocks.WEB;
|
||||||
|| block == Blocks.BUBBLE_COLUMN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -300,7 +288,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
*/
|
*/
|
||||||
static boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
static boolean canWalkOn(BlockStateInterface bsi, int x, int y, int z, IBlockState state) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (block instanceof BlockAir || block == Blocks.MAGMA_BLOCK || block == Blocks.BUBBLE_COLUMN) {
|
if (block == Blocks.AIR || block == Blocks.MAGMA) {
|
||||||
// early return for most common case (air)
|
// early return for most common case (air)
|
||||||
// plus magma, which is a normal cube but it hurts you
|
// plus magma, which is a normal cube but it hurts you
|
||||||
return false;
|
return false;
|
||||||
@@ -317,31 +305,33 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) {
|
if (block == Blocks.ENDER_CHEST || block == Blocks.CHEST) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (isWater(state)) {
|
if (isWater(block)) {
|
||||||
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
|
// since this is called literally millions of times per second, the benefit of not allocating millions of useless "pos.up()"
|
||||||
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
|
// BlockPos s that we'd just garbage collect immediately is actually noticeable. I don't even think its a decrease in readability
|
||||||
IBlockState upState = bsi.get0(x, y + 1, z);
|
Block up = bsi.get0(x, y + 1, z).getBlock();
|
||||||
Block up = upState.getBlock();
|
if (up == Blocks.WATERLILY || up == Blocks.CARPET) {
|
||||||
if (up == Blocks.LILY_PAD || up instanceof BlockCarpet) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (isFlowing(x, y, z, state, bsi) || upState.getFluidState().getFluid() == Fluids.FLOWING_WATER) {
|
if (isFlowing(x, y, z, state, bsi) || block == Blocks.FLOWING_WATER) {
|
||||||
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off
|
// the only scenario in which we can walk on flowing water is if it's under still water with jesus off
|
||||||
return isWater(upState) && !Baritone.settings().assumeWalkOnWater.value;
|
return isWater(up) && !Baritone.settings().assumeWalkOnWater.value;
|
||||||
}
|
}
|
||||||
// if assumeWalkOnWater is on, we can only walk on water if there isn't water above it
|
// if assumeWalkOnWater is on, we can only walk on water if there isn't water above it
|
||||||
// if assumeWalkOnWater is off, we can only walk on water if there is water above it
|
// if assumeWalkOnWater is off, we can only walk on water if there is water above it
|
||||||
return isWater(upState) ^ Baritone.settings().assumeWalkOnWater.value;
|
return isWater(up) ^ Baritone.settings().assumeWalkOnWater.value;
|
||||||
}
|
}
|
||||||
if (Baritone.settings().assumeWalkOnLava.value && isLava(state) && !isFlowing(x, y, z, state, bsi)) {
|
if (Baritone.settings().assumeWalkOnLava.value && isLava(block) && !isFlowing(x, y, z, state, bsi)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block == Blocks.GLASS || block instanceof BlockStainedGlass) {
|
if (block == Blocks.GLASS || block == Blocks.STAINED_GLASS) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (block instanceof BlockSlab) {
|
if (block instanceof BlockSlab) {
|
||||||
if (!Baritone.settings().allowWalkOnBottomSlab.value) {
|
if (!Baritone.settings().allowWalkOnBottomSlab.value) {
|
||||||
return state.isTopSolid();
|
if (((BlockSlab) block).isDouble()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return state.getValue(BlockSlab.HALF) != BlockSlab.EnumBlockHalf.BOTTOM;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -380,7 +370,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
// can we look at the center of a side face of this block and likely be able to place?
|
// can we look at the center of a side face of this block and likely be able to place?
|
||||||
// (thats how this check is used)
|
// (thats how this check is used)
|
||||||
// therefore dont include weird things that we technically could place against (like carpet) but practically can't
|
// therefore dont include weird things that we technically could place against (like carpet) but practically can't
|
||||||
return state.isBlockNormalCube() || state.isFullCube() || state.getBlock() == Blocks.GLASS || state.getBlock() instanceof BlockStainedGlass;
|
return state.isBlockNormalCube() || state.isFullBlock() || state.getBlock() == Blocks.GLASS || state.getBlock() == Blocks.STAINED_GLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) {
|
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) {
|
||||||
@@ -390,7 +380,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state, boolean includeFalling) {
|
static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state, boolean includeFalling) {
|
||||||
Block block = state.getBlock();
|
Block block = state.getBlock();
|
||||||
if (!canWalkThrough(context.bsi, x, y, z, state)) {
|
if (!canWalkThrough(context.bsi, x, y, z, state)) {
|
||||||
if (!state.getFluidState().isEmpty()) {
|
if (block instanceof BlockLiquid) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
double mult = context.breakCostMultiplierAt(x, y, z, state);
|
double mult = context.breakCostMultiplierAt(x, y, z, state);
|
||||||
@@ -420,7 +410,8 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
|
|
||||||
static boolean isBottomSlab(IBlockState state) {
|
static boolean isBottomSlab(IBlockState state) {
|
||||||
return state.getBlock() instanceof BlockSlab
|
return state.getBlock() instanceof BlockSlab
|
||||||
&& state.get(BlockSlab.TYPE) == SlabType.BOTTOM;
|
&& !((BlockSlab) state.getBlock()).isDouble()
|
||||||
|
&& state.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -457,12 +448,11 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* Returns whether or not the specified block is
|
* Returns whether or not the specified block is
|
||||||
* water, regardless of whether or not it is flowing.
|
* water, regardless of whether or not it is flowing.
|
||||||
*
|
*
|
||||||
* @param state The block state
|
* @param b The block
|
||||||
* @return Whether or not the block is water
|
* @return Whether or not the block is water
|
||||||
*/
|
*/
|
||||||
static boolean isWater(IBlockState state) {
|
static boolean isWater(Block b) {
|
||||||
Fluid f = state.getFluidState().getFluid();
|
return b == Blocks.FLOWING_WATER || b == Blocks.WATER;
|
||||||
return f == Fluids.WATER || f == Fluids.FLOWING_WATER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -474,12 +464,11 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* @return Whether or not the block is water
|
* @return Whether or not the block is water
|
||||||
*/
|
*/
|
||||||
static boolean isWater(IPlayerContext ctx, BlockPos bp) {
|
static boolean isWater(IPlayerContext ctx, BlockPos bp) {
|
||||||
return isWater(BlockStateInterface.get(ctx, bp));
|
return isWater(BlockStateInterface.getBlock(ctx, bp));
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isLava(IBlockState state) {
|
static boolean isLava(Block b) {
|
||||||
Fluid f = state.getFluidState().getFluid();
|
return b == Blocks.FLOWING_LAVA || b == Blocks.LAVA;
|
||||||
return f == Fluids.LAVA || f == Fluids.FLOWING_LAVA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -490,25 +479,20 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
* @return Whether or not the block is a liquid
|
* @return Whether or not the block is a liquid
|
||||||
*/
|
*/
|
||||||
static boolean isLiquid(IPlayerContext ctx, BlockPos p) {
|
static boolean isLiquid(IPlayerContext ctx, BlockPos p) {
|
||||||
return isLiquid(BlockStateInterface.get(ctx, p));
|
return BlockStateInterface.getBlock(ctx, p) instanceof BlockLiquid;
|
||||||
}
|
|
||||||
|
|
||||||
static boolean isLiquid(IBlockState blockState) {
|
|
||||||
return !blockState.getFluidState().isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean possiblyFlowing(IBlockState state) {
|
static boolean possiblyFlowing(IBlockState state) {
|
||||||
IFluidState fluidState = state.getFluidState();
|
// Will be IFluidState in 1.13
|
||||||
return fluidState.getFluid() instanceof FlowingFluid
|
return state.getBlock() instanceof BlockLiquid
|
||||||
&& fluidState.getFluid().getLevel(fluidState) != 8;
|
&& state.getValue(BlockLiquid.LEVEL) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isFlowing(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
|
static boolean isFlowing(int x, int y, int z, IBlockState state, BlockStateInterface bsi) {
|
||||||
IFluidState fluidState = state.getFluidState();
|
if (!(state.getBlock() instanceof BlockLiquid)) {
|
||||||
if (!(fluidState.getFluid() instanceof FlowingFluid)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (fluidState.getFluid().getLevel(fluidState) != 8) {
|
if (state.getValue(BlockLiquid.LEVEL) != 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return possiblyFlowing(bsi.get0(x + 1, y, z))
|
return possiblyFlowing(bsi.get0(x + 1, y, z))
|
||||||
@@ -539,7 +523,7 @@ public interface MovementHelper extends ActionCosts, Helper {
|
|||||||
double faceZ = (placeAt.getZ() + against1.getZ() + 1.0D) * 0.5D;
|
double faceZ = (placeAt.getZ() + against1.getZ() + 1.0D) * 0.5D;
|
||||||
Rotation place = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
|
Rotation place = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations());
|
||||||
RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), place, ctx.playerController().getBlockReachDistance());
|
RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), place, ctx.playerController().getBlockReachDistance());
|
||||||
if (res != null && res.type == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(placeAt)) {
|
if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(placeAt)) {
|
||||||
state.setTarget(new MovementState.MovementTarget(place, true));
|
state.setTarget(new MovementState.MovementTarget(place, true));
|
||||||
found = true;
|
found = true;
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ public class MovementDescend extends Movement {
|
|||||||
IBlockState ontoBlock = context.get(destX, newY, destZ);
|
IBlockState ontoBlock = context.get(destX, newY, destZ);
|
||||||
int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY
|
int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY
|
||||||
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
|
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
|
||||||
if (MovementHelper.isWater(ontoBlock)) {
|
if (MovementHelper.isWater(ontoBlock.getBlock())) {
|
||||||
if (!MovementHelper.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) {
|
if (!MovementHelper.canWalkThrough(context.bsi, destX, newY, destZ, ontoBlock)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -224,7 +224,7 @@ public class MovementDescend extends Movement {
|
|||||||
double destZ = (src.getZ() + 0.5) * 0.17 + (dest.getZ() + 0.5) * 0.83;
|
double destZ = (src.getZ() + 0.5) * 0.17 + (dest.getZ() + 0.5) * 0.83;
|
||||||
EntityPlayerSP player = ctx.player();
|
EntityPlayerSP player = ctx.player();
|
||||||
state.setTarget(new MovementState.MovementTarget(
|
state.setTarget(new MovementState.MovementTarget(
|
||||||
new Rotation(RotationUtils.calcRotationFromVec3d(player.getEyePosition(1.0F),
|
new Rotation(RotationUtils.calcRotationFromVec3d(player.getPositionEyes(1.0F),
|
||||||
new Vec3d(destX, dest.getY(), destZ),
|
new Vec3d(destX, dest.getY(), destZ),
|
||||||
new Rotation(player.rotationYaw, player.rotationPitch)).getYaw(), player.rotationPitch),
|
new Rotation(player.rotationYaw, player.rotationPitch)).getYaw(), player.rotationPitch),
|
||||||
false
|
false
|
||||||
@@ -256,7 +256,7 @@ public class MovementDescend extends Movement {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (int y = 0; y <= 2; y++) { // we could hit any of the three blocks
|
for (int y = 0; y <= 2; y++) { // we could hit any of the three blocks
|
||||||
if (MovementHelper.avoidWalkingInto(BlockStateInterface.get(ctx, into.up(y)))) {
|
if (MovementHelper.avoidWalkingInto(BlockStateInterface.getBlock(ctx, into.up(y)))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,18 +116,17 @@ public class MovementDiagonal extends Movement {
|
|||||||
if (fromDown == Blocks.SOUL_SAND) {
|
if (fromDown == Blocks.SOUL_SAND) {
|
||||||
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
multiplier += (WALK_ONE_OVER_SOUL_SAND_COST - WALK_ONE_BLOCK_COST) / 2;
|
||||||
}
|
}
|
||||||
IBlockState cuttingOver1 = context.get(x, y - 1, destZ);
|
Block cuttingOver1 = context.get(x, y - 1, destZ).getBlock();
|
||||||
if (cuttingOver1.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver1)) {
|
if (cuttingOver1 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver1)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState cuttingOver2 = context.get(destX, y - 1, z);
|
Block cuttingOver2 = context.get(destX, y - 1, z).getBlock();
|
||||||
if (cuttingOver2.getBlock() == Blocks.MAGMA_BLOCK || MovementHelper.isLava(cuttingOver2)) {
|
if (cuttingOver2 == Blocks.MAGMA || MovementHelper.isLava(cuttingOver2)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Block startIn = context.getBlock(x, y, z);
|
||||||
boolean water = false;
|
boolean water = false;
|
||||||
IBlockState startState = context.get(x, y, z);
|
if (MovementHelper.isWater(startIn) || MovementHelper.isWater(destInto.getBlock())) {
|
||||||
Block startIn = startState.getBlock();
|
|
||||||
if (MovementHelper.isWater(startState) || MovementHelper.isWater(destInto)) {
|
|
||||||
if (ascend) {
|
if (ascend) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -147,8 +146,8 @@ public class MovementDiagonal extends Movement {
|
|||||||
boolean BMid = MovementHelper.canWalkThrough(context.bsi, destX, y + 1, z);
|
boolean BMid = MovementHelper.canWalkThrough(context.bsi, destX, y + 1, z);
|
||||||
boolean BLow = MovementHelper.canWalkThrough(context.bsi, destX, y, z, pb2);
|
boolean BLow = MovementHelper.canWalkThrough(context.bsi, destX, y, z, pb2);
|
||||||
if ((!(ATop && AMid && ALow) && !(BTop && BMid && BLow)) // no option
|
if ((!(ATop && AMid && ALow) && !(BTop && BMid && BLow)) // no option
|
||||||
|| MovementHelper.avoidWalkingInto(pb0) // bad
|
|| MovementHelper.avoidWalkingInto(pb0.getBlock()) // bad
|
||||||
|| MovementHelper.avoidWalkingInto(pb2) // bad
|
|| MovementHelper.avoidWalkingInto(pb2.getBlock()) // bad
|
||||||
|| (ATop && AMid && MovementHelper.canWalkOn(context.bsi, x, y, destZ, pb0)) // we could just ascend
|
|| (ATop && AMid && MovementHelper.canWalkOn(context.bsi, x, y, destZ, pb0)) // we could just ascend
|
||||||
|| (BTop && BMid && MovementHelper.canWalkOn(context.bsi, destX, y, z, pb2)) // we could just ascend
|
|| (BTop && BMid && MovementHelper.canWalkOn(context.bsi, destX, y, z, pb2)) // we could just ascend
|
||||||
|| (!ATop && AMid && ALow) // head bonk A
|
|| (!ATop && AMid && ALow) // head bonk A
|
||||||
@@ -175,7 +174,7 @@ public class MovementDiagonal extends Movement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState pb3 = context.get(destX, y + 1, z);
|
IBlockState pb3 = context.get(destX, y + 1, z);
|
||||||
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2) && pb2.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb3))) {
|
if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb3.getBlock()))) {
|
||||||
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
|
// at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -184,7 +183,7 @@ public class MovementDiagonal extends Movement {
|
|||||||
// and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible
|
// and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0) && pb0.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb1))) {
|
if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb1.getBlock()))) {
|
||||||
// and now that option B is fully calculated, see if we can edge around that way
|
// and now that option B is fully calculated, see if we can edge around that way
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import net.minecraft.block.Block;
|
|||||||
import net.minecraft.block.BlockLadder;
|
import net.minecraft.block.BlockLadder;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
import net.minecraft.fluid.WaterFluid;
|
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@@ -92,11 +91,10 @@ public class MovementFall extends Movement {
|
|||||||
BlockPos playerFeet = ctx.playerFeet();
|
BlockPos playerFeet = ctx.playerFeet();
|
||||||
Rotation toDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations());
|
Rotation toDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations());
|
||||||
Rotation targetRotation = null;
|
Rotation targetRotation = null;
|
||||||
IBlockState destState = ctx.world().getBlockState(dest);
|
Block destBlock = ctx.world().getBlockState(dest).getBlock();
|
||||||
Block destBlock = destState.getBlock();
|
boolean isWater = destBlock == Blocks.WATER || destBlock == Blocks.FLOWING_WATER;
|
||||||
boolean isWater = destState.getFluidState().getFluid() instanceof WaterFluid;
|
|
||||||
if (!isWater && willPlaceBucket() && !playerFeet.equals(dest)) {
|
if (!isWater && willPlaceBucket() && !playerFeet.equals(dest)) {
|
||||||
if (!InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().getDimension().isNether()) {
|
if (!InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().provider.isNether()) {
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +160,7 @@ public class MovementFall extends Movement {
|
|||||||
for (int i = 0; i < 15; i++) {
|
for (int i = 0; i < 15; i++) {
|
||||||
IBlockState state = ctx.world().getBlockState(ctx.playerFeet().down(i));
|
IBlockState state = ctx.world().getBlockState(ctx.playerFeet().down(i));
|
||||||
if (state.getBlock() == Blocks.LADDER) {
|
if (state.getBlock() == Blocks.LADDER) {
|
||||||
return state.get(BlockLadder.FACING);
|
return state.getValue(BlockLadder.FACING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -28,11 +28,10 @@ import baritone.pathing.movement.MovementState;
|
|||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
import baritone.utils.pathing.MutableMoveResult;
|
import baritone.utils.pathing.MutableMoveResult;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockLiquid;
|
||||||
import net.minecraft.block.BlockStairs;
|
import net.minecraft.block.BlockStairs;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.fluid.WaterFluid;
|
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.init.Fluids;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -79,7 +78,7 @@ public class MovementParkour extends Movement {
|
|||||||
// second most common case -- we could just traverse not parkour
|
// second most common case -- we could just traverse not parkour
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (MovementHelper.avoidWalkingInto(adj) && !(adj.getFluidState().getFluid() instanceof WaterFluid)) { // magma sucks
|
if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!MovementHelper.fullyPassable(context, x + xDiff, y + 1, z + zDiff)) {
|
if (!MovementHelper.fullyPassable(context, x + xDiff, y + 1, z + zDiff)) {
|
||||||
@@ -92,7 +91,7 @@ public class MovementParkour extends Movement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IBlockState standingOn = context.get(x, y - 1, z);
|
IBlockState standingOn = context.get(x, y - 1, z);
|
||||||
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn) || standingOn.getFluidState().getFluid() != Fluids.EMPTY) {
|
if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || standingOn.getBlock() instanceof BlockStairs || MovementHelper.isBottomSlab(standingOn) || standingOn.getBlock() instanceof BlockLiquid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int maxJump;
|
int maxJump;
|
||||||
@@ -178,7 +177,7 @@ public class MovementParkour extends Movement {
|
|||||||
|
|
||||||
private static boolean checkOvershootSafety(BlockStateInterface bsi, int x, int y, int z) {
|
private static boolean checkOvershootSafety(BlockStateInterface bsi, int x, int y, int z) {
|
||||||
// we're going to walk into these two blocks after the landing of the parkour anyway, so make sure they aren't avoidWalkingInto
|
// we're going to walk into these two blocks after the landing of the parkour anyway, so make sure they aren't avoidWalkingInto
|
||||||
return !MovementHelper.avoidWalkingInto(bsi.get0(x, y, z)) && !MovementHelper.avoidWalkingInto(bsi.get0(x, y + 1, z));
|
return !MovementHelper.avoidWalkingInto(bsi.get0(x, y, z).getBlock()) && !MovementHelper.avoidWalkingInto(bsi.get0(x, y + 1, z).getBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double costFromJumpDistance(int dist) {
|
private static double costFromJumpDistance(int dist) {
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class MovementPillar extends Movement {
|
|||||||
if (fromDown.getBlock() == Blocks.LADDER || fromDown.getBlock() == Blocks.VINE) {
|
if (fromDown.getBlock() == Blocks.LADDER || fromDown.getBlock() == Blocks.VINE) {
|
||||||
return COST_INF; // can't pillar from a ladder or vine onto something that isn't also climbable
|
return COST_INF; // can't pillar from a ladder or vine onto something that isn't also climbable
|
||||||
}
|
}
|
||||||
if (fromDown.getBlock() instanceof BlockSlab && !fromDown.isTopSolid()) {
|
if (fromDown.getBlock() instanceof BlockSlab && !((BlockSlab) fromDown.getBlock()).isDouble() && fromDown.getValue(BlockSlab.HALF) == BlockSlab.EnumBlockHalf.BOTTOM) {
|
||||||
return COST_INF; // can't pillar up from a bottom slab onto a non ladder
|
return COST_INF; // can't pillar up from a bottom slab onto a non ladder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,9 +77,9 @@ public class MovementPillar extends Movement {
|
|||||||
if (toBreakBlock instanceof BlockFenceGate) { // see issue #172
|
if (toBreakBlock instanceof BlockFenceGate) { // see issue #172
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
IBlockState srcUp = null;
|
Block srcUp = null;
|
||||||
if (MovementHelper.isWater(toBreak) && MovementHelper.isWater(fromState)) { // TODO should this also be allowed if toBreakBlock is air?
|
if (MovementHelper.isWater(toBreakBlock) && MovementHelper.isWater(from)) { // TODO should this also be allowed if toBreakBlock is air?
|
||||||
srcUp = context.get(x, y + 1, z);
|
srcUp = context.get(x, y + 1, z).getBlock();
|
||||||
if (MovementHelper.isWater(srcUp)) {
|
if (MovementHelper.isWater(srcUp)) {
|
||||||
return LADDER_UP_ONE_COST; // allow ascending pillars of water, but only if we're already in one
|
return LADDER_UP_ONE_COST; // allow ascending pillars of water, but only if we're already in one
|
||||||
}
|
}
|
||||||
@@ -91,11 +91,11 @@ public class MovementPillar extends Movement {
|
|||||||
if (placeCost >= COST_INF) {
|
if (placeCost >= COST_INF) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (fromDown.getBlock() instanceof BlockAir) {
|
if (fromDown.getBlock() == Blocks.AIR) {
|
||||||
placeCost += 0.1; // slightly (1/200th of a second) penalize pillaring on what's currently air
|
placeCost += 0.1; // slightly (1/200th of a second) penalize pillaring on what's currently air
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((MovementHelper.isLiquid(fromState) && !MovementHelper.canPlaceAgainst(context.bsi, x, y - 1, z, fromDown)) || (MovementHelper.isLiquid(fromDown) && context.assumeWalkOnWater)) {
|
if (from instanceof BlockLiquid || (fromDown.getBlock() instanceof BlockLiquid && context.assumeWalkOnWater)) {
|
||||||
// otherwise, if we're standing in water, we cannot pillar
|
// otherwise, if we're standing in water, we cannot pillar
|
||||||
// if we're standing on water and assumeWalkOnWater is true, we cannot pillar
|
// if we're standing on water and assumeWalkOnWater is true, we cannot pillar
|
||||||
// if we're standing on water and assumeWalkOnWater is false, we must have ascended to here, or sneak backplaced, so it is possible to pillar again
|
// if we're standing on water and assumeWalkOnWater is false, we must have ascended to here, or sneak backplaced, so it is possible to pillar again
|
||||||
@@ -113,9 +113,9 @@ public class MovementPillar extends Movement {
|
|||||||
if (check.getBlock() instanceof BlockFalling) {
|
if (check.getBlock() instanceof BlockFalling) {
|
||||||
// see MovementAscend's identical check for breaking a falling block above our head
|
// see MovementAscend's identical check for breaking a falling block above our head
|
||||||
if (srcUp == null) {
|
if (srcUp == null) {
|
||||||
srcUp = context.get(x, y + 1, z);
|
srcUp = context.get(x, y + 1, z).getBlock();
|
||||||
}
|
}
|
||||||
if (!(toBreakBlock instanceof BlockFalling) || !(srcUp.getBlock() instanceof BlockFalling)) {
|
if (!(toBreakBlock instanceof BlockFalling) || !(srcUp instanceof BlockFalling)) {
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,7 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IBlockState fromDown = BlockStateInterface.get(ctx, src);
|
IBlockState fromDown = BlockStateInterface.get(ctx, src);
|
||||||
if (MovementHelper.isWater(fromDown) && MovementHelper.isWater(ctx, dest)) {
|
if (MovementHelper.isWater(fromDown.getBlock()) && MovementHelper.isWater(ctx, dest)) {
|
||||||
// stay centered while swimming up a water column
|
// stay centered while swimming up a water column
|
||||||
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations()), false));
|
state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations()), false));
|
||||||
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
|
Vec3d destCenter = VecUtils.getBlockPosCenter(dest);
|
||||||
@@ -184,7 +184,7 @@ public class MovementPillar extends Movement {
|
|||||||
}
|
}
|
||||||
boolean ladder = fromDown.getBlock() == Blocks.LADDER || fromDown.getBlock() == Blocks.VINE;
|
boolean ladder = fromDown.getBlock() == Blocks.LADDER || fromDown.getBlock() == Blocks.VINE;
|
||||||
boolean vine = fromDown.getBlock() == Blocks.VINE;
|
boolean vine = fromDown.getBlock() == Blocks.VINE;
|
||||||
Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.player().getEyePosition(1.0F),
|
Rotation rotation = RotationUtils.calcRotationFromVec3d(ctx.player().getPositionEyes(1.0F),
|
||||||
VecUtils.getBlockPosCenter(positionToPlace),
|
VecUtils.getBlockPosCenter(positionToPlace),
|
||||||
new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch));
|
new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch));
|
||||||
if (!ladder) {
|
if (!ladder) {
|
||||||
@@ -193,7 +193,7 @@ public class MovementPillar extends Movement {
|
|||||||
|
|
||||||
boolean blockIsThere = MovementHelper.canWalkOn(ctx, src) || ladder;
|
boolean blockIsThere = MovementHelper.canWalkOn(ctx, src) || ladder;
|
||||||
if (ladder) {
|
if (ladder) {
|
||||||
BlockPos against = vine ? getAgainst(new CalculationContext(baritone), src) : src.offset(fromDown.get(BlockLadder.FACING).getOpposite());
|
BlockPos against = vine ? getAgainst(new CalculationContext(baritone), src) : src.offset(fromDown.getValue(BlockLadder.FACING).getOpposite());
|
||||||
if (against == null) {
|
if (against == null) {
|
||||||
logDirect("Unable to climb vines. Consider disabling allowVines.");
|
logDirect("Unable to climb vines. Consider disabling allowVines.");
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
|
|||||||
@@ -33,9 +33,7 @@ import baritone.utils.BlockStateInterface;
|
|||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import net.minecraft.block.*;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.fluid.WaterFluid;
|
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.state.properties.SlabType;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
@@ -73,12 +71,11 @@ public class MovementTraverse extends Movement {
|
|||||||
IBlockState pb0 = context.get(destX, y + 1, destZ);
|
IBlockState pb0 = context.get(destX, y + 1, destZ);
|
||||||
IBlockState pb1 = context.get(destX, y, destZ);
|
IBlockState pb1 = context.get(destX, y, destZ);
|
||||||
IBlockState destOn = context.get(destX, y - 1, destZ);
|
IBlockState destOn = context.get(destX, y - 1, destZ);
|
||||||
IBlockState down = context.get(x, y - 1, z);
|
Block srcDown = context.getBlock(x, y - 1, z);
|
||||||
Block srcDown = down.getBlock();
|
|
||||||
if (MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
|
if (MovementHelper.canWalkOn(context.bsi, destX, y - 1, destZ, destOn)) {//this is a walk, not a bridge
|
||||||
double WC = WALK_ONE_BLOCK_COST;
|
double WC = WALK_ONE_BLOCK_COST;
|
||||||
boolean water = false;
|
boolean water = false;
|
||||||
if (MovementHelper.isWater(pb0) || MovementHelper.isWater(pb1)) {
|
if (MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock())) {
|
||||||
WC = context.waterWalkSpeed;
|
WC = context.waterWalkSpeed;
|
||||||
water = true;
|
water = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -115,8 +112,8 @@ public class MovementTraverse extends Movement {
|
|||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
if (MovementHelper.isReplaceable(destX, y - 1, destZ, destOn, context.bsi)) {
|
if (MovementHelper.isReplaceable(destX, y - 1, destZ, destOn, context.bsi)) {
|
||||||
boolean throughWater = MovementHelper.isWater(pb0) || MovementHelper.isWater(pb1);
|
boolean throughWater = MovementHelper.isWater(pb0.getBlock()) || MovementHelper.isWater(pb1.getBlock());
|
||||||
if (MovementHelper.isWater(destOn) && throughWater) {
|
if (MovementHelper.isWater(destOn.getBlock()) && throughWater) {
|
||||||
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed
|
// this happens when assume walk on water is true and this is a traverse in water, which isn't allowed
|
||||||
return COST_INF;
|
return COST_INF;
|
||||||
}
|
}
|
||||||
@@ -142,10 +139,10 @@ public class MovementTraverse extends Movement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// now that we've checked all possible directions to side place, we actually need to backplace
|
// now that we've checked all possible directions to side place, we actually need to backplace
|
||||||
if (srcDown == Blocks.SOUL_SAND || (srcDown instanceof BlockSlab && down.get(BlockSlab.TYPE) != SlabType.DOUBLE)) {
|
if (srcDown == Blocks.SOUL_SAND || (srcDown instanceof BlockSlab && !((BlockSlab) srcDown).isDouble())) {
|
||||||
return COST_INF; // can't sneak and backplace against soul sand or half slabs (regardless of whether it's top half or bottom half) =/
|
return COST_INF; // can't sneak and backplace against soul sand or half slabs (regardless of whether it's top half or bottom half) =/
|
||||||
}
|
}
|
||||||
if (down.getFluidState() instanceof WaterFluid) {
|
if (srcDown == Blocks.FLOWING_WATER || srcDown == Blocks.WATER) {
|
||||||
return COST_INF; // this is obviously impossible
|
return COST_INF; // this is obviously impossible
|
||||||
}
|
}
|
||||||
WC = WC * (SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST);//since we are sneak backplacing, we are sneaking lol
|
WC = WC * (SNEAK_ONE_BLOCK_COST / WALK_ONE_BLOCK_COST);//since we are sneak backplacing, we are sneaking lol
|
||||||
@@ -170,10 +167,10 @@ public class MovementTraverse extends Movement {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
// and if it's fine to walk into the blocks in front
|
// and if it's fine to walk into the blocks in front
|
||||||
if (MovementHelper.avoidWalkingInto(pb0)) {
|
if (MovementHelper.avoidWalkingInto(pb0.getBlock())) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
if (MovementHelper.avoidWalkingInto(pb1)) {
|
if (MovementHelper.avoidWalkingInto(pb1.getBlock())) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
// and we aren't already pressed up against the block
|
// and we aren't already pressed up against the block
|
||||||
@@ -254,8 +251,8 @@ public class MovementTraverse extends Movement {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
BlockPos into = dest.subtract(src).add(dest);
|
BlockPos into = dest.subtract(src).add(dest);
|
||||||
IBlockState intoBelow = BlockStateInterface.get(ctx, into);
|
Block intoBelow = BlockStateInterface.get(ctx, into).getBlock();
|
||||||
IBlockState intoAbove = BlockStateInterface.get(ctx, into.up());
|
Block intoAbove = BlockStateInterface.get(ctx, into.up()).getBlock();
|
||||||
if (wasTheBridgeBlockAlwaysThere && (!MovementHelper.isLiquid(ctx, feet) || Baritone.settings().sprintInWater.value) && (!MovementHelper.avoidWalkingInto(intoBelow) || MovementHelper.isWater(intoBelow)) && !MovementHelper.avoidWalkingInto(intoAbove)) {
|
if (wasTheBridgeBlockAlwaysThere && (!MovementHelper.isLiquid(ctx, feet) || Baritone.settings().sprintInWater.value) && (!MovementHelper.avoidWalkingInto(intoBelow) || MovementHelper.isWater(intoBelow)) && !MovementHelper.avoidWalkingInto(intoAbove)) {
|
||||||
state.setInput(Input.SPRINT, true);
|
state.setInput(Input.SPRINT, true);
|
||||||
}
|
}
|
||||||
@@ -263,7 +260,7 @@ public class MovementTraverse extends Movement {
|
|||||||
IBlockState destDown = BlockStateInterface.get(ctx, dest.down());
|
IBlockState destDown = BlockStateInterface.get(ctx, dest.down());
|
||||||
BlockPos against = positionsToBreak[0];
|
BlockPos against = positionsToBreak[0];
|
||||||
if (feet.getY() != dest.getY() && ladder && (destDown.getBlock() == Blocks.VINE || destDown.getBlock() == Blocks.LADDER)) {
|
if (feet.getY() != dest.getY() && ladder && (destDown.getBlock() == Blocks.VINE || destDown.getBlock() == Blocks.LADDER)) {
|
||||||
against = destDown.getBlock() == Blocks.VINE ? MovementPillar.getAgainst(new CalculationContext(baritone), dest.down()) : dest.offset(destDown.get(BlockLadder.FACING).getOpposite());
|
against = destDown.getBlock() == Blocks.VINE ? MovementPillar.getAgainst(new CalculationContext(baritone), dest.down()) : dest.offset(destDown.getValue(BlockLadder.FACING).getOpposite());
|
||||||
if (against == null) {
|
if (against == null) {
|
||||||
logDirect("Unable to climb vines. Consider disabling allowVines.");
|
logDirect("Unable to climb vines. Consider disabling allowVines.");
|
||||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import baritone.pathing.movement.Movement;
|
|||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
import baritone.pathing.movement.movements.*;
|
import baritone.pathing.movement.movements.*;
|
||||||
import baritone.utils.BlockStateInterface;
|
import baritone.utils.BlockStateInterface;
|
||||||
|
import net.minecraft.block.BlockLiquid;
|
||||||
import net.minecraft.util.Tuple;
|
import net.minecraft.util.Tuple;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
@@ -129,7 +130,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
Tuple<Double, BlockPos> status = closestPathPos(path);
|
Tuple<Double, BlockPos> status = closestPathPos(path);
|
||||||
if (possiblyOffPath(status, MAX_DIST_FROM_PATH)) {
|
if (possiblyOffPath(status, MAX_DIST_FROM_PATH)) {
|
||||||
ticksAway++;
|
ticksAway++;
|
||||||
System.out.println("FAR AWAY FROM PATH FOR " + ticksAway + " TICKS. Current distance: " + status.getA() + ". Threshold: " + MAX_DIST_FROM_PATH);
|
System.out.println("FAR AWAY FROM PATH FOR " + ticksAway + " TICKS. Current distance: " + status.getFirst() + ". Threshold: " + MAX_DIST_FROM_PATH);
|
||||||
if (ticksAway > MAX_TICKS_AWAY) {
|
if (ticksAway > MAX_TICKS_AWAY) {
|
||||||
logDebug("Too far away from path for too long, cancelling path");
|
logDebug("Too far away from path for too long, cancelling path");
|
||||||
cancel();
|
cancel();
|
||||||
@@ -302,7 +303,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean possiblyOffPath(Tuple<Double, BlockPos> status, double leniency) {
|
private boolean possiblyOffPath(Tuple<Double, BlockPos> status, double leniency) {
|
||||||
double distanceFromPath = status.getA();
|
double distanceFromPath = status.getFirst();
|
||||||
if (distanceFromPath > leniency) {
|
if (distanceFromPath > leniency) {
|
||||||
// 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
|
// 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) {
|
if (path.movements().get(pathPosition) instanceof MovementFall) {
|
||||||
@@ -322,7 +323,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
* @return Whether or not it was possible to snap to the current player feet
|
* @return Whether or not it was possible to snap to the current player feet
|
||||||
*/
|
*/
|
||||||
public boolean snipsnapifpossible() {
|
public boolean snipsnapifpossible() {
|
||||||
if (!ctx.player().onGround && ctx.world().getFluidState(ctx.playerFeet()).isEmpty()) {
|
if (!ctx.player().onGround && !(ctx.world().getBlockState(ctx.playerFeet()).getBlock() instanceof BlockLiquid)) {
|
||||||
// if we're falling in the air, and not in water, don't splice
|
// if we're falling in the air, and not in water, don't splice
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@@ -425,7 +426,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
if (current instanceof MovementFall) {
|
if (current instanceof MovementFall) {
|
||||||
Tuple<Vec3d, BlockPos> data = overrideFall((MovementFall) current);
|
Tuple<Vec3d, BlockPos> data = overrideFall((MovementFall) current);
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
BetterBlockPos fallDest = new BetterBlockPos(data.getB());
|
BetterBlockPos fallDest = new BetterBlockPos(data.getSecond());
|
||||||
if (!path.positions().contains(fallDest)) {
|
if (!path.positions().contains(fallDest)) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
@@ -436,7 +437,7 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
clearKeys();
|
clearKeys();
|
||||||
behavior.baritone.getLookBehavior().updateTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), data.getA(), ctx.playerRotations()), false);
|
behavior.baritone.getLookBehavior().updateTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), data.getFirst(), ctx.playerRotations()), false);
|
||||||
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.MOVE_FORWARD, true);
|
behavior.baritone.getInputOverrideHandler().setInputForceState(Input.MOVE_FORWARD, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -528,10 +529,10 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MovementHelper.avoidWalkingInto(ctx.world().getBlockState(current.getSrc().up(3)))) {
|
if (MovementHelper.avoidWalkingInto(ctx.world().getBlockState(current.getSrc().up(3)).getBlock())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return !MovementHelper.avoidWalkingInto(ctx.world().getBlockState(next.getDest().up(2))); // codacy smh my head
|
return !MovementHelper.avoidWalkingInto(ctx.world().getBlockState(next.getDest().up(2)).getBlock()); // codacy smh my head
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean canSprintFromDescendInto(IPlayerContext ctx, IMovement current, IMovement next) {
|
private static boolean canSprintFromDescendInto(IPlayerContext ctx, IMovement current, IMovement next) {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import baritone.pathing.path.PathExecutor;
|
|||||||
import baritone.utils.BaritoneProcessHelper;
|
import baritone.utils.BaritoneProcessHelper;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
import net.minecraft.world.chunk.EmptyChunk;
|
||||||
|
|
||||||
@@ -103,7 +104,7 @@ public final class BackfillProcess extends BaritoneProcessHelper {
|
|||||||
.keySet()
|
.keySet()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(pos -> ctx.world().getBlockState(pos).getBlock() == Blocks.AIR)
|
.filter(pos -> ctx.world().getBlockState(pos).getBlock() == Blocks.AIR)
|
||||||
.filter(pos -> baritone.getBuilderProcess().placementPlausible(pos, Blocks.DIRT.getDefaultState()))
|
.filter(pos -> ctx.world().mayPlace(Blocks.DIRT, pos, false, EnumFacing.UP, null))
|
||||||
.filter(pos -> !partOfCurrentMovement(pos))
|
.filter(pos -> !partOfCurrentMovement(pos))
|
||||||
.sorted(Comparator.<BlockPos>comparingDouble(ctx.player()::getDistanceSq).reversed())
|
.sorted(Comparator.<BlockPos>comparingDouble(ctx.player()::getDistanceSq).reversed())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|||||||
@@ -45,19 +45,14 @@ import baritone.utils.schematic.SchematicSystem;
|
|||||||
import baritone.utils.schematic.schematica.SchematicaHelper;
|
import baritone.utils.schematic.schematica.SchematicaHelper;
|
||||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
import net.minecraft.block.BlockAir;
|
import net.minecraft.block.BlockAir;
|
||||||
import net.minecraft.block.BlockFlowingFluid;
|
import net.minecraft.block.BlockLiquid;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
|
||||||
import net.minecraft.item.ItemBlock;
|
import net.minecraft.item.ItemBlock;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.ItemUseContext;
|
|
||||||
import net.minecraft.nbt.CompressedStreamTools;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.Tuple;
|
import net.minecraft.util.Tuple;
|
||||||
import net.minecraft.util.math.*;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -148,11 +143,11 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
if (SchematicaHelper.isSchematicaPresent()) {
|
if (SchematicaHelper.isSchematicaPresent()) {
|
||||||
Optional<Tuple<IStaticSchematic, BlockPos>> schematic = SchematicaHelper.getOpenSchematic();
|
Optional<Tuple<IStaticSchematic, BlockPos>> schematic = SchematicaHelper.getOpenSchematic();
|
||||||
if (schematic.isPresent()) {
|
if (schematic.isPresent()) {
|
||||||
IStaticSchematic s = schematic.get().getA();
|
IStaticSchematic s = schematic.get().getFirst();
|
||||||
this.build(
|
this.build(
|
||||||
schematic.get().getA().toString(),
|
schematic.get().getFirst().toString(),
|
||||||
Baritone.settings().mapArtMode.value ? new MapArtSchematic(s) : s,
|
Baritone.settings().mapArtMode.value ? new MapArtSchematic(s) : s,
|
||||||
schematic.get().getB()
|
schematic.get().getSecond()
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
logDirect("No schematic currently open");
|
logDirect("No schematic currently open");
|
||||||
@@ -188,7 +183,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
IBlockState state = schematic.desiredState(x - origin.getX(), y - origin.getY(), z - origin.getZ(), current, this.approxPlaceable);
|
IBlockState state = schematic.desiredState(x - origin.getX(), y - origin.getY(), z - origin.getZ(), current, this.approxPlaceable);
|
||||||
if (state.getBlock() instanceof BlockAir) {
|
if (state.getBlock() == Blocks.AIR) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
@@ -211,7 +206,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
continue; // irrelevant
|
continue; // irrelevant
|
||||||
}
|
}
|
||||||
IBlockState curr = bcc.bsi.get0(x, y, z);
|
IBlockState curr = bcc.bsi.get0(x, y, z);
|
||||||
if (!(curr.getBlock() instanceof BlockAir) && !(curr.getBlock() == Blocks.WATER || curr.getBlock() == Blocks.LAVA) && !valid(curr, desired)) {
|
if (curr.getBlock() != Blocks.AIR && !(curr.getBlock() instanceof BlockLiquid) && !valid(curr, desired)) {
|
||||||
BetterBlockPos pos = new BetterBlockPos(x, y, z);
|
BetterBlockPos pos = new BetterBlockPos(x, y, z);
|
||||||
Optional<Rotation> rot = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
|
Optional<Rotation> rot = RotationUtils.reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
|
||||||
if (rot.isPresent()) {
|
if (rot.isPresent()) {
|
||||||
@@ -253,7 +248,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
}
|
}
|
||||||
IBlockState curr = bcc.bsi.get0(x, y, z);
|
IBlockState curr = bcc.bsi.get0(x, y, z);
|
||||||
if (MovementHelper.isReplaceable(x, y, z, curr, bcc.bsi) && !valid(curr, desired)) {
|
if (MovementHelper.isReplaceable(x, y, z, curr, bcc.bsi) && !valid(curr, desired)) {
|
||||||
if (dy == 1 && bcc.bsi.get0(x, y + 1, z).getBlock() instanceof BlockAir) {
|
if (dy == 1 && bcc.bsi.get0(x, y + 1, z).getBlock() == Blocks.AIR) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
desirableOnHotbar.add(desired);
|
desirableOnHotbar.add(desired);
|
||||||
@@ -268,11 +263,6 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean placementPlausible(BlockPos pos, IBlockState state) {
|
|
||||||
VoxelShape voxelshape = state.getCollisionShape(ctx.world(), pos);
|
|
||||||
return voxelshape.isEmpty() || ctx.world().checkNoEntityCollision(null, voxelshape.withOffset(pos.getX(), pos.getY(), pos.getZ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<Placement> possibleToPlace(IBlockState toPlace, int x, int y, int z, BlockStateInterface bsi) {
|
private Optional<Placement> possibleToPlace(IBlockState toPlace, int x, int y, int z, BlockStateInterface bsi) {
|
||||||
for (EnumFacing against : EnumFacing.values()) {
|
for (EnumFacing against : EnumFacing.values()) {
|
||||||
BetterBlockPos placeAgainstPos = new BetterBlockPos(x, y, z).offset(against);
|
BetterBlockPos placeAgainstPos = new BetterBlockPos(x, y, z).offset(against);
|
||||||
@@ -280,20 +270,17 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
if (MovementHelper.isReplaceable(placeAgainstPos.x, placeAgainstPos.y, placeAgainstPos.z, placeAgainstState, bsi)) {
|
if (MovementHelper.isReplaceable(placeAgainstPos.x, placeAgainstPos.y, placeAgainstPos.z, placeAgainstState, bsi)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!toPlace.isValidPosition(ctx.world(), new BetterBlockPos(x, y, z))) {
|
if (!ctx.world().mayPlace(toPlace.getBlock(), new BetterBlockPos(x, y, z), false, against, null)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!placementPlausible(new BetterBlockPos(x, y, z), toPlace)) {
|
AxisAlignedBB aabb = placeAgainstState.getBoundingBox(ctx.world(), placeAgainstPos);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
AxisAlignedBB aabb = placeAgainstState.getShape(ctx.world(), placeAgainstPos).getBoundingBox();
|
|
||||||
for (Vec3d placementMultiplier : aabbSideMultipliers(against)) {
|
for (Vec3d placementMultiplier : aabbSideMultipliers(against)) {
|
||||||
double placeX = placeAgainstPos.x + aabb.minX * placementMultiplier.x + aabb.maxX * (1 - placementMultiplier.x);
|
double placeX = placeAgainstPos.x + aabb.minX * placementMultiplier.x + aabb.maxX * (1 - placementMultiplier.x);
|
||||||
double placeY = placeAgainstPos.y + aabb.minY * placementMultiplier.y + aabb.maxY * (1 - placementMultiplier.y);
|
double placeY = placeAgainstPos.y + aabb.minY * placementMultiplier.y + aabb.maxY * (1 - placementMultiplier.y);
|
||||||
double placeZ = placeAgainstPos.z + aabb.minZ * placementMultiplier.z + aabb.maxZ * (1 - placementMultiplier.z);
|
double placeZ = placeAgainstPos.z + aabb.minZ * placementMultiplier.z + aabb.maxZ * (1 - placementMultiplier.z);
|
||||||
Rotation rot = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(placeX, placeY, placeZ), ctx.playerRotations());
|
Rotation rot = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(placeX, placeY, placeZ), ctx.playerRotations());
|
||||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot, ctx.playerController().getBlockReachDistance());
|
RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot, ctx.playerController().getBlockReachDistance());
|
||||||
if (result != null && result.type == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(placeAgainstPos) && result.sideHit == against.getOpposite()) {
|
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(placeAgainstPos) && result.sideHit == against.getOpposite()) {
|
||||||
OptionalInt hotbar = hasAnyItemThatWouldPlace(toPlace, result, rot);
|
OptionalInt hotbar = hasAnyItemThatWouldPlace(toPlace, result, rot);
|
||||||
if (hotbar.isPresent()) {
|
if (hotbar.isPresent()) {
|
||||||
return Optional.of(new Placement(hotbar.getAsInt(), placeAgainstPos, against.getOpposite(), rot));
|
return Optional.of(new Placement(hotbar.getAsInt(), placeAgainstPos, against.getOpposite(), rot));
|
||||||
@@ -315,24 +302,18 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
// the state depends on the facing of the player sometimes
|
// the state depends on the facing of the player sometimes
|
||||||
ctx.player().rotationYaw = rot.getYaw();
|
ctx.player().rotationYaw = rot.getYaw();
|
||||||
ctx.player().rotationPitch = rot.getPitch();
|
ctx.player().rotationPitch = rot.getPitch();
|
||||||
BlockItemUseContext meme = new BlockItemUseContext(new ItemUseContext(
|
IBlockState wouldBePlaced = ((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(
|
||||||
ctx.player(),
|
ctx.world(),
|
||||||
stack,
|
|
||||||
result.getBlockPos().offset(result.sideHit),
|
result.getBlockPos().offset(result.sideHit),
|
||||||
result.sideHit,
|
result.sideHit,
|
||||||
(float) result.hitVec.x - result.getBlockPos().getX(),
|
(float) result.hitVec.x - result.getBlockPos().getX(), // as in PlayerControllerMP
|
||||||
(float) result.hitVec.y - result.getBlockPos().getY(),
|
(float) result.hitVec.y - result.getBlockPos().getY(),
|
||||||
(float) result.hitVec.z - result.getBlockPos().getZ()
|
(float) result.hitVec.z - result.getBlockPos().getZ(),
|
||||||
));
|
stack.getItem().getMetadata(stack.getMetadata()),
|
||||||
IBlockState wouldBePlaced = ((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(meme);
|
ctx.player()
|
||||||
|
);
|
||||||
ctx.player().rotationYaw = originalYaw;
|
ctx.player().rotationYaw = originalYaw;
|
||||||
ctx.player().rotationPitch = originalPitch;
|
ctx.player().rotationPitch = originalPitch;
|
||||||
if (wouldBePlaced == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!meme.canPlace()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (valid(wouldBePlaced, desired)) {
|
if (valid(wouldBePlaced, desired)) {
|
||||||
return OptionalInt.of(i);
|
return OptionalInt.of(i);
|
||||||
}
|
}
|
||||||
@@ -442,8 +423,8 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
if (toBreak.isPresent() && isSafeToCancel && ctx.player().onGround) {
|
if (toBreak.isPresent() && isSafeToCancel && ctx.player().onGround) {
|
||||||
// we'd like to pause to break this block
|
// we'd like to pause to break this block
|
||||||
// only change look direction if it's safe (don't want to fuck up an in progress parkour for example
|
// only change look direction if it's safe (don't want to fuck up an in progress parkour for example
|
||||||
Rotation rot = toBreak.get().getB();
|
Rotation rot = toBreak.get().getSecond();
|
||||||
BetterBlockPos pos = toBreak.get().getA();
|
BetterBlockPos pos = toBreak.get().getFirst();
|
||||||
baritone.getLookBehavior().updateTarget(rot, true);
|
baritone.getLookBehavior().updateTarget(rot, true);
|
||||||
MovementHelper.switchToBestToolFor(ctx, bcc.get(pos));
|
MovementHelper.switchToBestToolFor(ctx, bcc.get(pos));
|
||||||
if (ctx.player().isSneaking()) {
|
if (ctx.player().isSneaking()) {
|
||||||
@@ -606,7 +587,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
placeable.add(pos);
|
placeable.add(pos);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (state.getBlock() instanceof BlockFlowingFluid) {
|
if (state.getBlock() instanceof BlockLiquid) {
|
||||||
// if the block itself is JUST a liquid (i.e. not just a waterlogged block), we CANNOT break it
|
// if the block itself is JUST a liquid (i.e. not just a waterlogged block), we CANNOT break it
|
||||||
// TODO for 1.13 make sure that this only matches pure water, not waterlogged blocks
|
// TODO for 1.13 make sure that this only matches pure water, not waterlogged blocks
|
||||||
if (!MovementHelper.possiblyFlowing(state)) {
|
if (!MovementHelper.possiblyFlowing(state)) {
|
||||||
@@ -682,14 +663,14 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Goal placementGoal(BlockPos pos, BuilderCalculationContext bcc) {
|
private Goal placementGoal(BlockPos pos, BuilderCalculationContext bcc) {
|
||||||
if (!(ctx.world().getBlockState(pos).getBlock() instanceof BlockAir)) { // TODO can this even happen?
|
if (ctx.world().getBlockState(pos).getBlock() != Blocks.AIR) { // TODO can this even happen?
|
||||||
return new GoalPlace(pos);
|
return new GoalPlace(pos);
|
||||||
}
|
}
|
||||||
boolean allowSameLevel = !(ctx.world().getBlockState(pos.up()).getBlock() instanceof BlockAir);
|
boolean allowSameLevel = ctx.world().getBlockState(pos.up()).getBlock() != Blocks.AIR;
|
||||||
IBlockState current = ctx.world().getBlockState(pos);
|
IBlockState current = ctx.world().getBlockState(pos);
|
||||||
for (EnumFacing facing : Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP) {
|
for (EnumFacing facing : Movement.HORIZONTALS_BUT_ALSO_DOWN_____SO_EVERY_DIRECTION_EXCEPT_UP) {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
if (MovementHelper.canPlaceAgainst(ctx, pos.offset(facing)) && placementPlausible(pos, bcc.getSchematic(pos.getX(), pos.getY(), pos.getZ(), current))) {
|
if (MovementHelper.canPlaceAgainst(ctx, pos.offset(facing)) && ctx.world().mayPlace(bcc.getSchematic(pos.getX(), pos.getY(), pos.getZ(), current).getBlock(), pos, false, facing, null)) {
|
||||||
return new GoalAdjacent(pos, pos.offset(facing), allowSameLevel);
|
return new GoalAdjacent(pos, pos.offset(facing), allowSameLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -782,7 +763,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// <toxic cloud>
|
// <toxic cloud>
|
||||||
result.add(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(new BlockItemUseContext(new ItemUseContext(ctx.player(), stack, ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ))));
|
result.add(((ItemBlock) stack.getItem()).getBlock().getStateForPlacement(ctx.world(), ctx.playerFeet(), EnumFacing.UP, (float) ctx.player().posX, (float) ctx.player().posY, (float) ctx.player().posZ, stack.getItem().getMetadata(stack.getMetadata()), ctx.player()));
|
||||||
// </toxic cloud>
|
// </toxic cloud>
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -792,13 +773,10 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
if (desired == null) {
|
if (desired == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (current.getBlock() instanceof BlockAir && desired.getBlock() instanceof BlockAir) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ((current.getBlock() == Blocks.WATER || current.getBlock() == Blocks.LAVA) && Baritone.settings().okIfWater.value) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// TODO more complicated comparison logic I guess
|
// TODO more complicated comparison logic I guess
|
||||||
|
if (current.getBlock() instanceof BlockLiquid && Baritone.settings().okIfWater.value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (desired.getBlock() instanceof BlockAir && Baritone.settings().buildIgnoreBlocks.value.contains(current.getBlock())) {
|
if (desired.getBlock() instanceof BlockAir && Baritone.settings().buildIgnoreBlocks.value.contains(current.getBlock())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -844,7 +822,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
IBlockState sch = getSchematic(x, y, z, current);
|
IBlockState sch = getSchematic(x, y, z, current);
|
||||||
if (sch != null) {
|
if (sch != null) {
|
||||||
// TODO this can return true even when allowPlace is off.... is that an issue?
|
// TODO this can return true even when allowPlace is off.... is that an issue?
|
||||||
if (sch.getBlock() instanceof BlockAir) {
|
if (sch.getBlock() == Blocks.AIR) {
|
||||||
// we want this to be air, but they're asking if they can place here
|
// we want this to be air, but they're asking if they can place here
|
||||||
// this won't be a schematic block, this will be a throwaway
|
// this won't be a schematic block, this will be a throwaway
|
||||||
return placeBlockCost * 2; // we're going to have to break it eventually
|
return placeBlockCost * 2; // we're going to have to break it eventually
|
||||||
@@ -877,7 +855,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
|
|||||||
}
|
}
|
||||||
IBlockState sch = getSchematic(x, y, z, current);
|
IBlockState sch = getSchematic(x, y, z, current);
|
||||||
if (sch != null) {
|
if (sch != null) {
|
||||||
if (sch.getBlock() instanceof BlockAir) {
|
if (sch.getBlock() == Blocks.AIR) {
|
||||||
// it should be air
|
// it should be air
|
||||||
// regardless of current contents, we can break it
|
// regardless of current contents, we can break it
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ import net.minecraft.entity.Entity;
|
|||||||
import net.minecraft.entity.item.EntityItem;
|
import net.minecraft.entity.item.EntityItem;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
|
import net.minecraft.item.EnumDyeColor;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemDye;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@@ -71,17 +73,17 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
|
|||||||
Items.BEETROOT_SEEDS,
|
Items.BEETROOT_SEEDS,
|
||||||
Items.BEETROOT,
|
Items.BEETROOT,
|
||||||
Items.MELON_SEEDS,
|
Items.MELON_SEEDS,
|
||||||
Items.MELON_SLICE,
|
Items.MELON,
|
||||||
Blocks.MELON.asItem(),
|
Item.getItemFromBlock(Blocks.MELON_BLOCK),
|
||||||
Items.WHEAT_SEEDS,
|
Items.WHEAT_SEEDS,
|
||||||
Items.WHEAT,
|
Items.WHEAT,
|
||||||
Items.PUMPKIN_SEEDS,
|
Items.PUMPKIN_SEEDS,
|
||||||
Blocks.PUMPKIN.asItem(),
|
Item.getItemFromBlock(Blocks.PUMPKIN),
|
||||||
Items.POTATO,
|
Items.POTATO,
|
||||||
Items.CARROT,
|
Items.CARROT,
|
||||||
Items.NETHER_WART,
|
Items.NETHER_WART,
|
||||||
Blocks.SUGAR_CANE.asItem(),
|
Items.REEDS,
|
||||||
Blocks.CACTUS.asItem()
|
Item.getItemFromBlock(Blocks.CACTUS)
|
||||||
);
|
);
|
||||||
|
|
||||||
public FarmProcess(Baritone baritone) {
|
public FarmProcess(Baritone baritone) {
|
||||||
@@ -105,9 +107,9 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
|
|||||||
POTATOES((BlockCrops) Blocks.POTATOES),
|
POTATOES((BlockCrops) Blocks.POTATOES),
|
||||||
BEETROOT((BlockCrops) Blocks.BEETROOTS),
|
BEETROOT((BlockCrops) Blocks.BEETROOTS),
|
||||||
PUMPKIN(Blocks.PUMPKIN, state -> true),
|
PUMPKIN(Blocks.PUMPKIN, state -> true),
|
||||||
MELON(Blocks.MELON, state -> true),
|
MELON(Blocks.MELON_BLOCK, state -> true),
|
||||||
NETHERWART(Blocks.NETHER_WART, state -> state.get(BlockNetherWart.AGE) >= 3),
|
NETHERWART(Blocks.NETHER_WART, state -> state.getValue(BlockNetherWart.AGE) >= 3),
|
||||||
SUGARCANE(Blocks.SUGAR_CANE, null) {
|
SUGARCANE(Blocks.REEDS, null) {
|
||||||
@Override
|
@Override
|
||||||
public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) {
|
public boolean readyToHarvest(World world, BlockPos pos, IBlockState state) {
|
||||||
if (Baritone.settings().replantCrops.value) {
|
if (Baritone.settings().replantCrops.value) {
|
||||||
@@ -157,7 +159,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isBoneMeal(ItemStack stack) {
|
private boolean isBoneMeal(ItemStack stack) {
|
||||||
return !stack.isEmpty() && stack.getItem().equals(Items.BONE_MEAL);
|
return !stack.isEmpty() && stack.getItem() instanceof ItemDye && EnumDyeColor.byDyeDamage(stack.getMetadata()) == EnumDyeColor.WHITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNetherWart(ItemStack stack) {
|
private boolean isNetherWart(ItemStack stack) {
|
||||||
@@ -233,7 +235,7 @@ public final class FarmProcess extends BaritoneProcessHelper implements IFarmPro
|
|||||||
Optional<Rotation> rot = RotationUtils.reachableOffset(ctx.player(), pos, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance());
|
Optional<Rotation> rot = RotationUtils.reachableOffset(ctx.player(), pos, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), ctx.playerController().getBlockReachDistance());
|
||||||
if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, soulsand ? this::isNetherWart : this::isPlantable)) {
|
if (rot.isPresent() && isSafeToCancel && baritone.getInventoryBehavior().throwaway(true, soulsand ? this::isNetherWart : this::isPlantable)) {
|
||||||
RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance());
|
RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), rot.get(), ctx.playerController().getBlockReachDistance());
|
||||||
if (result.type == RayTraceResult.Type.BLOCK && result.sideHit == EnumFacing.UP) {
|
if (result.typeOfHit == RayTraceResult.Type.BLOCK && result.sideHit == EnumFacing.UP) {
|
||||||
baritone.getLookBehavior().updateTarget(rot.get(), true);
|
baritone.getLookBehavior().updateTarget(rot.get(), true);
|
||||||
if (ctx.isLookingAt(pos)) {
|
if (ctx.isLookingAt(pos)) {
|
||||||
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
|
baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true);
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
|
|||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!entity.isAlive()) {
|
if (entity.isDead) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (entity.equals(ctx.player())) {
|
if (entity.equals(ctx.player())) {
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG
|
|||||||
if (!Baritone.settings().enterPortal.value) {
|
if (!Baritone.settings().enterPortal.value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return block == Blocks.NETHER_PORTAL;
|
return block == Blocks.PORTAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean rightClickOnArrival(Block block) {
|
private boolean rightClickOnArrival(Block block) {
|
||||||
|
|||||||
@@ -24,18 +24,13 @@ import baritone.api.pathing.goals.Goal;
|
|||||||
import baritone.api.pathing.goals.GoalBlock;
|
import baritone.api.pathing.goals.GoalBlock;
|
||||||
import baritone.api.utils.Helper;
|
import baritone.api.utils.Helper;
|
||||||
import baritone.api.utils.IPlayerContext;
|
import baritone.api.utils.IPlayerContext;
|
||||||
import net.minecraft.client.GameSettings;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiMainMenu;
|
import net.minecraft.client.gui.GuiMainMenu;
|
||||||
|
import net.minecraft.client.settings.GameSettings;
|
||||||
import net.minecraft.client.tutorial.TutorialSteps;
|
import net.minecraft.client.tutorial.TutorialSteps;
|
||||||
import net.minecraft.util.HttpUtil;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.*;
|
import net.minecraft.world.*;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for automatically testing Baritone's pathing algorithm by automatically creating a world with a specific
|
* Responsible for automatically testing Baritone's pathing algorithm by automatically creating a world with a specific
|
||||||
* seed, setting a specified goal, and only allowing a certain amount of ticks to pass before the pathing test is
|
* seed, setting a specified goal, and only allowing a certain amount of ticks to pass before the pathing test is
|
||||||
@@ -96,11 +91,11 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
|||||||
if (mc.getIntegratedServer() != null) {
|
if (mc.getIntegratedServer() != null) {
|
||||||
mc.getIntegratedServer().setDifficultyForAllWorlds(EnumDifficulty.PEACEFUL);
|
mc.getIntegratedServer().setDifficultyForAllWorlds(EnumDifficulty.PEACEFUL);
|
||||||
|
|
||||||
for (final WorldServer world : mc.getIntegratedServer().getWorlds()) {
|
for (final WorldServer world : mc.getIntegratedServer().worlds) {
|
||||||
// If the world has initialized, set the spawn point to our defined starting position
|
// If the world has initialized, set the spawn point to our defined starting position
|
||||||
if (world != null) {
|
if (world != null) {
|
||||||
world.setSpawnPoint(STARTING_POSITION);
|
world.setSpawnPoint(STARTING_POSITION);
|
||||||
world.getGameRules().setOrCreateGameRule("spawnRadius", "0", mc.getIntegratedServer());
|
world.getGameRules().setOrCreateGameRule("spawnRadius", "0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,7 +105,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
|||||||
// Force the integrated server to share the world to LAN so that
|
// Force the integrated server to share the world to LAN so that
|
||||||
// the ingame pause menu gui doesn't actually pause our game
|
// the ingame pause menu gui doesn't actually pause our game
|
||||||
if (mc.isSingleplayer() && !mc.getIntegratedServer().getPublic()) {
|
if (mc.isSingleplayer() && !mc.getIntegratedServer().getPublic()) {
|
||||||
mc.getIntegratedServer().shareToLAN(GameType.SURVIVAL, false, HttpUtil.getSuitableLanPort());
|
mc.getIntegratedServer().shareToLAN(GameType.SURVIVAL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For the first 200 ticks, wait for the world to generate
|
// For the first 200 ticks, wait for the world to generate
|
||||||
@@ -132,16 +127,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper {
|
|||||||
// If we have reached our goal, print a message and safely close the game
|
// If we have reached our goal, print a message and safely close the game
|
||||||
if (GOAL.isInGoal(ctx.playerFeet())) {
|
if (GOAL.isInGoal(ctx.playerFeet())) {
|
||||||
System.out.println("Successfully pathed to " + ctx.playerFeet() + " in " + event.getCount() + " ticks");
|
System.out.println("Successfully pathed to " + ctx.playerFeet() + " in " + event.getCount() + " ticks");
|
||||||
try {
|
|
||||||
File file = new File("success");
|
|
||||||
System.out.println("Writing success to " + file.getAbsolutePath());
|
|
||||||
Files.write(file.getAbsoluteFile().toPath(), "Success!".getBytes());
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
mc.shutdown();
|
mc.shutdown();
|
||||||
mc.shutdownMinecraftApplet();
|
|
||||||
System.exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have exceeded the expected number of ticks to complete the pathing
|
// If we have exceeded the expected number of ticks to complete the pathing
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public final class BlockBreakHelper implements Helper {
|
|||||||
|
|
||||||
public void tick(boolean isLeftClick) {
|
public void tick(boolean isLeftClick) {
|
||||||
RayTraceResult trace = ctx.objectMouseOver();
|
RayTraceResult trace = ctx.objectMouseOver();
|
||||||
boolean isBlockTrace = trace != null && trace.type == RayTraceResult.Type.BLOCK;
|
boolean isBlockTrace = trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK;
|
||||||
|
|
||||||
if (isLeftClick && isBlockTrace) {
|
if (isLeftClick && isBlockTrace) {
|
||||||
if (!didBreakLastTick) {
|
if (!didBreakLastTick) {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class BlockPlaceHelper implements Helper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RayTraceResult mouseOver = ctx.objectMouseOver();
|
RayTraceResult mouseOver = ctx.objectMouseOver();
|
||||||
if (!rightClickRequested || ctx.player().isRowingBoat() || mouseOver == null || mouseOver.getBlockPos() == null || mouseOver.type != RayTraceResult.Type.BLOCK) {
|
if (!rightClickRequested || ctx.player().isRowingBoat() || mouseOver == null || mouseOver.getBlockPos() == null || mouseOver.typeOfHit != RayTraceResult.Type.BLOCK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rightClickTimer = Baritone.settings().rightClickSpeed.value;
|
rightClickTimer = Baritone.settings().rightClickSpeed.value;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user