Skip to content

Commit

Permalink
Ensure ComplexCollisionBoxes can only contain SimpleCollisionBoxes (#…
Browse files Browse the repository at this point in the history
…1805)

* Ensure ComplexCollisionBoxes can only contain SimpleCollisionBoxes

* Optimize ComplexCollisionBoxes by using primitives internally; Make new more efficient constructors available

* Port everything to new internal .downCast() API besides getCollisionBoxes

* implement new downCast() API for Dynamic, Simple, and No Collision Boxes

* Manually size ComplexCollisionBoxes Pt. 1

* Manually size ComplexCollisionBoxes Pt. 2

* Fix new downCast() for SimpleCollisionBox

* Fix logic error in CCB constructor

* Optimize DynamicHitboxFence

* Fix logic error again in CCB constructor

* Remove debug print statement

* Fix copying CCBs in edge case

* Rename variable for clarity

* Make CCD length private var

* Make makeShapes() CCD extra maxIndex explicit; Fix DynamicCollisionWall error

* Remove unused calls to makeShapes()
  • Loading branch information
Axionize authored Nov 23, 2024
1 parent dbc0c11 commit c4cd813
Show file tree
Hide file tree
Showing 22 changed files with 222 additions and 142 deletions.
8 changes: 5 additions & 3 deletions src/main/java/ac/grim/grimac/checks/type/BlockPlaceCheck.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import ac.grim.grimac.utils.anticheat.update.BlockPlace;
import ac.grim.grimac.utils.collisions.HitboxData;
import ac.grim.grimac.utils.collisions.datatypes.CollisionBox;
import ac.grim.grimac.utils.collisions.datatypes.ComplexCollisionBox;
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
Expand All @@ -18,6 +19,7 @@
public class BlockPlaceCheck extends Check implements RotationCheck, PostPredictionCheck {
private static final List<StateType> weirdBoxes = new ArrayList<>();
private static final List<StateType> buggyBoxes = new ArrayList<>();
private final SimpleCollisionBox[] boxes = new SimpleCollisionBox[ComplexCollisionBox.DEFAULT_MAX_COLLISION_BOX_SIZE];

protected int cancelVL;

Expand Down Expand Up @@ -69,11 +71,11 @@ protected SimpleCollisionBox getCombinedBox(final BlockPlace place) {
Vector3i clicked = place.getPlacedAgainstBlockLocation();
CollisionBox placedOn = HitboxData.getBlockHitbox(player, place.getMaterial(), player.getClientVersion(), player.compensatedWorld.getWrappedBlockStateAt(clicked), clicked.getX(), clicked.getY(), clicked.getZ());

List<SimpleCollisionBox> boxes = new ArrayList<>();
placedOn.downCast(boxes);
int size = placedOn.downCast(boxes);

SimpleCollisionBox combined = new SimpleCollisionBox(clicked.getX(), clicked.getY(), clicked.getZ());
for (SimpleCollisionBox box : boxes) {
for (int i = 0; i < size; i++) {
SimpleCollisionBox box = boxes[i];
double minX = Math.max(box.minX, combined.minX);
double minY = Math.max(box.minY, combined.minY);
double minZ = Math.max(box.minZ, combined.minZ);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.world.BlockFace;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.util.Vector;

import java.util.*;
Expand Down
29 changes: 16 additions & 13 deletions src/main/java/ac/grim/grimac/utils/anticheat/update/BlockPlace.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import ac.grim.grimac.utils.collisions.CollisionData;
import ac.grim.grimac.utils.collisions.blocks.DoorHandler;
import ac.grim.grimac.utils.collisions.datatypes.CollisionBox;
import ac.grim.grimac.utils.collisions.datatypes.ComplexCollisionBox;
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
import ac.grim.grimac.utils.data.HitData;
import ac.grim.grimac.utils.data.packetentity.PacketEntity;
Expand Down Expand Up @@ -37,7 +38,6 @@
import org.bukkit.util.Vector;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -72,6 +72,9 @@ public class BlockPlace {

@Getter private final boolean block;

// Allocated once instead of in functions to reduce new[] calls that need to be made. Since per-instance BlockPlace is always dealt with on the same thread we can use 1 buffer array
private final SimpleCollisionBox[] collisions = new SimpleCollisionBox[ComplexCollisionBox.DEFAULT_MAX_COLLISION_BOX_SIZE];

public BlockPlace(GrimPlayer player, InteractionHand hand, Vector3i blockPosition, int faceId, BlockFace face, ItemStack itemStack, HitData hitData) {
this.player = player;
this.hand = hand;
Expand Down Expand Up @@ -200,12 +203,12 @@ public boolean isFaceFullCenter(BlockFace facing) {
if (BlockTags.LEAVES.contains(data.getType())) return false;
if (BlockTags.FENCE_GATES.contains(data.getType())) return false;

List<SimpleCollisionBox> collisions = new ArrayList<>();
box.downCast(collisions);
int size = box.downCast(collisions);

AxisSelect axis = AxisUtil.getAxis(facing.getOppositeFace());

for (SimpleCollisionBox simpleBox : collisions) {
for (int i = 0; i < size; i++) {
SimpleCollisionBox simpleBox = collisions[i];
simpleBox = axis.modify(simpleBox);
if (simpleBox.minX <= 7 / 16d && simpleBox.maxX >= 7 / 16d
&& simpleBox.minY <= 0 && simpleBox.maxY >= 10 / 16d
Expand All @@ -225,12 +228,12 @@ public boolean isFaceRigid(BlockFace facing) {
if (isFullFace(facing)) return true;
if (BlockTags.LEAVES.contains(data.getType())) return false;

List<SimpleCollisionBox> collisions = new ArrayList<>();
box.downCast(collisions);
int size = box.downCast(collisions);

AxisSelect axis = AxisUtil.getAxis(facing.getOppositeFace());

for (SimpleCollisionBox simpleBox : collisions) {
for (int i = 0; i < size; i++) {
SimpleCollisionBox simpleBox = collisions[i];
simpleBox = axis.modify(simpleBox);
if (simpleBox.minX <= 2 / 16d && simpleBox.maxX >= 14 / 16d
&& simpleBox.minY <= 0 && simpleBox.maxY >= 1
Expand Down Expand Up @@ -289,10 +292,10 @@ public boolean isFullFace(BlockFace relative) {
}
}

List<SimpleCollisionBox> collisions = new ArrayList<>();
box.downCast(collisions);
int size = box.downCast(collisions);

for (SimpleCollisionBox simpleBox : collisions) {
for (int i = 0; i < size; i++) {
SimpleCollisionBox simpleBox = collisions[i];
if (axis.modify(simpleBox).isFullBlockNoCache()) return true;
}

Expand All @@ -318,12 +321,12 @@ public boolean isFaceEmpty(BlockFace facing) {
if (isFullFace(facing)) return true;
if (BlockTags.LEAVES.contains(data.getType())) return false;

List<SimpleCollisionBox> collisions = new ArrayList<>();
box.downCast(collisions);
int size = box.downCast(collisions);

AxisSelect axis = AxisUtil.getAxis(facing.getOppositeFace());

for (SimpleCollisionBox simpleBox : collisions) {
for (int i = 0; i < size; i++) {
SimpleCollisionBox simpleBox = collisions[i];
simpleBox = axis.modify(simpleBox);
// If all sides to the box have width, there is collision.
switch (facing) {
Expand Down
Loading

0 comments on commit c4cd813

Please sign in to comment.