Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
695 changes: 21 additions & 674 deletions LICENSE

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,4 @@ A dedicated (proof of concept) anti cheat for GeyserMC project.

### Credits
- https://github.com/GeyserMC/Geyser
- https://github.com/oomph-ac/oomph (fireworks boosting boost code)
- https://github.com/RaphiMC/ViaBedrock
- https://github.com/Mojang/bedrock-protocol-docs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
import ac.boar.anticheat.util.geyser.BoarChunk;
import ac.boar.anticheat.util.geyser.BoarChunkSection;
import ac.boar.anticheat.util.math.Mutable;
import ac.boar.anticheat.util.math.Vec3;
import it.unimi.dsi.fastutil.longs.*;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.cloudburstmc.math.GenericMath;
import org.cloudburstmc.math.vector.Vector3i;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.type.Entity;
Expand Down Expand Up @@ -74,33 +74,22 @@ public EntityCache addToCache(final BoarPlayer player, final long runtimeId, fin
}

private int radius;
private int centerX, centerZ;
private Vector3i radiusCenter;

// (https://github.com/RaphiMC/ViaBedrock/blob/main/src/main/java/net/raphimc/viabedrock/protocol/storage/ChunkTracker.java#L263)
public void yeetOutOfRangeChunks() {
final Set<Long> chunksToRemove = new HashSet<>();
for (long key : this.chunks.keySet()) {
this.chunks.keySet().removeIf(key -> {
final int chunkX = (int) key, chunkZ = (int) (key >> 32);
if (this.isInLoadDistance(chunkX, chunkZ)) {
continue;
}

chunksToRemove.add(key);
}
for (long key : chunksToRemove) {
this.chunks.remove(key);
}
return this.isOutOfRadius(chunkX << 4, chunkZ << 4);
});
}

