Block Tracking, Fixing Reach falses

This commit is contained in:
Dawson
2022-08-12 17:19:26 -04:00
parent f75657744a
commit f601295f58
15 changed files with 497 additions and 182 deletions
@@ -25,7 +25,7 @@ public class Reach extends Check {
private int hbuffer;
public Timer lastAimOnTarget = new TickTimer();
private final Queue<Entity> attacks = new LinkedBlockingQueue<>();
private final Queue<Tuple<Entity, KLocation>> attacks = new LinkedBlockingQueue<>();
private static final EnumSet<EntityType> allowedEntityTypes = EnumSet.of(EntityType.ZOMBIE, EntityType.SHEEP,
EntityType.BLAZE, EntityType.SKELETON, EntityType.PLAYER, EntityType.VILLAGER, EntityType.IRON_GOLEM,
@@ -39,7 +39,7 @@ public class Reach extends Check {
public void onUse(WPacketPlayInUseEntity packet) {
if(packet.getAction() == WPacketPlayInUseEntity.EnumEntityUseAction.ATTACK
&& allowedEntityTypes.contains(packet.getEntity(getPlayer().getBukkitPlayer().getWorld()).getType())) {
attacks.add(packet.getEntity(getPlayer().getBukkitPlayer().getWorld()));
attacks.add(new Tuple<>(packet.getEntity(getPlayer().getBukkitPlayer().getWorld()), getPlayer().getMovement().getTo().getLoc().clone()));
}
}
@@ -49,11 +49,11 @@ public class Reach extends Check {
attacks.clear();
return;
}
Entity target;
Tuple<Entity, KLocation> target;
while((target = attacks.poll()) != null) {
//Updating new entity loc
Optional<EntityLocation> optionalEloc = getPlayer().getEntityLocationHandler().getEntityLocation(target);
Optional<EntityLocation> optionalEloc = getPlayer().getEntityLocationHandler().getEntityLocation(target.one);
if(!optionalEloc.isPresent()) {
return;
@@ -61,16 +61,10 @@ public class Reach extends Check {
final EntityLocation eloc = optionalEloc.get();
final KLocation to = getPlayer().getMovement().getTo().getLoc().clone(),
from = getPlayer().getMovement().getFrom().getLoc().clone();
final KLocation to = target.two;
//debug("current loc: %.4f, %.4f, %.4f", eloc.x, eloc.y, eloc.z);
to.y+= getPlayer().getInfo().isSneaking() ? (ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_14)
? 1.27f : 1.54f) : 1.62f;
from.y+= getPlayer().getInfo().isSneaking() ? (ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_14)
? 1.27f : 1.54f) : 1.62f;
if(eloc.x == 0 && eloc.y == 0 & eloc.z == 0) {
return;
}
@@ -82,29 +76,29 @@ public class Reach extends Check {
if(eloc.oldLocations.size() > 0) {
for (KLocation oldLocation : eloc.oldLocations) {
SimpleCollisionBox box = (SimpleCollisionBox)
EntityData.getEntityBox(oldLocation.toVector(), target);
EntityData.getEntityBox(oldLocation.toVector(), target.one);
if(getPlayer().getPlayerVersion().isBelow(ProtocolVersion.V1_9)) {
box = box.expand(0.1);
box = box.expand(0.1325);
} else box = box.expand(0.0325);
boxes.add(box);
}
for (KLocation oldLocation : eloc.interpolatedLocations) {
SimpleCollisionBox box = (SimpleCollisionBox)
EntityData.getEntityBox(oldLocation.toVector(), target);
EntityData.getEntityBox(oldLocation.toVector(), target.one);
if(getPlayer().getPlayerVersion().isBelow(ProtocolVersion.V1_9)) {
box = box.expand(0.1);
box = box.expand(0.1325);
} else box = box.expand(0.0325);
boxes.add(box);
}
} else {
for (KLocation oldLocation : eloc.interpolatedLocations) {
SimpleCollisionBox box = (SimpleCollisionBox)
EntityData.getEntityBox(oldLocation.toVector(), target);
EntityData.getEntityBox(oldLocation.toVector(), target.one);
if(getPlayer().getPlayerVersion().isBelow(ProtocolVersion.V1_9)) {
box = box.expand(0.1);
box = box.expand(0.1325);
} else box = box.expand(0.0325);
boxes.add(box);
}
@@ -114,24 +108,41 @@ public class Reach extends Check {
int hits = 0;
for (SimpleCollisionBox targetBox : boxes) {
final AxisAlignedBB vanillaBox = new AxisAlignedBB(targetBox);
boolean didSneakOrElytra = getPlayer().getInfo().getLastElytra().isNotPassed(40)
|| getPlayer().getInfo().getLastElytra().isNotPassed(40);
Vec3D intersectTo = vanillaBox.rayTrace(to.toVector(), MathUtils.getDirection(to), 10),
intersectFrom = vanillaBox.rayTrace(from.toVector(),
MathUtils.getDirection(from), 10);
if(!didSneakOrElytra) {
to.y+= 1.62f;
for (SimpleCollisionBox targetBox : boxes) {
final AxisAlignedBB vanillaBox = new AxisAlignedBB(targetBox);
if(intersectTo != null) {
lastAimOnTarget.reset();
hits++;
distance = Math.min(distance, intersectTo.distanceSquared(new Vec3D(to.x, to.y, to.z)));
collided = true;
Vec3D intersectTo = vanillaBox.rayTrace(to.toVector(), MathUtils.getDirection(to), 10);
if(intersectTo != null) {
lastAimOnTarget.reset();
hits++;
distance = Math.min(distance, intersectTo.distanceSquared(new Vec3D(to.x, to.y, to.z)));
collided = true;
}
}
if(intersectFrom != null) {
lastAimOnTarget.reset();
hits++;
distance = Math.min(distance, intersectFrom.distanceSquared(new Vec3D(from.x, from.y, from.z)));
collided = true;
//Checking all possible eyeheights since client actions notoriously desync from the server side
} else {
for (double eyeHeight : getPlayer().getMovement().getEyeHeights()) {
for (SimpleCollisionBox targetBox : boxes) {
final AxisAlignedBB vanillaBox = new AxisAlignedBB(targetBox);
KLocation from = to.clone();
from.y+= eyeHeight;
Vec3D intersectTo = vanillaBox.rayTrace(from.toVector(), MathUtils.getDirection(from), 10);
if(intersectTo != null) {
lastAimOnTarget.reset();
hits++;
distance = Math.min(distance, intersectTo.distanceSquared(new Vec3D(from.x, from.y, from.z)));
collided = true;
}
}
}
}
@@ -9,10 +9,14 @@ import dev.brighten.ac.packet.ProtocolVersion;
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
import dev.brighten.ac.utils.BlockUtils;
import dev.brighten.ac.utils.MathHelper;
import dev.brighten.ac.utils.math.IntVector;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.util.CraftMagicNumbers;
import org.bukkit.potion.PotionEffectType;
import java.util.Deque;
@CheckData(name = "Speed", type = CheckType.MOVEMENT)
public class Speed extends Check {
private boolean lastLastClientGround;
@@ -38,16 +42,17 @@ public class Speed extends Check {
if (underBlock == null || lastUnderBlock == null)
return;
float friction = CraftMagicNumbers.getBlock(underBlock).frictionFactor,
lfriction = CraftMagicNumbers.getBlock(lastUnderBlock).frictionFactor;
Deque<Material> frictionList = getPlayer().getBlockUpdateHandler()
.getPossibleMaterials(new IntVector(underBlock.getX(), underBlock.getY(), underBlock.getZ())),
lfrictionList = getPlayer().getBlockUpdateHandler()
.getPossibleMaterials(new IntVector(lastUnderBlock.getX(), lastUnderBlock.getY(), lastUnderBlock.getZ()));
check:
{
if (!packet.isMoved()
/*|| getPlayer().playerInfo.generalCancel
|| getPlayer().playerInfo.onLadder
|| getPlayer().playerInfo.lastEntityCollision.isNotPassed(2)
|| getPlayer().playerInfo.lastVelocity.isNotPassed(1)*/
|| getPlayer().getInfo().isGeneralCancel()
|| getPlayer().getBlockInformation().onClimbable
|| getPlayer().getInfo().getVelocity().isNotPassed(1)
|| getPlayer().getBlockInformation().inLiquid
|| getPlayer().getBlockInformation().collidesHorizontally) {
break check;
@@ -59,129 +64,137 @@ public class Speed extends Check {
loop:
{
for (int f = -1; f < 2; f++) {
for (int s = -1; s < 2; s++) {
for (boolean sprinting : TRUE_FALSE) {
for (int fastMath = 0; fastMath <= 2; fastMath++) {
for (boolean attack : TRUE_FALSE) {
for (boolean using : TRUE_FALSE) {
for (boolean sneaking : TRUE_FALSE) {
for (boolean jumped : TRUE_FALSE) {
for(Material underMaterial : frictionList) {
for(Material lastUnderMaterial : lfrictionList) {
for (int s = -1; s < 2; s++) {
for (boolean sprinting : TRUE_FALSE) {
for (int fastMath = 0; fastMath <= 2; fastMath++) {
for (boolean attack : TRUE_FALSE) {
for (boolean using : TRUE_FALSE) {
for (boolean sneaking : TRUE_FALSE) {
for (boolean jumped : TRUE_FALSE) {
float forward = f, strafe = s;
float forward = f, strafe = s;
if (sneaking) {
forward *= 0.3;
strafe *= 0.3;
}
if (sneaking) {
forward *= 0.3;
strafe *= 0.3;
}
if (using) {
forward *= 0.2;
strafe *= 0.2;
}
float friction = CraftMagicNumbers.getBlock(underMaterial).frictionFactor;
float lfriction = CraftMagicNumbers.getBlock(lastUnderMaterial).frictionFactor;
//Multiplying by 0.98 like in client
forward *= 0.9800000190734863F;
strafe *= 0.9800000190734863F;
if (using) {
forward *= 0.2;
strafe *= 0.2;
}
double aiMoveSpeed = getPlayer().getBukkitPlayer().getWalkSpeed() / 2;
//Multiplying by 0.98 like in client
forward *= 0.9800000190734863F;
strafe *= 0.9800000190734863F;
float drag = 0.91f;
double lmotionX = getPlayer().getMovement().getLDeltaX(),
lmotionZ = getPlayer().getMovement().getLDeltaZ();
double aiMoveSpeed = getPlayer().getBukkitPlayer().getWalkSpeed() / 2;
//The "1" will effectively remove lastFriction from the equation
lmotionX *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D;
lmotionZ *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D;
float drag = 0.91f;
double lmotionX = getPlayer().getMovement().getLDeltaX(),
lmotionZ = getPlayer().getMovement().getLDeltaZ();
//Running multiplication done after previous prediction
if (getPlayer().getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) {
if (Math.abs(lmotionX) < 0.003)
lmotionX = 0;
if (Math.abs(lmotionZ) < 0.003)
lmotionZ = 0;
} else {
if (Math.abs(lmotionX) < 0.005)
lmotionX = 0;
if (Math.abs(lmotionZ) < 0.005)
lmotionZ = 0;
}
//The "1" will effectively remove lastFriction from the equation
lmotionX *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D;
lmotionZ *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D;
// Attack slowdown
if (attack) {
lmotionX *= 0.6;
lmotionZ *= 0.6;
}
//Running multiplication done after previous prediction
if (getPlayer().getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) {
if (Math.abs(lmotionX) < 0.003)
lmotionX = 0;
if (Math.abs(lmotionZ) < 0.003)
lmotionZ = 0;
} else {
if (Math.abs(lmotionX) < 0.005)
lmotionX = 0;
if (Math.abs(lmotionZ) < 0.005)
lmotionZ = 0;
}
if (sprinting) aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D;
// Attack slowdown
if (attack) {
lmotionX *= 0.6;
lmotionZ *= 0.6;
}
if (getPlayer().getPotionHandler().hasPotionEffect(PotionEffectType.SPEED))
aiMoveSpeed += (getPlayer().getPotionHandler().getEffectByType(PotionEffectType.SPEED)
.get()
.getAmplifier() + 1) * (double) 0.20000000298023224D * aiMoveSpeed;
if (getPlayer().getPotionHandler().hasPotionEffect(PotionEffectType.SLOW))
aiMoveSpeed += (getPlayer().getPotionHandler().getEffectByType(PotionEffectType.SLOW)
.get()
.getAmplifier() + 1) * (double) -0.15000000596046448D * aiMoveSpeed;
if (sprinting)
aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D;
float f5;
if (onGround) {
drag *= friction;
if (getPlayer().getPotionHandler().hasPotionEffect(PotionEffectType.SPEED))
aiMoveSpeed += (getPlayer().getPotionHandler().getEffectByType(PotionEffectType.SPEED)
.get()
.getAmplifier() + 1) * (double) 0.20000000298023224D * aiMoveSpeed;
if (getPlayer().getPotionHandler().hasPotionEffect(PotionEffectType.SLOW))
aiMoveSpeed += (getPlayer().getPotionHandler().getEffectByType(PotionEffectType.SLOW)
.get()
.getAmplifier() + 1) * (double) -0.15000000596046448D * aiMoveSpeed;
f5 = (float) (aiMoveSpeed * (0.16277136F / (drag * drag * drag)));
float f5;
if (onGround) {
drag *= friction;
if (sprinting && jumped) {
float rot = getPlayer().getMovement().getTo().getLoc().yaw * 0.017453292F;
lmotionX -= sin(fastMath, rot) * 0.2F;
lmotionZ += cos(fastMath, rot) * 0.2F;
}
f5 = (float) (aiMoveSpeed * (0.16277136F / (drag * drag * drag)));
} else f5 = sprinting ? 0.025999999F : 0.02f;
if (sprinting && jumped) {
float rot = getPlayer().getMovement().getTo().getLoc().yaw * 0.017453292F;
lmotionX -= sin(fastMath, rot) * 0.2F;
lmotionZ += cos(fastMath, rot) * 0.2F;
}
if (getPlayer().getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) {
double keyedMotion = forward * forward + strafe * strafe;
} else f5 = sprinting ? 0.025999999F : 0.02f;
if (keyedMotion >= 1.0E-4F) {
keyedMotion = f5 / Math.max(1.0, Math.sqrt(keyedMotion));
forward *= keyedMotion;
strafe *= keyedMotion;
if (getPlayer().getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) {
double keyedMotion = forward * forward + strafe * strafe;
final float yawSin = sin(fastMath,
getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F),
yawCos = cos(fastMath,
getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F);
if (keyedMotion >= 1.0E-4F) {
keyedMotion = f5 / Math.max(1.0, Math.sqrt(keyedMotion));
forward *= keyedMotion;
strafe *= keyedMotion;
lmotionX += (strafe * yawCos - forward * yawSin);
lmotionZ += (forward * yawCos + strafe * yawSin);
}
} else {
float keyedMotion = forward * forward + strafe * strafe;
final float yawSin = sin(fastMath,
getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F),
yawCos = cos(fastMath,
getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F);
if (keyedMotion >= 1.0E-4F) {
keyedMotion = f5 / Math.max(1.0f, MathHelper.sqrt_float(keyedMotion));
forward *= keyedMotion;
strafe *= keyedMotion;
lmotionX += (strafe * yawCos - forward * yawSin);
lmotionZ += (forward * yawCos + strafe * yawSin);
}
} else {
float keyedMotion = forward * forward + strafe * strafe;
final float yawSin = sin(fastMath,
getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F),
yawCos = cos(fastMath,
getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F);
if (keyedMotion >= 1.0E-4F) {
keyedMotion = f5 / Math.max(1.0f, MathHelper.sqrt_float(keyedMotion));
forward *= keyedMotion;
strafe *= keyedMotion;
lmotionX += (strafe * yawCos - forward * yawSin);
lmotionZ += (forward * yawCos + strafe * yawSin);
}
}
final float yawSin = sin(fastMath,
getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F),
yawCos = cos(fastMath,
getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F);
double diffX = getPlayer().getMovement().getDeltaX() - lmotionX,
diffZ = getPlayer().getMovement().getDeltaZ() - lmotionZ;
double delta = (diffX * diffX) + (diffZ * diffZ);
lmotionX += (strafe * yawCos - forward * yawSin);
lmotionZ += (forward * yawCos + strafe * yawSin);
}
}
if (delta < smallestDelta) {
smallestDelta = delta;
pmotionx = lmotionX;
pmotionz = lmotionZ;
double diffX = getPlayer().getMovement().getDeltaX() - lmotionX,
diffZ = getPlayer().getMovement().getDeltaZ() - lmotionZ;
double delta = (diffX * diffX) + (diffZ * diffZ);
if (delta < 1E-15) {
break loop;
if (delta < smallestDelta) {
smallestDelta = delta;
pmotionx = lmotionX;
pmotionz = lmotionZ;
if (delta < 1E-15) {
break loop;
}
}
}
}
}
@@ -7,10 +7,14 @@ import dev.brighten.ac.check.Check;
import dev.brighten.ac.check.CheckData;
import dev.brighten.ac.data.APlayer;
import dev.brighten.ac.messages.Messages;
import dev.brighten.ac.packet.handler.HandlerAbstract;
import dev.brighten.ac.utils.Color;
import dev.brighten.ac.utils.Init;
import dev.brighten.ac.utils.MiscUtils;
import dev.brighten.ac.utils.Priority;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_8_R3.PacketDataSerializer;
import net.minecraft.server.v1_8_R3.PacketPlayOutCustomPayload;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -96,4 +100,23 @@ public class AnticheatCommand extends BaseCommand {
sender.sendMessage(MiscUtils.line(Color.Dark_Gray));
});
}
@Subcommand("runtest")
public void onCommand(Player player) {
long start = System.currentTimeMillis();
PacketDataSerializer serializer = new PacketDataSerializer(Unpooled.buffer());
serializer.writeLong(start);
PacketPlayOutCustomPayload payload = new PacketPlayOutCustomPayload("Time|Send", serializer);
HandlerAbstract.getHandler().sendPacket(player, payload);
Anticheat.INSTANCE.getPlayerRegistry().getPlayer(player.getUniqueId()).ifPresent(aplayer -> {
aplayer.runInstantAction(ka -> {
if(!ka.isEnd()) {
long transDelta = System.currentTimeMillis() - start;
player.sendMessage("Transaction delta: " + transDelta + "ms");
}
});
});
}
}
@@ -11,6 +11,7 @@ import dev.brighten.ac.data.obj.InstantAction;
import dev.brighten.ac.data.obj.NormalAction;
import dev.brighten.ac.handler.EntityLocationHandler;
import dev.brighten.ac.handler.PotionHandler;
import dev.brighten.ac.handler.block.BlockUpdateHandler;
import dev.brighten.ac.handler.keepalive.KeepAlive;
import dev.brighten.ac.handler.protocolsupport.ProtocolAPI;
import dev.brighten.ac.messages.Messages;
@@ -45,6 +46,10 @@ public class APlayer {
private PotionHandler potionHandler;
@Getter
private EntityLocationHandler entityLocationHandler;
@Getter
private BlockUpdateHandler blockUpdateHandler;
@Getter
private GeneralInformation info;
@Getter
@@ -87,6 +92,7 @@ public class APlayer {
this.movement = new MovementHandler(this);
this.potionHandler = new PotionHandler(this);
this.entityLocationHandler = new EntityLocationHandler(this);
this.blockUpdateHandler = new BlockUpdateHandler(this);
this.info = new GeneralInformation();
this.lagInfo = new LagInformation();
this.blockInformation = new BlockInformation(this);
@@ -17,10 +17,12 @@ import java.util.Optional;
@Setter
public class GeneralInformation {
private Optional<Block> blockOnTo, blockBelow;
private Timer lastMove = new TickTimer(), vehicleSwitch = new TickTimer();
private Timer lastMove = new TickTimer(), vehicleSwitch = new TickTimer(),
lastSneak = new TickTimer(), velocity = new TickTimer(),
lastElytra = new TickTimer();
private LivingEntity target;
private boolean serverGround, lastServerGround, nearGround, worldLoaded, generalCancel, inVehicle, creative,
sneaking, sprinting;
sneaking, sprinting, gliding, riptiding;
private List<Entity> nearbyEntities = Collections.emptyList();
private PastLocation targetPastLocation = new PastLocation();;
private PastLocation targetPastLocation = new PastLocation();
}
@@ -228,6 +228,13 @@ public class MovementHandler {
boolean hasLevitation = ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_9)
&& player.getPotionHandler().hasPotionEffect(XPotion.LEVITATION.getPotionEffectType());
player.getInfo().setRiptiding(CompatHandler.getInstance().isRiptiding(player.getBukkitPlayer()));
player.getInfo().setGliding(CompatHandler.getInstance().isGliding(player.getBukkitPlayer()));
// Resetting glide/sneak timers
if(player.getInfo().isGliding()) player.getInfo().getLastElytra().reset();
if(player.getInfo().isSneaking()) player.getInfo().getLastSneak().reset();
player.getInfo().setGeneralCancel(player.getBukkitPlayer().getAllowFlight()
|| moveTicks == 0
|| excuseNextFlying
@@ -237,8 +244,8 @@ public class MovementHandler {
|| player.getInfo().isInVehicle()
|| player.getInfo().getVehicleSwitch().isNotPassed(1)
|| player.getBukkitPlayer().isSleeping()
|| CompatHandler.getInstance().isRiptiding(player.getBukkitPlayer())
|| CompatHandler.getInstance().isGliding(player.getBukkitPlayer())
|| player.getInfo().isGliding()
|| player.getInfo().isRiptiding()
|| hasLevitation);
/*
@@ -283,6 +290,14 @@ public class MovementHandler {
return result;
}
public double[] getEyeHeights() {
if(player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_14)) {
return new double[] {0.4f, 1.27f, 1.62f};
} else if(player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) {
return new double[] {0.4f, 1.54f, 1.62f};
} else return new double[] {1.54f, 1.62f};
}
public static float getExpiermentalDeltaY(APlayer data) {
float deltaPitch = data.getMovement().getDeltaPitch();
float sens = data.getMovement().sensitivityY;
@@ -85,8 +85,6 @@ public class EntityLocationHandler {
eloc.newPitch += packet.getPitch();
eloc.increment = 3;
eloc.interpolatedLocations.clear();
});
}
@@ -120,7 +118,6 @@ public class EntityLocationHandler {
eloc.newZ = eloc.z = packet.getZ();
eloc.newYaw = eloc.yaw = packet.getYaw();
eloc.newPitch = eloc.pitch = packet.getPitch();
eloc.interpolatedLocations.clear();
} else {
eloc.newX = packet.getX();
eloc.newY = packet.getY();
@@ -129,7 +126,6 @@ public class EntityLocationHandler {
eloc.newPitch = packet.getPitch();
eloc.increment = 3;
eloc.interpolatedLocations.clear();
}
} else {
//We don't need to do version checking here. Atlas handles this for us.
@@ -159,6 +155,7 @@ public class EntityLocationHandler {
if(data.getInfo().getTarget() != null && data.getInfo().getTarget().getEntityId() == entity.getEntityId()) {
data.runInstantAction(ia -> {
if(!ia.isEnd()) {
action.run();
} else entityLocationMap.get(entity.getUniqueId()).oldLocations.clear();
});
@@ -5,13 +5,13 @@ import dev.brighten.ac.data.APlayer;
import dev.brighten.ac.data.obj.NormalAction;
import dev.brighten.ac.packet.ProtocolVersion;
import dev.brighten.ac.packet.wrapper.PacketType;
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInEntityAction;
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInUseEntity;
import dev.brighten.ac.packet.wrapper.in.*;
import dev.brighten.ac.packet.wrapper.out.*;
import dev.brighten.ac.utils.KLocation;
import dev.brighten.ac.utils.MovementUtils;
import lombok.val;
import net.minecraft.server.v1_8_R3.PacketDataSerializer;
import net.minecraft.server.v1_8_R3.PacketPlayInCustomPayload;
import net.minecraft.server.v1_8_R3.PacketPlayInSteerVehicle;
import net.minecraft.server.v1_8_R3.PacketPlayInTransaction;
import org.bukkit.entity.Entity;
@@ -108,12 +108,28 @@ public class PacketHandler {
player.getMovement().process(packet, System.currentTimeMillis());
break;
}
case BLOCK_CHANGE: {
WPacketPlayOutBlockChange packet = (WPacketPlayOutBlockChange) packetObject;
player.getBlockUpdateHandler().runUpdate(packet);
break;
}
case MULTI_BLOCK_CHANGE: {
WPacketPlayOutMultiBlockChange packet = (WPacketPlayOutMultiBlockChange) packetObject;
player.getBlockUpdateHandler().runUpdate(packet);
break;
}
case ENTITY_EFFECT: {
WPacketPlayOutEntityEffect packet = (WPacketPlayOutEntityEffect) packetObject;
player.getPotionHandler().onPotionEffect(packet);
break;
}
case VELOCITY: {
player.runKeepaliveAction(ka -> player.getInfo().getVelocity().reset());
break;
}
case SERVER_POSITION: {
player.getMovement().addPosition((WPacketPlayOutPosition) packetObject);
break;
@@ -141,6 +157,24 @@ public class PacketHandler {
break;
}
case CLIENT_PAYLOAD: {
PacketPlayInCustomPayload packet = (PacketPlayInCustomPayload) packetObject;
if(packet.a().equals("Time|Receive")) {
PacketDataSerializer serial = packet.b();
long serverTime = serial.readLong();
long clientReceivedTime = serial.readLong();
long currentTime = System.currentTimeMillis();
long serverPing = clientReceivedTime - serverTime;
long clientToServer = currentTime - clientReceivedTime;
long totalFeedback = currentTime - serverTime;
player.getBukkitPlayer().sendMessage(String.format("total: %sms client-server: %sms server-client: %sms", totalFeedback, clientToServer, serverPing));
}
break;
}
case ENTITY_ACTION: {
WPacketPlayInEntityAction packet = (WPacketPlayInEntityAction) packetObject;
@@ -189,6 +223,18 @@ public class PacketHandler {
}
break;
}
case BLOCK_DIG: {
WPacketPlayInBlockPlace packet = (WPacketPlayInBlockPlace) packetObject;
player.getBlockUpdateHandler().onPlace(packet);
break;
}
case BLOCK_PLACE: {
WPacketPlayInBlockDig packet = (WPacketPlayInBlockDig) packetObject;
player.getBlockUpdateHandler().onDig(packet);
break;
}
}
player.callPacket(packetObject);
@@ -0,0 +1,137 @@
package dev.brighten.ac.handler.block;
import dev.brighten.ac.data.APlayer;
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockDig;
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockPlace;
import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutBlockChange;
import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutMultiBlockChange;
import dev.brighten.ac.utils.BlockUtils;
import dev.brighten.ac.utils.Tuple;
import dev.brighten.ac.utils.math.IntVector;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.bukkit.Material;
import org.bukkit.block.Block;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@RequiredArgsConstructor
public class BlockUpdateHandler {
private final Map<IntVector, Deque<Material>> blockInformation = new ConcurrentHashMap<>();
private final APlayer player;
public void onWorldChange() {
blockInformation.clear();
}
/**
* Keep track of block placements since the Bukkit API will be a bit behind
* @param place
*/
public void onPlace(WPacketPlayInBlockPlace place) {
if(!place.getItemStack().getType().isBlock()) return;
Deque<Material> possible = getPossibleMaterials(place.getBlockPos());
possible.add(place.getItemStack().getType());
}
/**
* Keep track of block breaking since the Bukkit API will be a bit behind.
* @param dig
*/
public void onDig(WPacketPlayInBlockDig dig) {
Deque<Material> possible = getPossibleMaterials(dig.getBlockPos());
possible.clear();
possible.add(Material.AIR);
}
public void runUpdate(WPacketPlayOutBlockChange packet) {
Deque<Material> blockInfo = blockInformation.compute(packet.getBlockLocation(), (blockLoc, blockI) -> {
if(blockI == null) {
blockI = new LinkedList<>();
val optional = BlockUtils
.getBlockAsync(packet.getBlockLocation().toBukkitVector()
.toLocation(player.getBukkitPlayer().getWorld()));
if(optional.isPresent()) {
Block block = optional.get();
blockI.add(block.getType());
}
}
return blockI;
});
// Updating block information
player.runInstantAction(k -> {
if(!k.isEnd()) {
blockInfo.add(packet.getMaterial());
} else if(blockInfo.size() > 1) {
blockInfo.removeFirst();
}
});
}
public void runUpdate(WPacketPlayOutMultiBlockChange packet) {
List<Tuple<Deque<Material>, Material>> changes = new ArrayList<>();
for (WPacketPlayOutMultiBlockChange.BlockChange change : packet.getChanges()) {
Deque<Material> blockInfo = blockInformation.compute(change.getLocation(), (blockLoc, blockI) -> {
if(blockI == null) {
blockI = new LinkedList<>();
val optional = BlockUtils
.getBlockAsync(change.getLocation().toBukkitVector()
.toLocation(player.getBukkitPlayer().getWorld()));
if(optional.isPresent()) {
Block block = optional.get();
blockI.add(block.getType());
}
}
return blockI;
});
changes.add(new Tuple<>(blockInfo, change.getMaterial()));
}
player.runInstantAction(k -> {
if(!k.isEnd()) {
for (Tuple<Deque<Material>, Material> tuple : changes) {
tuple.one.add(tuple.two);
}
} else {
for (Tuple<Deque<Material>, Material> tuple : changes) {
if(tuple.one.size() > 1) {
tuple.one.removeFirst();
}
}
}
});
}
public Deque<Material> getPossibleMaterials(IntVector loc) {
return blockInformation.compute(loc, (blockLoc, blockI) -> {
if(blockI == null) {
blockI = new LinkedList<>();
val optional = BlockUtils
.getBlockAsync(loc.toBukkitVector()
.toLocation(player.getBukkitPlayer().getWorld()));
if(optional.isPresent()) {
Block block = optional.get();
blockI.add(block.getType());
}
}
return blockI;
});
}
}
@@ -13,6 +13,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.Optional;
@@ -82,6 +83,14 @@ public class JoinListener implements Listener {
player.callEvent(event);
}
@EventHandler
public void onTeleport(PlayerTeleportEvent event) {
if(event.getFrom().getWorld().equals(event.getTo().getWorld())) return;
Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId())
.ifPresent(player -> player.getBlockUpdateHandler().onWorldChange());
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
Anticheat.INSTANCE.getPlayerRegistry().unregister(event.getPlayer().getUniqueId());
@@ -30,4 +30,8 @@ public interface PacketConverter {
WPacketPlayOutEntityTeleport processEntityTeleport(Object object);
WPacketHandshakingInSetProtocol processHandshakingProtocol(Object object);
WPacketPlayOutBlockChange processBlockChange(Object object);
WPacketPlayOutMultiBlockChange processMultiBlockChange(Object object);
}
@@ -85,13 +85,6 @@ public enum PacketType {
return Optional.empty();
}
public static class Login {
public static final String HANDSHAKE = "PacketHandshakingInSetProtocol";
public static final String PING = "PacketStatusInPing";
public static final String STATUS_START = "PacketStatusInStart";
public static final String LOGIN_START = "PacketLoginInStart";
}
public static Object processType(PacketType type, Object object) {
PacketConverter convert = Anticheat.INSTANCE.getPacketProcessor().getPacketConverter();
@@ -127,6 +120,10 @@ public enum PacketType {
return convert.processEntityTeleport(object);
case LOGIN_HANDSHAKE:
return convert.processHandshakingProtocol(object);
case BLOCK_CHANGE:
return convert.processBlockChange(object);
case MULTI_BLOCK_CHANGE:
return convert.processMultiBlockChange(object);
default:
return object;
}
@@ -9,7 +9,9 @@ import dev.brighten.ac.utils.reflections.types.WrappedClass;
import dev.brighten.ac.utils.reflections.types.WrappedField;
import io.netty.buffer.Unpooled;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_8_R3.util.CraftMagicNumbers;
import org.bukkit.util.Vector;
import java.io.IOException;
@@ -238,4 +240,55 @@ public class Processor_18 implements PacketConverter {
.protocol(WPacketHandshakingInSetProtocol.EnumProtocol.valueOf(EnumProtocol.a(serial.e()).name()))
.build();
}
@Override
public WPacketPlayOutBlockChange processBlockChange(Object object) {
PacketPlayOutBlockChange packet = (PacketPlayOutBlockChange) object;
PacketDataSerializer serial = new PacketDataSerializer(Unpooled.buffer());
try {
packet.b(serial);
} catch (IOException e) {
throw new RuntimeException(e);
}
BlockPosition blockPos = serial.c();
IntVector vecPos = new IntVector(blockPos.getX(), blockPos.getY(), blockPos.getZ());
Material material = CraftMagicNumbers.getMaterial(packet.block.getBlock());
return WPacketPlayOutBlockChange.builder()
.blockLocation(vecPos)
.material(material)
.build();
}
@Override
public WPacketPlayOutMultiBlockChange processMultiBlockChange(Object object) {
PacketPlayOutMultiBlockChange packet = (PacketPlayOutMultiBlockChange) object;
PacketDataSerializer serial = new PacketDataSerializer(Unpooled.buffer());
try {
packet.b(serial);
} catch (IOException e) {
throw new RuntimeException(e);
}
final int[] chunkLoc = new int[] {serial.readInt(), serial.readInt()};
final WPacketPlayOutMultiBlockChange.BlockChange[]
blockChanges = new WPacketPlayOutMultiBlockChange.BlockChange[serial.e()];
for (int i = 0; i < blockChanges.length; i++) {
short encodedloc = serial.readShort();
IntVector loc = new IntVector(encodedloc >> 12 & 15, encodedloc & 255, encodedloc >> 8 & 15);
Material blockType = CraftMagicNumbers.getMaterial(Block.d.a(serial.e()).getBlock());
blockChanges[i] = new WPacketPlayOutMultiBlockChange.BlockChange(loc, blockType);
}
return WPacketPlayOutMultiBlockChange.builder()
.chunk(chunkLoc)
.changes(blockChanges)
.build();
}
}
+14 -27
View File
@@ -8,6 +8,7 @@ package dev.brighten.ac.utils;
import org.bukkit.Location;
import javax.annotation.Nullable;
import java.util.Objects;
public class Vec3D {
public static final Vec3D a = new Vec3D(0.0D, 0.0D, 0.0D);
@@ -138,33 +139,6 @@ public class Vec3D {
}
}
public boolean equals(Object var1) {
if (this == var1) {
return true;
} else if (!(var1 instanceof Vec3D)) {
return false;
} else {
Vec3D var2 = (Vec3D)var1;
if (Double.compare(var2.x, this.x) != 0) {
return false;
} else if (Double.compare(var2.y, this.y) != 0) {
return false;
} else {
return Double.compare(var2.z, this.z) == 0;
}
}
}
public int hashCode() {
long var2 = Double.doubleToLongBits(this.x);
int var1 = (int)(var2 ^ var2 >>> 32);
var2 = Double.doubleToLongBits(this.y);
var1 = 31 * var1 + (int)(var2 ^ var2 >>> 32);
var2 = Double.doubleToLongBits(this.z);
var1 = 31 * var1 + (int)(var2 ^ var2 >>> 32);
return var1;
}
public String toString() {
return "(" + this.x + ", " + this.y + ", " + this.z + ")";
}
@@ -186,4 +160,17 @@ public class Vec3D {
double var8 = this.z * (double)var2 - this.x * (double)var3;
return new Vec3D(var4, var6, var8);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Vec3D vec3D = (Vec3D) o;
return Double.compare(vec3D.x, x) == 0 && Double.compare(vec3D.y, y) == 0 && Double.compare(vec3D.z, z) == 0;
}
@Override
public int hashCode() {
return Objects.hash(x, y, z);
}
}
@@ -6,6 +6,8 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import org.bukkit.util.Vector;
import java.util.Objects;
@AllArgsConstructor
@NoArgsConstructor
public class IntVector {
@@ -25,4 +27,17 @@ public class IntVector {
public String toString() {
return String.format("IntVector[%s, %s, %s]", x, y, z);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
IntVector intVector = (IntVector) o;
return x == intVector.x && y == intVector.y && z == intVector.z;
}
@Override
public int hashCode() {
return Objects.hash(x, y, z);
}
}