Compare commits
22
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
513e42c58e | ||
|
|
e1281c24fa | ||
|
|
82bb743120 | ||
|
|
85ed18e108 | ||
|
|
61a9bae878 | ||
|
|
d0ff246b03 | ||
|
|
f84321b7e7 | ||
|
|
72b1ec2665 | ||
|
|
2337386b37 | ||
|
|
d1288bf4af | ||
|
|
0072bfdee5 | ||
|
|
6b2153f03e | ||
|
|
ab86e65a65 | ||
|
|
1f2b6977b9 | ||
|
|
d5847f73d3 | ||
|
|
4e5e20280f | ||
|
|
baba4d6f6e | ||
|
|
1bb0bf7e76 | ||
|
|
c6cabe7ed6 | ||
|
|
4f2fe70300 | ||
|
|
52a611bf94 | ||
|
|
354564485a |
No files matched your search
+157
-1
@@ -30,7 +30,7 @@ version = "2.3.68"
|
||||
description = "Libre simulation anticheat designed for 1.21 with 1.8-1.21 support, powered by PacketEvents 2.0."
|
||||
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(18))
|
||||
}
|
||||
|
||||
// Set to false for debug builds
|
||||
@@ -59,6 +59,13 @@ repositories {
|
||||
// FastUtil, Discord-Webhooks
|
||||
}
|
||||
|
||||
// Add JMH configuration
|
||||
configurations {
|
||||
create("jmh")
|
||||
create("jmhAnnotationProcessor")
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
implementation("com.github.retrooper:packetevents-spigot:2.6.1-SNAPSHOT")
|
||||
implementation("co.aikar:acf-paper:0.5.1-SNAPSHOT")
|
||||
@@ -76,6 +83,12 @@ dependencies {
|
||||
compileOnly("com.viaversion:viaversion-api:5.0.4-SNAPSHOT")
|
||||
//
|
||||
compileOnly("io.netty:netty-all:4.1.85.Final")
|
||||
|
||||
// Replace jmhImplementation with the new configuration
|
||||
"jmh"("org.openjdk.jmh:jmh-core:1.37")
|
||||
"jmhAnnotationProcessor"("org.openjdk.jmh:jmh-generator-annprocess:1.37")
|
||||
|
||||
implementation(files("./nalim.jar"))
|
||||
}
|
||||
|
||||
bukkit {
|
||||
@@ -169,6 +182,71 @@ publishing.publications.create<MavenPublication>("maven") {
|
||||
artifact(tasks["shadowJar"])
|
||||
}
|
||||
|
||||
java {
|
||||
sourceSets {
|
||||
create("java18") {
|
||||
java {
|
||||
srcDirs("src/main/java18")
|
||||
}
|
||||
compileClasspath += main.get().output
|
||||
runtimeClasspath += main.get().output
|
||||
dependencies {
|
||||
implementation(files("./nalim.jar")) // Add nalim.jar to java18 source set
|
||||
}
|
||||
}
|
||||
create("jmh") {
|
||||
java {
|
||||
srcDir("src/jmh/java")
|
||||
}
|
||||
compileClasspath += sourceSets.main.get().output +
|
||||
sourceSets.getByName("java18").output +
|
||||
configurations["jmh"]
|
||||
runtimeClasspath += sourceSets.main.get().output +
|
||||
sourceSets.getByName("java18").output +
|
||||
configurations["jmh"]
|
||||
}
|
||||
}
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(18))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
if (name == "compileJava") {
|
||||
options.compilerArgs.addAll(listOf("--add-exports","java.base/jdk.internal=ALL-UNNAMED",
|
||||
"--add-exports", "java.base/jdk.internal.vm.annotation=ALL-UNNAMED"))
|
||||
}
|
||||
if (name == "compileJava18Java") {
|
||||
options.compilerArgs.addAll(listOf("--add-modules", "jdk.incubator.vector", "-Xlint:unchecked"))
|
||||
sourceCompatibility = "18"
|
||||
targetCompatibility = "18"
|
||||
}
|
||||
if (name == "compileJava21Java") {
|
||||
options.compilerArgs.addAll(listOf("--enable-preview", "--add-modules", "jdk.incubator.vector", "-Xlint:unchecked"))
|
||||
sourceCompatibility = "21"
|
||||
targetCompatibility = "21"
|
||||
}
|
||||
if (name == "compileJmhJava") {
|
||||
options.compilerArgs.addAll(listOf("--add-modules", "jdk.incubator.vector"))
|
||||
sourceCompatibility = "18"
|
||||
targetCompatibility = "18"
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<Jar> {
|
||||
manifest {
|
||||
attributes("Multi-Release" to "true")
|
||||
}
|
||||
duplicatesStrategy = DuplicatesStrategy.INCLUDE // Important for multi-release JARs
|
||||
from(sourceSets.main.get().output)
|
||||
from(sourceSets.getByName("java18").output) {
|
||||
into("META-INF/versions/18")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.shadowJar {
|
||||
minimize()
|
||||
archiveFileName.set("${project.name}-${project.version}.jar")
|
||||
@@ -192,3 +270,81 @@ tasks.shadowJar {
|
||||
relocate("org.jetbrains", "ac.grim.grimac.shaded.jetbrains")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register<Jar>("jmhJar") {
|
||||
dependsOn("compileGeneratedJmh")
|
||||
|
||||
from(sourceSets["main"].output)
|
||||
from(sourceSets["java18"].output)
|
||||
from(sourceSets["jmh"].output)
|
||||
from("${buildDir}/classes/java/jmh")
|
||||
from(configurations["jmh"].map { if (it.isDirectory) it else zipTree(it) })
|
||||
|
||||
manifest {
|
||||
attributes(
|
||||
"Main-Class" to "org.openjdk.jmh.Main",
|
||||
"Add-Opens" to "java.base/java.lang java.base/java.io java.base/java.util java.base/java.util.concurrent java.base/java.net",
|
||||
"Add-Modules" to "jdk.incubator.vector"
|
||||
)
|
||||
}
|
||||
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
archiveClassifier.set("benchmarks")
|
||||
}
|
||||
|
||||
|
||||
tasks.register<JavaCompile>("compileGeneratedJmh") {
|
||||
dependsOn("compileJmhJava")
|
||||
|
||||
source = fileTree("${buildDir}/generated-sources/jmh")
|
||||
|
||||
classpath = sourceSets["jmh"].compileClasspath +
|
||||
sourceSets["java18"].output +
|
||||
sourceSets["java18"].compileClasspath +
|
||||
sourceSets.main.get().output +
|
||||
sourceSets.main.get().compileClasspath +
|
||||
files("${buildDir}/classes/java/jmh")
|
||||
|
||||
destinationDirectory.set(file("${buildDir}/classes/java/jmh"))
|
||||
|
||||
sourceCompatibility = "18"
|
||||
targetCompatibility = "18"
|
||||
options.compilerArgs.addAll(listOf("--add-modules", "jdk.incubator.vector"))
|
||||
}
|
||||
|
||||
tasks.register("jmh") {
|
||||
dependsOn("jmhJar")
|
||||
doLast {
|
||||
val includes = System.getProperty("includes", "")
|
||||
|
||||
javaexec {
|
||||
classpath = files(tasks.named("jmhJar").get().outputs.files)
|
||||
mainClass.set("org.openjdk.jmh.Main")
|
||||
jvmArgs = listOf("--enable-preview", "--add-modules", "jdk.incubator.vector", "-XX:+UnlockExperimentalVMOptions", "-XX:+EnableJVMCI", "-javaagent:nalim.jar")
|
||||
|
||||
// Initialize the args list with default settings
|
||||
args = mutableListOf<String>().apply {
|
||||
// Add any default arguments here if needed
|
||||
if (includes.isNotEmpty()) {
|
||||
addAll(listOf(includes))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<JavaCompile>("compileJmhJava") {
|
||||
source = fileTree("src/jmh/java")
|
||||
classpath = sourceSets["jmh"].compileClasspath +
|
||||
sourceSets.main.get().output +
|
||||
sourceSets["java18"].output
|
||||
destinationDirectory.set(file("${buildDir}/classes/java/jmh"))
|
||||
|
||||
sourceCompatibility = "18"
|
||||
targetCompatibility = "18"
|
||||
options.compilerArgs.addAll(listOf("--add-modules", "jdk.incubator.vector"))
|
||||
}
|
||||
|
||||
tasks.named("jmhJar") {
|
||||
dependsOn("compileJmhJava")
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package ac.grim.grimac.utils.vector;
|
||||
|
||||
import jdk.incubator.vector.*;
|
||||
|
||||
public final class SIMDVector3D implements Vector3D {
|
||||
|
||||
private static final VectorSpecies<Double> SPECIES = DoubleVector.SPECIES_256;
|
||||
private static final VectorMask<Double> LENGTH_3_ARRAY_MASK = SPECIES.indexInRange(0, 3);
|
||||
private static final VectorShuffle<Double> CROSS_PRODUCT_SHUFFLE1 = VectorShuffle.fromArray(SPECIES, new int[]{1, 2, 0, 3}, 0);
|
||||
private static final VectorShuffle<Double> CROSS_PRODUCT_SHUFFLE2 = VectorShuffle.fromArray(SPECIES, new int[]{2, 0, 1, 3}, 0);
|
||||
private static final DoubleVector FOURTH_COMPONENT_ZERO = DoubleVector.zero(SPECIES).withLane(3, 1.0);
|
||||
|
||||
private DoubleVector vector;
|
||||
|
||||
public SIMDVector3D(double x, double y, double z) {
|
||||
this.vector = DoubleVector.fromArray(SPECIES, new double[]{x, y, z, 0}, 0, LENGTH_3_ARRAY_MASK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return this.vector.lane(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return this.vector.lane(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getZ() {
|
||||
return this.vector.lane(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D setX(double x) {
|
||||
this.vector = this.vector.withLane(0, x);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D setY(double y) {
|
||||
this.vector = this.vector.withLane(1, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D setZ(double z) {
|
||||
this.vector = this.vector.withLane(2, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double length() {
|
||||
return Math.sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double lengthSquared() {
|
||||
return this.vector.mul(this.vector).reduceLanes(VectorOperators.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D multiply(double m) {
|
||||
this.vector = this.vector.mul(m);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D normalize() {
|
||||
// DoubleVector squared = this.vector.mul(this.vector);
|
||||
// double sum = squared.reduceLanes(VectorOperators.ADD);
|
||||
// double length = Math.sqrt(sum);
|
||||
// this.vector = this.vector.div(length);
|
||||
// return this;
|
||||
this.vector = this.vector.div(length());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D crossProduct(Vector3D other) {
|
||||
SIMDVector3D o = (SIMDVector3D) other;
|
||||
|
||||
DoubleVector tmp0 = this.vector.rearrange(CROSS_PRODUCT_SHUFFLE1);
|
||||
DoubleVector tmp1 = o.vector.rearrange(CROSS_PRODUCT_SHUFFLE2);
|
||||
|
||||
DoubleVector tmp2 = tmp0.mul(o.vector);
|
||||
DoubleVector tmp3 = tmp0.mul(tmp1);
|
||||
|
||||
DoubleVector tmp4 = tmp2.rearrange(CROSS_PRODUCT_SHUFFLE1);
|
||||
|
||||
this.vector = tmp3.sub(tmp4).blend(FOURTH_COMPONENT_ZERO, LENGTH_3_ARRAY_MASK.not());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D add(Vector3D o) {
|
||||
this.vector = this.vector.add(((SIMDVector3D) o).vector);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D subtract(Vector3D o) {
|
||||
this.vector = this.vector.sub(((SIMDVector3D) o).vector);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D multiply(Vector3D o) {
|
||||
this.vector = this.vector.mul(((SIMDVector3D) o).vector);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double distance(Vector3D o) {
|
||||
return Math.sqrt(distanceSquared(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double distanceSquared(Vector3D o) {
|
||||
DoubleVector diff = this.vector.sub(((SIMDVector3D) o).vector);
|
||||
return diff.mul(diff).reduceLanes(VectorOperators.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double dot(Vector3D o) {
|
||||
return this.vector.mul(((SIMDVector3D) o).vector).reduceLanes(VectorOperators.ADD);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vector3D clone() {
|
||||
// I think this makes a shallow clone if I do it like this?
|
||||
// try {
|
||||
// return (Vector3D) super.clone();
|
||||
// } catch (CloneNotSupportedException e) {
|
||||
// throw new Error(e);
|
||||
// }
|
||||
try {
|
||||
SIMDVector3D cloned = (SIMDVector3D) super.clone();
|
||||
// Create a new DoubleVector with the same values
|
||||
cloned.vector = DoubleVector.fromArray(SPECIES,
|
||||
new double[]{this.getX(), this.getY(), this.getZ(), 0}, 0);
|
||||
return cloned;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package ac.grim.grimac.utils.vector;
|
||||
|
||||
|
||||
public class VectorOperationsJava18 implements VectorOperations {
|
||||
|
||||
@Override
|
||||
public Vector3D newVector(double x, double y, double z) {
|
||||
return new SIMDVector3D(x, y, z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
//package ac.grim.grimac.benchmark.vector;
|
||||
//
|
||||
//import ac.grim.grimac.utils.vector.Java21SIMDVector3D;
|
||||
//import org.openjdk.jmh.annotations.*;
|
||||
//
|
||||
//import java.util.concurrent.TimeUnit;
|
||||
//
|
||||
//@BenchmarkMode(Mode.AverageTime)
|
||||
//@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
//@State(Scope.Thread)
|
||||
//@Warmup(iterations = 2, time = 1)
|
||||
//@Measurement(iterations = 3, time = 1)
|
||||
//@Fork(1)
|
||||
//public class Java21SIMDVector3DBenchmark {
|
||||
//
|
||||
// private Java21SIMDVector3D vector1;
|
||||
// private Java21SIMDVector3D vector2;
|
||||
//
|
||||
// @Setup
|
||||
// public void setup() {
|
||||
// vector1 = new Java21SIMDVector3D(1.0, 2.0, 3.0);
|
||||
// vector2 = new Java21SIMDVector3D(4.0, 5.0, 6.0);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkGetX() {
|
||||
// return vector1.getX();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkGetY() {
|
||||
// return vector1.getY();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkGetZ() {
|
||||
// return vector1.getZ();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public Java21SIMDVector3D benchmarkSetX() {
|
||||
// return (Java21SIMDVector3D) vector1.setX(10.0);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public Java21SIMDVector3D benchmarkSetY() {
|
||||
// return (Java21SIMDVector3D) vector1.setY(20.0);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public Java21SIMDVector3D benchmarkSetZ() {
|
||||
// return (Java21SIMDVector3D) vector1.setZ(30.0);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkLength() {
|
||||
// return vector1.length();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkLengthSquared() {
|
||||
// return vector1.lengthSquared();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public Java21SIMDVector3D benchmarkMultiplyScalar() {
|
||||
// return (Java21SIMDVector3D) vector1.multiply(2.0);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public Java21SIMDVector3D benchmarkNormalize() {
|
||||
// return (Java21SIMDVector3D) vector1.normalize();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public Java21SIMDVector3D benchmarkCrossProduct() {
|
||||
// return (Java21SIMDVector3D) vector1.crossProduct(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public Java21SIMDVector3D benchmarkAdd() {
|
||||
// return (Java21SIMDVector3D) vector1.add(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public Java21SIMDVector3D benchmarkSubtract() {
|
||||
// return (Java21SIMDVector3D) vector1.subtract(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public Java21SIMDVector3D benchmarkMultiplyVector() {
|
||||
// return (Java21SIMDVector3D) vector1.multiply(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkDistance() {
|
||||
// return vector1.distance(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkDistanceSquared() {
|
||||
// return vector1.distanceSquared(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkDotProduct() {
|
||||
// return vector1.dot(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public Java21SIMDVector3D benchmarkClone() {
|
||||
// return (Java21SIMDVector3D) vector1.clone();
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,114 @@
|
||||
package ac.grim.grimac.benchmark.vector;
|
||||
|
||||
import ac.grim.grimac.utils.vector.NalimVector3D;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 2, time = 1)
|
||||
@Measurement(iterations = 3, time = 1)
|
||||
@Fork(1)
|
||||
public class NalimVector3DBenchmark {
|
||||
|
||||
private NalimVector3D vector1;
|
||||
private NalimVector3D vector2;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
vector1 = new NalimVector3D(1.0, 2.0, 3.0);
|
||||
vector2 = new NalimVector3D(4.0, 5.0, 6.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkGetX() {
|
||||
return vector1.getX();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkGetY() {
|
||||
return vector1.getY();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkGetZ() {
|
||||
return vector1.getZ();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NalimVector3D benchmarkSetX() {
|
||||
return (NalimVector3D) vector1.setX(10.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NalimVector3D benchmarkSetY() {
|
||||
return (NalimVector3D) vector1.setY(20.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NalimVector3D benchmarkSetZ() {
|
||||
return (NalimVector3D) vector1.setZ(30.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkLength() {
|
||||
return vector1.length();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkLengthSquared() {
|
||||
return vector1.lengthSquared();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NalimVector3D benchmarkMultiplyScalar() {
|
||||
return (NalimVector3D) vector1.multiply(2.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NalimVector3D benchmarkNormalize() {
|
||||
return (NalimVector3D) vector1.normalize();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NalimVector3D benchmarkCrossProduct() {
|
||||
return (NalimVector3D) vector1.crossProduct(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NalimVector3D benchmarkAdd() {
|
||||
return (NalimVector3D) vector1.add(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NalimVector3D benchmarkSubtract() {
|
||||
return (NalimVector3D) vector1.subtract(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NalimVector3D benchmarkMultiplyVector() {
|
||||
return (NalimVector3D) vector1.multiply(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkDistance() {
|
||||
return vector1.distance(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkDistanceSquared() {
|
||||
return vector1.distanceSquared(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkDotProduct() {
|
||||
return vector1.dot(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public NalimVector3D benchmarkClone() {
|
||||
return (NalimVector3D) vector1.clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
//package ac.grim.grimac.benchmark.vector;
|
||||
//
|
||||
//import ac.grim.grimac.utils.vector.NativeVector3D;
|
||||
//import org.openjdk.jmh.annotations.*;
|
||||
//
|
||||
//import java.util.concurrent.TimeUnit;
|
||||
//
|
||||
//@BenchmarkMode(Mode.AverageTime)
|
||||
//@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
//@State(Scope.Thread)
|
||||
//@Warmup(iterations = 2, time = 1)
|
||||
//@Measurement(iterations = 3, time = 1)
|
||||
//@Fork(1)
|
||||
//public class NativeVector3DBenchmark {
|
||||
//
|
||||
// private NativeVector3D vector1;
|
||||
// private NativeVector3D vector2;
|
||||
//
|
||||
// @Setup
|
||||
// public void setup() {
|
||||
// vector1 = new NativeVector3D(1.0, 2.0, 3.0);
|
||||
// vector2 = new NativeVector3D(4.0, 5.0, 6.0);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkGetX() {
|
||||
// return vector1.getX();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkGetY() {
|
||||
// return vector1.getY();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkGetZ() {
|
||||
// return vector1.getZ();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public NativeVector3D benchmarkSetX() {
|
||||
// return (NativeVector3D) vector1.setX(10.0);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public NativeVector3D benchmarkSetY() {
|
||||
// return (NativeVector3D) vector1.setY(20.0);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public NativeVector3D benchmarkSetZ() {
|
||||
// return (NativeVector3D) vector1.setZ(30.0);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkLength() {
|
||||
// return vector1.length();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkLengthSquared() {
|
||||
// return vector1.lengthSquared();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public NativeVector3D benchmarkMultiplyScalar() {
|
||||
// return (NativeVector3D) vector1.multiply(2.0);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public NativeVector3D benchmarkNormalize() {
|
||||
// return (NativeVector3D) vector1.normalize();
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public NativeVector3D benchmarkCrossProduct() {
|
||||
// return (NativeVector3D) vector1.crossProduct(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public NativeVector3D benchmarkAdd() {
|
||||
// return (NativeVector3D) vector1.add(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public NativeVector3D benchmarkSubtract() {
|
||||
// return (NativeVector3D) vector1.subtract(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public NativeVector3D benchmarkMultiplyVector() {
|
||||
// return (NativeVector3D) vector1.multiply(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkDistance() {
|
||||
// return vector1.distance(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkDistanceSquared() {
|
||||
// return vector1.distanceSquared(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public double benchmarkDotProduct() {
|
||||
// return vector1.dot(vector2);
|
||||
// }
|
||||
//
|
||||
// @Benchmark
|
||||
// public NativeVector3D benchmarkClone() {
|
||||
// return (NativeVector3D) vector1.clone();
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,114 @@
|
||||
package ac.grim.grimac.benchmark.vector;
|
||||
|
||||
import ac.grim.grimac.utils.vector.SIMDVector3D;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 2, time = 1)
|
||||
@Measurement(iterations = 3, time = 1)
|
||||
@Fork(1)
|
||||
public class SIMDVector3DBenchmark {
|
||||
|
||||
private SIMDVector3D vector1;
|
||||
private SIMDVector3D vector2;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
vector1 = new SIMDVector3D(1.0, 2.0, 3.0);
|
||||
vector2 = new SIMDVector3D(4.0, 5.0, 6.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkGetX() {
|
||||
return vector1.getX();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkGetY() {
|
||||
return vector1.getY();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkGetZ() {
|
||||
return vector1.getZ();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public SIMDVector3D benchmarkSetX() {
|
||||
return (SIMDVector3D) vector1.setX(10.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public SIMDVector3D benchmarkSetY() {
|
||||
return (SIMDVector3D) vector1.setY(20.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public SIMDVector3D benchmarkSetZ() {
|
||||
return (SIMDVector3D) vector1.setZ(30.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkLength() {
|
||||
return vector1.length();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkLengthSquared() {
|
||||
return vector1.lengthSquared();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public SIMDVector3D benchmarkMultiplyScalar() {
|
||||
return (SIMDVector3D) vector1.multiply(2.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public SIMDVector3D benchmarkNormalize() {
|
||||
return (SIMDVector3D) vector1.normalize();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public SIMDVector3D benchmarkCrossProduct() {
|
||||
return (SIMDVector3D) vector1.crossProduct(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public SIMDVector3D benchmarkAdd() {
|
||||
return (SIMDVector3D) vector1.add(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public SIMDVector3D benchmarkSubtract() {
|
||||
return (SIMDVector3D) vector1.subtract(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public SIMDVector3D benchmarkMultiplyVector() {
|
||||
return (SIMDVector3D) vector1.multiply(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkDistance() {
|
||||
return vector1.distance(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkDistanceSquared() {
|
||||
return vector1.distanceSquared(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkDotProduct() {
|
||||
return vector1.dot(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public SIMDVector3D benchmarkClone() {
|
||||
return (SIMDVector3D) vector1.clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package ac.grim.grimac.benchmark.vector;
|
||||
|
||||
import ac.grim.grimac.utils.vector.ScalarVector3D;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@State(Scope.Thread)
|
||||
@Warmup(iterations = 2, time = 1)
|
||||
@Measurement(iterations = 3, time = 1)
|
||||
@Fork(1)
|
||||
public class ScalarVector3DBenchmark {
|
||||
|
||||
private ScalarVector3D vector1;
|
||||
private ScalarVector3D vector2;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
vector1 = new ScalarVector3D(1.0, 2.0, 3.0);
|
||||
vector2 = new ScalarVector3D(4.0, 5.0, 6.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkGetX() {
|
||||
return vector1.getX();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkGetY() {
|
||||
return vector1.getY();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkGetZ() {
|
||||
return vector1.getZ();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ScalarVector3D benchmarkSetX() {
|
||||
return (ScalarVector3D) vector1.setX(10.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ScalarVector3D benchmarkSetY() {
|
||||
return (ScalarVector3D) vector1.setY(20.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ScalarVector3D benchmarkSetZ() {
|
||||
return (ScalarVector3D) vector1.setZ(30.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkLength() {
|
||||
return vector1.length();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkLengthSquared() {
|
||||
return vector1.lengthSquared();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ScalarVector3D benchmarkMultiplyScalar() {
|
||||
return (ScalarVector3D) vector1.multiply(2.0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ScalarVector3D benchmarkNormalize() {
|
||||
return (ScalarVector3D) vector1.normalize();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ScalarVector3D benchmarkCrossProduct() {
|
||||
return (ScalarVector3D) vector1.crossProduct(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ScalarVector3D benchmarkAdd() {
|
||||
return (ScalarVector3D) vector1.add(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ScalarVector3D benchmarkSubtract() {
|
||||
return (ScalarVector3D) vector1.subtract(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ScalarVector3D benchmarkMultiplyVector() {
|
||||
return (ScalarVector3D) vector1.multiply(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkDistance() {
|
||||
return vector1.distance(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkDistanceSquared() {
|
||||
return vector1.distanceSquared(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public double benchmarkDotProduct() {
|
||||
return vector1.dot(vector2);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ScalarVector3D benchmarkClone() {
|
||||
return (ScalarVector3D) vector1.clone();
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import ac.grim.grimac.utils.data.packetentity.PacketEntity;
|
||||
import ac.grim.grimac.utils.data.packetentity.dragon.PacketEntityEnderDragonPart;
|
||||
import ac.grim.grimac.utils.nmsutil.ReachUtils;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
@@ -35,10 +36,12 @@ import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
// You may not copy the check unless you are licensed under GPL
|
||||
@CheckData(name = "Reach", configName = "Reach", setback = 10)
|
||||
public class Reach extends Check implements PacketCheck {
|
||||
@@ -182,7 +185,7 @@ public class Reach extends Check implements PacketCheck {
|
||||
double minDistance = Double.MAX_VALUE;
|
||||
|
||||
// https://bugs.mojang.com/browse/MC-67665
|
||||
List<Vector> possibleLookDirs = new ArrayList<>(Collections.singletonList(ReachUtils.getLook(player, player.xRot, player.yRot)));
|
||||
List<Vector3D> possibleLookDirs = new ArrayList<>(Collections.singletonList(ReachUtils.getLook(player, player.xRot, player.yRot)));
|
||||
|
||||
// If we are a tick behind, we don't know their next look so don't bother doing this
|
||||
if (!isPrediction) {
|
||||
@@ -202,12 +205,12 @@ public class Reach extends Check implements PacketCheck {
|
||||
// +3 would be 3 + 3 = 6, which is the pre-1.20.5 behaviour, preventing "Missed Hitbox"
|
||||
final double distance = player.compensatedEntities.getSelf().getAttributeValue(Attributes.PLAYER_ENTITY_INTERACTION_RANGE) + 3;
|
||||
final double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
for (Vector lookVec : possibleLookDirs) {
|
||||
for (Vector3D lookVec : possibleLookDirs) {
|
||||
for (double eye : possibleEyeHeights) {
|
||||
Vector eyePos = new Vector(from.getX(), from.getY() + eye, from.getZ());
|
||||
Vector endReachPos = eyePos.clone().add(new Vector(lookVec.getX() * distance, lookVec.getY() * distance, lookVec.getZ() * distance));
|
||||
ac.grim.grimac.utils.vector.Vector3D eyePos = newVector3D(from.getX(), from.getY() + eye, from.getZ());
|
||||
ac.grim.grimac.utils.vector.Vector3D endReachPos = eyePos.clone().add(newVector3D(lookVec.getX() * distance, lookVec.getY() * distance, lookVec.getZ() * distance));
|
||||
|
||||
Vector intercept = ReachUtils.calculateIntercept(targetBox, eyePos, endReachPos).first();
|
||||
Vector3D intercept = ReachUtils.calculateIntercept(targetBox, eyePos, endReachPos).first();
|
||||
|
||||
if (ReachUtils.isVecInside(targetBox, eyePos)) {
|
||||
minDistance = 0;
|
||||
|
||||
@@ -9,7 +9,7 @@ import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import ac.grim.grimac.utils.lists.EvictingQueue;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -45,8 +45,8 @@ public class DebugHandler extends Check implements PostPredictionCheck {
|
||||
|
||||
ChatColor color = pickColor(offset, offset);
|
||||
|
||||
Vector predicted = player.predictedVelocity.vector;
|
||||
Vector actually = player.actualMovement;
|
||||
Vector3D predicted = player.predictedVelocity.vector;
|
||||
Vector3D actually = player.actualMovement;
|
||||
|
||||
ChatColor xColor = pickColor(Math.abs(predicted.getX() - actually.getX()), offset);
|
||||
ChatColor yColor = pickColor(Math.abs(predicted.getY() - actually.getY()), offset);
|
||||
|
||||
@@ -9,7 +9,9 @@ import ac.grim.grimac.utils.math.VectorUtils;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
@CheckData(name = "FarPlace")
|
||||
public class FarPlace extends BlockPlaceCheck {
|
||||
@@ -27,8 +29,8 @@ public class FarPlace extends BlockPlaceCheck {
|
||||
final double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
for (double d : possibleEyeHeights) {
|
||||
SimpleCollisionBox box = new SimpleCollisionBox(blockPos);
|
||||
Vector eyes = new Vector(player.x, player.y + d, player.z);
|
||||
Vector best = VectorUtils.cutBoxToVector(eyes, box);
|
||||
Vector3D eyes = newVector3D(player.x, player.y + d, player.z);
|
||||
Vector3D best = VectorUtils.cutBoxToVector(eyes, box);
|
||||
min = Math.min(min, eyes.distanceSquared(best));
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import ac.grim.grimac.utils.data.Pair;
|
||||
import ac.grim.grimac.utils.nmsutil.Ray;
|
||||
import ac.grim.grimac.utils.nmsutil.ReachUtils;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
@@ -15,7 +16,6 @@ import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.util.Vector3f;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -111,7 +111,7 @@ public class RotationPlace extends BlockPlaceCheck {
|
||||
Vector3d starting = new Vector3d(player.x, player.y + d, player.z);
|
||||
// xRot and yRot are a tick behind
|
||||
Ray trace = new Ray(player, starting.getX(), starting.getY(), starting.getZ(), lookDir.getX(), lookDir.getY());
|
||||
Pair<Vector, BlockFace> intercept = ReachUtils.calculateIntercept(box, trace.getOrigin(), trace.getPointAtDistance(distance));
|
||||
Pair<Vector3D, BlockFace> intercept = ReachUtils.calculateIntercept(box, trace.getOrigin(), trace.getPointAtDistance(distance));
|
||||
|
||||
if (intercept.first() != null) return true;
|
||||
}
|
||||
|
||||
@@ -19,12 +19,13 @@ import com.github.retrooper.packetevents.util.Vector3f;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerExplosion;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
@CheckData(name = "AntiExplosion", configName = "Explosion", setback = 10)
|
||||
public class ExplosionHandler extends Check implements PostPredictionCheck {
|
||||
Deque<VelocityData> firstBreadMap = new LinkedList<>();
|
||||
@@ -121,7 +122,7 @@ public class ExplosionHandler extends Check implements PostPredictionCheck {
|
||||
}
|
||||
|
||||
public void addPlayerExplosion(int breadOne, Vector3f explosion) {
|
||||
firstBreadMap.add(new VelocityData(-1, breadOne, player.getSetbackTeleportUtil().isSendingSetback, new Vector(explosion.getX(), explosion.getY(), explosion.getZ())));
|
||||
firstBreadMap.add(new VelocityData(-1, breadOne, player.getSetbackTeleportUtil().isSendingSetback, newVector3D(explosion.getX(), explosion.getY(), explosion.getZ())));
|
||||
}
|
||||
|
||||
public void setPointThree(boolean isPointThree) {
|
||||
|
||||
@@ -15,12 +15,14 @@ import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityVelocity;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
// We are making a velocity sandwich between two pieces of transaction packets (bread)
|
||||
@CheckData(name = "AntiKB", alternativeName = "AntiKnockback", configName = "Knockback", setback = 10, decay = 0.025)
|
||||
public class KnockbackHandler extends Check implements PostPredictionCheck {
|
||||
@@ -71,12 +73,12 @@ public class KnockbackHandler extends Check implements PostPredictionCheck {
|
||||
|
||||
// Wrap velocity between two transactions
|
||||
player.sendTransaction();
|
||||
addPlayerKnockback(entityId, player.lastTransactionSent.get(), new Vector(playerVelocity.getX(), playerVelocity.getY(), playerVelocity.getZ()));
|
||||
addPlayerKnockback(entityId, player.lastTransactionSent.get(), newVector3D(playerVelocity.getX(), playerVelocity.getY(), playerVelocity.getZ()));
|
||||
event.getTasksAfterSend().add(player::sendTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull public Pair<VelocityData, Vector> getFutureKnockback() {
|
||||
@NotNull public Pair<VelocityData, Vector3D> getFutureKnockback() {
|
||||
// Chronologically in the future
|
||||
if (firstBreadMap.size() > 0) {
|
||||
VelocityData data = firstBreadMap.peek();
|
||||
@@ -98,7 +100,7 @@ public class KnockbackHandler extends Check implements PostPredictionCheck {
|
||||
return new Pair<>(null, null);
|
||||
}
|
||||
|
||||
private void addPlayerKnockback(int entityID, int breadOne, Vector knockback) {
|
||||
private void addPlayerKnockback(int entityID, int breadOne, Vector3D knockback) {
|
||||
firstBreadMap.add(new VelocityData(entityID, breadOne, player.getSetbackTeleportUtil().isSendingSetback, knockback));
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ import ac.grim.grimac.utils.latency.CompensatedWorld;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
import ac.grim.grimac.utils.math.VectorUtils;
|
||||
import ac.grim.grimac.utils.nmsutil.*;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import ac.grim.grimac.utils.vector.VectorFactory;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||
@@ -47,7 +49,6 @@ import com.github.retrooper.packetevents.wrapper.play.client.*;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAcknowledgeBlockChanges;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetSlot;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -793,10 +794,10 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
|
||||
private static HitData getNearestHitResult(GrimPlayer player, StateType heldItem, boolean sourcesHaveHitbox) {
|
||||
Vector3d startingPos = new Vector3d(player.x, player.y + player.getEyeHeight(), player.z);
|
||||
Vector startingVec = new Vector(startingPos.getX(), startingPos.getY(), startingPos.getZ());
|
||||
Vector3D startingVec = VectorFactory.newVector3D(startingPos.getX(), startingPos.getY(), startingPos.getZ());
|
||||
Ray trace = new Ray(player, startingPos.getX(), startingPos.getY(), startingPos.getZ(), player.xRot, player.yRot);
|
||||
final double distance = player.compensatedEntities.getSelf().getAttributeValue(Attributes.PLAYER_BLOCK_INTERACTION_RANGE);
|
||||
Vector endVec = trace.getPointAtDistance(distance);
|
||||
Vector3D endVec = trace.getPointAtDistance(distance);
|
||||
Vector3d endPos = new Vector3d(endVec.getX(), endVec.getY(), endVec.getZ());
|
||||
|
||||
return traverseBlocks(player, startingPos, endPos, (block, vector3i) -> {
|
||||
@@ -805,14 +806,14 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
data.downCast(boxes);
|
||||
|
||||
double bestHitResult = Double.MAX_VALUE;
|
||||
Vector bestHitLoc = null;
|
||||
Vector3D bestHitLoc = null;
|
||||
BlockFace bestFace = null;
|
||||
|
||||
for (SimpleCollisionBox box : boxes) {
|
||||
Pair<Vector, BlockFace> intercept = ReachUtils.calculateIntercept(box, trace.getOrigin(), trace.getPointAtDistance(distance));
|
||||
Pair<Vector3D, BlockFace> intercept = ReachUtils.calculateIntercept(box, trace.getOrigin(), trace.getPointAtDistance(distance));
|
||||
if (intercept.first() == null) continue; // No intercept
|
||||
|
||||
Vector hitLoc = intercept.first();
|
||||
Vector3D hitLoc = intercept.first();
|
||||
|
||||
if (hitLoc.distanceSquared(startingVec) < bestHitResult) {
|
||||
bestHitResult = hitLoc.distanceSquared(startingVec);
|
||||
@@ -830,7 +831,7 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
double waterHeight = player.compensatedWorld.getFluidLevelAt(vector3i.getX(), vector3i.getY(), vector3i.getZ());
|
||||
SimpleCollisionBox box = new SimpleCollisionBox(vector3i.getX(), vector3i.getY(), vector3i.getZ(), vector3i.getX() + 1, vector3i.getY() + waterHeight, vector3i.getZ() + 1);
|
||||
|
||||
Pair<Vector, BlockFace> intercept = ReachUtils.calculateIntercept(box, trace.getOrigin(), trace.getPointAtDistance(distance));
|
||||
Pair<Vector3D, BlockFace> intercept = ReachUtils.calculateIntercept(box, trace.getOrigin(), trace.getPointAtDistance(distance));
|
||||
|
||||
if (intercept.first() != null) {
|
||||
return new HitData(vector3i, intercept.first(), intercept.second(), block);
|
||||
|
||||
@@ -20,11 +20,12 @@ import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerJoinGame;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateHealth;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
/**
|
||||
* PlayerRespawnS2CPacket info (1.20.2+):
|
||||
* If the world is different (check via registry key), world is recreated (all entities etc destroyed).
|
||||
@@ -191,7 +192,7 @@ public class PacketPlayerRespawn extends PacketListenerAbstract {
|
||||
player.compensatedEntities.hasSprintingAttributeEnabled = false;
|
||||
}
|
||||
player.pose = Pose.STANDING;
|
||||
player.clientVelocity = new Vector();
|
||||
player.clientVelocity = newVector3D();
|
||||
player.gamemode = respawn.getGameMode();
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_17)) {
|
||||
player.compensatedWorld.setDimension(respawn.getDimensionType(), event.getUser());
|
||||
|
||||
@@ -19,6 +19,7 @@ import ac.grim.grimac.utils.math.VectorUtils;
|
||||
import ac.grim.grimac.utils.nmsutil.Collisions;
|
||||
import ac.grim.grimac.utils.nmsutil.GetBoundingBox;
|
||||
import ac.grim.grimac.utils.nmsutil.ReachUtils;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
@@ -31,13 +32,15 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
// Sync to netty
|
||||
public final ConcurrentLinkedQueue<TeleportData> pendingTeleports = new ConcurrentLinkedQueue<>();
|
||||
@@ -65,7 +68,7 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
@Override
|
||||
public void onPredictionComplete(final PredictionComplete predictionComplete) {
|
||||
// Grab friction now when we know player on ground and other variables
|
||||
Vector afterTickFriction = player.clientVelocity.clone();
|
||||
Vector3D afterTickFriction = player.clientVelocity.clone();
|
||||
|
||||
// We must first check if the player has accepted their setback
|
||||
// If the setback isn't complete, then this position is illegitimate
|
||||
@@ -115,7 +118,7 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void simulateFriction(Vector vector) {
|
||||
private void simulateFriction(Vector3D vector) {
|
||||
// We must always do this before simulating positions, as this is the last actual (safe) movement
|
||||
// We must not do this for knockback or explosions, as they are at the start of the tick
|
||||
if (player.wasTouchingWater) {
|
||||
@@ -123,9 +126,9 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
} else if (player.wasTouchingLava) {
|
||||
vector.multiply(0.5D);
|
||||
if (player.hasGravity)
|
||||
vector.add(new Vector(0.0D, -player.gravity / 4.0D, 0.0D));
|
||||
vector.add(newVector3D(0.0D, -player.gravity / 4.0D, 0.0D));
|
||||
} else if (player.isGliding) {
|
||||
PredictionEngineElytra.getElytraMovement(player, vector, ReachUtils.getLook(player, player.xRot, player.yRot)).multiply(player.stuckSpeedMultiplier).multiply(new Vector(0.99F, 0.98F, 0.99F));
|
||||
PredictionEngineElytra.getElytraMovement(player, vector, ReachUtils.getLook(player, player.xRot, player.yRot)).multiply(player.stuckSpeedMultiplier).multiply(newVector3D(0.99F, 0.98F, 0.99F));
|
||||
vector.setY(vector.getY() - 0.05); // Make the player fall a bit
|
||||
} else { // Gliding doesn't have friction, we handle it differently
|
||||
PredictionEngineNormal.staticVectorEndOfTick(player, vector); // Lava and normal movement
|
||||
@@ -148,9 +151,9 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
lastWorldResync = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
Vector clientVel = lastKnownGoodPosition.vector.clone();
|
||||
Vector3D clientVel = lastKnownGoodPosition.vector.clone();
|
||||
|
||||
Pair<VelocityData, Vector> futureKb = player.checkManager.getKnockbackHandler().getFutureKnockback();
|
||||
Pair<VelocityData, Vector3D> futureKb = player.checkManager.getKnockbackHandler().getFutureKnockback();
|
||||
VelocityData futureExplosion = player.checkManager.getExplosionHandler().getFutureExplosion();
|
||||
|
||||
// Velocity sets
|
||||
@@ -170,7 +173,7 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
|
||||
// Mini prediction engine - simulate collisions
|
||||
if (simulateNextTickPosition) {
|
||||
Vector collide = Collisions.collide(player, clientVel.getX(), clientVel.getY(), clientVel.getZ());
|
||||
Vector3D collide = Collisions.collide(player, clientVel.getX(), clientVel.getY(), clientVel.getZ());
|
||||
|
||||
position = position.withX(position.getX() + collide.getX());
|
||||
// 1.8 players need the collision epsilon to not phase into blocks when being setback
|
||||
@@ -413,7 +416,7 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
data = new TeleportData(safePosition, flags, transaction, teleportId);
|
||||
requiredSetBack = new SetBackData(data, player.xRot, player.yRot, null, false, plugin);
|
||||
|
||||
this.lastKnownGoodPosition = new SetbackPosWithVector(safePosition, new Vector());
|
||||
this.lastKnownGoodPosition = new SetbackPosWithVector(safePosition, newVector3D());
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@@ -421,6 +424,6 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
@Setter
|
||||
public static class SetbackPosWithVector {
|
||||
private Vector3d pos;
|
||||
private Vector vector;
|
||||
private Vector3D vector;
|
||||
}
|
||||
}
|
||||
@@ -10,26 +10,28 @@ import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import ac.grim.grimac.utils.lists.EvictingQueue;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
private static final StringBuilder[] flags = new StringBuilder[256]; // 17 MB of logs in memory
|
||||
|
||||
Object2IntMap<StringBuilder> continuedDebug = new Object2IntOpenHashMap<>();
|
||||
|
||||
List<VectorData> predicted = new EvictingQueue<>(60);
|
||||
List<Vector> actually = new EvictingQueue<>(60);
|
||||
List<Vector3D> actually = new EvictingQueue<>(60);
|
||||
List<Location> locations = new EvictingQueue<>(60);
|
||||
List<Vector> startTickClientVel = new EvictingQueue<>(60);
|
||||
List<Vector> baseTickAddition = new EvictingQueue<>(60);
|
||||
List<Vector> baseTickWater = new EvictingQueue<>(60);
|
||||
List<Vector3D> startTickClientVel = new EvictingQueue<>(60);
|
||||
List<Vector3D> baseTickAddition = new EvictingQueue<>(60);
|
||||
List<Vector3D> baseTickWater = new EvictingQueue<>(60);
|
||||
|
||||
public SuperDebug(GrimPlayer player) {
|
||||
super(player);
|
||||
@@ -80,11 +82,11 @@ public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
|
||||
for (int i = 0; i < predicted.size(); i++) {
|
||||
VectorData predict = predicted.get(i);
|
||||
Vector actual = actually.get(i);
|
||||
Vector3D actual = actually.get(i);
|
||||
Location loc = locations.get(i);
|
||||
Vector startTickVel = startTickClientVel.get(i);
|
||||
Vector addition = baseTickAddition.get(i);
|
||||
Vector water = baseTickWater.get(i);
|
||||
Vector3D startTickVel = startTickClientVel.get(i);
|
||||
Vector3D addition = baseTickAddition.get(i);
|
||||
Vector3D water = baseTickWater.get(i);
|
||||
appendDebug(sb, predict, actual, loc, startTickVel, addition, water);
|
||||
}
|
||||
|
||||
@@ -189,7 +191,7 @@ public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
continuedDebug.put(sb, 40);
|
||||
}
|
||||
|
||||
private void appendDebug(StringBuilder sb, VectorData predict, Vector actual, Location location, Vector startTick, Vector addition, Vector water) {
|
||||
private void appendDebug(StringBuilder sb, VectorData predict, Vector3D actual, Location location, Vector3D startTick, Vector3D addition, Vector3D water) {
|
||||
if (predict.isZeroPointZeroThree()) {
|
||||
sb.append("Movement threshold/tick skipping\n");
|
||||
}
|
||||
@@ -225,11 +227,11 @@ public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
// Apply 0.003/0.005 to make numbers more accurate
|
||||
Set<VectorData> set = new HashSet<>(Collections.singletonList(new VectorData(startTick.clone(), VectorData.VectorType.BestVelPicked)));
|
||||
new PredictionEngine().applyMovementThreshold(player, set);
|
||||
Vector trueStartVel = ((VectorData) set.toArray()[0]).vector;
|
||||
Vector3D trueStartVel = ((VectorData) set.toArray()[0]).vector;
|
||||
|
||||
Vector clientMovement = getPlayerMathMovement(player, actual.clone().subtract(trueStartVel), location.xRot);
|
||||
Vector simulatedMovement = getPlayerMathMovement(player, predict.vector.clone().subtract(trueStartVel), location.xRot);
|
||||
Vector offset = actual.clone().subtract(predict.vector);
|
||||
Vector3D clientMovement = getPlayerMathMovement(player, actual.clone().subtract(trueStartVel), location.xRot);
|
||||
Vector3D simulatedMovement = getPlayerMathMovement(player, predict.vector.clone().subtract(trueStartVel), location.xRot);
|
||||
Vector3D offset = actual.clone().subtract(predict.vector);
|
||||
trueStartVel.add(addition);
|
||||
trueStartVel.add(water);
|
||||
|
||||
@@ -268,14 +270,14 @@ public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
sb.append("\n\n");
|
||||
}
|
||||
|
||||
private Vector getPlayerMathMovement(GrimPlayer player, Vector wantedMovement, float f2) {
|
||||
private Vector3D getPlayerMathMovement(GrimPlayer player, Vector3D wantedMovement, float f2) {
|
||||
float f3 = player.trigHandler.sin(f2 * 0.017453292f);
|
||||
float f4 = player.trigHandler.cos(f2 * 0.017453292f);
|
||||
|
||||
float bestTheoreticalX = (float) (f3 * wantedMovement.getZ() + f4 * wantedMovement.getX()) / (f3 * f3 + f4 * f4);
|
||||
float bestTheoreticalZ = (float) (-f3 * wantedMovement.getX() + f4 * wantedMovement.getZ()) / (f3 * f3 + f4 * f4);
|
||||
|
||||
return new Vector(bestTheoreticalX, 0, bestTheoreticalZ);
|
||||
return newVector3D(bestTheoreticalX, 0, bestTheoreticalZ);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
|
||||
@@ -54,7 +54,7 @@ import net.kyori.adventure.text.TranslatableComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
@@ -64,6 +64,9 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static ac.grim.grimac.utils.data.VectorData.VectorType.Normal;
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
// Everything in this class should be sync'd to the anticheat thread.
|
||||
// Put variables sync'd to the netty thread in PacketStateData
|
||||
// Variables that need lag compensation should have their own class
|
||||
@@ -90,7 +93,7 @@ public class GrimPlayer implements GrimUser {
|
||||
public MovementCheckRunner movementCheckRunner;
|
||||
public SyncedTags tagManager;
|
||||
// End manager like classes
|
||||
public Vector clientVelocity = new Vector();
|
||||
public ac.grim.grimac.utils.vector.Vector3D clientVelocity = newVector3D();
|
||||
PacketTracker packetTracker;
|
||||
private long transactionPing = 0;
|
||||
public long lastTransSent = 0;
|
||||
@@ -103,9 +106,9 @@ public class GrimPlayer implements GrimUser {
|
||||
public boolean hasGravity = true;
|
||||
public final long joinTime = System.currentTimeMillis();
|
||||
public boolean playerEntityHasGravity = true;
|
||||
public VectorData predictedVelocity = new VectorData(new Vector(), VectorData.VectorType.Normal);
|
||||
public Vector actualMovement = new Vector();
|
||||
public Vector stuckSpeedMultiplier = new Vector(1, 1, 1);
|
||||
public VectorData predictedVelocity = new VectorData(newVector3D(), Normal);
|
||||
public Vector3D actualMovement = newVector3D();
|
||||
public Vector3D stuckSpeedMultiplier = newVector3D(1, 1, 1);
|
||||
public UncertaintyHandler uncertaintyHandler;
|
||||
public double gravity;
|
||||
public float friction;
|
||||
@@ -184,9 +187,9 @@ public class GrimPlayer implements GrimUser {
|
||||
public TrigHandler trigHandler;
|
||||
public PacketStateData packetStateData;
|
||||
// Keep track of basetick stuff
|
||||
public Vector baseTickAddition = new Vector();
|
||||
public Vector baseTickWaterPushing = new Vector();
|
||||
public Vector startTickClientVel = new Vector();
|
||||
public Vector3D baseTickAddition = newVector3D();
|
||||
public Vector3D baseTickWaterPushing = newVector3D();
|
||||
public Vector3D startTickClientVel = newVector3D();
|
||||
// For syncing the player's full swing in 1.9+
|
||||
public int movementPackets = 0;
|
||||
public VelocityData firstBreadKB = null;
|
||||
@@ -361,15 +364,15 @@ public class GrimPlayer implements GrimUser {
|
||||
return data != null && data.first() == id;
|
||||
}
|
||||
|
||||
public void baseTickAddWaterPushing(Vector vector) {
|
||||
public void baseTickAddWaterPushing(ac.grim.grimac.utils.vector.Vector3D vector) {
|
||||
baseTickWaterPushing.add(vector);
|
||||
}
|
||||
|
||||
public void baseTickAddVector(Vector vector) {
|
||||
public void baseTickAddVector(Vector3D vector) {
|
||||
clientVelocity.add(vector);
|
||||
}
|
||||
|
||||
public void trackBaseTickAddition(Vector vector) {
|
||||
public void trackBaseTickAddition(Vector3D vector) {
|
||||
baseTickAddition.add(vector);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,10 @@ import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.data.VectorData.VectorType.Dead;
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
// Averaged over 500 predictions (Defaults set slightly above my 3600x results)
|
||||
@@ -138,10 +141,10 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
double negX = Math.min(-0.05, GrimMath.clamp(player.actualMovement.getX(), -16, 16) - 0.05);
|
||||
double negZ = Math.min(-0.05, GrimMath.clamp(player.actualMovement.getZ(), -16, 16) - 0.05);
|
||||
|
||||
Vector NE = Collisions.maybeBackOffFromEdge(new Vector(posX, 0, negZ), player, true);
|
||||
Vector NW = Collisions.maybeBackOffFromEdge(new Vector(negX, 0, negZ), player, true);
|
||||
Vector SE = Collisions.maybeBackOffFromEdge(new Vector(posX, 0, posZ), player, true);
|
||||
Vector SW = Collisions.maybeBackOffFromEdge(new Vector(negX, 0, posZ), player, true);
|
||||
Vector3D NE = Collisions.maybeBackOffFromEdge(newVector3D(posX, 0, negZ), player, true);
|
||||
Vector3D NW = Collisions.maybeBackOffFromEdge(newVector3D(negX, 0, negZ), player, true);
|
||||
Vector3D SE = Collisions.maybeBackOffFromEdge(newVector3D(posX, 0, posZ), player, true);
|
||||
Vector3D SW = Collisions.maybeBackOffFromEdge(newVector3D(negX, 0, posZ), player, true);
|
||||
|
||||
boolean isEast = NE.getX() != posX || SE.getX() != posX;
|
||||
boolean isWest = NW.getX() != negX || SW.getX() != negX;
|
||||
@@ -184,7 +187,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
player.vehicleData.wasVehicleSwitch = false;
|
||||
|
||||
if (riding != null) {
|
||||
Vector pos = new Vector(player.x, player.y, player.z);
|
||||
Vector3D pos = newVector3D(player.x, player.y, player.z);
|
||||
SimpleCollisionBox interTruePositions = riding.getPossibleCollisionBoxes();
|
||||
|
||||
// We shrink the expanded bounding box to what the packet positions can be, for a smaller box
|
||||
@@ -194,7 +197,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
interTruePositions.expand(-width, 0, -width);
|
||||
interTruePositions.expandMax(0, -height, 0);
|
||||
|
||||
Vector cutTo = VectorUtils.cutBoxToVector(pos, interTruePositions);
|
||||
Vector3D cutTo = VectorUtils.cutBoxToVector(pos, interTruePositions);
|
||||
|
||||
// Now we need to simulate a tick starting at the most optimal position
|
||||
// The start position is never sent, so we assume the most optimal start position
|
||||
@@ -212,14 +215,14 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
} else {
|
||||
// Server always teleports the player when they eject anyways,
|
||||
// so just let the player control where they eject within reason, they get set back anyways
|
||||
if (new Vector(player.lastX, player.lastY, player.lastZ).distance(new Vector(player.x, player.y, player.z)) > 3) {
|
||||
if (newVector3D(player.lastX, player.lastY, player.lastZ).distance(newVector3D(player.x, player.y, player.z)) > 3) {
|
||||
player.getSetbackTeleportUtil().executeForceResync(); // Too far! (I think this value is sane)
|
||||
}
|
||||
|
||||
handleTeleport(update);
|
||||
|
||||
if (player.isClimbing) {
|
||||
Vector ladder = player.clientVelocity.clone().setY(0.2);
|
||||
Vector3D ladder = player.clientVelocity.clone().setY(0.2);
|
||||
PredictionEngineNormal.staticVectorEndOfTick(player, ladder);
|
||||
player.lastWasClimbing = ladder.getY();
|
||||
}
|
||||
@@ -299,7 +302,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
player.clientControlledVerticalCollision = Math.abs(player.y % (1 / 64D)) < 0.00001;
|
||||
|
||||
// This isn't the final velocity of the player in the tick, only the one applied to the player
|
||||
player.actualMovement = new Vector(player.x - player.lastX, player.y - player.lastY, player.z - player.lastZ);
|
||||
player.actualMovement = newVector3D(player.x - player.lastX, player.y - player.lastY, player.z - player.lastZ);
|
||||
|
||||
if (player.isSprinting != player.lastSprinting) {
|
||||
player.compensatedEntities.hasSprintingAttributeEnabled = player.isSprinting;
|
||||
@@ -426,8 +429,8 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
// Exempt if the player is dead or is riding a dead entity
|
||||
if (player.compensatedEntities.getSelf().isDead || (riding != null && riding.isDead)) {
|
||||
// Dead players can't cheat, if you find a way how they could, open an issue
|
||||
player.predictedVelocity = new VectorData(new Vector(), VectorData.VectorType.Dead);
|
||||
player.clientVelocity = new Vector();
|
||||
player.predictedVelocity = new VectorData(newVector3D(), Dead);
|
||||
player.clientVelocity = newVector3D();
|
||||
} else if (player.disableGrim || (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_8) && player.gamemode == GameMode.SPECTATOR) || player.isFlying || (player.isExemptElytra() && player.isGliding)) {
|
||||
// We could technically check spectator but what's the point...
|
||||
// Added complexity to analyze a gamemode used mainly by moderators
|
||||
@@ -450,7 +453,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
// Riptiding while on the ground moves the hitbox upwards before any movement code runs
|
||||
// It's a pain to support and this is my best attempt
|
||||
if (player.lastOnGround && player.packetStateData.tryingToRiptide && !player.compensatedEntities.getSelf().inVehicle()) {
|
||||
Vector pushingMovement = Collisions.collide(player, 0, 1.1999999F, 0);
|
||||
Vector3D pushingMovement = Collisions.collide(player, 0, 1.1999999F, 0);
|
||||
player.verticalCollision = pushingMovement.getY() != 1.1999999F;
|
||||
double currentY = player.clientVelocity.getY();
|
||||
|
||||
@@ -462,7 +465,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
player.lastY += pushingMovement.getY();
|
||||
new PlayerBaseTick(player).updatePlayerPose();
|
||||
player.boundingBox = GetBoundingBox.getPlayerBoundingBox(player, player.lastX, player.lastY, player.lastZ);
|
||||
player.actualMovement = new Vector(player.x - player.lastX, player.y - player.lastY, player.z - player.lastZ);
|
||||
player.actualMovement = newVector3D(player.x - player.lastX, player.y - player.lastY, player.z - player.lastZ);
|
||||
|
||||
player.couldSkipTick = true;
|
||||
|
||||
@@ -514,7 +517,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
//
|
||||
// Checking for oldClientVel being too high fixes BleachHack vertical scaffold
|
||||
if (player.getSetbackTeleportUtil().getRequiredSetBack() != null && player.getSetbackTeleportUtil().getRequiredSetBack().getTicksComplete() == 1) {
|
||||
Vector setbackVel = player.getSetbackTeleportUtil().getRequiredSetBack().getVelocity();
|
||||
Vector3D setbackVel = player.getSetbackTeleportUtil().getRequiredSetBack().getVelocity();
|
||||
// A player must have velocity going INTO the ground to be able to jump
|
||||
// Otherwise they could ignore upwards velocity that isn't useful into more useful upwards velocity (towering)
|
||||
// So if they are supposed to be going upwards, or are supposed to be off the ground, resync
|
||||
@@ -543,7 +546,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
// Patch sprint jumping with elytra exploit
|
||||
if (player.bukkitPlayer != null && player.isGliding && player.predictedVelocity.isJump() && player.isSprinting && !allowSprintJumpingWithElytra) {
|
||||
SetbackTeleportUtil.SetbackPosWithVector lastKnownGoodPosition = player.getSetbackTeleportUtil().lastKnownGoodPosition;
|
||||
lastKnownGoodPosition.setVector(lastKnownGoodPosition.getVector().multiply(new Vector(0.6 * 0.91, 1, 0.6 * 0.91)));
|
||||
lastKnownGoodPosition.setVector(lastKnownGoodPosition.getVector().multiply(newVector3D(0.6 * 0.91, 1, 0.6 * 0.91)));
|
||||
player.getSetbackTeleportUtil().executeNonSimulatingSetback();
|
||||
}
|
||||
|
||||
@@ -620,7 +623,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
* @param pushingMovement The collision result when trying to move the player upwards by 1.2f
|
||||
* @return Whether it is more likely that this player was on the ground the tick they riptided
|
||||
*/
|
||||
private boolean likelyGroundRiptide(Vector pushingMovement) {
|
||||
private boolean likelyGroundRiptide(Vector3D pushingMovement) {
|
||||
// Y velocity gets reset if the player collides vertically
|
||||
double riptideYResult = Riptide.getRiptideVelocity(player).getY();
|
||||
|
||||
|
||||
@@ -9,16 +9,19 @@ import ac.grim.grimac.utils.enums.Pose;
|
||||
import ac.grim.grimac.utils.latency.CompensatedEntities;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
import ac.grim.grimac.utils.nmsutil.*;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class PlayerBaseTick {
|
||||
GrimPlayer player;
|
||||
|
||||
@@ -40,11 +43,11 @@ public class PlayerBaseTick {
|
||||
|
||||
public void doBaseTick() {
|
||||
// Keep track of basetick stuff
|
||||
player.baseTickAddition = new Vector();
|
||||
player.baseTickWaterPushing = new Vector();
|
||||
player.baseTickAddition = newVector3D();
|
||||
player.baseTickWaterPushing = newVector3D();
|
||||
|
||||
if (player.isFlying && player.isSneaking && !player.compensatedEntities.getSelf().inVehicle()) {
|
||||
Vector flyingShift = new Vector(0, player.flySpeed * -3, 0);
|
||||
Vector3D flyingShift = newVector3D(0, player.flySpeed * -3, 0);
|
||||
player.baseTickAddVector(flyingShift);
|
||||
player.trackBaseTickAddition(flyingShift);
|
||||
}
|
||||
@@ -60,7 +63,7 @@ public class PlayerBaseTick {
|
||||
// You cannot crouch while flying, only shift - could be specific to 1.14?
|
||||
// pre-1.13 clients don't have this code
|
||||
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_13) && player.wasTouchingWater && player.isSneaking && !player.isFlying && !player.compensatedEntities.getSelf().inVehicle()) {
|
||||
Vector waterPushVector = new Vector(0, -0.04f, 0);
|
||||
Vector3D waterPushVector = newVector3D(0, -0.04f, 0);
|
||||
player.baseTickAddVector(waterPushVector);
|
||||
player.trackBaseTickAddition(waterPushVector);
|
||||
}
|
||||
@@ -414,7 +417,7 @@ public class PlayerBaseTick {
|
||||
}
|
||||
|
||||
boolean hasPushed = false;
|
||||
Vector vec3 = new Vector();
|
||||
Vector3D vec3 = newVector3D();
|
||||
|
||||
for (int x = floorX; x < ceilX; ++x) {
|
||||
for (int y = floorY; y < ceilY; ++y) {
|
||||
@@ -464,7 +467,7 @@ public class PlayerBaseTick {
|
||||
}
|
||||
double d2 = 0.0;
|
||||
boolean hasTouched = false;
|
||||
Vector vec3 = new Vector();
|
||||
Vector3D vec3 = newVector3D();
|
||||
int n7 = 0;
|
||||
|
||||
for (int x = floorX; x < ceilX; ++x) {
|
||||
@@ -489,7 +492,7 @@ public class PlayerBaseTick {
|
||||
d2 = Math.max(fluidHeightToWorld - aABB.minY, d2);
|
||||
|
||||
if (!player.isFlying) {
|
||||
Vector vec32 = FluidTypeFlowing.getFlow(player, x, y, z);
|
||||
Vector3D vec32 = FluidTypeFlowing.getFlow(player, x, y, z);
|
||||
if (d2 < 0.4) {
|
||||
vec32 = vec32.multiply(d2);
|
||||
}
|
||||
|
||||
@@ -18,11 +18,13 @@ import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Set;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
/**
|
||||
* A lot of care was put into handling all the stupid stuff occurring between events
|
||||
* <p>
|
||||
@@ -141,7 +143,7 @@ public class PointThreeEstimator {
|
||||
isNearBubbleColumn = true;
|
||||
}
|
||||
|
||||
Vector fluidVector = FluidTypeFlowing.getFlow(player, x, y, z);
|
||||
Vector3D fluidVector = FluidTypeFlowing.getFlow(player, x, y, z);
|
||||
if (fluidVector.getX() != 0 || fluidVector.getZ() != 0) {
|
||||
isNearHorizontalFlowingLiquid = true;
|
||||
}
|
||||
@@ -305,7 +307,7 @@ public class PointThreeEstimator {
|
||||
player.boundingBox = player.boundingBox.copy().expand(0.03, 0, 0.03).offset(0, 0.03, 0);
|
||||
// 0.16 magic value -> 0.03 plus gravity, plus some additional lenience
|
||||
double searchDistance = -0.2 + Math.min(0, y);
|
||||
Vector collisionResult = Collisions.collide(player, 0, searchDistance, 0);
|
||||
Vector3D collisionResult = Collisions.collide(player, 0, searchDistance, 0);
|
||||
player.boundingBox = playerBox;
|
||||
return collisionResult.getY() != searchDistance;
|
||||
}
|
||||
@@ -339,9 +341,9 @@ public class PointThreeEstimator {
|
||||
// Takes 0.01 millis, on average, to compute... this should be improved eventually
|
||||
for (VectorData data : init) {
|
||||
// Try to get the vector as close to zero as possible to give the best chance at 0.03...
|
||||
Vector toZeroVec = new PredictionEngine().handleStartingVelocityUncertainty(player, data, new Vector());
|
||||
Vector3D toZeroVec = new PredictionEngine().handleStartingVelocityUncertainty(player, data, newVector3D());
|
||||
// Collide to handle mostly gravity, but other scenarios similar to this.
|
||||
Vector collisionResult = Collisions.collide(player, toZeroVec.getX(), toZeroVec.getY(), toZeroVec.getZ(), Integer.MIN_VALUE, null);
|
||||
Vector3D collisionResult = Collisions.collide(player, toZeroVec.getX(), toZeroVec.getY(), toZeroVec.getZ(), Integer.MIN_VALUE, null);
|
||||
|
||||
// If this tick is the tick after y velocity was by 0, a stepping movement is POSSIBLE to have been hidden
|
||||
// A bit hacky... is there a better way? I'm unsure...
|
||||
|
||||
@@ -13,10 +13,12 @@ import ac.grim.grimac.utils.nmsutil.ReachUtils;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class UncertaintyHandler {
|
||||
private final GrimPlayer player;
|
||||
// Handles uncertainty when a piston could have pushed a player in a direction
|
||||
@@ -149,15 +151,15 @@ public class UncertaintyHandler {
|
||||
entityBox.maxY -= height;
|
||||
entityBox.expand(-width / 2, 0, -width / 2);
|
||||
|
||||
Vector maxLocation = new Vector(entityBox.maxX, entityBox.maxY, entityBox.maxZ);
|
||||
Vector minLocation = new Vector(entityBox.minX, entityBox.minY, entityBox.minZ);
|
||||
Vector3D maxLocation = newVector3D(entityBox.maxX, entityBox.maxY, entityBox.maxZ);
|
||||
Vector3D minLocation = newVector3D(entityBox.minX, entityBox.minY, entityBox.minZ);
|
||||
|
||||
Vector diff = minLocation.subtract(new Vector(player.lastX, player.lastY + 0.8 * 1.8, player.lastZ)).multiply(0.1);
|
||||
Vector3D diff = minLocation.subtract(newVector3D(player.lastX, player.lastY + 0.8 * 1.8, player.lastZ)).multiply(0.1);
|
||||
fishingRodPullBox.minX = Math.min(0, diff.getX());
|
||||
fishingRodPullBox.minY = Math.min(0, diff.getY());
|
||||
fishingRodPullBox.minZ = Math.min(0, diff.getZ());
|
||||
|
||||
diff = maxLocation.subtract(new Vector(player.lastX, player.lastY + 0.8 * 1.8, player.lastZ)).multiply(0.1);
|
||||
diff = maxLocation.subtract(newVector3D(player.lastX, player.lastY + 0.8 * 1.8, player.lastZ)).multiply(0.1);
|
||||
fishingRodPullBox.maxX = Math.max(0, diff.getX());
|
||||
fishingRodPullBox.maxY = Math.max(0, diff.getY());
|
||||
fishingRodPullBox.maxZ = Math.max(0, diff.getZ());
|
||||
@@ -172,8 +174,8 @@ public class UncertaintyHandler {
|
||||
|
||||
fireworksBox = new SimpleCollisionBox();
|
||||
|
||||
Vector currentLook = ReachUtils.getLook(player, player.xRot, player.yRot);
|
||||
Vector lastLook = ReachUtils.getLook(player, player.lastXRot, player.lastYRot);
|
||||
Vector3D currentLook = ReachUtils.getLook(player, player.xRot, player.yRot);
|
||||
ac.grim.grimac.utils.vector.Vector3D lastLook = ReachUtils.getLook(player, player.lastXRot, player.lastYRot);
|
||||
|
||||
double antiTickSkipping = player.isPointThree() ? 0 : 0.05; // With 0.03, let that handle tick skipping
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@ import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import io.github.retrooper.packetevents.util.viaversion.ViaVersionUtil;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class MovementTicker {
|
||||
public final GrimPlayer player;
|
||||
@@ -86,9 +88,9 @@ public class MovementTicker {
|
||||
player.uncertaintyHandler.collidingEntities.add(possibleCollidingEntities);
|
||||
}
|
||||
|
||||
public void move(Vector inputVel, Vector collide) {
|
||||
public void move(Vector3D inputVel, Vector3D collide) {
|
||||
if (player.stuckSpeedMultiplier.getX() < 0.99) {
|
||||
player.clientVelocity = new Vector();
|
||||
player.clientVelocity = newVector3D();
|
||||
}
|
||||
|
||||
if (inputVel.getX() != collide.getX()) {
|
||||
@@ -181,21 +183,21 @@ public class MovementTicker {
|
||||
|
||||
// The game disregards movements smaller than 1e-7 (such as in boats)
|
||||
if (collide.lengthSquared() < 1e-7) {
|
||||
collide = new Vector();
|
||||
collide = newVector3D();
|
||||
}
|
||||
|
||||
// This is where vanilla moves the bounding box and sets it
|
||||
player.predictedVelocity = new VectorData(collide.clone(), player.predictedVelocity.lastVector, player.predictedVelocity.vectorType);
|
||||
|
||||
float f = BlockProperties.getBlockSpeedFactor(player, player.mainSupportingBlockData, new Vector3d(player.x, player.y, player.z));
|
||||
player.clientVelocity.multiply(new Vector(f, 1, f));
|
||||
player.clientVelocity.multiply(newVector3D(f, 1, f));
|
||||
|
||||
// Reset stuck speed so it can update
|
||||
if (player.stuckSpeedMultiplier.getX() < 0.99) {
|
||||
player.uncertaintyHandler.lastStuckSpeedMultiplier.reset();
|
||||
}
|
||||
|
||||
player.stuckSpeedMultiplier = new Vector(1, 1, 1);
|
||||
player.stuckSpeedMultiplier = newVector3D(1, 1, 1);
|
||||
|
||||
// 1.15 and older clients use the handleInsideBlocks method for lava
|
||||
if (player.getClientVersion().isOlderThan(ClientVersion.V_1_16))
|
||||
@@ -210,7 +212,7 @@ public class MovementTicker {
|
||||
|
||||
// Flying players are not affected by cobwebs/sweet berry bushes
|
||||
if (player.isFlying) {
|
||||
player.stuckSpeedMultiplier = new Vector(1, 1, 1);
|
||||
player.stuckSpeedMultiplier = newVector3D(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,14 +399,14 @@ public class MovementTicker {
|
||||
|
||||
// Lava movement changed in 1.16
|
||||
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_16) && player.slightlyTouchingLava) {
|
||||
player.clientVelocity = player.clientVelocity.multiply(new Vector(0.5D, 0.800000011920929D, 0.5D));
|
||||
player.clientVelocity = player.clientVelocity.multiply(newVector3D(0.5D, 0.800000011920929D, 0.5D));
|
||||
player.clientVelocity = FluidFallingAdjustedMovement.getFluidFallingAdjustedMovement(player, playerGravity, isFalling, player.clientVelocity);
|
||||
} else {
|
||||
player.clientVelocity.multiply(0.5D);
|
||||
}
|
||||
|
||||
if (player.hasGravity)
|
||||
player.clientVelocity.add(new Vector(0.0D, -playerGravity / 4.0D, 0.0D));
|
||||
player.clientVelocity.add(newVector3D(0.0D, -playerGravity / 4.0D, 0.0D));
|
||||
|
||||
} else if (player.isGliding) {
|
||||
player.friction = 0.99F; // Not vanilla, just useful for other grim stuff
|
||||
|
||||
@@ -5,7 +5,8 @@ import ac.grim.grimac.utils.data.packetentity.PacketEntityHorse;
|
||||
import ac.grim.grimac.utils.nmsutil.Collisions;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class MovementTickerHorse extends MovementTickerLivingVehicle {
|
||||
|
||||
@@ -26,7 +27,7 @@ public class MovementTickerHorse extends MovementTickerLivingVehicle {
|
||||
forwardsInput *= 0.25F;
|
||||
}
|
||||
|
||||
this.movementInput = new Vector(horizInput, 0, forwardsInput);
|
||||
this.movementInput = newVector3D(horizInput, 0, forwardsInput);
|
||||
if (movementInput.lengthSquared() > 1) movementInput.normalize();
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -7,10 +7,13 @@ import ac.grim.grimac.predictionengine.predictions.rideable.PredictionEngineRide
|
||||
import ac.grim.grimac.predictionengine.predictions.rideable.PredictionEngineRideableWaterLegacy;
|
||||
import ac.grim.grimac.utils.nmsutil.BlockProperties;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class MovementTickerLivingVehicle extends MovementTicker {
|
||||
Vector movementInput = new Vector();
|
||||
Vector3D movementInput = newVector3D();
|
||||
|
||||
public MovementTickerLivingVehicle(GrimPlayer player) {
|
||||
super(player);
|
||||
|
||||
@@ -3,12 +3,13 @@ package ac.grim.grimac.predictionengine.movementtick;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.data.packetentity.PacketEntityRideable;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class MovementTickerPig extends MovementTickerRideable {
|
||||
public MovementTickerPig(GrimPlayer player) {
|
||||
super(player);
|
||||
movementInput = new Vector(0, 0, 1);
|
||||
movementInput = newVector3D(0, 0, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-3
@@ -11,15 +11,16 @@ import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class MovementTickerStrider extends MovementTickerRideable {
|
||||
|
||||
public MovementTickerStrider(GrimPlayer player) {
|
||||
super(player);
|
||||
movementInput = new Vector(0, 0, 1);
|
||||
movementInput = newVector3D(0, 0, 1);
|
||||
}
|
||||
|
||||
public static void floatStrider(GrimPlayer player) {
|
||||
@@ -27,7 +28,7 @@ public class MovementTickerStrider extends MovementTickerRideable {
|
||||
if (isAbove(player) && player.compensatedWorld.getLavaFluidLevelAt((int) Math.floor(player.x), (int) Math.floor(player.y + 1), (int) Math.floor(player.z)) == 0) {
|
||||
player.onGround = true;
|
||||
} else {
|
||||
player.clientVelocity.multiply(0.5).add(new Vector(0, 0.05, 0));
|
||||
player.clientVelocity.multiply(0.5).add(newVector3D(0, 0.05, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,20 +12,29 @@ import ac.grim.grimac.utils.nmsutil.Collisions;
|
||||
import ac.grim.grimac.utils.nmsutil.GetBoundingBox;
|
||||
import ac.grim.grimac.utils.nmsutil.JumpPower;
|
||||
import ac.grim.grimac.utils.nmsutil.Riptide;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static ac.grim.grimac.utils.data.VectorData.VectorType.ZeroPointZeroThree;
|
||||
import static ac.grim.grimac.utils.nmsutil.Collisions.isEmpty;
|
||||
import static ac.grim.grimac.utils.nmsutil.GetBoundingBox.getBoundingBoxFromPosAndSize;
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static com.github.retrooper.packetevents.protocol.attribute.Attributes.GENERIC_GRAVITY;
|
||||
import static com.github.retrooper.packetevents.protocol.player.ClientVersion.V_1_13;
|
||||
import static java.lang.Math.*;
|
||||
import static java.util.Collections.max;
|
||||
|
||||
public class PredictionEngine {
|
||||
|
||||
public static Vector clampMovementToHardBorder(GrimPlayer player, Vector outputVel) {
|
||||
public static Vector3D clampMovementToHardBorder(GrimPlayer player, Vector3D outputVel) {
|
||||
// TODO: Reimplement
|
||||
return outputVel;
|
||||
}
|
||||
|
||||
public static Vector transformInputsToVector(GrimPlayer player, Vector theoreticalInput) {
|
||||
public static Vector3D transformInputsToVector(GrimPlayer player, Vector3D theoreticalInput) {
|
||||
float bestPossibleX;
|
||||
float bestPossibleZ;
|
||||
|
||||
@@ -43,15 +52,15 @@ public class PredictionEngine {
|
||||
bestPossibleZ *= 0.2F;
|
||||
}
|
||||
|
||||
Vector inputVector = new Vector(bestPossibleX, 0, bestPossibleZ);
|
||||
Vector3D inputVector = newVector3D(bestPossibleX, 0, bestPossibleZ);
|
||||
inputVector.multiply(0.98F);
|
||||
|
||||
// Simulate float rounding imprecision
|
||||
inputVector = new Vector((float) inputVector.getX(), (float) inputVector.getY(), (float) inputVector.getZ());
|
||||
inputVector = newVector3D((float) inputVector.getX(), (float) inputVector.getY(), (float) inputVector.getZ());
|
||||
|
||||
if (inputVector.lengthSquared() > 1) {
|
||||
double d0 = Math.sqrt(inputVector.getX() * inputVector.getX() + inputVector.getY() * inputVector.getY() + inputVector.getZ() * inputVector.getZ());
|
||||
inputVector = new Vector(inputVector.getX() / d0, inputVector.getY() / d0, inputVector.getZ() / d0);
|
||||
double d0 = sqrt(inputVector.getX() * inputVector.getX() + inputVector.getY() * inputVector.getY() + inputVector.getZ() * inputVector.getZ());
|
||||
inputVector = newVector3D(inputVector.getX() / d0, inputVector.getY() / d0, inputVector.getZ() / d0);
|
||||
}
|
||||
|
||||
return inputVector;
|
||||
@@ -63,7 +72,7 @@ public class PredictionEngine {
|
||||
if (player.uncertaintyHandler.influencedByBouncyBlock()) {
|
||||
for (VectorData data : init) {
|
||||
// Try to get the vector as close to zero as possible to give the best chance at 0.03...
|
||||
Vector toZeroVec = new PredictionEngine().handleStartingVelocityUncertainty(player, data, new Vector(0, -1000000000, 0)); // Downwards without overflow risk
|
||||
Vector3D toZeroVec = new PredictionEngine().handleStartingVelocityUncertainty(player, data, newVector3D(0, -1000000000, 0)); // Downwards without overflow risk
|
||||
|
||||
player.uncertaintyHandler.nextTickSlimeBlockUncertainty = Math.max(Math.abs(toZeroVec.getY()), player.uncertaintyHandler.nextTickSlimeBlockUncertainty);
|
||||
}
|
||||
@@ -106,8 +115,8 @@ public class PredictionEngine {
|
||||
double bestInput = Double.MAX_VALUE;
|
||||
|
||||
VectorData bestCollisionVel = null;
|
||||
Vector beforeCollisionMovement = null;
|
||||
Vector originalClientVel = player.clientVelocity.clone();
|
||||
Vector3D beforeCollisionMovement = null;
|
||||
Vector3D originalClientVel = player.clientVelocity.clone();
|
||||
|
||||
SimpleCollisionBox originalBB = player.boundingBox;
|
||||
// 0.03 doesn't exist with vehicles, thank god
|
||||
@@ -119,9 +128,9 @@ public class PredictionEngine {
|
||||
player.skippedTickInActualMovement = false;
|
||||
|
||||
for (VectorData clientVelAfterInput : possibleVelocities) {
|
||||
Vector primaryPushMovement = handleStartingVelocityUncertainty(player, clientVelAfterInput, player.actualMovement);
|
||||
Vector3D primaryPushMovement = handleStartingVelocityUncertainty(player, clientVelAfterInput, player.actualMovement);
|
||||
|
||||
Vector bestTheoreticalCollisionResult = VectorUtils.cutBoxToVector(player.actualMovement, new SimpleCollisionBox(0, Math.min(0, primaryPushMovement.getY()), 0, primaryPushMovement.getX(), Math.max(0.6, primaryPushMovement.getY()), primaryPushMovement.getZ()).sort());
|
||||
Vector3D bestTheoreticalCollisionResult = VectorUtils.cutBoxToVector(player.actualMovement, new SimpleCollisionBox(0, Math.min(0, primaryPushMovement.getY()), 0, primaryPushMovement.getX(), Math.max(0.6, primaryPushMovement.getY()), primaryPushMovement.getZ()).sort());
|
||||
// Check if this vector could ever possible beat the last vector in terms of accuracy
|
||||
// This is quite a good optimization :)
|
||||
if (bestTheoreticalCollisionResult.distanceSquared(player.actualMovement) > bestInput && !clientVelAfterInput.isKnockback() && !clientVelAfterInput.isExplosion()) {
|
||||
@@ -135,9 +144,9 @@ public class PredictionEngine {
|
||||
}
|
||||
|
||||
// Returns pair of primary push movement, and then outputvel
|
||||
Pair<Vector, Vector> output = doSeekingWallCollisions(player, primaryPushMovement, originalClientVel, clientVelAfterInput);
|
||||
Pair<Vector3D, Vector3D> output = doSeekingWallCollisions(player, primaryPushMovement, originalClientVel, clientVelAfterInput);
|
||||
primaryPushMovement = output.first();
|
||||
Vector outputVel = clampMovementToHardBorder(player, output.second());
|
||||
Vector3D outputVel = clampMovementToHardBorder(player, output.second());
|
||||
|
||||
double resultAccuracy = outputVel.distanceSquared(player.actualMovement);
|
||||
|
||||
@@ -211,7 +220,7 @@ public class PredictionEngine {
|
||||
}
|
||||
}
|
||||
|
||||
private Pair<Vector, Vector> doSeekingWallCollisions(GrimPlayer player, Vector primaryPushMovement, Vector originalClientVel, VectorData clientVelAfterInput) {
|
||||
private Pair<Vector3D, Vector3D> doSeekingWallCollisions(GrimPlayer player, Vector3D primaryPushMovement, Vector3D originalClientVel, VectorData clientVelAfterInput) {
|
||||
boolean vehicleKB = player.compensatedEntities.getSelf().inVehicle() && clientVelAfterInput.isKnockback() && clientVelAfterInput.vector.getY() == 0;
|
||||
// Extra collision epsilon required for vehicles to be accurate
|
||||
double xAdditional = Math.signum(primaryPushMovement.getX()) * SimpleCollisionBox.COLLISION_EPSILON;
|
||||
@@ -224,9 +233,9 @@ public class PredictionEngine {
|
||||
double testX = primaryPushMovement.getX() + xAdditional;
|
||||
double testY = primaryPushMovement.getY() + yAdditional;
|
||||
double testZ = primaryPushMovement.getZ() + zAdditional;
|
||||
primaryPushMovement = new Vector(testX, testY, testZ);
|
||||
primaryPushMovement = newVector3D(testX, testY, testZ);
|
||||
|
||||
Vector outputVel = Collisions.collide(player, primaryPushMovement.getX(), primaryPushMovement.getY(), primaryPushMovement.getZ(), originalClientVel.getY(), clientVelAfterInput);
|
||||
Vector3D outputVel = Collisions.collide(player, primaryPushMovement.getX(), primaryPushMovement.getY(), primaryPushMovement.getZ(), originalClientVel.getY(), clientVelAfterInput);
|
||||
|
||||
if (testX == outputVel.getX()) { // the player didn't have X collision, don't ruin offset by collision epsilon
|
||||
primaryPushMovement.setX(primaryPushMovement.getX() - xAdditional);
|
||||
@@ -252,20 +261,20 @@ public class PredictionEngine {
|
||||
|
||||
// For now just let the player control their Y velocity within 0.03. Gravity should stop exploits.
|
||||
// 0.03 - 0.784 < -0.03 = can't skip next tick
|
||||
Vector pointThreeVector = new Vector();
|
||||
Vector3D pointThreeVector = newVector3D();
|
||||
|
||||
// Stop a bypass (and fix falses) by carrying over the player's current velocity IF they couldn't have modified it
|
||||
if (!player.pointThreeEstimator.controlsVerticalMovement()) {
|
||||
pointThreeVector.setY(player.clientVelocity.getY());
|
||||
} else { // Carry over the current Y velocity to try and help with gravity issues
|
||||
pointThreePossibilities.add(new VectorData(new Vector(0, player.clientVelocity.getY(), 0), VectorData.VectorType.ZeroPointZeroThree));
|
||||
pointThreePossibilities.add(new VectorData(newVector3D(0, player.clientVelocity.getY(), 0), ZeroPointZeroThree));
|
||||
}
|
||||
|
||||
pointThreePossibilities.add(new VectorData(pointThreeVector, VectorData.VectorType.ZeroPointZeroThree));
|
||||
|
||||
// Swim hop
|
||||
if (player.pointThreeEstimator.isNearFluid && !Collisions.isEmpty(player, player.boundingBox.copy().expand(0.4, 0, 0.4)) && !player.onGround) { // onGround can still be used here, else generic 0.03
|
||||
pointThreePossibilities.add(new VectorData(new Vector(0, 0.3, 0), VectorData.VectorType.ZeroPointZeroThree));
|
||||
pointThreePossibilities.add(new VectorData(newVector3D(0, 0.3, 0), ZeroPointZeroThree));
|
||||
}
|
||||
|
||||
// Swimming vertically can add more Y velocity than normal
|
||||
@@ -282,7 +291,7 @@ public class PredictionEngine {
|
||||
player.clientVelocity.getX(), 0, player.clientVelocity.getZ()).expand(0.5, -SimpleCollisionBox.COLLISION_EPSILON, 0.5)))) {
|
||||
|
||||
// Calculate the Y velocity after friction
|
||||
Vector hackyClimbVector = new Vector(0, 0.2, 0);
|
||||
Vector3D hackyClimbVector = newVector3D(0, 0.2, 0);
|
||||
PredictionEngineNormal.staticVectorEndOfTick(player, hackyClimbVector);
|
||||
|
||||
pointThreePossibilities.add(new VectorData(hackyClimbVector, VectorData.VectorType.ZeroPointZeroThree));
|
||||
@@ -293,8 +302,8 @@ public class PredictionEngine {
|
||||
addExplosionToPossibilities(player, pointThreePossibilities);
|
||||
|
||||
if (player.packetStateData.tryingToRiptide) {
|
||||
Vector riptideAddition = Riptide.getRiptideVelocity(player);
|
||||
pointThreePossibilities.add(new VectorData(player.clientVelocity.clone().add(riptideAddition), new VectorData(new Vector(), VectorData.VectorType.ZeroPointZeroThree), VectorData.VectorType.Trident));
|
||||
Vector3D riptideAddition = Riptide.getRiptideVelocity(player);
|
||||
pointThreePossibilities.add(new VectorData(player.clientVelocity.clone().add(riptideAddition), new VectorData(newVector3D(), ZeroPointZeroThree), VectorData.VectorType.Trident));
|
||||
}
|
||||
|
||||
possibleVelocities.addAll(applyInputsToVelocityPossibilities(player, pointThreePossibilities, speed));
|
||||
@@ -315,7 +324,7 @@ public class PredictionEngine {
|
||||
// Water pushing movement is affected by initial velocity due to 0.003 eating pushing in the past
|
||||
if (vectorData.isKnockback() && player.baseTickWaterPushing.lengthSquared() != 0) {
|
||||
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_13)) {
|
||||
Vector vec3 = player.baseTickWaterPushing.clone();
|
||||
Vector3D vec3 = player.baseTickWaterPushing.clone();
|
||||
if (Math.abs(vectorData.vector.getX()) < 0.003 && Math.abs(vectorData.vector.getZ()) < 0.003 && player.baseTickWaterPushing.length() < 0.0045000000000000005D) {
|
||||
vec3 = vec3.normalize().multiply(0.0045000000000000005);
|
||||
}
|
||||
@@ -335,7 +344,7 @@ public class PredictionEngine {
|
||||
addExplosionToPossibilities(player, velocities);
|
||||
|
||||
if (player.packetStateData.tryingToRiptide) {
|
||||
Vector riptideAddition = Riptide.getRiptideVelocity(player);
|
||||
Vector3D riptideAddition = Riptide.getRiptideVelocity(player);
|
||||
velocities.add(new VectorData(player.clientVelocity.clone().add(riptideAddition), VectorData.VectorType.Trident));
|
||||
}
|
||||
|
||||
@@ -364,7 +373,7 @@ public class PredictionEngine {
|
||||
private void addAttackSlowToPossibilities(GrimPlayer player, Set<VectorData> velocities) {
|
||||
for (int x = 1; x <= Math.min(player.maxPlayerAttackSlow, 5); x++) {
|
||||
for (VectorData data : new HashSet<>(velocities)) {
|
||||
velocities.add(data.returnNewModified(data.vector.clone().multiply(new Vector(0.6, 1, 0.6)), VectorData.VectorType.AttackSlow));
|
||||
velocities.add(data.returnNewModified(data.vector.clone().multiply(newVector3D(0.6, 1, 0.6)), VectorData.VectorType.AttackSlow));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -467,15 +476,15 @@ public class PredictionEngine {
|
||||
return Double.compare(a.vector.distanceSquared(player.actualMovement), b.vector.distanceSquared(player.actualMovement));
|
||||
}
|
||||
|
||||
public Vector handleStartingVelocityUncertainty(GrimPlayer player, VectorData vector, Vector targetVec) {
|
||||
double avgColliding = Collections.max(player.uncertaintyHandler.collidingEntities);
|
||||
public Vector3D handleStartingVelocityUncertainty(GrimPlayer player, VectorData vector, Vector3D targetVec) {
|
||||
double avgColliding = max(player.uncertaintyHandler.collidingEntities);
|
||||
|
||||
double additionHorizontal = player.uncertaintyHandler.getOffsetHorizontal(vector);
|
||||
double additionVertical = player.uncertaintyHandler.getVerticalOffset(vector);
|
||||
|
||||
double pistonX = Collections.max(player.uncertaintyHandler.pistonX);
|
||||
double pistonY = Collections.max(player.uncertaintyHandler.pistonY);
|
||||
double pistonZ = Collections.max(player.uncertaintyHandler.pistonZ);
|
||||
double pistonX = max(player.uncertaintyHandler.pistonX);
|
||||
double pistonY = max(player.uncertaintyHandler.pistonY);
|
||||
double pistonZ = max(player.uncertaintyHandler.pistonZ);
|
||||
|
||||
additionHorizontal += player.uncertaintyHandler.lastHorizontalOffset;
|
||||
additionVertical += player.uncertaintyHandler.lastVerticalOffset;
|
||||
@@ -518,13 +527,13 @@ public class PredictionEngine {
|
||||
// 0.075 seems safe?
|
||||
//
|
||||
// Be somewhat careful as there is an antikb (for horizontal) that relies on this lenience
|
||||
Vector uncertainty = new Vector(avgColliding * 0.08, additionVertical, avgColliding * 0.08);
|
||||
Vector3D uncertainty = newVector3D(avgColliding * 0.08, additionVertical, avgColliding * 0.08);
|
||||
|
||||
Vector min = new Vector(player.uncertaintyHandler.xNegativeUncertainty - additionHorizontal, -bonusY + player.uncertaintyHandler.yNegativeUncertainty, player.uncertaintyHandler.zNegativeUncertainty - additionHorizontal);
|
||||
Vector max = new Vector(player.uncertaintyHandler.xPositiveUncertainty + additionHorizontal, bonusY + player.uncertaintyHandler.yPositiveUncertainty, player.uncertaintyHandler.zPositiveUncertainty + additionHorizontal);
|
||||
Vector3D min = newVector3D(player.uncertaintyHandler.xNegativeUncertainty - additionHorizontal, -bonusY + player.uncertaintyHandler.yNegativeUncertainty, player.uncertaintyHandler.zNegativeUncertainty - additionHorizontal);
|
||||
Vector3D max = newVector3D(player.uncertaintyHandler.xPositiveUncertainty + additionHorizontal, bonusY + player.uncertaintyHandler.yPositiveUncertainty, player.uncertaintyHandler.zPositiveUncertainty + additionHorizontal);
|
||||
|
||||
Vector minVector = vector.vector.clone().add(min.subtract(uncertainty));
|
||||
Vector maxVector = vector.vector.clone().add(max.add(uncertainty));
|
||||
Vector3D minVector = vector.vector.clone().add(min.subtract(uncertainty));
|
||||
Vector3D maxVector = vector.vector.clone().add(max.add(uncertainty));
|
||||
|
||||
// Handle the player landing within 0.03 movement, which resets Y velocity
|
||||
if (player.uncertaintyHandler.onGroundUncertain && vector.vector.getY() < 0) {
|
||||
@@ -551,7 +560,7 @@ public class PredictionEngine {
|
||||
// We can't simulate the player's Y velocity, unknown number of ticks with a gravity change
|
||||
// Feel free to simulate all 104857600000000000000000000 possibilities!
|
||||
if (!player.pointThreeEstimator.canPredictNextVerticalMovement()) {
|
||||
minVector.setY(minVector.getY() - player.compensatedEntities.getSelf().getAttributeValue(Attributes.GENERIC_GRAVITY));
|
||||
minVector.setY(minVector.getY() - player.compensatedEntities.getSelf().getAttributeValue(GENERIC_GRAVITY));
|
||||
}
|
||||
|
||||
// Hidden slime block bounces by missing idle tick and 0.03
|
||||
@@ -591,9 +600,9 @@ public class PredictionEngine {
|
||||
box.maxZ += sneaking.getSneakingPotentialHiddenVelocity().maxZ;
|
||||
|
||||
if (player.uncertaintyHandler.fireworksBox != null) {
|
||||
double minXdiff = Math.min(0, player.uncertaintyHandler.fireworksBox.minX - originalVec.vector.getX());
|
||||
double minYdiff = Math.min(0, player.uncertaintyHandler.fireworksBox.minY - originalVec.vector.getY());
|
||||
double minZdiff = Math.min(0, player.uncertaintyHandler.fireworksBox.minZ - originalVec.vector.getZ());
|
||||
double minXdiff = min(0, player.uncertaintyHandler.fireworksBox.minX - originalVec.vector.getX());
|
||||
double minYdiff = min(0, player.uncertaintyHandler.fireworksBox.minY - originalVec.vector.getY());
|
||||
double minZdiff = min(0, player.uncertaintyHandler.fireworksBox.minZ - originalVec.vector.getZ());
|
||||
double maxXdiff = Math.max(0, player.uncertaintyHandler.fireworksBox.maxX - originalVec.vector.getX());
|
||||
double maxYdiff = Math.max(0, player.uncertaintyHandler.fireworksBox.maxY - originalVec.vector.getY());
|
||||
double maxZdiff = Math.max(0, player.uncertaintyHandler.fireworksBox.maxZ - originalVec.vector.getZ());
|
||||
@@ -649,7 +658,7 @@ public class PredictionEngine {
|
||||
//
|
||||
// Or the player is switching in and out of controlling a vehicle, in which friction messes it up
|
||||
//
|
||||
if (player.uncertaintyHandler.lastVehicleSwitch.hasOccurredSince(0) || player.uncertaintyHandler.lastHardCollidingLerpingEntity.hasOccurredSince(3) || (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_13) && vector.vector.getY() > 0 && vector.isZeroPointZeroThree() && !Collisions.isEmpty(player, GetBoundingBox.getBoundingBoxFromPosAndSize(player, player.lastX, vector.vector.getY() + player.lastY + 0.6, player.lastZ, 0.6f, 1.26f)))) {
|
||||
if (player.uncertaintyHandler.lastVehicleSwitch.hasOccurredSince(0) || player.uncertaintyHandler.lastHardCollidingLerpingEntity.hasOccurredSince(3) || (player.getClientVersion().isNewerThanOrEquals(V_1_13) && vector.vector.getY() > 0 && vector.isZeroPointZeroThree() && !isEmpty(player, getBoundingBoxFromPosAndSize(player, player.lastX, vector.vector.getY() + player.lastY + 0.6, player.lastZ, 0.6f, 1.26f)))) {
|
||||
box.expandToAbsoluteCoordinates(0, 0, 0);
|
||||
}
|
||||
|
||||
@@ -661,9 +670,9 @@ public class PredictionEngine {
|
||||
if (player.wasTouchingWater) trueFriction = 0.96;
|
||||
|
||||
double maxY = Math.max(box.maxY, box.maxY + ((box.maxY - player.gravity) * 0.91));
|
||||
double minY = Math.min(box.minY, box.minY + ((box.minY - player.gravity) * 0.91));
|
||||
double minX = Math.min(box.minX, box.minX + (-player.speed * trueFriction));
|
||||
double minZ = Math.min(box.minZ, box.minZ + (-player.speed * trueFriction));
|
||||
double minY = min(box.minY, box.minY + ((box.minY - player.gravity) * 0.91));
|
||||
double minX = min(box.minX, box.minX + (-player.speed * trueFriction));
|
||||
double minZ = min(box.minZ, box.minZ + (-player.speed * trueFriction));
|
||||
double maxX = Math.max(box.maxX, box.maxX + (player.speed * trueFriction));
|
||||
double maxZ = Math.max(box.maxZ, box.maxZ + (player.speed * trueFriction));
|
||||
|
||||
@@ -679,15 +688,15 @@ public class PredictionEngine {
|
||||
maxVector = box.max();
|
||||
|
||||
if (pistonX != 0) {
|
||||
minVector.setX(Math.min(minVector.getX() - pistonX, pistonX));
|
||||
minVector.setX(min(minVector.getX() - pistonX, pistonX));
|
||||
maxVector.setX(Math.max(maxVector.getX() + pistonX, pistonX));
|
||||
}
|
||||
if (pistonY != 0) {
|
||||
minVector.setY(Math.min(minVector.getY() - pistonY, pistonY));
|
||||
minVector.setY(min(minVector.getY() - pistonY, pistonY));
|
||||
maxVector.setY(Math.max(maxVector.getY() + pistonY, pistonY));
|
||||
}
|
||||
if (pistonZ != 0) {
|
||||
minVector.setZ(Math.min(minVector.getZ() - pistonZ, pistonZ));
|
||||
minVector.setZ(min(minVector.getZ() - pistonZ, pistonZ));
|
||||
maxVector.setZ(Math.max(maxVector.getZ() + pistonZ, pistonZ));
|
||||
}
|
||||
return VectorUtils.cutBoxToVector(targetVec, minVector, maxVector);
|
||||
@@ -747,7 +756,7 @@ public class PredictionEngine {
|
||||
for (int strafe = strafeMin; strafe <= strafeMax; strafe++) {
|
||||
for (int forward = forwardMin; forward <= forwardMax; forward++) {
|
||||
VectorData result = new VectorData(possibleLastTickOutput.vector.clone()
|
||||
.add(getMovementResultFromInput(player, transformInputsToVector(player, new Vector(strafe, 0, forward)), speed, player.xRot)),
|
||||
.add(getMovementResultFromInput(player, transformInputsToVector(player, newVector3D(strafe, 0, forward)), speed, player.xRot)),
|
||||
possibleLastTickOutput, VectorData.VectorType.InputResult);
|
||||
result = result.returnNewModified(result.vector.clone().multiply(player.stuckSpeedMultiplier), VectorData.VectorType.StuckMultiplier);
|
||||
result = result.returnNewModified(handleOnClimbable(result.vector.clone(), player), VectorData.VectorType.Climbable);
|
||||
@@ -815,21 +824,21 @@ public class PredictionEngine {
|
||||
|
||||
// This is just the vanilla equation, which accepts invalid inputs greater than 1
|
||||
// We need it because of collision support when a player is using speed
|
||||
public Vector getMovementResultFromInput(GrimPlayer player, Vector inputVector, float f, float f2) {
|
||||
public Vector3D getMovementResultFromInput(GrimPlayer player, Vector3D inputVector, float f, float f2) {
|
||||
float f3 = player.trigHandler.sin(f2 * 0.017453292f);
|
||||
float f4 = player.trigHandler.cos(f2 * 0.017453292f);
|
||||
|
||||
double xResult = inputVector.getX() * f4 - inputVector.getZ() * f3;
|
||||
double zResult = inputVector.getZ() * f4 + inputVector.getX() * f3;
|
||||
|
||||
return new Vector(xResult * f, 0, zResult * f);
|
||||
return newVector3D(xResult * f, 0, zResult * f);
|
||||
}
|
||||
|
||||
public Vector handleOnClimbable(Vector vector, GrimPlayer player) {
|
||||
public Vector3D handleOnClimbable(Vector3D vector, GrimPlayer player) {
|
||||
return vector;
|
||||
}
|
||||
|
||||
public void doJump(GrimPlayer player, Vector vector) {
|
||||
public void doJump(GrimPlayer player, Vector3D vector) {
|
||||
if (!player.lastOnGround || player.onGround)
|
||||
return;
|
||||
|
||||
|
||||
+21
-16
@@ -3,28 +3,33 @@ package ac.grim.grimac.predictionengine.predictions;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import ac.grim.grimac.utils.nmsutil.ReachUtils;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static com.github.retrooper.packetevents.protocol.attribute.Attributes.GENERIC_GRAVITY;
|
||||
import static com.github.retrooper.packetevents.protocol.player.ClientVersion.V_1_18_2;
|
||||
import static com.github.retrooper.packetevents.protocol.player.ClientVersion.V_1_20_5;
|
||||
import static java.lang.Math.*;
|
||||
|
||||
public class PredictionEngineElytra extends PredictionEngine {
|
||||
// Inputs have no effect on movement
|
||||
@Override
|
||||
public List<VectorData> applyInputsToVelocityPossibilities(GrimPlayer player, Set<VectorData> possibleVectors, float speed) {
|
||||
List<VectorData> results = new ArrayList<>();
|
||||
Vector currentLook = ReachUtils.getLook(player, player.xRot, player.yRot);
|
||||
Vector3D currentLook = ReachUtils.getLook(player, player.xRot, player.yRot);
|
||||
|
||||
for (VectorData data : possibleVectors) {
|
||||
Vector elytraResult = getElytraMovement(player, data.vector.clone(), currentLook).multiply(player.stuckSpeedMultiplier).multiply(new Vector(0.99F, 0.98F, 0.99F));
|
||||
Vector3D elytraResult = getElytraMovement(player, data.vector.clone(), currentLook).multiply(player.stuckSpeedMultiplier).multiply(newVector3D(0.99F, 0.98F, 0.99F));
|
||||
results.add(data.returnNewModified(elytraResult, VectorData.VectorType.InputResult));
|
||||
|
||||
// We must bruteforce Optifine ShitMath
|
||||
player.trigHandler.toggleShitMath();
|
||||
elytraResult = getElytraMovement(player, data.vector.clone(), ReachUtils.getLook(player, player.xRot, player.yRot)).multiply(player.stuckSpeedMultiplier).multiply(new Vector(0.99F, 0.98F, 0.99F));
|
||||
elytraResult = getElytraMovement(player, data.vector.clone(), ReachUtils.getLook(player, player.xRot, player.yRot)).multiply(player.stuckSpeedMultiplier).multiply(newVector3D(0.99F, 0.98F, 0.99F));
|
||||
player.trigHandler.toggleShitMath();
|
||||
results.add(data.returnNewModified(elytraResult, VectorData.VectorType.InputResult));
|
||||
}
|
||||
@@ -32,42 +37,42 @@ public class PredictionEngineElytra extends PredictionEngine {
|
||||
return results;
|
||||
}
|
||||
|
||||
public static Vector getElytraMovement(GrimPlayer player, Vector vector, Vector lookVector) {
|
||||
public static Vector3D getElytraMovement(GrimPlayer player, Vector3D vector, Vector3D lookVector) {
|
||||
float yRotRadians = player.yRot * 0.017453292F;
|
||||
double horizontalSqrt = Math.sqrt(lookVector.getX() * lookVector.getX() + lookVector.getZ() * lookVector.getZ());
|
||||
double horizontalSqrt = sqrt(lookVector.getX() * lookVector.getX() + lookVector.getZ() * lookVector.getZ());
|
||||
double horizontalLength = vector.clone().setY(0).length();
|
||||
double length = lookVector.length();
|
||||
|
||||
// Mojang changed from using their math to using regular java math in 1.18.2 elytra movement
|
||||
double vertCosRotation = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_18_2) ? Math.cos(yRotRadians) : player.trigHandler.cos(yRotRadians);
|
||||
vertCosRotation = (float) (vertCosRotation * vertCosRotation * Math.min(1.0D, length / 0.4D));
|
||||
double vertCosRotation = player.getClientVersion().isNewerThanOrEquals(V_1_18_2) ? cos(yRotRadians) : player.trigHandler.cos(yRotRadians);
|
||||
vertCosRotation = (float) (vertCosRotation * vertCosRotation * min(1.0D, length / 0.4D));
|
||||
|
||||
// So we actually use the player's actual movement to get the gravity/slow falling status
|
||||
// However, this is wrong with elytra movement because players can control vertical movement after gravity is calculated
|
||||
// Yeah, slow falling needs a refactor in grim.
|
||||
double recalculatedGravity = player.compensatedEntities.getSelf().getAttributeValue(Attributes.GENERIC_GRAVITY);
|
||||
double recalculatedGravity = player.compensatedEntities.getSelf().getAttributeValue(GENERIC_GRAVITY);
|
||||
if (player.clientVelocity.getY() <= 0 && player.compensatedEntities.getSlowFallingAmplifier().isPresent()) {
|
||||
recalculatedGravity = player.getClientVersion().isOlderThan(ClientVersion.V_1_20_5) ? 0.01 : Math.min(recalculatedGravity, 0.01);
|
||||
recalculatedGravity = player.getClientVersion().isOlderThan(V_1_20_5) ? 0.01 : min(recalculatedGravity, 0.01);
|
||||
}
|
||||
|
||||
vector.add(new Vector(0.0D, recalculatedGravity * (-1.0D + vertCosRotation * 0.75D), 0.0D));
|
||||
vector.add(newVector3D(0.0D, recalculatedGravity * (-1.0D + vertCosRotation * 0.75D), 0.0D));
|
||||
double d5;
|
||||
|
||||
// Handle slowing the player down when falling
|
||||
if (vector.getY() < 0.0D && horizontalSqrt > 0.0D) {
|
||||
d5 = vector.getY() * -0.1D * vertCosRotation;
|
||||
vector.add(new Vector(lookVector.getX() * d5 / horizontalSqrt, d5, lookVector.getZ() * d5 / horizontalSqrt));
|
||||
vector.add(newVector3D(lookVector.getX() * d5 / horizontalSqrt, d5, lookVector.getZ() * d5 / horizontalSqrt));
|
||||
}
|
||||
|
||||
// Handle accelerating the player when they are looking down
|
||||
if (yRotRadians < 0.0F && horizontalSqrt > 0.0D) {
|
||||
d5 = horizontalLength * (double) (-player.trigHandler.sin(yRotRadians)) * 0.04D;
|
||||
vector.add(new Vector(-lookVector.getX() * d5 / horizontalSqrt, d5 * 3.2D, -lookVector.getZ() * d5 / horizontalSqrt));
|
||||
vector.add(newVector3D(-lookVector.getX() * d5 / horizontalSqrt, d5 * 3.2D, -lookVector.getZ() * d5 / horizontalSqrt));
|
||||
}
|
||||
|
||||
// Handle accelerating the player sideways
|
||||
if (horizontalSqrt > 0) {
|
||||
vector.add(new Vector((lookVector.getX() / horizontalSqrt * horizontalLength - vector.getX()) * 0.1D, 0.0D, (lookVector.getZ() / horizontalSqrt * horizontalLength - vector.getZ()) * 0.1D));
|
||||
vector.add(newVector3D((lookVector.getX() / horizontalSqrt * horizontalLength - vector.getX()) * 0.1D, 0.0D, (lookVector.getZ() / horizontalSqrt * horizontalLength - vector.getZ()) * 0.1D));
|
||||
}
|
||||
|
||||
return vector;
|
||||
|
||||
@@ -3,11 +3,13 @@ package ac.grim.grimac.predictionengine.predictions;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class PredictionEngineLava extends PredictionEngine {
|
||||
@Override
|
||||
public void addJumpsToPossibilities(GrimPlayer player, Set<VectorData> existingVelocities) {
|
||||
@@ -16,11 +18,11 @@ public class PredictionEngineLava extends PredictionEngine {
|
||||
double extraVelFromVertTickSkipUpwards = GrimMath.clamp(player.actualMovement.getY(), vector.vector.clone().getY(), vector.vector.clone().getY() + 0.05f);
|
||||
existingVelocities.add(new VectorData(vector.vector.clone().setY(extraVelFromVertTickSkipUpwards), vector, VectorData.VectorType.Jump));
|
||||
} else {
|
||||
existingVelocities.add(new VectorData(vector.vector.clone().add(new Vector(0, 0.04f, 0)), vector, VectorData.VectorType.Jump));
|
||||
existingVelocities.add(new VectorData(vector.vector.clone().add(newVector3D(0, 0.04f, 0)), vector, VectorData.VectorType.Jump));
|
||||
}
|
||||
|
||||
if (player.slightlyTouchingLava && player.lastOnGround && !player.onGround) {
|
||||
Vector withJump = vector.vector.clone();
|
||||
Vector3D withJump = vector.vector.clone();
|
||||
super.doJump(player, withJump);
|
||||
existingVelocities.add(new VectorData(withJump, vector, VectorData.VectorType.Jump));
|
||||
}
|
||||
|
||||
+17
-12
@@ -3,23 +3,28 @@ package ac.grim.grimac.predictionengine.predictions;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
import ac.grim.grimac.utils.nmsutil.Collisions;
|
||||
import ac.grim.grimac.utils.nmsutil.JumpPower;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Set;
|
||||
|
||||
import static ac.grim.grimac.utils.math.GrimMath.clamp;
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static com.github.retrooper.packetevents.protocol.world.states.type.StateTypes.SCAFFOLDING;
|
||||
import static java.lang.Math.max;
|
||||
|
||||
public class PredictionEngineNormal extends PredictionEngine {
|
||||
|
||||
public static void staticVectorEndOfTick(GrimPlayer player, Vector vector) {
|
||||
public static void staticVectorEndOfTick(GrimPlayer player, Vector3D vector) {
|
||||
double adjustedY = vector.getY();
|
||||
final OptionalInt levitation = player.compensatedEntities.getPotionLevelForPlayer(PotionTypes.LEVITATION);
|
||||
if (levitation.isPresent()) {
|
||||
@@ -42,7 +47,7 @@ public class PredictionEngineNormal extends PredictionEngine {
|
||||
}
|
||||
|
||||
for (VectorData vector : new HashSet<>(existingVelocities)) {
|
||||
Vector jump = vector.vector.clone();
|
||||
Vector3D jump = vector.vector.clone();
|
||||
|
||||
if (!player.isFlying) {
|
||||
// Negative jump boost does not allow the player to leave the ground
|
||||
@@ -56,9 +61,9 @@ public class PredictionEngineNormal extends PredictionEngine {
|
||||
|
||||
JumpPower.jumpFromGround(player, jump);
|
||||
} else {
|
||||
jump.add(new Vector(0, player.flySpeed * 3, 0));
|
||||
jump.add(newVector3D(0, player.flySpeed * 3, 0));
|
||||
if (!player.wasFlying) {
|
||||
Vector edgeCaseJump = jump.clone();
|
||||
Vector3D edgeCaseJump = jump.clone();
|
||||
JumpPower.jumpFromGround(player, edgeCaseJump);
|
||||
existingVelocities.add(vector.returnNewModified(edgeCaseJump, VectorData.VectorType.Jump));
|
||||
}
|
||||
@@ -86,7 +91,7 @@ public class PredictionEngineNormal extends PredictionEngine {
|
||||
if (player.lastWasClimbing == 0 && (player.pointThreeEstimator.isNearClimbable() || player.isClimbing) && (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14)
|
||||
|| !Collisions.isEmpty(player, player.boundingBox.copy().expand(
|
||||
player.clientVelocity.getX(), 0, player.clientVelocity.getZ()).expand(0.5, -SimpleCollisionBox.COLLISION_EPSILON, 0.5))) || walkingOnPowderSnow) {
|
||||
Vector ladderVelocity = player.clientVelocity.clone().setY(0.2);
|
||||
Vector3D ladderVelocity = player.clientVelocity.clone().setY(0.2);
|
||||
staticVectorEndOfTick(player, ladderVelocity);
|
||||
player.lastWasClimbing = ladderVelocity.getY();
|
||||
}
|
||||
@@ -97,17 +102,17 @@ public class PredictionEngineNormal extends PredictionEngine {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector handleOnClimbable(Vector vector, GrimPlayer player) {
|
||||
public Vector3D handleOnClimbable(Vector3D vector, GrimPlayer player) {
|
||||
if (player.isClimbing) {
|
||||
// Reset fall distance when climbing
|
||||
player.fallDistance = 0;
|
||||
|
||||
vector.setX(GrimMath.clamp(vector.getX(), -0.15F, 0.15F));
|
||||
vector.setZ(GrimMath.clamp(vector.getZ(), -0.15F, 0.15F));
|
||||
vector.setY(Math.max(vector.getY(), -0.15F));
|
||||
vector.setX(clamp(vector.getX(), -0.15F, 0.15F));
|
||||
vector.setZ(clamp(vector.getZ(), -0.15F, 0.15F));
|
||||
vector.setY(max(vector.getY(), -0.15F));
|
||||
|
||||
// Yes, this uses shifting not crouching
|
||||
if (vector.getY() < 0.0 && !(player.compensatedWorld.getStateTypeAt(player.lastX, player.lastY, player.lastZ) == StateTypes.SCAFFOLDING) && player.isSneaking && !player.isFlying) {
|
||||
if (vector.getY() < 0.0 && !(player.compensatedWorld.getStateTypeAt(player.lastX, player.lastY, player.lastZ) == SCAFFOLDING) && player.isSneaking && !player.isFlying) {
|
||||
vector.setY(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
+10
-7
@@ -9,11 +9,14 @@ import ac.grim.grimac.utils.nmsutil.Collisions;
|
||||
import ac.grim.grimac.utils.nmsutil.FluidFallingAdjustedMovement;
|
||||
import ac.grim.grimac.utils.nmsutil.ReachUtils;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static ac.grim.grimac.utils.data.VectorData.VectorType.SwimmingSpace;
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class PredictionEngineWater extends PredictionEngine {
|
||||
boolean isFalling;
|
||||
double playerGravity;
|
||||
@@ -21,9 +24,9 @@ public class PredictionEngineWater extends PredictionEngine {
|
||||
float swimmingFriction;
|
||||
double lastY;
|
||||
|
||||
public static void staticVectorEndOfTick(GrimPlayer player, Vector vector, float swimmingFriction, double playerGravity, boolean isFalling) {
|
||||
vector.multiply(new Vector(swimmingFriction, 0.8F, swimmingFriction));
|
||||
Vector fluidVector = FluidFallingAdjustedMovement.getFluidFallingAdjustedMovement(player, playerGravity, isFalling, vector);
|
||||
public static void staticVectorEndOfTick(GrimPlayer player, Vector3D vector, float swimmingFriction, double playerGravity, boolean isFalling) {
|
||||
vector.multiply(newVector3D(swimmingFriction, 0.8F, swimmingFriction));
|
||||
Vector3D fluidVector = FluidFallingAdjustedMovement.getFluidFallingAdjustedMovement(player, playerGravity, isFalling, vector);
|
||||
vector.setX(fluidVector.getX());
|
||||
vector.setY(fluidVector.getY());
|
||||
vector.setZ(fluidVector.getZ());
|
||||
@@ -47,7 +50,7 @@ public class PredictionEngineWater extends PredictionEngine {
|
||||
double scalar = lookYAmount < -0.2 ? 0.085 : 0.06;
|
||||
|
||||
// The player can always press jump and activate this
|
||||
swimmingVelocities.add(vector.returnNewModified(new Vector(vector.vector.getX(), vector.vector.getY() + ((lookYAmount - vector.vector.getY()) * scalar), vector.vector.getZ()), VectorData.VectorType.SwimmingSpace));
|
||||
swimmingVelocities.add(vector.returnNewModified(newVector3D(vector.vector.getX(), vector.vector.getY() + ((lookYAmount - vector.vector.getY()) * scalar), vector.vector.getZ()), SwimmingSpace));
|
||||
|
||||
// This scenario will occur if the player does not press jump and the other conditions are met
|
||||
// Theoretically we should check this BEFORE allowing no look, but there isn't a cheat that takes advantage of this yet
|
||||
@@ -80,11 +83,11 @@ public class PredictionEngineWater extends PredictionEngine {
|
||||
double extraVelFromVertTickSkipUpwards = GrimMath.clamp(player.actualMovement.getY(), vector.vector.clone().getY(), vector.vector.clone().getY() + 0.05f);
|
||||
existingVelocities.add(new VectorData(vector.vector.clone().setY(extraVelFromVertTickSkipUpwards), vector, VectorData.VectorType.Jump));
|
||||
} else {
|
||||
existingVelocities.add(new VectorData(vector.vector.clone().add(new Vector(0, 0.04f, 0)), vector, VectorData.VectorType.Jump));
|
||||
existingVelocities.add(new VectorData(vector.vector.clone().add(newVector3D(0, 0.04f, 0)), vector, VectorData.VectorType.Jump));
|
||||
}
|
||||
|
||||
if (player.slightlyTouchingWater && player.lastOnGround && !player.onGround) {
|
||||
Vector withJump = vector.vector.clone();
|
||||
Vector3D withJump = vector.vector.clone();
|
||||
super.doJump(player, withJump);
|
||||
existingVelocities.add(new VectorData(withJump, vector, VectorData.VectorType.Jump));
|
||||
}
|
||||
|
||||
+12
-9
@@ -2,11 +2,15 @@ package ac.grim.grimac.predictionengine.predictions;
|
||||
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static java.lang.Math.sqrt;
|
||||
|
||||
public class PredictionEngineWaterLegacy extends PredictionEngine {
|
||||
double playerGravity;
|
||||
float swimmingSpeed;
|
||||
@@ -23,11 +27,11 @@ public class PredictionEngineWaterLegacy extends PredictionEngine {
|
||||
|
||||
// This is just the vanilla equation for legacy water movement
|
||||
@Override
|
||||
public Vector getMovementResultFromInput(GrimPlayer player, Vector inputVector, float f, float f2) {
|
||||
public Vector3D getMovementResultFromInput(GrimPlayer player, Vector3D inputVector, float f, float f2) {
|
||||
float lengthSquared = (float) inputVector.lengthSquared();
|
||||
|
||||
if (lengthSquared >= 1.0E-4F) {
|
||||
lengthSquared = (float) Math.sqrt(lengthSquared);
|
||||
lengthSquared = (float) sqrt(lengthSquared);
|
||||
|
||||
if (lengthSquared < 1.0F) {
|
||||
lengthSquared = 1.0F;
|
||||
@@ -38,21 +42,20 @@ public class PredictionEngineWaterLegacy extends PredictionEngine {
|
||||
float sinResult = player.trigHandler.sin(player.xRot * 0.017453292F);
|
||||
float cosResult = player.trigHandler.cos(player.xRot * 0.017453292F);
|
||||
|
||||
return new Vector(inputVector.getX() * cosResult - inputVector.getZ() * sinResult,
|
||||
inputVector.getY(), inputVector.getZ() * cosResult + inputVector.getX() * sinResult);
|
||||
return newVector3D(inputVector.getX() * cosResult - inputVector.getZ() * sinResult, inputVector.getY(), inputVector.getZ() * cosResult + inputVector.getX() * sinResult);
|
||||
}
|
||||
|
||||
return new Vector();
|
||||
return newVector3D();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addJumpsToPossibilities(GrimPlayer player, Set<VectorData> existingVelocities) {
|
||||
for (VectorData vector : new HashSet<>(existingVelocities)) {
|
||||
existingVelocities.add(new VectorData(vector.vector.clone().add(new Vector(0, 0.04f, 0)), vector, VectorData.VectorType.Jump));
|
||||
existingVelocities.add(new VectorData(vector.vector.clone().add(newVector3D(0, 0.04f, 0)), vector, VectorData.VectorType.Jump));
|
||||
|
||||
if (player.skippedTickInActualMovement) {
|
||||
existingVelocities.add(new VectorData(vector.vector.clone().add(new Vector(0, 0.02f, 0)), vector, VectorData.VectorType.Jump));
|
||||
existingVelocities.add(new VectorData(vector.vector.clone().add(newVector3D(0, 0.02f, 0)), vector, VectorData.VectorType.Jump));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +65,7 @@ public class PredictionEngineWaterLegacy extends PredictionEngine {
|
||||
super.endOfTick(player, playerGravity);
|
||||
|
||||
for (VectorData vector : player.getPossibleVelocitiesMinusKnockback()) {
|
||||
vector.vector.multiply(new Vector(swimmingFriction, 0.8F, swimmingFriction));
|
||||
vector.vector.multiply(newVector3D(swimmingFriction, 0.8F, swimmingFriction));
|
||||
|
||||
// Gravity
|
||||
vector.vector.setY(vector.vector.getY() - 0.02D);
|
||||
|
||||
+9
-6
@@ -13,12 +13,15 @@ import ac.grim.grimac.utils.nmsutil.GetBoundingBox;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static java.lang.Math.PI;
|
||||
|
||||
public class BoatPredictionEngine extends PredictionEngine {
|
||||
public BoatPredictionEngine(GrimPlayer player) {
|
||||
player.uncertaintyHandler.collidingEntities.add(0); // We don't do collisions like living entities
|
||||
@@ -147,7 +150,7 @@ public class BoatPredictionEngine extends PredictionEngine {
|
||||
// so if a player tries to move in both directions, a packet will
|
||||
// show that the player is staying, but the boat will move anyway
|
||||
if (player.vehicleData.vehicleForward == 0) {
|
||||
Vector vector = data.vector.clone();
|
||||
Vector3D vector = data.vector.clone();
|
||||
controlBoat(player, vector, true);
|
||||
vector.multiply(player.stuckSpeedMultiplier);
|
||||
vectors.add(data.returnNewModified(vector, VectorData.VectorType.InputResult));
|
||||
@@ -184,7 +187,7 @@ public class BoatPredictionEngine extends PredictionEngine {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void floatBoat(GrimPlayer player, Vector vector) {
|
||||
private void floatBoat(GrimPlayer player, Vector3D vector) {
|
||||
double d1 = player.hasGravity ? -0.04f : 0;
|
||||
double d2 = 0.0D;
|
||||
float invFriction = 0.05F;
|
||||
@@ -194,7 +197,7 @@ public class BoatPredictionEngine extends PredictionEngine {
|
||||
|
||||
player.lastY = getWaterLevelAbove(player) - 0.5625F + 0.101D;
|
||||
player.boundingBox = GetBoundingBox.getCollisionBoxForPlayer(player, player.lastX, player.lastY, player.lastZ);
|
||||
player.actualMovement = new Vector(player.x - player.lastX, player.y - player.lastY, player.z - player.lastZ);
|
||||
player.actualMovement = newVector3D(player.x - player.lastX, player.y - player.lastY, player.z - player.lastZ);
|
||||
vector.setY(0);
|
||||
|
||||
player.vehicleData.lastYd = 0.0D;
|
||||
@@ -260,7 +263,7 @@ public class BoatPredictionEngine extends PredictionEngine {
|
||||
return (float) (l + 1);
|
||||
}
|
||||
|
||||
private void controlBoat(GrimPlayer player, Vector vector, boolean intermediate) {
|
||||
private void controlBoat(GrimPlayer player, Vector3D vector, boolean intermediate) {
|
||||
float f = 0.0F;
|
||||
if (player.vehicleData.vehicleHorizontal != 0 && (!intermediate && player.vehicleData.vehicleForward == 0)) {
|
||||
f += 0.005F;
|
||||
@@ -275,6 +278,6 @@ public class BoatPredictionEngine extends PredictionEngine {
|
||||
f -= 0.005F;
|
||||
}
|
||||
|
||||
vector.add(new Vector(player.trigHandler.sin(-player.xRot * ((float) Math.PI / 180F)) * f, 0, (double) (player.trigHandler.cos(player.xRot * ((float) Math.PI / 180F)) * f)));
|
||||
vector.add(newVector3D(player.trigHandler.sin(-player.xRot * ((float) PI / 180F)) * f, 0, (double) (player.trigHandler.cos(player.xRot * ((float) PI / 180F)) * f)));
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -3,16 +3,16 @@ package ac.grim.grimac.predictionengine.predictions.rideable;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.predictionengine.predictions.PredictionEngineLava;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class PredictionEngineRideableLava extends PredictionEngineLava {
|
||||
|
||||
Vector movementVector;
|
||||
Vector3D movementVector;
|
||||
|
||||
public PredictionEngineRideableLava(Vector movementVector) {
|
||||
public PredictionEngineRideableLava(Vector3D movementVector) {
|
||||
this.movementVector = movementVector;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -3,16 +3,16 @@ package ac.grim.grimac.predictionengine.predictions.rideable;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.predictionengine.predictions.PredictionEngineNormal;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class PredictionEngineRideableNormal extends PredictionEngineNormal {
|
||||
|
||||
Vector movementVector;
|
||||
Vector3D movementVector;
|
||||
|
||||
public PredictionEngineRideableNormal(Vector movementVector) {
|
||||
public PredictionEngineRideableNormal(Vector3D movementVector) {
|
||||
this.movementVector = movementVector;
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -8,13 +8,15 @@ import ac.grim.grimac.utils.data.packetentity.PacketEntityHorse;
|
||||
import ac.grim.grimac.utils.nmsutil.JumpPower;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.Set;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class PredictionEngineRideableUtils {
|
||||
public static Set<VectorData> handleJumps(GrimPlayer player, Set<VectorData> possibleVectors) {
|
||||
if (!(player.compensatedEntities.getSelf().getRiding() instanceof PacketEntityHorse horse)) return possibleVectors;
|
||||
@@ -55,7 +57,7 @@ public class PredictionEngineRideableUtils {
|
||||
for (VectorData vectorData : possibleVectors) {
|
||||
vectorData.vector.setY(d1);
|
||||
if (f1 > 0.0F) {
|
||||
vectorData.vector.add(new Vector(-0.4F * f2 * player.vehicleData.horseJump, 0.0D, 0.4F * f3 * player.vehicleData.horseJump));
|
||||
vectorData.vector.add(newVector3D(-0.4F * f2 * player.vehicleData.horseJump, 0.0D, 0.4F * f3 * player.vehicleData.horseJump));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +73,7 @@ public class PredictionEngineRideableUtils {
|
||||
return possibleVectors;
|
||||
}
|
||||
|
||||
public static List<VectorData> applyInputsToVelocityPossibilities(Vector movementVector, GrimPlayer player, Set<VectorData> possibleVectors, float speed) {
|
||||
public static List<VectorData> applyInputsToVelocityPossibilities(Vector3D movementVector, GrimPlayer player, Set<VectorData> possibleVectors, float speed) {
|
||||
List<VectorData> returnVectors = new ArrayList<>();
|
||||
|
||||
for (VectorData possibleLastTickOutput : possibleVectors) {
|
||||
|
||||
+3
-3
@@ -3,16 +3,16 @@ package ac.grim.grimac.predictionengine.predictions.rideable;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.predictionengine.predictions.PredictionEngineWater;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class PredictionEngineRideableWater extends PredictionEngineWater {
|
||||
|
||||
Vector movementVector;
|
||||
Vector3D movementVector;
|
||||
|
||||
public PredictionEngineRideableWater(Vector movementVector) {
|
||||
public PredictionEngineRideableWater(Vector3D movementVector) {
|
||||
this.movementVector = movementVector;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -3,15 +3,15 @@ package ac.grim.grimac.predictionengine.predictions.rideable;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.predictionengine.predictions.PredictionEngineWaterLegacy;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class PredictionEngineRideableWaterLegacy extends PredictionEngineWaterLegacy {
|
||||
Vector movementVector;
|
||||
Vector3D movementVector;
|
||||
|
||||
public PredictionEngineRideableWaterLegacy(Vector movementVector) {
|
||||
public PredictionEngineRideableWaterLegacy(Vector3D movementVector) {
|
||||
this.movementVector = movementVector;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import ac.grim.grimac.utils.math.GrimMath;
|
||||
import ac.grim.grimac.utils.nmsutil.BoundingBoxSize;
|
||||
import ac.grim.grimac.utils.nmsutil.GetBoundingBox;
|
||||
import ac.grim.grimac.utils.nmsutil.Materials;
|
||||
import ac.grim.grimac.utils.nmsutil.ReachUtils;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
@@ -35,18 +35,23 @@ import com.github.retrooper.packetevents.util.Vector3f;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static ac.grim.grimac.utils.nmsutil.ReachUtils.calculateIntercept;
|
||||
import static ac.grim.grimac.utils.nmsutil.ReachUtils.getLook;
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static com.github.retrooper.packetevents.protocol.attribute.Attributes.PLAYER_BLOCK_INTERACTION_RANGE;
|
||||
|
||||
public class BlockPlace {
|
||||
protected static final BlockFace[] UPDATE_SHAPE_ORDER = new BlockFace[]{BlockFace.WEST, BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.DOWN, BlockFace.UP};
|
||||
private static final BlockFace[] BY_2D = new BlockFace[]{BlockFace.SOUTH, BlockFace.WEST, BlockFace.NORTH, BlockFace.EAST};
|
||||
static final BlockFace[] BY_3D = new BlockFace[]{BlockFace.DOWN, BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, BlockFace.EAST};
|
||||
@Setter
|
||||
Vector3i blockPosition;
|
||||
public Vector3i blockPosition;
|
||||
@Getter
|
||||
InteractionHand hand;
|
||||
@Getter
|
||||
@@ -661,18 +666,18 @@ public class BlockPlace {
|
||||
// You also have the desync caused by eye height as apparently tracking the player's ticks wasn't important to you
|
||||
// No mojang, you really do need to track client ticks to get their accurate eye height.
|
||||
// another damn desync added... maybe next decade it will get fixed and double the amount of issues.
|
||||
public Vector getClickedLocation() {
|
||||
public Vector3D getClickedLocation() {
|
||||
SimpleCollisionBox box = new SimpleCollisionBox(getPlacedAgainstBlockLocation());
|
||||
Vector look = ReachUtils.getLook(player, player.xRot, player.yRot);
|
||||
Vector3D look = getLook(player, player.xRot, player.yRot);
|
||||
|
||||
final double distance = player.compensatedEntities.getSelf().getAttributeValue(Attributes.PLAYER_BLOCK_INTERACTION_RANGE) + 3;
|
||||
Vector eyePos = new Vector(player.x, player.y + player.getEyeHeight(), player.z);
|
||||
Vector endReachPos = eyePos.clone().add(new Vector(look.getX() * distance, look.getY() * distance, look.getZ() * distance));
|
||||
Vector intercept = ReachUtils.calculateIntercept(box, eyePos, endReachPos).first();
|
||||
final double distance = player.compensatedEntities.getSelf().getAttributeValue(PLAYER_BLOCK_INTERACTION_RANGE) + 3;
|
||||
Vector3D eyePos = newVector3D(player.x, player.y + player.getEyeHeight(), player.z);
|
||||
Vector3D endReachPos = eyePos.clone().add(newVector3D(look.getX() * distance, look.getY() * distance, look.getZ() * distance));
|
||||
Vector3D intercept = calculateIntercept(box, eyePos, endReachPos).first();
|
||||
|
||||
// Bring this back to relative to the block
|
||||
// The player didn't even click the block... (we should force resync BEFORE we get here!)
|
||||
if (intercept == null) return new Vector();
|
||||
if (intercept == null) return newVector3D();
|
||||
|
||||
intercept.setX(intercept.getX() - box.minX);
|
||||
intercept.setY(intercept.getY() - box.minY);
|
||||
|
||||
@@ -21,11 +21,13 @@ import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateValue;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public enum BlockPlaceResult {
|
||||
|
||||
// If the block only has directional data
|
||||
@@ -80,7 +82,7 @@ public enum BlockPlaceResult {
|
||||
}, ItemTypes.SNOW),
|
||||
|
||||
SLAB((player, place) -> {
|
||||
Vector clickedPos = place.getClickedLocation();
|
||||
Vector3D clickedPos = place.getClickedLocation();
|
||||
WrappedBlockState slabData = place.getMaterial().createBlockState(CompensatedWorld.blockVersion);
|
||||
WrappedBlockState existing = place.getExistingBlockData();
|
||||
|
||||
@@ -909,7 +911,7 @@ public enum BlockPlaceResult {
|
||||
WrappedBlockState ccwState = place.getDirectionalState(ccw);
|
||||
CollisionBox ccwBox = CollisionData.getData(ccwState.getType()).getMovementCollisionBox(player, player.getClientVersion(), ccwState);
|
||||
|
||||
Vector aboveCCWPos = place.getClickedLocation().add(new Vector(ccw.getModX(), ccw.getModY(), ccw.getModZ())).add(new Vector(0, 1, 0));
|
||||
Vector3D aboveCCWPos = place.getClickedLocation().add(newVector3D(ccw.getModX(), ccw.getModY(), ccw.getModZ())).add(newVector3D(0, 1, 0));
|
||||
WrappedBlockState aboveCCWState = player.compensatedWorld.getWrappedBlockStateAt(aboveCCWPos);
|
||||
CollisionBox aboveCCWBox = CollisionData.getData(aboveCCWState.getType()).getMovementCollisionBox(player, player.getClientVersion(), aboveCCWState);
|
||||
|
||||
@@ -917,7 +919,7 @@ public enum BlockPlaceResult {
|
||||
WrappedBlockState cwState = place.getDirectionalState(cw);
|
||||
CollisionBox cwBox = CollisionData.getData(cwState.getType()).getMovementCollisionBox(player, player.getClientVersion(), cwState);
|
||||
|
||||
Vector aboveCWPos = place.getClickedLocation().add(new Vector(cw.getModX(), cw.getModY(), cw.getModZ())).add(new Vector(0, 1, 0));
|
||||
Vector3D aboveCWPos = place.getClickedLocation().add(newVector3D(cw.getModX(), cw.getModY(), cw.getModZ())).add(newVector3D(0, 1, 0));
|
||||
WrappedBlockState aboveCWState = player.compensatedWorld.getWrappedBlockStateAt(aboveCWPos);
|
||||
CollisionBox aboveCWBox = CollisionData.getData(aboveCWState.getType()).getMovementCollisionBox(player, player.getClientVersion(), aboveCWState);
|
||||
|
||||
@@ -934,7 +936,7 @@ public enum BlockPlaceResult {
|
||||
if ((!isCWLower || isCCWLower) && i >= 0) {
|
||||
int j = playerFacing.getModX();
|
||||
int k = playerFacing.getModZ();
|
||||
Vector vec3 = place.getClickedLocation();
|
||||
Vector3D vec3 = place.getClickedLocation();
|
||||
double d0 = vec3.getX();
|
||||
double d1 = vec3.getY();
|
||||
hinge = (j >= 0 || d1 >= 0.5D) && (j <= 0 || d1 <= 0.5D) && (k >= 0 || d0 <= 0.5D) && (k <= 0 || d0 >= 0.5D) ? Hinge.LEFT : Hinge.RIGHT;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package ac.grim.grimac.utils.blockstate.helper;
|
||||
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
public class BlockFaceHelper {
|
||||
public static boolean isFaceVertical(BlockFace face) {
|
||||
@@ -56,7 +57,7 @@ public class BlockFaceHelper {
|
||||
};
|
||||
}
|
||||
|
||||
public Vector offset(Vector toOffset, BlockFace face) {
|
||||
public Vector3D offset(Vector3D toOffset, BlockFace face) {
|
||||
toOffset.setX(toOffset.getX() + face.getModX());
|
||||
toOffset.setY(toOffset.getY() + face.getModY());
|
||||
toOffset.setZ(toOffset.getZ() + face.getModZ());
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package ac.grim.grimac.utils.collisions.datatypes;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class BoundingBox {
|
||||
|
||||
@@ -15,7 +18,7 @@ public class BoundingBox {
|
||||
this.maxZ = maxZ;
|
||||
}
|
||||
|
||||
public BoundingBox(Vector min, Vector max) {
|
||||
public BoundingBox(Vector3D min, Vector3D max) {
|
||||
this.minX = (float) Math.min(min.getX(), max.getX());
|
||||
this.minY = (float) Math.min(min.getY(), max.getY());
|
||||
this.minZ = (float) Math.min(min.getZ(), max.getZ());
|
||||
@@ -44,7 +47,7 @@ public class BoundingBox {
|
||||
return new BoundingBox(newMinX, newMinY, newMinZ, newMaxX, newMaxY, newMaxZ);
|
||||
}
|
||||
|
||||
public BoundingBox add(Vector vector) {
|
||||
public BoundingBox add(Vector3D vector) {
|
||||
float x = (float) vector.getX(), y = (float) vector.getY(), z = (float) vector.getZ();
|
||||
|
||||
float newMinX = minX + x;
|
||||
@@ -87,27 +90,27 @@ public class BoundingBox {
|
||||
return new BoundingBox(this.minX - minX, this.minY - minY, this.minZ - minZ, this.maxX - maxX, this.maxY - maxY, this.maxZ - maxZ);
|
||||
}
|
||||
|
||||
public boolean intersectsWithBox(Vector vector) {
|
||||
public boolean intersectsWithBox(Vector3D vector) {
|
||||
return (vector.getX() > this.minX && vector.getX() < this.maxX) && ((vector.getY() > this.minY && vector.getY() < this.maxY) && (vector.getZ() > this.minZ && vector.getZ() < this.maxZ));
|
||||
}
|
||||
|
||||
public Vector getMinimum() {
|
||||
return new Vector(minX, minY, minZ);
|
||||
public Vector3D getMinimum() {
|
||||
return newVector3D(minX, minY, minZ);
|
||||
}
|
||||
|
||||
public Vector getMaximum() {
|
||||
return new Vector(maxX, maxY, maxZ);
|
||||
public Vector3D getMaximum() {
|
||||
return newVector3D(maxX, maxY, maxZ);
|
||||
}
|
||||
|
||||
public boolean collides(Vector vector) {
|
||||
public boolean collides(Vector3D vector) {
|
||||
return (vector.getX() >= this.minX && vector.getX() <= this.maxX) && ((vector.getY() >= this.minY && vector.getY() <= this.maxY) && (vector.getZ() >= this.minZ && vector.getZ() <= this.maxZ));
|
||||
}
|
||||
|
||||
public boolean collidesHorizontally(Vector vector) {
|
||||
public boolean collidesHorizontally(Vector3D vector) {
|
||||
return (vector.getX() >= this.minX && vector.getX() <= this.maxX) && ((vector.getY() > this.minY && vector.getY() < this.maxY) && (vector.getZ() >= this.minZ && vector.getZ() <= this.maxZ));
|
||||
}
|
||||
|
||||
public boolean collidesVertically(Vector vector) {
|
||||
public boolean collidesVertically(Vector3D vector) {
|
||||
return (vector.getX() > this.minX && vector.getX() < this.maxX) && ((vector.getY() >= this.minY && vector.getY() <= this.maxY) && (vector.getZ() > this.minZ && vector.getZ() < this.maxZ));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package ac.grim.grimac.utils.collisions.datatypes;
|
||||
|
||||
import ac.grim.grimac.utils.nmsutil.Ray;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
@@ -8,10 +9,12 @@ import it.unimi.dsi.fastutil.doubles.AbstractDoubleList;
|
||||
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
|
||||
import it.unimi.dsi.fastutil.doubles.DoubleList;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class SimpleCollisionBox implements CollisionBox {
|
||||
|
||||
public static final double COLLISION_EPSILON = 1.0E-7;
|
||||
@@ -46,7 +49,7 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
isFullBlock = fullBlock;
|
||||
}
|
||||
|
||||
public SimpleCollisionBox(Vector min, Vector max) {
|
||||
public SimpleCollisionBox(Vector3D min, Vector3D max) {
|
||||
this(min.getX(), min.getY(), min.getZ(), max.getX(), max.getY(), max.getZ());
|
||||
}
|
||||
|
||||
@@ -85,10 +88,10 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
}
|
||||
|
||||
public SimpleCollisionBox(Location loc, double width, double height) {
|
||||
this(loc.toVector(), width, height);
|
||||
this(newVector3D(loc.getX(), loc.getY(), loc.getZ()), width, height);
|
||||
}
|
||||
|
||||
public SimpleCollisionBox(Vector vec, double width, double height) {
|
||||
public SimpleCollisionBox(Vector3D vec, double width, double height) {
|
||||
this(vec.getX(), vec.getY(), vec.getZ(), vec.getX(), vec.getY(), vec.getZ());
|
||||
|
||||
expand(width / 2, 0, width / 2);
|
||||
@@ -151,16 +154,16 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector[] corners() {
|
||||
Vector[] vectors = new Vector[8];
|
||||
vectors[0] = new Vector(minX, minY, minZ);
|
||||
vectors[1] = new Vector(minX, minY, maxZ);
|
||||
vectors[2] = new Vector(maxX, minY, minZ);
|
||||
vectors[3] = new Vector(maxX, minY, maxZ);
|
||||
vectors[4] = new Vector(minX, maxY, minZ);
|
||||
vectors[5] = new Vector(minX, maxY, maxZ);
|
||||
vectors[6] = new Vector(maxX, maxY, minZ);
|
||||
vectors[7] = new Vector(maxX, maxY, maxZ);
|
||||
public Vector3D[] corners() {
|
||||
Vector3D[] vectors = new Vector3D[8];
|
||||
vectors[0] = newVector3D(minX, minY, minZ);
|
||||
vectors[1] = newVector3D(minX, minY, maxZ);
|
||||
vectors[2] = newVector3D(maxX, minY, minZ);
|
||||
vectors[3] = newVector3D(maxX, minY, maxZ);
|
||||
vectors[4] = newVector3D(minX, maxY, minZ);
|
||||
vectors[5] = newVector3D(minX, maxY, maxZ);
|
||||
vectors[6] = newVector3D(maxX, maxY, minZ);
|
||||
vectors[7] = newVector3D(maxX, maxY, maxZ);
|
||||
return vectors;
|
||||
}
|
||||
|
||||
@@ -408,14 +411,14 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
*/
|
||||
// Copied from hawk lol
|
||||
// I would like to point out that this is magic to me and I have not attempted to understand this code
|
||||
public Vector intersectsRay(Ray ray, float minDist, float maxDist) {
|
||||
Vector invDir = new Vector(1f / ray.calculateDirection().getX(), 1f / ray.calculateDirection().getY(), 1f / ray.calculateDirection().getZ());
|
||||
public Vector3D intersectsRay(Ray ray, float minDist, float maxDist) {
|
||||
Vector3D invDir = newVector3D(1f / ray.calculateDirection().getX(), 1f / ray.calculateDirection().getY(), 1f / ray.calculateDirection().getZ());
|
||||
|
||||
boolean signDirX = invDir.getX() < 0;
|
||||
boolean signDirY = invDir.getY() < 0;
|
||||
boolean signDirZ = invDir.getZ() < 0;
|
||||
|
||||
Vector bbox = signDirX ? max() : min();
|
||||
Vector3D bbox = signDirX ? max() : min();
|
||||
double tmin = (bbox.getX() - ray.getOrigin().getX()) * invDir.getX();
|
||||
bbox = signDirX ? min() : max();
|
||||
double tmax = (bbox.getX() - ray.getOrigin().getX()) * invDir.getX();
|
||||
@@ -454,12 +457,12 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Vector max() {
|
||||
return new Vector(maxX, maxY, maxZ);
|
||||
public Vector3D max() {
|
||||
return newVector3D(maxX, maxY, maxZ);
|
||||
}
|
||||
|
||||
public Vector min() {
|
||||
return new Vector(minX, minY, minZ);
|
||||
public Vector3D min() {
|
||||
return newVector3D(minX, minY, minZ);
|
||||
}
|
||||
|
||||
public DoubleList getYPointPositions() {
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package ac.grim.grimac.utils.data;
|
||||
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
public class HitData {
|
||||
Vector3i position;
|
||||
Vector blockHitLocation;
|
||||
Vector3D blockHitLocation;
|
||||
WrappedBlockState state;
|
||||
BlockFace closestDirection;
|
||||
|
||||
public HitData(Vector3i position, Vector blockHitLocation, BlockFace closestDirection, WrappedBlockState state) {
|
||||
public HitData(Vector3i position, Vector3D blockHitLocation, BlockFace closestDirection, WrappedBlockState state) {
|
||||
this.position = position;
|
||||
this.blockHitLocation = blockHitLocation;
|
||||
this.closestDirection = closestDirection;
|
||||
|
||||
@@ -3,7 +3,7 @@ package ac.grim.grimac.utils.data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@@ -11,14 +11,14 @@ import org.bukkit.util.Vector;
|
||||
public class SetBackData {
|
||||
TeleportData teleportData;
|
||||
float xRot, yRot;
|
||||
Vector velocity;
|
||||
Vector3D velocity;
|
||||
boolean vehicle;
|
||||
boolean isComplete = false;
|
||||
// TODO: Rethink when we block movements for teleports, perhaps after 10 ticks or 5 blocks?
|
||||
boolean isPlugin = false;
|
||||
int ticksComplete = 0;
|
||||
|
||||
public SetBackData(TeleportData teleportData, float xRot, float yRot, Vector velocity, boolean vehicle, boolean isPlugin) {
|
||||
public SetBackData(TeleportData teleportData, float xRot, float yRot, Vector3D velocity, boolean vehicle, boolean isPlugin) {
|
||||
this.teleportData = teleportData;
|
||||
this.xRot = xRot;
|
||||
this.yRot = yRot;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package ac.grim.grimac.utils.data;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -9,13 +9,13 @@ public class VectorData {
|
||||
public VectorType vectorType;
|
||||
public VectorData lastVector;
|
||||
public VectorData preUncertainty;
|
||||
public Vector vector;
|
||||
public Vector3D vector;
|
||||
|
||||
@Getter
|
||||
private boolean isKnockback, firstBreadKb, isExplosion, firstBreadExplosion, isTrident, isZeroPointZeroThree, isSwimHop, isFlipSneaking, isFlipItem, isJump, isAttackSlow = false;
|
||||
|
||||
// For handling replacing the type of vector it is while keeping data
|
||||
public VectorData(Vector vector, VectorData lastVector, VectorType vectorType) {
|
||||
public VectorData(Vector3D vector, VectorData lastVector, VectorType vectorType) {
|
||||
this.vector = vector;
|
||||
this.lastVector = lastVector;
|
||||
this.vectorType = vectorType;
|
||||
@@ -38,7 +38,7 @@ public class VectorData {
|
||||
addVectorType(vectorType);
|
||||
}
|
||||
|
||||
public VectorData(Vector vector, VectorType vectorType) {
|
||||
public VectorData(Vector3D vector, VectorType vectorType) {
|
||||
this.vector = vector;
|
||||
this.vectorType = vectorType;
|
||||
addVectorType(vectorType);
|
||||
@@ -48,7 +48,7 @@ public class VectorData {
|
||||
return new VectorData(vector, this, type);
|
||||
}
|
||||
|
||||
public VectorData returnNewModified(Vector newVec, VectorType type) {
|
||||
public VectorData returnNewModified(Vector3D newVec, VectorType type) {
|
||||
return new VectorData(newVec, this, type);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class VectorData {
|
||||
return Objects.hash(vectorType, lastVector, preUncertainty, vector, isKnockback, firstBreadKb, isExplosion, firstBreadExplosion, isTrident, isZeroPointZeroThree, isSwimHop, isFlipSneaking, isFlipItem, isJump, isAttackSlow);
|
||||
}
|
||||
|
||||
private void addVectorType(VectorType type) {
|
||||
protected void addVectorType(VectorType type) {
|
||||
switch (type) {
|
||||
case Knockback:
|
||||
isKnockback = true;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package ac.grim.grimac.utils.data;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
public class VelocityData {
|
||||
public final Vector vector;
|
||||
public final Vector3D vector;
|
||||
public final int entityID;
|
||||
public final int transaction;
|
||||
public double offset = Integer.MAX_VALUE;
|
||||
public boolean isSetback;
|
||||
|
||||
public VelocityData(int entityID, int transaction, boolean isSetback, Vector vector) {
|
||||
public VelocityData(int entityID, int transaction, boolean isSetback, Vector3D vector) {
|
||||
this.entityID = entityID;
|
||||
this.vector = vector;
|
||||
this.transaction = transaction;
|
||||
@@ -17,7 +17,7 @@ public class VelocityData {
|
||||
}
|
||||
|
||||
// First bread last tick -> Required this tick = don't require kb twice
|
||||
public VelocityData(int entityID, int transaction, Vector vector, boolean isSetback, double offset) {
|
||||
public VelocityData(int entityID, int transaction, Vector3D vector, boolean isSetback, double offset) {
|
||||
this.entityID = entityID;
|
||||
this.vector = vector;
|
||||
this.transaction = transaction;
|
||||
|
||||
@@ -49,7 +49,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -686,7 +686,7 @@ public class CompensatedWorld {
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
public WrappedBlockState getWrappedBlockStateAt(Vector aboveCCWPos) {
|
||||
public WrappedBlockState getWrappedBlockStateAt(Vector3D aboveCCWPos) {
|
||||
return getWrappedBlockStateAt(aboveCCWPos.getX(), aboveCCWPos.getY(), aboveCCWPos.getZ());
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,14 @@
|
||||
package ac.grim.grimac.utils.math;
|
||||
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static com.github.retrooper.packetevents.protocol.player.ClientVersion.V_1_8;
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class TrigHandler {
|
||||
GrimPlayer player;
|
||||
@@ -19,24 +24,24 @@ public class TrigHandler {
|
||||
isVanillaMath = !isVanillaMath;
|
||||
}
|
||||
|
||||
public Vector getVanillaMathMovement(Vector wantedMovement, float f, float f2) {
|
||||
public Vector3D getVanillaMathMovement(Vector3D wantedMovement, float f, float f2) {
|
||||
float f3 = VanillaMath.sin(f2 * 0.017453292f);
|
||||
float f4 = VanillaMath.cos(f2 * 0.017453292f);
|
||||
|
||||
float bestTheoreticalX = (float) (f3 * wantedMovement.getZ() + f4 * wantedMovement.getX()) / (f3 * f3 + f4 * f4) / f;
|
||||
float bestTheoreticalZ = (float) (-f3 * wantedMovement.getX() + f4 * wantedMovement.getZ()) / (f3 * f3 + f4 * f4) / f;
|
||||
|
||||
return new Vector(bestTheoreticalX, 0, bestTheoreticalZ);
|
||||
return newVector3D(bestTheoreticalX, 0, bestTheoreticalZ);
|
||||
}
|
||||
|
||||
public Vector getShitMathMovement(Vector wantedMovement, float f, float f2) {
|
||||
float f3 = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_8) ? OptifineFastMath.sin(f2 * 0.017453292f) : LegacyFastMath.sin(f2 * 0.017453292f);
|
||||
float f4 = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_8) ? OptifineFastMath.cos(f2 * 0.017453292f) : LegacyFastMath.cos(f2 * 0.017453292f);
|
||||
public Vector3D getShitMathMovement(Vector3D wantedMovement, float f, float f2) {
|
||||
float f3 = player.getClientVersion().isNewerThanOrEquals(V_1_8) ? OptifineFastMath.sin(f2 * 0.017453292f) : LegacyFastMath.sin(f2 * 0.017453292f);
|
||||
float f4 = player.getClientVersion().isNewerThanOrEquals(V_1_8) ? OptifineFastMath.cos(f2 * 0.017453292f) : LegacyFastMath.cos(f2 * 0.017453292f);
|
||||
|
||||
float bestTheoreticalX = (float) (f3 * wantedMovement.getZ() + f4 * wantedMovement.getX()) / (f3 * f3 + f4 * f4) / f;
|
||||
float bestTheoreticalZ = (float) (-f3 * wantedMovement.getX() + f4 * wantedMovement.getZ()) / (f3 * f3 + f4 * f4) / f;
|
||||
|
||||
return new Vector(bestTheoreticalX, 0, bestTheoreticalZ);
|
||||
return newVector3D(bestTheoreticalX, 0, bestTheoreticalZ);
|
||||
}
|
||||
|
||||
public void setOffset(double offset) {
|
||||
@@ -49,12 +54,12 @@ public class TrigHandler {
|
||||
}
|
||||
|
||||
if (offset > 1e-5) {
|
||||
Vector trueMovement = player.actualMovement.clone().subtract(player.startTickClientVel);
|
||||
Vector correctMath = getVanillaMathMovement(trueMovement, 0.1f, player.xRot);
|
||||
Vector fastMath = getShitMathMovement(trueMovement, 0.1f, player.xRot);
|
||||
Vector3D trueMovement = player.actualMovement.clone().subtract(player.startTickClientVel);
|
||||
Vector3D correctMath = getVanillaMathMovement(trueMovement, 0.1f, player.xRot);
|
||||
Vector3D fastMath = getShitMathMovement(trueMovement, 0.1f, player.xRot);
|
||||
|
||||
correctMath = new Vector(Math.abs(correctMath.getX()), 0, Math.abs(correctMath.getZ()));
|
||||
fastMath = new Vector(Math.abs(fastMath.getX()), 0, Math.abs(fastMath.getZ()));
|
||||
correctMath = newVector3D(abs(correctMath.getX()), 0, abs(correctMath.getZ()));
|
||||
fastMath = newVector3D(abs(fastMath.getX()), 0, abs(fastMath.getZ()));
|
||||
|
||||
double minCorrectHorizontal = Math.min(correctMath.getX(), correctMath.getZ());
|
||||
// Support diagonal inputs
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
package ac.grim.grimac.utils.math;
|
||||
|
||||
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.math.GrimMath.clamp;
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class VectorUtils {
|
||||
public static Vector cutBoxToVector(Vector vectorToCutTo, Vector min, Vector max) {
|
||||
public static Vector3D cutBoxToVector(Vector3D vectorToCutTo, Vector3D min, Vector3D max) {
|
||||
SimpleCollisionBox box = new SimpleCollisionBox(min, max).sort();
|
||||
return cutBoxToVector(vectorToCutTo, box);
|
||||
}
|
||||
|
||||
public static Vector cutBoxToVector(Vector vectorCutTo, SimpleCollisionBox box) {
|
||||
return new Vector(GrimMath.clamp(vectorCutTo.getX(), box.minX, box.maxX),
|
||||
GrimMath.clamp(vectorCutTo.getY(), box.minY, box.maxY),
|
||||
GrimMath.clamp(vectorCutTo.getZ(), box.minZ, box.maxZ));
|
||||
public static Vector3D cutBoxToVector(Vector3D vectorCutTo, SimpleCollisionBox box) {
|
||||
return newVector3D(clamp(vectorCutTo.getX(), box.minX, box.maxX), clamp(vectorCutTo.getY(), box.minY, box.maxY), clamp(vectorCutTo.getZ(), box.minZ, box.maxZ));
|
||||
}
|
||||
|
||||
public static Vector fromVec3d(Vector3d vector3d) {
|
||||
return new Vector(vector3d.getX(), vector3d.getY(), vector3d.getZ());
|
||||
public static Vector3D fromVec3d(Vector3d vector3d) {
|
||||
return newVector3D(vector3d.getX(), vector3d.getY(), vector3d.getZ());
|
||||
}
|
||||
|
||||
// Clamping stops the player from causing an integer overflow and crashing the netty thread
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -12,6 +12,7 @@ import ac.grim.grimac.utils.data.tags.SyncedTags;
|
||||
import ac.grim.grimac.utils.latency.CompensatedWorld;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
import ac.grim.grimac.utils.math.VectorUtils;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
@@ -26,7 +27,7 @@ import it.unimi.dsi.fastutil.floats.FloatArraySet;
|
||||
import it.unimi.dsi.fastutil.floats.FloatArrays;
|
||||
import it.unimi.dsi.fastutil.floats.FloatSet;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -34,6 +35,13 @@ import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static ac.grim.grimac.utils.nmsutil.Collisions.Axis.*;
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static com.github.retrooper.packetevents.protocol.player.ClientVersion.*;
|
||||
import static java.lang.Double.MAX_VALUE;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
public class Collisions {
|
||||
private static final double COLLISION_EPSILON = 1.0E-7;
|
||||
|
||||
@@ -72,12 +80,12 @@ public class Collisions {
|
||||
}
|
||||
|
||||
// Call this when there isn't uncertainty on the Y axis
|
||||
public static Vector collide(GrimPlayer player, double desiredX, double desiredY, double desiredZ) {
|
||||
public static Vector3D collide(GrimPlayer player, double desiredX, double desiredY, double desiredZ) {
|
||||
return collide(player, desiredX, desiredY, desiredZ, desiredY, null);
|
||||
}
|
||||
|
||||
public static Vector collide(GrimPlayer player, double desiredX, double desiredY, double desiredZ, double clientVelY, VectorData data) {
|
||||
if (desiredX == 0 && desiredY == 0 && desiredZ == 0) return new Vector();
|
||||
public static Vector3D collide(GrimPlayer player, double desiredX, double desiredY, double desiredZ, double clientVelY, VectorData data) {
|
||||
if (desiredX == 0 && desiredY == 0 && desiredZ == 0) return newVector3D();
|
||||
|
||||
final SimpleCollisionBox grabBoxesBB = player.boundingBox.copy();
|
||||
final double stepUpHeight = player.getMaxUpStep();
|
||||
@@ -95,7 +103,7 @@ public class Collisions {
|
||||
grabBoxesBB.expandToCoordinate(desiredX, desiredY, desiredZ);
|
||||
grabBoxesBB.maxY += stepUpHeight;
|
||||
} else {
|
||||
grabBoxesBB.expandToCoordinate(desiredX, Math.max(stepUpHeight, desiredY), desiredZ);
|
||||
grabBoxesBB.expandToCoordinate(desiredX, max(stepUpHeight, desiredY), desiredZ);
|
||||
}
|
||||
} else {
|
||||
grabBoxesBB.expandToCoordinate(desiredX, desiredY, desiredZ);
|
||||
@@ -105,14 +113,14 @@ public class Collisions {
|
||||
List<SimpleCollisionBox> desiredMovementCollisionBoxes = new ArrayList<>();
|
||||
getCollisionBoxes(player, grabBoxesBB, desiredMovementCollisionBoxes, false);
|
||||
|
||||
double bestInput = Double.MAX_VALUE;
|
||||
Vector bestOrderResult = null;
|
||||
double bestInput = MAX_VALUE;
|
||||
Vector3D bestOrderResult = null;
|
||||
|
||||
Vector bestTheoreticalCollisionResult = VectorUtils.cutBoxToVector(player.actualMovement, new SimpleCollisionBox(0, Math.min(0, desiredY), 0, desiredX, Math.max(stepUpHeight, desiredY), desiredZ).sort());
|
||||
Vector3D bestTheoreticalCollisionResult = VectorUtils.cutBoxToVector(player.actualMovement, new SimpleCollisionBox(0, min(0, desiredY), 0, desiredX, max(stepUpHeight, desiredY), desiredZ).sort());
|
||||
int zeroCount = (desiredX == 0 ? 1 : 0) + (desiredY == 0 ? 1 : 0) + (desiredZ == 0 ? 1 : 0);
|
||||
|
||||
for (List<Axis> order : (data != null && data.isZeroPointZeroThree() ? allAxisCombinations : nonStupidityCombinations)) {
|
||||
Vector collisionResult = collideBoundingBoxLegacy(new Vector(desiredX, desiredY, desiredZ), player.boundingBox, desiredMovementCollisionBoxes, order);
|
||||
Vector3D collisionResult = collideBoundingBoxLegacy(newVector3D(desiredX, desiredY, desiredZ), player.boundingBox, desiredMovementCollisionBoxes, order);
|
||||
|
||||
// While running up stairs and holding space, the player activates the "lastOnGround" part without otherwise being able to step
|
||||
// 0.03 movement must compensate for stepping elsewhere. Too much of a hack to include in this met5hod.
|
||||
@@ -124,7 +132,7 @@ public class Collisions {
|
||||
if (stepUpHeight > 0.0F && movingIntoGround && (collisionResult.getX() != desiredX || collisionResult.getZ() != desiredZ)) {
|
||||
player.uncertaintyHandler.isStepMovement = true;
|
||||
// 1.21 significantly refactored this
|
||||
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_21)) {
|
||||
if (player.getClientVersion().isNewerThanOrEquals(V_1_21)) {
|
||||
SimpleCollisionBox box2 = movingIntoGroundReal ? player.boundingBox.copy().offset(0.0, collisionResult.getY(), 0.0) : player.boundingBox.copy();
|
||||
SimpleCollisionBox box3 = box2.copy().expandToCoordinate(desiredX, stepUpHeight, desiredZ);
|
||||
if (!movingIntoGroundReal) {
|
||||
@@ -136,21 +144,21 @@ public class Collisions {
|
||||
final float[] stepHeights = collectStepHeights(box2, list2, (float) stepUpHeight, (float) collisionResult.getY());
|
||||
|
||||
for (float stepHeight : stepHeights) {
|
||||
Vector vec3d2 = collideBoundingBoxLegacy(new Vector(desiredX, stepHeight, desiredZ), box2, list2, order);
|
||||
Vector3D vec3d2 = collideBoundingBoxLegacy(newVector3D(desiredX, stepHeight, desiredZ), box2, list2, order);
|
||||
if (getHorizontalDistanceSqr(vec3d2) > getHorizontalDistanceSqr(collisionResult)) {
|
||||
final double d = player.boundingBox.minY - box2.minY;
|
||||
collisionResult = vec3d2.add(new Vector(0.0, -d, 0.0));
|
||||
collisionResult = vec3d2.add(newVector3D(0.0, -d, 0.0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Vector regularStepUp = collideBoundingBoxLegacy(new Vector(desiredX, stepUpHeight, desiredZ), player.boundingBox, desiredMovementCollisionBoxes, order);
|
||||
Vector3D regularStepUp = collideBoundingBoxLegacy(newVector3D(desiredX, stepUpHeight, desiredZ), player.boundingBox, desiredMovementCollisionBoxes, order);
|
||||
|
||||
// 1.7 clients do not have this stepping bug fix
|
||||
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_8)) {
|
||||
Vector stepUpBugFix = collideBoundingBoxLegacy(new Vector(0, stepUpHeight, 0), player.boundingBox.copy().expandToCoordinate(desiredX, 0, desiredZ), desiredMovementCollisionBoxes, order);
|
||||
if (player.getClientVersion().isNewerThanOrEquals(V_1_8)) {
|
||||
Vector3D stepUpBugFix = collideBoundingBoxLegacy(newVector3D(0, stepUpHeight, 0), player.boundingBox.copy().expandToCoordinate(desiredX, 0, desiredZ), desiredMovementCollisionBoxes, order);
|
||||
if (stepUpBugFix.getY() < stepUpHeight) {
|
||||
Vector stepUpBugFixResult = collideBoundingBoxLegacy(new Vector(desiredX, 0, desiredZ), player.boundingBox.copy().offset(0, stepUpBugFix.getY(), 0), desiredMovementCollisionBoxes, order).add(stepUpBugFix);
|
||||
Vector3D stepUpBugFixResult = collideBoundingBoxLegacy(newVector3D(desiredX, 0, desiredZ), player.boundingBox.copy().offset(0, stepUpBugFix.getY(), 0), desiredMovementCollisionBoxes, order).add(stepUpBugFix);
|
||||
if (getHorizontalDistanceSqr(stepUpBugFixResult) > getHorizontalDistanceSqr(regularStepUp)) {
|
||||
regularStepUp = stepUpBugFixResult;
|
||||
}
|
||||
@@ -158,7 +166,7 @@ public class Collisions {
|
||||
}
|
||||
|
||||
if (getHorizontalDistanceSqr(regularStepUp) > getHorizontalDistanceSqr(collisionResult)) {
|
||||
collisionResult = regularStepUp.add(collideBoundingBoxLegacy(new Vector(0, -regularStepUp.getY() + (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14) ? desiredY : 0), 0), player.boundingBox.copy().offset(regularStepUp.getX(), regularStepUp.getY(), regularStepUp.getZ()), desiredMovementCollisionBoxes, order));
|
||||
collisionResult = regularStepUp.add(collideBoundingBoxLegacy(newVector3D(0, -regularStepUp.getY() + (player.getClientVersion().isNewerThanOrEquals(V_1_14) ? desiredY : 0), 0), player.boundingBox.copy().offset(regularStepUp.getX(), regularStepUp.getY(), regularStepUp.getZ()), desiredMovementCollisionBoxes, order));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -343,7 +351,7 @@ public class Collisions {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Vector collideBoundingBoxLegacy(Vector toCollide, SimpleCollisionBox
|
||||
public static Vector3D collideBoundingBoxLegacy(Vector3D toCollide, SimpleCollisionBox
|
||||
box, List<SimpleCollisionBox> desiredMovementCollisionBoxes, List<Axis> order) {
|
||||
double x = toCollide.getX();
|
||||
double y = toCollide.getY();
|
||||
@@ -352,17 +360,17 @@ public class Collisions {
|
||||
SimpleCollisionBox setBB = box.copy();
|
||||
|
||||
for (Axis axis : order) {
|
||||
if (axis == Axis.X) {
|
||||
if (axis == X) {
|
||||
for (SimpleCollisionBox bb : desiredMovementCollisionBoxes) {
|
||||
x = bb.collideX(setBB, x);
|
||||
}
|
||||
setBB.offset(x, 0.0D, 0.0D);
|
||||
} else if (axis == Axis.Y) {
|
||||
} else if (axis == Y) {
|
||||
for (SimpleCollisionBox bb : desiredMovementCollisionBoxes) {
|
||||
y = bb.collideY(setBB, y);
|
||||
}
|
||||
setBB.offset(0.0D, y, 0.0D);
|
||||
} else if (axis == Axis.Z) {
|
||||
} else if (axis == Z) {
|
||||
for (SimpleCollisionBox bb : desiredMovementCollisionBoxes) {
|
||||
z = bb.collideZ(setBB, z);
|
||||
}
|
||||
@@ -370,23 +378,23 @@ public class Collisions {
|
||||
}
|
||||
}
|
||||
|
||||
return new Vector(x, y, z);
|
||||
return newVector3D(x, y, z);
|
||||
}
|
||||
|
||||
public static boolean isEmpty(GrimPlayer player, SimpleCollisionBox playerBB) {
|
||||
return !getCollisionBoxes(player, playerBB, null, true);
|
||||
}
|
||||
|
||||
private static double getHorizontalDistanceSqr(Vector vector) {
|
||||
private static double getHorizontalDistanceSqr(Vector3D vector) {
|
||||
return vector.getX() * vector.getX() + vector.getZ() * vector.getZ();
|
||||
}
|
||||
|
||||
public static Vector maybeBackOffFromEdge(Vector vec3, GrimPlayer player, boolean overrideVersion) {
|
||||
public static Vector3D maybeBackOffFromEdge(Vector3D vec3, GrimPlayer player, boolean overrideVersion) {
|
||||
if (!player.isFlying && player.isSneaking && isAboveGround(player)) {
|
||||
double x = vec3.getX();
|
||||
double z = vec3.getZ();
|
||||
|
||||
double maxStepDown = overrideVersion || player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_11) ? -player.getMaxUpStep() : -1 + COLLISION_EPSILON;
|
||||
double maxStepDown = overrideVersion || player.getClientVersion().isNewerThanOrEquals(V_1_11) ? -player.getMaxUpStep() : -1 + COLLISION_EPSILON;
|
||||
|
||||
while (x != 0.0 && isEmpty(player, player.boundingBox.copy().offset(x, maxStepDown, 0.0))) {
|
||||
if (x < 0.05D && x >= -0.05D) {
|
||||
@@ -423,7 +431,7 @@ public class Collisions {
|
||||
z += 0.05D;
|
||||
}
|
||||
}
|
||||
vec3 = new Vector(x, vec3.getY(), z);
|
||||
vec3 = newVector3D(x, vec3.getY(), z);
|
||||
}
|
||||
|
||||
return vec3;
|
||||
@@ -454,20 +462,20 @@ public class Collisions {
|
||||
|
||||
if (blockType == StateTypes.COBWEB) {
|
||||
if (player.compensatedEntities.hasPotionEffect(PotionTypes.WEAVING)) {
|
||||
player.stuckSpeedMultiplier = new Vector(0.5, 0.25, 0.5);
|
||||
player.stuckSpeedMultiplier = newVector3D(0.5, 0.25, 0.5);
|
||||
} else {
|
||||
player.stuckSpeedMultiplier = new Vector(0.25, 0.05000000074505806, 0.25);
|
||||
player.stuckSpeedMultiplier = newVector3D(0.25, 0.05000000074505806, 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
if (blockType == StateTypes.SWEET_BERRY_BUSH
|
||||
&& player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14)) {
|
||||
player.stuckSpeedMultiplier = new Vector(0.800000011920929, 0.75, 0.800000011920929);
|
||||
player.stuckSpeedMultiplier = newVector3D(0.800000011920929, 0.75, 0.800000011920929);
|
||||
}
|
||||
|
||||
if (blockType == StateTypes.POWDER_SNOW && i == Math.floor(player.x) && j == Math.floor(player.y) && k == Math.floor(player.z)
|
||||
&& player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_17)) {
|
||||
player.stuckSpeedMultiplier = new Vector(0.8999999761581421, 1.5, 0.8999999761581421);
|
||||
player.stuckSpeedMultiplier = newVector3D(0.8999999761581421, 1.5, 0.8999999761581421);
|
||||
}
|
||||
|
||||
if (blockType == StateTypes.SOUL_SAND && player.getClientVersion().isOlderThan(ClientVersion.V_1_15)) {
|
||||
@@ -534,7 +542,7 @@ public class Collisions {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSlidingDown(Vector vector, GrimPlayer player, int locationX, int locationY,
|
||||
private static boolean isSlidingDown(Vector3D vector, GrimPlayer player, int locationX, int locationY,
|
||||
int locationZ) {
|
||||
if (player.onGround) {
|
||||
return false;
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
package ac.grim.grimac.utils.nmsutil;
|
||||
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static com.github.retrooper.packetevents.protocol.player.ClientVersion.V_1_14;
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class FluidFallingAdjustedMovement {
|
||||
public static Vector getFluidFallingAdjustedMovement(GrimPlayer player, double d, boolean bl, Vector vec3) {
|
||||
public static Vector3D getFluidFallingAdjustedMovement(GrimPlayer player, double d, boolean bl, Vector3D vec3) {
|
||||
if (player.hasGravity && !player.isSprinting) {
|
||||
boolean falling = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14) ? bl : vec3.getY() < 0;
|
||||
double d2 = falling && Math.abs(vec3.getY() - 0.005) >= 0.003 && Math.abs(vec3.getY() - d / 16.0) < 0.003 ? -0.003 : vec3.getY() - d / 16.0;
|
||||
return new Vector(vec3.getX(), d2, vec3.getZ());
|
||||
boolean falling = player.getClientVersion().isNewerThanOrEquals(V_1_14) ? bl : vec3.getY() < 0;
|
||||
double d2 = falling && abs(vec3.getY() - 0.005) >= 0.003 && abs(vec3.getY() - d / 16.0) < 0.003 ? -0.003 : vec3.getY() - d / 16.0;
|
||||
return newVector3D(vec3.getX(), d2, vec3.getZ());
|
||||
}
|
||||
return vec3;
|
||||
}
|
||||
|
||||
@@ -3,29 +3,37 @@ package ac.grim.grimac.utils.nmsutil;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.collisions.CollisionData;
|
||||
import ac.grim.grimac.utils.collisions.blocks.DoorHandler;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.nmsutil.Materials.isSolidBlockingBlacklist;
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static com.github.retrooper.packetevents.protocol.world.BlockFace.*;
|
||||
import static com.github.retrooper.packetevents.protocol.world.states.type.StateTypes.LAVA;
|
||||
import static com.github.retrooper.packetevents.protocol.world.states.type.StateTypes.WATER;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
public class FluidTypeFlowing {
|
||||
public static Vector getFlow(GrimPlayer player, int originalX, int originalY, int originalZ) {
|
||||
float fluidLevel = (float) Math.min(player.compensatedWorld.getFluidLevelAt(originalX, originalY, originalZ), 8 / 9D);
|
||||
public static Vector3D getFlow(GrimPlayer player, int originalX, int originalY, int originalZ) {
|
||||
float fluidLevel = (float) min(player.compensatedWorld.getFluidLevelAt(originalX, originalY, originalZ), 8 / 9D);
|
||||
ClientVersion version = player.getClientVersion();
|
||||
|
||||
if (fluidLevel == 0) return new Vector();
|
||||
if (fluidLevel == 0) return newVector3D();
|
||||
|
||||
double d0 = 0.0D;
|
||||
double d1 = 0.0D;
|
||||
for (BlockFace enumdirection : new BlockFace[]{BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST}) {
|
||||
for (BlockFace enumdirection : new BlockFace[]{NORTH, EAST, SOUTH, WEST}) {
|
||||
int modifiedX = originalX + enumdirection.getModX();
|
||||
int modifiedZ = originalZ + enumdirection.getModZ();
|
||||
|
||||
if (affectsFlow(player, originalX, originalY, originalZ, modifiedX, originalY, modifiedZ)) {
|
||||
float f = (float) Math.min(player.compensatedWorld.getFluidLevelAt(modifiedX, originalY, modifiedZ), 8 / 9D);
|
||||
float f = (float) min(player.compensatedWorld.getFluidLevelAt(modifiedX, originalY, modifiedZ), 8 / 9D);
|
||||
float f1 = 0.0F;
|
||||
if (f == 0.0F) {
|
||||
StateType mat = player.compensatedWorld.getStateTypeAt(modifiedX, originalY, modifiedZ);
|
||||
@@ -33,9 +41,9 @@ public class FluidTypeFlowing {
|
||||
// Grim's definition of solid is whether the block has a hitbox
|
||||
// Minecraft is... it's whatever Mojang was feeling like, but it's very consistent
|
||||
// Use method call to support 1.13-1.15 clients and banner oddity
|
||||
if (Materials.isSolidBlockingBlacklist(mat, version)) {
|
||||
if (isSolidBlockingBlacklist(mat, version)) {
|
||||
if (affectsFlow(player, originalX, originalY, originalZ, modifiedX, originalY - 1, modifiedZ)) {
|
||||
f = (float) Math.min(player.compensatedWorld.getFluidLevelAt(modifiedX, originalY - 1, modifiedZ), 8 / 9D);
|
||||
f = (float) min(player.compensatedWorld.getFluidLevelAt(modifiedX, originalY - 1, modifiedZ), 8 / 9D);
|
||||
if (f > 0.0F) {
|
||||
f1 = fluidLevel - (f - 0.8888889F);
|
||||
}
|
||||
@@ -53,15 +61,15 @@ public class FluidTypeFlowing {
|
||||
}
|
||||
}
|
||||
|
||||
Vector vec3d = new Vector(d0, 0.0D, d1);
|
||||
Vector3D vec3d = newVector3D(d0, 0.0D, d1);
|
||||
|
||||
// Fluid level 1-7 is for regular fluid heights
|
||||
// Fluid level 8-15 is for falling fluids
|
||||
WrappedBlockState state = player.compensatedWorld.getWrappedBlockStateAt(originalX, originalY, originalZ);
|
||||
if ((state.getType() == StateTypes.WATER || state.getType() == StateTypes.LAVA) && state.getLevel() >= 8) {
|
||||
for (BlockFace enumdirection : new BlockFace[]{BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST}) {
|
||||
if ((state.getType() == WATER || state.getType() == LAVA) && state.getLevel() >= 8) {
|
||||
for (BlockFace enumdirection : new BlockFace[]{NORTH, EAST, SOUTH, WEST}) {
|
||||
if (isSolidFace(player, originalX, originalY, originalZ, enumdirection) || isSolidFace(player, originalX, originalY + 1, originalZ, enumdirection)) {
|
||||
vec3d = normalizeVectorWithoutNaN(vec3d).add(new Vector(0.0D, -6.0D, 0.0D));
|
||||
vec3d = normalizeVectorWithoutNaN(vec3d).add(newVector3D(0.0D, -6.0D, 0.0D));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -150,9 +158,9 @@ public class FluidTypeFlowing {
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector normalizeVectorWithoutNaN(Vector vector) {
|
||||
private static Vector3D normalizeVectorWithoutNaN(Vector3D vector) {
|
||||
double var0 = vector.length();
|
||||
return var0 < 1.0E-4 ? new Vector() : vector.multiply(1 / var0);
|
||||
return var0 < 1.0E-4 ? newVector3D() : vector.multiply(1 / var0);
|
||||
}
|
||||
|
||||
public static boolean isEmpty(GrimPlayer player, int x, int y, int z) {
|
||||
|
||||
@@ -5,12 +5,14 @@ import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class JumpPower {
|
||||
public static void jumpFromGround(GrimPlayer player, Vector vector) {
|
||||
public static void jumpFromGround(GrimPlayer player, Vector3D vector) {
|
||||
float jumpPower = getJumpPower(player);
|
||||
|
||||
final OptionalInt jumpBoost = player.compensatedEntities.getPotionLevelForPlayer(PotionTypes.JUMP_BOOST);
|
||||
@@ -24,7 +26,7 @@ public class JumpPower {
|
||||
|
||||
if (player.isSprinting) {
|
||||
float radRotation = player.xRot * ((float) Math.PI / 180);
|
||||
vector.add(new Vector(-player.trigHandler.sin(radRotation) * 0.2, 0.0, player.trigHandler.cos(radRotation) * 0.2));
|
||||
vector.add(newVector3D(-player.trigHandler.sin(radRotation) * 0.2, 0.0, player.trigHandler.cos(radRotation) * 0.2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,30 +2,34 @@ package ac.grim.grimac.utils.nmsutil;
|
||||
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.data.Pair;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static java.lang.Math.toRadians;
|
||||
|
||||
// Copied directly from Hawk
|
||||
public class Ray implements Cloneable {
|
||||
|
||||
private Vector origin;
|
||||
private Vector direction;
|
||||
private Vector3D origin;
|
||||
private Vector3D direction;
|
||||
|
||||
public Ray(Vector origin, Vector direction) {
|
||||
public Ray(Vector3D origin, Vector3D direction) {
|
||||
this.origin = origin;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public Ray(GrimPlayer player, double x, double y, double z, float xRot, float yRot) {
|
||||
this.origin = new Vector(x, y, z);
|
||||
this.origin = newVector3D(x, y, z);
|
||||
this.direction = calculateDirection(player, xRot, yRot);
|
||||
}
|
||||
|
||||
// Account for FastMath by using player's trig handler
|
||||
// Copied from hawk which probably copied it from NMS
|
||||
public static Vector calculateDirection(GrimPlayer player, float xRot, float yRot) {
|
||||
Vector vector = new Vector();
|
||||
float rotX = (float) Math.toRadians(xRot);
|
||||
float rotY = (float) Math.toRadians(yRot);
|
||||
public static Vector3D calculateDirection(GrimPlayer player, float xRot, float yRot) {
|
||||
Vector3D vector = newVector3D();
|
||||
float rotX = (float) toRadians(xRot);
|
||||
float rotY = (float) toRadians(yRot);
|
||||
vector.setY(-player.trigHandler.sin(rotY));
|
||||
double xz = player.trigHandler.cos(rotY);
|
||||
vector.setX(-xz * player.trigHandler.sin(rotX));
|
||||
@@ -50,28 +54,28 @@ public class Ray implements Cloneable {
|
||||
return "origin: " + origin + " direction: " + direction;
|
||||
}
|
||||
|
||||
public Vector getPointAtDistance(double distance) {
|
||||
Vector dir = new Vector(direction.getX(), direction.getY(), direction.getZ());
|
||||
Vector orig = new Vector(origin.getX(), origin.getY(), origin.getZ());
|
||||
public Vector3D getPointAtDistance(double distance) {
|
||||
Vector3D dir = newVector3D(direction.getX(), direction.getY(), direction.getZ());
|
||||
Vector3D orig = newVector3D(origin.getX(), origin.getY(), origin.getZ());
|
||||
return orig.add(dir.multiply(distance));
|
||||
}
|
||||
|
||||
//https://en.wikipedia.org/wiki/Skew_lines#Nearest_Points
|
||||
public Pair<Vector, Vector> closestPointsBetweenLines(Ray other) {
|
||||
Vector n1 = direction.clone().crossProduct(other.direction.clone().crossProduct(direction));
|
||||
Vector n2 = other.direction.clone().crossProduct(direction.clone().crossProduct(other.direction));
|
||||
public Pair<Vector3D, Vector3D> closestPointsBetweenLines(Ray other) {
|
||||
Vector3D n1 = direction.clone().crossProduct(other.direction.clone().crossProduct(direction));
|
||||
Vector3D n2 = other.direction.clone().crossProduct(direction.clone().crossProduct(other.direction));
|
||||
|
||||
Vector c1 = origin.clone().add(direction.clone().multiply(other.origin.clone().subtract(origin).dot(n2) / direction.dot(n2)));
|
||||
Vector c2 = other.origin.clone().add(other.direction.clone().multiply(origin.clone().subtract(other.origin).dot(n1) / other.direction.dot(n1)));
|
||||
Vector3D c1 = origin.clone().add(direction.clone().multiply(other.origin.clone().subtract(origin).dot(n2) / direction.dot(n2)));
|
||||
Vector3D c2 = other.origin.clone().add(other.direction.clone().multiply(origin.clone().subtract(other.origin).dot(n1) / other.direction.dot(n1)));
|
||||
|
||||
return new Pair<>(c1, c2);
|
||||
}
|
||||
|
||||
public Vector getOrigin() {
|
||||
public Vector3D getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
public Vector calculateDirection() {
|
||||
public Vector3D calculateDirection() {
|
||||
return direction;
|
||||
}
|
||||
}
|
||||
@@ -5,19 +5,24 @@ import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import ac.grim.grimac.utils.data.Pair;
|
||||
import ac.grim.grimac.utils.math.VectorUtils;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static com.github.retrooper.packetevents.protocol.player.ClientVersion.V_1_12_2;
|
||||
import static java.lang.Math.PI;
|
||||
|
||||
public class ReachUtils {
|
||||
// Copied from 1.8... I couldn't figure out 1.14+. "Enterprise" java code is unreadable!
|
||||
public static Pair<Vector, BlockFace> calculateIntercept(SimpleCollisionBox self, Vector origin, Vector end) {
|
||||
Vector minX = getIntermediateWithXValue(origin, end, self.minX);
|
||||
Vector maxX = getIntermediateWithXValue(origin, end, self.maxX);
|
||||
Vector minY = getIntermediateWithYValue(origin, end, self.minY);
|
||||
Vector maxY = getIntermediateWithYValue(origin, end, self.maxY);
|
||||
Vector minZ = getIntermediateWithZValue(origin, end, self.minZ);
|
||||
Vector maxZ = getIntermediateWithZValue(origin, end, self.maxZ);
|
||||
public static Pair<Vector3D, BlockFace> calculateIntercept(SimpleCollisionBox self, Vector3D origin, Vector3D end) {
|
||||
Vector3D minX = getIntermediateWithXValue(origin, end, self.minX);
|
||||
Vector3D maxX = getIntermediateWithXValue(origin, end, self.maxX);
|
||||
Vector3D minY = getIntermediateWithYValue(origin, end, self.minY);
|
||||
Vector3D maxY = getIntermediateWithYValue(origin, end, self.maxY);
|
||||
Vector3D minZ = getIntermediateWithZValue(origin, end, self.minZ);
|
||||
Vector3D maxZ = getIntermediateWithZValue(origin, end, self.maxZ);
|
||||
|
||||
BlockFace bestFace = null;
|
||||
|
||||
@@ -45,7 +50,7 @@ public class ReachUtils {
|
||||
maxZ = null;
|
||||
}
|
||||
|
||||
Vector best = null;
|
||||
Vector3D best = null;
|
||||
|
||||
if (minX != null) {
|
||||
best = minX;
|
||||
@@ -84,7 +89,7 @@ public class ReachUtils {
|
||||
* Returns a new vector with x value equal to the second parameter, along the line between this vector and the
|
||||
* passed in vector, or null if not possible.
|
||||
*/
|
||||
public static Vector getIntermediateWithXValue(Vector self, Vector other, double x) {
|
||||
public static Vector3D getIntermediateWithXValue(Vector3D self, Vector3D other, double x) {
|
||||
double d0 = other.getX() - self.getX();
|
||||
double d1 = other.getY() - self.getY();
|
||||
double d2 = other.getZ() - self.getZ();
|
||||
@@ -93,7 +98,7 @@ public class ReachUtils {
|
||||
return null;
|
||||
} else {
|
||||
double d3 = (x - self.getX()) / d0;
|
||||
return d3 >= 0.0D && d3 <= 1.0D ? new Vector(self.getX() + d0 * d3, self.getY() + d1 * d3, self.getZ() + d2 * d3) : null;
|
||||
return d3 >= 0.0D && d3 <= 1.0D ? newVector3D(self.getX() + d0 * d3, self.getY() + d1 * d3, self.getZ() + d2 * d3) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +106,7 @@ public class ReachUtils {
|
||||
* Returns a new vector with y value equal to the second parameter, along the line between this vector and the
|
||||
* passed in vector, or null if not possible.
|
||||
*/
|
||||
public static Vector getIntermediateWithYValue(Vector self, Vector other, double y) {
|
||||
public static Vector3D getIntermediateWithYValue(Vector3D self, Vector3D other, double y) {
|
||||
double d0 = other.getX() - self.getX();
|
||||
double d1 = other.getY() - self.getY();
|
||||
double d2 = other.getZ() - self.getZ();
|
||||
@@ -110,7 +115,7 @@ public class ReachUtils {
|
||||
return null;
|
||||
} else {
|
||||
double d3 = (y - self.getY()) / d1;
|
||||
return d3 >= 0.0D && d3 <= 1.0D ? new Vector(self.getX() + d0 * d3, self.getY() + d1 * d3, self.getZ() + d2 * d3) : null;
|
||||
return d3 >= 0.0D && d3 <= 1.0D ? newVector3D(self.getX() + d0 * d3, self.getY() + d1 * d3, self.getZ() + d2 * d3) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +123,7 @@ public class ReachUtils {
|
||||
* Returns a new vector with z value equal to the second parameter, along the line between this vector and the
|
||||
* passed in vector, or null if not possible.
|
||||
*/
|
||||
public static Vector getIntermediateWithZValue(Vector self, Vector other, double z) {
|
||||
public static Vector3D getIntermediateWithZValue(Vector3D self, Vector3D other, double z) {
|
||||
double d0 = other.getX() - self.getX();
|
||||
double d1 = other.getY() - self.getY();
|
||||
double d2 = other.getZ() - self.getZ();
|
||||
@@ -127,51 +132,51 @@ public class ReachUtils {
|
||||
return null;
|
||||
} else {
|
||||
double d3 = (z - self.getZ()) / d2;
|
||||
return d3 >= 0.0D && d3 <= 1.0D ? new Vector(self.getX() + d0 * d3, self.getY() + d1 * d3, self.getZ() + d2 * d3) : null;
|
||||
return d3 >= 0.0D && d3 <= 1.0D ? newVector3D(self.getX() + d0 * d3, self.getY() + d1 * d3, self.getZ() + d2 * d3) : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified vector is within the YZ dimensions of the bounding box. Args: Vec3D
|
||||
*/
|
||||
private static boolean isVecInYZ(SimpleCollisionBox self, Vector vec) {
|
||||
private static boolean isVecInYZ(SimpleCollisionBox self, Vector3D vec) {
|
||||
return vec != null && vec.getY() >= self.minY && vec.getY() <= self.maxY && vec.getZ() >= self.minZ && vec.getZ() <= self.maxZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified vector is within the XZ dimensions of the bounding box. Args: Vec3D
|
||||
*/
|
||||
private static boolean isVecInXZ(SimpleCollisionBox self, Vector vec) {
|
||||
private static boolean isVecInXZ(SimpleCollisionBox self, Vector3D vec) {
|
||||
return vec != null && vec.getX() >= self.minX && vec.getX() <= self.maxX && vec.getZ() >= self.minZ && vec.getZ() <= self.maxZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified vector is within the XY dimensions of the bounding box. Args: Vec3D
|
||||
*/
|
||||
private static boolean isVecInXY(SimpleCollisionBox self, Vector vec) {
|
||||
private static boolean isVecInXY(SimpleCollisionBox self, Vector3D vec) {
|
||||
return vec != null && vec.getX() >= self.minX && vec.getX() <= self.maxX && vec.getY() >= self.minY && vec.getY() <= self.maxY;
|
||||
}
|
||||
|
||||
// Look vector accounting for optifine FastMath, and client version differences
|
||||
public static Vector getLook(GrimPlayer player, float yaw, float pitch) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_12_2)) {
|
||||
float f = player.trigHandler.cos(-yaw * 0.017453292F - (float)Math.PI);
|
||||
float f1 = player.trigHandler.sin(-yaw * 0.017453292F - (float)Math.PI);
|
||||
public static Vector3D getLook(GrimPlayer player, float yaw, float pitch) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(V_1_12_2)) {
|
||||
float f = player.trigHandler.cos(-yaw * 0.017453292F - (float) PI);
|
||||
float f1 = player.trigHandler.sin(-yaw * 0.017453292F - (float) PI);
|
||||
float f2 = -player.trigHandler.cos(-pitch * 0.017453292F);
|
||||
float f3 = player.trigHandler.sin(-pitch * 0.017453292F);
|
||||
return new Vector(f1 * f2, f3, f * f2);
|
||||
return newVector3D(f1 * f2, f3, f * f2);
|
||||
} else {
|
||||
float f = pitch * ((float) Math.PI / 180F);
|
||||
float f1 = -yaw * ((float) Math.PI / 180F);
|
||||
float f = pitch * ((float) PI / 180F);
|
||||
float f1 = -yaw * ((float) PI / 180F);
|
||||
float f2 = player.trigHandler.cos(f1);
|
||||
float f3 = player.trigHandler.sin(f1);
|
||||
float f4 = player.trigHandler.cos(f);
|
||||
float f5 = player.trigHandler.sin(f);
|
||||
return new Vector(f3 * f4, -f5, (double) (f2 * f4));
|
||||
return newVector3D(f3 * f4, -f5, (double) (f2 * f4));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isVecInside(SimpleCollisionBox self, Vector vec) {
|
||||
public static boolean isVecInside(SimpleCollisionBox self, Vector3D vec) {
|
||||
return vec.getX() > self.minX && vec.getX() < self.maxX && (vec.getY() > self.minY && vec.getY() < self.maxY && vec.getZ() > self.minZ && vec.getZ() < self.maxZ);
|
||||
}
|
||||
|
||||
@@ -184,8 +189,8 @@ public class ReachUtils {
|
||||
if (giveMovementThresholdLenience) targetBox.expand(player.getMovementThreshold());
|
||||
final double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
for (double eyes : possibleEyeHeights) {
|
||||
Vector from = new Vector(player.x, player.y + eyes, player.z);
|
||||
Vector closestPoint = VectorUtils.cutBoxToVector(from, targetBox);
|
||||
Vector3D from = newVector3D(player.x, player.y + eyes, player.z);
|
||||
Vector3D closestPoint = VectorUtils.cutBoxToVector(from, targetBox);
|
||||
lowest = Math.min(lowest, closestPoint.distance(from));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,32 +1,37 @@
|
||||
package ac.grim.grimac.utils.nmsutil;
|
||||
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import org.bukkit.util.Vector;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import static com.github.retrooper.packetevents.PacketEvents.getAPI;
|
||||
import static com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes.RIPTIDE;
|
||||
import static com.github.retrooper.packetevents.protocol.item.type.ItemTypes.TRIDENT;
|
||||
import static java.lang.Math.PI;
|
||||
import static java.lang.Math.sqrt;
|
||||
|
||||
public class Riptide {
|
||||
public static Vector getRiptideVelocity(GrimPlayer player) {
|
||||
public static Vector3D getRiptideVelocity(GrimPlayer player) {
|
||||
ItemStack main = player.getInventory().getHeldItem();
|
||||
ItemStack off = player.getInventory().getOffHand();
|
||||
|
||||
int j;
|
||||
if (main.getType() == ItemTypes.TRIDENT) {
|
||||
j = main.getEnchantmentLevel(EnchantmentTypes.RIPTIDE, PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
||||
} else if (off.getType() == ItemTypes.TRIDENT) {
|
||||
j = off.getEnchantmentLevel(EnchantmentTypes.RIPTIDE, PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
||||
if (main.getType() == TRIDENT) {
|
||||
j = main.getEnchantmentLevel(RIPTIDE, getAPI().getServerManager().getVersion().toClientVersion());
|
||||
} else if (off.getType() == TRIDENT) {
|
||||
j = off.getEnchantmentLevel(RIPTIDE, getAPI().getServerManager().getVersion().toClientVersion());
|
||||
} else {
|
||||
return new Vector(); // Can't riptide
|
||||
return newVector3D(); // Can't riptide
|
||||
}
|
||||
|
||||
float f7 = player.xRot;
|
||||
float f = player.yRot;
|
||||
float f1 = -player.trigHandler.sin(f7 * ((float) Math.PI / 180F)) * player.trigHandler.cos(f * ((float) Math.PI / 180F));
|
||||
float f2 = -player.trigHandler.sin(f * ((float) Math.PI / 180F));
|
||||
float f3 = player.trigHandler.cos(f7 * ((float) Math.PI / 180F)) * player.trigHandler.cos(f * ((float) Math.PI / 180F));
|
||||
float f4 = (float) Math.sqrt(f1 * f1 + f2 * f2 + f3 * f3);
|
||||
float f1 = -player.trigHandler.sin(f7 * ((float) PI / 180F)) * player.trigHandler.cos(f * ((float) PI / 180F));
|
||||
float f2 = -player.trigHandler.sin(f * ((float) PI / 180F));
|
||||
float f3 = player.trigHandler.cos(f7 * ((float) PI / 180F)) * player.trigHandler.cos(f * ((float) PI / 180F));
|
||||
float f4 = (float) sqrt(f1 * f1 + f2 * f2 + f3 * f3);
|
||||
float f5 = 3.0F * ((1.0F + j) / 4.0F);
|
||||
f1 = f1 * (f5 / f4);
|
||||
f2 = f2 * (f5 / f4);
|
||||
@@ -34,8 +39,8 @@ public class Riptide {
|
||||
|
||||
// If the player collided vertically with the 1.199999F pushing movement, then the Y additional movement was added
|
||||
// (We switched the order around as our prediction engine isn't designed for the proper implementation)
|
||||
if (player.verticalCollision) return new Vector(f1, 0, f3);
|
||||
if (player.verticalCollision) return newVector3D(f1, 0, f3);
|
||||
|
||||
return new Vector(f1, f2, f3);
|
||||
return newVector3D(f1, f2, f3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package ac.grim.grimac.utils.vector;
|
||||
|
||||
public class BasicVectorOps implements VectorOperations {
|
||||
|
||||
@Override
|
||||
public Vector3D newVector(double x, double y, double z) {
|
||||
return new ScalarVector3D(x, y, z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package ac.grim.grimac.utils.vector;
|
||||
|
||||
import one.nalim.Library;
|
||||
import one.nalim.Link;
|
||||
import one.nalim.Linker;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Library("vector_ops")
|
||||
public class NalimVector3D implements Vector3D {
|
||||
|
||||
static {
|
||||
Linker.linkClass(NalimVector3D.class);
|
||||
}
|
||||
|
||||
double[] loc;
|
||||
|
||||
// public final long nativePtr; // Holds pointer to SimdVector
|
||||
// @Link(name = "create_vector")
|
||||
// private static native long create_vector(double x, double y, double z);
|
||||
|
||||
public NalimVector3D(double x, double y, double z) {
|
||||
loc = new double[]{x, y, z};
|
||||
// nativePtr = create_vector(0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return loc[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return loc[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getZ() {
|
||||
return loc[2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D setX(double x) {
|
||||
loc[0] = x;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector3D setY(double y) {
|
||||
loc[1] =y;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D setZ(double z) {
|
||||
loc[2] = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double length() {
|
||||
return Math.sqrt(loc[0] * loc[0] + loc[1] * loc[1] + loc[2] * loc[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double lengthSquared() {
|
||||
return loc[0] * loc[0] + loc[1] * loc[1] + loc[2] * loc[2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Vector3D multiply(double m) {
|
||||
loc[0] *= m;
|
||||
loc[1] *= m;
|
||||
loc[2] *= m;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Vector3D normalize() {
|
||||
double length = this.length();
|
||||
loc[0] /= length;
|
||||
loc[1] /= length;
|
||||
loc[2] /= length;
|
||||
return this;
|
||||
}
|
||||
|
||||
// @Link(name = "delete_vector2")
|
||||
// private static native void delete_vector(long[] x);
|
||||
|
||||
@IntrinsicCandidate @ForceInline @Link(name = "cross_product2")
|
||||
private static native void crossProduct(double[] a, double[] b);
|
||||
|
||||
@IntrinsicCandidate @ForceInline @Link(name = "cross_product")
|
||||
private static native void cross_product(long a, long b);
|
||||
|
||||
@Override
|
||||
public @NotNull Vector3D crossProduct(@NotNull Vector3D o) {
|
||||
// cross_product(nativePtr, ((NalimVector3D) o).nativePtr);
|
||||
crossProduct(this.loc, ((NalimVector3D) o).loc);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector3D add(@NotNull Vector3D vec) {
|
||||
loc[0] += vec.getX();
|
||||
loc[1] += vec.getY();
|
||||
loc[2] += vec.getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector3D subtract(@NotNull Vector3D vec) {
|
||||
loc[0] -= vec.getX();
|
||||
loc[1] -= vec.getY();
|
||||
loc[2] -= vec.getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector3D multiply(@NotNull Vector3D vec) {
|
||||
loc[0] *= vec.getX();
|
||||
loc[1] *= vec.getY();
|
||||
loc[2] *= vec.getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double distance(@NotNull Vector3D o) {
|
||||
return Math.sqrt(distanceSquared(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double distanceSquared(@NotNull Vector3D o) {
|
||||
return (loc[0] - o.getX()) * (loc[0] - o.getX())
|
||||
+ (loc[1] - o.getY()) * (loc[1] - o.getY())
|
||||
+ (loc[2] - o.getZ()) * (loc[2] - o.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double dot(@NotNull Vector3D other) {
|
||||
return loc[0] * other.getX() + loc[1] * other.getY() + loc[2] * other.getZ();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector3D clone() {
|
||||
try {
|
||||
return (Vector3D) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package ac.grim.grimac.utils.vector;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ScalarVector3D implements Vector3D {
|
||||
|
||||
double x, y ,z;
|
||||
|
||||
public ScalarVector3D(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D setX(double x) {
|
||||
this.x = x;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector3D setY(double y) {
|
||||
this.y =y;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D setZ(double z) {
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double length() {
|
||||
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double lengthSquared() {
|
||||
return this.x * this.x + this.y * this.y + this.z * this.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Vector3D multiply(double m) {
|
||||
this.x *= m;
|
||||
this.y *= m;
|
||||
this.z *= m;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Vector3D normalize() {
|
||||
double length = this.length();
|
||||
this.x /= length;
|
||||
this.y /= length;
|
||||
this.z /= length;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Vector3D crossProduct(@NotNull Vector3D o) {
|
||||
double newX = this.y * o.getZ() - o.getY() * this.z;
|
||||
double newY = this.z * o.getX() - o.getZ() * this.x;
|
||||
double newZ = this.x * o.getY() - o.getX() * this.y;
|
||||
this.x = newX;
|
||||
this.y = newY;
|
||||
this.z = newZ;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector3D add(@NotNull Vector3D vec) {
|
||||
this.x += vec.getX();
|
||||
this.y += vec.getY();
|
||||
this.z += vec.getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector3D subtract(@NotNull Vector3D vec) {
|
||||
this.x -= vec.getX();
|
||||
this.y -= vec.getY();
|
||||
this.z -= vec.getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector3D multiply(@NotNull Vector3D vec) {
|
||||
this.x *= vec.getX();
|
||||
this.y *= vec.getY();
|
||||
this.z *= vec.getZ();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double distance(@NotNull Vector3D o) {
|
||||
return Math.sqrt(distanceSquared(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double distanceSquared(@NotNull Vector3D o) {
|
||||
return (this.x - o.getX()) * (this.x - o.getX())
|
||||
+ (this.y - o.getY()) * (this.y - o.getY())
|
||||
+ (this.z - o.getZ()) * (this.z - o.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double dot(@NotNull Vector3D other) {
|
||||
return this.x * other.getX() + this.y * other.getY() + this.z * other.getZ();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Vector3D clone() {
|
||||
try {
|
||||
return (Vector3D) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package ac.grim.grimac.utils.vector;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface Vector3D extends Cloneable {
|
||||
double getX();
|
||||
double getY();
|
||||
double getZ();
|
||||
|
||||
Vector3D setX(double x);
|
||||
Vector3D setY(double y);
|
||||
Vector3D setZ(double z);
|
||||
|
||||
double length();
|
||||
double lengthSquared();
|
||||
|
||||
@NotNull Vector3D multiply(double m);
|
||||
@NotNull Vector3D normalize();
|
||||
@NotNull Vector3D crossProduct(@NotNull Vector3D o);
|
||||
@NotNull Vector3D add(@NotNull Vector3D o);
|
||||
@NotNull Vector3D subtract(@NotNull Vector3D o);
|
||||
@NotNull Vector3D multiply(@NotNull Vector3D o);
|
||||
double distance(@NotNull Vector3D o);
|
||||
double distanceSquared(@NotNull Vector3D o);
|
||||
double dot(@NotNull Vector3D o);
|
||||
|
||||
@NotNull Vector3D clone();
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package ac.grim.grimac.utils.vector;
|
||||
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
// Factory that loads once at startup
|
||||
public final class VectorFactory {
|
||||
public static final VectorOperations INSTANCE;
|
||||
|
||||
static {
|
||||
// This happens once during class initialization
|
||||
VectorOperations ops;
|
||||
try {
|
||||
if (isSimdApiAvailable()) {
|
||||
ops = (VectorOperations) Class
|
||||
.forName("ac.grim.grimac.utils.vector.VectorOperationsJava18")
|
||||
.getDeclaredConstructor()
|
||||
.newInstance();
|
||||
} else {
|
||||
LogUtil.info("java.lang.vector.VectorSpecies not found. SIMD is unavailable falling back to Scalar Operations.");
|
||||
ops = new BasicVectorOps();
|
||||
}
|
||||
} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | InstantiationException |
|
||||
IllegalAccessException e) {
|
||||
LogUtil.error("SIMD is unavailable falling back to Scalar Operations: " + e.getMessage());
|
||||
ops = new BasicVectorOps();
|
||||
}
|
||||
INSTANCE = ops;
|
||||
}
|
||||
|
||||
public static Vector3D newVector3D() {
|
||||
return INSTANCE.newVector(0 ,0, 0);
|
||||
}
|
||||
|
||||
public static Vector3D newVector3D(int x, int y, int z) {
|
||||
return INSTANCE.newVector(x, y, z);
|
||||
}
|
||||
|
||||
public static Vector3D newVector3D(float x, float y, float z) {
|
||||
return INSTANCE.newVector(x, y, z);
|
||||
}
|
||||
|
||||
public static Vector3D newVector3D(double x, double y, double z) {
|
||||
return INSTANCE.newVector(x, y, z);
|
||||
}
|
||||
|
||||
private static boolean isSimdApiAvailable() {
|
||||
int javaVersion = getJavaVersion();
|
||||
if (javaVersion >= 18) {
|
||||
try {
|
||||
// Attempt to load a class that uses the Vector API
|
||||
Class.forName("java.lang.vector.VectorSpecies");
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Vector API not available
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int getJavaVersion() {
|
||||
String versionString = System.getProperty("java.version");
|
||||
if (versionString.startsWith("1.")) {
|
||||
versionString = versionString.substring(2, 3);
|
||||
} else {
|
||||
int dotIndex = versionString.indexOf(".");
|
||||
if (dotIndex != -1) {
|
||||
versionString = versionString.substring(0, dotIndex);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(versionString);
|
||||
} catch (NumberFormatException e) {
|
||||
// Fallback to assuming Java 8 if parsing fails
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package ac.grim.grimac.utils.vector;
|
||||
|
||||
public interface VectorOperations {
|
||||
|
||||
Vector3D newVector(double x, double y, double z);
|
||||
}
|
||||
Reference in new issue
Block a user