From 24965108b2da3f7f3fa82ffa97387b90473c03da Mon Sep 17 00:00:00 2001 From: Axionize <154778082+Axionize@users.noreply.github.com> Date: Sat, 16 Nov 2024 16:00:27 -0500 Subject: [PATCH] Fix for entities that players can hit through blocking reach/attack ray trace --- .../packetentity/PacketEntityArmorStand.java | 23 +++++++++++++++++++ .../data/packetentity/PacketEntityArrow.java | 18 +++++++++++++++ .../data/packetentity/PacketEntityHook.java | 5 ++++ .../data/packetentity/TypedPacketEntity.java | 15 ++++++++++++ .../utils/latency/CompensatedEntities.java | 4 ++++ .../grimac/utils/nmsutil/BlockRayTrace.java | 4 +++- 6 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityArmorStand.java create mode 100644 src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityArrow.java diff --git a/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityArmorStand.java b/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityArmorStand.java new file mode 100644 index 0000000000..c27fc2ba43 --- /dev/null +++ b/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityArmorStand.java @@ -0,0 +1,23 @@ +package ac.grim.grimac.utils.data.packetentity; + +import ac.grim.grimac.player.GrimPlayer; +import com.github.retrooper.packetevents.protocol.entity.type.EntityType; + +import java.util.UUID; + +public class PacketEntityArmorStand extends PacketEntity { + + public static final int MARKER_FLAG = 16; + + boolean isMarker; + + public PacketEntityArmorStand(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z, int extraData) { + super(player, uuid, type, x, y, z); + isMarker = (extraData & MARKER_FLAG) != 0; + } + + @Override + public boolean canHit() { + return !isMarker; + } +} diff --git a/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityArrow.java b/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityArrow.java new file mode 100644 index 0000000000..90569f6d4d --- /dev/null +++ b/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityArrow.java @@ -0,0 +1,18 @@ +package ac.grim.grimac.utils.data.packetentity; + +import ac.grim.grimac.player.GrimPlayer; +import com.github.retrooper.packetevents.protocol.entity.type.EntityType; + +import java.util.UUID; + +public class PacketEntityArrow extends PacketEntity { + + public PacketEntityArrow(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z) { + super(player, uuid, type, x, y, z); + } + + @Override + public boolean canHit() { + return false; + } +} diff --git a/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityHook.java b/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityHook.java index 5378518cb0..e6107383d1 100644 --- a/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityHook.java +++ b/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityHook.java @@ -13,4 +13,9 @@ public PacketEntityHook(GrimPlayer player, UUID uuid, EntityType type, double x, super(player, uuid, type, x, y, z); this.owner = owner; } + + @Override + public boolean canHit() { + return false; + } } diff --git a/src/main/java/ac/grim/grimac/utils/data/packetentity/TypedPacketEntity.java b/src/main/java/ac/grim/grimac/utils/data/packetentity/TypedPacketEntity.java index c9d8ea37b7..a15d4e6acb 100644 --- a/src/main/java/ac/grim/grimac/utils/data/packetentity/TypedPacketEntity.java +++ b/src/main/java/ac/grim/grimac/utils/data/packetentity/TypedPacketEntity.java @@ -47,6 +47,21 @@ public boolean isBoat() { return isBoat; } + // Mojang makes this default to true and overrides it for everything where it isn't + // That's too much work for us to replicate... + // This is temporary hack and technically wrong + /* By Default every entity in the game cannot be hit by player crosshair. This is overwritten as follows: + Most Boats, Minecart's, TNT, Falling Blocks, and LivingEntities can only be hit if they're not removed + Every single BlockAttachedEntity can be hit (Leashes and other decorations) + End Crystals and IntersecetionEntities can be hit + Ender Dragon entity itself cannot be hit but its parts can be + ArmorStands can only be hit if they're not removed AND they're not markers. + Of all Projectiles, only redirectable ones (Fireballs - not blaze fireballs, Wind Charge, and Breeze Wind charges) can be hit + Persistent Projectiles can only be hit if they're not on the ground and redirectable + */ + // TLDR If we want to get 90% of the way there everything can be hit except for fishing rod bobbers, arrows, and marker armor stands + public boolean canHit() { return true; } + public boolean isPushable() { // Players can only push living entities // Minecarts and boats are the only non-living that can push diff --git a/src/main/java/ac/grim/grimac/utils/latency/CompensatedEntities.java b/src/main/java/ac/grim/grimac/utils/latency/CompensatedEntities.java index 00e08d4b0d..9ac74b9e1d 100644 --- a/src/main/java/ac/grim/grimac/utils/latency/CompensatedEntities.java +++ b/src/main/java/ac/grim/grimac/utils/latency/CompensatedEntities.java @@ -182,6 +182,10 @@ public void addEntity(int entityID, UUID uuid, EntityType entityType, Vector3d p packetEntity = new PacketEntityHook(player, uuid, entityType, position.getX(), position.getY(), position.getZ(), data); } else if (EntityTypes.ENDER_DRAGON.equals(entityType)) { packetEntity = new PacketEntityEnderDragon(player, uuid, entityID, position.getX(), position.getY(), position.getZ()); + } else if (EntityTypes.isTypeInstanceOf(entityType, EntityTypes.ABSTRACT_ARROW)) { + packetEntity = new PacketEntityArrow(player, uuid, entityType, position.getX(), position.getY(), position.getZ()); + } else if (EntityTypes.ARMOR_STAND.equals(entityType)) { + packetEntity = new PacketEntityArmorStand(player, uuid, entityType, position.getX(), position.getY(), position.getZ(), data); } else { packetEntity = new PacketEntity(player, uuid, entityType, position.getX(), position.getY(), position.getZ()); } diff --git a/src/main/java/ac/grim/grimac/utils/nmsutil/BlockRayTrace.java b/src/main/java/ac/grim/grimac/utils/nmsutil/BlockRayTrace.java index 78af0e0cf0..3afe28d7ed 100644 --- a/src/main/java/ac/grim/grimac/utils/nmsutil/BlockRayTrace.java +++ b/src/main/java/ac/grim/grimac/utils/nmsutil/BlockRayTrace.java @@ -12,6 +12,7 @@ import ac.grim.grimac.utils.data.HitData; import ac.grim.grimac.utils.data.Pair; import ac.grim.grimac.utils.data.packetentity.PacketEntity; +import ac.grim.grimac.utils.data.packetentity.TypedPacketEntity; import ac.grim.grimac.utils.math.GrimMath; import com.github.retrooper.packetevents.protocol.attribute.Attributes; import com.github.retrooper.packetevents.protocol.player.ClientVersion; @@ -28,6 +29,7 @@ import java.util.Arrays; import java.util.List; import java.util.function.BiFunction; +import java.util.stream.Collectors; public class BlockRayTrace { @@ -292,7 +294,7 @@ public static HitData getNearestHitResult(GrimPlayer player, PacketEntity target PacketEntity closestEntity = null; // Check entities - for (PacketEntity entity : player.compensatedEntities.entityMap.values()) { + for (PacketEntity entity : player.compensatedEntities.entityMap.values().stream().filter(TypedPacketEntity::canHit).collect(Collectors.toList())) { SimpleCollisionBox box = null; // 1.7 and 1.8 players get a bit of extra hitbox (this is why you should use 1.8 on cross version servers) // Yes, this is vanilla and not uncertainty. All reach checks have this or they are wrong.