mirror of
https://github.com/funkemunky/KauriV3.git
synced 2026-06-02 14:32:17 +00:00
Fixing tons of issues
- Fixing Velocity B falses - Fixing lilypad false positives by accounting for it on interact. - New Block (A) with block place interaction check - Fixing Block B false positive. - Fixing Horizontal false positive and bypass - Fixing Fly (B) on liquids and climables. - Fixing Fly (A) on liquids and climables
This commit is contained in:
+15
-15
@@ -21,7 +21,7 @@ import java.util.*;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
@CheckData(name = "Hitbox", type = CheckType.COMBAT)
|
||||
public class Reach extends Check {
|
||||
public class Hitbox extends Check {
|
||||
private float buffer;
|
||||
private int hbuffer;
|
||||
|
||||
@@ -32,7 +32,7 @@ public class Reach extends Check {
|
||||
EntityType.BLAZE, EntityType.SKELETON, EntityType.PLAYER, EntityType.VILLAGER, EntityType.IRON_GOLEM,
|
||||
EntityType.WITCH, EntityType.COW, EntityType.CREEPER);
|
||||
|
||||
public Reach(APlayer player) {
|
||||
public Hitbox(APlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@@ -57,19 +57,19 @@ public class Reach extends Check {
|
||||
|
||||
while((target = attacks.poll()) != null) {
|
||||
//Updating new entity loc
|
||||
Optional<EntityLocation> optionalEloc = player.getEntityLocationHandler().getEntityLocation(target.one);
|
||||
Optional<Tuple<EntityLocation, EntityLocation>> optionalEloc = player.getEntityLocationHandler().getEntityLocation(target.one);
|
||||
|
||||
if(!optionalEloc.isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final EntityLocation eloc = optionalEloc.get();
|
||||
final Tuple<EntityLocation, EntityLocation> eloc = optionalEloc.get();
|
||||
|
||||
final KLocation to = target.two;
|
||||
|
||||
debug("current loc: %.4f, %.4f, %.4f", eloc.x, eloc.y, eloc.z);
|
||||
debug("current loc: %.4f, %.4f, %.4f", eloc.one.x, eloc.one.y, eloc.one.z);
|
||||
|
||||
if(eloc.x == 0 && eloc.y == 0 & eloc.z == 0) {
|
||||
if(eloc.one.x == 0 && eloc.one.y == 0 & eloc.one.z == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ public class Reach extends Check {
|
||||
boolean collided = false; //Using this to compare smaller numbers than Double.MAX_VALUE. Slightly faster
|
||||
|
||||
List<SimpleCollisionBox> boxes = new ArrayList<>();
|
||||
if(eloc.oldLocations.size() > 0) {
|
||||
for (KLocation oldLocation : eloc.oldLocations) {
|
||||
if(eloc.two != null) {
|
||||
for (KLocation oldLocation : eloc.one.interpolatedLocations) {
|
||||
SimpleCollisionBox box = (SimpleCollisionBox)
|
||||
EntityData.getEntityBox(oldLocation.toVector(), target.one);
|
||||
|
||||
@@ -87,7 +87,7 @@ public class Reach extends Check {
|
||||
} else box = box.expand(0.0325);
|
||||
boxes.add(box);
|
||||
}
|
||||
for (KLocation oldLocation : eloc.interpolatedLocations) {
|
||||
for (KLocation oldLocation : eloc.two.interpolatedLocations) {
|
||||
SimpleCollisionBox box = (SimpleCollisionBox)
|
||||
EntityData.getEntityBox(oldLocation.toVector(), target.one);
|
||||
|
||||
@@ -97,7 +97,7 @@ public class Reach extends Check {
|
||||
boxes.add(box);
|
||||
}
|
||||
} else {
|
||||
for (KLocation oldLocation : eloc.interpolatedLocations) {
|
||||
for (KLocation oldLocation : eloc.one.interpolatedLocations) {
|
||||
SimpleCollisionBox box = (SimpleCollisionBox)
|
||||
EntityData.getEntityBox(oldLocation.toVector(), target.one);
|
||||
|
||||
@@ -163,10 +163,10 @@ public class Reach extends Check {
|
||||
if(collided) {
|
||||
hbuffer = 0;
|
||||
distance = Math.sqrt(distance);
|
||||
if(distance > 3.05) {
|
||||
if(++buffer > 2) {
|
||||
flag("d=%.3f>-3.05", distance);
|
||||
buffer = Math.min(2, buffer);
|
||||
if(distance > 3.001) {
|
||||
if(++buffer > 1) {
|
||||
flag("d=%.3f>-3.0", distance);
|
||||
buffer = Math.min(1, buffer);
|
||||
}
|
||||
} else if(buffer > 0) buffer-= 0.05f;
|
||||
|
||||
@@ -175,7 +175,7 @@ public class Reach extends Check {
|
||||
debug("buffer: %.3f distance=%.2f hits=%s", buffer, distance, hits);
|
||||
} else {
|
||||
if (++hbuffer > 5) {
|
||||
flag("%.1f;%.1f;%.1f", eloc.x, eloc.y, eloc.z);
|
||||
flag("%.1f;%.1f;%.1f", eloc.one.x, eloc.one.y, eloc.one.z);
|
||||
}
|
||||
debug("Missed!");
|
||||
}
|
||||
@@ -55,19 +55,23 @@ public class FlyA extends Check {
|
||||
double deltaPredict = MathUtils.getDelta(player.getMovement().getDeltaY(), predicted);
|
||||
|
||||
if(!player.getInfo().isGeneralCancel()
|
||||
&& player.getMovement().getTeleportsToConfirm() == 0
|
||||
&& player.getInfo().getBlockAbove().isPassed(1)
|
||||
&& !player.getInfo().isOnLadder()
|
||||
&& player.getInfo().climbTimer.isPassed(2)
|
||||
&& !player.getBlockInfo().inWeb
|
||||
&& !player.getBlockInfo().inScaffolding
|
||||
&& !player.getBlockInfo().inLiquid
|
||||
&& player.getInfo().getLastLiquid().isPassed(2)
|
||||
&& !player.getBlockInfo().fenceBelow
|
||||
&& !player.getInfo().isServerGround()
|
||||
&& !player.getBlockInfo().onHalfBlock
|
||||
&& player.getInfo().getVelocity().isPassed(1)
|
||||
&& !player.getBlockInfo().onSlime && deltaPredict > 0.001) {
|
||||
if(++buffer > 5) {
|
||||
buffer = 5;
|
||||
if(++buffer > 3) {
|
||||
buffer = 3;
|
||||
flag("dY=%.3f p=%.3f dx=%.3f", player.getMovement().getDeltaY(), predicted,
|
||||
player.getMovement().getDeltaXZ());
|
||||
cancel();
|
||||
}
|
||||
} else buffer-= buffer > 0 ? 0.25f : 0;
|
||||
|
||||
|
||||
@@ -2,18 +2,21 @@ package dev.brighten.ac.check.impl.fly;
|
||||
|
||||
import dev.brighten.ac.check.Action;
|
||||
import dev.brighten.ac.check.Check;
|
||||
import dev.brighten.ac.check.CheckData;
|
||||
import dev.brighten.ac.check.CheckType;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
|
||||
import dev.brighten.ac.utils.timer.Timer;
|
||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||
|
||||
//@CheckData(name = "Fly (B)", type = CheckType.MOVEMENT)
|
||||
@CheckData(name = "Fly (B)", type = CheckType.MOVEMENT)
|
||||
public class FlyB extends Check {
|
||||
public FlyB(APlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private Timer lastNearGround = new TickTimer();
|
||||
private float buffer;
|
||||
|
||||
@Action
|
||||
public void onFlying(WPacketPlayInFlying packet) {
|
||||
@@ -24,10 +27,14 @@ public class FlyB extends Check {
|
||||
&& player.getMovement().getMoveTicks() > 3
|
||||
&& player.getInfo().getLastPlace().isPassed(3)
|
||||
&& lastNearGround.isPassed(2)
|
||||
&& player.getInfo().lastLiquid.isPassed(1)
|
||||
&& player.getInfo().climbTimer.isPassed(1)
|
||||
&& player.getInfo().getVelocity().isPassed(2)
|
||||
&& player.getMovement().getDeltaY() > 0) {
|
||||
flag("%.4f>-%.4f",
|
||||
player.getMovement().getDeltaY(), player.getMovement().getLDeltaY());
|
||||
}
|
||||
if(++buffer > 1) {
|
||||
flag("%.4f>-%.4f",
|
||||
player.getMovement().getDeltaY(), player.getMovement().getLDeltaY());
|
||||
}
|
||||
} else if(buffer > 0) buffer-= 0.05f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public class NoFallA extends Check {
|
||||
|
||||
@Action
|
||||
public void onFlying(WPacketPlayInFlying packet) {
|
||||
if(!player.getInfo().isGeneralCancel()
|
||||
if(player.getInfo().isGeneralCancel()
|
||||
|| (player.getMovement().getDeltaXZ() == 0 && player.getMovement().getDeltaY() == 0)
|
||||
|| player.getBlockInfo().inLiquid
|
||||
|| player.getMovement().getLastTeleport().isNotPassed(1)
|
||||
|
||||
@@ -54,6 +54,7 @@ public class Horizontal extends Check {
|
||||
.getPossibleMaterials(new IntVector(lastUnderBlock.getX(), lastUnderBlock.getY(), lastUnderBlock.getZ()));
|
||||
|
||||
if (!packet.isMoved()
|
||||
|| player.getMovement().getMoveTicks() == 0
|
||||
|| player.getInfo().getVelocity().isNotPassed(1)
|
||||
|| player.getInfo().isGeneralCancel()
|
||||
|| player.getBlockInfo().onClimbable
|
||||
@@ -254,10 +255,8 @@ public class Horizontal extends Check {
|
||||
buffer = Math.min(3.5f, buffer); //Ensuring we don't have a run-away buffer
|
||||
flag("smallest=%s b=%.1f to=%s dxz=%.2f", smallestDelta, buffer,
|
||||
player.getMovement().getTo().getLoc(), player.getMovement().getDeltaXZ());
|
||||
} else {
|
||||
debug("bad movement");
|
||||
cancel();
|
||||
}
|
||||
} else debug("bad movement");
|
||||
} else if (buffer > 0) buffer -= 0.1f;
|
||||
|
||||
debug("smallest=%s pm=%.5f dxz=%.5f b=%.1f f/s=%.2f,%.2f soulsand=%s", smallestDelta, pmotion,
|
||||
|
||||
@@ -158,10 +158,10 @@ public class VelocityB extends Check {
|
||||
&& player.getCreation().isPassed(3000L)
|
||||
&& player.getMovement().getLastTeleport().isPassed(1)
|
||||
&& !player.getBlockInfo().blocksNear) {
|
||||
if(player.getInfo().lastUseItem.isPassed(2) && ++buffer > 20) {
|
||||
if(player.getInfo().lastUseItem.isPassed(2) && ++buffer > 11) {
|
||||
flag("pct=%.2f buffer=%.1f forward=%.2f strafe=%.2f",
|
||||
ratio * 100, buffer, moveStrafe, moveForward);
|
||||
buffer = 21;
|
||||
buffer = 11;
|
||||
}
|
||||
} else if(buffer > 0) buffer-= 0.5;
|
||||
|
||||
@@ -170,16 +170,8 @@ public class VelocityB extends Check {
|
||||
buffer, ticks, moveStrafe, moveForward,
|
||||
found, player.getInfo().getVelocity().getPassed());
|
||||
|
||||
pvX *= drag;
|
||||
pvZ *= drag;
|
||||
|
||||
if(++ticks > 2) {
|
||||
ticks = 0;
|
||||
pvX = pvZ = 0;
|
||||
}
|
||||
|
||||
if(Math.abs(pvX) < 0.005) pvX = 0;
|
||||
if(Math.abs(pvZ) < 0.005) pvZ = 0;
|
||||
pvX = 0;
|
||||
pvZ = 0;
|
||||
}
|
||||
}
|
||||
sprint = player.getInfo().isSprinting();
|
||||
|
||||
@@ -5,39 +5,97 @@ import dev.brighten.ac.check.Check;
|
||||
import dev.brighten.ac.check.CheckData;
|
||||
import dev.brighten.ac.check.CheckType;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.packet.ProtocolVersion;
|
||||
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockPlace;
|
||||
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
|
||||
import dev.brighten.ac.utils.BlockUtils;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.MathUtils;
|
||||
import org.bukkit.util.Vector;
|
||||
import dev.brighten.ac.utils.Tuple;
|
||||
import dev.brighten.ac.utils.math.cond.MaxDouble;
|
||||
import dev.brighten.ac.utils.world.BlockData;
|
||||
import dev.brighten.ac.utils.world.CollisionBox;
|
||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
@CheckData(name = "Block (A)", type = CheckType.INTERACT)
|
||||
public class BlockA extends Check {
|
||||
|
||||
public BlockA(APlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int buffer;
|
||||
private final MaxDouble verbose = new MaxDouble(20);
|
||||
private Queue<Tuple<Block, SimpleCollisionBox>> blockPlacements = new LinkedBlockingQueue<>();
|
||||
|
||||
@Action
|
||||
public void onPlace(WPacketPlayInBlockPlace packet) {
|
||||
Vector dir = new Vector(packet.getDirection().getAdjacentX(), 0, packet.getDirection().getAdjacentZ()),
|
||||
opposite = new Vector(packet.getDirection().opposite().getAdjacentX(),
|
||||
0, packet.getDirection().opposite().getAdjacentZ());
|
||||
public void onBlockPlace(WPacketPlayInBlockPlace event) {
|
||||
Location loc = event.getBlockPos().toBukkitVector().toLocation(player.getBukkitPlayer().getWorld());
|
||||
Optional<Block> optionalBlock = BlockUtils.getBlockAsync(loc);
|
||||
|
||||
if(!packet.getItemStack().getType().isBlock()) return;
|
||||
if(!optionalBlock.isPresent()) return;
|
||||
|
||||
Vector delta = new Vector(player.getMovement().getDeltaX(), player.getMovement().getDeltaY(), player.getMovement().getDeltaZ());
|
||||
final Block block = optionalBlock.get();
|
||||
CollisionBox box = BlockData.getData(block.getType()).getBox(block, player.getPlayerVersion());
|
||||
|
||||
double dist = delta.distance(dir), dist2 = opposite.distance(MathUtils.getDirection(player.getMovement().getTo().getLoc()).setY(0));
|
||||
boolean check = dist <= 1 && dist > 0.7 && dist2 >= 0.5 && dist2 < 1;
|
||||
debug(event.getBlockPos().toString());
|
||||
if(!(box instanceof SimpleCollisionBox)) {
|
||||
debug("Not SimpleCollisionBox: " + box.getClass().getSimpleName() + ";" + block.getType());
|
||||
return;
|
||||
}
|
||||
|
||||
if(check && packet.getDirection().getAdjacentY() == 0 && player.getInfo().isSprinting()) {
|
||||
if((buffer+= 4) != 15) {
|
||||
flag("dist=%.3f dist2=%.3f placeVec=%s", dist, dist2, dir.toString());
|
||||
buffer = 14;
|
||||
}
|
||||
} else if(buffer > 0) buffer--;
|
||||
final SimpleCollisionBox simpleBox = ((SimpleCollisionBox) box);
|
||||
|
||||
debug("dist=%.3f dist2=%.3f buffer=%s", dist, dist2, buffer);
|
||||
if(Math.abs(simpleBox.yMax - simpleBox.yMin) != 1.
|
||||
|| Math.abs(simpleBox.xMax - simpleBox.xMin) != 1.
|
||||
|| Math.abs(simpleBox.zMax - simpleBox.zMin) != 1.) {
|
||||
debug("not full block: x=%.1f y=%.1f z=%.1f",
|
||||
Math.abs(simpleBox.xMax - simpleBox.xMin),
|
||||
Math.abs(simpleBox.yMax - simpleBox.yMin),
|
||||
Math.abs(simpleBox.zMax - simpleBox.zMin));
|
||||
return;
|
||||
}
|
||||
|
||||
blockPlacements.add(new Tuple<>(block, simpleBox.expand(0.1)));
|
||||
}
|
||||
|
||||
@Action
|
||||
public void onFlying(WPacketPlayInFlying packet) {
|
||||
Tuple<Block, SimpleCollisionBox> tuple;
|
||||
|
||||
while((tuple = blockPlacements.poll()) != null) {
|
||||
final SimpleCollisionBox box = tuple.two.copy().expand(0.025);
|
||||
final Block block = tuple.one;
|
||||
|
||||
final KLocation to = player.getMovement().getTo().getLoc().clone(),
|
||||
from = player.getMovement().getFrom().getLoc().clone();
|
||||
|
||||
to.y+= player.getInfo().sneaking ? (ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_14)
|
||||
? 1.27f : 1.54f) : 1.62f;
|
||||
from.y+= player.getInfo().lsneaking ? (ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_14)
|
||||
? 1.27f : 1.54f) : 1.62f;
|
||||
|
||||
final RayCollision rayTo = new RayCollision(to.toVector(),
|
||||
MathUtils.getDirection(to)),
|
||||
rayFrom = new RayCollision(from.toVector(),
|
||||
MathUtils.getDirection(from));
|
||||
|
||||
final boolean collided = rayTo.isCollided(box) || rayFrom.isCollided(box);
|
||||
|
||||
if(!collided) {
|
||||
if(verbose.add() > 4) {
|
||||
flag("to=[x=%.1f y=%.1f z=%.1f yaw=%.1f pitch=%.1f] loc=[%.1f,%.1f,%.1f]",
|
||||
to.x, to.y, to.z, to.yaw, from.pitch,
|
||||
block.getLocation().getX(), block.getLocation().getY(), block.getLocation().getZ());
|
||||
}
|
||||
} else verbose.subtract(0.33);
|
||||
|
||||
debug("collided=%s verbose=%s", collided, verbose.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ public class BlockB extends Check {
|
||||
Block b = event.getBlock();
|
||||
double ypos = b.getLocation().getY() - player.getBukkitPlayer().getLocation().getY();
|
||||
double distance = player.getBukkitPlayer().getLocation().distance(b.getLocation());
|
||||
double ab_distance = player.getBukkitPlayer().getLocation().distance(ba.getLocation()) + 0.3;
|
||||
double ab_distance = player.getBukkitPlayer().getLocation().distance(ba.getLocation()) + 0.4;
|
||||
|
||||
if (distance >= 1.4 && distance > ab_distance && ypos <= 0.5) {
|
||||
if (distance >= 1.3 && distance > ab_distance && ypos <= 0.5) {
|
||||
flag("d:%.4f, ad:%.4f y=%.1f", distance, ab_distance, ypos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,6 +179,7 @@ public class APlayer {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int runKeepaliveAction(Consumer<KeepAlive> action) {
|
||||
return runKeepaliveAction(action, 0);
|
||||
}
|
||||
|
||||
@@ -21,14 +21,15 @@ import java.util.Optional;
|
||||
@Getter
|
||||
@Setter
|
||||
public class GeneralInformation {
|
||||
public Optional<Block> blockOnTo, blockBelow;
|
||||
public Optional<Block> blockOnTo = Optional.empty(), blockBelow = Optional.empty();
|
||||
public Timer lastMove = new TickTimer(), vehicleSwitch = new TickTimer(), lastAbilities = new TickTimer(),
|
||||
lastSneak = new TickTimer(), velocity = new TickTimer(), lastCancel = new TickTimer(),
|
||||
slimeTimer = new TickTimer(), lastElytra = new TickTimer(), blockAbove = new TickTimer(),
|
||||
lastPlace = new TickTimer(), climbTimer = new TickTimer(), lastUseItem = new TickTimer();
|
||||
lastPlace = new TickTimer(), climbTimer = new TickTimer(), lastUseItem = new TickTimer(),
|
||||
lastLiquid = new TickTimer();
|
||||
public LivingEntity target;
|
||||
public boolean serverGround, lastServerGround, canFly, nearGround, worldLoaded, generalCancel, inVehicle, creative,
|
||||
sneaking, sprinting, gliding, riptiding, wasOnSlime, onLadder, doingVelocity;
|
||||
sneaking, lsneaking, sprinting, gliding, riptiding, wasOnSlime, onLadder, doingVelocity;
|
||||
public List<Entity> nearbyEntities = Collections.emptyList();
|
||||
public PastLocation targetPastLocation = new PastLocation();
|
||||
public KLocation lastKnownGoodPosition;
|
||||
|
||||
@@ -49,6 +49,7 @@ public class MovementHandler {
|
||||
@Getter
|
||||
private final Timer lastTeleport = new TickTimer(), lastHighRate = new TickTimer();
|
||||
|
||||
@Getter
|
||||
private int teleportsToConfirm;
|
||||
|
||||
@Getter
|
||||
@@ -222,14 +223,14 @@ public class MovementHandler {
|
||||
// Resetting glide/sneak timers
|
||||
if (player.getInfo().isGliding()) player.getInfo().getLastElytra().reset();
|
||||
if (player.getInfo().isSneaking()) player.getInfo().getLastSneak().reset();
|
||||
if (player.getBlockInfo().inLiquid) player.getInfo().getLastLiquid().reset();
|
||||
|
||||
player.getInfo().setGeneralCancel(player.getBukkitPlayer().getAllowFlight()
|
||||
|| moveTicks == 0
|
||||
|| excuseNextFlying
|
||||
|| player.getBukkitPlayer().isFlying()
|
||||
|| player.getInfo().isCanFly()
|
||||
|| player.getInfo().isCreative()
|
||||
|| lastTeleport.isNotPassed(2)
|
||||
|| teleportsToConfirm > 0
|
||||
|| player.getInfo().isInVehicle()
|
||||
|| player.getInfo().getVehicleSwitch().isNotPassed(1)
|
||||
|| player.getBukkitPlayer().isSleeping()
|
||||
|
||||
@@ -6,13 +6,18 @@ import dev.brighten.ac.packet.ProtocolVersion;
|
||||
import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutEntity;
|
||||
import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutEntityTeleport;
|
||||
import dev.brighten.ac.utils.EntityLocation;
|
||||
import dev.brighten.ac.utils.Tuple;
|
||||
import dev.brighten.ac.utils.timer.Timer;
|
||||
import dev.brighten.ac.utils.timer.impl.MillisTimer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.val;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@@ -20,7 +25,7 @@ public class EntityLocationHandler {
|
||||
|
||||
private final APlayer data;
|
||||
|
||||
private final Map<UUID, EntityLocation> entityLocationMap = new ConcurrentHashMap<>();
|
||||
private final Map<UUID, Tuple<EntityLocation, EntityLocation>> entityLocationMap = new ConcurrentHashMap<>();
|
||||
private final Timer lastFlying = new MillisTimer();
|
||||
public int streak;
|
||||
|
||||
@@ -36,7 +41,7 @@ public class EntityLocationHandler {
|
||||
* @param entity Entity
|
||||
* @return Optional<EntityLocation></EntityLocation>
|
||||
*/
|
||||
public Optional<EntityLocation> getEntityLocation(Entity entity) {
|
||||
public Optional<Tuple<EntityLocation, EntityLocation>> getEntityLocation(Entity entity) {
|
||||
return Optional.ofNullable(entityLocationMap.get(entity.getUniqueId()));
|
||||
}
|
||||
|
||||
@@ -51,7 +56,10 @@ public class EntityLocationHandler {
|
||||
streak = 1;
|
||||
}
|
||||
|
||||
entityLocationMap.values().forEach(EntityLocation::interpolateLocation);
|
||||
entityLocationMap.values().forEach(eloc -> {
|
||||
if(eloc.one != null) eloc.one.interpolateLocation();
|
||||
if(eloc.two != null) eloc.two.interpolateLocation();
|
||||
});
|
||||
|
||||
lastFlying.reset();
|
||||
}
|
||||
@@ -71,15 +79,14 @@ public class EntityLocationHandler {
|
||||
|
||||
if(!allowedEntityTypes.contains(entity.getType())) return;
|
||||
|
||||
EntityLocation eloc = entityLocationMap.computeIfAbsent(entity.getUniqueId(),
|
||||
key -> new EntityLocation(entity));
|
||||
val tuple = entityLocationMap.computeIfAbsent(entity.getUniqueId(),
|
||||
key -> new Tuple<>(new EntityLocation(entity), null));
|
||||
|
||||
EntityLocation eloc = tuple.one;
|
||||
|
||||
tuple.two = tuple.one.clone();
|
||||
|
||||
runAction(entity, () -> {
|
||||
eloc.oldLocations.addAll(eloc.interpolatedLocations);
|
||||
|
||||
while(eloc.interpolatedLocations.size() > 1) {
|
||||
eloc.interpolatedLocations.removeFirst();
|
||||
}
|
||||
//We don't need to do version checking here. Atlas handles this for us.
|
||||
eloc.newX += packet.getX();
|
||||
eloc.newY += packet.getY();
|
||||
@@ -106,14 +113,14 @@ public class EntityLocationHandler {
|
||||
|
||||
if(!allowedEntityTypes.contains(entity.getType())) return;
|
||||
|
||||
EntityLocation eloc = entityLocationMap.computeIfAbsent(entity.getUniqueId(),
|
||||
key -> new EntityLocation(entity));
|
||||
val tuple = entityLocationMap.computeIfAbsent(entity.getUniqueId(),
|
||||
key -> new Tuple<>(new EntityLocation(entity), null));
|
||||
|
||||
EntityLocation eloc = tuple.one;
|
||||
|
||||
tuple.two = tuple.one.clone();
|
||||
|
||||
runAction(entity, () -> {
|
||||
eloc.oldLocations.addAll(eloc.interpolatedLocations);
|
||||
while(eloc.interpolatedLocations.size() > 1) {
|
||||
eloc.interpolatedLocations.removeFirst();
|
||||
}
|
||||
if(data.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) {
|
||||
if (!(Math.abs(eloc.x - packet.getX()) >= 0.03125D)
|
||||
&& !(Math.abs(eloc.y - packet.getY()) >= 0.015625D)
|
||||
@@ -163,12 +170,12 @@ public class EntityLocationHandler {
|
||||
data.runInstantAction(ia -> {
|
||||
if(!ia.isEnd()) {
|
||||
action.run();
|
||||
} else entityLocationMap.get(entity.getUniqueId()).oldLocations.clear();
|
||||
} else entityLocationMap.get(entity.getUniqueId()).two = null;
|
||||
});
|
||||
} else {
|
||||
data.runKeepaliveAction(keepalive -> action.run());
|
||||
data.runKeepaliveAction(keepalive ->
|
||||
entityLocationMap.get(entity.getUniqueId()).oldLocations.clear(), 1);
|
||||
entityLocationMap.get(entity.getUniqueId()).two = null, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,5 +299,10 @@ public class PacketHandler {
|
||||
}
|
||||
|
||||
player.callPacket(packetObject, timestamp);
|
||||
|
||||
// Post flying settings
|
||||
if(type.equals(PacketType.FLYING)) {
|
||||
player.getInfo().lsneaking = player.getInfo().sneaking;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ 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.Materials;
|
||||
import dev.brighten.ac.utils.Tuple;
|
||||
import dev.brighten.ac.utils.XMaterial;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.val;
|
||||
import org.bukkit.Material;
|
||||
@@ -32,23 +35,32 @@ public class BlockUpdateHandler {
|
||||
*/
|
||||
public void onPlace(WPacketPlayInBlockPlace place) {
|
||||
// Could not possibly be a block placement as it's not a block a player is holding.
|
||||
if(!place.getItemStack().getType().isBlock()) return;
|
||||
IntVector pos = place.getBlockPos().clone();
|
||||
|
||||
IntVector pos = place.getBlockPos();
|
||||
// Some dumbass shit I have to do because Minecraft with Lilypads
|
||||
if(place.getItemStack() != null && XMaterial.matchXMaterial(place.getItemStack().getType()).equals(XMaterial.LILY_PAD)) {
|
||||
RayCollision rayCollision = new RayCollision(player.getBukkitPlayer().getEyeLocation().toVector(),
|
||||
player.getBukkitPlayer().getLocation().getDirection());
|
||||
Block block = rayCollision.getClosestBlockOfType(player.getBukkitPlayer().getWorld(), Materials.LIQUID, 5);
|
||||
|
||||
// Not an actual block place, just an interact
|
||||
if(pos.getX() == -1 && (pos.getY() == 255 || pos.getY() == -1) && pos.getZ() == -1) return;
|
||||
if(block != null) {
|
||||
if (Materials.checkFlag(block.getType(), Materials.WATER)) {
|
||||
pos = new IntVector(block.getX(), block.getY() + 1, block.getZ());
|
||||
}
|
||||
} else return;
|
||||
} // Not an actual block place, just an interact
|
||||
else if(pos.getX() == -1 && (pos.getY() == 255 || pos.getY() == -1) && pos.getZ() == -1) {
|
||||
return;
|
||||
} else {
|
||||
pos.setX(pos.getX() + place.getDirection().getAdjacentX());
|
||||
pos.setY(pos.getY() + place.getDirection().getAdjacentY());
|
||||
pos.setZ(pos.getZ() + place.getDirection().getAdjacentZ());
|
||||
}
|
||||
|
||||
player.getInfo().getLastPlace().reset();
|
||||
|
||||
pos.setX(pos.getX() + place.getDirection().getAdjacentX());
|
||||
pos.setY(pos.getY() + place.getDirection().getAdjacentY());
|
||||
pos.setZ(pos.getZ() + place.getDirection().getAdjacentZ());
|
||||
|
||||
Deque<Material> possible = getPossibleMaterials(place.getBlockPos());
|
||||
Deque<Material> possible = getPossibleMaterials(pos);
|
||||
possible.add(place.getItemStack().getType());
|
||||
|
||||
player.getBukkitPlayer().sendMessage("Placed possible: " + possible + ";" + place.getBlockPos());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,9 +17,8 @@ public class EntityLocation {
|
||||
public float newYaw, newPitch, yaw, pitch;
|
||||
public int increment = 0;
|
||||
public boolean sentTeleport = false;
|
||||
public KLocation oldLocation, location;
|
||||
public Deque<KLocation> oldLocations = new EvictingList<>(3),
|
||||
interpolatedLocations = new EvictingList<>(3);
|
||||
public KLocation location;
|
||||
public Deque<KLocation> interpolatedLocations = new EvictingList<>(2);
|
||||
|
||||
public void interpolateLocations() {
|
||||
increment = 3;
|
||||
|
||||
@@ -40,8 +40,8 @@ public class Helper {
|
||||
return PlayerSizeHandler.instance.bounds(player, x, y, z);
|
||||
}
|
||||
|
||||
public static void drawRay(RayCollision collision, EnumParticle particle, Collection<? extends Player> players) {
|
||||
for (double i = 0; i < 8; i += 0.2) {
|
||||
public static void drawRay(RayCollision collision, double distance, EnumParticle particle, Collection<? extends Player> players) {
|
||||
for (double i = 0; i < 3; i += 0.2) {
|
||||
float fx = (float) (collision.originX + (collision.directionX * i));
|
||||
float fy = (float) (collision.originY + (collision.directionY * i));
|
||||
float fz = (float) (collision.originZ + (collision.directionZ * i));
|
||||
|
||||
@@ -33,6 +33,10 @@ public class MathUtils {
|
||||
current - (float)Math.floor(current / previous) * previous);
|
||||
}
|
||||
|
||||
public static double lerp(double lerpAmount, double start, double end) {
|
||||
return start + lerpAmount * (end - start);
|
||||
}
|
||||
|
||||
public static boolean isScientificNotation(double value) {
|
||||
return String.valueOf(value).contains("E");
|
||||
}
|
||||
|
||||
@@ -96,7 +96,10 @@ public enum BlockData {
|
||||
|| mat.name().contains("HEAD")).toArray(Material[]::new)),
|
||||
|
||||
_DOOR(new DoorHandler(), Arrays.stream(Material.values())
|
||||
.filter(mat -> !mat.name().contains("TRAP") && mat.name().contains("DOOR"))
|
||||
.filter(mat -> !mat.name().contains("TRAP") && !mat.name().contains("ITEM")
|
||||
&& mat.name().contains("DOOR")
|
||||
// Potential cause for ClassCastException to MaterialData instead of Door
|
||||
&& !mat.name().equals("WOOD_DOOR") && !mat.name().equals("IRON_DOOR"))
|
||||
.toArray(Material[]::new)),
|
||||
|
||||
_HOPPER(new HopperBounding(), XMaterial.HOPPER.parseMaterial()),
|
||||
@@ -216,7 +219,7 @@ public enum BlockData {
|
||||
if (v.isBelow(ProtocolVersion.V1_9))
|
||||
return new SimpleCollisionBox(0.0f, 0.0F, 0.0f, 1.0f, 0.015625F, 1.0f);
|
||||
return new SimpleCollisionBox(0.0625, 0.0F, 0.0625, 0.9375, 0.015625F, 0.9375);
|
||||
}, MiscUtils.match("WATER_LILY")),
|
||||
}, XMaterial.LILY_PAD.parseMaterial()),
|
||||
|
||||
_BED(new SimpleCollisionBox(0.0F, 0.0F, 0.0F, 1.0F, 0.5625, 1.0F),
|
||||
Arrays.stream(XMaterial.values()).filter(mat -> mat.name().contains("BED") && !mat.name().contains("ROCK"))
|
||||
|
||||
@@ -136,7 +136,7 @@ public class RayCollision implements CollisionBox {
|
||||
|
||||
@Override
|
||||
public void draw(EnumParticle particle, Player... players) {
|
||||
Helper.drawRay(this, particle, Arrays.asList(players));
|
||||
Helper.drawRay(this, 3, particle, Arrays.asList(players));
|
||||
}
|
||||
|
||||
public List<CollisionBox> boxesOnRay(World world, double distance) {
|
||||
@@ -174,6 +174,40 @@ public class RayCollision implements CollisionBox {
|
||||
return boxes;
|
||||
}
|
||||
|
||||
public Block getClosestBlockOfType(World world, int bitmask, double distance) {
|
||||
int amount = Math.round((float) (distance / 0.5));
|
||||
|
||||
Location[] locs = new Location[Math.max(2, amount)]; //We do a max to prevent NegativeArraySizeException.
|
||||
boolean primaryThread = Bukkit.isPrimaryThread();
|
||||
ProtocolVersion version = ProtocolVersion.getGameVersion();
|
||||
|
||||
for (int i = 0; i < locs.length; i++) {
|
||||
double ix = i / 2d;
|
||||
|
||||
double fx = (originX + (directionX * ix));
|
||||
double fy = (originY + (directionY * ix));
|
||||
double fz = (originZ + (directionZ * ix));
|
||||
|
||||
Location loc = new Location(world, fx, fy, fz);
|
||||
|
||||
Block block = primaryThread ? loc.getBlock() : BlockUtils.getBlock(loc);
|
||||
|
||||
if (block == null) continue;
|
||||
|
||||
final Material type = block.getType();
|
||||
|
||||
if (!Materials.checkFlag(type, bitmask)) continue;
|
||||
|
||||
CollisionBox box = BlockData.getData(type).getBox(block, version);
|
||||
|
||||
if (!isCollided(box)) continue;
|
||||
|
||||
return block;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void downCast(List<SimpleCollisionBox> list) {/*Do Nothing, Ray cannot be down-casted*/}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user