// (https://github.com/RaphiMC/ViaBedrock/blob/main/src/main/java/net/raphimc/viabedrock/protocol/storage/ChunkTracker.java#L247)
public boolean isInLoadDistance(final int chunkX, final int chunkZ) {
if (!(Math.abs(chunkX - this.centerX) <= this.radius && Math.abs(chunkZ - this.centerZ) <= this.radius)) {
final int centerX = GenericMath.floor(player.position.getX()) >> 4;
final int centerZ = GenericMath.floor(player.position.getZ()) >> 4;
return Math.abs(chunkX - centerX) <= this.radius && Math.abs(chunkZ - centerZ) <= this.radius;
}
public boolean isOutOfRadius(int chunkX, int chunkZ) {
Vec3 radiusCenter = new Vec3(this.radiusCenter).add(0.5f, 0.5f, 0.5f); // Properly correct eh?

return true;
// Still unsure about this... should we get rid of chunk sections, or chunk?
// Well since we're getting rid of chunks for now, let set the y pos to 0.
Vec3 chunkCenter = new Vec3(chunkX + 8, 0, chunkZ + 8);
return radiusCenter.squaredDistanceTo(chunkCenter) > this.radius * this.radius;
}

public void put(int x, int z, BoarChunkSection[] chunks) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void onPacketSend(final CloudburstPacketEvent event) {
return;
}

player.glideBoostTicks = packet.getDuration() / 2;
player.glideBoostTicks = Math.max(1, packet.getDuration() / 2);
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ public void onPacketSend(CloudburstPacketEvent event) {

if (event.getPacket() instanceof NetworkChunkPublisherUpdatePacket packet) {
player.sendLatencyStack(() -> {
world.setCenterX(packet.getPosition().getX() >> 4);
world.setCenterZ(packet.getPosition().getZ() >> 4);
world.setRadiusCenter(packet.getPosition());
world.setRadius(packet.getRadius());

world.yeetOutOfRangeChunks();
Expand Down Expand Up @@ -84,8 +83,7 @@ public void onPacketSend(CloudburstPacketEvent event) {
}

player.getLatencyUtil().queue(() -> {
if (!player.compensatedWorld.isInLoadDistance(packet.getChunkX(), packet.getChunkZ()) || dimension != player.compensatedWorld.getDimension()) {
// System.out.println("Out of distance...");
if (player.compensatedWorld.isOutOfRadius(packet.getChunkX() << 4, packet.getChunkZ() << 4) || dimension != player.compensatedWorld.getDimension()) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/ac/boar/anticheat/player/BoarPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public void tick() {
}

public void postTick() {
this.glideBoostTicks--;
this.glideBoostTicks--; // Glide boost should tick regardless if the player is gliding or not!
this.getItemUseTracker().postTick();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,45 +13,42 @@ public GlidingPredictionEngine(final BoarPlayer player) {
}

@Override
public Vec3 travel(Vec3 vec3) {
float velX = vec3.x, velY = vec3.y, velZ = vec3.z;

final Vec3 view = MathUtil.getRotationVector(player.pitch, player.yaw);

float v8 = player.pitch * MathUtil.DEGREE_TO_RAD;
float v9 = view.horizontalLength();
float v10 = view.lengthSquared();
float v11 = vec3.horizontalLength();
float v12 = TrigMath.cos(v8);
float v14 = v12 * (Math.min((float) GenericMath.sqrt(v10) * 2.5F, 1.0F) * v12);

float v15 = 1.0F / v9;

velY -= (v14 * 0.75F - 1.0F) * -player.getEffectiveGravity(vec3);
if (velY < 0.0 && v9 > 0.0) {
float v21 = velY * -0.1F * v14;
velZ += (view.z * v21 * v15);
velY += v21;
velX += (view.x * v21 * v15);
public Vec3 travel(Vec3 movement) {
final Vec3 lookAngle = MathUtil.getRotationVector(player.pitch, player.yaw);

// Based off https://mcsrc.dev/1/26.1.2/net/minecraft/world/entity/LivingEntity#L2536
float leanAngle = player.pitch * MathUtil.DEGREE_TO_RAD;
float lookHorLength = lookAngle.horizontalLength();
float moveHorLength = movement.horizontalLength();

// Lift force is kinda the only part somewhat differ from java, according to BDS?
float cosOfLeanAngle = TrigMath.cos(leanAngle);
float liftForce = cosOfLeanAngle * (Math.min((float) GenericMath.sqrt(lookAngle.lengthSquared()) * 2.5F, 1.0F) * cosOfLeanAngle);

movement.y -= (liftForce * 0.75F - 1.0F) * -player.getEffectiveGravity(movement);
if (movement.y < 0.0 && lookHorLength > 0.0) {
float convert = movement.y * -0.1F * liftForce;
movement = movement.add(lookAngle.x * convert / lookHorLength, convert, lookAngle.z * convert / lookHorLength);
}
if (v8 < 0.0) {
float v26 = TrigMath.sin(v8) * v11 * -0.039999999F;
velX -= v26 * view.x * v15;
velY += v26 * 3.2F;
velZ -= v26 * view.z * v15;
if (leanAngle < 0.0) {
float convert = TrigMath.sin(leanAngle) * moveHorLength * -0.04f;
movement = movement.subtract(convert * lookAngle.x / lookHorLength, convert * -3.2F, convert * lookAngle.z / lookHorLength);
}
if (v9 > 0.0) {
velX += (v15 * view.x * v11 - velX) * 0.1F;
velZ += (v15 * view.z * v11 - velZ) * 0.1F;
if (lookHorLength > 0.0) {
movement = movement.add(
(lookAngle.x / lookHorLength * moveHorLength - movement.x) * 0.1f, 0, (lookAngle.z / lookHorLength * moveHorLength - movement.z) * 0.1f
);
}

// It seems like it's the same as java code (https://mcsrc.dev/1/26.1.2/net/minecraft/world/entity/projectile/FireworkRocketEntity#L136)
// Although different is that it's ticking here instead of in the fireworks entity (since the fireworks entity logic doesn't really exist)
if (player.glideBoostTicks > 0) {
velX += (view.x * 0.1F) + (((view.x * 1.5F) - velX) * 0.5F);
velY += (view.y * 0.1F) + (((view.y * 1.5F) - velY) * 0.5F);
velZ += (view.z * 0.1F) + (((view.z * 1.5F) - velZ) * 0.5F);
movement = movement.add(lookAngle.x * 0.1f + (lookAngle.x * 1.5f - movement.x) * 0.5f,
lookAngle.y * 0.1f + (lookAngle.y * 1.5f - movement.y) * 0.5f,
lookAngle.z * 0.1f + (lookAngle.z * 1.5f - movement.z) * 0.5f);
}

return new Vec3(velX * 0.99000001F, velY * 0.98000002f, velZ * 0.99000001F);
return movement.multiply(0.99f, 0.98f, 0.99f);
}

@Override
Expand Down
Loading