Skip to content

Commit

Permalink
Expand hitbox of target block by 0.03/0.0002 to account for known MC bug
Browse files Browse the repository at this point in the history
  • Loading branch information
Axionize committed Aug 24, 2024
1 parent 6a13c9f commit 328596f
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 22 deletions.
29 changes: 8 additions & 21 deletions src/main/java/ac/grim/grimac/checks/impl/scaffolding/BlockLOS.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,25 @@
import ac.grim.grimac.checks.type.BlockPlaceCheck;
import ac.grim.grimac.player.GrimPlayer;
import ac.grim.grimac.utils.anticheat.update.BlockPlace;
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
import ac.grim.grimac.utils.data.HitData;
import ac.grim.grimac.utils.data.Pair;
import ac.grim.grimac.utils.nmsutil.BlockRayTrace;
import ac.grim.grimac.utils.nmsutil.Ray;
import ac.grim.grimac.utils.nmsutil.ReachUtils;
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.BlockFace;
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.util.Vector3f;
import com.github.retrooper.packetevents.util.Vector3i;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.util.Vector;

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

@CheckData(name = "ContainerLOS")
public class ContainerLOS extends BlockPlaceCheck {
public class BlockLOS extends BlockPlaceCheck {

public ContainerLOS(GrimPlayer player) {
public BlockLOS(GrimPlayer player) {
super(player);
}

Expand All @@ -53,29 +44,25 @@ public void onPostFlyingBlockPlace(BlockPlace place) {
private boolean didRayTraceHit(BlockPlace place) {
Vector3i interactBlockVec = new Vector3i(place.getPlacedAgainstBlockLocation().getX(),
place.getPlacedAgainstBlockLocation().getY(), place.getPlacedAgainstBlockLocation().getZ());
WrappedBlockState interactBlock = player.compensatedWorld.getWrappedBlockStateAt(interactBlockVec);

double maxDistance = player.compensatedEntities.getSelf()
.getAttributeValue(Attributes.PLAYER_BLOCK_INTERACTION_RANGE);
.getAttributeValue(Attributes.PLAYER_BLOCK_INTERACTION_RANGE) + player.getMovementThreshold();
List<Vector3f> possibleLookDirs = new ArrayList<>(Arrays.asList(
new Vector3f(player.lastXRot, player.yRot, 0),
new Vector3f(player.xRot, player.yRot, 0)
));
for (double eyeHeight : player.getPossibleEyeHeights()) {
for (Vector3f lookDir : possibleLookDirs) {
Vector eyePosition = new Vector(player.x, player.y + eyeHeight, player.z);
// Why do we have our own vector classes and MC vector classes mixed throughout this codebase?
Vector eyeLookDir = new Ray(player, eyePosition.getX(), eyePosition.getY(), eyePosition.getZ(), lookDir.x, lookDir.y).calculateDirection();

WrappedBlockState targetBlock;
Vector3i targetBlockVec = getTargetBlock(eyePosition, eyeLookDir, maxDistance);
Vector3i rayTracedBlockVec = getTargetBlock(eyePosition, eyeLookDir, maxDistance, interactBlockVec);

if (targetBlockVec == null) {
if (rayTracedBlockVec == null) {
continue;
}
targetBlock = player.compensatedWorld.getWrappedBlockStateAt(targetBlockVec);

if (interactBlock.equals(targetBlock)) {
if (interactBlockVec.equals(rayTracedBlockVec)) {
return true;
}
}
Expand All @@ -84,8 +71,8 @@ private boolean didRayTraceHit(BlockPlace place) {
return false;
}

private Vector3i getTargetBlock(Vector eyePosition, Vector eyeDirection, double maxDistance) {
HitData hitData = BlockRayTrace.getNearestReachHitResult(player, eyePosition, eyeDirection, maxDistance, maxDistance);
private Vector3i getTargetBlock(Vector eyePosition, Vector eyeDirection, double maxDistance, Vector3i targetBlockVec) {
HitData hitData = BlockRayTrace.getNearestReachHitResult003Compensated(player, eyePosition, eyeDirection, maxDistance, maxDistance, targetBlockVec);
if (hitData == null) return null;
return hitData.getPosition();
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/ac/grim/grimac/manager/CheckManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public CheckManager(GrimPlayer player) {
.put(PositionPlace.class, new PositionPlace(player))
.put(RotationPlace.class, new RotationPlace(player))
.put(DuplicateRotPlace.class, new DuplicateRotPlace(player))
.put(ContainerLOS.class, new ContainerLOS(player))
.put(BlockLOS.class, new BlockLOS(player))
.put(GhostBlockMitigation.class, new GhostBlockMitigation(player))
.build();

Expand Down
58 changes: 58 additions & 0 deletions src/main/java/ac/grim/grimac/utils/nmsutil/BlockRayTrace.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
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.type.StateType;
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 org.bukkit.util.Vector;
Expand Down Expand Up @@ -115,6 +116,63 @@ public static HitData getNearestReachHitResult(GrimPlayer player, Vector eyePos,
return getTraverseResult(player, null, startingPos, startingVec, trace, endPos, false, true, currentDistance);
}

@Nullable
public static HitData getNearestReachHitResult003Compensated(GrimPlayer player, Vector eyePos, Vector lookVec, double currentDistance, double maxDistance, Vector3i targetBlockVec) {
Vector3d startingPos = new Vector3d(eyePos.getX(), eyePos.getY(), eyePos.getZ());
Vector startingVec = new Vector(startingPos.getX(), startingPos.getY(), startingPos.getZ());
Ray trace = new Ray(eyePos, lookVec);
Vector endVec = trace.getPointAtDistance(maxDistance);
Vector3d endPos = new Vector3d(endVec.getX(), endVec.getY(), endVec.getZ());

StateType heldItem = null;
// boolean sourcesHaveHitbox = false;
boolean checkInside = true;
double knownDistance = currentDistance;

return traverseBlocks(player, startingPos, endPos, (block, vector3i) -> {
CollisionBox data = HitboxData.getBlockHitbox(player, heldItem, player.getClientVersion(), block, vector3i.getX(), vector3i.getY(), vector3i.getZ());
List<SimpleCollisionBox> boxes = new ArrayList<>();
data.downCast(boxes);

double bestHitResult = Double.MAX_VALUE;
Vector bestHitLoc = null;
BlockFace bestFace = null;

for (SimpleCollisionBox box : boxes) {
// Expand hitbox
if (vector3i.equals(targetBlockVec)) {
box.expand(player.getMovementThreshold());
} else {
// TODO figure out a way to shirnk every simplecollisionbox that makes up the CollisionBox by 0.03/0.0002
// In every direction except faces where they are joined together
}


Pair<Vector, BlockFace> intercept = ReachUtils.calculateIntercept(box, trace.getOrigin(), trace.getPointAtDistance(knownDistance));
if (intercept.getFirst() == null) continue; // No intercept

Vector hitLoc = intercept.getFirst();

// If inside a block, return empty result for reach check (don't bother checking this?)
if (checkInside && ReachUtils.isVecInside(box, trace.getOrigin())) {
return null;
}

if (hitLoc.distanceSquared(startingVec) < bestHitResult) {
bestHitResult = hitLoc.distanceSquared(startingVec);
bestHitLoc = hitLoc;
bestFace = intercept.getSecond();
}
}

if (bestHitLoc != null) {
return new HitData(vector3i, bestHitLoc, bestFace, block);
}

return null;
});
}

private static HitData getTraverseResult(GrimPlayer player, @Nullable StateType heldItem, Vector3d startingPos, Vector startingVec, Ray trace, Vector3d endPos, boolean sourcesHaveHitbox, boolean checkInside, double knownDistance) {
return traverseBlocks(player, startingPos, endPos, (block, vector3i) -> {
CollisionBox data = HitboxData.getBlockHitbox(player, heldItem, player.getClientVersion(), block, vector3i.getX(), vector3i.getY(), vector3i.getZ());
Expand Down

0 comments on commit 328596f

Please sign in to comment.