mirror of
https://github.com/funkemunky/KauriV3.git
synced 2026-05-31 05:51:55 +00:00
Merge main: apply array-based chunk storage to World.java, resolve BlockUpdateHandler conflict
Co-authored-by: funkemunky <30784509+funkemunky@users.noreply.github.com>
This commit is contained in:
+5
-5
@@ -19,6 +19,10 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>maven-central</id>
|
||||||
|
<url>https://nexus.funkemunky.cc/repository/maven-central/</url>
|
||||||
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>viaversion-repo</id>
|
<id>viaversion-repo</id>
|
||||||
<url>https://repo.viaversion.com</url>
|
<url>https://repo.viaversion.com</url>
|
||||||
@@ -27,10 +31,6 @@
|
|||||||
<id>spigot-repo</id>
|
<id>spigot-repo</id>
|
||||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
|
||||||
<id>evokegames</id>
|
|
||||||
<url>https://maven.evokegames.gg/snapshots</url>
|
|
||||||
</repository>
|
|
||||||
<repository>
|
<repository>
|
||||||
<id>aikar</id>
|
<id>aikar</id>
|
||||||
<url>https://repo.aikar.co/content/groups/aikar/</url>
|
<url>https://repo.aikar.co/content/groups/aikar/</url>
|
||||||
@@ -267,7 +267,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.retrooper</groupId>
|
<groupId>com.github.retrooper</groupId>
|
||||||
<artifactId>packetevents-spigot</artifactId>
|
<artifactId>packetevents-spigot</artifactId>
|
||||||
<version>2.9.4</version>
|
<version>2.11.1</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import dev.brighten.ac.handler.PacketHandler;
|
|||||||
import dev.brighten.ac.handler.entity.FakeEntityTracker;
|
import dev.brighten.ac.handler.entity.FakeEntityTracker;
|
||||||
import dev.brighten.ac.handler.keepalive.KeepaliveProcessor;
|
import dev.brighten.ac.handler.keepalive.KeepaliveProcessor;
|
||||||
import dev.brighten.ac.handler.keepalive.actions.ActionManager;
|
import dev.brighten.ac.handler.keepalive.actions.ActionManager;
|
||||||
|
import dev.brighten.ac.handler.protocol.Protocol;
|
||||||
|
import dev.brighten.ac.handler.protocol.impl.NoAPI;
|
||||||
import dev.brighten.ac.logging.LoggerManager;
|
import dev.brighten.ac.logging.LoggerManager;
|
||||||
import dev.brighten.ac.utils.*;
|
import dev.brighten.ac.utils.*;
|
||||||
import dev.brighten.ac.utils.annotation.ConfigSetting;
|
import dev.brighten.ac.utils.annotation.ConfigSetting;
|
||||||
@@ -30,6 +32,7 @@ import dev.brighten.ac.utils.timer.impl.TickTimer;
|
|||||||
import dev.brighten.ac.utils.world.WorldInfo;
|
import dev.brighten.ac.utils.world.WorldInfo;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.experimental.PackagePrivate;
|
import lombok.experimental.PackagePrivate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@@ -116,6 +119,9 @@ public class Anticheat extends JavaPlugin {
|
|||||||
private final RollingAverageDouble tps = new RollingAverageDouble(4, 20);
|
private final RollingAverageDouble tps = new RollingAverageDouble(4, 20);
|
||||||
private final Map<UUID, WorldInfo> worldInfoMap = new HashMap<>();
|
private final Map<UUID, WorldInfo> worldInfoMap = new HashMap<>();
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private Protocol protocol = new NoAPI();
|
||||||
|
|
||||||
private final List<BaseCommand> commands = new ArrayList<>();
|
private final List<BaseCommand> commands = new ArrayList<>();
|
||||||
|
|
||||||
public static boolean allowDebug = true;
|
public static boolean allowDebug = true;
|
||||||
@@ -252,7 +258,7 @@ public class Anticheat extends JavaPlugin {
|
|||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
Anticheat.INSTANCE.getLogger().log(Level.SEVERE, "Check ID unregister failed", e);
|
Anticheat.INSTANCE.getLogger().log(Level.SEVERE, "Check ID unregister failed", e);
|
||||||
}
|
}
|
||||||
commandManager.getScheduler().cancelLocaleTask();
|
|
||||||
commandPropertiesManager = null;
|
commandPropertiesManager = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -23,5 +23,5 @@ public @interface CheckData {
|
|||||||
int punishVl() default 10;
|
int punishVl() default 10;
|
||||||
|
|
||||||
ClientVersion minVersion() default ClientVersion.V_1_8;
|
ClientVersion minVersion() default ClientVersion.V_1_8;
|
||||||
ClientVersion maxVersion() default ClientVersion.V_1_21_7;
|
ClientVersion maxVersion() default ClientVersion.V_1_21_11;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
|||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
|
import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
|
||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||||
import dev.brighten.ac.Anticheat;
|
import dev.brighten.ac.Anticheat;
|
||||||
@@ -19,7 +20,6 @@ import dev.brighten.ac.utils.timer.Timer;
|
|||||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||||
import dev.brighten.ac.utils.world.EntityData;
|
import dev.brighten.ac.utils.world.EntityData;
|
||||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
@@ -46,7 +46,7 @@ public class Hitbox extends Check {
|
|||||||
if(packet.getAction() != WrapperPlayClientInteractEntity.InteractAction.ATTACK)
|
if(packet.getAction() != WrapperPlayClientInteractEntity.InteractAction.ATTACK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Optional<TrackedEntity> entity = player.getEntityLocationHandler().getTrackedEntity(packet.getEntityId());
|
Optional<TrackedEntity> entity = player.getWorldTracker().getCurrentWorld().get().getTrackedEntity(packet.getEntityId());
|
||||||
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
||||||
|
|
||||||
attacks.add(new Tuple<>(entity.get(),
|
attacks.add(new Tuple<>(entity.get(),
|
||||||
@@ -118,7 +118,7 @@ public class Hitbox extends Check {
|
|||||||
boolean didSneakOrElytra = player.getInfo().getLastSneak().isNotPassed(40)
|
boolean didSneakOrElytra = player.getInfo().getLastSneak().isNotPassed(40)
|
||||||
|| player.getInfo().getLastElytra().isNotPassed(40);
|
|| player.getInfo().getLastElytra().isNotPassed(40);
|
||||||
|
|
||||||
List<Vector> directions = new ArrayList<>(Arrays.asList(MathUtils.getDirection(
|
List<Vector3d> directions = new ArrayList<>(Arrays.asList(MathUtils.getDirection(
|
||||||
player.getMovement().getTo().getLoc().getYaw(),
|
player.getMovement().getTo().getLoc().getYaw(),
|
||||||
player.getMovement().getTo().getLoc().getPitch()),
|
player.getMovement().getTo().getLoc().getPitch()),
|
||||||
MathUtils.getDirection(player.getMovement().getFrom().getLoc().getYaw(),
|
MathUtils.getDirection(player.getMovement().getFrom().getLoc().getYaw(),
|
||||||
@@ -126,7 +126,7 @@ public class Hitbox extends Check {
|
|||||||
|
|
||||||
if(!didSneakOrElytra) {
|
if(!didSneakOrElytra) {
|
||||||
to.add(0, 1.62f, 0);
|
to.add(0, 1.62f, 0);
|
||||||
for (Vector direction : directions) {
|
for (Vector3d direction : directions) {
|
||||||
for (SimpleCollisionBox targetBox : boxes) {
|
for (SimpleCollisionBox targetBox : boxes) {
|
||||||
final AxisAlignedBB vanillaBox = new AxisAlignedBB(targetBox);
|
final AxisAlignedBB vanillaBox = new AxisAlignedBB(targetBox);
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ public class Hitbox extends Check {
|
|||||||
}
|
}
|
||||||
//Checking all possible eyeheights since client actions notoriously desync from the server side
|
//Checking all possible eyeheights since client actions notoriously desync from the server side
|
||||||
} else {
|
} else {
|
||||||
for (Vector direction : directions) {
|
for (Vector3d direction : directions) {
|
||||||
for (double eyeHeight : player.getMovement().getEyeHeights()) {
|
for (double eyeHeight : player.getMovement().getEyeHeights()) {
|
||||||
for (SimpleCollisionBox targetBox : boxes) {
|
for (SimpleCollisionBox targetBox : boxes) {
|
||||||
final AxisAlignedBB vanillaBox = new AxisAlignedBB(targetBox);
|
final AxisAlignedBB vanillaBox = new AxisAlignedBB(targetBox);
|
||||||
@@ -180,7 +180,7 @@ public class Hitbox extends Check {
|
|||||||
|
|
||||||
debug("buffer: %.3f distance=%.2f hits=%s sneaking=%s", buffer, distance, hits,
|
debug("buffer: %.3f distance=%.2f hits=%s sneaking=%s", buffer, distance, hits,
|
||||||
player.getInfo().isSneaking());
|
player.getInfo().isSneaking());
|
||||||
} else if(player.getEntityLocationHandler().streak > 1) {
|
} else if(player.getEntityTrackHandler().streak > 1) {
|
||||||
if (++hbuffer > 5) {
|
if (++hbuffer > 5) {
|
||||||
flag("%.1f;%.1f;%.1f", entity.getNewEntityLocation().x, entity.getNewEntityLocation().y, entity.getNewEntityLocation().z);
|
flag("%.1f;%.1f;%.1f", entity.getNewEntityLocation().x, entity.getNewEntityLocation().y, entity.getNewEntityLocation().z);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package dev.brighten.ac.check.impl.combat.killaura;
|
package dev.brighten.ac.check.impl.combat.killaura;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientAnimation;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientAnimation;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||||
import dev.brighten.ac.api.check.CheckType;
|
import dev.brighten.ac.api.check.CheckType;
|
||||||
@@ -29,10 +28,10 @@ public class KABot extends Check {
|
|||||||
|
|
||||||
@Bind
|
@Bind
|
||||||
WAction<WrapperPlayClientInteractEntity> packet = packet -> {
|
WAction<WrapperPlayClientInteractEntity> packet = packet -> {
|
||||||
val optional = player.getEntityLocationHandler().getTrackedEntity(packet.getEntityId());
|
val optional = player.getWorldTracker().getCurrentWorld().get().getTrackedEntity(packet.getEntityId());
|
||||||
|
|
||||||
if(optional.isPresent()
|
if(optional.isPresent()
|
||||||
&& (player.getEntityLocationHandler().clientHasEntity.get()
|
&& (player.getEntityTrackHandler().clientHasEntity.get()
|
||||||
|| !optional.get().getFakeMobs().isEmpty())) {
|
|| !optional.get().getFakeMobs().isEmpty())) {
|
||||||
if(++buffer > 3) {
|
if(++buffer > 3) {
|
||||||
flag("Attacked player without attacking bot!");
|
flag("Attacked player without attacking bot!");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package dev.brighten.ac.check.impl.combat.killaura;
|
package dev.brighten.ac.check.impl.combat.killaura;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||||
import dev.brighten.ac.api.check.CheckType;
|
import dev.brighten.ac.api.check.CheckType;
|
||||||
import dev.brighten.ac.check.Check;
|
import dev.brighten.ac.check.Check;
|
||||||
@@ -13,7 +13,6 @@ import dev.brighten.ac.utils.world.CollisionBox;
|
|||||||
import dev.brighten.ac.utils.world.EntityData;
|
import dev.brighten.ac.utils.world.EntityData;
|
||||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author funkemunky
|
* @author funkemunky
|
||||||
@@ -43,14 +42,13 @@ public class KATrace extends Check {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var trackedEntity = player.getEntityLocationHandler().getTrackedEntity(player.getInfo().getTarget().getEntityId());
|
var trackedEntity = player.getWorldTracker().getCurrentWorld().get().getTrackedEntity(player.getInfo().getTarget().getEntityId());
|
||||||
|
|
||||||
if(trackedEntity.isEmpty()) {
|
if(trackedEntity.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Getting the target's bounding box
|
// Getting the target's bounding box
|
||||||
SimpleCollisionBox targetBox = (SimpleCollisionBox) EntityData.getEntityBox(player.getInfo().getTarget()
|
SimpleCollisionBox targetBox = (SimpleCollisionBox) EntityData.getEntityBox(player.getInfo().getTarget().getLocation(), trackedEntity.get());
|
||||||
.getLocation(), trackedEntity.get());
|
|
||||||
|
|
||||||
if(targetBox == null) return;
|
if(targetBox == null) return;
|
||||||
|
|
||||||
@@ -59,12 +57,12 @@ public class KATrace extends Check {
|
|||||||
// Setting the player's eye height based on their sneak status
|
// Setting the player's eye height based on their sneak status
|
||||||
origin.add(0, player.getEyeHeight(), 0);
|
origin.add(0, player.getEyeHeight(), 0);
|
||||||
|
|
||||||
final Vector originVec = origin.toVector();
|
final Vector3d originVec = origin.toVector();
|
||||||
|
|
||||||
// Setting a trace based on their view direction
|
// Setting a trace based on their view direction
|
||||||
RayCollision collision = new RayCollision(originVec, origin.getDirection());
|
RayCollision collision = new RayCollision(originVec, origin.getDirection());
|
||||||
|
|
||||||
Vector targetPoint = collision.collisionPoint(targetBox);
|
Vector3d targetPoint = collision.collisionPoint(targetBox);
|
||||||
//If the ray isn't collided, we might as well not run this check. Just a simple boxes on array check
|
//If the ray isn't collided, we might as well not run this check. Just a simple boxes on array check
|
||||||
if(targetPoint == null) return;
|
if(targetPoint == null) return;
|
||||||
|
|
||||||
@@ -84,7 +82,7 @@ public class KATrace extends Check {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// We want to shrink the box slightly since there is a bit of a margin of error in the ray trace.
|
// We want to shrink the box slightly since there is a bit of a margin of error in the ray trace.
|
||||||
Vector point = collision.collisionPoint(box.copy().shrink(0.005f, 0.005f, 0.005f));
|
Vector3d point = collision.collisionPoint(box.copy().shrink(0.005f, 0.005f, 0.005f));
|
||||||
|
|
||||||
if (point != null && originVec.distanceSquared(point) < dist - 0.2) {
|
if (point != null && originVec.distanceSquared(point) < dist - 0.2) {
|
||||||
rayCollidedOnBlock = true;
|
rayCollidedOnBlock = true;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class KACalc extends KListener {
|
|||||||
@Bind
|
@Bind
|
||||||
WAction<WrapperPlayClientPlayerFlying> flying = packet -> {
|
WAction<WrapperPlayClientPlayerFlying> flying = packet -> {
|
||||||
if(player.getInfo().getTarget() == null || player.getInfo().lastAttack.isPassed(40)) return;
|
if(player.getInfo().getTarget() == null || player.getInfo().lastAttack.isPassed(40)) return;
|
||||||
Optional<TrackedEntity> optional = player.getEntityLocationHandler()
|
Optional<TrackedEntity> optional = player.getWorldTracker().getCurrentWorld().get()
|
||||||
.getTrackedEntity(player.getInfo().getTarget().getEntityId());
|
.getTrackedEntity(player.getInfo().getTarget().getEntityId());
|
||||||
|
|
||||||
if(optional.isEmpty()) return;
|
if(optional.isEmpty()) return;
|
||||||
@@ -46,7 +46,7 @@ public class KACalc extends KListener {
|
|||||||
KLocation originKLoc = player.getMovement().getTo().getLoc().clone()
|
KLocation originKLoc = player.getMovement().getTo().getLoc().clone()
|
||||||
.add(0, player.getInfo().isSneaking() ? 1.54f : 1.62f, 0);
|
.add(0, player.getInfo().isSneaking() ? 1.54f : 1.62f, 0);
|
||||||
|
|
||||||
double halfHeight = player.getInfo().getTarget().getEyeHeight() / 2;
|
double halfHeight = player.getInfo().getTarget().getPose().eyeHeight / 2;
|
||||||
KLocation targetLocation = new KLocation(current.getX(), current.getY(), current.getZ());
|
KLocation targetLocation = new KLocation(current.getX(), current.getY(), current.getZ());
|
||||||
var rotations = MathUtils
|
var rotations = MathUtils
|
||||||
.getRotation(originKLoc, targetLocation.clone().add(0, halfHeight, 0));
|
.getRotation(originKLoc, targetLocation.clone().add(0, halfHeight, 0));
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dev.brighten.ac.check.impl.movement;
|
package dev.brighten.ac.check.impl.movement;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.teleport.RelativeFlag;
|
import com.github.retrooper.packetevents.protocol.teleport.RelativeFlag;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerPositionAndLook;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerPositionAndLook;
|
||||||
import dev.brighten.ac.Anticheat;
|
import dev.brighten.ac.Anticheat;
|
||||||
@@ -18,7 +19,6 @@ import dev.brighten.ac.utils.annotation.Bind;
|
|||||||
import dev.brighten.ac.utils.objects.evicting.EvictingSet;
|
import dev.brighten.ac.utils.objects.evicting.EvictingSet;
|
||||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -31,7 +31,7 @@ public class Phase extends Check {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int ticks;
|
private int ticks;
|
||||||
private final Set<Vector> POSITIONS = new EvictingSet<>(10);
|
private final Set<Vector3d> POSITIONS = new EvictingSet<>(10);
|
||||||
private Location teleportLoc = null;
|
private Location teleportLoc = null;
|
||||||
|
|
||||||
@Bind
|
@Bind
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dev.brighten.ac.check.impl.movement.speed;
|
package dev.brighten.ac.check.impl.movement.speed;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||||
|
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||||
import dev.brighten.ac.api.check.CheckType;
|
import dev.brighten.ac.api.check.CheckType;
|
||||||
import dev.brighten.ac.check.Check;
|
import dev.brighten.ac.check.Check;
|
||||||
@@ -36,11 +37,11 @@ public class Speed extends Check {
|
|||||||
|
|
||||||
moveFactor+= (float) (moveFactor * 0.30000001192092896D);
|
moveFactor+= (float) (moveFactor * 0.30000001192092896D);
|
||||||
|
|
||||||
if(player.getPotionHandler().hasPotionEffect(PotionEffectType.SPEED))
|
if(player.getPotionHandler().hasPotionEffect(PotionTypes.SPEED))
|
||||||
moveFactor += (float) ((PlayerUtils.getPotionEffectLevel(player.getBukkitPlayer(), PotionEffectType.SPEED)
|
moveFactor += (float) ((PlayerUtils.getPotionEffectLevel(player.getBukkitPlayer(), PotionEffectType.SPEED)
|
||||||
* (0.200000000298023224D)) * moveFactor);
|
* (0.200000000298023224D)) * moveFactor);
|
||||||
|
|
||||||
if(player.getPotionHandler().hasPotionEffect(PotionEffectType.SLOW))
|
if(player.getPotionHandler().hasPotionEffect(PotionTypes.SLOWNESS))
|
||||||
moveFactor += (float) ((PlayerUtils.getPotionEffectLevel(player.getBukkitPlayer(), PotionEffectType.SLOW)
|
moveFactor += (float) ((PlayerUtils.getPotionEffectLevel(player.getBukkitPlayer(), PotionEffectType.SLOW)
|
||||||
* (-0.15000000596046448D)) * moveFactor);
|
* (-0.15000000596046448D)) * moveFactor);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package dev.brighten.ac.check.impl.movement.velocity;
|
package dev.brighten.ac.check.impl.movement.velocity;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||||
|
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||||
import dev.brighten.ac.api.check.CheckType;
|
import dev.brighten.ac.api.check.CheckType;
|
||||||
import dev.brighten.ac.check.Check;
|
import dev.brighten.ac.check.Check;
|
||||||
@@ -12,12 +14,10 @@ import dev.brighten.ac.utils.BlockUtils;
|
|||||||
import dev.brighten.ac.utils.KLocation;
|
import dev.brighten.ac.utils.KLocation;
|
||||||
import dev.brighten.ac.utils.MathUtils;
|
import dev.brighten.ac.utils.MathUtils;
|
||||||
import dev.brighten.ac.utils.annotation.Bind;
|
import dev.brighten.ac.utils.annotation.Bind;
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
|
||||||
import dev.brighten.ac.utils.timer.Timer;
|
import dev.brighten.ac.utils.timer.Timer;
|
||||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import me.hydro.emulator.util.mcp.MathHelper;
|
import me.hydro.emulator.util.mcp.MathHelper;
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -61,8 +61,8 @@ public class VelocityB extends Check {
|
|||||||
val underBlockLoc = previousFrom != null
|
val underBlockLoc = previousFrom != null
|
||||||
? player.getMovement().getFrom().getLoc() : player.getMovement().getTo().getLoc();
|
? player.getMovement().getFrom().getLoc() : player.getMovement().getTo().getLoc();
|
||||||
|
|
||||||
WrappedBlock underMaterial = player.getBlockUpdateHandler()
|
WrappedBlock underMaterial = player.getWorldTracker()
|
||||||
.getBlock(new IntVector(MathHelper.floor_double(underBlockLoc.getX()),
|
.getBlock(new Vector3i(MathHelper.floor_double(underBlockLoc.getX()),
|
||||||
MathHelper.floor_double(underBlockLoc.getY() - 1),
|
MathHelper.floor_double(underBlockLoc.getY() - 1),
|
||||||
MathHelper.floor_double(underBlockLoc.getZ())));
|
MathHelper.floor_double(underBlockLoc.getZ())));
|
||||||
|
|
||||||
@@ -87,8 +87,8 @@ public class VelocityB extends Check {
|
|||||||
double pmotionx = 0, pmotionz = 0;
|
double pmotionx = 0, pmotionz = 0;
|
||||||
boolean onGround = player.getMovement().getFrom().isOnGround();
|
boolean onGround = player.getMovement().getFrom().isOnGround();
|
||||||
|
|
||||||
val speed = player.getPotionHandler().getEffectByType(PotionEffectType.SPEED);
|
val speed = player.getPotionHandler().getEffectByType(PotionTypes.SPEED);
|
||||||
val slow = player.getPotionHandler().getEffectByType(PotionEffectType.SLOW);
|
val slow = player.getPotionHandler().getEffectByType(PotionTypes.SLOWNESS);
|
||||||
|
|
||||||
for (Iteration iteration : iterations) {
|
for (Iteration iteration : iterations) {
|
||||||
float forward = iteration.f, strafe = iteration.s;
|
float forward = iteration.f, strafe = iteration.s;
|
||||||
@@ -138,9 +138,9 @@ public class VelocityB extends Check {
|
|||||||
aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D;
|
aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D;
|
||||||
|
|
||||||
if (speed.isPresent())
|
if (speed.isPresent())
|
||||||
aiMoveSpeed += (speed.get().getAmplifier() + 1) * 0.20000000298023224D * aiMoveSpeed;
|
aiMoveSpeed += (speed.get().properties().amplifier() + 1) * 0.20000000298023224D * aiMoveSpeed;
|
||||||
if (slow.isPresent())
|
if (slow.isPresent())
|
||||||
aiMoveSpeed += (slow.get().getAmplifier() + 1) * -0.15000000596046448D * aiMoveSpeed;
|
aiMoveSpeed += (slow.get().properties().amplifier() + 1) * -0.15000000596046448D * aiMoveSpeed;
|
||||||
|
|
||||||
float f5;
|
float f5;
|
||||||
if (onGround) {
|
if (onGround) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dev.brighten.ac.check.impl.world;
|
package dev.brighten.ac.check.impl.world;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.util.Vector3d;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerBlockPlacement;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerBlockPlacement;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||||
import dev.brighten.ac.api.check.CheckType;
|
import dev.brighten.ac.api.check.CheckType;
|
||||||
@@ -35,7 +36,7 @@ public class BlockA extends Check {
|
|||||||
WAction<WrapperPlayClientPlayerBlockPlacement> blockPlace = packet -> {
|
WAction<WrapperPlayClientPlayerBlockPlacement> blockPlace = packet -> {
|
||||||
Vector3d loc = packet.getBlockPosition().toVector3d();
|
Vector3d loc = packet.getBlockPosition().toVector3d();
|
||||||
|
|
||||||
WrappedBlock block = player.getBlockUpdateHandler().getBlock(loc);
|
WrappedBlock block = player.getWorldTracker().getBlock(new Vector3i(MathUtils.floor(loc.getX()), MathUtils.floor(loc.getY()), MathUtils.floor(loc.getZ())));
|
||||||
|
|
||||||
CollisionBox box = BlockData.getData(block.getType()).getBox(player, block, player.getPlayerVersion());
|
CollisionBox box = BlockData.getData(block.getType()).getBox(player, block, player.getPlayerVersion());
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ import dev.brighten.ac.data.APlayer;
|
|||||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||||
import dev.brighten.ac.utils.KLocation;
|
import dev.brighten.ac.utils.KLocation;
|
||||||
import dev.brighten.ac.utils.annotation.Bind;
|
import dev.brighten.ac.utils.annotation.Bind;
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
|
||||||
import dev.brighten.ac.utils.timer.Timer;
|
import dev.brighten.ac.utils.timer.Timer;
|
||||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||||
import dev.brighten.ac.utils.world.BlockData;
|
import dev.brighten.ac.utils.world.BlockData;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@CheckData(name = "Block (D)", checkId = "blockc", type = CheckType.INTERACT)
|
@CheckData(name = "Block (D)", checkId = "blockc", type = CheckType.INTERACT)
|
||||||
public class BlockD extends Check {
|
public class BlockD extends Check {
|
||||||
@@ -45,7 +45,7 @@ public class BlockD extends Check {
|
|||||||
packet.getFace().getModY(),
|
packet.getFace().getModY(),
|
||||||
packet.getFace().getModZ());
|
packet.getFace().getModZ());
|
||||||
|
|
||||||
WrappedBlock block = new WrappedBlock(new IntVector(packet.getBlockPosition()),
|
WrappedBlock block = new WrappedBlock(packet.getBlockPosition(),
|
||||||
placedType,
|
placedType,
|
||||||
WrappedBlockState.getDefaultState(placedType));
|
WrappedBlockState.getDefaultState(placedType));
|
||||||
blockPlaceLocations.put(blockpos, block);
|
blockPlaceLocations.put(blockpos, block);
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
|||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||||
import com.github.retrooper.packetevents.protocol.player.User;
|
import com.github.retrooper.packetevents.protocol.player.User;
|
||||||
import com.github.retrooper.packetevents.protocol.world.dimension.DimensionType;
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
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.StateTypes;
|
||||||
import com.github.retrooper.packetevents.util.Vector3d;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
import dev.brighten.ac.Anticheat;
|
import dev.brighten.ac.Anticheat;
|
||||||
import dev.brighten.ac.api.spigot.impl.LegacyPlayer;
|
import dev.brighten.ac.api.spigot.impl.LegacyPlayer;
|
||||||
import dev.brighten.ac.api.spigot.impl.ModernPlayer;
|
import dev.brighten.ac.api.spigot.impl.ModernPlayer;
|
||||||
@@ -22,17 +23,20 @@ import dev.brighten.ac.data.info.GeneralInformation;
|
|||||||
import dev.brighten.ac.data.info.LagInformation;
|
import dev.brighten.ac.data.info.LagInformation;
|
||||||
import dev.brighten.ac.data.obj.InstantAction;
|
import dev.brighten.ac.data.obj.InstantAction;
|
||||||
import dev.brighten.ac.data.obj.NormalAction;
|
import dev.brighten.ac.data.obj.NormalAction;
|
||||||
import dev.brighten.ac.handler.EntityLocationHandler;
|
import dev.brighten.ac.handler.EntityTrackHandler;
|
||||||
import dev.brighten.ac.handler.MovementHandler;
|
import dev.brighten.ac.handler.MovementHandler;
|
||||||
import dev.brighten.ac.handler.PotionHandler;
|
import dev.brighten.ac.handler.PotionHandler;
|
||||||
import dev.brighten.ac.handler.VelocityHandler;
|
import dev.brighten.ac.handler.VelocityHandler;
|
||||||
import dev.brighten.ac.handler.block.BlockUpdateHandler;
|
import dev.brighten.ac.handler.block.BlockUpdateHandler;
|
||||||
|
import dev.brighten.ac.handler.block.World;
|
||||||
import dev.brighten.ac.handler.entity.FakeMob;
|
import dev.brighten.ac.handler.entity.FakeMob;
|
||||||
import dev.brighten.ac.handler.keepalive.KeepAlive;
|
import dev.brighten.ac.handler.keepalive.KeepAlive;
|
||||||
import dev.brighten.ac.handler.protocol.Protocol;
|
|
||||||
import dev.brighten.ac.messages.Messages;
|
import dev.brighten.ac.messages.Messages;
|
||||||
import dev.brighten.ac.packet.TransactionServerWrapper;
|
import dev.brighten.ac.packet.TransactionServerWrapper;
|
||||||
import dev.brighten.ac.utils.*;
|
import dev.brighten.ac.utils.Helper;
|
||||||
|
import dev.brighten.ac.utils.KLocation;
|
||||||
|
import dev.brighten.ac.utils.Tuple;
|
||||||
|
import dev.brighten.ac.utils.XMaterial;
|
||||||
import dev.brighten.ac.utils.objects.evicting.EvictingList;
|
import dev.brighten.ac.utils.objects.evicting.EvictingList;
|
||||||
import dev.brighten.ac.utils.timer.Timer;
|
import dev.brighten.ac.utils.timer.Timer;
|
||||||
import dev.brighten.ac.utils.timer.impl.MillisTimer;
|
import dev.brighten.ac.utils.timer.impl.MillisTimer;
|
||||||
@@ -49,7 +53,6 @@ import me.hydro.emulator.object.input.DataSupplier;
|
|||||||
import me.hydro.emulator.util.mcp.AxisAlignedBB;
|
import me.hydro.emulator.util.mcp.AxisAlignedBB;
|
||||||
import me.hydro.emulator.util.mcp.BlockPos;
|
import me.hydro.emulator.util.mcp.BlockPos;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
@@ -72,10 +75,10 @@ public class APlayer {
|
|||||||
private VelocityHandler velocityHandler;
|
private VelocityHandler velocityHandler;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private EntityLocationHandler entityLocationHandler;
|
private EntityTrackHandler entityTrackHandler;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private BlockUpdateHandler blockUpdateHandler;
|
private BlockUpdateHandler worldTracker;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private CheckHandler checkHandler;
|
private CheckHandler checkHandler;
|
||||||
@@ -138,87 +141,103 @@ public class APlayer {
|
|||||||
this.movement = new MovementHandler(this);
|
this.movement = new MovementHandler(this);
|
||||||
this.potionHandler = new PotionHandler(this);
|
this.potionHandler = new PotionHandler(this);
|
||||||
this.velocityHandler = new VelocityHandler(this);
|
this.velocityHandler = new VelocityHandler(this);
|
||||||
this.entityLocationHandler = new EntityLocationHandler(this);
|
this.entityTrackHandler = new EntityTrackHandler(this);
|
||||||
this.blockUpdateHandler = new BlockUpdateHandler(this);
|
this.worldTracker = new BlockUpdateHandler(this);
|
||||||
this.checkHandler = new CheckHandler(this);
|
this.checkHandler = new CheckHandler(this);
|
||||||
this.info = new GeneralInformation();
|
this.info = new GeneralInformation();
|
||||||
this.lagInfo = new LagInformation();
|
this.lagInfo = new LagInformation();
|
||||||
this.blockInfo = new BlockInformation(this);
|
this.blockInfo = new BlockInformation(this);
|
||||||
|
|
||||||
|
worldTracker.getCurrentWorld().set(new World(bukkitPlayer.getWorld().getName()));
|
||||||
|
|
||||||
creation.reset();
|
creation.reset();
|
||||||
|
|
||||||
|
playerVersion = ClientVersion.getById(Anticheat.INSTANCE.getProtocol().getPlayerVersion(this));
|
||||||
|
|
||||||
Anticheat.INSTANCE.getScheduler().schedule(() -> {
|
Anticheat.INSTANCE.getScheduler().schedule(() -> {
|
||||||
// Grabbing the protocol version of the player.
|
// Grabbing the protocol version of the player.
|
||||||
Anticheat.INSTANCE.getLogger().info("Attempting Getting player version for " + getBukkitPlayer().getName());
|
Anticheat.INSTANCE.getLogger().info("Attempting Getting player version for " + getBukkitPlayer().getName());
|
||||||
|
|
||||||
ClientVersion version = ClientVersion.getById(Protocol.getProtocol().getPlayerVersion(getBukkitPlayer()));
|
ClientVersion version = ClientVersion.getById(Anticheat.INSTANCE.getProtocol().getPlayerVersion(this));
|
||||||
|
|
||||||
this.playerVersion = version;
|
this.playerVersion = version;
|
||||||
|
|
||||||
Anticheat.INSTANCE.getLogger().info("Got player version " + version.name() + " for " + getBukkitPlayer().getName());
|
Anticheat.INSTANCE.getLogger().info("Got player version " + version.name() + " for " + getBukkitPlayer().getName());
|
||||||
|
|
||||||
if(PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) {
|
|
||||||
this.wrappedPlayer = new LegacyPlayer(getBukkitPlayer());
|
|
||||||
} else this.wrappedPlayer = new ModernPlayer(getBukkitPlayer());
|
|
||||||
|
|
||||||
EMULATOR = new Emulator(new DataSupplier() {
|
|
||||||
@Override
|
|
||||||
public List<AxisAlignedBB> getCollidingBoxes(AxisAlignedBB bb) {
|
|
||||||
SimpleCollisionBox sbc = new SimpleCollisionBox(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ);
|
|
||||||
|
|
||||||
// Greater than 20? We want to truncate to prevent huge processing cost
|
|
||||||
if(sbc.min().distanceSquared(sbc.max()) > 400) {
|
|
||||||
sbc.maxX = sbc.minX + Math.min(sbc.maxX - sbc.minX, 20);
|
|
||||||
sbc.maxY = sbc.minY + Math.max(sbc.maxY - sbc.minY, 20);
|
|
||||||
sbc.maxZ = sbc.minZ + Math.max(sbc.maxZ - sbc.minZ, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<AxisAlignedBB> axisAlignedBBs = new ArrayList<>();
|
|
||||||
|
|
||||||
for (SimpleCollisionBox bb2 : Helper.getCollisions(APlayer.this,
|
|
||||||
sbc)) {
|
|
||||||
axisAlignedBBs
|
|
||||||
.add(new AxisAlignedBB(bb2.minX, bb2.minY, bb2.minZ, bb2.maxX, bb2.maxY, bb2.maxZ));
|
|
||||||
}
|
|
||||||
|
|
||||||
return axisAlignedBBs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Block getBlockAt(BlockPos blockPos) {
|
|
||||||
//Optional<org.bukkit.block.Block>
|
|
||||||
var block = APlayer.this.getBlockUpdateHandler()
|
|
||||||
.getBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
|
||||||
|
|
||||||
StateType type = block.getType();
|
|
||||||
|
|
||||||
if(type == StateTypes.SLIME_BLOCK) {
|
|
||||||
return new BlockSlime();
|
|
||||||
} else if(type == StateTypes.SOUL_SAND) {
|
|
||||||
return new BlockSoulSand();
|
|
||||||
} else if(type == StateTypes.COBWEB) {
|
|
||||||
return new BlockWeb();
|
|
||||||
} else if(type == StateTypes.ICE || type == StateTypes.PACKED_ICE || type == StateTypes.FROSTED_ICE) {
|
|
||||||
return new BlockIce();
|
|
||||||
} else if(type == StateTypes.BLUE_ICE) {
|
|
||||||
return new BlockBlueIce();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Block();
|
|
||||||
}
|
|
||||||
}, getPlayerVersion().getProtocolVersion());
|
|
||||||
|
|
||||||
generateEntities();
|
|
||||||
|
|
||||||
// Enabling alerts for players on join if they have the permissions to
|
|
||||||
if(getBukkitPlayer().hasPermission("anticheat.command.alerts")
|
|
||||||
|| getBukkitPlayer().hasPermission("anticheat.alerts")) {
|
|
||||||
Check.alertsEnabled.add(getUuid());
|
|
||||||
getBukkitPlayer().spigot().sendMessage(Messages.ALERTS_ON);
|
|
||||||
}
|
|
||||||
initialized = true;
|
|
||||||
Anticheat.INSTANCE.getRunUtils().task(() -> checkHandler.initChecks());
|
|
||||||
}, 100, TimeUnit.MILLISECONDS);
|
}, 100, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
if(PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) {
|
||||||
|
this.wrappedPlayer = new LegacyPlayer(getBukkitPlayer());
|
||||||
|
} else this.wrappedPlayer = new ModernPlayer(getBukkitPlayer());
|
||||||
|
|
||||||
|
Cache<AxisAlignedBB, List<AxisAlignedBB>> collisionCache = CacheBuilder.newBuilder()
|
||||||
|
.maximumSize(200)
|
||||||
|
.expireAfterWrite(100, TimeUnit.MILLISECONDS)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EMULATOR = new Emulator(new DataSupplier() {
|
||||||
|
@Override
|
||||||
|
public List<AxisAlignedBB> getCollidingBoxes(AxisAlignedBB bb) {
|
||||||
|
|
||||||
|
var cacheIfPresent = collisionCache.getIfPresent(bb);
|
||||||
|
|
||||||
|
if(cacheIfPresent != null) return cacheIfPresent;
|
||||||
|
|
||||||
|
SimpleCollisionBox sbc = new SimpleCollisionBox(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ);
|
||||||
|
|
||||||
|
// Greater than 20? We want to truncate to prevent huge processing cost
|
||||||
|
if(sbc.min().distanceSquared(sbc.max()) > 400) {
|
||||||
|
sbc.maxX = sbc.minX + Math.min(sbc.maxX - sbc.minX, 20);
|
||||||
|
sbc.maxY = sbc.minY + Math.max(sbc.maxY - sbc.minY, 20);
|
||||||
|
sbc.maxZ = sbc.minZ + Math.max(sbc.maxZ - sbc.minZ, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<AxisAlignedBB> axisAlignedBBs = new ArrayList<>();
|
||||||
|
|
||||||
|
for (SimpleCollisionBox bb2 : Helper.getCollisions(APlayer.this,
|
||||||
|
sbc)) {
|
||||||
|
axisAlignedBBs
|
||||||
|
.add(new AxisAlignedBB(bb2.minX, bb2.minY, bb2.minZ, bb2.maxX, bb2.maxY, bb2.maxZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
collisionCache.put(bb, axisAlignedBBs);
|
||||||
|
|
||||||
|
return axisAlignedBBs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Block getBlockAt(BlockPos blockPos) {
|
||||||
|
//Optional<org.bukkit.block.Block>
|
||||||
|
var block = APlayer.this.getWorldTracker()
|
||||||
|
.getBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||||
|
|
||||||
|
StateType type = block.getType();
|
||||||
|
|
||||||
|
if(type == StateTypes.SLIME_BLOCK) {
|
||||||
|
return new BlockSlime();
|
||||||
|
} else if(type == StateTypes.SOUL_SAND) {
|
||||||
|
return new BlockSoulSand();
|
||||||
|
} else if(type == StateTypes.COBWEB) {
|
||||||
|
return new BlockWeb();
|
||||||
|
} else if(type == StateTypes.ICE || type == StateTypes.PACKED_ICE || type == StateTypes.FROSTED_ICE) {
|
||||||
|
return new BlockIce();
|
||||||
|
} else if(type == StateTypes.BLUE_ICE) {
|
||||||
|
return new BlockBlueIce();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Block();
|
||||||
|
}
|
||||||
|
}, getPlayerVersion().getProtocolVersion());
|
||||||
|
|
||||||
|
generateEntities();
|
||||||
|
|
||||||
|
// Enabling alerts for players on join if they have the permissions to
|
||||||
|
if(getBukkitPlayer().hasPermission("anticheat.command.alerts")
|
||||||
|
|| getBukkitPlayer().hasPermission("anticheat.alerts")) {
|
||||||
|
Check.alertsEnabled.add(getUuid());
|
||||||
|
getBukkitPlayer().spigot().sendMessage(Messages.ALERTS_ON);
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
Anticheat.INSTANCE.getRunUtils().task(() -> checkHandler.initChecks());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateEntities() {
|
private void generateEntities() {
|
||||||
@@ -228,7 +247,7 @@ public class APlayer {
|
|||||||
|
|
||||||
RayCollision coll = new RayCollision(origin.toVector(), origin.getDirection().multiply(-1));
|
RayCollision coll = new RayCollision(origin.toVector(), origin.getDirection().multiply(-1));
|
||||||
|
|
||||||
Vector loc1 = coll.collisionPoint(2);
|
Vector3d loc1 = coll.collisionPoint(2);
|
||||||
|
|
||||||
List<EntityData<?>> dataList = new ArrayList<>();
|
List<EntityData<?>> dataList = new ArrayList<>();
|
||||||
|
|
||||||
@@ -330,10 +349,6 @@ public class APlayer {
|
|||||||
user.writePacketSilently(packet);
|
user.writePacketSilently(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DimensionType getDimensionType() {
|
|
||||||
return user.getDimensionType();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendPacket(PacketWrapper<?> packet) {
|
public void sendPacket(PacketWrapper<?> packet) {
|
||||||
user.sendPacket(packet);
|
user.sendPacket(packet);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
|
|||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
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.StateTypes;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import dev.brighten.ac.Anticheat;
|
import dev.brighten.ac.Anticheat;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||||
@@ -132,11 +133,11 @@ public class BlockInformation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final StateType type =
|
final StateType type =
|
||||||
player.getBlockUpdateHandler().getBlock(new IntVector(x, y, z)).getType();
|
player.getWorldTracker().getBlock(new Vector3i(x, y, z)).getType();
|
||||||
|
|
||||||
if (type != StateTypes.AIR) {
|
if (type != StateTypes.AIR) {
|
||||||
|
|
||||||
IntVector vec = new IntVector(x, y, z);
|
Vector3i vec = new Vector3i(x, y, z);
|
||||||
CollisionBox blockBox = BlockData.getData(type)
|
CollisionBox blockBox = BlockData.getData(type)
|
||||||
.getBox(player, vec, player.getPlayerVersion());
|
.getBox(player, vec, player.getPlayerVersion());
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package dev.brighten.ac.data.info;
|
package dev.brighten.ac.data.info;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.util.Vector3d;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
|
import dev.brighten.ac.data.obj.Pose;
|
||||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||||
import dev.brighten.ac.packet.PlayerCapabilities;
|
import dev.brighten.ac.packet.PlayerCapabilities;
|
||||||
import dev.brighten.ac.utils.KLocation;
|
import dev.brighten.ac.utils.KLocation;
|
||||||
|
import dev.brighten.ac.utils.KPotionEffect;
|
||||||
import dev.brighten.ac.utils.PastLocation;
|
import dev.brighten.ac.utils.PastLocation;
|
||||||
import dev.brighten.ac.utils.math.RollingAverage;
|
import dev.brighten.ac.utils.math.RollingAverage;
|
||||||
import dev.brighten.ac.utils.objects.evicting.EvictingList;
|
import dev.brighten.ac.utils.objects.evicting.EvictingList;
|
||||||
@@ -12,8 +14,6 @@ import dev.brighten.ac.utils.timer.Timer;
|
|||||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.potion.PotionEffect;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -33,8 +33,8 @@ public class GeneralInformation {
|
|||||||
lastBlockUpdate = new TickTimer(), lastMiscNear = new TickTimer(), lastHalfBlock = new TickTimer(),
|
lastBlockUpdate = new TickTimer(), lastMiscNear = new TickTimer(), lastHalfBlock = new TickTimer(),
|
||||||
lastFence = new TickTimer(), lastFakeBotHit = new TickTimer(), lastInventoryOpen = new TickTimer(),
|
lastFence = new TickTimer(), lastFakeBotHit = new TickTimer(), lastInventoryOpen = new TickTimer(),
|
||||||
botAttack = new TickTimer(), lastAttack = new TickTimer(), lastCanceledFlying = new TickTimer();
|
botAttack = new TickTimer(), lastAttack = new TickTimer(), lastCanceledFlying = new TickTimer();
|
||||||
public LivingEntity target;
|
public TrackedEntity target;
|
||||||
public Optional<PotionEffect> groundJumpBoost;
|
public Optional<KPotionEffect> groundJumpBoost = Optional.empty();
|
||||||
public boolean serverGround, lastServerGround, canFly, nearGround, worldLoaded, generalCancel, inVehicle, creative,
|
public boolean serverGround, lastServerGround, canFly, nearGround, worldLoaded, generalCancel, inVehicle, creative,
|
||||||
sneaking, lsneaking, sprinting, gliding, riptiding, wasOnSlime, onLadder, doingVelocity, breakingBlock,
|
sneaking, lsneaking, sprinting, gliding, riptiding, wasOnSlime, onLadder, doingVelocity, breakingBlock,
|
||||||
inventoryOpen, swimming;
|
inventoryOpen, swimming;
|
||||||
@@ -46,4 +46,7 @@ public class GeneralInformation {
|
|||||||
public List<Vector3d> velocityHistory = Collections.synchronizedList(new EvictingList<>(5));
|
public List<Vector3d> velocityHistory = Collections.synchronizedList(new EvictingList<>(5));
|
||||||
public List<PlayerCapabilities> possibleCapabilities = new ArrayList<>();
|
public List<PlayerCapabilities> possibleCapabilities = new ArrayList<>();
|
||||||
private int clientGroundTicks, clientAirTicks;
|
private int clientGroundTicks, clientAirTicks;
|
||||||
|
private double walkSpeed, flySpeed;
|
||||||
|
private PlayerInput playerInput = PlayerInput.NONE;
|
||||||
|
private Pose pose;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package dev.brighten.ac.data.info;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerInput;
|
||||||
|
|
||||||
|
public record PlayerInput(boolean forward, boolean backward, boolean left, boolean right, boolean jump, boolean sprint, boolean shift) {
|
||||||
|
|
||||||
|
public static PlayerInput getFromPacket(WrapperPlayClientPlayerInput packet) {
|
||||||
|
return new PlayerInput(packet.isForward(), packet.isBackward(), packet.isLeft(),
|
||||||
|
packet.isRight(), packet.isJump(), packet.isSprint(), packet.isShift());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final PlayerInput NONE = new PlayerInput(false, false, false,
|
||||||
|
false, false, false, false);
|
||||||
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package dev.brighten.ac.data.obj;
|
package dev.brighten.ac.data.obj;
|
||||||
|
|
||||||
|
import dev.brighten.ac.handler.block.World;
|
||||||
import dev.brighten.ac.utils.KLocation;
|
import dev.brighten.ac.utils.KLocation;
|
||||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package dev.brighten.ac.data.obj;
|
||||||
|
|
||||||
|
public enum Pose {
|
||||||
|
STANDING(0.6f, 1.8f, 1.62f),
|
||||||
|
FALL_FLYING(0.6f, 0.6f, 0.4f),
|
||||||
|
SLEEPING(0.2f, 0.2f, 0.2f),
|
||||||
|
SWIMMING(0.6f, 0.6f, 0.4f),
|
||||||
|
SPIN_ATTACK(0.6f, 0.6f, 0.4f),
|
||||||
|
CROUCHING(0.6f, 1.5f, 1.27f),
|
||||||
|
DYING(0.2f, 0.2f, 0.2f),
|
||||||
|
|
||||||
|
// Non-player poses
|
||||||
|
NINE_CROUCHING(0.6f, 1.65f, 1.54f), // 1.9-1.13 clients have a slightly different crouching hitbox
|
||||||
|
LONG_JUMPING(0.6f, 1.8f, 1.54f); // DUMMY (players can't have this pose)
|
||||||
|
|
||||||
|
public final float width;
|
||||||
|
public final float height;
|
||||||
|
public final float eyeHeight;
|
||||||
|
|
||||||
|
Pose(float width, float height, float eyeHeight) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.eyeHeight = eyeHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package dev.brighten.ac.handler;
|
package dev.brighten.ac.handler;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
|
import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import dev.brighten.ac.Anticheat;
|
import dev.brighten.ac.Anticheat;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||||
import dev.brighten.ac.utils.ItemBuilder;
|
import dev.brighten.ac.utils.ItemBuilder;
|
||||||
import dev.brighten.ac.utils.Materials;
|
import dev.brighten.ac.utils.Materials;
|
||||||
import dev.brighten.ac.utils.annotation.Init;
|
import dev.brighten.ac.utils.annotation.Init;
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
|
||||||
import dev.brighten.ac.utils.world.BlockData;
|
import dev.brighten.ac.utils.world.BlockData;
|
||||||
import dev.brighten.ac.utils.world.EntityData;
|
import dev.brighten.ac.utils.world.EntityData;
|
||||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||||
@@ -31,7 +31,7 @@ import java.util.stream.Collectors;
|
|||||||
@Init
|
@Init
|
||||||
public class BBRevealHandler implements Listener {
|
public class BBRevealHandler implements Listener {
|
||||||
|
|
||||||
private final Map<UUID, Set<IntVector>> blocksToShow = new HashMap<>();
|
private final Map<UUID, Set<Vector3i>> blocksToShow = new HashMap<>();
|
||||||
private final Set<Entity> entitiesToShow = new HashSet<>();
|
private final Set<Entity> entitiesToShow = new HashSet<>();
|
||||||
|
|
||||||
public static BBRevealHandler INSTANCE;
|
public static BBRevealHandler INSTANCE;
|
||||||
@@ -52,9 +52,9 @@ public class BBRevealHandler implements Listener {
|
|||||||
if(player == null || !player.getWrappedPlayer().getItemInHand().isSimilar(wand)) return;
|
if(player == null || !player.getWrappedPlayer().getItemInHand().isSimilar(wand)) return;
|
||||||
|
|
||||||
if(event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
if(event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||||
IntVector blockLoc = new IntVector(event.getClickedBlock().getX(),
|
Vector3i blockLoc = new Vector3i(event.getClickedBlock().getX(),
|
||||||
event.getClickedBlock().getY(), event.getClickedBlock().getZ());
|
event.getClickedBlock().getY(), event.getClickedBlock().getZ());
|
||||||
Set<IntVector> blocksToShow = this.blocksToShow
|
Set<Vector3i> blocksToShow = this.blocksToShow
|
||||||
.computeIfAbsent(event.getPlayer().getUniqueId(), k -> new HashSet<>());
|
.computeIfAbsent(event.getPlayer().getUniqueId(), k -> new HashSet<>());
|
||||||
if(blocksToShow.contains(blockLoc)) {
|
if(blocksToShow.contains(blockLoc)) {
|
||||||
blocksToShow.remove(blockLoc);
|
blocksToShow.remove(blockLoc);
|
||||||
@@ -63,11 +63,11 @@ public class BBRevealHandler implements Listener {
|
|||||||
.create());
|
.create());
|
||||||
} else {
|
} else {
|
||||||
blocksToShow.add(blockLoc);
|
blocksToShow.add(blockLoc);
|
||||||
WrappedBlock block = player.getBlockUpdateHandler().getBlock(blockLoc);
|
WrappedBlock block = player.getWorldTracker().getCurrentWorld().get().getBlock(blockLoc);
|
||||||
event.getPlayer().spigot().sendMessage(new ComponentBuilder("Now showing block: ")
|
event.getPlayer().spigot().sendMessage(new ComponentBuilder("Now showing block: ")
|
||||||
.color(ChatColor.GREEN).color(ChatColor.WHITE).append(event.getClickedBlock().getType().name())
|
.color(ChatColor.GREEN).color(ChatColor.WHITE).append(event.getClickedBlock().getType().name())
|
||||||
.color(ChatColor.GRAY)
|
.color(ChatColor.GRAY)
|
||||||
.append(" flags: " + block.getBlockState().getType() + " | " + Materials.checkFlag(block.getType(), Materials.COLLIDABLE) + "," +
|
.append(" flags: " + block.getType() + " | " + block.getType().isSolid() + "," +
|
||||||
Materials.checkFlag(block.getType(), Materials.SOLID) + "," + Materials.checkFlag(block.getType(), Materials.LIQUID))
|
Materials.checkFlag(block.getType(), Materials.SOLID) + "," + Materials.checkFlag(block.getType(), Materials.LIQUID))
|
||||||
.color(ChatColor.RED)
|
.color(ChatColor.RED)
|
||||||
.append(" | box=" + BlockData.getData(block.getType()).getBox(player, blockLoc, player.getPlayerVersion()).downCast().stream().map(SimpleCollisionBox::toString).collect(Collectors.joining(", ")))
|
.append(" | box=" + BlockData.getData(block.getType()).getBox(player, blockLoc, player.getPlayerVersion()).downCast().stream().map(SimpleCollisionBox::toString).collect(Collectors.joining(", ")))
|
||||||
@@ -107,7 +107,7 @@ public class BBRevealHandler implements Listener {
|
|||||||
if(player.isEmpty()) return;
|
if(player.isEmpty()) return;
|
||||||
|
|
||||||
blocks.forEach(blockLoc -> {
|
blocks.forEach(blockLoc -> {
|
||||||
var block = player.get().getBlockUpdateHandler().getBlock(blockLoc);
|
var block = player.get().getWorldTracker().getCurrentWorld().get().getBlock(blockLoc);
|
||||||
|
|
||||||
var blockBox = BlockData.getData(block.getType())
|
var blockBox = BlockData.getData(block.getType())
|
||||||
.getBox(player.get(), blockLoc, player.get().getPlayerVersion());
|
.getBox(player.get(), blockLoc, player.get().getPlayerVersion());
|
||||||
|
|||||||
+50
-37
@@ -1,14 +1,17 @@
|
|||||||
package dev.brighten.ac.handler;
|
package dev.brighten.ac.handler;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
|
||||||
|
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityPositionSync;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityPositionSync;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityTeleport;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityTeleport;
|
||||||
import dev.brighten.ac.Anticheat;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.entity.FakeMob;
|
import dev.brighten.ac.handler.entity.FakeMob;
|
||||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||||
@@ -18,20 +21,15 @@ import dev.brighten.ac.utils.KLocation;
|
|||||||
import dev.brighten.ac.utils.timer.Timer;
|
import dev.brighten.ac.utils.timer.Timer;
|
||||||
import dev.brighten.ac.utils.timer.impl.MillisTimer;
|
import dev.brighten.ac.utils.timer.impl.MillisTimer;
|
||||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class EntityLocationHandler {
|
public class EntityTrackHandler {
|
||||||
|
|
||||||
private final APlayer data;
|
private final APlayer data;
|
||||||
@Getter
|
|
||||||
private Map<Integer, TrackedEntity> trackedEntities = new Int2ObjectArrayMap<>();
|
|
||||||
private final Timer lastFlying = new MillisTimer();
|
private final Timer lastFlying = new MillisTimer();
|
||||||
|
|
||||||
public Set<Integer> canCreateMob = new HashSet<>();
|
public Set<Integer> canCreateMob = new HashSet<>();
|
||||||
@@ -43,7 +41,8 @@ public class EntityLocationHandler {
|
|||||||
EntityTypes.WITCH, EntityTypes.COW, EntityTypes.CREEPER);
|
EntityTypes.WITCH, EntityTypes.COW, EntityTypes.CREEPER);
|
||||||
|
|
||||||
public Optional<Integer> getTargetOfFakeMob(int fakeMobId) {
|
public Optional<Integer> getTargetOfFakeMob(int fakeMobId) {
|
||||||
for (TrackedEntity value : trackedEntities.values()) {
|
for (TrackedEntity value : data.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntities().values()) {
|
||||||
if(value.getFakeMobs().stream().anyMatch(mob -> mob.getEntityId() == fakeMobId)) {
|
if(value.getFakeMobs().stream().anyMatch(mob -> mob.getEntityId() == fakeMobId)) {
|
||||||
return Optional.of(value.getEntityId());
|
return Optional.of(value.getEntityId());
|
||||||
}
|
}
|
||||||
@@ -51,23 +50,6 @@ public class EntityLocationHandler {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<TrackedEntity> getTrackedEntity(int entityId) {
|
|
||||||
TrackedEntity trackedEntity = trackedEntities.get(entityId);
|
|
||||||
|
|
||||||
if(trackedEntity == null) {
|
|
||||||
var entity = Anticheat.INSTANCE.getWorldInfo(data.getBukkitPlayer().getWorld()).getEntity(entityId);
|
|
||||||
|
|
||||||
if(entity.isEmpty()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
KLocation loc = new KLocation(entity.get().getLocation());
|
|
||||||
trackedEntity = new TrackedEntity(entityId, EntityTypes.PLAYER, loc);
|
|
||||||
trackedEntities.put(entityId, trackedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Optional.of(trackedEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* We are processing PacketPlayInFlying to iterate the tracked entity locations
|
* We are processing PacketPlayInFlying to iterate the tracked entity locations
|
||||||
@@ -81,7 +63,7 @@ public class EntityLocationHandler {
|
|||||||
|
|
||||||
processZombie();
|
processZombie();
|
||||||
|
|
||||||
trackedEntities.values().forEach(entity -> {
|
data.getWorldTracker().getCurrentWorld().get().getTrackedEntities().values().forEach(entity -> {
|
||||||
var oldLoc = entity.getOldEntityLocation();
|
var oldLoc = entity.getOldEntityLocation();
|
||||||
var newLoc = entity.getNewEntityLocation();
|
var newLoc = entity.getNewEntityLocation();
|
||||||
|
|
||||||
@@ -109,7 +91,8 @@ public class EntityLocationHandler {
|
|||||||
* @param packet WrappedOutRelativePosition
|
* @param packet WrappedOutRelativePosition
|
||||||
*/
|
*/
|
||||||
void onRelPosition(WPacketPlayOutEntity packet) {
|
void onRelPosition(WPacketPlayOutEntity packet) {
|
||||||
Optional<TrackedEntity> entity = getTrackedEntity(packet.getId());
|
Optional<TrackedEntity> entity = data.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntity(packet.getId());
|
||||||
|
|
||||||
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
||||||
|
|
||||||
@@ -132,7 +115,8 @@ public class EntityLocationHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onPositionSync(WrapperPlayServerEntityPositionSync packet) {
|
void onPositionSync(WrapperPlayServerEntityPositionSync packet) {
|
||||||
Optional<TrackedEntity> entity = getTrackedEntity(packet.getId());
|
Optional<TrackedEntity> entity = data.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntity(packet.getId());
|
||||||
|
|
||||||
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
||||||
|
|
||||||
@@ -161,7 +145,8 @@ public class EntityLocationHandler {
|
|||||||
* @param packet WrappedOutEntityTeleportPacket
|
* @param packet WrappedOutEntityTeleportPacket
|
||||||
*/
|
*/
|
||||||
void onTeleportSent(WrapperPlayServerEntityTeleport packet) {
|
void onTeleportSent(WrapperPlayServerEntityTeleport packet) {
|
||||||
Optional<TrackedEntity> entity = getTrackedEntity(packet.getEntityId());
|
Optional<TrackedEntity> entity = data.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntity(packet.getEntityId());
|
||||||
|
|
||||||
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
||||||
|
|
||||||
@@ -205,6 +190,28 @@ public class EntityLocationHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateAttributes(WrapperPlayServerUpdateAttributes attributes) {
|
||||||
|
data.runKeepaliveAction(ka -> {
|
||||||
|
TrackedEntity tracked = data.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntity(attributes.getEntityId()).orElse(null);
|
||||||
|
|
||||||
|
if(tracked == null) return;
|
||||||
|
|
||||||
|
for (WrapperPlayServerUpdateAttributes.Property property : attributes.getProperties()) {
|
||||||
|
Attribute attribute = property.getAttribute();
|
||||||
|
|
||||||
|
if(attributes.getEntityId() == data.getBukkitPlayer().getEntityId() && attribute == Attributes.MOVEMENT_SPEED) {
|
||||||
|
ValuedAttribute value = tracked.getAttribute(attribute);
|
||||||
|
|
||||||
|
value.updateAttribute(property);
|
||||||
|
data.getInfo().setWalkSpeed(value.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
tracked.updateAttribute(property);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* We are running an action when a transaction is received. If the Entity provided is currently a target,
|
* We are running an action when a transaction is received. If the Entity provided is currently a target,
|
||||||
@@ -239,8 +246,10 @@ public class EntityLocationHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void removeFakeMob(int id) {
|
public void removeFakeMob(int id) {
|
||||||
if(trackedEntities.containsKey(id)) {
|
if(data.getWorldTracker().getCurrentWorld().get()
|
||||||
List<FakeMob> mobs = getTrackedEntity(id).map(TrackedEntity::getFakeMobs).orElse(new ArrayList<>());
|
.getTrackedEntities().containsKey(id)) {
|
||||||
|
List<FakeMob> mobs = data.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntity(id).map(TrackedEntity::getFakeMobs).orElse(new ArrayList<>());
|
||||||
|
|
||||||
for (FakeMob mob : mobs) {
|
for (FakeMob mob : mobs) {
|
||||||
mob.despawn();
|
mob.despawn();
|
||||||
@@ -256,9 +265,11 @@ public class EntityLocationHandler {
|
|||||||
private void createFakeMob(int entityId, KLocation location) {
|
private void createFakeMob(int entityId, KLocation location) {
|
||||||
if (!canCreateMob.contains(entityId)) return;
|
if (!canCreateMob.contains(entityId)) return;
|
||||||
|
|
||||||
Optional<TrackedEntity> trackedEntity = getTrackedEntity(entityId);
|
Optional<TrackedEntity> trackedEntity = data.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntity(entityId);
|
||||||
|
|
||||||
Optional<TrackedEntity> playerEntity = getTrackedEntity(data.getBukkitPlayer().getEntityId());
|
Optional<TrackedEntity> playerEntity = data.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntity(data.getBukkitPlayer().getEntityId());
|
||||||
|
|
||||||
if(trackedEntity.isEmpty() || playerEntity.isEmpty()) return;
|
if(trackedEntity.isEmpty() || playerEntity.isEmpty()) return;
|
||||||
|
|
||||||
@@ -281,7 +292,7 @@ public class EntityLocationHandler {
|
|||||||
|
|
||||||
RayCollision collision = new RayCollision(eyeLoc.toVector(), eyeLoc.getDirection());
|
RayCollision collision = new RayCollision(eyeLoc.toVector(), eyeLoc.getDirection());
|
||||||
|
|
||||||
Vector point = collision.collisionPoint(0.4);
|
Vector3d point = collision.collisionPoint(0.4);
|
||||||
|
|
||||||
FakeMob mob = new FakeMob(EntityTypes.SLIME);
|
FakeMob mob = new FakeMob(EntityTypes.SLIME);
|
||||||
List<EntityData<?>> types = new ArrayList<>();
|
List<EntityData<?>> types = new ArrayList<>();
|
||||||
@@ -298,7 +309,8 @@ public class EntityLocationHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void processZombie() {
|
public void processZombie() {
|
||||||
List<FakeMob> fakeMobs = getTrackedEntity(data.getBukkitPlayer().getEntityId())
|
List<FakeMob> fakeMobs = data.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntity(data.getBukkitPlayer().getEntityId())
|
||||||
.map(TrackedEntity::getFakeMobs)
|
.map(TrackedEntity::getFakeMobs)
|
||||||
.orElse(new ArrayList<>());
|
.orElse(new ArrayList<>());
|
||||||
|
|
||||||
@@ -312,7 +324,7 @@ public class EntityLocationHandler {
|
|||||||
|
|
||||||
RayCollision collision = new RayCollision(eyeLoc.toVector(), eyeLoc.getDirection());
|
RayCollision collision = new RayCollision(eyeLoc.toVector(), eyeLoc.getDirection());
|
||||||
|
|
||||||
Vector point = collision.collisionPoint(0.4);
|
Vector3d point = collision.collisionPoint(0.4);
|
||||||
|
|
||||||
fakeMob.teleport(point.getX(), point.getY(), point.getZ(), 0 ,0);
|
fakeMob.teleport(point.getX(), point.getY(), point.getZ(), 0 ,0);
|
||||||
break;
|
break;
|
||||||
@@ -321,7 +333,8 @@ public class EntityLocationHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void processFakeMobs(int entityId, boolean rel, double x, double y, double z) {
|
public void processFakeMobs(int entityId, boolean rel, double x, double y, double z) {
|
||||||
List<FakeMob> fakeMobs = getTrackedEntity(entityId).map(TrackedEntity::getFakeMobs).orElse(new ArrayList<>());
|
List<FakeMob> fakeMobs = data.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntity(entityId).map(TrackedEntity::getFakeMobs).orElse(new ArrayList<>());
|
||||||
|
|
||||||
if(fakeMobs.isEmpty()) {
|
if(fakeMobs.isEmpty()) {
|
||||||
if(!rel) {
|
if(!rel) {
|
||||||
@@ -3,6 +3,7 @@ package dev.brighten.ac.handler;
|
|||||||
import com.github.retrooper.packetevents.PacketEvents;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||||
|
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||||
import com.github.retrooper.packetevents.protocol.teleport.RelativeFlag;
|
import com.github.retrooper.packetevents.protocol.teleport.RelativeFlag;
|
||||||
import com.github.retrooper.packetevents.util.Vector3d;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||||
@@ -12,13 +13,13 @@ import dev.brighten.ac.compat.CompatHandler;
|
|||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.data.obj.CMove;
|
import dev.brighten.ac.data.obj.CMove;
|
||||||
import dev.brighten.ac.utils.*;
|
import dev.brighten.ac.utils.*;
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
|
||||||
import dev.brighten.ac.utils.objects.evicting.EvictingList;
|
import dev.brighten.ac.utils.objects.evicting.EvictingList;
|
||||||
import dev.brighten.ac.utils.timer.Timer;
|
import dev.brighten.ac.utils.timer.Timer;
|
||||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||||
import dev.brighten.ac.utils.world.CollisionBox;
|
import dev.brighten.ac.utils.world.CollisionBox;
|
||||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||||
|
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
@@ -30,9 +31,6 @@ import me.hydro.emulator.util.Vector;
|
|||||||
import me.hydro.emulator.util.mcp.MathHelper;
|
import me.hydro.emulator.util.mcp.MathHelper;
|
||||||
import me.hydro.emulator.util.mcp.MathHelper.FastMathType;
|
import me.hydro.emulator.util.mcp.MathHelper.FastMathType;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -87,21 +85,14 @@ public class MovementHandler {
|
|||||||
private final Timer lastCinematic = new TickTimer(2);
|
private final Timer lastCinematic = new TickTimer(2);
|
||||||
private final Timer lastReset = new TickTimer(2);
|
private final Timer lastReset = new TickTimer(2);
|
||||||
private final EvictingList<Integer> sensitivitySamples = new EvictingList<>(50);
|
private final EvictingList<Integer> sensitivitySamples = new EvictingList<>(50);
|
||||||
private boolean modernMovement;
|
private final boolean modernMovement;
|
||||||
|
|
||||||
public MovementHandler(APlayer player) {
|
public MovementHandler(APlayer player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
|
||||||
Player bplayer = player.getBukkitPlayer();
|
|
||||||
|
|
||||||
// Initializing player location
|
// Initializing player location
|
||||||
to.setWorld(bplayer.getWorld());
|
|
||||||
to.getLoc().setX(bplayer.getLocation().getX());
|
|
||||||
to.getLoc().setY(bplayer.getLocation().getY());
|
|
||||||
to.getLoc().setZ(bplayer.getLocation().getZ());
|
|
||||||
to.getLoc().setYaw(bplayer.getLocation().getYaw());
|
|
||||||
to.getLoc().setPitch(bplayer.getLocation().getPitch());
|
|
||||||
to.setBox(new SimpleCollisionBox(to.getLoc(), 0.6, 1.8));
|
to.setBox(new SimpleCollisionBox(to.getLoc(), 0.6, 1.8));
|
||||||
to.setOnGround(bplayer.isOnGround());
|
to.setOnGround(false);
|
||||||
|
|
||||||
// Setting from as same location as to
|
// Setting from as same location as to
|
||||||
from.setLoc(to);
|
from.setLoc(to);
|
||||||
@@ -123,31 +114,32 @@ public class MovementHandler {
|
|||||||
*/
|
*/
|
||||||
final PotionEffect[] EFFECTS = new PotionEffect[3];
|
final PotionEffect[] EFFECTS = new PotionEffect[3];
|
||||||
|
|
||||||
for (org.bukkit.potion.PotionEffect potionEffect : player.getPotionHandler().potionEffects) {
|
for (KPotionEffect potionEffect : player.getPotionHandler().getPotionEffects()) {
|
||||||
if (potionEffect.getType().equals(PotionEffectType.SPEED)) {
|
if (potionEffect.potionType().equals(PotionTypes.SPEED)) {
|
||||||
EFFECTS[0] = PotionEffect.builder()
|
EFFECTS[0] = PotionEffect.builder()
|
||||||
.amplifier(potionEffect.getAmplifier())
|
.amplifier(potionEffect.properties().amplifier())
|
||||||
.type(me.hydro.emulator.util.PotionEffectType.SPEED)
|
.type(me.hydro.emulator.util.PotionEffectType.SPEED)
|
||||||
.build();
|
.build();
|
||||||
} else if (potionEffect.getType().equals(PotionEffectType.SLOW)) {
|
} else if (potionEffect.potionType().equals(PotionTypes.SLOWNESS)) {
|
||||||
EFFECTS[1] = PotionEffect.builder()
|
EFFECTS[1] = PotionEffect.builder()
|
||||||
.amplifier(potionEffect.getAmplifier())
|
.amplifier(potionEffect.properties().amplifier())
|
||||||
.type(me.hydro.emulator.util.PotionEffectType.SLOW)
|
.type(me.hydro.emulator.util.PotionEffectType.SLOW)
|
||||||
.build();
|
.build();
|
||||||
} else if (potionEffect.getType().equals(PotionEffectType.JUMP)) {
|
} else if (potionEffect.potionType().equals(PotionTypes.JUMP_BOOST)) {
|
||||||
EFFECTS[2] = PotionEffect.builder()
|
EFFECTS[2] = PotionEffect.builder()
|
||||||
.amplifier(potionEffect.getAmplifier())
|
.amplifier(potionEffect.properties().amplifier())
|
||||||
.type(me.hydro.emulator.util.PotionEffectType.JUMP)
|
.type(me.hydro.emulator.util.PotionEffectType.JUMP)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(player.EMULATOR.getTags().contains("003") && !isZeroThree) {
|
if (player.EMULATOR.getTags().contains("003") && !isZeroThree) {
|
||||||
runEmulation(to, true);
|
runEmulation(to, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
IterationResult minimum = null;
|
IterationResult minimum = null;
|
||||||
iteration: {
|
iteration:
|
||||||
|
{
|
||||||
for (KLocation posLoc : new ArrayList<>(posLocs)) {
|
for (KLocation posLoc : new ArrayList<>(posLocs)) {
|
||||||
// Resetting to prevent lag issues.
|
// Resetting to prevent lag issues.
|
||||||
|
|
||||||
@@ -157,7 +149,7 @@ public class MovementHandler {
|
|||||||
if (minimum == null || minimum.getOffset() > result.getOffset()) {
|
if (minimum == null || minimum.getOffset() > result.getOffset()) {
|
||||||
minimum = result;
|
minimum = result;
|
||||||
|
|
||||||
if(minimum.getOffset() < 1E-26) {
|
if (minimum.getOffset() < 1E-26) {
|
||||||
// The player teleported, therefore we don't need to continue with predictions.
|
// The player teleported, therefore we don't need to continue with predictions.
|
||||||
break iteration;
|
break iteration;
|
||||||
}
|
}
|
||||||
@@ -171,96 +163,95 @@ public class MovementHandler {
|
|||||||
|
|
||||||
Motion previousMotion = player.EMULATOR.getMotion().clone();
|
Motion previousMotion = player.EMULATOR.getMotion().clone();
|
||||||
|
|
||||||
for (int forward : isZeroThree ? new int[] {0} : FULL_RANGE) {
|
for (int forward : isZeroThree ? new int[]{0} : FULL_RANGE) {
|
||||||
for (int strafe : isZeroThree ? new int[] {0} : FULL_RANGE) {
|
for (int strafe : isZeroThree ? new int[]{0} : FULL_RANGE) {
|
||||||
for (boolean jumping : getJumpingIterations()) {
|
for (boolean jumping : getJumpingIterations()) {
|
||||||
for (boolean sprinting : getSprintingIterations(forward)) {
|
for (boolean sprinting : getSprintingIterations(forward)) {
|
||||||
for (boolean usingItem : getUsingItemIterations(forward, strafe)) {
|
for (boolean usingItem : getUsingItemIterations(forward, strafe)) {
|
||||||
for (boolean hitSlow : getHitSlowIterations()) {
|
for (boolean hitSlow : getHitSlowIterations()) {
|
||||||
for (FastMathType fastMath : getFastMathIterations(forward, strafe)) {
|
for (FastMathType fastMath : getFastMathIterations(forward, strafe)) {
|
||||||
for(Vector3d possibleVector : possibleVelocity) {
|
for (Vector3d possibleVector : possibleVelocity) {
|
||||||
IterationInput input = IterationInput.builder()
|
IterationInput input = IterationInput.builder()
|
||||||
.jumping(jumping)
|
.jumping(jumping)
|
||||||
.forward(forward)
|
.forward(forward)
|
||||||
.strafing(strafe)
|
.strafing(strafe)
|
||||||
.sprinting(sprinting)
|
.sprinting(sprinting)
|
||||||
.usingItem(usingItem)
|
.usingItem(usingItem)
|
||||||
.modernMovement(modernMovement)
|
.modernMovement(modernMovement)
|
||||||
.hitSlowdown(hitSlow)
|
.hitSlowdown(hitSlow)
|
||||||
.aiMoveSpeed(player.getBukkitPlayer().getWalkSpeed() / 2)
|
.aiMoveSpeed(player.getBukkitPlayer().getWalkSpeed() / 2)
|
||||||
.fastMathType(fastMath)
|
.fastMathType(fastMath)
|
||||||
.sneaking(player.getInfo().isSneaking())
|
.sneaking(player.getInfo().sneaking)
|
||||||
.ground(from.isOnGround())
|
.ground(from.isOnGround())
|
||||||
.to(new Vector(to.getX(), to.getY(), to.getZ()))
|
.to(new Vector(to.getX(), to.getY(), to.getZ()))
|
||||||
.yaw(to.getYaw())
|
.yaw(to.getYaw())
|
||||||
.lastReportedBoundingBox(from.getBox().toNeo())
|
.lastReportedBoundingBox(from.getBox().toNeo())
|
||||||
.effectSpeed(EFFECTS[0])
|
.effectSpeed(EFFECTS[0])
|
||||||
.effectSlow(EFFECTS[1])
|
.effectSlow(EFFECTS[1])
|
||||||
.waitingForTeleport(!posLocs.isEmpty())
|
.waitingForTeleport(!posLocs.isEmpty())
|
||||||
.effectJump(EFFECTS[2]).build();
|
.effectJump(EFFECTS[2]).build();
|
||||||
|
|
||||||
boolean isVelocity = false;
|
boolean isVelocity = false;
|
||||||
if(possibleVector != null) {
|
if (possibleVector != null) {
|
||||||
// Setting the motion to the possible velocity vector.
|
// Setting the motion to the possible velocity vector.
|
||||||
player.EMULATOR.getMotion().setMotionX(possibleVector.getX());
|
player.EMULATOR.getMotion().setMotionX(possibleVector.getX());
|
||||||
player.EMULATOR.getMotion().setMotionY(possibleVector.getY());
|
player.EMULATOR.getMotion().setMotionY(possibleVector.getY());
|
||||||
player.EMULATOR.getMotion().setMotionZ(possibleVector.getZ());
|
player.EMULATOR.getMotion().setMotionZ(possibleVector.getZ());
|
||||||
// Has to be this way because order of operations in the emulator.
|
// Has to be this way because order of operations in the emulator.
|
||||||
isVelocity = true;
|
isVelocity = true;
|
||||||
} else {
|
} else {
|
||||||
// Resetting the motion to the previous motion.
|
// Resetting the motion to the previous motion.
|
||||||
player.EMULATOR.getMotion().setMotionX(previousMotion.getMotionX());
|
player.EMULATOR.getMotion().setMotionX(previousMotion.getMotionX());
|
||||||
player.EMULATOR.getMotion().setMotionY(previousMotion.getMotionY());
|
player.EMULATOR.getMotion().setMotionY(previousMotion.getMotionY());
|
||||||
player.EMULATOR.getMotion().setMotionZ(previousMotion.getMotionZ());
|
player.EMULATOR.getMotion().setMotionZ(previousMotion.getMotionZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
IterationResult result = player.EMULATOR.runIteration(input);
|
IterationResult result = player.EMULATOR.runIteration(input);
|
||||||
|
|
||||||
if(isVelocity) {
|
if (isVelocity) {
|
||||||
result.getTags().add("velocity");
|
result.getTags().add("velocity");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(fastMath == FastMathType.FAST_LEGACY) {
|
if (fastMath == FastMathType.FAST_LEGACY) {
|
||||||
result.getTags().add("fast_legacy");
|
result.getTags().add("fast_legacy");
|
||||||
} else if(fastMath == FastMathType.VANILLA) {
|
} else if (fastMath == FastMathType.VANILLA) {
|
||||||
result.getTags().add("vanilla");
|
result.getTags().add("vanilla");
|
||||||
} else if(fastMath == FastMathType.FAST_NEW) {
|
} else if (fastMath == FastMathType.FAST_NEW) {
|
||||||
result.getTags().add("fast_new");
|
result.getTags().add("fast_new");
|
||||||
} else if(fastMath == FastMathType.MODERN_VANILLA) {
|
} else if (fastMath == FastMathType.MODERN_VANILLA) {
|
||||||
result.getTags().add("modern_vanilla");
|
result.getTags().add("modern_vanilla");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(forward > 0) {
|
if (forward > 0) {
|
||||||
result.getTags().add("w-key");
|
result.getTags().add("w-key");
|
||||||
} else if(forward < 0) {
|
} else if (forward < 0) {
|
||||||
result.getTags().add("s-key");
|
result.getTags().add("s-key");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strafe > 0) {
|
if (strafe > 0) {
|
||||||
result.getTags().add("d-key");
|
result.getTags().add("d-key");
|
||||||
} else if(strafe < 0) {
|
} else if (strafe < 0) {
|
||||||
result.getTags().add("a-key");
|
result.getTags().add("a-key");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minimum == null || minimum.getOffset() > result.getOffset()) {
|
if (minimum == null || minimum.getOffset() > result.getOffset()) {
|
||||||
minimum = result;
|
minimum = result;
|
||||||
|
|
||||||
if (minimum.getOffset() < 1E-26) {
|
if (minimum.getOffset() < 1E-26) {
|
||||||
break iteration;
|
break iteration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (minimum != null) {
|
||||||
if(minimum != null) {
|
|
||||||
predicted = minimum.getPredicted();
|
predicted = minimum.getPredicted();
|
||||||
|
|
||||||
double mx = player.EMULATOR.getMotion().getMotionX();
|
double mx = player.EMULATOR.getMotion().getMotionX();
|
||||||
@@ -269,7 +260,7 @@ public class MovementHandler {
|
|||||||
|
|
||||||
double total = mx * mx + my * my + mz * mz;
|
double total = mx * mx + my * my + mz * mz;
|
||||||
|
|
||||||
if(total < 9E-4) {
|
if (total < 9E-4) {
|
||||||
player.getInfo().lastCanceledFlying.reset();
|
player.getInfo().lastCanceledFlying.reset();
|
||||||
minimum.getTags().add("003");
|
minimum.getTags().add("003");
|
||||||
}
|
}
|
||||||
@@ -282,11 +273,11 @@ public class MovementHandler {
|
|||||||
}
|
}
|
||||||
player.EMULATOR.confirm(minimum.getIteration());
|
player.EMULATOR.confirm(minimum.getIteration());
|
||||||
|
|
||||||
if(minimum.getTags().contains("003")) {
|
if (minimum.getTags().contains("003")) {
|
||||||
player.EMULATOR.getTags().add("003");
|
player.EMULATOR.getTags().add("003");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(minimum.getTags().contains("bad_offset")) {
|
if (minimum.getTags().contains("bad_offset")) {
|
||||||
player.EMULATOR.setLastReportedBoundingBox(getTo().getBox().toNeo());
|
player.EMULATOR.setLastReportedBoundingBox(getTo().getBox().toNeo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,7 +285,7 @@ public class MovementHandler {
|
|||||||
|
|
||||||
private FastMathType[] getFastMathIterations(int strafe, int forward) {
|
private FastMathType[] getFastMathIterations(int strafe, int forward) {
|
||||||
// Because no movement is being applied, there is no angle calculation being done
|
// Because no movement is being applied, there is no angle calculation being done
|
||||||
if(strafe == 0 && forward == 0) {
|
if (strafe == 0 && forward == 0) {
|
||||||
return new FastMathType[]{FastMathType.FAST_LEGACY};
|
return new FastMathType[]{FastMathType.FAST_LEGACY};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +308,9 @@ public class MovementHandler {
|
|||||||
|
|
||||||
private boolean[] getUsingItemIterations(int forward, int strafe) {
|
private boolean[] getUsingItemIterations(int forward, int strafe) {
|
||||||
return (forward == 0 && strafe == 0 ||
|
return (forward == 0 && strafe == 0 ||
|
||||||
!BlockUtils.isUsable(player.getBukkitPlayer().getItemInHand().getType())) ? ALWAYS_FALSE : IS_OR_NOT;
|
!BlockUtils.isUsable(player.getPlayerVersion(),
|
||||||
|
SpigotConversionUtil.fromBukkitItemMaterial(player.getBukkitPlayer().getInventory().getItemInHand().getType())))
|
||||||
|
? ALWAYS_FALSE : IS_OR_NOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean[] getJumpingIterations() {
|
private boolean[] getJumpingIterations() {
|
||||||
@@ -336,13 +329,13 @@ public class MovementHandler {
|
|||||||
&& player.getPlayerVersion().isNewerThanOrEquals(ClientVersion.V_1_17);
|
&& player.getPlayerVersion().isNewerThanOrEquals(ClientVersion.V_1_17);
|
||||||
|
|
||||||
checkMovement = teleportsToConfirm == 0 && posLocs.isEmpty();
|
checkMovement = teleportsToConfirm == 0 && posLocs.isEmpty();
|
||||||
|
|
||||||
if (checkMovement) {
|
if (checkMovement) {
|
||||||
moveTicks++;
|
moveTicks++;
|
||||||
if (!packet.hasPositionChanged()) moveTicks = 1;
|
if (!packet.hasPositionChanged()) moveTicks = 1;
|
||||||
} else moveTicks = 0;
|
} else moveTicks = 0;
|
||||||
|
|
||||||
if(excuseNextFlying) {
|
if (excuseNextFlying) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,10 +352,10 @@ public class MovementHandler {
|
|||||||
if (moveTicks > 0) {
|
if (moveTicks > 0) {
|
||||||
|
|
||||||
// Updating block locations
|
// Updating block locations
|
||||||
player.getInfo().setBlockOnTo(Optional.of(player.getBlockUpdateHandler()
|
player.getInfo().setBlockOnTo(Optional.of(player.getWorldTracker()
|
||||||
.getBlock(new IntVector(to.getLoc()))));
|
.getBlock(to.getLoc().toVector3i())));
|
||||||
player.getInfo().setBlockBelow(Optional.of(player.getBlockUpdateHandler()
|
player.getInfo().setBlockBelow(Optional.of(player.getWorldTracker()
|
||||||
.getBlock(new IntVector(to.getLoc().clone().subtract(0, 1, 0)))));
|
.getBlock(to.getLoc().clone().subtract(0, 1, 0).clone().toVector3i())));
|
||||||
|
|
||||||
if (packet.hasPositionChanged()) {
|
if (packet.hasPositionChanged()) {
|
||||||
// Updating player bounding box
|
// Updating player bounding box
|
||||||
@@ -486,7 +479,7 @@ public class MovementHandler {
|
|||||||
player.getInfo().setWasOnSlime(player.getBlockInfo().onSlime);
|
player.getInfo().setWasOnSlime(player.getBlockInfo().onSlime);
|
||||||
groundTicks++;
|
groundTicks++;
|
||||||
airTicks = 0;
|
airTicks = 0;
|
||||||
player.getInfo().groundJumpBoost = player.getPotionHandler().getEffectByType(PotionEffectType.JUMP);
|
player.getInfo().groundJumpBoost = player.getPotionHandler().getEffectByType(PotionTypes.JUMP_BOOST);
|
||||||
} else {
|
} else {
|
||||||
player.getInfo().groundJumpBoost = Optional.empty();
|
player.getInfo().groundJumpBoost = Optional.empty();
|
||||||
airTicks++;
|
airTicks++;
|
||||||
@@ -503,7 +496,7 @@ public class MovementHandler {
|
|||||||
.anyMatch(capability -> capability.canFly));
|
.anyMatch(capability -> capability.canFly));
|
||||||
|
|
||||||
boolean hasLevitation = PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)
|
boolean hasLevitation = PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)
|
||||||
&& player.getPotionHandler().hasPotionEffect(XPotion.LEVITATION.getPotionEffectType());
|
&& player.getPotionHandler().hasPotionEffect(PotionTypes.LEVITATION);
|
||||||
|
|
||||||
player.getInfo().setRiptiding(CompatHandler.getINSTANCE().isRiptiding(player.getBukkitPlayer()));
|
player.getInfo().setRiptiding(CompatHandler.getINSTANCE().isRiptiding(player.getBukkitPlayer()));
|
||||||
player.getInfo().setGliding(CompatHandler.getINSTANCE().isGliding(player.getBukkitPlayer()));
|
player.getInfo().setGliding(CompatHandler.getINSTANCE().isGliding(player.getBukkitPlayer()));
|
||||||
@@ -570,7 +563,7 @@ it
|
|||||||
// generate a method that processes velocityHistory and compares to current deltaY.
|
// generate a method that processes velocityHistory and compares to current deltaY.
|
||||||
private void processVelocity() {
|
private void processVelocity() {
|
||||||
//Iterate through player.getInfo().getVelocityHistory() and compare to current deltaY.
|
//Iterate through player.getInfo().getVelocityHistory() and compare to current deltaY.
|
||||||
if(player.getInfo().isDoingVelocity()) {
|
if (player.getInfo().isDoingVelocity()) {
|
||||||
player.getInfo().getVelocity().reset();
|
player.getInfo().getVelocity().reset();
|
||||||
}
|
}
|
||||||
synchronized (player.getInfo().getVelocityHistory()) {
|
synchronized (player.getInfo().getVelocityHistory()) {
|
||||||
@@ -590,22 +583,22 @@ it
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void processBotMove(WrapperPlayClientPlayerFlying packet) {
|
private void processBotMove(WrapperPlayClientPlayerFlying packet) {
|
||||||
if(player.getMob() == null) return;
|
if (player.getMob() == null) return;
|
||||||
if (packet.hasPositionChanged() || packet.hasRotationChanged()) {
|
if (packet.hasPositionChanged() || packet.hasRotationChanged()) {
|
||||||
KLocation origin = to.getLoc().clone().add(0, 1.7, 0);
|
KLocation origin = to.getLoc().clone().add(0, 1.7, 0);
|
||||||
|
|
||||||
final double MULTIPLIER = Math.max(-0.5, Math.min(-1, -1 / (Math.abs(deltaYaw) * 0.25)));
|
final double MULTIPLIER = Math.max(-0.5, Math.min(-1, -1 / (Math.abs(deltaYaw) * 0.25)));
|
||||||
RayCollision coll = new RayCollision(origin.toVector(), origin.getDirection()
|
RayCollision coll = new RayCollision(origin.toVector(), origin.getDirection()
|
||||||
.multiply(MULTIPLIER).setY(0));
|
.multiply(MULTIPLIER).withY(0));
|
||||||
|
|
||||||
Location loc1 = coll.collisionPoint(1.5).toLocation(player.getBukkitPlayer().getWorld());
|
KLocation loc1 = new KLocation(coll.collisionPoint(1.5));
|
||||||
|
|
||||||
if (player.getInfo().botAttack.isNotPassed(7)) {
|
if (player.getInfo().botAttack.isNotPassed(7)) {
|
||||||
loc1.setY(Math.max(origin.getY() + 2, loc1.getY()));
|
loc1.setY(Math.max(origin.getY() + 2, loc1.getY()));
|
||||||
player.getMob().teleport(loc1.getX(), loc1.getY(), loc1.getZ(), loc1.getYaw(), loc1.getPitch());
|
player.getMob().teleport(loc1.getX(), loc1.getY(), loc1.getZ(), loc1.getYaw(), loc1.getPitch());
|
||||||
} else {
|
} else {
|
||||||
loc1.setY(Math.max(origin.getY() + 0.6, loc1.getY()));
|
loc1.setY(Math.max(origin.getY() + 0.6, loc1.getY()));
|
||||||
if(Math.random() > 0.2)
|
if (Math.random() > 0.2)
|
||||||
Anticheat.INSTANCE.getRunUtils().taskLaterAsync(() -> player.getMob()
|
Anticheat.INSTANCE.getRunUtils().taskLaterAsync(() -> player.getMob()
|
||||||
.teleport(loc1.getX(), loc1.getY(), loc1.getZ(), loc1.getYaw(), loc1.getPitch()), 5);
|
.teleport(loc1.getX(), loc1.getY(), loc1.getZ(), loc1.getYaw(), loc1.getPitch()), 5);
|
||||||
}
|
}
|
||||||
@@ -661,7 +654,7 @@ it
|
|||||||
public void runPositionHackFix() {
|
public void runPositionHackFix() {
|
||||||
if (sentPositionUpdate) return;
|
if (sentPositionUpdate) return;
|
||||||
|
|
||||||
player.sendPacket(new WrapperPlayServerPlayerPositionAndLook(0, Vector3d.zero(), new Vector3d(0,0,0), 0, 0,
|
player.sendPacket(new WrapperPlayServerPlayerPositionAndLook(0, Vector3d.zero(), new Vector3d(0, 0, 0), 0, 0,
|
||||||
relFlags));
|
relFlags));
|
||||||
|
|
||||||
player.getBukkitPlayer().sendMessage("§c[Anticheat] §7Position update sent to fix movement issues.");
|
player.getBukkitPlayer().sendMessage("§c[Anticheat] §7Position update sent to fix movement issues.");
|
||||||
@@ -725,10 +718,10 @@ it
|
|||||||
packet.getYaw(), packet.getPitch());
|
packet.getYaw(), packet.getPitch());
|
||||||
|
|
||||||
if (packet.getRelativeFlags().has(RelativeFlag.X)) {
|
if (packet.getRelativeFlags().has(RelativeFlag.X)) {
|
||||||
loc.add(player.getMovement().getTo().getLoc().getX(), 0 ,0);
|
loc.add(player.getMovement().getTo().getLoc().getX(), 0, 0);
|
||||||
}
|
}
|
||||||
if (packet.getRelativeFlags().has(RelativeFlag.Y)) {
|
if (packet.getRelativeFlags().has(RelativeFlag.Y)) {
|
||||||
loc.add(0, player.getMovement().getTo().getLoc().getY() ,0);
|
loc.add(0, player.getMovement().getTo().getLoc().getY(), 0);
|
||||||
}
|
}
|
||||||
if (packet.getRelativeFlags().has(RelativeFlag.Z)) {
|
if (packet.getRelativeFlags().has(RelativeFlag.Z)) {
|
||||||
loc.add(0, 0, player.getMovement().getTo().getLoc().getZ());
|
loc.add(0, 0, player.getMovement().getTo().getLoc().getZ());
|
||||||
@@ -743,7 +736,6 @@ it
|
|||||||
teleportsToConfirm++;
|
teleportsToConfirm++;
|
||||||
|
|
||||||
loc.setTimeStamp(System.currentTimeMillis());
|
loc.setTimeStamp(System.currentTimeMillis());
|
||||||
|
|
||||||
player.runKeepaliveAction(ka -> {
|
player.runKeepaliveAction(ka -> {
|
||||||
teleportsToConfirm--;
|
teleportsToConfirm--;
|
||||||
|
|
||||||
@@ -762,7 +754,7 @@ it
|
|||||||
*
|
*
|
||||||
* @param location Location
|
* @param location Location
|
||||||
*/
|
*/
|
||||||
public void moveTo(Location location) {
|
public void moveTo(KLocation location) {
|
||||||
KLocation newLoc = new KLocation(location);
|
KLocation newLoc = new KLocation(location);
|
||||||
to.getLoc().setLocation(newLoc);
|
to.getLoc().setLocation(newLoc);
|
||||||
to.getLoc().setLocation(newLoc);
|
to.getLoc().setLocation(newLoc);
|
||||||
@@ -814,7 +806,7 @@ it
|
|||||||
* @param packet WrapperPlayClientPlayerFlyingh
|
* @param packet WrapperPlayClientPlayerFlyingh
|
||||||
*/
|
*/
|
||||||
private void setTo(WrapperPlayClientPlayerFlying packet) {
|
private void setTo(WrapperPlayClientPlayerFlying packet) {
|
||||||
to.setWorld(player.getBukkitPlayer().getWorld());
|
to.setWorld(player.getWorldTracker().getCurrentWorld().get());
|
||||||
if (packet.hasPositionChanged()) {
|
if (packet.hasPositionChanged()) {
|
||||||
to.getLoc().setX(packet.getLocation().getX());
|
to.getLoc().setX(packet.getLocation().getX());
|
||||||
to.getLoc().setY(packet.getLocation().getY());
|
to.getLoc().setY(packet.getLocation().getY());
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import com.google.common.io.ByteArrayDataInput;
|
|||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
import dev.brighten.ac.Anticheat;
|
import dev.brighten.ac.Anticheat;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
|
import dev.brighten.ac.data.info.PlayerInput;
|
||||||
|
import dev.brighten.ac.data.obj.Pose;
|
||||||
import dev.brighten.ac.handler.entity.FakeMob;
|
import dev.brighten.ac.handler.entity.FakeMob;
|
||||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||||
import dev.brighten.ac.packet.PlayerCapabilities;
|
import dev.brighten.ac.packet.PlayerCapabilities;
|
||||||
@@ -26,10 +28,7 @@ import dev.brighten.ac.packet.WPacketPlayOutEntity;
|
|||||||
import dev.brighten.ac.utils.BlockUtils;
|
import dev.brighten.ac.utils.BlockUtils;
|
||||||
import dev.brighten.ac.utils.KLocation;
|
import dev.brighten.ac.utils.KLocation;
|
||||||
import dev.brighten.ac.utils.MovementUtils;
|
import dev.brighten.ac.utils.MovementUtils;
|
||||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@@ -38,13 +37,14 @@ public class PacketHandler {
|
|||||||
public boolean processReceive(APlayer player, PacketReceiveEvent event) {
|
public boolean processReceive(APlayer player, PacketReceiveEvent event) {
|
||||||
long timestamp = System.currentTimeMillis();
|
long timestamp = System.currentTimeMillis();
|
||||||
Object wrapped;
|
Object wrapped;
|
||||||
if (event.getPacketType().equals(PacketType.Play.Client.PONG)
|
|
||||||
|| event.getPacketType().equals(PacketType.Play.Client.WINDOW_CONFIRMATION)) {
|
boolean cancel = false;
|
||||||
|
if (event.getPacketType().equals(PacketType.Play.Client.PONG) || event.getPacketType().equals(PacketType.Play.Client.WINDOW_CONFIRMATION)) {
|
||||||
TransactionClientWrapper packet = new TransactionClientWrapper(event);
|
TransactionClientWrapper packet = new TransactionClientWrapper(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
if(packet.getId() == 0) {
|
if (packet.getId() == 0) {
|
||||||
if (Anticheat.INSTANCE.getKeepaliveProcessor().keepAlives.get(packet.getAction()) != null) {
|
if (Anticheat.INSTANCE.getKeepaliveProcessor().keepAlives.get(packet.getAction()) != null) {
|
||||||
Anticheat.INSTANCE.getKeepaliveProcessor().addResponse(player, packet.getAction());
|
Anticheat.INSTANCE.getKeepaliveProcessor().addResponse(player, packet.getAction());
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ public class PacketHandler {
|
|||||||
synchronized (player.instantTransaction) {
|
synchronized (player.instantTransaction) {
|
||||||
var iterator = player.instantTransaction.keySet().iterator();
|
var iterator = player.instantTransaction.keySet().iterator();
|
||||||
|
|
||||||
while(iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
Short key = iterator.next();
|
Short key = iterator.next();
|
||||||
|
|
||||||
if (key > ka.id) {
|
if (key > ka.id) {
|
||||||
@@ -96,7 +96,7 @@ public class PacketHandler {
|
|||||||
|
|
||||||
synchronized (player.keepAliveLock) {
|
synchronized (player.keepAliveLock) {
|
||||||
player.keepAliveStamps.removeIf(action -> {
|
player.keepAliveStamps.removeIf(action -> {
|
||||||
if(action.stamp > ka.id) {
|
if (action.stamp > ka.id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,10 +110,17 @@ public class PacketHandler {
|
|||||||
Optional.ofNullable(player.instantTransaction.remove(packet.getAction()))
|
Optional.ofNullable(player.instantTransaction.remove(packet.getAction()))
|
||||||
.ifPresent(t -> t.two.accept(t.one));
|
.ifPresent(t -> t.two.accept(t.one));
|
||||||
}
|
}
|
||||||
} else if(event.getPacketType().equals(PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION)
|
} else if (event.getPacketType().equals(PacketType.Play.Client.PLAYER_INPUT)) {
|
||||||
|| event.getPacketType().equals(PacketType.Play.Client.PLAYER_POSITION)
|
WrapperPlayClientPlayerInput packet = new WrapperPlayClientPlayerInput(event);
|
||||||
|| event.getPacketType().equals(PacketType.Play.Client.PLAYER_ROTATION)
|
|
||||||
|| event.getPacketType().equals(PacketType.Play.Client.PLAYER_FLYING)) {
|
wrapped = packet;
|
||||||
|
|
||||||
|
player.getInfo().setSprinting(packet.isSprint());
|
||||||
|
player.getInfo().setSneaking(packet.isShift());
|
||||||
|
player.getInfo().setPlayerInput(PlayerInput.getFromPacket(packet));
|
||||||
|
|
||||||
|
player.getBukkitPlayer().sendMessage("packet: " + packet.isForward());
|
||||||
|
} else if (event.getPacketType().equals(PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION) || event.getPacketType().equals(PacketType.Play.Client.PLAYER_POSITION) || event.getPacketType().equals(PacketType.Play.Client.PLAYER_ROTATION) || event.getPacketType().equals(PacketType.Play.Client.PLAYER_FLYING)) {
|
||||||
WrapperPlayClientPlayerFlying packet = new WrapperPlayClientPlayerFlying(event);
|
WrapperPlayClientPlayerFlying packet = new WrapperPlayClientPlayerFlying(event);
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
if (player.getMovement().isExcuseNextFlying()) {
|
if (player.getMovement().isExcuseNextFlying()) {
|
||||||
@@ -127,7 +134,7 @@ public class PacketHandler {
|
|||||||
|
|
||||||
player.getLagInfo().setLastFlying(timestamp);
|
player.getLagInfo().setLastFlying(timestamp);
|
||||||
|
|
||||||
player.getEntityLocationHandler().onFlying();
|
player.getEntityTrackHandler().onFlying();
|
||||||
|
|
||||||
if (player.getPlayerVersion().isNewerThanOrEquals(ClientVersion.V_1_17)
|
if (player.getPlayerVersion().isNewerThanOrEquals(ClientVersion.V_1_17)
|
||||||
&& packet.hasPositionChanged() && packet.hasRotationChanged()
|
&& packet.hasPositionChanged() && packet.hasRotationChanged()
|
||||||
@@ -145,17 +152,17 @@ public class PacketHandler {
|
|||||||
player.getVelocityHandler().onFlyingPost(packet);
|
player.getVelocityHandler().onFlyingPost(packet);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
} else if(event.getPacketType().equals(PacketType.Play.Client.STEER_VEHICLE)) {
|
} else if (event.getPacketType().equals(PacketType.Play.Client.STEER_VEHICLE)) {
|
||||||
WrapperPlayClientSteerVehicle packet = new WrapperPlayClientSteerVehicle(event);
|
WrapperPlayClientSteerVehicle packet = new WrapperPlayClientSteerVehicle(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
// Check for isUnmount()
|
// Check for isUnmount()
|
||||||
if (player.getBukkitPlayer().isInsideVehicle() && packet.isUnmount()) {
|
if (player.getInfo().isInVehicle() && packet.isUnmount()) {
|
||||||
player.getInfo().getVehicleSwitch().reset();
|
player.getInfo().getVehicleSwitch().reset();
|
||||||
player.getInfo().setInVehicle(false);
|
player.getInfo().setInVehicle(false);
|
||||||
}
|
}
|
||||||
} else if(event.getPacketType().equals(PacketType.Play.Client.ENTITY_ACTION)) {
|
} else if (event.getPacketType().equals(PacketType.Play.Client.ENTITY_ACTION)) {
|
||||||
WrapperPlayClientEntityAction packet = new WrapperPlayClientEntityAction(event);
|
WrapperPlayClientEntityAction packet = new WrapperPlayClientEntityAction(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
@@ -178,13 +185,13 @@ public class PacketHandler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case START_FLYING_WITH_ELYTRA: {
|
case START_FLYING_WITH_ELYTRA: {
|
||||||
if(player.isGlidePossible()) {
|
if (player.isGlidePossible()) {
|
||||||
player.getInfo().setGliding(true);
|
player.getInfo().setGliding(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(event.getPacketType().equals(PacketType.Play.Client.INTERACT_ENTITY)) {
|
} else if (event.getPacketType().equals(PacketType.Play.Client.INTERACT_ENTITY)) {
|
||||||
WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
|
WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
@@ -192,39 +199,44 @@ public class PacketHandler {
|
|||||||
FakeMob mob = Anticheat.INSTANCE.getFakeTracker().getEntityById(packet.getEntityId());
|
FakeMob mob = Anticheat.INSTANCE.getFakeTracker().getEntityById(packet.getEntityId());
|
||||||
|
|
||||||
if (packet.getAction() == WrapperPlayClientInteractEntity.InteractAction.ATTACK) {
|
if (packet.getAction() == WrapperPlayClientInteractEntity.InteractAction.ATTACK) {
|
||||||
|
if (player.hitsToCancel > 0) {
|
||||||
|
player.hitsToCancel--;
|
||||||
|
cancel = true;
|
||||||
|
}
|
||||||
if (mob != null) {
|
if (mob != null) {
|
||||||
player.getEntityLocationHandler().getTargetOfFakeMob(mob.getEntityId())
|
player.getEntityTrackHandler().getTargetOfFakeMob(mob.getEntityId())
|
||||||
.ifPresent(targetId -> {
|
.ifPresent(targetId -> {
|
||||||
player.getEntityLocationHandler().removeFakeMob(targetId);
|
player.getEntityTrackHandler().removeFakeMob(targetId);
|
||||||
player.getInfo().lastFakeBotHit.reset();
|
player.getInfo().lastFakeBotHit.reset();
|
||||||
});
|
});
|
||||||
if (player.getMob().getEntityId() == packet.getEntityId()) {
|
if (player.getMob().getEntityId() == packet.getEntityId()) {
|
||||||
player.getInfo().botAttack.reset();
|
player.getInfo().botAttack.reset();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Optional<Entity> target = Anticheat.INSTANCE.getWorldInfo(player.getBukkitPlayer().getWorld()).getEntity(packet.getEntityId());
|
Optional<TrackedEntity> target = player.getWorldTracker().getCurrentWorld().get()
|
||||||
|
.getTrackedEntity(packet.getEntityId());
|
||||||
|
|
||||||
if(target.isPresent() && target.get() instanceof LivingEntity entity) {
|
if (target.isPresent() && target.get().getEntityType().isInstanceOf(EntityTypes.LIVINGENTITY)) {
|
||||||
if (player.getInfo().lastFakeBotHit.isPassed(400) && Math.random() > 0.9) {
|
if (player.getInfo().lastFakeBotHit.isPassed(400) && Math.random() > 0.9) {
|
||||||
player.getEntityLocationHandler().canCreateMob.add(entity.getEntityId());
|
player.getEntityTrackHandler().canCreateMob.add(target.get().getEntityId());
|
||||||
}
|
}
|
||||||
player.getInfo().setTarget(entity);
|
player.getInfo().setTarget(target.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
player.getInfo().lastAttack.reset();
|
player.getInfo().lastAttack.reset();
|
||||||
}
|
}
|
||||||
} else if(event.getPacketType().equals(PacketType.Play.Client.ANIMATION)) {
|
} else if (event.getPacketType().equals(PacketType.Play.Client.ANIMATION)) {
|
||||||
WrapperPlayClientAnimation packet = new WrapperPlayClientAnimation(event);
|
WrapperPlayClientAnimation packet = new WrapperPlayClientAnimation(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
if(packet.getHand() == InteractionHand.MAIN_HAND) {
|
if (packet.getHand() == InteractionHand.MAIN_HAND) {
|
||||||
long delta = timestamp - player.getInfo().lastArmSwing;
|
long delta = timestamp - player.getInfo().lastArmSwing;
|
||||||
|
|
||||||
player.getInfo().cps.add(1000D / delta, timestamp);
|
player.getInfo().cps.add(1000D / delta, timestamp);
|
||||||
player.getInfo().lastArmSwing = timestamp;
|
player.getInfo().lastArmSwing = timestamp;
|
||||||
}
|
}
|
||||||
} else if(event.getPacketType().equals(PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT)) {
|
} else if (event.getPacketType().equals(PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT)) {
|
||||||
WrapperPlayClientPlayerBlockPlacement packet = new WrapperPlayClientPlayerBlockPlacement(event);
|
WrapperPlayClientPlayerBlockPlacement packet = new WrapperPlayClientPlayerBlockPlacement(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
@@ -236,19 +248,19 @@ public class PacketHandler {
|
|||||||
// Used item
|
// Used item
|
||||||
if (pos.getX() == -1 && (pos.getY() == 255 | pos.getY() == -1) && pos.getZ() == -1
|
if (pos.getX() == -1 && (pos.getY() == 255 | pos.getY() == -1) && pos.getZ() == -1
|
||||||
&& stack.isPresent()
|
&& stack.isPresent()
|
||||||
&& BlockUtils.isUsable(SpigotConversionUtil.toBukkitItemMaterial(stack.get().getType()))) {
|
&& BlockUtils.isUsable(player.getPlayerVersion(), stack.get().getType())) {
|
||||||
player.getInfo().getLastUseItem().reset();
|
player.getInfo().getLastUseItem().reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
player.getBlockUpdateHandler().onPlace(packet);
|
player.getWorldTracker().onPlace(packet);
|
||||||
} else if(event.getPacketType().equals(PacketType.Play.Client.PLAYER_DIGGING)) {
|
} else if (event.getPacketType().equals(PacketType.Play.Client.PLAYER_DIGGING)) {
|
||||||
WrapperPlayClientPlayerDigging packet = new WrapperPlayClientPlayerDigging(event);
|
WrapperPlayClientPlayerDigging packet = new WrapperPlayClientPlayerDigging(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getInfo().getLastBlockDig().reset();
|
player.getInfo().getLastBlockDig().reset();
|
||||||
player.getBlockUpdateHandler().onDig(packet);
|
player.getWorldTracker().onDig(packet);
|
||||||
} else if(event.getPacketType().equals(PacketType.Play.Client.CLIENT_STATUS)) {
|
} else if (event.getPacketType().equals(PacketType.Play.Client.CLIENT_STATUS)) {
|
||||||
WrapperPlayClientClientStatus packet = new WrapperPlayClientClientStatus(event);
|
WrapperPlayClientClientStatus packet = new WrapperPlayClientClientStatus(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
@@ -258,10 +270,10 @@ public class PacketHandler {
|
|||||||
player.getInfo().lastInventoryOpen.reset();
|
player.getInfo().lastInventoryOpen.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if(event.getPacketType().equals(PacketType.Play.Client.CLOSE_WINDOW)) {
|
} else if (event.getPacketType().equals(PacketType.Play.Client.CLOSE_WINDOW)) {
|
||||||
wrapped = new WrapperPlayClientCloseWindow(event);
|
wrapped = new WrapperPlayClientCloseWindow(event);
|
||||||
player.getInfo().setInventoryOpen(false);
|
player.getInfo().setInventoryOpen(false);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Client.PLUGIN_MESSAGE) {
|
} else if (event.getPacketType().equals(PacketType.Play.Client.PLUGIN_MESSAGE)) {
|
||||||
WrapperPlayClientPluginMessage packet = new WrapperPlayClientPluginMessage(event);
|
WrapperPlayClientPluginMessage packet = new WrapperPlayClientPluginMessage(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
@@ -286,7 +298,7 @@ public class PacketHandler {
|
|||||||
+ ": " + wrapped);
|
+ ": " + wrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
return player.getCheckHandler().callSyncPacket(wrapped, timestamp);
|
return cancel || player.getCheckHandler().callSyncPacket(wrapped, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean processSend(APlayer player, PacketSendEvent event) {
|
public boolean processSend(APlayer player, PacketSendEvent event) {
|
||||||
@@ -309,30 +321,36 @@ public class PacketHandler {
|
|||||||
player.getInfo().getPossibleCapabilities().clear();
|
player.getInfo().getPossibleCapabilities().clear();
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
|
} else if(event.getPacketType() == PacketType.Play.Server.UPDATE_ATTRIBUTES) {
|
||||||
|
WrapperPlayServerUpdateAttributes packet = new WrapperPlayServerUpdateAttributes(event);
|
||||||
|
|
||||||
|
wrapped = packet;
|
||||||
|
|
||||||
|
player.getEntityTrackHandler().updateAttributes(packet);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.BLOCK_CHANGE) {
|
} else if(event.getPacketType() == PacketType.Play.Server.BLOCK_CHANGE) {
|
||||||
WrapperPlayServerBlockChange packet = new WrapperPlayServerBlockChange(event);
|
WrapperPlayServerBlockChange packet = new WrapperPlayServerBlockChange(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getBlockUpdateHandler().runUpdate(packet);
|
player.getWorldTracker().runUpdate(packet);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.MULTI_BLOCK_CHANGE) {
|
} else if(event.getPacketType() == PacketType.Play.Server.MULTI_BLOCK_CHANGE) {
|
||||||
WrapperPlayServerMultiBlockChange packet = new WrapperPlayServerMultiBlockChange(event);
|
WrapperPlayServerMultiBlockChange packet = new WrapperPlayServerMultiBlockChange(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getBlockUpdateHandler().runUpdate(packet);
|
player.getWorldTracker().runUpdate(packet);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.CHUNK_DATA) {
|
} else if(event.getPacketType() == PacketType.Play.Server.CHUNK_DATA) {
|
||||||
WrapperPlayServerChunkData packet = new WrapperPlayServerChunkData(event);
|
WrapperPlayServerChunkData packet = new WrapperPlayServerChunkData(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getBlockUpdateHandler().runUpdate(packet);
|
player.getWorldTracker().runUpdate(packet);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.MAP_CHUNK_BULK) {
|
} else if(event.getPacketType() == PacketType.Play.Server.MAP_CHUNK_BULK) {
|
||||||
WrapperPlayServerChunkDataBulk packet = new WrapperPlayServerChunkDataBulk(event);
|
WrapperPlayServerChunkDataBulk packet = new WrapperPlayServerChunkDataBulk(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getBlockUpdateHandler().runUpdate(packet);
|
player.getWorldTracker().runUpdate(packet);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_EFFECT) {
|
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_EFFECT) {
|
||||||
WrapperPlayServerEntityEffect packet = new WrapperPlayServerEntityEffect(event);
|
WrapperPlayServerEntityEffect packet = new WrapperPlayServerEntityEffect(event);
|
||||||
|
|
||||||
@@ -394,18 +412,19 @@ public class PacketHandler {
|
|||||||
} else if(event.getPacketType() == PacketType.Play.Server.RESPAWN) {
|
} else if(event.getPacketType() == PacketType.Play.Server.RESPAWN) {
|
||||||
wrapped = new WrapperPlayServerRespawn(event);
|
wrapped = new WrapperPlayServerRespawn(event);
|
||||||
if(player.getPlayerVersion().isOlderThan(ClientVersion.V_1_14)) {
|
if(player.getPlayerVersion().isOlderThan(ClientVersion.V_1_14)) {
|
||||||
player.runKeepaliveAction(k -> player.getBukkitPlayer().setSprinting(false), 1);
|
player.runKeepaliveAction(k -> player.getInfo().setSprinting(false), 1);
|
||||||
}
|
}
|
||||||
player.runKeepaliveAction(ka -> player.getInfo().lastRespawn.reset());
|
player.runKeepaliveAction(ka -> {
|
||||||
player.runKeepaliveAction(ka -> player.getBlockUpdateHandler()
|
player.getInfo().lastRespawn.reset();
|
||||||
.setMinHeight(player.getDimensionType()));
|
player.getInfo().setPose(Pose.STANDING);
|
||||||
|
});
|
||||||
|
player.runKeepaliveAction(ka -> player.getWorldTracker()
|
||||||
|
.onRespawn((WrapperPlayServerRespawn) wrapped));
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.PLAYER_POSITION_AND_LOOK) {
|
} else if(event.getPacketType() == PacketType.Play.Server.PLAYER_POSITION_AND_LOOK) {
|
||||||
WrapperPlayServerPlayerPositionAndLook packet = new WrapperPlayServerPlayerPositionAndLook(event);
|
WrapperPlayServerPlayerPositionAndLook packet = new WrapperPlayServerPlayerPositionAndLook(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.runKeepaliveAction(ka ->
|
|
||||||
player.getBlockUpdateHandler().setMinHeight(player.getDimensionType()));
|
|
||||||
player.getMovement().addPosition(packet);
|
player.getMovement().addPosition(packet);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.ATTACH_ENTITY) {
|
} else if(event.getPacketType() == PacketType.Play.Server.ATTACH_ENTITY) {
|
||||||
WrapperPlayServerAttachEntity packet = new WrapperPlayServerAttachEntity(event);
|
WrapperPlayServerAttachEntity packet = new WrapperPlayServerAttachEntity(event);
|
||||||
@@ -423,37 +442,37 @@ public class PacketHandler {
|
|||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getEntityLocationHandler().onEntityDestroy(packet);
|
player.getEntityTrackHandler().onEntityDestroy(packet);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_TELEPORT) {
|
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_TELEPORT) {
|
||||||
WrapperPlayServerEntityTeleport packet = new WrapperPlayServerEntityTeleport(event);
|
WrapperPlayServerEntityTeleport packet = new WrapperPlayServerEntityTeleport(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getEntityLocationHandler().onTeleportSent(packet);
|
player.getEntityTrackHandler().onTeleportSent(packet);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_MOVEMENT) {
|
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_MOVEMENT) {
|
||||||
WrapperPlayServerEntityMovement packet = new WrapperPlayServerEntityMovement(event);
|
WrapperPlayServerEntityMovement packet = new WrapperPlayServerEntityMovement(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getEntityLocationHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
player.getEntityTrackHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_RELATIVE_MOVE) {
|
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_RELATIVE_MOVE) {
|
||||||
WrapperPlayServerEntityRelativeMove packet = new WrapperPlayServerEntityRelativeMove(event);
|
WrapperPlayServerEntityRelativeMove packet = new WrapperPlayServerEntityRelativeMove(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getEntityLocationHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
player.getEntityTrackHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_ROTATION) {
|
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_ROTATION) {
|
||||||
WrapperPlayServerEntityRotation packet = new WrapperPlayServerEntityRotation(event);
|
WrapperPlayServerEntityRotation packet = new WrapperPlayServerEntityRotation(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getEntityLocationHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
player.getEntityTrackHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_RELATIVE_MOVE_AND_ROTATION) {
|
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_RELATIVE_MOVE_AND_ROTATION) {
|
||||||
WrapperPlayServerEntityRelativeMoveAndRotation packet = new WrapperPlayServerEntityRelativeMoveAndRotation(event);
|
WrapperPlayServerEntityRelativeMoveAndRotation packet = new WrapperPlayServerEntityRelativeMoveAndRotation(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getEntityLocationHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
player.getEntityTrackHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_ENTITY) {
|
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_ENTITY) {
|
||||||
WrapperPlayServerSpawnEntity packet = new WrapperPlayServerSpawnEntity(event);
|
WrapperPlayServerSpawnEntity packet = new WrapperPlayServerSpawnEntity(event);
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
@@ -462,7 +481,7 @@ public class PacketHandler {
|
|||||||
double y = packet.getPosition().getY();
|
double y = packet.getPosition().getY();
|
||||||
double z = packet.getPosition().getZ();
|
double z = packet.getPosition().getZ();
|
||||||
|
|
||||||
player.getEntityLocationHandler().getTrackedEntities().put(packet.getEntityId(),
|
player.getWorldTracker().getCurrentWorld().get().getTrackedEntities().put(packet.getEntityId(),
|
||||||
new TrackedEntity(packet.getEntityId(), packet.getEntityType(),
|
new TrackedEntity(packet.getEntityId(), packet.getEntityType(),
|
||||||
new KLocation(x, y, z, packet.getYaw(), packet.getPitch())));
|
new KLocation(x, y, z, packet.getYaw(), packet.getPitch())));
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_LIVING_ENTITY) {
|
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_LIVING_ENTITY) {
|
||||||
@@ -474,7 +493,7 @@ public class PacketHandler {
|
|||||||
double y = packet.getPosition().getY();
|
double y = packet.getPosition().getY();
|
||||||
double z = packet.getPosition().getZ();
|
double z = packet.getPosition().getZ();
|
||||||
|
|
||||||
player.getEntityLocationHandler().getTrackedEntities().put(packet.getEntityId(),
|
player.getWorldTracker().getCurrentWorld().get().getTrackedEntities().put(packet.getEntityId(),
|
||||||
new TrackedEntity(packet.getEntityId(), packet.getEntityType(),
|
new TrackedEntity(packet.getEntityId(), packet.getEntityType(),
|
||||||
new KLocation(x, y, z, packet.getYaw(), packet.getPitch())));
|
new KLocation(x, y, z, packet.getYaw(), packet.getPitch())));
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_PLAYER) {
|
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_PLAYER) {
|
||||||
@@ -487,7 +506,7 @@ public class PacketHandler {
|
|||||||
double z = packet.getPosition().getZ();
|
double z = packet.getPosition().getZ();
|
||||||
|
|
||||||
|
|
||||||
player.getEntityLocationHandler().getTrackedEntities().put(packet.getEntityId(),
|
player.getWorldTracker().getCurrentWorld().get().getTrackedEntities().put(packet.getEntityId(),
|
||||||
new TrackedEntity(packet.getEntityId(), EntityTypes.PLAYER,
|
new TrackedEntity(packet.getEntityId(), EntityTypes.PLAYER,
|
||||||
new KLocation(x, y, z, packet.getYaw(),packet.getPitch())));
|
new KLocation(x, y, z, packet.getYaw(),packet.getPitch())));
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_PAINTING) {
|
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_PAINTING) {
|
||||||
@@ -499,14 +518,14 @@ public class PacketHandler {
|
|||||||
int y = packet.getPosition().getY();
|
int y = packet.getPosition().getY();
|
||||||
int z = packet.getPosition().getZ();
|
int z = packet.getPosition().getZ();
|
||||||
|
|
||||||
player.getEntityLocationHandler().getTrackedEntities().put(packet.getEntityId(),
|
player.getWorldTracker().getCurrentWorld().get().getTrackedEntities().put(packet.getEntityId(),
|
||||||
new TrackedEntity(packet.getEntityId(), EntityTypes.PAINTING, new KLocation(x, y, z)));
|
new TrackedEntity(packet.getEntityId(), EntityTypes.PAINTING, new KLocation(x, y, z)));
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_POSITION_SYNC) {
|
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_POSITION_SYNC) {
|
||||||
WrapperPlayServerEntityPositionSync packet = new WrapperPlayServerEntityPositionSync(event);
|
WrapperPlayServerEntityPositionSync packet = new WrapperPlayServerEntityPositionSync(event);
|
||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getEntityLocationHandler().onPositionSync(packet);
|
player.getEntityTrackHandler().onPositionSync(packet);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_METADATA) {
|
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_METADATA) {
|
||||||
wrapped = new WrapperPlayServerEntityMetadata(event);
|
wrapped = new WrapperPlayServerEntityMetadata(event);
|
||||||
}else if(event.getPacketType() == PacketType.Play.Server.DESTROY_ENTITIES) {
|
}else if(event.getPacketType() == PacketType.Play.Server.DESTROY_ENTITIES) {
|
||||||
@@ -514,7 +533,7 @@ public class PacketHandler {
|
|||||||
|
|
||||||
wrapped = packet;
|
wrapped = packet;
|
||||||
|
|
||||||
player.getEntityLocationHandler().onEntityDestroy(packet);
|
player.getEntityTrackHandler().onEntityDestroy(packet);
|
||||||
} else if(event.getPacketType() == PacketType.Play.Server.CLOSE_WINDOW) {
|
} else if(event.getPacketType() == PacketType.Play.Server.CLOSE_WINDOW) {
|
||||||
wrapped = new WrapperPlayServerCloseWindow(event);
|
wrapped = new WrapperPlayServerCloseWindow(event);
|
||||||
player.runKeepaliveAction(ka -> player.getInfo().setInventoryOpen(false));
|
player.runKeepaliveAction(ka -> player.getInfo().setInventoryOpen(false));
|
||||||
|
|||||||
@@ -1,59 +1,118 @@
|
|||||||
package dev.brighten.ac.handler;
|
package dev.brighten.ac.handler;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.potion.PotionType;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEffect;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEffect;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
|
import dev.brighten.ac.utils.KPotionEffect;
|
||||||
|
import dev.brighten.ac.utils.KProperties;
|
||||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||||
import org.bukkit.potion.PotionEffect;
|
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
public class PotionHandler {
|
public class PotionHandler {
|
||||||
private final APlayer data;
|
private final APlayer data;
|
||||||
|
|
||||||
public List<PotionEffect> potionEffects = new CopyOnWriteArrayList<>();
|
private final List<KPotionEffect> potionEffects = new ArrayList<>();
|
||||||
|
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
public PotionHandler(APlayer data) {
|
public PotionHandler(APlayer data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
|
||||||
potionEffects.addAll(data.getBukkitPlayer().getActivePotionEffects());
|
lock.writeLock().lock();
|
||||||
|
|
||||||
|
try {
|
||||||
|
data.getBukkitPlayer().getActivePotionEffects().stream()
|
||||||
|
.map(pe ->
|
||||||
|
new KPotionEffect(
|
||||||
|
SpigotConversionUtil.fromBukkitPotionEffectType(pe.getType()),
|
||||||
|
KProperties.fromBukkit(pe)
|
||||||
|
))
|
||||||
|
.forEach(potionEffects::add);
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onFlying(WrapperPlayClientPlayerFlying packet) {
|
public void onFlying(WrapperPlayClientPlayerFlying packet) {
|
||||||
for (PotionEffect effect : potionEffects) {
|
lock.readLock().lock();
|
||||||
if(data.getBukkitPlayer().hasPotionEffect(effect.getType())) continue;
|
try {
|
||||||
|
for (KPotionEffect effect : potionEffects) {
|
||||||
|
lock.readLock().lock();
|
||||||
|
|
||||||
data.runKeepaliveAction(d -> data.getPotionHandler().potionEffects.remove(effect));
|
try {
|
||||||
|
if (data.getBukkitPlayer().hasPotionEffect(SpigotConversionUtil.toBukkitPotionEffectType(effect.potionType()))) continue;
|
||||||
|
|
||||||
|
data.runKeepaliveAction(d -> {
|
||||||
|
lock.writeLock().lock();
|
||||||
|
try {
|
||||||
|
data.getPotionHandler().potionEffects.remove(effect);
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPotionEffect(WrapperPlayServerEntityEffect packet) {
|
public void onPotionEffect(WrapperPlayServerEntityEffect packet) {
|
||||||
data.runKeepaliveAction(d -> {
|
data.runKeepaliveAction(d -> {
|
||||||
var type = SpigotConversionUtil.toBukkitPotionEffectType(packet.getPotionType());
|
var type = packet.getPotionType();
|
||||||
data.getPotionHandler().potionEffects.stream().filter(pe -> pe.getType().equals(type))
|
lock.writeLock().lock();
|
||||||
.forEach(data.getPotionHandler().potionEffects::remove);
|
try {
|
||||||
data.getPotionHandler().potionEffects
|
data.getPotionHandler().potionEffects.removeIf(pe -> pe.potionType().equals(type));
|
||||||
.add(new PotionEffect(type, packet.getEffectDurationTicks(), packet.getEffectAmplifier(),
|
data.getPotionHandler().potionEffects
|
||||||
packet.isAmbient()));
|
.add(new KPotionEffect(type, new KProperties(packet.getEffectAmplifier()
|
||||||
|
, packet.getEffectDurationTicks(),
|
||||||
|
packet.isAmbient(), packet.isVisible(), packet.isShowIcon(), null)));
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPotionEffect(PotionEffectType type) {
|
public boolean hasPotionEffect(PotionType type) {
|
||||||
for (PotionEffect potionEffect : potionEffects) {
|
lock.readLock().lock();
|
||||||
if(potionEffect.getType().equals(type))
|
try {
|
||||||
return true;
|
for (KPotionEffect potionEffect : potionEffects) {
|
||||||
|
if (potionEffect.potionType().equals(type))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<PotionEffect> getEffectByType(PotionEffectType type) {
|
public Optional<KPotionEffect> getEffectByType(PotionType type) {
|
||||||
for (PotionEffect potionEffect : potionEffects) {
|
lock.readLock().lock();
|
||||||
if(potionEffect.getType().equals(type))
|
try {
|
||||||
return Optional.of(potionEffect);
|
for (KPotionEffect potionEffect : potionEffects) {
|
||||||
|
if (potionEffect.potionType().equals(type))
|
||||||
|
return Optional.of(potionEffect);
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public List<KPotionEffect> getPotionEffects() {
|
||||||
|
lock.readLock().lock();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new ArrayList<>(potionEffects);
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package dev.brighten.ac.handler;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import me.hydro.emulator.util.mcp.MathHelper;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class ValuedAttribute {
|
||||||
|
private final Attribute attribute;
|
||||||
|
@Setter
|
||||||
|
private WrapperPlayServerUpdateAttributes.Property property;
|
||||||
|
private double value;
|
||||||
|
|
||||||
|
public ValuedAttribute(Attribute attribute) {
|
||||||
|
this.attribute = attribute;
|
||||||
|
this.value = attribute.getDefaultValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateAttribute(WrapperPlayServerUpdateAttributes.Property property) {
|
||||||
|
this.property = property;
|
||||||
|
|
||||||
|
double multiplier = 1, additional = 0, base = 0;
|
||||||
|
for (WrapperPlayServerUpdateAttributes.PropertyModifier modifier : property.getModifiers()) {
|
||||||
|
switch (modifier.getOperation()) {
|
||||||
|
case ADDITION -> additional += modifier.getAmount();
|
||||||
|
case MULTIPLY_BASE -> base += modifier.getAmount();
|
||||||
|
case MULTIPLY_TOTAL -> multiplier*= (1 + modifier.getAmount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.value = MathHelper.clamp_double((property.getValue() + additional) * (1 - base) * multiplier,
|
||||||
|
attribute.getMinValue(), attribute.getMaxValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof ValuedAttribute that)) return false;
|
||||||
|
return Objects.equals(attribute, that.attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(attribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,67 +1,68 @@
|
|||||||
package dev.brighten.ac.handler.block;
|
package dev.brighten.ac.handler.block;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEvents;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||||
import com.github.retrooper.packetevents.protocol.player.DiggingAction;
|
import com.github.retrooper.packetevents.protocol.player.DiggingAction;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||||
import com.github.retrooper.packetevents.protocol.world.chunk.BaseChunk;
|
import com.github.retrooper.packetevents.protocol.world.chunk.BaseChunk;
|
||||||
import com.github.retrooper.packetevents.protocol.world.chunk.Column;
|
import com.github.retrooper.packetevents.protocol.world.chunk.Column;
|
||||||
import com.github.retrooper.packetevents.protocol.world.chunk.TileEntity;
|
import com.github.retrooper.packetevents.protocol.world.chunk.TileEntity;
|
||||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_16.Chunk_v1_9;
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_7.Chunk_v1_7;
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_8.Chunk_v1_8;
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v_1_18.Chunk_v1_18;
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.chunk.palette.PaletteType;
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.dimension.DimensionType;
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
|
||||||
import com.github.retrooper.packetevents.util.Vector3d;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerBlockPlacement;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerBlockPlacement;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging;
|
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBlockChange;
|
import com.github.retrooper.packetevents.wrapper.play.server.*;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChunkData;
|
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChunkDataBulk;
|
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerMultiBlockChange;
|
|
||||||
import dev.brighten.ac.Anticheat;
|
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.utils.BlockUtils;
|
import dev.brighten.ac.utils.KLocation;
|
||||||
import dev.brighten.ac.utils.Materials;
|
import dev.brighten.ac.utils.Materials;
|
||||||
import dev.brighten.ac.utils.XMaterial;
|
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
|
||||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import me.hydro.emulator.util.mcp.MathHelper;
|
|
||||||
import org.bukkit.Chunk;
|
import java.util.ArrayList;
|
||||||
import org.bukkit.Location;
|
import java.util.HashMap;
|
||||||
import org.bukkit.Material;
|
import java.util.Map;
|
||||||
import org.bukkit.World;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.BlockFace;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class BlockUpdateHandler {
|
public class BlockUpdateHandler {
|
||||||
// Array dimensions: 64×64 covers a render distance of up to 32 chunks without
|
|
||||||
// collision. Index = (chunkX & MASK) * SIZE + (chunkZ & MASK); stored KColumn
|
|
||||||
// x/z are chunk coordinates and are validated on every lookup.
|
|
||||||
private static final int CHUNK_ARRAY_BITS = 6; // 2^6 = 64 per axis
|
|
||||||
private static final int CHUNK_ARRAY_SIZE = 1 << CHUNK_ARRAY_BITS; // 64
|
|
||||||
private static final int CHUNK_ARRAY_MASK = CHUNK_ARRAY_SIZE - 1; // 63
|
|
||||||
private final KColumn[] chunks = new KColumn[CHUNK_ARRAY_SIZE * CHUNK_ARRAY_SIZE];
|
|
||||||
|
|
||||||
private final APlayer player;
|
private final APlayer player;
|
||||||
|
private final Map<String, World> worlds = new HashMap<>();
|
||||||
|
@Getter
|
||||||
|
private AtomicReference<World> currentWorld = new AtomicReference<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all chunks when the player changes worlds
|
* Clear all chunks when the player changes worlds
|
||||||
*/
|
*/
|
||||||
public void onWorldChange() {
|
public void onRespawn(WrapperPlayServerRespawn respawn) {
|
||||||
synchronized (chunks) {
|
respawn.getWorldName()
|
||||||
java.util.Arrays.fill(chunks, null);
|
.filter(name -> !name.equals(currentWorld.get().getName()))
|
||||||
}
|
.ifPresent(worldName -> {
|
||||||
|
currentWorld.set(getWorldByName(worldName));
|
||||||
|
player.getMob().despawn();
|
||||||
|
|
||||||
setMinHeight(player.getDimensionType());
|
player.runKeepaliveAction(ka -> {
|
||||||
|
KLocation origin = player.getMovement().getTo().getLoc().add(0, 1.7, 0);
|
||||||
|
|
||||||
|
RayCollision coll = new RayCollision(origin.toVector(), origin.getDirection().multiply(-1));
|
||||||
|
|
||||||
|
Vector3d loc1 = coll.collisionPoint(1.2);
|
||||||
|
player.getMob().spawn(true, new KLocation(loc1), new ArrayList<>(), player);
|
||||||
|
}, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private World getWorldByName(String name) {
|
||||||
|
return worlds.values().stream()
|
||||||
|
.filter(world -> world.getName().equals(name))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(worlds.put(name, new World(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,25 +73,30 @@ public class BlockUpdateHandler {
|
|||||||
public void onPlace(WrapperPlayClientPlayerBlockPlacement place) {
|
public void onPlace(WrapperPlayClientPlayerBlockPlacement place) {
|
||||||
player.getInfo().lastBlockUpdate.reset();
|
player.getInfo().lastBlockUpdate.reset();
|
||||||
// Could not possibly be a block placement as it's not a block a player is holding.
|
// Could not possibly be a block placement as it's not a block a player is holding.
|
||||||
IntVector pos = new IntVector(place.getBlockPosition());
|
Vector3i pos = place.getBlockPosition();
|
||||||
|
|
||||||
// Some dumbass shit I have to do because Minecraft with Lilypads
|
// Some dumbass shit I have to do because Minecraft with Lilypads
|
||||||
if (place.getItemStack().isPresent()
|
if (place.getItemStack().isPresent()
|
||||||
&& BlockUtils.getXMaterial(place.getItemStack().get().getType()).equals(XMaterial.LILY_PAD)) {
|
&& place.getItemStack().get().getType().equals(ItemTypes.LILY_PAD)) {
|
||||||
RayCollision rayCollision = new RayCollision(player.getBukkitPlayer().getEyeLocation().toVector(),
|
RayCollision rayCollision = new RayCollision(player.getMovement().getTo().getLoc()
|
||||||
player.getBukkitPlayer().getLocation().getDirection());
|
.add(0, player.getEyeHeight(), 0).toVector(),
|
||||||
|
player.getMovement().getTo().getLoc().getDirection());
|
||||||
|
//TODO Refactor this system to use just packetevents instead of this class
|
||||||
WrappedBlock block = rayCollision.getClosestBlockOfType(player, Materials.LIQUID, 5);
|
WrappedBlock block = rayCollision.getClosestBlockOfType(player, Materials.LIQUID, 5);
|
||||||
|
|
||||||
if (block != null) {
|
if (block != null) {
|
||||||
pos = new IntVector(block.getLocation().getX(), block.getLocation().getY() + 1, block.getLocation().getZ());
|
pos = new Vector3i(
|
||||||
|
block.getLocation().getX(),
|
||||||
|
block.getLocation().getY() + 1,
|
||||||
|
block.getLocation().getZ());
|
||||||
} else return;
|
} else return;
|
||||||
} // Not an actual block place, just an interact
|
} // Not an actual block place, just an interact
|
||||||
else if (pos.getX() == -1 && (pos.getY() == 255 || pos.getY() == -1) && pos.getZ() == -1) {
|
else if (pos.getX() == -1 && (pos.getY() == 255 || pos.getY() == -1) && pos.getZ() == -1) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
pos.setX(pos.getX() + place.getFace().getModX());
|
pos = pos.with(pos.getX() + place.getFace().getModX(),
|
||||||
pos.setY(pos.getY() + place.getFace().getModY());
|
pos.getY() + place.getFace().getModY(),
|
||||||
pos.setZ(pos.getZ() + place.getFace().getModZ());
|
pos.getZ() + place.getFace().getModZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
player.getInfo().getLastPlace().reset();
|
player.getInfo().getLastPlace().reset();
|
||||||
@@ -100,220 +106,16 @@ public class BlockUpdateHandler {
|
|||||||
int y = pos.getY();
|
int y = pos.getY();
|
||||||
int z = pos.getZ();
|
int z = pos.getZ();
|
||||||
|
|
||||||
var placedType = place.getItemStack().get().getType().getPlacedType();
|
if(place.getItemStack().isEmpty() || place.getItemStack().get().getType().getPlacedType() == null) {
|
||||||
if(place.getItemStack().isEmpty() || placedType == null) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBlock(x, y, z, WrappedBlockState.getDefaultState(placedType));
|
currentWorld.get().updateBlock(x, y, z,
|
||||||
|
WrappedBlockState.getDefaultState(place.getItemStack().get().getType().getPlacedType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static final WrappedBlockState airBlockState = WrappedBlockState
|
||||||
* Keep track of block diggings since the Bukkit API will be a bit behind
|
.getByGlobalId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), 0);
|
||||||
* @param x x coordinate
|
|
||||||
* @param z z coordinate
|
|
||||||
* @return the chunk at the specified coordinates
|
|
||||||
*/
|
|
||||||
public KColumn getChunk(int x, int z) {
|
|
||||||
int chunkX = x >> 4;
|
|
||||||
int chunkZ = z >> 4;
|
|
||||||
synchronized (chunks) {
|
|
||||||
int index = chunkIndex(chunkX, chunkZ);
|
|
||||||
KColumn chunk = chunks[index];
|
|
||||||
|
|
||||||
// Validate that the stored entry belongs to this chunk position
|
|
||||||
if (chunk == null || chunk.x() != chunkX || chunk.z() != chunkZ) {
|
|
||||||
chunk = getBukkitColumn(player.getBukkitPlayer().getWorld(), x, z);
|
|
||||||
|
|
||||||
if (chunk == null) {
|
|
||||||
return new KColumn(chunkX, chunkZ, new BaseChunk[maxHeight / 16]);
|
|
||||||
}
|
|
||||||
chunks[index] = chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
return chunk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int chunkIndex(int chunkX, int chunkZ) {
|
|
||||||
return (chunkX & CHUNK_ARRAY_MASK) * CHUNK_ARRAY_SIZE + (chunkZ & CHUNK_ARRAY_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
private KColumn getBukkitColumn(World world, int x, int z) {
|
|
||||||
int chunkX = x >> 4;
|
|
||||||
int chunkZ = z >> 4;
|
|
||||||
Chunk chunk = BlockUtils.getChunkAsync(world, chunkX, chunkZ).orElse(null);
|
|
||||||
|
|
||||||
if(chunk == null) {
|
|
||||||
// Handle loading on main thread
|
|
||||||
Anticheat.INSTANCE.getRunUtils().task(() -> {
|
|
||||||
int index = chunkIndex(chunkX, chunkZ);
|
|
||||||
synchronized (chunks) {
|
|
||||||
KColumn existing = chunks[index];
|
|
||||||
if (existing == null || existing.x() != chunkX || existing.z() != chunkZ) {
|
|
||||||
KColumn loaded = getBukkitColumn(world, x, z);
|
|
||||||
if (loaded != null) {
|
|
||||||
chunks[index] = loaded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
BaseChunk[] levels = new BaseChunk[world.getMaxHeight() / 16];
|
|
||||||
|
|
||||||
for(int i = 0; i < levels.length; i++) {
|
|
||||||
levels[i] = create();
|
|
||||||
}
|
|
||||||
|
|
||||||
int chunkBlockX = chunk.getX() * 16;
|
|
||||||
int chunkBlockZ = chunk.getZ() * 16;
|
|
||||||
|
|
||||||
for(int blockX = chunkBlockX; blockX < chunkBlockX + 16 ; blockX++) {
|
|
||||||
for(int blockZ = chunkBlockZ; blockZ < chunkBlockZ + 16 ; blockZ++) {
|
|
||||||
for(int blockY = minHeight ; blockY < world.getMaxHeight() ; blockY++) {
|
|
||||||
Block block = chunk.getBlock(blockX, blockY, blockZ);
|
|
||||||
|
|
||||||
if(block.getType() == null || block.getType().equals(Material.AIR)) {
|
|
||||||
continue; // Air
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseChunk baseChunk = levels[blockY >> 4];
|
|
||||||
|
|
||||||
WrappedBlockState state = SpigotConversionUtil.fromBukkitMaterialData(block.getState().getData());
|
|
||||||
|
|
||||||
baseChunk.set(blockX & 15, blockY & 15, blockZ & 15, state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new KColumn(chunkX, chunkZ, levels);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateChunk(Column chunk) {
|
|
||||||
synchronized (chunks) {
|
|
||||||
int index = chunkIndex(chunk.getX(), chunk.getZ());
|
|
||||||
chunks[index] = new KColumn(chunk.getX(), chunk.getZ(), chunk.getChunks());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BaseChunk create() {
|
|
||||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_18)) {
|
|
||||||
return new Chunk_v1_18();
|
|
||||||
} else if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
|
|
||||||
return new Chunk_v1_9(0, PaletteType.BIOME.create().paletteType.create());
|
|
||||||
} else if(PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_8)) {
|
|
||||||
return new Chunk_v1_8(false);
|
|
||||||
}
|
|
||||||
return new Chunk_v1_7(false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a block at the specified coordinates
|
|
||||||
* @param location the location of the block
|
|
||||||
* @return the block at the specified coordinates
|
|
||||||
*/
|
|
||||||
public WrappedBlock getBlock(Location location) {
|
|
||||||
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
private int minHeight = 0, maxHeight = 256;
|
|
||||||
|
|
||||||
public void setMinHeight(DimensionType type) {
|
|
||||||
minHeight = type.getMinY();
|
|
||||||
maxHeight = minHeight + type.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final WrappedBlockState airBlockState = WrappedBlockState.getByGlobalId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a block at the specified coordinates
|
|
||||||
* @param x x coordinate
|
|
||||||
* @param y y coordinate
|
|
||||||
* @param z z coordinate
|
|
||||||
* @return the block at the specified coordinates
|
|
||||||
*/
|
|
||||||
public WrappedBlock getBlock(int x, int y, int z) {
|
|
||||||
KColumn col = getChunk(x, z);
|
|
||||||
|
|
||||||
y -= minHeight;
|
|
||||||
|
|
||||||
final int worldY = y;
|
|
||||||
|
|
||||||
// Fast bounds check for absurd/invalid Y before chunk indexing
|
|
||||||
if (y < 0 || y >= (maxHeight - minHeight)) {
|
|
||||||
return new WrappedBlock(new IntVector(x, worldY, z),
|
|
||||||
StateTypes.AIR,
|
|
||||||
airBlockState);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also ensure the section index is within the cached column bounds
|
|
||||||
final int sectionIndex = y >> 4;
|
|
||||||
if (sectionIndex >= col.chunks().length) {
|
|
||||||
return new WrappedBlock(new IntVector(x, worldY, z),
|
|
||||||
StateTypes.AIR,
|
|
||||||
airBlockState);
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseChunk chunk = col.chunks()[sectionIndex];
|
|
||||||
|
|
||||||
if(chunk == null) {
|
|
||||||
//Get Bukkit Block
|
|
||||||
Block block = BlockUtils.getBlockAsync(new Location(player.getBukkitPlayer().getWorld(), x, y, z))
|
|
||||||
.orElse(null);
|
|
||||||
|
|
||||||
if(block != null) {
|
|
||||||
WrappedBlockState state = SpigotConversionUtil.fromBukkitMaterialData(block.getState().getData());
|
|
||||||
|
|
||||||
if (state.getType() == StateTypes.AIR) {
|
|
||||||
return new WrappedBlock(new IntVector(x, y + minHeight, z),
|
|
||||||
StateTypes.AIR,
|
|
||||||
airBlockState);
|
|
||||||
} else {
|
|
||||||
chunk = create();
|
|
||||||
col.chunks()[y >> 4] = chunk;
|
|
||||||
chunk.set(x & 15, y & 15, z & 15, state);
|
|
||||||
}
|
|
||||||
} else return new WrappedBlock(new IntVector(x, y, z),
|
|
||||||
StateTypes.AIR,
|
|
||||||
airBlockState);
|
|
||||||
}
|
|
||||||
|
|
||||||
WrappedBlockState state = chunk.get(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(),x & 15, y & 15, z & 15);
|
|
||||||
|
|
||||||
return new WrappedBlock(new IntVector(x, y, z),
|
|
||||||
state.getType(),
|
|
||||||
state);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a block at the specified coordinates
|
|
||||||
* @param vec the coordinates
|
|
||||||
* @return the block at the specified coordinates
|
|
||||||
*/
|
|
||||||
public WrappedBlock getBlock(IntVector vec) {
|
|
||||||
return getBlock(vec.getX(), vec.getY(), vec.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public WrappedBlock getBlock(Vector3d vec) {
|
|
||||||
return getBlock(
|
|
||||||
MathHelper.floor_double(vec.getX()),
|
|
||||||
MathHelper.floor_double(vec.getY()),
|
|
||||||
MathHelper.floor_double(vec.getZ())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a block at the specified coordinates
|
|
||||||
* @param block Grabs coordinates from @link{org.bukkit.block.Block}
|
|
||||||
* @return the block at the specified coordinates
|
|
||||||
*/
|
|
||||||
public WrappedBlock getBlock(Block block) {
|
|
||||||
return getBlock(block.getX(), block.getY(), block.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep track of block breaking since the Bukkit API will be a bit behind.
|
* Keep track of block breaking since the Bukkit API will be a bit behind.
|
||||||
@@ -324,13 +126,13 @@ public class BlockUpdateHandler {
|
|||||||
player.getInfo().lastBlockUpdate.reset();
|
player.getInfo().lastBlockUpdate.reset();
|
||||||
if (dig.getAction() == DiggingAction.FINISHED_DIGGING) {
|
if (dig.getAction() == DiggingAction.FINISHED_DIGGING) {
|
||||||
|
|
||||||
IntVector pos = new IntVector(dig.getBlockPosition());
|
Vector3i pos = dig.getBlockPosition();
|
||||||
|
|
||||||
if (pos.getX() == -1 && (pos.getY() == 255 || pos.getY() == -1) && pos.getZ() == -1) {
|
if (pos.getX() == -1 && (pos.getY() == 255 || pos.getY() == -1) && pos.getZ() == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBlock(pos.getX(), pos.getY(), pos.getZ(), airBlockState);
|
currentWorld.get().updateBlock(pos.getX(), pos.getY(), pos.getZ(), airBlockState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,9 +145,9 @@ public class BlockUpdateHandler {
|
|||||||
|
|
||||||
// Updating block information
|
// Updating block information
|
||||||
player.runKeepaliveAction(k -> {
|
player.runKeepaliveAction(k -> {
|
||||||
IntVector pos = new IntVector(packet.getBlockPosition());
|
Vector3i pos = packet.getBlockPosition();
|
||||||
|
|
||||||
updateBlock(pos.getX(), pos.getY(), pos.getZ(), packet.getBlockState());
|
currentWorld.get().updateBlock(pos.getX(), pos.getY(), pos.getZ(), packet.getBlockState());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,41 +160,20 @@ public class BlockUpdateHandler {
|
|||||||
player.runKeepaliveAction(k -> {
|
player.runKeepaliveAction(k -> {
|
||||||
for (WrapperPlayServerMultiBlockChange.EncodedBlock info : packet.getBlocks()) {
|
for (WrapperPlayServerMultiBlockChange.EncodedBlock info : packet.getBlocks()) {
|
||||||
|
|
||||||
WrappedBlockState blockState = info.getBlockState(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
WrappedBlockState blockState = info
|
||||||
|
.getBlockState(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
||||||
|
|
||||||
updateBlock(info.getX(), info.getY(), info.getZ(), blockState);
|
currentWorld.get().updateBlock(info.getX(), info.getY(), info.getZ(), blockState);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBlock(int x, int y, int z, WrappedBlockState blockState) {
|
|
||||||
KColumn col = getChunk(x, z);
|
|
||||||
|
|
||||||
int offset = y - minHeight;
|
|
||||||
|
|
||||||
if(offset < 0 || (offset >> 4) > col.chunks().length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseChunk chunk = col.chunks()[offset >> 4];
|
|
||||||
|
|
||||||
if(chunk == null) {
|
|
||||||
chunk = create();
|
|
||||||
col.chunks()[offset >> 4] = chunk;
|
|
||||||
|
|
||||||
chunk.set(player.getPlayerVersion(), 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk.set(x & 15, offset & 15, z & 15,
|
|
||||||
blockState);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep track of block updates since the Bukkit API will be a bit behind.
|
* Keep track of block updates since the Bukkit API will be a bit behind.
|
||||||
* @param chunkUpdate Wrapped PacketPlayOutMapChunk
|
* @param chunkUpdate Wrapped PacketPlayOutMapChunk
|
||||||
*/
|
*/
|
||||||
public void runUpdate(WrapperPlayServerChunkData chunkUpdate) {
|
public void runUpdate(WrapperPlayServerChunkData chunkUpdate) {
|
||||||
player.runKeepaliveAction(k -> updateChunk(chunkUpdate.getColumn()));
|
player.runKeepaliveAction(k -> currentWorld.get().updateChunk(chunkUpdate.getColumn()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runUpdate(WrapperPlayServerChunkDataBulk chunkBulk) {
|
public void runUpdate(WrapperPlayServerChunkDataBulk chunkBulk) {
|
||||||
@@ -403,9 +184,10 @@ public class BlockUpdateHandler {
|
|||||||
int x = chunkBulk.getX()[index];
|
int x = chunkBulk.getX()[index];
|
||||||
int z = chunkBulk.getZ()[index];
|
int z = chunkBulk.getZ()[index];
|
||||||
|
|
||||||
Column column = new Column(x, z, true, chunks, new TileEntity[0], chunkBulk.getBiomeData()[index]);
|
Column column = new Column(x, z, true, chunks, new TileEntity[0],
|
||||||
|
chunkBulk.getBiomeData()[index]);
|
||||||
|
|
||||||
updateChunk(column);
|
currentWorld.get().updateChunk(column);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -418,8 +200,8 @@ public class BlockUpdateHandler {
|
|||||||
* @param modZ the z modifier
|
* @param modZ the z modifier
|
||||||
* @return the block relative to the specified location
|
* @return the block relative to the specified location
|
||||||
*/
|
*/
|
||||||
public WrappedBlock getRelative(IntVector location, int modX, int modY, int modZ) {
|
public WrappedBlock getRelative(Vector3i location, int modX, int modY, int modZ) {
|
||||||
return getBlock(location.clone().add(modX, modY, modZ));
|
return currentWorld.get().getBlock(location.add(modX, modY, modZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -429,7 +211,7 @@ public class BlockUpdateHandler {
|
|||||||
* @param distance the distance
|
* @param distance the distance
|
||||||
* @return the block relative to the specified location
|
* @return the block relative to the specified location
|
||||||
*/
|
*/
|
||||||
public WrappedBlock getRelative(IntVector location, BlockFace face, int distance) {
|
public WrappedBlock getRelative(Vector3i location, BlockFace face, int distance) {
|
||||||
return getRelative(location,
|
return getRelative(location,
|
||||||
face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance);
|
face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance);
|
||||||
}
|
}
|
||||||
@@ -440,8 +222,20 @@ public class BlockUpdateHandler {
|
|||||||
* @param face the face
|
* @param face the face
|
||||||
* @return the block relative to the specified location
|
* @return the block relative to the specified location
|
||||||
*/
|
*/
|
||||||
public WrappedBlock getRelative(IntVector location, BlockFace face) {
|
public WrappedBlock getRelative(Vector3i location, BlockFace face) {
|
||||||
return getBlock(location.clone().add(face.getModX(), face.getModY(), face.getModZ()));
|
return currentWorld.get().getBlock(location.add(face.getModX(), face.getModY(), face.getModZ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrappedBlock getBlock(int x, int y, int z) {
|
||||||
|
return currentWorld.get().getBlock(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrappedBlock getBlock(KLocation location) {
|
||||||
|
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrappedBlock getBlock(Vector3i location) {
|
||||||
|
return getBlock(location.getX(), location.getY(), location.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
public record KColumn(int x, int z, BaseChunk[] chunks) {}
|
public record KColumn(int x, int z, BaseChunk[] chunks) {}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package dev.brighten.ac.handler.block;
|
package dev.brighten.ac.handler.block;
|
||||||
|
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -17,7 +19,7 @@ public class Chunk {
|
|||||||
* @param location - Location of the block
|
* @param location - Location of the block
|
||||||
* @return Optional of the block at the specified location
|
* @return Optional of the block at the specified location
|
||||||
*/
|
*/
|
||||||
public Optional<WrappedBlock> getBlockAt(IntVector location) {
|
public Optional<WrappedBlock> getBlockAt(Vector3i location) {
|
||||||
return getBlockAt(location.getX(), location.getY(), location.getZ());
|
return getBlockAt(location.getX(), location.getY(), location.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +66,18 @@ public class Chunk {
|
|||||||
* @param location - Location of the block
|
* @param location - Location of the block
|
||||||
* @param block - Block to update to
|
* @param block - Block to update to
|
||||||
*/
|
*/
|
||||||
public void updateBlock(IntVector location, WrappedBlock block) {
|
public void updateBlock(Vector3i location, WrappedBlock block) {
|
||||||
updateBlock(location.getX(), location.getY(), location.getZ(), block);
|
updateBlock(location.getX(), location.getY(), location.getZ(), block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof Chunk chunk)) return false;
|
||||||
|
return x == chunk.x && z == chunk.z && Objects.deepEquals(blocks, chunk.blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(x, z, Arrays.deepHashCode(blocks));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,186 @@
|
|||||||
|
package dev.brighten.ac.handler.block;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
|
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.chunk.BaseChunk;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.chunk.Column;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_16.Chunk_v1_9;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_7.Chunk_v1_7;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_8.Chunk_v1_8;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v_1_18.Chunk_v1_18;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.chunk.palette.PaletteType;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.dimension.DimensionType;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||||
|
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
|
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||||
|
import dev.brighten.ac.utils.KLocation;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import lombok.Getter;
|
||||||
|
import me.hydro.emulator.util.mcp.MathHelper;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class World {
|
||||||
|
private final String name;
|
||||||
|
// Array dimensions: 64×64 covers a render distance of up to 32 chunks without
|
||||||
|
// collision. Index = (chunkX & MASK) * SIZE + (chunkZ & MASK); stored KColumn
|
||||||
|
// x/z are chunk coordinates and are validated on every lookup.
|
||||||
|
private static final int CHUNK_ARRAY_BITS = 6; // 2^6 = 64 per axis
|
||||||
|
private static final int CHUNK_ARRAY_SIZE = 1 << CHUNK_ARRAY_BITS; // 64
|
||||||
|
private static final int CHUNK_ARRAY_MASK = CHUNK_ARRAY_SIZE - 1; // 63
|
||||||
|
private final BlockUpdateHandler.KColumn[] chunks = new BlockUpdateHandler.KColumn[CHUNK_ARRAY_SIZE * CHUNK_ARRAY_SIZE];
|
||||||
|
private final Map<Integer, TrackedEntity> trackedEntities = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
public World(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int minHeight = 0, maxHeight = 256;
|
||||||
|
|
||||||
|
public void setMinHeight(DimensionType type) {
|
||||||
|
minHeight = type.getMinY();
|
||||||
|
maxHeight = minHeight + type.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep track of block diggings since the Bukkit API will be a bit behind
|
||||||
|
* @param x x coordinate
|
||||||
|
* @param z z coordinate
|
||||||
|
* @return the chunk at the specified coordinates
|
||||||
|
*/
|
||||||
|
public BlockUpdateHandler.KColumn getChunk(int x, int z) {
|
||||||
|
int chunkX = x >> 4;
|
||||||
|
int chunkZ = z >> 4;
|
||||||
|
synchronized (chunks) {
|
||||||
|
int index = chunkIndex(chunkX, chunkZ);
|
||||||
|
BlockUpdateHandler.KColumn chunk = chunks[index];
|
||||||
|
|
||||||
|
// Validate that the stored entry belongs to this chunk position
|
||||||
|
if (chunk == null || chunk.x() != chunkX || chunk.z() != chunkZ) {
|
||||||
|
chunk = new BlockUpdateHandler.KColumn(chunkX, chunkZ, new BaseChunk[maxHeight / 16]);
|
||||||
|
chunks[index] = chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int chunkIndex(int chunkX, int chunkZ) {
|
||||||
|
return ((chunkX & CHUNK_ARRAY_MASK) << CHUNK_ARRAY_BITS) | (chunkZ & CHUNK_ARRAY_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateChunk(Column chunk) {
|
||||||
|
synchronized (chunks) {
|
||||||
|
int index = chunkIndex(chunk.getX(), chunk.getZ());
|
||||||
|
chunks[index] = new BlockUpdateHandler.KColumn(chunk.getX(), chunk.getZ(), chunk.getChunks());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BaseChunk create() {
|
||||||
|
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_18)) {
|
||||||
|
return new Chunk_v1_18();
|
||||||
|
} else if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
|
||||||
|
return new Chunk_v1_9(0, PaletteType.BIOME.create().paletteType.create());
|
||||||
|
} else if(PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_8)) {
|
||||||
|
return new Chunk_v1_8(false);
|
||||||
|
}
|
||||||
|
return new Chunk_v1_7(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a block at the specified coordinates
|
||||||
|
* @param location the location of the block
|
||||||
|
* @return the block at the specified coordinates
|
||||||
|
*/
|
||||||
|
public WrappedBlock getBlock(KLocation location) {
|
||||||
|
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a block at the specified coordinates
|
||||||
|
* @param x x coordinate
|
||||||
|
* @param y y coordinate
|
||||||
|
* @param z z coordinate
|
||||||
|
* @return the block at the specified coordinates
|
||||||
|
*/
|
||||||
|
public WrappedBlock getBlock(int x, int y, int z) {
|
||||||
|
BlockUpdateHandler.KColumn col = getChunk(x, z);
|
||||||
|
|
||||||
|
y -= minHeight;
|
||||||
|
|
||||||
|
if(col == null) {
|
||||||
|
return new WrappedBlock(new Vector3i(x, y, z),
|
||||||
|
StateTypes.AIR,
|
||||||
|
BlockUpdateHandler.airBlockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseChunk chunk = col.chunks().length - 1 < (y >> 4) ? null : col.chunks()[Math.max(0, (y >> 4))];
|
||||||
|
|
||||||
|
if(chunk == null) {
|
||||||
|
//Get Bukkit Block
|
||||||
|
return new WrappedBlock(new Vector3i(x, y, z),
|
||||||
|
StateTypes.AIR,
|
||||||
|
BlockUpdateHandler.airBlockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
WrappedBlockState state = chunk.get(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(),x & 15, y & 15, z & 15);
|
||||||
|
|
||||||
|
return new WrappedBlock(new Vector3i(x, y, z),
|
||||||
|
state.getType(),
|
||||||
|
state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateBlock(int x, int y, int z, WrappedBlockState blockState) {
|
||||||
|
BlockUpdateHandler.KColumn col = getChunk(x, z);
|
||||||
|
|
||||||
|
int offset = y - minHeight;
|
||||||
|
|
||||||
|
if(offset < 0 || (offset >> 4) > col.chunks().length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseChunk chunk = col.chunks()[offset >> 4];
|
||||||
|
|
||||||
|
if(chunk == null) {
|
||||||
|
chunk = create();
|
||||||
|
col.chunks()[offset >> 4] = chunk;
|
||||||
|
|
||||||
|
chunk.set(null, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk.set(x & 15, offset & 15, z & 15,
|
||||||
|
blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a block at the specified coordinates
|
||||||
|
* @param vec the coordinates
|
||||||
|
* @return the block at the specified coordinates
|
||||||
|
*/
|
||||||
|
public WrappedBlock getBlock(Vector3i vec) {
|
||||||
|
return getBlock(vec.getX(), vec.getY(), vec.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrappedBlock getBlock(Vector3d vec) {
|
||||||
|
return getBlock(
|
||||||
|
MathHelper.floor_double(vec.getX()),
|
||||||
|
MathHelper.floor_double(vec.getY()),
|
||||||
|
MathHelper.floor_double(vec.getZ())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<TrackedEntity> getTrackedEntity(int entityId) {
|
||||||
|
TrackedEntity trackedEntity = trackedEntities.get(entityId);
|
||||||
|
|
||||||
|
if(trackedEntity == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of(trackedEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,14 +2,14 @@ package dev.brighten.ac.handler.block;
|
|||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
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.StateType;
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class WrappedBlock {
|
public class WrappedBlock {
|
||||||
private IntVector location;
|
private Vector3i location;
|
||||||
private StateType type;
|
private StateType type;
|
||||||
private WrappedBlockState blockState;
|
private WrappedBlockState blockState;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
package dev.brighten.ac.handler.entity;
|
package dev.brighten.ac.handler.entity;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||||
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||||
|
import dev.brighten.ac.data.obj.Pose;
|
||||||
|
import dev.brighten.ac.handler.ValuedAttribute;
|
||||||
import dev.brighten.ac.utils.EntityLocation;
|
import dev.brighten.ac.utils.EntityLocation;
|
||||||
import dev.brighten.ac.utils.KLocation;
|
import dev.brighten.ac.utils.KLocation;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@@ -17,6 +23,8 @@ public class TrackedEntity {
|
|||||||
private KLocation location;
|
private KLocation location;
|
||||||
private EntityLocation oldEntityLocation, newEntityLocation;
|
private EntityLocation oldEntityLocation, newEntityLocation;
|
||||||
private List<FakeMob> fakeMobs = new ArrayList<>();
|
private List<FakeMob> fakeMobs = new ArrayList<>();
|
||||||
|
private Set<ValuedAttribute> attributes = new HashSet<>();
|
||||||
|
private Pose pose = Pose.STANDING;
|
||||||
|
|
||||||
public TrackedEntity(int entityId, EntityType entityType, KLocation location) {
|
public TrackedEntity(int entityId, EntityType entityType, KLocation location) {
|
||||||
this.entityId = entityId;
|
this.entityId = entityId;
|
||||||
@@ -31,4 +39,30 @@ public class TrackedEntity {
|
|||||||
newEntityLocation.yaw = location.getYaw();
|
newEntityLocation.yaw = location.getYaw();
|
||||||
newEntityLocation.pitch = location.getPitch();
|
newEntityLocation.pitch = location.getPitch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KLocation getEyeLocation() {
|
||||||
|
return new KLocation(location.getX(), location.getY() + pose.eyeHeight, location.getZ(),
|
||||||
|
location.getYaw(), location.getPitch());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValuedAttribute getAttribute(Attribute type) {
|
||||||
|
for(ValuedAttribute attribute : attributes) {
|
||||||
|
if(attribute.getAttribute().equals(type)) {
|
||||||
|
return attribute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateAttribute(WrapperPlayServerUpdateAttributes.Property property) {
|
||||||
|
ValuedAttribute attribute = getAttribute(property.getAttribute());
|
||||||
|
|
||||||
|
if(attribute == null) {
|
||||||
|
attribute = new ValuedAttribute(property.getAttribute());
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute.updateAttribute(property);
|
||||||
|
|
||||||
|
attributes.add(attribute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class KeepaliveProcessor {
|
|||||||
double dh = Math.min(value.getMovement().getDeltaXZ(), 1),
|
double dh = Math.min(value.getMovement().getDeltaXZ(), 1),
|
||||||
dy = Math.min(1, Math.abs(value.getMovement().getDeltaY()));
|
dy = Math.min(1, Math.abs(value.getMovement().getDeltaY()));
|
||||||
|
|
||||||
value.getInfo().nearbyEntities = value.getEntityLocationHandler().getTrackedEntities().values()
|
value.getInfo().nearbyEntities = value.getWorldTracker().getCurrentWorld().get().getTrackedEntities().values()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(te ->
|
.filter(te ->
|
||||||
te.getLocation().distance(value.getMovement().getTo().getLoc()) < (2 + (dh + dy) / 2))
|
te.getLocation().distance(value.getMovement().getTo().getLoc()) < (2 + (dh + dy) / 2))
|
||||||
|
|||||||
@@ -1,25 +1,8 @@
|
|||||||
package dev.brighten.ac.handler.protocol;
|
package dev.brighten.ac.handler.protocol;
|
||||||
|
|
||||||
import dev.brighten.ac.Anticheat;
|
|
||||||
import dev.brighten.ac.handler.protocol.impl.NoAPI;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.protocol.impl.ProtocolSupport;
|
|
||||||
import dev.brighten.ac.handler.protocol.impl.ViaVersionAPI;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public interface Protocol {
|
public interface Protocol {
|
||||||
int getPlayerVersion(Player player);
|
int getPlayerVersion(APlayer player);
|
||||||
|
|
||||||
static Protocol getProtocol() {
|
|
||||||
if(Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) {
|
|
||||||
Anticheat.INSTANCE.alog("Using ViaVersion for ProtocolAPI");
|
|
||||||
return new ViaVersionAPI();
|
|
||||||
} else if(Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport")) {
|
|
||||||
Anticheat.INSTANCE.alog("Using ProtocolSupport for ProtocolAPI");
|
|
||||||
return new ProtocolSupport();
|
|
||||||
} else {
|
|
||||||
Anticheat.INSTANCE.alog("Using Vanilla API for ProtocolAPI");
|
|
||||||
return new NoAPI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package dev.brighten.ac.handler.protocol.impl;
|
package dev.brighten.ac.handler.protocol.impl;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEvents;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.protocol.Protocol;
|
import dev.brighten.ac.handler.protocol.Protocol;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class NoAPI implements Protocol {
|
public class NoAPI implements Protocol {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPlayerVersion(Player player) {
|
public int getPlayerVersion(APlayer player) {
|
||||||
return PacketEvents.getAPI().getPlayerManager().getClientVersion(player).getProtocolVersion();
|
return PacketEvents.getAPI().getPlayerManager().getClientVersion(player.getBukkitPlayer()).getProtocolVersion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package dev.brighten.ac.handler.protocol.impl;
|
|
||||||
|
|
||||||
import dev.brighten.ac.handler.protocol.Protocol;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import protocolsupport.api.ProtocolSupportAPI;
|
|
||||||
|
|
||||||
public class ProtocolSupport implements Protocol {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPlayerVersion(Player player) {
|
|
||||||
return ProtocolSupportAPI.getProtocolVersion(player).getId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,16 +2,16 @@ package dev.brighten.ac.handler.protocol.impl;
|
|||||||
|
|
||||||
import com.viaversion.viaversion.api.Via;
|
import com.viaversion.viaversion.api.Via;
|
||||||
import dev.brighten.ac.Anticheat;
|
import dev.brighten.ac.Anticheat;
|
||||||
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.protocol.Protocol;
|
import dev.brighten.ac.handler.protocol.Protocol;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class ViaVersionAPI implements Protocol {
|
public class ViaVersionAPI implements Protocol {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPlayerVersion(Player player) {
|
public int getPlayerVersion(APlayer player) {
|
||||||
Anticheat.INSTANCE.alog("Getting player version for " + player.getName());
|
Anticheat.INSTANCE.alog("Getting player version for " + player.getBukkitPlayer().getName());
|
||||||
var toReturn = Via.getAPI().getPlayerVersion(player.getUniqueId());
|
var toReturn = Via.getAPI().getPlayerVersion(player.getBukkitPlayer().getUniqueId());
|
||||||
Anticheat.INSTANCE.alog("Player version for " + player.getName() + " is " + toReturn);
|
Anticheat.INSTANCE.alog("Player version for " + player.getBukkitPlayer().getName() + " is " + toReturn);
|
||||||
|
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package dev.brighten.ac.listener;
|
package dev.brighten.ac.listener;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import dev.brighten.ac.Anticheat;
|
import dev.brighten.ac.Anticheat;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.utils.KLocation;
|
import dev.brighten.ac.utils.KLocation;
|
||||||
@@ -68,14 +69,15 @@ public class GeneralListener implements Listener {
|
|||||||
|
|
||||||
Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId())
|
Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId())
|
||||||
.ifPresent(player -> {
|
.ifPresent(player -> {
|
||||||
player.getBlockUpdateHandler().onWorldChange();
|
|
||||||
|
|
||||||
// Updating bot loc when changing worlds
|
// Updating bot loc when changing worlds
|
||||||
Location origin = event.getTo().clone().add(0, 1.7, 0);
|
Location origin = event.getTo().clone().add(0, 1.7, 0);
|
||||||
|
Vector mult = origin.getDirection().multiply(-1);
|
||||||
|
|
||||||
RayCollision coll = new RayCollision(origin.toVector(), origin.getDirection().multiply(-1));
|
RayCollision coll = new RayCollision(new Vector3d(origin.getX(), origin.getY(), origin.getZ()),
|
||||||
|
new Vector3d(mult.getX(), mult.getY(), mult.getZ()));
|
||||||
|
|
||||||
Vector loc1 = coll.collisionPoint(1.2);
|
Vector3d loc1 = coll.collisionPoint(1.2);
|
||||||
|
|
||||||
Anticheat.INSTANCE.getRunUtils().taskLater(() -> {
|
Anticheat.INSTANCE.getRunUtils().taskLater(() -> {
|
||||||
player.getMob().despawn();
|
player.getMob().despawn();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package dev.brighten.ac.utils;
|
package dev.brighten.ac.utils;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.world.Direction;
|
import com.github.retrooper.packetevents.protocol.world.Direction;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -211,6 +212,14 @@ public class AxisAlignedBB {
|
|||||||
return rayTrace(origin, dir);
|
return rayTrace(origin, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vec3D rayTrace(Vector3d vorigin, Vector3d vdirection, double distance) {
|
||||||
|
Vec3D origin = new Vec3D(vorigin.getX(), vorigin.getY(), vorigin.getZ());
|
||||||
|
Vector3d direction = vdirection.multiply(distance);
|
||||||
|
Vec3D dir = origin.clone().add(direction.getX(), direction.getY(), direction.getZ());
|
||||||
|
|
||||||
|
return rayTrace(origin, dir);
|
||||||
|
}
|
||||||
|
|
||||||
public Vec3D rayTrace(Vec3D vec3d, Vec3D vec3d1) {
|
public Vec3D rayTrace(Vec3D vec3d, Vec3D vec3d1) {
|
||||||
Vec3D vec3d2 = vec3d.a(vec3d1, this.minX);
|
Vec3D vec3d2 = vec3d.a(vec3d1, this.minX);
|
||||||
Vec3D vec3d3 = vec3d.a(vec3d1, this.maxX);
|
Vec3D vec3d3 = vec3d.a(vec3d1, this.maxX);
|
||||||
|
|||||||
@@ -2,19 +2,18 @@ package dev.brighten.ac.utils;
|
|||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
||||||
|
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
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.StateTypes;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
|
||||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.Vehicle;
|
|
||||||
|
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
@@ -84,20 +83,20 @@ public class BlockUtils {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<WrappedBlock> getRelative(APlayer player, IntVector location, int modX, int modY, int modZ) {
|
public static Optional<WrappedBlock> getRelative(APlayer player, Vector3i location, int modX, int modY, int modZ) {
|
||||||
return Optional.of(player.getBlockUpdateHandler()
|
return Optional.of(player.getWorldTracker()
|
||||||
.getRelative(new IntVector(location.getX(), location.getY(), location.getZ()),
|
.getRelative(new Vector3i(location.getX(), location.getY(), location.getZ()),
|
||||||
modX, modY, modZ));
|
modX, modY, modZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<WrappedBlock> getRelative(APlayer player, IntVector location,
|
public static Optional<WrappedBlock> getRelative(APlayer player, Vector3i location,
|
||||||
com.github.retrooper.packetevents.protocol.world
|
com.github.retrooper.packetevents.protocol.world
|
||||||
.BlockFace face, int distance) {
|
.BlockFace face, int distance) {
|
||||||
return getRelative(player, location,
|
return getRelative(player, location,
|
||||||
face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance);
|
face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<WrappedBlock> getRelative(APlayer player, IntVector vector, BlockFace face) {
|
public static Optional<WrappedBlock> getRelative(APlayer player, Vector3i vector, BlockFace face) {
|
||||||
return getRelative(player, vector,
|
return getRelative(player, vector,
|
||||||
face.getModX(), face.getModY(), face.getModZ());
|
face.getModX(), face.getModY(), face.getModZ());
|
||||||
}
|
}
|
||||||
@@ -134,6 +133,12 @@ public class BlockUtils {
|
|||||||
return isUsable(getXMaterial(material));
|
return isUsable(getXMaterial(material));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isUsable(ClientVersion version, ItemType type) {
|
||||||
|
return type.hasAttribute(ItemTypes.ItemAttribute.EDIBLE)
|
||||||
|
|| (version.isOlderThan(ClientVersion.V_1_9) && type.hasAttribute(ItemTypes.ItemAttribute.SWORD))
|
||||||
|
|| type.equals(ItemTypes.SHIELD);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isUsable(XMaterial xmaterial) {
|
public static boolean isUsable(XMaterial xmaterial) {
|
||||||
if(XEDIBLE.contains(xmaterial)) return true;
|
if(XEDIBLE.contains(xmaterial)) return true;
|
||||||
return switch (xmaterial) {
|
return switch (xmaterial) {
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
package dev.brighten.ac.utils;
|
package dev.brighten.ac.utils;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEvents;
|
|
||||||
import com.github.retrooper.packetevents.protocol.particle.Particle;
|
import com.github.retrooper.packetevents.protocol.particle.Particle;
|
||||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
|
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
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.StateTypes;
|
||||||
import com.github.retrooper.packetevents.util.Vector3d;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import com.github.retrooper.packetevents.util.Vector3f;
|
import com.github.retrooper.packetevents.util.Vector3f;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerParticle;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerParticle;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
|
||||||
import dev.brighten.ac.utils.world.BlockData;
|
import dev.brighten.ac.utils.world.BlockData;
|
||||||
import dev.brighten.ac.utils.world.CollisionBox;
|
import dev.brighten.ac.utils.world.CollisionBox;
|
||||||
import dev.brighten.ac.utils.world.EntityData;
|
import dev.brighten.ac.utils.world.EntityData;
|
||||||
@@ -137,8 +136,8 @@ public class Helper {
|
|||||||
for (int x = x1; x < x2; ++x)
|
for (int x = x1; x < x2; ++x)
|
||||||
for (int y = y1 - 1; y < y2; ++y)
|
for (int y = y1 - 1; y < y2; ++y)
|
||||||
for (int z = z1; z < z2; ++z) {
|
for (int z = z1; z < z2; ++z) {
|
||||||
IntVector vec = new IntVector(x, y, z);
|
Vector3i vec = new Vector3i(x, y, z);
|
||||||
StateType type = player.getBlockUpdateHandler().getBlock(vec).getType();
|
StateType type = player.getWorldTracker().getBlock(vec).getType();
|
||||||
|
|
||||||
if (type != StateTypes.AIR && (mask == -100 || Materials.checkFlag(type, mask))) {
|
if (type != StateTypes.AIR && (mask == -100 || Materials.checkFlag(type, mask))) {
|
||||||
CollisionBox box = BlockData.getData(type)
|
CollisionBox box = BlockData.getData(type)
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package dev.brighten.ac.utils;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.potion.PotionType;
|
||||||
|
|
||||||
|
public record KPotionEffect(PotionType potionType, KProperties properties) {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package dev.brighten.ac.utils;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.potion.PotionEffect;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public record KProperties(int amplifier, int duration, boolean ambient, boolean showParticles, boolean showIcon,
|
||||||
|
@Nullable KProperties hiddenEffect) {
|
||||||
|
|
||||||
|
public PotionEffect.Properties toProperties() {
|
||||||
|
return new PotionEffect.Properties(amplifier, duration, ambient, showParticles, showIcon,
|
||||||
|
hiddenEffect == null ? null : hiddenEffect.toProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static KProperties fromBukkit(org.bukkit.potion.PotionEffect potionEffect) {
|
||||||
|
return new KProperties(potionEffect.getAmplifier(), potionEffect.getDuration(), potionEffect.isAmbient(),
|
||||||
|
potionEffect.hasParticles(), false, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import org.bukkit.Material;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
//TODO Refactor this system to use just packetevents instead of this class
|
||||||
public class Materials {
|
public class Materials {
|
||||||
private static final Map<StateType, Integer> MATERIAL_FLAGS = new HashMap<>();
|
private static final Map<StateType, Integer> MATERIAL_FLAGS = new HashMap<>();
|
||||||
|
|
||||||
@@ -31,11 +32,11 @@ public class Materials {
|
|||||||
int flag = MATERIAL_FLAGS.getOrDefault(mat, 0);
|
int flag = MATERIAL_FLAGS.getOrDefault(mat, 0);
|
||||||
|
|
||||||
//We use the one in BlockUtils also since we can't trust Material to include everything.
|
//We use the one in BlockUtils also since we can't trust Material to include everything.
|
||||||
if (mat.isSolid() || mat.getName().contains("COMPARATOR") || mat.getName().contains("DIODE")) {
|
if (mat.isSolid() || mat.getName().contains("COMPARATOR") || mat.getName().contains("DIODE") || mat.isBlocking()) {
|
||||||
flag |= SOLID;
|
flag |= SOLID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(BlockData.getData(mat).getDefaultBox() instanceof NoCollisionBox)) {
|
if(!(BlockData.getData(mat).getDefaultBox() instanceof NoCollisionBox) || mat.isBlocking()) {
|
||||||
flag |= COLLIDABLE;
|
flag |= COLLIDABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class MiscUtils {
|
|||||||
for(int x = startX ; x < endX ; x++) {
|
for(int x = startX ; x < endX ; x++) {
|
||||||
for(int y = startY ; y < endY ; y++) {
|
for(int y = startY ; y < endY ; y++) {
|
||||||
for(int z = startZ ; z < endZ ; z++) {
|
for(int z = startZ ; z < endZ ; z++) {
|
||||||
StateType type = player.getBlockUpdateHandler().getBlock(x, y, z).getType();
|
StateType type = player.getWorldTracker().getBlock(x, y, z).getType();
|
||||||
|
|
||||||
if(Materials.checkFlag(type, bitmask))
|
if(Materials.checkFlag(type, bitmask))
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class MovementUtils {
|
|||||||
public static double getJumpHeight(APlayer data) {
|
public static double getJumpHeight(APlayer data) {
|
||||||
float baseHeight = 0.42f;
|
float baseHeight = 0.42f;
|
||||||
|
|
||||||
baseHeight+= data.getInfo().groundJumpBoost.map(ef -> ef.getAmplifier() + 1)
|
baseHeight+= data.getInfo().groundJumpBoost.map(ef -> ef.properties().amplifier() + 1)
|
||||||
.orElse(0) * 0.1f;
|
.orElse(0) * 0.1f;
|
||||||
|
|
||||||
return baseHeight;
|
return baseHeight;
|
||||||
@@ -38,7 +38,7 @@ public class MovementUtils {
|
|||||||
int i = MathHelper.floor_double(data.getMovement().getTo().getLoc().getX());
|
int i = MathHelper.floor_double(data.getMovement().getTo().getLoc().getX());
|
||||||
int j = MathHelper.floor_double(data.getMovement().getTo().getBox().minY);
|
int j = MathHelper.floor_double(data.getMovement().getTo().getBox().minY);
|
||||||
int k = MathHelper.floor_double(data.getMovement().getTo().getLoc().getZ());
|
int k = MathHelper.floor_double(data.getMovement().getTo().getLoc().getZ());
|
||||||
WrappedBlock block = data.getBlockUpdateHandler().getBlock(i, j, k);
|
WrappedBlock block = data.getWorldTracker().getBlock(i, j, k);
|
||||||
|
|
||||||
return Materials.checkFlag(block.getType(), Materials.LADDER);
|
return Materials.checkFlag(block.getType(), Materials.LADDER);
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ public class IntVector implements Cloneable {
|
|||||||
return new Vector(x, y, z);
|
return new Vector(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector3i toVector3i() {
|
||||||
|
return new Vector3i(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[" + x + ", " + y + ", " + z + "]";
|
return "[" + x + ", " + y + ", " + z + "]";
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ package dev.brighten.ac.utils.math;
|
|||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEvents;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
|
import dev.brighten.ac.utils.KLocation;
|
||||||
|
import dev.brighten.ac.utils.MathUtils;
|
||||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -15,15 +18,15 @@ public class RayTrace {
|
|||||||
|
|
||||||
//origin = start position
|
//origin = start position
|
||||||
//direction = direction in which the raytrace will go
|
//direction = direction in which the raytrace will go
|
||||||
Vector origin, direction;
|
Vector3d origin, direction;
|
||||||
|
|
||||||
public RayTrace(Vector origin, Vector direction) {
|
public RayTrace(Vector3d origin, Vector3d direction) {
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
//general intersection detection
|
//general intersection detection
|
||||||
public static boolean intersects(Vector position, Vector min, Vector max) {
|
public static boolean intersects(Vector3d position, Vector3d min, Vector3d max) {
|
||||||
if (position.getX() < min.getX() || position.getX() > max.getX()) {
|
if (position.getX() < min.getX() || position.getX() > max.getX()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (position.getY() < min.getY() || position.getY() > max.getY()) {
|
} else if (position.getY() < min.getY() || position.getY() > max.getY()) {
|
||||||
@@ -32,27 +35,27 @@ public class RayTrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//get a point on the raytrace at X blocks away
|
//get a point on the raytrace at X blocks away
|
||||||
public Vector getPostion(double blocksAway) {
|
public Vector3d getPostion(double blocksAway) {
|
||||||
return origin.clone().add(direction.clone().multiply(blocksAway));
|
return origin.add(direction.multiply(blocksAway));
|
||||||
}
|
}
|
||||||
|
|
||||||
//checks if a position is on contained within the position
|
//checks if a position is on contained within the position
|
||||||
public boolean isOnLine(Vector position) {
|
public boolean isOnLine(Vector3d position) {
|
||||||
double t = (position.getX() - origin.getX()) / direction.getX();
|
double t = (position.getX() - origin.getX()) / direction.getX();
|
||||||
return position.getBlockY() == origin.getY() + (t * direction.getY()) && position.getBlockZ() == origin.getZ() + (t * direction.getZ());
|
return MathUtils.floor(position.getY()) == origin.getY() + (t * direction.getY()) && MathUtils.floor(position.getZ()) == origin.getZ() + (t * direction.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
//get all postions on a raytrace
|
//get all postions on a raytrace
|
||||||
public List<Vector> traverse(double blocksAway, double accuracy) {
|
public List<Vector3d> traverse(double blocksAway, double accuracy) {
|
||||||
List<Vector> positions = new ArrayList<>();
|
List<Vector3d> positions = new ArrayList<>();
|
||||||
for (double d = 0; d <= blocksAway; d += accuracy) {
|
for (double d = 0; d <= blocksAway; d += accuracy) {
|
||||||
positions.add(getPostion(d));
|
positions.add(getPostion(d));
|
||||||
}
|
}
|
||||||
return positions;
|
return positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Vector> traverse(double skip, double blocksAway, double accuracy) {
|
public List<Vector3d> traverse(double skip, double blocksAway, double accuracy) {
|
||||||
List<Vector> positions = new ArrayList<>();
|
List<Vector3d> positions = new ArrayList<>();
|
||||||
for (double d = skip; d <= blocksAway; d += accuracy) {
|
for (double d = skip; d <= blocksAway; d += accuracy) {
|
||||||
positions.add(getPostion(d));
|
positions.add(getPostion(d));
|
||||||
}
|
}
|
||||||
@@ -62,14 +65,17 @@ public class RayTrace {
|
|||||||
public List<Block> getBlocks(World world, double blocksAway, double accuracy) {
|
public List<Block> getBlocks(World world, double blocksAway, double accuracy) {
|
||||||
List<Block> blocks = new ArrayList<>();
|
List<Block> blocks = new ArrayList<>();
|
||||||
|
|
||||||
traverse(blocksAway, accuracy).stream().filter(vector -> vector.toLocation(world).getBlock().getType().isSolid()).forEach(vector -> blocks.add(vector.toLocation(world).getBlock()));
|
traverse(blocksAway, accuracy).stream()
|
||||||
|
.map(KLocation::new)
|
||||||
|
.filter(vector -> vector.toLocation(world).getBlock().getType().isSolid())
|
||||||
|
.forEach(vector -> blocks.add(vector.toLocation(world).getBlock()));
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
//intersection detection for current raytrace with return
|
//intersection detection for current raytrace with return
|
||||||
public Vector positionOfIntersection(Vector min, Vector max, double blocksAway, double accuracy) {
|
public Vector3d positionOfIntersection(Vector3d min, Vector3d max, double blocksAway, double accuracy) {
|
||||||
List<Vector> positions = traverse(blocksAway, accuracy);
|
List<Vector3d> positions = traverse(blocksAway, accuracy);
|
||||||
for (Vector position : positions) {
|
for (Vector3d position : positions) {
|
||||||
if (intersects(position, min, max)) {
|
if (intersects(position, min, max)) {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@@ -78,9 +84,9 @@ public class RayTrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//intersection detection for current raytrace
|
//intersection detection for current raytrace
|
||||||
public boolean intersects(Vector min, Vector max, double blocksAway, double accuracy) {
|
public boolean intersects(Vector3d min, Vector3d max, double blocksAway, double accuracy) {
|
||||||
List<Vector> positions = traverse(blocksAway, accuracy);
|
List<Vector3d> positions = traverse(blocksAway, accuracy);
|
||||||
for (Vector position : positions) {
|
for (Vector3d position : positions) {
|
||||||
if (intersects(position, min, max)) {
|
if (intersects(position, min, max)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -89,9 +95,9 @@ public class RayTrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//bounding blockbox instead of vector
|
//bounding blockbox instead of vector
|
||||||
public Vector positionOfIntersection(SimpleCollisionBox collisionBox, double blocksAway, double accuracy) {
|
public Vector3d positionOfIntersection(SimpleCollisionBox collisionBox, double blocksAway, double accuracy) {
|
||||||
List<Vector> positions = traverse(blocksAway, accuracy);
|
List<Vector3d> positions = traverse(blocksAway, accuracy);
|
||||||
for (Vector position : positions) {
|
for (Vector3d position : positions) {
|
||||||
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@@ -99,9 +105,9 @@ public class RayTrace {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector positionOfIntersection(SimpleCollisionBox collisionBox, double skip, double blocksAway, double accuracy) {
|
public Vector3d positionOfIntersection(SimpleCollisionBox collisionBox, double skip, double blocksAway, double accuracy) {
|
||||||
List<Vector> positions = traverse(skip, blocksAway, accuracy);
|
List<Vector3d> positions = traverse(skip, blocksAway, accuracy);
|
||||||
for (Vector position : positions) {
|
for (Vector3d position : positions) {
|
||||||
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@@ -111,8 +117,8 @@ public class RayTrace {
|
|||||||
|
|
||||||
//bounding blockbox instead of vector
|
//bounding blockbox instead of vector
|
||||||
public boolean intersects(SimpleCollisionBox collisionBox, double blocksAway, double accuracy) {
|
public boolean intersects(SimpleCollisionBox collisionBox, double blocksAway, double accuracy) {
|
||||||
List<Vector> positions = traverse(blocksAway, accuracy);
|
List<Vector3d> positions = traverse(blocksAway, accuracy);
|
||||||
for (Vector position : positions) {
|
for (Vector3d position : positions) {
|
||||||
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -121,8 +127,8 @@ public class RayTrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean intersects(SimpleCollisionBox collisionBox, double skip, double blocksAway, double accuracy) {
|
public boolean intersects(SimpleCollisionBox collisionBox, double skip, double blocksAway, double accuracy) {
|
||||||
List<Vector> positions = traverse(blocksAway, accuracy);
|
List<Vector3d> positions = traverse(blocksAway, accuracy);
|
||||||
for (Vector position : positions) {
|
for (Vector3d position : positions) {
|
||||||
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -132,8 +138,8 @@ public class RayTrace {
|
|||||||
|
|
||||||
//debug / effects
|
//debug / effects
|
||||||
public void highlight(World world, double blocksAway, double accuracy) {
|
public void highlight(World world, double blocksAway, double accuracy) {
|
||||||
for (Vector position : traverse(blocksAway, accuracy)) {
|
for (Vector3d position : traverse(blocksAway, accuracy)) {
|
||||||
world.playEffect(position.toLocation(world), (PacketEvents.getAPI().getServerManager().getVersion()
|
world.playEffect(new Location(world, position.x, position.y, position.z), (PacketEvents.getAPI().getServerManager().getVersion()
|
||||||
.isNewerThanOrEquals(ServerVersion.V_1_13) ? Effect.SMOKE : Effect.valueOf("COLOURED_DUST")), 0);
|
.isNewerThanOrEquals(ServerVersion.V_1_13) ? Effect.SMOKE : Effect.valueOf("COLOURED_DUST")), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ import com.github.retrooper.packetevents.protocol.world.states.defaulttags.Block
|
|||||||
import com.github.retrooper.packetevents.protocol.world.states.enums.*;
|
import com.github.retrooper.packetevents.protocol.world.states.enums.*;
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
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.StateTypes;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||||
import dev.brighten.ac.utils.BlockUtils;
|
import dev.brighten.ac.utils.BlockUtils;
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
|
||||||
import dev.brighten.ac.utils.world.blocks.*;
|
import dev.brighten.ac.utils.world.blocks.*;
|
||||||
import dev.brighten.ac.utils.world.types.*;
|
import dev.brighten.ac.utils.world.types.*;
|
||||||
|
|
||||||
@@ -110,12 +110,58 @@ public enum BlockData {
|
|||||||
|
|
||||||
_DOOR(new DoorHandler(), BlockTags.DOORS.getStates().toArray(new StateType[0])),
|
_DOOR(new DoorHandler(), BlockTags.DOORS.getStates().toArray(new StateType[0])),
|
||||||
|
|
||||||
_HOPPER(new HopperBounding(), StateTypes.HOPPER),
|
_HOPPER((version, player, block) -> {
|
||||||
|
if(version.isOlderThan(ClientVersion.V_1_13)) {
|
||||||
|
double thickness = 0.125;
|
||||||
|
return new ComplexCollisionBox(
|
||||||
|
new SimpleCollisionBox(0,0,0,1, 0.125*5,1),
|
||||||
|
new SimpleCollisionBox(0, 0.125*5, 0, thickness, 1, 1),
|
||||||
|
new SimpleCollisionBox(1-thickness, 0.125*5, 0, 1, 1, 1),
|
||||||
|
new SimpleCollisionBox(0, 0.125*5, 0, 1, 1, thickness),
|
||||||
|
new SimpleCollisionBox(0, 0.125*5, 1-thickness, 1, 1, 1)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
ComplexCollisionBox hopperBox = new ComplexCollisionBox();
|
||||||
|
|
||||||
|
switch (block.getBlockState().getFacing()) {
|
||||||
|
case DOWN:
|
||||||
|
hopperBox.add(new HexCollisionBox(6.0D, 0.0D, 6.0D, 10.0D, 4.0D, 10.0D));
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
hopperBox.add(new HexCollisionBox(12.0D, 4.0D, 6.0D, 16.0D, 8.0D, 10.0D));
|
||||||
|
break;
|
||||||
|
case NORTH:
|
||||||
|
hopperBox.add(new HexCollisionBox(6.0D, 4.0D, 0.0D, 10.0D, 8.0D, 4.0D));
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
hopperBox.add(new HexCollisionBox(6.0D, 4.0D, 12.0D, 10.0D, 8.0D, 16.0D));
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
hopperBox.add(new HexCollisionBox(0.0D, 4.0D, 6.0D, 4.0D, 8.0D, 10.0D));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hopperBox.add(new SimpleCollisionBox(0, 0.625, 0, 1.0, 0.6875, 1.0));
|
||||||
|
hopperBox.add(new SimpleCollisionBox(0, 0.6875, 0, 0.125, 1, 1));
|
||||||
|
hopperBox.add(new SimpleCollisionBox(0.125, 0.6875, 0, 1, 1, 0.125));
|
||||||
|
hopperBox.add(new SimpleCollisionBox(0.125, 0.6875, 0.875, 1, 1, 1));
|
||||||
|
hopperBox.add(new SimpleCollisionBox(0.25, 0.25, 0.25, 0.75, 0.625, 0.75));
|
||||||
|
hopperBox.add(new SimpleCollisionBox(0.875, 0.6875, 0.125, 1, 1, 0.875));
|
||||||
|
|
||||||
|
return hopperBox;
|
||||||
|
}
|
||||||
|
}, StateTypes.HOPPER),
|
||||||
_CAKE((protocol, player, block) -> {
|
_CAKE((protocol, player, block) -> {
|
||||||
double f1 = (1 + block.getBlockState().getBites() * 2) / 16D;
|
double f1 = (1 + block.getBlockState().getBites() * 2) / 16D;
|
||||||
|
|
||||||
return new SimpleCollisionBox(f1, 0, 0.0625, 1 - 0.0625, 0.5, 1 - 0.0625);
|
return new SimpleCollisionBox(f1, 0, 0.0625, 1 - 0.0625, 0.5, 1 - 0.0625);
|
||||||
}, StateTypes.CAKE),
|
}, StateTypes.CAKE),
|
||||||
|
STONE_CUTTER((version, player, block) -> {
|
||||||
|
if (version.isOlderThanOrEquals(ClientVersion.V_1_13_2))
|
||||||
|
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1);
|
||||||
|
|
||||||
|
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D);
|
||||||
|
}, StateTypes.STONECUTTER),
|
||||||
_COCOA_BEAN((protocol, player, block) -> {
|
_COCOA_BEAN((protocol, player, block) -> {
|
||||||
int age = block.getBlockState().getAge();
|
int age = block.getBlockState().getAge();
|
||||||
if (protocol.isNewerThanOrEquals(ClientVersion.V_1_9_1) && protocol.isOlderThan(ClientVersion.V_1_11))
|
if (protocol.isNewerThanOrEquals(ClientVersion.V_1_9_1) && protocol.isOlderThan(ClientVersion.V_1_11))
|
||||||
@@ -282,7 +328,34 @@ public enum BlockData {
|
|||||||
StateTypes.STRUCTURE_VOID),
|
StateTypes.STRUCTURE_VOID),
|
||||||
|
|
||||||
_END_ROD(new DynamicRod(), StateTypes.END_ROD),
|
_END_ROD(new DynamicRod(), StateTypes.END_ROD),
|
||||||
_CAULDRON(new CouldronBounding(), StateTypes.CAULDRON),
|
_CAULDRON((version, player, block) -> {
|
||||||
|
if(version.isOlderThanOrEquals(ClientVersion.V_1_13_2)) {
|
||||||
|
double thickness = 0.125;
|
||||||
|
|
||||||
|
return new ComplexCollisionBox(new SimpleCollisionBox(0,0,0,1, 0.3125,1),
|
||||||
|
new SimpleCollisionBox(0, 0.3125, 0, thickness, 1, 1),
|
||||||
|
new SimpleCollisionBox(1-thickness, 0.3125, 0, 1, 1, 1),
|
||||||
|
new SimpleCollisionBox(0, 0.3125, 0, 1, 1, thickness),
|
||||||
|
new SimpleCollisionBox(0, 0.3125, 1-thickness, 1, 1, 1));
|
||||||
|
} else {
|
||||||
|
return new ComplexCollisionBox(new SimpleCollisionBox(0.0, 0.0, 0.0, 0.125, 1.0, 0.25),
|
||||||
|
new SimpleCollisionBox(0.0, 0.0, 0.75, 0.125, 1.0, 1.0),
|
||||||
|
new SimpleCollisionBox(0.125, 0.0, 0.0, 0.25, 1.0, 0.125),
|
||||||
|
new SimpleCollisionBox(0.125, 0.0, 0.875, 0.25, 1.0, 1.0),
|
||||||
|
new SimpleCollisionBox(0.75, 0.0, 0.0, 1.0, 1.0, 0.125),
|
||||||
|
new SimpleCollisionBox(0.75, 0.0, 0.875, 1.0, 1.0, 1.0),
|
||||||
|
new SimpleCollisionBox(0.875, 0.0, 0.125, 1.0, 1.0, 0.25),
|
||||||
|
new SimpleCollisionBox(0.875, 0.0, 0.75, 1.0, 1.0, 0.875),
|
||||||
|
new SimpleCollisionBox(0.0, 0.1875, 0.25, 1.0, 0.25, 0.75),
|
||||||
|
new SimpleCollisionBox(0.125, 0.1875, 0.125, 0.875, 0.25, 0.25),
|
||||||
|
new SimpleCollisionBox(0.125, 0.1875, 0.75, 0.875, 0.25, 0.875),
|
||||||
|
new SimpleCollisionBox(0.25, 0.1875, 0.0, 0.75, 1.0, 0.125),
|
||||||
|
new SimpleCollisionBox(0.25, 0.1875, 0.875, 0.75, 1.0, 1.0),
|
||||||
|
new SimpleCollisionBox(0.0, 0.25, 0.25, 0.125, 1.0, 0.75),
|
||||||
|
new SimpleCollisionBox(0.875, 0.25, 0.25, 1.0, 1.0, 0.75)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, StateTypes.CAULDRON),
|
||||||
_CACTUS(new SimpleCollisionBox(0.0625, 0, 0.0625,
|
_CACTUS(new SimpleCollisionBox(0.0625, 0, 0.0625,
|
||||||
1 - 0.0625, 1 - 0.0625, 1 - 0.0625), StateTypes.CACTUS),
|
1 - 0.0625, 1 - 0.0625, 1 - 0.0625), StateTypes.CACTUS),
|
||||||
_PISTON_BASE(new PistonBaseCollision(), StateTypes.PISTON, StateTypes.STICKY_PISTON),
|
_PISTON_BASE(new PistonBaseCollision(), StateTypes.PISTON, StateTypes.STICKY_PISTON),
|
||||||
@@ -304,6 +377,67 @@ public enum BlockData {
|
|||||||
}, StateTypes.LECTERN),
|
}, StateTypes.LECTERN),
|
||||||
_POT(new SimpleCollisionBox(0.3125, 0.0, 0.3125, 0.6875, 0.375, 0.6875),
|
_POT(new SimpleCollisionBox(0.3125, 0.0, 0.3125, 0.6875, 0.375, 0.6875),
|
||||||
StateTypes.FLOWER_POT),
|
StateTypes.FLOWER_POT),
|
||||||
|
KELP(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D), StateTypes.KELP),
|
||||||
|
// Kelp block is a full block, so it by default is correct
|
||||||
|
|
||||||
|
BELL((version, player, block) -> {
|
||||||
|
if (version.isOlderThanOrEquals(ClientVersion.V_1_13_2))
|
||||||
|
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1);
|
||||||
|
|
||||||
|
BlockFace direction = block.getBlockState().getFacing();
|
||||||
|
|
||||||
|
if (block.getBlockState().getAttachment() == Attachment.FLOOR) {
|
||||||
|
return direction != BlockFace.NORTH && direction != BlockFace.SOUTH ?
|
||||||
|
new HexCollisionBox(4.0D, 0.0D, 0.0D, 12.0D, 16.0D, 16.0D) :
|
||||||
|
new HexCollisionBox(0.0D, 0.0D, 4.0D, 16.0D, 16.0D, 12.0D);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ComplexCollisionBox complex = new ComplexCollisionBox(
|
||||||
|
new HexCollisionBox(5.0D, 6.0D, 5.0D, 11.0D, 13.0D, 11.0D),
|
||||||
|
new HexCollisionBox(4.0D, 4.0D, 4.0D, 12.0D, 6.0D, 12.0D));
|
||||||
|
|
||||||
|
if (block.getBlockState().getAttachment() == Attachment.CEILING) {
|
||||||
|
complex.add(new HexCollisionBox(7.0D, 13.0D, 7.0D, 9.0D, 16.0D, 9.0D));
|
||||||
|
} else if (block.getBlockState().getAttachment() == Attachment.DOUBLE_WALL) {
|
||||||
|
if (direction != BlockFace.NORTH && direction != BlockFace.SOUTH) {
|
||||||
|
complex.add(new HexCollisionBox(0.0D, 13.0D, 7.0D, 16.0D, 15.0D, 9.0D));
|
||||||
|
} else {
|
||||||
|
complex.add(new HexCollisionBox(7.0D, 13.0D, 0.0D, 9.0D, 15.0D, 16.0D));
|
||||||
|
}
|
||||||
|
} else if (direction == BlockFace.NORTH) {
|
||||||
|
complex.add(new HexCollisionBox(7.0D, 13.0D, 0.0D, 9.0D, 15.0D, 13.0D));
|
||||||
|
} else if (direction == BlockFace.SOUTH) {
|
||||||
|
complex.add(new HexCollisionBox(7.0D, 13.0D, 3.0D, 9.0D, 15.0D, 16.0D));
|
||||||
|
} else {
|
||||||
|
if (direction == BlockFace.EAST) {
|
||||||
|
complex.add(new HexCollisionBox(3.0D, 13.0D, 7.0D, 16.0D, 15.0D, 9.0D));
|
||||||
|
} else {
|
||||||
|
complex.add(new HexCollisionBox(0.0D, 13.0D, 7.0D, 13.0D, 15.0D, 9.0D));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return complex;
|
||||||
|
|
||||||
|
}, StateTypes.BELL),
|
||||||
|
|
||||||
|
SCAFFOLDING((version, player, block) -> {
|
||||||
|
// ViaVersion replacement block - hay block
|
||||||
|
if (version.isOlderThanOrEquals(ClientVersion.V_1_13_2))
|
||||||
|
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1);
|
||||||
|
|
||||||
|
if (player.getMovement().getFrom().getY() > player.getMovement().getTo().getY() + 1 - 1e-5 && !player.getInfo().sneaking) {
|
||||||
|
return new ComplexCollisionBox(new HexCollisionBox(0.0D, 14.0D, 0.0D, 16.0D, 16.0D, 16.0D),
|
||||||
|
new HexCollisionBox(0.0D, 0.0D, 0.0D, 2.0D, 16.0D, 2.0D),
|
||||||
|
new HexCollisionBox(14.0D, 0.0D, 0.0D, 16.0D, 16.0D, 2.0D),
|
||||||
|
new HexCollisionBox(0.0D, 0.0D, 14.0D, 2.0D, 16.0D, 16.0),
|
||||||
|
new HexCollisionBox(14.0D, 0.0D, 14.0D, 16.0D, 16.0D, 16.0D));
|
||||||
|
}
|
||||||
|
|
||||||
|
return block.getBlockState().getDistance() != 0 && block.getBlockState().isBottom() && player.getMovement().getFrom().getY() > player.getMovement().getTo().getY() - 1e-5 ?
|
||||||
|
new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D) :
|
||||||
|
NoCollisionBox.INSTANCE;
|
||||||
|
}, StateTypes.SCAFFOLDING),
|
||||||
|
|
||||||
_NONE(NoCollisionBox.INSTANCE, Stream.of(StateTypes.TORCH, StateTypes.REDSTONE_TORCH,
|
_NONE(NoCollisionBox.INSTANCE, Stream.of(StateTypes.TORCH, StateTypes.REDSTONE_TORCH,
|
||||||
StateTypes.REDSTONE_WIRE, StateTypes.REDSTONE_WALL_TORCH, StateTypes.POWERED_RAIL, StateTypes.WALL_TORCH,
|
StateTypes.REDSTONE_WIRE, StateTypes.REDSTONE_WALL_TORCH, StateTypes.POWERED_RAIL, StateTypes.WALL_TORCH,
|
||||||
@@ -361,10 +495,10 @@ public enum BlockData {
|
|||||||
return getBox(player, block.getLocation(), version);
|
return getBox(player, block.getLocation(), version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CollisionBox getBox(APlayer player, IntVector block, ClientVersion version) {
|
public CollisionBox getBox(APlayer player, Vector3i block, ClientVersion version) {
|
||||||
if (this.box != null)
|
if (this.box != null)
|
||||||
return this.box.copy().offset(block.getX(), block.getY(), block.getZ());
|
return this.box.copy().offset(block.getX(), block.getY(), block.getZ());
|
||||||
return new DynamicCollisionBox(dynamic, player, player.getBlockUpdateHandler().getBlock(block), version)
|
return new DynamicCollisionBox(dynamic, player, player.getWorldTracker().getBlock(block), version)
|
||||||
.offset(block.getX(), block.getY(), block.getZ());
|
.offset(block.getX(), block.getY(), block.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package dev.brighten.ac.utils.world;
|
|||||||
import com.github.retrooper.packetevents.PacketEvents;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||||
|
import dev.brighten.ac.utils.KLocation;
|
||||||
import dev.brighten.ac.utils.world.types.NoCollisionBox;
|
import dev.brighten.ac.utils.world.types.NoCollisionBox;
|
||||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -23,6 +24,10 @@ public class EntityData {
|
|||||||
return bounds(entity.getEntityType()).offset(location.getX(), location.getY(), location.getZ());
|
return bounds(entity.getEntityType()).offset(location.getX(), location.getY(), location.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CollisionBox getEntityBox(KLocation location, TrackedEntity entity) {
|
||||||
|
return bounds(entity.getEntityType()).offset(location.getX(), location.getY(), location.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
public static CollisionBox getEntityBox(Location location, EntityType entity) {
|
public static CollisionBox getEntityBox(Location location, EntityType entity) {
|
||||||
return bounds(entity).offset(location.getX(), location.getY(), location.getZ());
|
return bounds(entity).offset(location.getX(), location.getY(), location.getZ());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ 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.WrappedBlockState;
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.enums.Half;
|
import com.github.retrooper.packetevents.protocol.world.states.enums.Half;
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.enums.Hinge;
|
import com.github.retrooper.packetevents.protocol.world.states.enums.Hinge;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||||
import dev.brighten.ac.utils.math.IntVector;
|
|
||||||
import dev.brighten.ac.utils.world.CollisionBox;
|
import dev.brighten.ac.utils.world.CollisionBox;
|
||||||
import dev.brighten.ac.utils.world.types.CollisionFactory;
|
import dev.brighten.ac.utils.world.types.CollisionFactory;
|
||||||
import dev.brighten.ac.utils.world.types.HexCollisionBox;
|
import dev.brighten.ac.utils.world.types.HexCollisionBox;
|
||||||
@@ -50,10 +50,10 @@ public class DoorHandler implements CollisionFactory {
|
|||||||
if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThanOrEquals(ServerVersion.V_1_12_2)
|
if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThanOrEquals(ServerVersion.V_1_12_2)
|
||||||
|| version.isOlderThanOrEquals(ClientVersion.V_1_12_2)) {
|
|| version.isOlderThanOrEquals(ClientVersion.V_1_12_2)) {
|
||||||
if (door.getBlockState().getHalf() == Half.LOWER) {
|
if (door.getBlockState().getHalf() == Half.LOWER) {
|
||||||
IntVector aboveVec = door.getLocation().clone();
|
Vector3i aboveVec = door.getLocation();
|
||||||
|
|
||||||
aboveVec.setY(aboveVec.getY() + 1);
|
aboveVec = aboveVec.add(0, aboveVec.getY() + 1, 0);
|
||||||
WrappedBlockState above = player.getBlockUpdateHandler().getBlock(aboveVec).getBlockState();
|
WrappedBlockState above = player.getWorldTracker().getBlock(aboveVec).getBlockState();
|
||||||
|
|
||||||
facingDirection = door.getBlockState().getFacing();
|
facingDirection = door.getBlockState().getFacing();
|
||||||
isClosed = !door.getBlockState().isOpen();
|
isClosed = !door.getBlockState().isOpen();
|
||||||
@@ -67,10 +67,10 @@ public class DoorHandler implements CollisionFactory {
|
|||||||
isRightHinge = false;
|
isRightHinge = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IntVector belowVec = door.getLocation().clone();
|
Vector3i belowVec = door.getLocation();
|
||||||
|
|
||||||
belowVec.setY(belowVec.getY() - 1);
|
belowVec = belowVec.add(0, belowVec.getY() - 1, 0);
|
||||||
WrappedBlockState below = player.getBlockUpdateHandler().getBlock(belowVec).getBlockState();
|
WrappedBlockState below = player.getWorldTracker().getBlock(belowVec).getBlockState();
|
||||||
|
|
||||||
if (below.getType() == door.getBlockState().getType() && below.getHalf() == Half.LOWER) {
|
if (below.getType() == door.getBlockState().getType() && below.getHalf() == Half.LOWER) {
|
||||||
isClosed = !below.isOpen();
|
isClosed = !below.isOpen();
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class DynamicStair implements CollisionFactory {
|
|||||||
z = originalStairs.getLocation().getZ();
|
z = originalStairs.getLocation().getZ();
|
||||||
WrappedBlock offsetOne = player == null
|
WrappedBlock offsetOne = player == null
|
||||||
? null
|
? null
|
||||||
: player.getBlockUpdateHandler().getBlock(
|
: player.getWorldTracker().getBlock(
|
||||||
x + facing.getModX(),
|
x + facing.getModX(),
|
||||||
y + facing.getModY(),
|
y + facing.getModY(),
|
||||||
z + facing.getModZ());
|
z + facing.getModZ());
|
||||||
@@ -64,7 +64,7 @@ public class DynamicStair implements CollisionFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WrappedBlock offsetTwo = player.getBlockUpdateHandler()
|
WrappedBlock offsetTwo = player.getWorldTracker()
|
||||||
.getBlock(x + facing.getOppositeFace().getModX(),
|
.getBlock(x + facing.getOppositeFace().getModX(),
|
||||||
y + facing.getOppositeFace().getModY(), z
|
y + facing.getOppositeFace().getModY(), z
|
||||||
+ facing.getOppositeFace().getModZ());
|
+ facing.getOppositeFace().getModZ());
|
||||||
|
|||||||
@@ -4,18 +4,18 @@ import com.github.retrooper.packetevents.PacketEvents;
|
|||||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
|
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
|
||||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||||
|
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||||
import dev.brighten.ac.utils.Helper;
|
import dev.brighten.ac.utils.Helper;
|
||||||
|
import dev.brighten.ac.utils.KLocation;
|
||||||
import dev.brighten.ac.utils.Materials;
|
import dev.brighten.ac.utils.Materials;
|
||||||
import dev.brighten.ac.utils.Tuple;
|
import dev.brighten.ac.utils.Tuple;
|
||||||
import dev.brighten.ac.utils.math.RayTrace;
|
import dev.brighten.ac.utils.math.RayTrace;
|
||||||
import dev.brighten.ac.utils.world.BlockData;
|
import dev.brighten.ac.utils.world.BlockData;
|
||||||
import dev.brighten.ac.utils.world.CollisionBox;
|
import dev.brighten.ac.utils.world.CollisionBox;
|
||||||
import me.hydro.emulator.util.mcp.MathHelper;
|
import me.hydro.emulator.util.mcp.MathHelper;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -58,15 +58,15 @@ public class RayCollision implements CollisionBox {
|
|||||||
directionZ = 0;
|
directionZ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RayCollision(LivingEntity e) {
|
public RayCollision(TrackedEntity e) {
|
||||||
this(e.getEyeLocation());
|
this(e.getEyeLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
public RayCollision(Location l) {
|
public RayCollision(KLocation l) {
|
||||||
this(l.toVector(),l.getDirection());
|
this(l.toVector(),l.getDirection());
|
||||||
}
|
}
|
||||||
|
|
||||||
public RayCollision(Vector position, Vector direction) {
|
public RayCollision(Vector3d position, Vector3d direction) {
|
||||||
this.originX = position.getX();
|
this.originX = position.getX();
|
||||||
this.originY = position.getY();
|
this.originY = position.getY();
|
||||||
this.originZ = position.getZ();
|
this.originZ = position.getZ();
|
||||||
@@ -75,17 +75,17 @@ public class RayCollision implements CollisionBox {
|
|||||||
this.directionZ = direction.getZ();
|
this.directionZ = direction.getZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector getOrigin() {
|
public Vector3d getOrigin() {
|
||||||
return new Vector(originX, originY, originZ);
|
return new Vector3d(originX, originY, originZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector getDirection() {
|
public Vector3d getDirection() {
|
||||||
return new Vector(directionX, directionY, directionZ);
|
return new Vector3d(directionX, directionY, directionZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCollided(CollisionBox other) {
|
public boolean isCollided(CollisionBox other) {
|
||||||
if (other instanceof RayCollision) {
|
if (other instanceof RayCollision) {
|
||||||
return false; // lol no support
|
return false; // lol no support
|
||||||
} else {
|
} else {
|
||||||
List<SimpleCollisionBox> boxes = new ArrayList<>();
|
List<SimpleCollisionBox> boxes = new ArrayList<>();
|
||||||
@@ -141,7 +141,7 @@ public class RayCollision implements CollisionBox {
|
|||||||
public List<CollisionBox> boxesOnRay(APlayer player, double distance) {
|
public List<CollisionBox> boxesOnRay(APlayer player, double distance) {
|
||||||
int amount = Math.round((float) (distance / 0.5));
|
int amount = Math.round((float) (distance / 0.5));
|
||||||
|
|
||||||
Location[] locs = new Location[Math.max(2, amount)]; //We do a max to prevent NegativeArraySizeException.
|
KLocation[] locs = new KLocation[Math.max(2, amount)]; //We do a max to prevent NegativeArraySizeException.
|
||||||
List<CollisionBox> boxes = new ArrayList<>();
|
List<CollisionBox> boxes = new ArrayList<>();
|
||||||
ClientVersion version = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion();
|
ClientVersion version = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion();
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ public class RayCollision implements CollisionBox {
|
|||||||
int fy = MathHelper.floor_double(originY + (directionY * ix));
|
int fy = MathHelper.floor_double(originY + (directionY * ix));
|
||||||
int fz = MathHelper.floor_double(originZ + (directionZ * ix));
|
int fz = MathHelper.floor_double(originZ + (directionZ * ix));
|
||||||
|
|
||||||
WrappedBlock block = player.getBlockUpdateHandler().getBlock(fx, fy, fz);
|
WrappedBlock block = player.getWorldTracker().getBlock(fx, fy, fz);
|
||||||
|
|
||||||
if (block == null) continue;
|
if (block == null) continue;
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ public class RayCollision implements CollisionBox {
|
|||||||
public WrappedBlock getClosestBlockOfType(APlayer player, int bitmask, double distance) {
|
public WrappedBlock getClosestBlockOfType(APlayer player, int bitmask, double distance) {
|
||||||
int amount = Math.round((float) (distance / 0.5));
|
int amount = Math.round((float) (distance / 0.5));
|
||||||
|
|
||||||
Location[] locs = new Location[Math.max(2, amount)]; //We do a max
|
KLocation[] locs = new KLocation[Math.max(2, amount)]; //We do a max
|
||||||
ClientVersion version = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion();
|
ClientVersion version = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion();
|
||||||
|
|
||||||
for (int i = 0; i < locs.length; i++) {
|
for (int i = 0; i < locs.length; i++) {
|
||||||
@@ -183,7 +183,7 @@ public class RayCollision implements CollisionBox {
|
|||||||
int fy = MathHelper.floor_double(originY + (directionY * ix));
|
int fy = MathHelper.floor_double(originY + (directionY * ix));
|
||||||
int fz = MathHelper.floor_double(originZ + (directionZ * ix));
|
int fz = MathHelper.floor_double(originZ + (directionZ * ix));
|
||||||
|
|
||||||
WrappedBlock block = player.getBlockUpdateHandler().getBlock(fx, fy, fz);
|
WrappedBlock block = player.getWorldTracker().getBlock(fx, fy, fz);
|
||||||
|
|
||||||
if(block == null || !Materials.checkFlag(block.getType(), bitmask)) continue;
|
if(block == null || !Materials.checkFlag(block.getType(), bitmask)) continue;
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ public class RayCollision implements CollisionBox {
|
|||||||
|
|
||||||
RayTrace trace = new RayTrace(ray.getOrigin(), ray.getDirection());
|
RayTrace trace = new RayTrace(ray.getOrigin(), ray.getDirection());
|
||||||
|
|
||||||
Vector point = trace.positionOfIntersection(box, Math.max(0, dist - range), 0.01);
|
Vector3d point = trace.positionOfIntersection(box, Math.max(0, dist - range), 0.01);
|
||||||
|
|
||||||
return ray.getOrigin().distance(point);
|
return ray.getOrigin().distance(point);
|
||||||
}
|
}
|
||||||
@@ -347,23 +347,23 @@ public class RayCollision implements CollisionBox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector collisionPoint(SimpleCollisionBox box) {
|
public Vector3d collisionPoint(SimpleCollisionBox box) {
|
||||||
Tuple<Double, Double> p = new Tuple<>();
|
Tuple<Double, Double> p = new Tuple<>();
|
||||||
if (box==null||!intersect(this,box,p))
|
if (box==null||!intersect(this,box,p))
|
||||||
return null;
|
return null;
|
||||||
Vector vector = new Vector(directionX,directionY,directionZ);
|
Vector3d vector = new Vector3d(directionX,directionY,directionZ);
|
||||||
vector.normalize();
|
vector.normalize();
|
||||||
vector.multiply(p.one);
|
vector.multiply(p.one);
|
||||||
vector.add(new Vector(originX,originY,originZ));
|
vector.add(new Vector3d(originX,originY,originZ));
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector collisionPoint(double dist) {
|
public Vector3d collisionPoint(double dist) {
|
||||||
Vector vector = new Vector(directionX,directionY,directionZ);
|
Vector3d vector = new Vector3d(directionX,directionY,directionZ);
|
||||||
vector.normalize();
|
vector.normalize();
|
||||||
vector.multiply(dist);
|
vector.multiply(dist);
|
||||||
vector.add(new Vector(originX,originY,originZ));
|
vector.add(new Vector3d(originX,originY,originZ));
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package dev.brighten.ac.utils.world.types;
|
package dev.brighten.ac.utils.world.types;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
|
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import dev.brighten.ac.data.APlayer;
|
import dev.brighten.ac.data.APlayer;
|
||||||
import dev.brighten.ac.utils.Helper;
|
import dev.brighten.ac.utils.Helper;
|
||||||
import dev.brighten.ac.utils.KLocation;
|
import dev.brighten.ac.utils.KLocation;
|
||||||
@@ -54,7 +55,7 @@ public class SimpleCollisionBox implements CollisionBox {
|
|||||||
maxZ = width / 2;
|
maxZ = width / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
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());
|
this(min.getX(), min.getY(), min.getZ(), max.getX(), max.getY(), max.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +77,13 @@ public class SimpleCollisionBox implements CollisionBox {
|
|||||||
maxY += height;
|
maxY += 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);
|
||||||
|
maxY += height;
|
||||||
|
}
|
||||||
|
|
||||||
public void sort() {
|
public void sort() {
|
||||||
double temp;
|
double temp;
|
||||||
if (minX >= maxX) {
|
if (minX >= maxX) {
|
||||||
@@ -196,26 +204,26 @@ public class SimpleCollisionBox implements CollisionBox {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector[] corners() {
|
public Vector3d[] corners() {
|
||||||
sort();
|
sort();
|
||||||
Vector[] vectors = new Vector[8];
|
Vector3d[] vectors = new Vector3d[8];
|
||||||
vectors[0] = new Vector(minX, minY, minZ);
|
vectors[0] = new Vector3d(minX, minY, minZ);
|
||||||
vectors[1] = new Vector(minX, minY, maxZ);
|
vectors[1] = new Vector3d(minX, minY, maxZ);
|
||||||
vectors[2] = new Vector(maxX, minY, minZ);
|
vectors[2] = new Vector3d(maxX, minY, minZ);
|
||||||
vectors[3] = new Vector(maxX, minY, maxZ);
|
vectors[3] = new Vector3d(maxX, minY, maxZ);
|
||||||
vectors[4] = new Vector(minX, maxY, minZ);
|
vectors[4] = new Vector3d(minX, maxY, minZ);
|
||||||
vectors[5] = new Vector(minX, maxY, maxZ);
|
vectors[5] = new Vector3d(minX, maxY, maxZ);
|
||||||
vectors[6] = new Vector(maxX, maxY, minZ);
|
vectors[6] = new Vector3d(maxX, maxY, minZ);
|
||||||
vectors[7] = new Vector(maxX, maxY, maxZ);
|
vectors[7] = new Vector3d(maxX, maxY, maxZ);
|
||||||
return vectors;
|
return vectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector min() {
|
public Vector3d min() {
|
||||||
return new Vector(minX, minY, minZ);
|
return new Vector3d(minX, minY, minZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector max() {
|
public Vector3d max() {
|
||||||
return new Vector(maxX, maxY, maxZ);
|
return new Vector3d(maxX, maxY, maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package dev.brighten.ac.utils;
|
package dev.brighten.ac.utils;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.util.MathUtil;
|
||||||
import com.github.retrooper.packetevents.util.Vector3d;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3i;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
import org.joml.Vector2d;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -41,14 +41,18 @@ public class KLocation implements Cloneable {
|
|||||||
this.timeStamp = System.currentTimeMillis();
|
this.timeStamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KLocation(Vector vector) {
|
public KLocation(Location location) {
|
||||||
|
this(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||||
|
}
|
||||||
|
|
||||||
|
public KLocation(Vector3d vector) {
|
||||||
this.x = vector.getX();
|
this.x = vector.getX();
|
||||||
this.y = vector.getY();
|
this.y = vector.getY();
|
||||||
this.z = vector.getZ();
|
this.z = vector.getZ();
|
||||||
this.timeStamp = System.currentTimeMillis();
|
this.timeStamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KLocation(Location location) {
|
public KLocation(KLocation location) {
|
||||||
this.x = location.getX();
|
this.x = location.getX();
|
||||||
this.y = location.getY();
|
this.y = location.getY();
|
||||||
this.z = location.getZ();
|
this.z = location.getZ();
|
||||||
@@ -57,12 +61,12 @@ public class KLocation implements Cloneable {
|
|||||||
this.timeStamp = System.currentTimeMillis();
|
this.timeStamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector toVector() {
|
public Vector3d toVector() {
|
||||||
return new Vector(x, y, z);
|
return new Vector3d(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3d toVector3d() {
|
public Vector3i toVector3i() {
|
||||||
return new Vector3d(x, y, z);
|
return new Vector3i((int) x, (int) y, (int) z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location toLocation(World world) {
|
public Location toLocation(World world) {
|
||||||
@@ -112,8 +116,27 @@ public class KLocation implements Cloneable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector getDirection() {
|
public Vector3d getDirection() {
|
||||||
return MathUtils.getDirection(this);
|
double rotX = this.getYaw();
|
||||||
|
double rotY = this.getPitch();
|
||||||
|
double x, y, z;
|
||||||
|
y = -Math.sin(Math.toRadians(rotY));
|
||||||
|
double xz = Math.cos(Math.toRadians(rotY));
|
||||||
|
x = -xz * Math.sin(Math.toRadians(rotX));
|
||||||
|
z = xz * Math.cos(Math.toRadians(rotX));
|
||||||
|
return new Vector3d(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlockX() {
|
||||||
|
return MathUtil.floor(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlockY() {
|
||||||
|
return MathUtil.floor(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlockZ() {
|
||||||
|
return MathUtil.floor(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package dev.brighten.ac.utils;
|
package dev.brighten.ac.utils;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import me.hydro.emulator.util.mcp.MathHelper;
|
import me.hydro.emulator.util.mcp.MathHelper;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -196,10 +197,6 @@ public class MathUtils {
|
|||||||
return MathUtils.yawTo180D(playerRotation.getX() - expectedRotation.getX());
|
return MathUtils.yawTo180D(playerRotation.getX() - expectedRotation.getX());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double getAngle(KLocation loc1, KLocation loc2) {
|
|
||||||
return getAngle(loc1.toLocation(null), loc2.toLocation(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float distanceBetweenAngles(float a, float b) {
|
public static float distanceBetweenAngles(float a, float b) {
|
||||||
final float first = a % 360;
|
final float first = a % 360;
|
||||||
final float second = b % 360;
|
final float second = b % 360;
|
||||||
@@ -544,16 +541,14 @@ public class MathUtils {
|
|||||||
return (short) num;
|
return (short) num;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stolen from Bukkit */
|
public static Vector3d getDirection(KLocation loc) {
|
||||||
public static Vector getDirection(KLocation loc) {
|
Vector3d vector = new Vector3d();
|
||||||
Vector vector = new Vector();
|
|
||||||
double rotX = loc.getYaw();
|
double rotX = loc.getYaw();
|
||||||
double rotY = loc.getPitch();
|
double rotY = loc.getPitch();
|
||||||
vector.setY(-Math.sin(Math.toRadians(rotY)));
|
|
||||||
double xz = Math.cos(Math.toRadians(rotY));
|
double xz = Math.cos(Math.toRadians(rotY));
|
||||||
vector.setX(-xz * Math.sin(Math.toRadians(rotX)));
|
return new Vector3d(-xz * Math.sin(Math.toRadians(rotX)),
|
||||||
vector.setZ(xz * Math.cos(Math.toRadians(rotX)));
|
-Math.sin(Math.toRadians(rotY)),
|
||||||
return vector;
|
xz * Math.cos(Math.toRadians(rotX)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -704,12 +699,12 @@ public class MathUtils {
|
|||||||
return squareRoot;
|
return squareRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector getDirection(float yaw, float pitch) {
|
public static Vector3d getDirection(float yaw, float pitch) {
|
||||||
float f = MathHelper.cos(MathHelper.FastMathType.VANILLA, -yaw * 0.017453292F - (float)Math.PI);
|
float f = MathHelper.cos(MathHelper.FastMathType.VANILLA, -yaw * 0.017453292F - (float)Math.PI);
|
||||||
float f1 = MathHelper.sin(MathHelper.FastMathType.VANILLA, -yaw * 0.017453292F - (float)Math.PI);
|
float f1 = MathHelper.sin(MathHelper.FastMathType.VANILLA, -yaw * 0.017453292F - (float)Math.PI);
|
||||||
float f2 = -MathHelper.cos(MathHelper.FastMathType.VANILLA, -pitch * 0.017453292F);
|
float f2 = -MathHelper.cos(MathHelper.FastMathType.VANILLA, -pitch * 0.017453292F);
|
||||||
float f3 = MathHelper.sin(MathHelper.FastMathType.VANILLA, -pitch * 0.017453292F);
|
float f3 = MathHelper.sin(MathHelper.FastMathType.VANILLA, -pitch * 0.017453292F);
|
||||||
return new Vector(f1 * f2, f3, f * f2);
|
return new Vector3d(f1 * f2, f3, f * f2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float sqrt(float number) {
|
public static float sqrt(float number) {
|
||||||
|
|||||||
+1
-1
Submodule Neo updated: b45b76d09d...feb79131a2
@@ -30,6 +30,10 @@
|
|||||||
</build>
|
</build>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>maven-central</id>
|
||||||
|
<url>https://nexus.funkemunky.cc/repository/maven-central/</url>
|
||||||
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>spigot-repo</id>
|
<id>spigot-repo</id>
|
||||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
|
|||||||
Reference in New Issue
Block a user