mirror of
https://github.com/funkemunky/KauriV3.git
synced 2026-05-31 05:51:55 +00:00
+5
-5
@@ -19,6 +19,10 @@
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>maven-central</id>
|
||||
<url>https://nexus.funkemunky.cc/repository/maven-central/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>viaversion-repo</id>
|
||||
<url>https://repo.viaversion.com</url>
|
||||
@@ -27,10 +31,6 @@
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>evokegames</id>
|
||||
<url>https://maven.evokegames.gg/snapshots</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>aikar</id>
|
||||
<url>https://repo.aikar.co/content/groups/aikar/</url>
|
||||
@@ -267,7 +267,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.retrooper</groupId>
|
||||
<artifactId>packetevents-spigot</artifactId>
|
||||
<version>2.9.4</version>
|
||||
<version>2.11.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -17,6 +17,8 @@ import dev.brighten.ac.handler.PacketHandler;
|
||||
import dev.brighten.ac.handler.entity.FakeEntityTracker;
|
||||
import dev.brighten.ac.handler.keepalive.KeepaliveProcessor;
|
||||
import dev.brighten.ac.handler.keepalive.actions.ActionManager;
|
||||
import dev.brighten.ac.handler.protocol.Protocol;
|
||||
import dev.brighten.ac.handler.protocol.impl.NoAPI;
|
||||
import dev.brighten.ac.logging.LoggerManager;
|
||||
import dev.brighten.ac.utils.*;
|
||||
import dev.brighten.ac.utils.annotation.ConfigSetting;
|
||||
@@ -30,6 +32,7 @@ import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||
import dev.brighten.ac.utils.world.WorldInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.PackagePrivate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
@@ -116,6 +119,9 @@ public class Anticheat extends JavaPlugin {
|
||||
private final RollingAverageDouble tps = new RollingAverageDouble(4, 20);
|
||||
private final Map<UUID, WorldInfo> worldInfoMap = new HashMap<>();
|
||||
|
||||
@Setter
|
||||
private Protocol protocol = new NoAPI();
|
||||
|
||||
private final List<BaseCommand> commands = new ArrayList<>();
|
||||
|
||||
public static boolean allowDebug = true;
|
||||
@@ -252,7 +258,7 @@ public class Anticheat extends JavaPlugin {
|
||||
} catch (IllegalStateException e) {
|
||||
Anticheat.INSTANCE.getLogger().log(Level.SEVERE, "Check ID unregister failed", e);
|
||||
}
|
||||
commandManager.getScheduler().cancelLocaleTask();
|
||||
|
||||
commandPropertiesManager = null;
|
||||
|
||||
try {
|
||||
|
||||
@@ -23,5 +23,5 @@ public @interface CheckData {
|
||||
int punishVl() default 10;
|
||||
|
||||
ClientVersion minVersion() default ClientVersion.V_1_8;
|
||||
ClientVersion maxVersion() default ClientVersion.V_1_21_7;
|
||||
ClientVersion maxVersion() default ClientVersion.V_1_21_11;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import dev.brighten.ac.Anticheat;
|
||||
@@ -19,7 +20,6 @@ import dev.brighten.ac.utils.timer.Timer;
|
||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||
import dev.brighten.ac.utils.world.EntityData;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
@@ -46,7 +46,7 @@ public class Hitbox extends Check {
|
||||
if(packet.getAction() != WrapperPlayClientInteractEntity.InteractAction.ATTACK)
|
||||
return;
|
||||
|
||||
Optional<TrackedEntity> entity = player.getEntityLocationHandler().getTrackedEntity(packet.getEntityId());
|
||||
Optional<TrackedEntity> entity = player.getWorldTracker().getCurrentWorld().get().getTrackedEntity(packet.getEntityId());
|
||||
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
||||
|
||||
attacks.add(new Tuple<>(entity.get(),
|
||||
@@ -118,7 +118,7 @@ public class Hitbox extends Check {
|
||||
boolean didSneakOrElytra = player.getInfo().getLastSneak().isNotPassed(40)
|
||||
|| player.getInfo().getLastElytra().isNotPassed(40);
|
||||
|
||||
List<Vector> directions = new ArrayList<>(Arrays.asList(MathUtils.getDirection(
|
||||
List<Vector3d> directions = new ArrayList<>(Arrays.asList(MathUtils.getDirection(
|
||||
player.getMovement().getTo().getLoc().getYaw(),
|
||||
player.getMovement().getTo().getLoc().getPitch()),
|
||||
MathUtils.getDirection(player.getMovement().getFrom().getLoc().getYaw(),
|
||||
@@ -126,7 +126,7 @@ public class Hitbox extends Check {
|
||||
|
||||
if(!didSneakOrElytra) {
|
||||
to.add(0, 1.62f, 0);
|
||||
for (Vector direction : directions) {
|
||||
for (Vector3d direction : directions) {
|
||||
for (SimpleCollisionBox targetBox : boxes) {
|
||||
final AxisAlignedBB vanillaBox = new AxisAlignedBB(targetBox);
|
||||
|
||||
@@ -143,7 +143,7 @@ public class Hitbox extends Check {
|
||||
}
|
||||
//Checking all possible eyeheights since client actions notoriously desync from the server side
|
||||
} else {
|
||||
for (Vector direction : directions) {
|
||||
for (Vector3d direction : directions) {
|
||||
for (double eyeHeight : player.getMovement().getEyeHeights()) {
|
||||
for (SimpleCollisionBox targetBox : boxes) {
|
||||
final AxisAlignedBB vanillaBox = new AxisAlignedBB(targetBox);
|
||||
@@ -180,7 +180,7 @@ public class Hitbox extends Check {
|
||||
|
||||
debug("buffer: %.3f distance=%.2f hits=%s sneaking=%s", buffer, distance, hits,
|
||||
player.getInfo().isSneaking());
|
||||
} else if(player.getEntityLocationHandler().streak > 1) {
|
||||
} else if(player.getEntityTrackHandler().streak > 1) {
|
||||
if (++hbuffer > 5) {
|
||||
flag("%.1f;%.1f;%.1f", entity.getNewEntityLocation().x, entity.getNewEntityLocation().y, entity.getNewEntityLocation().z);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.brighten.ac.check.impl.combat.killaura;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientAnimation;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import dev.brighten.ac.api.check.CheckType;
|
||||
@@ -29,10 +28,10 @@ public class KABot extends Check {
|
||||
|
||||
@Bind
|
||||
WAction<WrapperPlayClientInteractEntity> packet = packet -> {
|
||||
val optional = player.getEntityLocationHandler().getTrackedEntity(packet.getEntityId());
|
||||
val optional = player.getWorldTracker().getCurrentWorld().get().getTrackedEntity(packet.getEntityId());
|
||||
|
||||
if(optional.isPresent()
|
||||
&& (player.getEntityLocationHandler().clientHasEntity.get()
|
||||
&& (player.getEntityTrackHandler().clientHasEntity.get()
|
||||
|| !optional.get().getFakeMobs().isEmpty())) {
|
||||
if(++buffer > 3) {
|
||||
flag("Attacked player without attacking bot!");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package dev.brighten.ac.check.impl.combat.killaura;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import dev.brighten.ac.api.check.CheckType;
|
||||
import dev.brighten.ac.check.Check;
|
||||
@@ -13,7 +13,6 @@ import dev.brighten.ac.utils.world.CollisionBox;
|
||||
import dev.brighten.ac.utils.world.EntityData;
|
||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* @author funkemunky
|
||||
@@ -43,14 +42,13 @@ public class KATrace extends Check {
|
||||
return;
|
||||
}
|
||||
|
||||
var trackedEntity = player.getEntityLocationHandler().getTrackedEntity(player.getInfo().getTarget().getEntityId());
|
||||
var trackedEntity = player.getWorldTracker().getCurrentWorld().get().getTrackedEntity(player.getInfo().getTarget().getEntityId());
|
||||
|
||||
if(trackedEntity.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// Getting the target's bounding box
|
||||
SimpleCollisionBox targetBox = (SimpleCollisionBox) EntityData.getEntityBox(player.getInfo().getTarget()
|
||||
.getLocation(), trackedEntity.get());
|
||||
SimpleCollisionBox targetBox = (SimpleCollisionBox) EntityData.getEntityBox(player.getInfo().getTarget().getLocation(), trackedEntity.get());
|
||||
|
||||
if(targetBox == null) return;
|
||||
|
||||
@@ -59,12 +57,12 @@ public class KATrace extends Check {
|
||||
// Setting the player's eye height based on their sneak status
|
||||
origin.add(0, player.getEyeHeight(), 0);
|
||||
|
||||
final Vector originVec = origin.toVector();
|
||||
final Vector3d originVec = origin.toVector();
|
||||
|
||||
// Setting a trace based on their view direction
|
||||
RayCollision collision = new RayCollision(originVec, origin.getDirection());
|
||||
|
||||
Vector targetPoint = collision.collisionPoint(targetBox);
|
||||
Vector3d targetPoint = collision.collisionPoint(targetBox);
|
||||
//If the ray isn't collided, we might as well not run this check. Just a simple boxes on array check
|
||||
if(targetPoint == null) return;
|
||||
|
||||
@@ -84,7 +82,7 @@ public class KATrace extends Check {
|
||||
continue;
|
||||
|
||||
// We want to shrink the box slightly since there is a bit of a margin of error in the ray trace.
|
||||
Vector point = collision.collisionPoint(box.copy().shrink(0.005f, 0.005f, 0.005f));
|
||||
Vector3d point = collision.collisionPoint(box.copy().shrink(0.005f, 0.005f, 0.005f));
|
||||
|
||||
if (point != null && originVec.distanceSquared(point) < dist - 0.2) {
|
||||
rayCollidedOnBlock = true;
|
||||
|
||||
@@ -31,7 +31,7 @@ public class KACalc extends KListener {
|
||||
@Bind
|
||||
WAction<WrapperPlayClientPlayerFlying> flying = packet -> {
|
||||
if(player.getInfo().getTarget() == null || player.getInfo().lastAttack.isPassed(40)) return;
|
||||
Optional<TrackedEntity> optional = player.getEntityLocationHandler()
|
||||
Optional<TrackedEntity> optional = player.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(player.getInfo().getTarget().getEntityId());
|
||||
|
||||
if(optional.isEmpty()) return;
|
||||
@@ -46,7 +46,7 @@ public class KACalc extends KListener {
|
||||
KLocation originKLoc = player.getMovement().getTo().getLoc().clone()
|
||||
.add(0, player.getInfo().isSneaking() ? 1.54f : 1.62f, 0);
|
||||
|
||||
double halfHeight = player.getInfo().getTarget().getEyeHeight() / 2;
|
||||
double halfHeight = player.getInfo().getTarget().getPose().eyeHeight / 2;
|
||||
KLocation targetLocation = new KLocation(current.getX(), current.getY(), current.getZ());
|
||||
var rotations = MathUtils
|
||||
.getRotation(originKLoc, targetLocation.clone().add(0, halfHeight, 0));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.brighten.ac.check.impl.movement;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.teleport.RelativeFlag;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerPositionAndLook;
|
||||
import dev.brighten.ac.Anticheat;
|
||||
@@ -18,7 +19,6 @@ import dev.brighten.ac.utils.annotation.Bind;
|
||||
import dev.brighten.ac.utils.objects.evicting.EvictingSet;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -31,7 +31,7 @@ public class Phase extends Check {
|
||||
}
|
||||
|
||||
private int ticks;
|
||||
private final Set<Vector> POSITIONS = new EvictingSet<>(10);
|
||||
private final Set<Vector3d> POSITIONS = new EvictingSet<>(10);
|
||||
private Location teleportLoc = null;
|
||||
|
||||
@Bind
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.brighten.ac.check.impl.movement.speed;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import dev.brighten.ac.api.check.CheckType;
|
||||
import dev.brighten.ac.check.Check;
|
||||
@@ -36,11 +37,11 @@ public class Speed extends Check {
|
||||
|
||||
moveFactor+= (float) (moveFactor * 0.30000001192092896D);
|
||||
|
||||
if(player.getPotionHandler().hasPotionEffect(PotionEffectType.SPEED))
|
||||
if(player.getPotionHandler().hasPotionEffect(PotionTypes.SPEED))
|
||||
moveFactor += (float) ((PlayerUtils.getPotionEffectLevel(player.getBukkitPlayer(), PotionEffectType.SPEED)
|
||||
* (0.200000000298023224D)) * moveFactor);
|
||||
|
||||
if(player.getPotionHandler().hasPotionEffect(PotionEffectType.SLOW))
|
||||
if(player.getPotionHandler().hasPotionEffect(PotionTypes.SLOWNESS))
|
||||
moveFactor += (float) ((PlayerUtils.getPotionEffectLevel(player.getBukkitPlayer(), PotionEffectType.SLOW)
|
||||
* (-0.15000000596046448D)) * moveFactor);
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package dev.brighten.ac.check.impl.movement.velocity;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import dev.brighten.ac.api.check.CheckType;
|
||||
import dev.brighten.ac.check.Check;
|
||||
@@ -12,12 +14,10 @@ import dev.brighten.ac.utils.BlockUtils;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.MathUtils;
|
||||
import dev.brighten.ac.utils.annotation.Bind;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import dev.brighten.ac.utils.timer.Timer;
|
||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||
import lombok.val;
|
||||
import me.hydro.emulator.util.mcp.MathHelper;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -61,8 +61,8 @@ public class VelocityB extends Check {
|
||||
val underBlockLoc = previousFrom != null
|
||||
? player.getMovement().getFrom().getLoc() : player.getMovement().getTo().getLoc();
|
||||
|
||||
WrappedBlock underMaterial = player.getBlockUpdateHandler()
|
||||
.getBlock(new IntVector(MathHelper.floor_double(underBlockLoc.getX()),
|
||||
WrappedBlock underMaterial = player.getWorldTracker()
|
||||
.getBlock(new Vector3i(MathHelper.floor_double(underBlockLoc.getX()),
|
||||
MathHelper.floor_double(underBlockLoc.getY() - 1),
|
||||
MathHelper.floor_double(underBlockLoc.getZ())));
|
||||
|
||||
@@ -87,8 +87,8 @@ public class VelocityB extends Check {
|
||||
double pmotionx = 0, pmotionz = 0;
|
||||
boolean onGround = player.getMovement().getFrom().isOnGround();
|
||||
|
||||
val speed = player.getPotionHandler().getEffectByType(PotionEffectType.SPEED);
|
||||
val slow = player.getPotionHandler().getEffectByType(PotionEffectType.SLOW);
|
||||
val speed = player.getPotionHandler().getEffectByType(PotionTypes.SPEED);
|
||||
val slow = player.getPotionHandler().getEffectByType(PotionTypes.SLOWNESS);
|
||||
|
||||
for (Iteration iteration : iterations) {
|
||||
float forward = iteration.f, strafe = iteration.s;
|
||||
@@ -138,9 +138,9 @@ public class VelocityB extends Check {
|
||||
aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D;
|
||||
|
||||
if (speed.isPresent())
|
||||
aiMoveSpeed += (speed.get().getAmplifier() + 1) * 0.20000000298023224D * aiMoveSpeed;
|
||||
aiMoveSpeed += (speed.get().properties().amplifier() + 1) * 0.20000000298023224D * aiMoveSpeed;
|
||||
if (slow.isPresent())
|
||||
aiMoveSpeed += (slow.get().getAmplifier() + 1) * -0.15000000596046448D * aiMoveSpeed;
|
||||
aiMoveSpeed += (slow.get().properties().amplifier() + 1) * -0.15000000596046448D * aiMoveSpeed;
|
||||
|
||||
float f5;
|
||||
if (onGround) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.brighten.ac.check.impl.world;
|
||||
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerBlockPlacement;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import dev.brighten.ac.api.check.CheckType;
|
||||
@@ -35,7 +36,7 @@ public class BlockA extends Check {
|
||||
WAction<WrapperPlayClientPlayerBlockPlacement> blockPlace = packet -> {
|
||||
Vector3d loc = packet.getBlockPosition().toVector3d();
|
||||
|
||||
WrappedBlock block = player.getBlockUpdateHandler().getBlock(loc);
|
||||
WrappedBlock block = player.getWorldTracker().getBlock(new Vector3i(MathUtils.floor(loc.getX()), MathUtils.floor(loc.getY()), MathUtils.floor(loc.getZ())));
|
||||
|
||||
CollisionBox box = BlockData.getData(block.getType()).getBox(player, block, player.getPlayerVersion());
|
||||
|
||||
|
||||
@@ -14,12 +14,12 @@ import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.annotation.Bind;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import dev.brighten.ac.utils.timer.Timer;
|
||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||
import dev.brighten.ac.utils.world.BlockData;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@CheckData(name = "Block (D)", checkId = "blockc", type = CheckType.INTERACT)
|
||||
public class BlockD extends Check {
|
||||
@@ -45,7 +45,7 @@ public class BlockD extends Check {
|
||||
packet.getFace().getModY(),
|
||||
packet.getFace().getModZ());
|
||||
|
||||
WrappedBlock block = new WrappedBlock(new IntVector(packet.getBlockPosition()),
|
||||
WrappedBlock block = new WrappedBlock(packet.getBlockPosition(),
|
||||
placedType,
|
||||
WrappedBlockState.getDefaultState(placedType));
|
||||
blockPlaceLocations.put(blockpos, block);
|
||||
|
||||
@@ -7,11 +7,12 @@ import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.protocol.world.dimension.DimensionType;
|
||||
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.wrapper.PacketWrapper;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import dev.brighten.ac.Anticheat;
|
||||
import dev.brighten.ac.api.spigot.impl.LegacyPlayer;
|
||||
import dev.brighten.ac.api.spigot.impl.ModernPlayer;
|
||||
@@ -22,17 +23,20 @@ import dev.brighten.ac.data.info.GeneralInformation;
|
||||
import dev.brighten.ac.data.info.LagInformation;
|
||||
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.EntityTrackHandler;
|
||||
import dev.brighten.ac.handler.MovementHandler;
|
||||
import dev.brighten.ac.handler.PotionHandler;
|
||||
import dev.brighten.ac.handler.VelocityHandler;
|
||||
import dev.brighten.ac.handler.block.BlockUpdateHandler;
|
||||
import dev.brighten.ac.handler.block.World;
|
||||
import dev.brighten.ac.handler.entity.FakeMob;
|
||||
import dev.brighten.ac.handler.keepalive.KeepAlive;
|
||||
import dev.brighten.ac.handler.protocol.Protocol;
|
||||
import dev.brighten.ac.messages.Messages;
|
||||
import dev.brighten.ac.packet.TransactionServerWrapper;
|
||||
import dev.brighten.ac.utils.*;
|
||||
import dev.brighten.ac.utils.Helper;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.Tuple;
|
||||
import dev.brighten.ac.utils.XMaterial;
|
||||
import dev.brighten.ac.utils.objects.evicting.EvictingList;
|
||||
import dev.brighten.ac.utils.timer.Timer;
|
||||
import dev.brighten.ac.utils.timer.impl.MillisTimer;
|
||||
@@ -49,7 +53,6 @@ import me.hydro.emulator.object.input.DataSupplier;
|
||||
import me.hydro.emulator.util.mcp.AxisAlignedBB;
|
||||
import me.hydro.emulator.util.mcp.BlockPos;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
@@ -72,10 +75,10 @@ public class APlayer {
|
||||
private VelocityHandler velocityHandler;
|
||||
|
||||
@Getter
|
||||
private EntityLocationHandler entityLocationHandler;
|
||||
private EntityTrackHandler entityTrackHandler;
|
||||
|
||||
@Getter
|
||||
private BlockUpdateHandler blockUpdateHandler;
|
||||
private BlockUpdateHandler worldTracker;
|
||||
|
||||
@Getter
|
||||
private CheckHandler checkHandler;
|
||||
@@ -138,87 +141,103 @@ public class APlayer {
|
||||
this.movement = new MovementHandler(this);
|
||||
this.potionHandler = new PotionHandler(this);
|
||||
this.velocityHandler = new VelocityHandler(this);
|
||||
this.entityLocationHandler = new EntityLocationHandler(this);
|
||||
this.blockUpdateHandler = new BlockUpdateHandler(this);
|
||||
this.entityTrackHandler = new EntityTrackHandler(this);
|
||||
this.worldTracker = new BlockUpdateHandler(this);
|
||||
this.checkHandler = new CheckHandler(this);
|
||||
this.info = new GeneralInformation();
|
||||
this.lagInfo = new LagInformation();
|
||||
this.blockInfo = new BlockInformation(this);
|
||||
|
||||
worldTracker.getCurrentWorld().set(new World(bukkitPlayer.getWorld().getName()));
|
||||
|
||||
creation.reset();
|
||||
|
||||
playerVersion = ClientVersion.getById(Anticheat.INSTANCE.getProtocol().getPlayerVersion(this));
|
||||
|
||||
Anticheat.INSTANCE.getScheduler().schedule(() -> {
|
||||
// Grabbing the protocol version of the player.
|
||||
Anticheat.INSTANCE.getLogger().info("Attempting Getting player version for " + getBukkitPlayer().getName());
|
||||
|
||||
ClientVersion version = ClientVersion.getById(Protocol.getProtocol().getPlayerVersion(getBukkitPlayer()));
|
||||
ClientVersion version = ClientVersion.getById(Anticheat.INSTANCE.getProtocol().getPlayerVersion(this));
|
||||
|
||||
this.playerVersion = version;
|
||||
|
||||
Anticheat.INSTANCE.getLogger().info("Got player version " + version.name() + " for " + getBukkitPlayer().getName());
|
||||
|
||||
if(PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) {
|
||||
this.wrappedPlayer = new LegacyPlayer(getBukkitPlayer());
|
||||
} else this.wrappedPlayer = new ModernPlayer(getBukkitPlayer());
|
||||
|
||||
EMULATOR = new Emulator(new DataSupplier() {
|
||||
@Override
|
||||
public List<AxisAlignedBB> getCollidingBoxes(AxisAlignedBB bb) {
|
||||
SimpleCollisionBox sbc = new SimpleCollisionBox(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ);
|
||||
|
||||
// Greater than 20? We want to truncate to prevent huge processing cost
|
||||
if(sbc.min().distanceSquared(sbc.max()) > 400) {
|
||||
sbc.maxX = sbc.minX + Math.min(sbc.maxX - sbc.minX, 20);
|
||||
sbc.maxY = sbc.minY + Math.max(sbc.maxY - sbc.minY, 20);
|
||||
sbc.maxZ = sbc.minZ + Math.max(sbc.maxZ - sbc.minZ, 20);
|
||||
}
|
||||
|
||||
List<AxisAlignedBB> axisAlignedBBs = new ArrayList<>();
|
||||
|
||||
for (SimpleCollisionBox bb2 : Helper.getCollisions(APlayer.this,
|
||||
sbc)) {
|
||||
axisAlignedBBs
|
||||
.add(new AxisAlignedBB(bb2.minX, bb2.minY, bb2.minZ, bb2.maxX, bb2.maxY, bb2.maxZ));
|
||||
}
|
||||
|
||||
return axisAlignedBBs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockAt(BlockPos blockPos) {
|
||||
//Optional<org.bukkit.block.Block>
|
||||
var block = APlayer.this.getBlockUpdateHandler()
|
||||
.getBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||
|
||||
StateType type = block.getType();
|
||||
|
||||
if(type == StateTypes.SLIME_BLOCK) {
|
||||
return new BlockSlime();
|
||||
} else if(type == StateTypes.SOUL_SAND) {
|
||||
return new BlockSoulSand();
|
||||
} else if(type == StateTypes.COBWEB) {
|
||||
return new BlockWeb();
|
||||
} else if(type == StateTypes.ICE || type == StateTypes.PACKED_ICE || type == StateTypes.FROSTED_ICE) {
|
||||
return new BlockIce();
|
||||
} else if(type == StateTypes.BLUE_ICE) {
|
||||
return new BlockBlueIce();
|
||||
}
|
||||
|
||||
return new Block();
|
||||
}
|
||||
}, getPlayerVersion().getProtocolVersion());
|
||||
|
||||
generateEntities();
|
||||
|
||||
// Enabling alerts for players on join if they have the permissions to
|
||||
if(getBukkitPlayer().hasPermission("anticheat.command.alerts")
|
||||
|| getBukkitPlayer().hasPermission("anticheat.alerts")) {
|
||||
Check.alertsEnabled.add(getUuid());
|
||||
getBukkitPlayer().spigot().sendMessage(Messages.ALERTS_ON);
|
||||
}
|
||||
initialized = true;
|
||||
Anticheat.INSTANCE.getRunUtils().task(() -> checkHandler.initChecks());
|
||||
}, 100, TimeUnit.MILLISECONDS);
|
||||
|
||||
if(PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) {
|
||||
this.wrappedPlayer = new LegacyPlayer(getBukkitPlayer());
|
||||
} else this.wrappedPlayer = new ModernPlayer(getBukkitPlayer());
|
||||
|
||||
Cache<AxisAlignedBB, List<AxisAlignedBB>> collisionCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(200)
|
||||
.expireAfterWrite(100, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
|
||||
EMULATOR = new Emulator(new DataSupplier() {
|
||||
@Override
|
||||
public List<AxisAlignedBB> getCollidingBoxes(AxisAlignedBB bb) {
|
||||
|
||||
var cacheIfPresent = collisionCache.getIfPresent(bb);
|
||||
|
||||
if(cacheIfPresent != null) return cacheIfPresent;
|
||||
|
||||
SimpleCollisionBox sbc = new SimpleCollisionBox(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ);
|
||||
|
||||
// Greater than 20? We want to truncate to prevent huge processing cost
|
||||
if(sbc.min().distanceSquared(sbc.max()) > 400) {
|
||||
sbc.maxX = sbc.minX + Math.min(sbc.maxX - sbc.minX, 20);
|
||||
sbc.maxY = sbc.minY + Math.max(sbc.maxY - sbc.minY, 20);
|
||||
sbc.maxZ = sbc.minZ + Math.max(sbc.maxZ - sbc.minZ, 20);
|
||||
}
|
||||
|
||||
List<AxisAlignedBB> axisAlignedBBs = new ArrayList<>();
|
||||
|
||||
for (SimpleCollisionBox bb2 : Helper.getCollisions(APlayer.this,
|
||||
sbc)) {
|
||||
axisAlignedBBs
|
||||
.add(new AxisAlignedBB(bb2.minX, bb2.minY, bb2.minZ, bb2.maxX, bb2.maxY, bb2.maxZ));
|
||||
}
|
||||
|
||||
collisionCache.put(bb, axisAlignedBBs);
|
||||
|
||||
return axisAlignedBBs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockAt(BlockPos blockPos) {
|
||||
//Optional<org.bukkit.block.Block>
|
||||
var block = APlayer.this.getWorldTracker()
|
||||
.getBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||
|
||||
StateType type = block.getType();
|
||||
|
||||
if(type == StateTypes.SLIME_BLOCK) {
|
||||
return new BlockSlime();
|
||||
} else if(type == StateTypes.SOUL_SAND) {
|
||||
return new BlockSoulSand();
|
||||
} else if(type == StateTypes.COBWEB) {
|
||||
return new BlockWeb();
|
||||
} else if(type == StateTypes.ICE || type == StateTypes.PACKED_ICE || type == StateTypes.FROSTED_ICE) {
|
||||
return new BlockIce();
|
||||
} else if(type == StateTypes.BLUE_ICE) {
|
||||
return new BlockBlueIce();
|
||||
}
|
||||
|
||||
return new Block();
|
||||
}
|
||||
}, getPlayerVersion().getProtocolVersion());
|
||||
|
||||
generateEntities();
|
||||
|
||||
// Enabling alerts for players on join if they have the permissions to
|
||||
if(getBukkitPlayer().hasPermission("anticheat.command.alerts")
|
||||
|| getBukkitPlayer().hasPermission("anticheat.alerts")) {
|
||||
Check.alertsEnabled.add(getUuid());
|
||||
getBukkitPlayer().spigot().sendMessage(Messages.ALERTS_ON);
|
||||
}
|
||||
initialized = true;
|
||||
Anticheat.INSTANCE.getRunUtils().task(() -> checkHandler.initChecks());
|
||||
}
|
||||
|
||||
private void generateEntities() {
|
||||
@@ -228,7 +247,7 @@ public class APlayer {
|
||||
|
||||
RayCollision coll = new RayCollision(origin.toVector(), origin.getDirection().multiply(-1));
|
||||
|
||||
Vector loc1 = coll.collisionPoint(2);
|
||||
Vector3d loc1 = coll.collisionPoint(2);
|
||||
|
||||
List<EntityData<?>> dataList = new ArrayList<>();
|
||||
|
||||
@@ -330,10 +349,6 @@ public class APlayer {
|
||||
user.writePacketSilently(packet);
|
||||
}
|
||||
|
||||
public DimensionType getDimensionType() {
|
||||
return user.getDimensionType();
|
||||
}
|
||||
|
||||
public void sendPacket(PacketWrapper<?> packet) {
|
||||
user.sendPacket(packet);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
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.Vector3i;
|
||||
import dev.brighten.ac.Anticheat;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||
@@ -132,11 +133,11 @@ public class BlockInformation {
|
||||
}
|
||||
|
||||
final StateType type =
|
||||
player.getBlockUpdateHandler().getBlock(new IntVector(x, y, z)).getType();
|
||||
player.getWorldTracker().getBlock(new Vector3i(x, y, z)).getType();
|
||||
|
||||
if (type != StateTypes.AIR) {
|
||||
|
||||
IntVector vec = new IntVector(x, y, z);
|
||||
Vector3i vec = new Vector3i(x, y, z);
|
||||
CollisionBox blockBox = BlockData.getData(type)
|
||||
.getBox(player, vec, player.getPlayerVersion());
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package dev.brighten.ac.data.info;
|
||||
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import dev.brighten.ac.data.obj.Pose;
|
||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||
import dev.brighten.ac.packet.PlayerCapabilities;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.KPotionEffect;
|
||||
import dev.brighten.ac.utils.PastLocation;
|
||||
import dev.brighten.ac.utils.math.RollingAverage;
|
||||
import dev.brighten.ac.utils.objects.evicting.EvictingList;
|
||||
@@ -12,8 +14,6 @@ import dev.brighten.ac.utils.timer.Timer;
|
||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -33,8 +33,8 @@ public class GeneralInformation {
|
||||
lastBlockUpdate = new TickTimer(), lastMiscNear = new TickTimer(), lastHalfBlock = new TickTimer(),
|
||||
lastFence = new TickTimer(), lastFakeBotHit = new TickTimer(), lastInventoryOpen = new TickTimer(),
|
||||
botAttack = new TickTimer(), lastAttack = new TickTimer(), lastCanceledFlying = new TickTimer();
|
||||
public LivingEntity target;
|
||||
public Optional<PotionEffect> groundJumpBoost;
|
||||
public TrackedEntity target;
|
||||
public Optional<KPotionEffect> groundJumpBoost = Optional.empty();
|
||||
public boolean serverGround, lastServerGround, canFly, nearGround, worldLoaded, generalCancel, inVehicle, creative,
|
||||
sneaking, lsneaking, sprinting, gliding, riptiding, wasOnSlime, onLadder, doingVelocity, breakingBlock,
|
||||
inventoryOpen, swimming;
|
||||
@@ -46,4 +46,7 @@ public class GeneralInformation {
|
||||
public List<Vector3d> velocityHistory = Collections.synchronizedList(new EvictingList<>(5));
|
||||
public List<PlayerCapabilities> possibleCapabilities = new ArrayList<>();
|
||||
private int clientGroundTicks, clientAirTicks;
|
||||
private double walkSpeed, flySpeed;
|
||||
private PlayerInput playerInput = PlayerInput.NONE;
|
||||
private Pose pose;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.brighten.ac.data.info;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerInput;
|
||||
|
||||
public record PlayerInput(boolean forward, boolean backward, boolean left, boolean right, boolean jump, boolean sprint, boolean shift) {
|
||||
|
||||
public static PlayerInput getFromPacket(WrapperPlayClientPlayerInput packet) {
|
||||
return new PlayerInput(packet.isForward(), packet.isBackward(), packet.isLeft(),
|
||||
packet.isRight(), packet.isJump(), packet.isSprint(), packet.isShift());
|
||||
}
|
||||
|
||||
public static final PlayerInput NONE = new PlayerInput(false, false, false,
|
||||
false, false, false, false);
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
package dev.brighten.ac.data.obj;
|
||||
|
||||
import dev.brighten.ac.handler.block.World;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.World;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package dev.brighten.ac.data.obj;
|
||||
|
||||
public enum Pose {
|
||||
STANDING(0.6f, 1.8f, 1.62f),
|
||||
FALL_FLYING(0.6f, 0.6f, 0.4f),
|
||||
SLEEPING(0.2f, 0.2f, 0.2f),
|
||||
SWIMMING(0.6f, 0.6f, 0.4f),
|
||||
SPIN_ATTACK(0.6f, 0.6f, 0.4f),
|
||||
CROUCHING(0.6f, 1.5f, 1.27f),
|
||||
DYING(0.2f, 0.2f, 0.2f),
|
||||
|
||||
// Non-player poses
|
||||
NINE_CROUCHING(0.6f, 1.65f, 1.54f), // 1.9-1.13 clients have a slightly different crouching hitbox
|
||||
LONG_JUMPING(0.6f, 1.8f, 1.54f); // DUMMY (players can't have this pose)
|
||||
|
||||
public final float width;
|
||||
public final float height;
|
||||
public final float eyeHeight;
|
||||
|
||||
Pose(float width, float height, float eyeHeight) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.eyeHeight = eyeHeight;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
package dev.brighten.ac.handler;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import dev.brighten.ac.Anticheat;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||
import dev.brighten.ac.utils.ItemBuilder;
|
||||
import dev.brighten.ac.utils.Materials;
|
||||
import dev.brighten.ac.utils.annotation.Init;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import dev.brighten.ac.utils.world.BlockData;
|
||||
import dev.brighten.ac.utils.world.EntityData;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
@@ -31,7 +31,7 @@ import java.util.stream.Collectors;
|
||||
@Init
|
||||
public class BBRevealHandler implements Listener {
|
||||
|
||||
private final Map<UUID, Set<IntVector>> blocksToShow = new HashMap<>();
|
||||
private final Map<UUID, Set<Vector3i>> blocksToShow = new HashMap<>();
|
||||
private final Set<Entity> entitiesToShow = new HashSet<>();
|
||||
|
||||
public static BBRevealHandler INSTANCE;
|
||||
@@ -52,9 +52,9 @@ public class BBRevealHandler implements Listener {
|
||||
if(player == null || !player.getWrappedPlayer().getItemInHand().isSimilar(wand)) return;
|
||||
|
||||
if(event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
IntVector blockLoc = new IntVector(event.getClickedBlock().getX(),
|
||||
Vector3i blockLoc = new Vector3i(event.getClickedBlock().getX(),
|
||||
event.getClickedBlock().getY(), event.getClickedBlock().getZ());
|
||||
Set<IntVector> blocksToShow = this.blocksToShow
|
||||
Set<Vector3i> blocksToShow = this.blocksToShow
|
||||
.computeIfAbsent(event.getPlayer().getUniqueId(), k -> new HashSet<>());
|
||||
if(blocksToShow.contains(blockLoc)) {
|
||||
blocksToShow.remove(blockLoc);
|
||||
@@ -63,11 +63,11 @@ public class BBRevealHandler implements Listener {
|
||||
.create());
|
||||
} else {
|
||||
blocksToShow.add(blockLoc);
|
||||
WrappedBlock block = player.getBlockUpdateHandler().getBlock(blockLoc);
|
||||
WrappedBlock block = player.getWorldTracker().getCurrentWorld().get().getBlock(blockLoc);
|
||||
event.getPlayer().spigot().sendMessage(new ComponentBuilder("Now showing block: ")
|
||||
.color(ChatColor.GREEN).color(ChatColor.WHITE).append(event.getClickedBlock().getType().name())
|
||||
.color(ChatColor.GRAY)
|
||||
.append(" flags: " + block.getBlockState().getType() + " | " + Materials.checkFlag(block.getType(), Materials.COLLIDABLE) + "," +
|
||||
.append(" flags: " + block.getType() + " | " + block.getType().isSolid() + "," +
|
||||
Materials.checkFlag(block.getType(), Materials.SOLID) + "," + Materials.checkFlag(block.getType(), Materials.LIQUID))
|
||||
.color(ChatColor.RED)
|
||||
.append(" | box=" + BlockData.getData(block.getType()).getBox(player, blockLoc, player.getPlayerVersion()).downCast().stream().map(SimpleCollisionBox::toString).collect(Collectors.joining(", ")))
|
||||
@@ -107,7 +107,7 @@ public class BBRevealHandler implements Listener {
|
||||
if(player.isEmpty()) return;
|
||||
|
||||
blocks.forEach(blockLoc -> {
|
||||
var block = player.get().getBlockUpdateHandler().getBlock(blockLoc);
|
||||
var block = player.get().getWorldTracker().getCurrentWorld().get().getBlock(blockLoc);
|
||||
|
||||
var blockBox = BlockData.getData(block.getType())
|
||||
.getBox(player.get(), blockLoc, player.get().getPlayerVersion());
|
||||
|
||||
+50
-37
@@ -1,14 +1,17 @@
|
||||
package dev.brighten.ac.handler;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityPositionSync;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityTeleport;
|
||||
import dev.brighten.ac.Anticheat;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.entity.FakeMob;
|
||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||
@@ -18,20 +21,15 @@ import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.timer.Timer;
|
||||
import dev.brighten.ac.utils.timer.impl.MillisTimer;
|
||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class EntityLocationHandler {
|
||||
public class EntityTrackHandler {
|
||||
|
||||
private final APlayer data;
|
||||
@Getter
|
||||
private Map<Integer, TrackedEntity> trackedEntities = new Int2ObjectArrayMap<>();
|
||||
private final Timer lastFlying = new MillisTimer();
|
||||
|
||||
public Set<Integer> canCreateMob = new HashSet<>();
|
||||
@@ -43,7 +41,8 @@ public class EntityLocationHandler {
|
||||
EntityTypes.WITCH, EntityTypes.COW, EntityTypes.CREEPER);
|
||||
|
||||
public Optional<Integer> getTargetOfFakeMob(int fakeMobId) {
|
||||
for (TrackedEntity value : trackedEntities.values()) {
|
||||
for (TrackedEntity value : data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntities().values()) {
|
||||
if(value.getFakeMobs().stream().anyMatch(mob -> mob.getEntityId() == fakeMobId)) {
|
||||
return Optional.of(value.getEntityId());
|
||||
}
|
||||
@@ -51,23 +50,6 @@ public class EntityLocationHandler {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<TrackedEntity> getTrackedEntity(int entityId) {
|
||||
TrackedEntity trackedEntity = trackedEntities.get(entityId);
|
||||
|
||||
if(trackedEntity == null) {
|
||||
var entity = Anticheat.INSTANCE.getWorldInfo(data.getBukkitPlayer().getWorld()).getEntity(entityId);
|
||||
|
||||
if(entity.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
KLocation loc = new KLocation(entity.get().getLocation());
|
||||
trackedEntity = new TrackedEntity(entityId, EntityTypes.PLAYER, loc);
|
||||
trackedEntities.put(entityId, trackedEntity);
|
||||
}
|
||||
|
||||
return Optional.of(trackedEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* We are processing PacketPlayInFlying to iterate the tracked entity locations
|
||||
@@ -81,7 +63,7 @@ public class EntityLocationHandler {
|
||||
|
||||
processZombie();
|
||||
|
||||
trackedEntities.values().forEach(entity -> {
|
||||
data.getWorldTracker().getCurrentWorld().get().getTrackedEntities().values().forEach(entity -> {
|
||||
var oldLoc = entity.getOldEntityLocation();
|
||||
var newLoc = entity.getNewEntityLocation();
|
||||
|
||||
@@ -109,7 +91,8 @@ public class EntityLocationHandler {
|
||||
* @param packet WrappedOutRelativePosition
|
||||
*/
|
||||
void onRelPosition(WPacketPlayOutEntity packet) {
|
||||
Optional<TrackedEntity> entity = getTrackedEntity(packet.getId());
|
||||
Optional<TrackedEntity> entity = data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(packet.getId());
|
||||
|
||||
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
||||
|
||||
@@ -132,7 +115,8 @@ public class EntityLocationHandler {
|
||||
}
|
||||
|
||||
void onPositionSync(WrapperPlayServerEntityPositionSync packet) {
|
||||
Optional<TrackedEntity> entity = getTrackedEntity(packet.getId());
|
||||
Optional<TrackedEntity> entity = data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(packet.getId());
|
||||
|
||||
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
||||
|
||||
@@ -161,7 +145,8 @@ public class EntityLocationHandler {
|
||||
* @param packet WrappedOutEntityTeleportPacket
|
||||
*/
|
||||
void onTeleportSent(WrapperPlayServerEntityTeleport packet) {
|
||||
Optional<TrackedEntity> entity = getTrackedEntity(packet.getEntityId());
|
||||
Optional<TrackedEntity> entity = data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(packet.getEntityId());
|
||||
|
||||
if(entity.isEmpty() || !allowedEntityTypes.contains(entity.get().getEntityType())) return;
|
||||
|
||||
@@ -205,6 +190,28 @@ public class EntityLocationHandler {
|
||||
});
|
||||
}
|
||||
|
||||
void updateAttributes(WrapperPlayServerUpdateAttributes attributes) {
|
||||
data.runKeepaliveAction(ka -> {
|
||||
TrackedEntity tracked = data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(attributes.getEntityId()).orElse(null);
|
||||
|
||||
if(tracked == null) return;
|
||||
|
||||
for (WrapperPlayServerUpdateAttributes.Property property : attributes.getProperties()) {
|
||||
Attribute attribute = property.getAttribute();
|
||||
|
||||
if(attributes.getEntityId() == data.getBukkitPlayer().getEntityId() && attribute == Attributes.MOVEMENT_SPEED) {
|
||||
ValuedAttribute value = tracked.getAttribute(attribute);
|
||||
|
||||
value.updateAttribute(property);
|
||||
data.getInfo().setWalkSpeed(value.getValue());
|
||||
}
|
||||
|
||||
tracked.updateAttribute(property);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* We are running an action when a transaction is received. If the Entity provided is currently a target,
|
||||
@@ -239,8 +246,10 @@ public class EntityLocationHandler {
|
||||
}
|
||||
|
||||
public void removeFakeMob(int id) {
|
||||
if(trackedEntities.containsKey(id)) {
|
||||
List<FakeMob> mobs = getTrackedEntity(id).map(TrackedEntity::getFakeMobs).orElse(new ArrayList<>());
|
||||
if(data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntities().containsKey(id)) {
|
||||
List<FakeMob> mobs = data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(id).map(TrackedEntity::getFakeMobs).orElse(new ArrayList<>());
|
||||
|
||||
for (FakeMob mob : mobs) {
|
||||
mob.despawn();
|
||||
@@ -256,9 +265,11 @@ public class EntityLocationHandler {
|
||||
private void createFakeMob(int entityId, KLocation location) {
|
||||
if (!canCreateMob.contains(entityId)) return;
|
||||
|
||||
Optional<TrackedEntity> trackedEntity = getTrackedEntity(entityId);
|
||||
Optional<TrackedEntity> trackedEntity = data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(entityId);
|
||||
|
||||
Optional<TrackedEntity> playerEntity = getTrackedEntity(data.getBukkitPlayer().getEntityId());
|
||||
Optional<TrackedEntity> playerEntity = data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(data.getBukkitPlayer().getEntityId());
|
||||
|
||||
if(trackedEntity.isEmpty() || playerEntity.isEmpty()) return;
|
||||
|
||||
@@ -281,7 +292,7 @@ public class EntityLocationHandler {
|
||||
|
||||
RayCollision collision = new RayCollision(eyeLoc.toVector(), eyeLoc.getDirection());
|
||||
|
||||
Vector point = collision.collisionPoint(0.4);
|
||||
Vector3d point = collision.collisionPoint(0.4);
|
||||
|
||||
FakeMob mob = new FakeMob(EntityTypes.SLIME);
|
||||
List<EntityData<?>> types = new ArrayList<>();
|
||||
@@ -298,7 +309,8 @@ public class EntityLocationHandler {
|
||||
}
|
||||
|
||||
public void processZombie() {
|
||||
List<FakeMob> fakeMobs = getTrackedEntity(data.getBukkitPlayer().getEntityId())
|
||||
List<FakeMob> fakeMobs = data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(data.getBukkitPlayer().getEntityId())
|
||||
.map(TrackedEntity::getFakeMobs)
|
||||
.orElse(new ArrayList<>());
|
||||
|
||||
@@ -312,7 +324,7 @@ public class EntityLocationHandler {
|
||||
|
||||
RayCollision collision = new RayCollision(eyeLoc.toVector(), eyeLoc.getDirection());
|
||||
|
||||
Vector point = collision.collisionPoint(0.4);
|
||||
Vector3d point = collision.collisionPoint(0.4);
|
||||
|
||||
fakeMob.teleport(point.getX(), point.getY(), point.getZ(), 0 ,0);
|
||||
break;
|
||||
@@ -321,7 +333,8 @@ public class EntityLocationHandler {
|
||||
}
|
||||
|
||||
public void processFakeMobs(int entityId, boolean rel, double x, double y, double z) {
|
||||
List<FakeMob> fakeMobs = getTrackedEntity(entityId).map(TrackedEntity::getFakeMobs).orElse(new ArrayList<>());
|
||||
List<FakeMob> fakeMobs = data.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(entityId).map(TrackedEntity::getFakeMobs).orElse(new ArrayList<>());
|
||||
|
||||
if(fakeMobs.isEmpty()) {
|
||||
if(!rel) {
|
||||
@@ -3,6 +3,7 @@ package dev.brighten.ac.handler;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||
import com.github.retrooper.packetevents.protocol.teleport.RelativeFlag;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
@@ -12,13 +13,13 @@ import dev.brighten.ac.compat.CompatHandler;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.data.obj.CMove;
|
||||
import dev.brighten.ac.utils.*;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import dev.brighten.ac.utils.objects.evicting.EvictingList;
|
||||
import dev.brighten.ac.utils.timer.Timer;
|
||||
import dev.brighten.ac.utils.timer.impl.TickTimer;
|
||||
import dev.brighten.ac.utils.world.CollisionBox;
|
||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
@@ -30,9 +31,6 @@ import me.hydro.emulator.util.Vector;
|
||||
import me.hydro.emulator.util.mcp.MathHelper;
|
||||
import me.hydro.emulator.util.mcp.MathHelper.FastMathType;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -87,21 +85,14 @@ public class MovementHandler {
|
||||
private final Timer lastCinematic = new TickTimer(2);
|
||||
private final Timer lastReset = new TickTimer(2);
|
||||
private final EvictingList<Integer> sensitivitySamples = new EvictingList<>(50);
|
||||
private boolean modernMovement;
|
||||
private final boolean modernMovement;
|
||||
|
||||
public MovementHandler(APlayer player) {
|
||||
this.player = player;
|
||||
|
||||
Player bplayer = player.getBukkitPlayer();
|
||||
|
||||
// Initializing player location
|
||||
to.setWorld(bplayer.getWorld());
|
||||
to.getLoc().setX(bplayer.getLocation().getX());
|
||||
to.getLoc().setY(bplayer.getLocation().getY());
|
||||
to.getLoc().setZ(bplayer.getLocation().getZ());
|
||||
to.getLoc().setYaw(bplayer.getLocation().getYaw());
|
||||
to.getLoc().setPitch(bplayer.getLocation().getPitch());
|
||||
to.setBox(new SimpleCollisionBox(to.getLoc(), 0.6, 1.8));
|
||||
to.setOnGround(bplayer.isOnGround());
|
||||
to.setOnGround(false);
|
||||
|
||||
// Setting from as same location as to
|
||||
from.setLoc(to);
|
||||
@@ -123,31 +114,32 @@ public class MovementHandler {
|
||||
*/
|
||||
final PotionEffect[] EFFECTS = new PotionEffect[3];
|
||||
|
||||
for (org.bukkit.potion.PotionEffect potionEffect : player.getPotionHandler().potionEffects) {
|
||||
if (potionEffect.getType().equals(PotionEffectType.SPEED)) {
|
||||
for (KPotionEffect potionEffect : player.getPotionHandler().getPotionEffects()) {
|
||||
if (potionEffect.potionType().equals(PotionTypes.SPEED)) {
|
||||
EFFECTS[0] = PotionEffect.builder()
|
||||
.amplifier(potionEffect.getAmplifier())
|
||||
.amplifier(potionEffect.properties().amplifier())
|
||||
.type(me.hydro.emulator.util.PotionEffectType.SPEED)
|
||||
.build();
|
||||
} else if (potionEffect.getType().equals(PotionEffectType.SLOW)) {
|
||||
} else if (potionEffect.potionType().equals(PotionTypes.SLOWNESS)) {
|
||||
EFFECTS[1] = PotionEffect.builder()
|
||||
.amplifier(potionEffect.getAmplifier())
|
||||
.amplifier(potionEffect.properties().amplifier())
|
||||
.type(me.hydro.emulator.util.PotionEffectType.SLOW)
|
||||
.build();
|
||||
} else if (potionEffect.getType().equals(PotionEffectType.JUMP)) {
|
||||
} else if (potionEffect.potionType().equals(PotionTypes.JUMP_BOOST)) {
|
||||
EFFECTS[2] = PotionEffect.builder()
|
||||
.amplifier(potionEffect.getAmplifier())
|
||||
.amplifier(potionEffect.properties().amplifier())
|
||||
.type(me.hydro.emulator.util.PotionEffectType.JUMP)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
if(player.EMULATOR.getTags().contains("003") && !isZeroThree) {
|
||||
if (player.EMULATOR.getTags().contains("003") && !isZeroThree) {
|
||||
runEmulation(to, true);
|
||||
}
|
||||
|
||||
IterationResult minimum = null;
|
||||
iteration: {
|
||||
iteration:
|
||||
{
|
||||
for (KLocation posLoc : new ArrayList<>(posLocs)) {
|
||||
// Resetting to prevent lag issues.
|
||||
|
||||
@@ -157,7 +149,7 @@ public class MovementHandler {
|
||||
if (minimum == null || minimum.getOffset() > result.getOffset()) {
|
||||
minimum = result;
|
||||
|
||||
if(minimum.getOffset() < 1E-26) {
|
||||
if (minimum.getOffset() < 1E-26) {
|
||||
// The player teleported, therefore we don't need to continue with predictions.
|
||||
break iteration;
|
||||
}
|
||||
@@ -171,96 +163,95 @@ public class MovementHandler {
|
||||
|
||||
Motion previousMotion = player.EMULATOR.getMotion().clone();
|
||||
|
||||
for (int forward : isZeroThree ? new int[] {0} : FULL_RANGE) {
|
||||
for (int strafe : isZeroThree ? new int[] {0} : FULL_RANGE) {
|
||||
for (int forward : isZeroThree ? new int[]{0} : FULL_RANGE) {
|
||||
for (int strafe : isZeroThree ? new int[]{0} : FULL_RANGE) {
|
||||
for (boolean jumping : getJumpingIterations()) {
|
||||
for (boolean sprinting : getSprintingIterations(forward)) {
|
||||
for (boolean usingItem : getUsingItemIterations(forward, strafe)) {
|
||||
for (boolean hitSlow : getHitSlowIterations()) {
|
||||
for (FastMathType fastMath : getFastMathIterations(forward, strafe)) {
|
||||
for(Vector3d possibleVector : possibleVelocity) {
|
||||
IterationInput input = IterationInput.builder()
|
||||
.jumping(jumping)
|
||||
.forward(forward)
|
||||
.strafing(strafe)
|
||||
.sprinting(sprinting)
|
||||
.usingItem(usingItem)
|
||||
.modernMovement(modernMovement)
|
||||
.hitSlowdown(hitSlow)
|
||||
.aiMoveSpeed(player.getBukkitPlayer().getWalkSpeed() / 2)
|
||||
.fastMathType(fastMath)
|
||||
.sneaking(player.getInfo().isSneaking())
|
||||
.ground(from.isOnGround())
|
||||
.to(new Vector(to.getX(), to.getY(), to.getZ()))
|
||||
.yaw(to.getYaw())
|
||||
.lastReportedBoundingBox(from.getBox().toNeo())
|
||||
.effectSpeed(EFFECTS[0])
|
||||
.effectSlow(EFFECTS[1])
|
||||
.waitingForTeleport(!posLocs.isEmpty())
|
||||
.effectJump(EFFECTS[2]).build();
|
||||
for (boolean usingItem : getUsingItemIterations(forward, strafe)) {
|
||||
for (boolean hitSlow : getHitSlowIterations()) {
|
||||
for (FastMathType fastMath : getFastMathIterations(forward, strafe)) {
|
||||
for (Vector3d possibleVector : possibleVelocity) {
|
||||
IterationInput input = IterationInput.builder()
|
||||
.jumping(jumping)
|
||||
.forward(forward)
|
||||
.strafing(strafe)
|
||||
.sprinting(sprinting)
|
||||
.usingItem(usingItem)
|
||||
.modernMovement(modernMovement)
|
||||
.hitSlowdown(hitSlow)
|
||||
.aiMoveSpeed(player.getBukkitPlayer().getWalkSpeed() / 2)
|
||||
.fastMathType(fastMath)
|
||||
.sneaking(player.getInfo().sneaking)
|
||||
.ground(from.isOnGround())
|
||||
.to(new Vector(to.getX(), to.getY(), to.getZ()))
|
||||
.yaw(to.getYaw())
|
||||
.lastReportedBoundingBox(from.getBox().toNeo())
|
||||
.effectSpeed(EFFECTS[0])
|
||||
.effectSlow(EFFECTS[1])
|
||||
.waitingForTeleport(!posLocs.isEmpty())
|
||||
.effectJump(EFFECTS[2]).build();
|
||||
|
||||
boolean isVelocity = false;
|
||||
if(possibleVector != null) {
|
||||
// Setting the motion to the possible velocity vector.
|
||||
player.EMULATOR.getMotion().setMotionX(possibleVector.getX());
|
||||
player.EMULATOR.getMotion().setMotionY(possibleVector.getY());
|
||||
player.EMULATOR.getMotion().setMotionZ(possibleVector.getZ());
|
||||
// Has to be this way because order of operations in the emulator.
|
||||
isVelocity = true;
|
||||
} else {
|
||||
// Resetting the motion to the previous motion.
|
||||
player.EMULATOR.getMotion().setMotionX(previousMotion.getMotionX());
|
||||
player.EMULATOR.getMotion().setMotionY(previousMotion.getMotionY());
|
||||
player.EMULATOR.getMotion().setMotionZ(previousMotion.getMotionZ());
|
||||
}
|
||||
boolean isVelocity = false;
|
||||
if (possibleVector != null) {
|
||||
// Setting the motion to the possible velocity vector.
|
||||
player.EMULATOR.getMotion().setMotionX(possibleVector.getX());
|
||||
player.EMULATOR.getMotion().setMotionY(possibleVector.getY());
|
||||
player.EMULATOR.getMotion().setMotionZ(possibleVector.getZ());
|
||||
// Has to be this way because order of operations in the emulator.
|
||||
isVelocity = true;
|
||||
} else {
|
||||
// Resetting the motion to the previous motion.
|
||||
player.EMULATOR.getMotion().setMotionX(previousMotion.getMotionX());
|
||||
player.EMULATOR.getMotion().setMotionY(previousMotion.getMotionY());
|
||||
player.EMULATOR.getMotion().setMotionZ(previousMotion.getMotionZ());
|
||||
}
|
||||
|
||||
IterationResult result = player.EMULATOR.runIteration(input);
|
||||
IterationResult result = player.EMULATOR.runIteration(input);
|
||||
|
||||
if(isVelocity) {
|
||||
result.getTags().add("velocity");
|
||||
}
|
||||
if (isVelocity) {
|
||||
result.getTags().add("velocity");
|
||||
}
|
||||
|
||||
|
||||
if(fastMath == FastMathType.FAST_LEGACY) {
|
||||
result.getTags().add("fast_legacy");
|
||||
} else if(fastMath == FastMathType.VANILLA) {
|
||||
result.getTags().add("vanilla");
|
||||
} else if(fastMath == FastMathType.FAST_NEW) {
|
||||
result.getTags().add("fast_new");
|
||||
} else if(fastMath == FastMathType.MODERN_VANILLA) {
|
||||
result.getTags().add("modern_vanilla");
|
||||
}
|
||||
if (fastMath == FastMathType.FAST_LEGACY) {
|
||||
result.getTags().add("fast_legacy");
|
||||
} else if (fastMath == FastMathType.VANILLA) {
|
||||
result.getTags().add("vanilla");
|
||||
} else if (fastMath == FastMathType.FAST_NEW) {
|
||||
result.getTags().add("fast_new");
|
||||
} else if (fastMath == FastMathType.MODERN_VANILLA) {
|
||||
result.getTags().add("modern_vanilla");
|
||||
}
|
||||
|
||||
if(forward > 0) {
|
||||
result.getTags().add("w-key");
|
||||
} else if(forward < 0) {
|
||||
result.getTags().add("s-key");
|
||||
}
|
||||
if (forward > 0) {
|
||||
result.getTags().add("w-key");
|
||||
} else if (forward < 0) {
|
||||
result.getTags().add("s-key");
|
||||
}
|
||||
|
||||
if(strafe > 0) {
|
||||
result.getTags().add("d-key");
|
||||
} else if(strafe < 0) {
|
||||
result.getTags().add("a-key");
|
||||
}
|
||||
if (strafe > 0) {
|
||||
result.getTags().add("d-key");
|
||||
} else if (strafe < 0) {
|
||||
result.getTags().add("a-key");
|
||||
}
|
||||
|
||||
if (minimum == null || minimum.getOffset() > result.getOffset()) {
|
||||
minimum = result;
|
||||
if (minimum == null || minimum.getOffset() > result.getOffset()) {
|
||||
minimum = result;
|
||||
|
||||
if (minimum.getOffset() < 1E-26) {
|
||||
break iteration;
|
||||
if (minimum.getOffset() < 1E-26) {
|
||||
break iteration;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(minimum != null) {
|
||||
if (minimum != null) {
|
||||
predicted = minimum.getPredicted();
|
||||
|
||||
double mx = player.EMULATOR.getMotion().getMotionX();
|
||||
@@ -269,7 +260,7 @@ public class MovementHandler {
|
||||
|
||||
double total = mx * mx + my * my + mz * mz;
|
||||
|
||||
if(total < 9E-4) {
|
||||
if (total < 9E-4) {
|
||||
player.getInfo().lastCanceledFlying.reset();
|
||||
minimum.getTags().add("003");
|
||||
}
|
||||
@@ -282,11 +273,11 @@ public class MovementHandler {
|
||||
}
|
||||
player.EMULATOR.confirm(minimum.getIteration());
|
||||
|
||||
if(minimum.getTags().contains("003")) {
|
||||
if (minimum.getTags().contains("003")) {
|
||||
player.EMULATOR.getTags().add("003");
|
||||
}
|
||||
|
||||
if(minimum.getTags().contains("bad_offset")) {
|
||||
if (minimum.getTags().contains("bad_offset")) {
|
||||
player.EMULATOR.setLastReportedBoundingBox(getTo().getBox().toNeo());
|
||||
}
|
||||
}
|
||||
@@ -294,7 +285,7 @@ public class MovementHandler {
|
||||
|
||||
private FastMathType[] getFastMathIterations(int strafe, int forward) {
|
||||
// Because no movement is being applied, there is no angle calculation being done
|
||||
if(strafe == 0 && forward == 0) {
|
||||
if (strafe == 0 && forward == 0) {
|
||||
return new FastMathType[]{FastMathType.FAST_LEGACY};
|
||||
}
|
||||
|
||||
@@ -317,7 +308,9 @@ public class MovementHandler {
|
||||
|
||||
private boolean[] getUsingItemIterations(int forward, int strafe) {
|
||||
return (forward == 0 && strafe == 0 ||
|
||||
!BlockUtils.isUsable(player.getBukkitPlayer().getItemInHand().getType())) ? ALWAYS_FALSE : IS_OR_NOT;
|
||||
!BlockUtils.isUsable(player.getPlayerVersion(),
|
||||
SpigotConversionUtil.fromBukkitItemMaterial(player.getBukkitPlayer().getInventory().getItemInHand().getType())))
|
||||
? ALWAYS_FALSE : IS_OR_NOT;
|
||||
}
|
||||
|
||||
private boolean[] getJumpingIterations() {
|
||||
@@ -336,13 +329,13 @@ public class MovementHandler {
|
||||
&& player.getPlayerVersion().isNewerThanOrEquals(ClientVersion.V_1_17);
|
||||
|
||||
checkMovement = teleportsToConfirm == 0 && posLocs.isEmpty();
|
||||
|
||||
|
||||
if (checkMovement) {
|
||||
moveTicks++;
|
||||
if (!packet.hasPositionChanged()) moveTicks = 1;
|
||||
} else moveTicks = 0;
|
||||
|
||||
if(excuseNextFlying) {
|
||||
if (excuseNextFlying) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -359,10 +352,10 @@ public class MovementHandler {
|
||||
if (moveTicks > 0) {
|
||||
|
||||
// Updating block locations
|
||||
player.getInfo().setBlockOnTo(Optional.of(player.getBlockUpdateHandler()
|
||||
.getBlock(new IntVector(to.getLoc()))));
|
||||
player.getInfo().setBlockBelow(Optional.of(player.getBlockUpdateHandler()
|
||||
.getBlock(new IntVector(to.getLoc().clone().subtract(0, 1, 0)))));
|
||||
player.getInfo().setBlockOnTo(Optional.of(player.getWorldTracker()
|
||||
.getBlock(to.getLoc().toVector3i())));
|
||||
player.getInfo().setBlockBelow(Optional.of(player.getWorldTracker()
|
||||
.getBlock(to.getLoc().clone().subtract(0, 1, 0).clone().toVector3i())));
|
||||
|
||||
if (packet.hasPositionChanged()) {
|
||||
// Updating player bounding box
|
||||
@@ -486,7 +479,7 @@ public class MovementHandler {
|
||||
player.getInfo().setWasOnSlime(player.getBlockInfo().onSlime);
|
||||
groundTicks++;
|
||||
airTicks = 0;
|
||||
player.getInfo().groundJumpBoost = player.getPotionHandler().getEffectByType(PotionEffectType.JUMP);
|
||||
player.getInfo().groundJumpBoost = player.getPotionHandler().getEffectByType(PotionTypes.JUMP_BOOST);
|
||||
} else {
|
||||
player.getInfo().groundJumpBoost = Optional.empty();
|
||||
airTicks++;
|
||||
@@ -503,7 +496,7 @@ public class MovementHandler {
|
||||
.anyMatch(capability -> capability.canFly));
|
||||
|
||||
boolean hasLevitation = PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)
|
||||
&& player.getPotionHandler().hasPotionEffect(XPotion.LEVITATION.getPotionEffectType());
|
||||
&& player.getPotionHandler().hasPotionEffect(PotionTypes.LEVITATION);
|
||||
|
||||
player.getInfo().setRiptiding(CompatHandler.getINSTANCE().isRiptiding(player.getBukkitPlayer()));
|
||||
player.getInfo().setGliding(CompatHandler.getINSTANCE().isGliding(player.getBukkitPlayer()));
|
||||
@@ -570,7 +563,7 @@ it
|
||||
// generate a method that processes velocityHistory and compares to current deltaY.
|
||||
private void processVelocity() {
|
||||
//Iterate through player.getInfo().getVelocityHistory() and compare to current deltaY.
|
||||
if(player.getInfo().isDoingVelocity()) {
|
||||
if (player.getInfo().isDoingVelocity()) {
|
||||
player.getInfo().getVelocity().reset();
|
||||
}
|
||||
synchronized (player.getInfo().getVelocityHistory()) {
|
||||
@@ -590,22 +583,22 @@ it
|
||||
}
|
||||
|
||||
private void processBotMove(WrapperPlayClientPlayerFlying packet) {
|
||||
if(player.getMob() == null) return;
|
||||
if (player.getMob() == null) return;
|
||||
if (packet.hasPositionChanged() || packet.hasRotationChanged()) {
|
||||
KLocation origin = to.getLoc().clone().add(0, 1.7, 0);
|
||||
|
||||
final double MULTIPLIER = Math.max(-0.5, Math.min(-1, -1 / (Math.abs(deltaYaw) * 0.25)));
|
||||
RayCollision coll = new RayCollision(origin.toVector(), origin.getDirection()
|
||||
.multiply(MULTIPLIER).setY(0));
|
||||
.multiply(MULTIPLIER).withY(0));
|
||||
|
||||
Location loc1 = coll.collisionPoint(1.5).toLocation(player.getBukkitPlayer().getWorld());
|
||||
KLocation loc1 = new KLocation(coll.collisionPoint(1.5));
|
||||
|
||||
if (player.getInfo().botAttack.isNotPassed(7)) {
|
||||
loc1.setY(Math.max(origin.getY() + 2, loc1.getY()));
|
||||
player.getMob().teleport(loc1.getX(), loc1.getY(), loc1.getZ(), loc1.getYaw(), loc1.getPitch());
|
||||
} else {
|
||||
loc1.setY(Math.max(origin.getY() + 0.6, loc1.getY()));
|
||||
if(Math.random() > 0.2)
|
||||
if (Math.random() > 0.2)
|
||||
Anticheat.INSTANCE.getRunUtils().taskLaterAsync(() -> player.getMob()
|
||||
.teleport(loc1.getX(), loc1.getY(), loc1.getZ(), loc1.getYaw(), loc1.getPitch()), 5);
|
||||
}
|
||||
@@ -661,7 +654,7 @@ it
|
||||
public void runPositionHackFix() {
|
||||
if (sentPositionUpdate) return;
|
||||
|
||||
player.sendPacket(new WrapperPlayServerPlayerPositionAndLook(0, Vector3d.zero(), new Vector3d(0,0,0), 0, 0,
|
||||
player.sendPacket(new WrapperPlayServerPlayerPositionAndLook(0, Vector3d.zero(), new Vector3d(0, 0, 0), 0, 0,
|
||||
relFlags));
|
||||
|
||||
player.getBukkitPlayer().sendMessage("§c[Anticheat] §7Position update sent to fix movement issues.");
|
||||
@@ -725,10 +718,10 @@ it
|
||||
packet.getYaw(), packet.getPitch());
|
||||
|
||||
if (packet.getRelativeFlags().has(RelativeFlag.X)) {
|
||||
loc.add(player.getMovement().getTo().getLoc().getX(), 0 ,0);
|
||||
loc.add(player.getMovement().getTo().getLoc().getX(), 0, 0);
|
||||
}
|
||||
if (packet.getRelativeFlags().has(RelativeFlag.Y)) {
|
||||
loc.add(0, player.getMovement().getTo().getLoc().getY() ,0);
|
||||
loc.add(0, player.getMovement().getTo().getLoc().getY(), 0);
|
||||
}
|
||||
if (packet.getRelativeFlags().has(RelativeFlag.Z)) {
|
||||
loc.add(0, 0, player.getMovement().getTo().getLoc().getZ());
|
||||
@@ -743,7 +736,6 @@ it
|
||||
teleportsToConfirm++;
|
||||
|
||||
loc.setTimeStamp(System.currentTimeMillis());
|
||||
|
||||
player.runKeepaliveAction(ka -> {
|
||||
teleportsToConfirm--;
|
||||
|
||||
@@ -762,7 +754,7 @@ it
|
||||
*
|
||||
* @param location Location
|
||||
*/
|
||||
public void moveTo(Location location) {
|
||||
public void moveTo(KLocation location) {
|
||||
KLocation newLoc = new KLocation(location);
|
||||
to.getLoc().setLocation(newLoc);
|
||||
to.getLoc().setLocation(newLoc);
|
||||
@@ -814,7 +806,7 @@ it
|
||||
* @param packet WrapperPlayClientPlayerFlyingh
|
||||
*/
|
||||
private void setTo(WrapperPlayClientPlayerFlying packet) {
|
||||
to.setWorld(player.getBukkitPlayer().getWorld());
|
||||
to.setWorld(player.getWorldTracker().getCurrentWorld().get());
|
||||
if (packet.hasPositionChanged()) {
|
||||
to.getLoc().setX(packet.getLocation().getX());
|
||||
to.getLoc().setY(packet.getLocation().getY());
|
||||
|
||||
@@ -18,6 +18,8 @@ import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import dev.brighten.ac.Anticheat;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.data.info.PlayerInput;
|
||||
import dev.brighten.ac.data.obj.Pose;
|
||||
import dev.brighten.ac.handler.entity.FakeMob;
|
||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||
import dev.brighten.ac.packet.PlayerCapabilities;
|
||||
@@ -26,10 +28,7 @@ import dev.brighten.ac.packet.WPacketPlayOutEntity;
|
||||
import dev.brighten.ac.utils.BlockUtils;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.MovementUtils;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import lombok.val;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -38,13 +37,14 @@ public class PacketHandler {
|
||||
public boolean processReceive(APlayer player, PacketReceiveEvent event) {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
Object wrapped;
|
||||
if (event.getPacketType().equals(PacketType.Play.Client.PONG)
|
||||
|| event.getPacketType().equals(PacketType.Play.Client.WINDOW_CONFIRMATION)) {
|
||||
|
||||
boolean cancel = false;
|
||||
if (event.getPacketType().equals(PacketType.Play.Client.PONG) || event.getPacketType().equals(PacketType.Play.Client.WINDOW_CONFIRMATION)) {
|
||||
TransactionClientWrapper packet = new TransactionClientWrapper(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
if(packet.getId() == 0) {
|
||||
if (packet.getId() == 0) {
|
||||
if (Anticheat.INSTANCE.getKeepaliveProcessor().keepAlives.get(packet.getAction()) != null) {
|
||||
Anticheat.INSTANCE.getKeepaliveProcessor().addResponse(player, packet.getAction());
|
||||
|
||||
@@ -68,7 +68,7 @@ public class PacketHandler {
|
||||
synchronized (player.instantTransaction) {
|
||||
var iterator = player.instantTransaction.keySet().iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
while (iterator.hasNext()) {
|
||||
Short key = iterator.next();
|
||||
|
||||
if (key > ka.id) {
|
||||
@@ -96,7 +96,7 @@ public class PacketHandler {
|
||||
|
||||
synchronized (player.keepAliveLock) {
|
||||
player.keepAliveStamps.removeIf(action -> {
|
||||
if(action.stamp > ka.id) {
|
||||
if (action.stamp > ka.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -110,10 +110,17 @@ public class PacketHandler {
|
||||
Optional.ofNullable(player.instantTransaction.remove(packet.getAction()))
|
||||
.ifPresent(t -> t.two.accept(t.one));
|
||||
}
|
||||
} else if(event.getPacketType().equals(PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION)
|
||||
|| event.getPacketType().equals(PacketType.Play.Client.PLAYER_POSITION)
|
||||
|| event.getPacketType().equals(PacketType.Play.Client.PLAYER_ROTATION)
|
||||
|| event.getPacketType().equals(PacketType.Play.Client.PLAYER_FLYING)) {
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.PLAYER_INPUT)) {
|
||||
WrapperPlayClientPlayerInput packet = new WrapperPlayClientPlayerInput(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getInfo().setSprinting(packet.isSprint());
|
||||
player.getInfo().setSneaking(packet.isShift());
|
||||
player.getInfo().setPlayerInput(PlayerInput.getFromPacket(packet));
|
||||
|
||||
player.getBukkitPlayer().sendMessage("packet: " + packet.isForward());
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION) || event.getPacketType().equals(PacketType.Play.Client.PLAYER_POSITION) || event.getPacketType().equals(PacketType.Play.Client.PLAYER_ROTATION) || event.getPacketType().equals(PacketType.Play.Client.PLAYER_FLYING)) {
|
||||
WrapperPlayClientPlayerFlying packet = new WrapperPlayClientPlayerFlying(event);
|
||||
wrapped = packet;
|
||||
if (player.getMovement().isExcuseNextFlying()) {
|
||||
@@ -127,7 +134,7 @@ public class PacketHandler {
|
||||
|
||||
player.getLagInfo().setLastFlying(timestamp);
|
||||
|
||||
player.getEntityLocationHandler().onFlying();
|
||||
player.getEntityTrackHandler().onFlying();
|
||||
|
||||
if (player.getPlayerVersion().isNewerThanOrEquals(ClientVersion.V_1_17)
|
||||
&& packet.hasPositionChanged() && packet.hasRotationChanged()
|
||||
@@ -145,17 +152,17 @@ public class PacketHandler {
|
||||
player.getVelocityHandler().onFlyingPost(packet);
|
||||
|
||||
return result;
|
||||
} else if(event.getPacketType().equals(PacketType.Play.Client.STEER_VEHICLE)) {
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.STEER_VEHICLE)) {
|
||||
WrapperPlayClientSteerVehicle packet = new WrapperPlayClientSteerVehicle(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
// Check for isUnmount()
|
||||
if (player.getBukkitPlayer().isInsideVehicle() && packet.isUnmount()) {
|
||||
if (player.getInfo().isInVehicle() && packet.isUnmount()) {
|
||||
player.getInfo().getVehicleSwitch().reset();
|
||||
player.getInfo().setInVehicle(false);
|
||||
}
|
||||
} else if(event.getPacketType().equals(PacketType.Play.Client.ENTITY_ACTION)) {
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.ENTITY_ACTION)) {
|
||||
WrapperPlayClientEntityAction packet = new WrapperPlayClientEntityAction(event);
|
||||
|
||||
wrapped = packet;
|
||||
@@ -178,13 +185,13 @@ public class PacketHandler {
|
||||
break;
|
||||
}
|
||||
case START_FLYING_WITH_ELYTRA: {
|
||||
if(player.isGlidePossible()) {
|
||||
if (player.isGlidePossible()) {
|
||||
player.getInfo().setGliding(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(event.getPacketType().equals(PacketType.Play.Client.INTERACT_ENTITY)) {
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.INTERACT_ENTITY)) {
|
||||
WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
|
||||
|
||||
wrapped = packet;
|
||||
@@ -192,39 +199,44 @@ public class PacketHandler {
|
||||
FakeMob mob = Anticheat.INSTANCE.getFakeTracker().getEntityById(packet.getEntityId());
|
||||
|
||||
if (packet.getAction() == WrapperPlayClientInteractEntity.InteractAction.ATTACK) {
|
||||
if (player.hitsToCancel > 0) {
|
||||
player.hitsToCancel--;
|
||||
cancel = true;
|
||||
}
|
||||
if (mob != null) {
|
||||
player.getEntityLocationHandler().getTargetOfFakeMob(mob.getEntityId())
|
||||
player.getEntityTrackHandler().getTargetOfFakeMob(mob.getEntityId())
|
||||
.ifPresent(targetId -> {
|
||||
player.getEntityLocationHandler().removeFakeMob(targetId);
|
||||
player.getEntityTrackHandler().removeFakeMob(targetId);
|
||||
player.getInfo().lastFakeBotHit.reset();
|
||||
});
|
||||
if (player.getMob().getEntityId() == packet.getEntityId()) {
|
||||
player.getInfo().botAttack.reset();
|
||||
}
|
||||
} else {
|
||||
Optional<Entity> target = Anticheat.INSTANCE.getWorldInfo(player.getBukkitPlayer().getWorld()).getEntity(packet.getEntityId());
|
||||
Optional<TrackedEntity> target = player.getWorldTracker().getCurrentWorld().get()
|
||||
.getTrackedEntity(packet.getEntityId());
|
||||
|
||||
if(target.isPresent() && target.get() instanceof LivingEntity entity) {
|
||||
if (target.isPresent() && target.get().getEntityType().isInstanceOf(EntityTypes.LIVINGENTITY)) {
|
||||
if (player.getInfo().lastFakeBotHit.isPassed(400) && Math.random() > 0.9) {
|
||||
player.getEntityLocationHandler().canCreateMob.add(entity.getEntityId());
|
||||
player.getEntityTrackHandler().canCreateMob.add(target.get().getEntityId());
|
||||
}
|
||||
player.getInfo().setTarget(entity);
|
||||
player.getInfo().setTarget(target.get());
|
||||
}
|
||||
}
|
||||
player.getInfo().lastAttack.reset();
|
||||
}
|
||||
} else if(event.getPacketType().equals(PacketType.Play.Client.ANIMATION)) {
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.ANIMATION)) {
|
||||
WrapperPlayClientAnimation packet = new WrapperPlayClientAnimation(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
if(packet.getHand() == InteractionHand.MAIN_HAND) {
|
||||
if (packet.getHand() == InteractionHand.MAIN_HAND) {
|
||||
long delta = timestamp - player.getInfo().lastArmSwing;
|
||||
|
||||
player.getInfo().cps.add(1000D / delta, timestamp);
|
||||
player.getInfo().lastArmSwing = timestamp;
|
||||
}
|
||||
} else if(event.getPacketType().equals(PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT)) {
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT)) {
|
||||
WrapperPlayClientPlayerBlockPlacement packet = new WrapperPlayClientPlayerBlockPlacement(event);
|
||||
|
||||
wrapped = packet;
|
||||
@@ -236,19 +248,19 @@ public class PacketHandler {
|
||||
// Used item
|
||||
if (pos.getX() == -1 && (pos.getY() == 255 | pos.getY() == -1) && pos.getZ() == -1
|
||||
&& stack.isPresent()
|
||||
&& BlockUtils.isUsable(SpigotConversionUtil.toBukkitItemMaterial(stack.get().getType()))) {
|
||||
&& BlockUtils.isUsable(player.getPlayerVersion(), stack.get().getType())) {
|
||||
player.getInfo().getLastUseItem().reset();
|
||||
}
|
||||
|
||||
player.getBlockUpdateHandler().onPlace(packet);
|
||||
} else if(event.getPacketType().equals(PacketType.Play.Client.PLAYER_DIGGING)) {
|
||||
player.getWorldTracker().onPlace(packet);
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.PLAYER_DIGGING)) {
|
||||
WrapperPlayClientPlayerDigging packet = new WrapperPlayClientPlayerDigging(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getInfo().getLastBlockDig().reset();
|
||||
player.getBlockUpdateHandler().onDig(packet);
|
||||
} else if(event.getPacketType().equals(PacketType.Play.Client.CLIENT_STATUS)) {
|
||||
player.getWorldTracker().onDig(packet);
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.CLIENT_STATUS)) {
|
||||
WrapperPlayClientClientStatus packet = new WrapperPlayClientClientStatus(event);
|
||||
|
||||
wrapped = packet;
|
||||
@@ -258,10 +270,10 @@ public class PacketHandler {
|
||||
player.getInfo().lastInventoryOpen.reset();
|
||||
return false;
|
||||
}
|
||||
} else if(event.getPacketType().equals(PacketType.Play.Client.CLOSE_WINDOW)) {
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.CLOSE_WINDOW)) {
|
||||
wrapped = new WrapperPlayClientCloseWindow(event);
|
||||
player.getInfo().setInventoryOpen(false);
|
||||
} else if(event.getPacketType() == PacketType.Play.Client.PLUGIN_MESSAGE) {
|
||||
} else if (event.getPacketType().equals(PacketType.Play.Client.PLUGIN_MESSAGE)) {
|
||||
WrapperPlayClientPluginMessage packet = new WrapperPlayClientPluginMessage(event);
|
||||
|
||||
wrapped = packet;
|
||||
@@ -286,7 +298,7 @@ public class PacketHandler {
|
||||
+ ": " + wrapped);
|
||||
}
|
||||
|
||||
return player.getCheckHandler().callSyncPacket(wrapped, timestamp);
|
||||
return cancel || player.getCheckHandler().callSyncPacket(wrapped, timestamp);
|
||||
}
|
||||
|
||||
public boolean processSend(APlayer player, PacketSendEvent event) {
|
||||
@@ -309,30 +321,36 @@ public class PacketHandler {
|
||||
player.getInfo().getPossibleCapabilities().clear();
|
||||
}
|
||||
}, true);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.UPDATE_ATTRIBUTES) {
|
||||
WrapperPlayServerUpdateAttributes packet = new WrapperPlayServerUpdateAttributes(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getEntityTrackHandler().updateAttributes(packet);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.BLOCK_CHANGE) {
|
||||
WrapperPlayServerBlockChange packet = new WrapperPlayServerBlockChange(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getBlockUpdateHandler().runUpdate(packet);
|
||||
player.getWorldTracker().runUpdate(packet);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.MULTI_BLOCK_CHANGE) {
|
||||
WrapperPlayServerMultiBlockChange packet = new WrapperPlayServerMultiBlockChange(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getBlockUpdateHandler().runUpdate(packet);
|
||||
player.getWorldTracker().runUpdate(packet);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.CHUNK_DATA) {
|
||||
WrapperPlayServerChunkData packet = new WrapperPlayServerChunkData(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getBlockUpdateHandler().runUpdate(packet);
|
||||
player.getWorldTracker().runUpdate(packet);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.MAP_CHUNK_BULK) {
|
||||
WrapperPlayServerChunkDataBulk packet = new WrapperPlayServerChunkDataBulk(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getBlockUpdateHandler().runUpdate(packet);
|
||||
player.getWorldTracker().runUpdate(packet);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_EFFECT) {
|
||||
WrapperPlayServerEntityEffect packet = new WrapperPlayServerEntityEffect(event);
|
||||
|
||||
@@ -394,18 +412,19 @@ public class PacketHandler {
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.RESPAWN) {
|
||||
wrapped = new WrapperPlayServerRespawn(event);
|
||||
if(player.getPlayerVersion().isOlderThan(ClientVersion.V_1_14)) {
|
||||
player.runKeepaliveAction(k -> player.getBukkitPlayer().setSprinting(false), 1);
|
||||
player.runKeepaliveAction(k -> player.getInfo().setSprinting(false), 1);
|
||||
}
|
||||
player.runKeepaliveAction(ka -> player.getInfo().lastRespawn.reset());
|
||||
player.runKeepaliveAction(ka -> player.getBlockUpdateHandler()
|
||||
.setMinHeight(player.getDimensionType()));
|
||||
player.runKeepaliveAction(ka -> {
|
||||
player.getInfo().lastRespawn.reset();
|
||||
player.getInfo().setPose(Pose.STANDING);
|
||||
});
|
||||
player.runKeepaliveAction(ka -> player.getWorldTracker()
|
||||
.onRespawn((WrapperPlayServerRespawn) wrapped));
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.PLAYER_POSITION_AND_LOOK) {
|
||||
WrapperPlayServerPlayerPositionAndLook packet = new WrapperPlayServerPlayerPositionAndLook(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.runKeepaliveAction(ka ->
|
||||
player.getBlockUpdateHandler().setMinHeight(player.getDimensionType()));
|
||||
player.getMovement().addPosition(packet);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.ATTACH_ENTITY) {
|
||||
WrapperPlayServerAttachEntity packet = new WrapperPlayServerAttachEntity(event);
|
||||
@@ -423,37 +442,37 @@ public class PacketHandler {
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getEntityLocationHandler().onEntityDestroy(packet);
|
||||
player.getEntityTrackHandler().onEntityDestroy(packet);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_TELEPORT) {
|
||||
WrapperPlayServerEntityTeleport packet = new WrapperPlayServerEntityTeleport(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getEntityLocationHandler().onTeleportSent(packet);
|
||||
player.getEntityTrackHandler().onTeleportSent(packet);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_MOVEMENT) {
|
||||
WrapperPlayServerEntityMovement packet = new WrapperPlayServerEntityMovement(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getEntityLocationHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||
player.getEntityTrackHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_RELATIVE_MOVE) {
|
||||
WrapperPlayServerEntityRelativeMove packet = new WrapperPlayServerEntityRelativeMove(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getEntityLocationHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||
player.getEntityTrackHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_ROTATION) {
|
||||
WrapperPlayServerEntityRotation packet = new WrapperPlayServerEntityRotation(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getEntityLocationHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||
player.getEntityTrackHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_RELATIVE_MOVE_AND_ROTATION) {
|
||||
WrapperPlayServerEntityRelativeMoveAndRotation packet = new WrapperPlayServerEntityRelativeMoveAndRotation(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getEntityLocationHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||
player.getEntityTrackHandler().onRelPosition(new WPacketPlayOutEntity(packet));
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_ENTITY) {
|
||||
WrapperPlayServerSpawnEntity packet = new WrapperPlayServerSpawnEntity(event);
|
||||
wrapped = packet;
|
||||
@@ -462,7 +481,7 @@ public class PacketHandler {
|
||||
double y = packet.getPosition().getY();
|
||||
double z = packet.getPosition().getZ();
|
||||
|
||||
player.getEntityLocationHandler().getTrackedEntities().put(packet.getEntityId(),
|
||||
player.getWorldTracker().getCurrentWorld().get().getTrackedEntities().put(packet.getEntityId(),
|
||||
new TrackedEntity(packet.getEntityId(), packet.getEntityType(),
|
||||
new KLocation(x, y, z, packet.getYaw(), packet.getPitch())));
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_LIVING_ENTITY) {
|
||||
@@ -474,7 +493,7 @@ public class PacketHandler {
|
||||
double y = packet.getPosition().getY();
|
||||
double z = packet.getPosition().getZ();
|
||||
|
||||
player.getEntityLocationHandler().getTrackedEntities().put(packet.getEntityId(),
|
||||
player.getWorldTracker().getCurrentWorld().get().getTrackedEntities().put(packet.getEntityId(),
|
||||
new TrackedEntity(packet.getEntityId(), packet.getEntityType(),
|
||||
new KLocation(x, y, z, packet.getYaw(), packet.getPitch())));
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_PLAYER) {
|
||||
@@ -487,7 +506,7 @@ public class PacketHandler {
|
||||
double z = packet.getPosition().getZ();
|
||||
|
||||
|
||||
player.getEntityLocationHandler().getTrackedEntities().put(packet.getEntityId(),
|
||||
player.getWorldTracker().getCurrentWorld().get().getTrackedEntities().put(packet.getEntityId(),
|
||||
new TrackedEntity(packet.getEntityId(), EntityTypes.PLAYER,
|
||||
new KLocation(x, y, z, packet.getYaw(),packet.getPitch())));
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.SPAWN_PAINTING) {
|
||||
@@ -499,14 +518,14 @@ public class PacketHandler {
|
||||
int y = packet.getPosition().getY();
|
||||
int z = packet.getPosition().getZ();
|
||||
|
||||
player.getEntityLocationHandler().getTrackedEntities().put(packet.getEntityId(),
|
||||
player.getWorldTracker().getCurrentWorld().get().getTrackedEntities().put(packet.getEntityId(),
|
||||
new TrackedEntity(packet.getEntityId(), EntityTypes.PAINTING, new KLocation(x, y, z)));
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_POSITION_SYNC) {
|
||||
WrapperPlayServerEntityPositionSync packet = new WrapperPlayServerEntityPositionSync(event);
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getEntityLocationHandler().onPositionSync(packet);
|
||||
player.getEntityTrackHandler().onPositionSync(packet);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.ENTITY_METADATA) {
|
||||
wrapped = new WrapperPlayServerEntityMetadata(event);
|
||||
}else if(event.getPacketType() == PacketType.Play.Server.DESTROY_ENTITIES) {
|
||||
@@ -514,7 +533,7 @@ public class PacketHandler {
|
||||
|
||||
wrapped = packet;
|
||||
|
||||
player.getEntityLocationHandler().onEntityDestroy(packet);
|
||||
player.getEntityTrackHandler().onEntityDestroy(packet);
|
||||
} else if(event.getPacketType() == PacketType.Play.Server.CLOSE_WINDOW) {
|
||||
wrapped = new WrapperPlayServerCloseWindow(event);
|
||||
player.runKeepaliveAction(ka -> player.getInfo().setInventoryOpen(false));
|
||||
|
||||
@@ -1,59 +1,118 @@
|
||||
package dev.brighten.ac.handler;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEffect;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.utils.KPotionEffect;
|
||||
import dev.brighten.ac.utils.KProperties;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public class PotionHandler {
|
||||
private final APlayer data;
|
||||
|
||||
public List<PotionEffect> potionEffects = new CopyOnWriteArrayList<>();
|
||||
private final List<KPotionEffect> potionEffects = new ArrayList<>();
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
public PotionHandler(APlayer data) {
|
||||
public PotionHandler(APlayer data) {
|
||||
this.data = data;
|
||||
|
||||
potionEffects.addAll(data.getBukkitPlayer().getActivePotionEffects());
|
||||
lock.writeLock().lock();
|
||||
|
||||
try {
|
||||
data.getBukkitPlayer().getActivePotionEffects().stream()
|
||||
.map(pe ->
|
||||
new KPotionEffect(
|
||||
SpigotConversionUtil.fromBukkitPotionEffectType(pe.getType()),
|
||||
KProperties.fromBukkit(pe)
|
||||
))
|
||||
.forEach(potionEffects::add);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void onFlying(WrapperPlayClientPlayerFlying packet) {
|
||||
for (PotionEffect effect : potionEffects) {
|
||||
if(data.getBukkitPlayer().hasPotionEffect(effect.getType())) continue;
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
for (KPotionEffect effect : potionEffects) {
|
||||
lock.readLock().lock();
|
||||
|
||||
data.runKeepaliveAction(d -> data.getPotionHandler().potionEffects.remove(effect));
|
||||
try {
|
||||
if (data.getBukkitPlayer().hasPotionEffect(SpigotConversionUtil.toBukkitPotionEffectType(effect.potionType()))) continue;
|
||||
|
||||
data.runKeepaliveAction(d -> {
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
data.getPotionHandler().potionEffects.remove(effect);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void onPotionEffect(WrapperPlayServerEntityEffect packet) {
|
||||
data.runKeepaliveAction(d -> {
|
||||
var type = SpigotConversionUtil.toBukkitPotionEffectType(packet.getPotionType());
|
||||
data.getPotionHandler().potionEffects.stream().filter(pe -> pe.getType().equals(type))
|
||||
.forEach(data.getPotionHandler().potionEffects::remove);
|
||||
data.getPotionHandler().potionEffects
|
||||
.add(new PotionEffect(type, packet.getEffectDurationTicks(), packet.getEffectAmplifier(),
|
||||
packet.isAmbient()));
|
||||
var type = packet.getPotionType();
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
data.getPotionHandler().potionEffects.removeIf(pe -> pe.potionType().equals(type));
|
||||
data.getPotionHandler().potionEffects
|
||||
.add(new KPotionEffect(type, new KProperties(packet.getEffectAmplifier()
|
||||
, packet.getEffectDurationTicks(),
|
||||
packet.isAmbient(), packet.isVisible(), packet.isShowIcon(), null)));
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean hasPotionEffect(PotionEffectType type) {
|
||||
for (PotionEffect potionEffect : potionEffects) {
|
||||
if(potionEffect.getType().equals(type))
|
||||
return true;
|
||||
public boolean hasPotionEffect(PotionType type) {
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
for (KPotionEffect potionEffect : potionEffects) {
|
||||
if (potionEffect.potionType().equals(type))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Optional<PotionEffect> getEffectByType(PotionEffectType type) {
|
||||
for (PotionEffect potionEffect : potionEffects) {
|
||||
if(potionEffect.getType().equals(type))
|
||||
return Optional.of(potionEffect);
|
||||
public Optional<KPotionEffect> getEffectByType(PotionType type) {
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
for (KPotionEffect potionEffect : potionEffects) {
|
||||
if (potionEffect.potionType().equals(type))
|
||||
return Optional.of(potionEffect);
|
||||
}
|
||||
return Optional.empty();
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public List<KPotionEffect> getPotionEffects() {
|
||||
lock.readLock().lock();
|
||||
|
||||
try {
|
||||
return new ArrayList<>(potionEffects);
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package dev.brighten.ac.handler;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.hydro.emulator.util.mcp.MathHelper;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Getter
|
||||
public class ValuedAttribute {
|
||||
private final Attribute attribute;
|
||||
@Setter
|
||||
private WrapperPlayServerUpdateAttributes.Property property;
|
||||
private double value;
|
||||
|
||||
public ValuedAttribute(Attribute attribute) {
|
||||
this.attribute = attribute;
|
||||
this.value = attribute.getDefaultValue();
|
||||
}
|
||||
|
||||
public void updateAttribute(WrapperPlayServerUpdateAttributes.Property property) {
|
||||
this.property = property;
|
||||
|
||||
double multiplier = 1, additional = 0, base = 0;
|
||||
for (WrapperPlayServerUpdateAttributes.PropertyModifier modifier : property.getModifiers()) {
|
||||
switch (modifier.getOperation()) {
|
||||
case ADDITION -> additional += modifier.getAmount();
|
||||
case MULTIPLY_BASE -> base += modifier.getAmount();
|
||||
case MULTIPLY_TOTAL -> multiplier*= (1 + modifier.getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
this.value = MathHelper.clamp_double((property.getValue() + additional) * (1 - base) * multiplier,
|
||||
attribute.getMinValue(), attribute.getMaxValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ValuedAttribute that)) return false;
|
||||
return Objects.equals(attribute, that.attribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(attribute);
|
||||
}
|
||||
}
|
||||
@@ -1,63 +1,68 @@
|
||||
package dev.brighten.ac.handler.block;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.DiggingAction;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.BaseChunk;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.Column;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.TileEntity;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_16.Chunk_v1_9;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_7.Chunk_v1_7;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_8.Chunk_v1_8;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v_1_18.Chunk_v1_18;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.palette.PaletteType;
|
||||
import com.github.retrooper.packetevents.protocol.world.dimension.DimensionType;
|
||||
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.Vector3i;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerBlockPlacement;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBlockChange;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChunkData;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChunkDataBulk;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerMultiBlockChange;
|
||||
import dev.brighten.ac.Anticheat;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.*;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.utils.BlockUtils;
|
||||
import dev.brighten.ac.utils.LongHash;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.Materials;
|
||||
import dev.brighten.ac.utils.XMaterial;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.hydro.emulator.util.mcp.MathHelper;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@Slf4j
|
||||
@SuppressWarnings("unused")
|
||||
@RequiredArgsConstructor
|
||||
public class BlockUpdateHandler {
|
||||
private final Long2ObjectOpenHashMap<KColumn> chunks = new Long2ObjectOpenHashMap<>(1000);
|
||||
|
||||
|
||||
private final APlayer player;
|
||||
private final Map<String, World> worlds = new HashMap<>();
|
||||
@Getter
|
||||
private AtomicReference<World> currentWorld = new AtomicReference<>();
|
||||
|
||||
/**
|
||||
* Clear all chunks when the player changes worlds
|
||||
*/
|
||||
public void onWorldChange() {
|
||||
synchronized (chunks) {
|
||||
chunks.clear();
|
||||
}
|
||||
public void onRespawn(WrapperPlayServerRespawn respawn) {
|
||||
respawn.getWorldName()
|
||||
.filter(name -> !name.equals(currentWorld.get().getName()))
|
||||
.ifPresent(worldName -> {
|
||||
currentWorld.set(getWorldByName(worldName));
|
||||
player.getMob().despawn();
|
||||
|
||||
setMinHeight(player.getDimensionType());
|
||||
player.runKeepaliveAction(ka -> {
|
||||
KLocation origin = player.getMovement().getTo().getLoc().add(0, 1.7, 0);
|
||||
|
||||
RayCollision coll = new RayCollision(origin.toVector(), origin.getDirection().multiply(-1));
|
||||
|
||||
Vector3d loc1 = coll.collisionPoint(1.2);
|
||||
player.getMob().spawn(true, new KLocation(loc1), new ArrayList<>(), player);
|
||||
}, 1);
|
||||
});
|
||||
}
|
||||
|
||||
private World getWorldByName(String name) {
|
||||
return worlds.values().stream()
|
||||
.filter(world -> world.getName().equals(name))
|
||||
.findFirst()
|
||||
.orElse(worlds.put(name, new World(name)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,25 +73,30 @@ public class BlockUpdateHandler {
|
||||
public void onPlace(WrapperPlayClientPlayerBlockPlacement place) {
|
||||
player.getInfo().lastBlockUpdate.reset();
|
||||
// Could not possibly be a block placement as it's not a block a player is holding.
|
||||
IntVector pos = new IntVector(place.getBlockPosition());
|
||||
Vector3i pos = place.getBlockPosition();
|
||||
|
||||
// Some dumbass shit I have to do because Minecraft with Lilypads
|
||||
if (place.getItemStack().isPresent()
|
||||
&& BlockUtils.getXMaterial(place.getItemStack().get().getType()).equals(XMaterial.LILY_PAD)) {
|
||||
RayCollision rayCollision = new RayCollision(player.getBukkitPlayer().getEyeLocation().toVector(),
|
||||
player.getBukkitPlayer().getLocation().getDirection());
|
||||
&& place.getItemStack().get().getType().equals(ItemTypes.LILY_PAD)) {
|
||||
RayCollision rayCollision = new RayCollision(player.getMovement().getTo().getLoc()
|
||||
.add(0, player.getEyeHeight(), 0).toVector(),
|
||||
player.getMovement().getTo().getLoc().getDirection());
|
||||
//TODO Refactor this system to use just packetevents instead of this class
|
||||
WrappedBlock block = rayCollision.getClosestBlockOfType(player, Materials.LIQUID, 5);
|
||||
|
||||
if (block != null) {
|
||||
pos = new IntVector(block.getLocation().getX(), block.getLocation().getY() + 1, block.getLocation().getZ());
|
||||
pos = new Vector3i(
|
||||
block.getLocation().getX(),
|
||||
block.getLocation().getY() + 1,
|
||||
block.getLocation().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.getFace().getModX());
|
||||
pos.setY(pos.getY() + place.getFace().getModY());
|
||||
pos.setZ(pos.getZ() + place.getFace().getModZ());
|
||||
pos = pos.with(pos.getX() + place.getFace().getModX(),
|
||||
pos.getY() + place.getFace().getModY(),
|
||||
pos.getZ() + place.getFace().getModZ());
|
||||
}
|
||||
|
||||
player.getInfo().getLastPlace().reset();
|
||||
@@ -96,207 +106,16 @@ public class BlockUpdateHandler {
|
||||
int y = pos.getY();
|
||||
int z = pos.getZ();
|
||||
|
||||
var placedType = place.getItemStack().get().getType().getPlacedType();
|
||||
if(place.getItemStack().isEmpty() || placedType == null) {
|
||||
if(place.getItemStack().isEmpty() || place.getItemStack().get().getType().getPlacedType() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateBlock(x, y, z, WrappedBlockState.getDefaultState(placedType));
|
||||
currentWorld.get().updateBlock(x, y, z,
|
||||
WrappedBlockState.getDefaultState(place.getItemStack().get().getType().getPlacedType()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep track of block diggings since the Bukkit API will be a bit behind
|
||||
* @param x x coordinate
|
||||
* @param z z coordinate
|
||||
* @return the chunk at the specified coordinates
|
||||
*/
|
||||
public KColumn getChunk(int x, int z) {
|
||||
synchronized (chunks) {
|
||||
long hash = LongHash.toLong(x >> 4, z >> 4);
|
||||
KColumn chunk = chunks.get(hash);
|
||||
|
||||
// If the chunk is null, create a new one
|
||||
if(chunk == null) {
|
||||
chunk = getBukkitColumn(player.getBukkitPlayer().getWorld(), x, z);
|
||||
|
||||
if(chunk == null) {
|
||||
return new KColumn(x, z, new BaseChunk[maxHeight / 16]);
|
||||
}
|
||||
chunks.put(hash, chunk);
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
}
|
||||
|
||||
private KColumn getBukkitColumn(World world, int x, int z) {
|
||||
Chunk chunk = BlockUtils.getChunkAsync(world, x >> 4, z >> 4).orElse(null);
|
||||
|
||||
if(chunk == null) {
|
||||
// Handle loading on main thread
|
||||
Anticheat.INSTANCE.getRunUtils().task(() -> {
|
||||
long hash = LongHash.toLong(x >> 4, z >> 4);
|
||||
|
||||
if(!chunks.containsKey(hash)) {
|
||||
chunks.put(hash, getBukkitColumn(world, x, z));
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
BaseChunk[] levels = new BaseChunk[world.getMaxHeight() / 16];
|
||||
|
||||
for(int i = 0; i < levels.length; i++) {
|
||||
levels[i] = create();
|
||||
}
|
||||
|
||||
int chunkX = chunk.getX() * 16;
|
||||
int chunkZ = chunk.getZ() * 16;
|
||||
|
||||
for(int blockX = chunkX; blockX < chunkX + 16 ; blockX++) {
|
||||
for(int blockZ = chunkZ; blockZ < chunkZ + 16 ; blockZ++) {
|
||||
for(int blockY = minHeight ; blockY < world.getMaxHeight() ; blockY++) {
|
||||
Block block = chunk.getBlock(blockX, blockY, blockZ);
|
||||
|
||||
if(block.getType() == null || block.getType().equals(Material.AIR)) {
|
||||
continue; // Air
|
||||
}
|
||||
|
||||
BaseChunk baseChunk = levels[blockY >> 4];
|
||||
|
||||
WrappedBlockState state = SpigotConversionUtil.fromBukkitMaterialData(block.getState().getData());
|
||||
|
||||
baseChunk.set(blockX & 15, blockY & 15, blockZ & 15, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new KColumn(x, z, levels);
|
||||
}
|
||||
|
||||
private void updateChunk(Column chunk) {
|
||||
synchronized (chunks) {
|
||||
KColumn column = new KColumn(chunk.getX(), chunk.getZ(), chunk.getChunks());
|
||||
chunks.put(LongHash.toLong(column.x(), column.z()), column);
|
||||
}
|
||||
}
|
||||
|
||||
private static BaseChunk create() {
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_18)) {
|
||||
return new Chunk_v1_18();
|
||||
} else if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
|
||||
return new Chunk_v1_9(0, PaletteType.BIOME.create().paletteType.create());
|
||||
} else if(PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_8)) {
|
||||
return new Chunk_v1_8(false);
|
||||
}
|
||||
return new Chunk_v1_7(false, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a block at the specified coordinates
|
||||
* @param location the location of the block
|
||||
* @return the block at the specified coordinates
|
||||
*/
|
||||
public WrappedBlock getBlock(Location location) {
|
||||
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
private int minHeight = 0, maxHeight = 256;
|
||||
|
||||
public void setMinHeight(DimensionType type) {
|
||||
minHeight = type.getMinY();
|
||||
maxHeight = minHeight + type.getHeight();
|
||||
}
|
||||
|
||||
private static final WrappedBlockState airBlockState = WrappedBlockState.getByGlobalId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), 0);
|
||||
|
||||
/**
|
||||
* Get a block at the specified coordinates
|
||||
* @param x x coordinate
|
||||
* @param y y coordinate
|
||||
* @param z z coordinate
|
||||
* @return the block at the specified coordinates
|
||||
*/
|
||||
public WrappedBlock getBlock(int x, int y, int z) {
|
||||
KColumn col = getChunk(x, z);
|
||||
|
||||
y -= minHeight;
|
||||
|
||||
final int worldY = y;
|
||||
|
||||
// Fast bounds check for absurd/invalid Y before chunk indexing
|
||||
if (y < 0 || y >= (maxHeight - minHeight)) {
|
||||
return new WrappedBlock(new IntVector(x, worldY, z),
|
||||
StateTypes.AIR,
|
||||
airBlockState);
|
||||
}
|
||||
|
||||
// Also ensure the section index is within the cached column bounds
|
||||
final int sectionIndex = y >> 4;
|
||||
if (sectionIndex >= col.chunks().length) {
|
||||
return new WrappedBlock(new IntVector(x, worldY, z),
|
||||
StateTypes.AIR,
|
||||
airBlockState);
|
||||
}
|
||||
|
||||
BaseChunk chunk = col.chunks()[sectionIndex];
|
||||
|
||||
if(chunk == null) {
|
||||
//Get Bukkit Block
|
||||
Block block = BlockUtils.getBlockAsync(new Location(player.getBukkitPlayer().getWorld(), x, y, z))
|
||||
.orElse(null);
|
||||
|
||||
if(block != null) {
|
||||
WrappedBlockState state = SpigotConversionUtil.fromBukkitMaterialData(block.getState().getData());
|
||||
|
||||
if (state.getType() == StateTypes.AIR) {
|
||||
return new WrappedBlock(new IntVector(x, y + minHeight, z),
|
||||
StateTypes.AIR,
|
||||
airBlockState);
|
||||
} else {
|
||||
chunk = create();
|
||||
col.chunks()[y >> 4] = chunk;
|
||||
chunk.set(x & 15, y & 15, z & 15, state);
|
||||
}
|
||||
} else return new WrappedBlock(new IntVector(x, y, z),
|
||||
StateTypes.AIR,
|
||||
airBlockState);
|
||||
}
|
||||
|
||||
WrappedBlockState state = chunk.get(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(),x & 15, y & 15, z & 15);
|
||||
|
||||
return new WrappedBlock(new IntVector(x, y, z),
|
||||
state.getType(),
|
||||
state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a block at the specified coordinates
|
||||
* @param vec the coordinates
|
||||
* @return the block at the specified coordinates
|
||||
*/
|
||||
public WrappedBlock getBlock(IntVector vec) {
|
||||
return getBlock(vec.getX(), vec.getY(), vec.getZ());
|
||||
}
|
||||
|
||||
public WrappedBlock getBlock(Vector3d vec) {
|
||||
return getBlock(
|
||||
MathHelper.floor_double(vec.getX()),
|
||||
MathHelper.floor_double(vec.getY()),
|
||||
MathHelper.floor_double(vec.getZ())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a block at the specified coordinates
|
||||
* @param block Grabs coordinates from @link{org.bukkit.block.Block}
|
||||
* @return the block at the specified coordinates
|
||||
*/
|
||||
public WrappedBlock getBlock(Block block) {
|
||||
return getBlock(block.getX(), block.getY(), block.getZ());
|
||||
}
|
||||
static final WrappedBlockState airBlockState = WrappedBlockState
|
||||
.getByGlobalId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), 0);
|
||||
|
||||
/**
|
||||
* Keep track of block breaking since the Bukkit API will be a bit behind.
|
||||
@@ -307,13 +126,13 @@ public class BlockUpdateHandler {
|
||||
player.getInfo().lastBlockUpdate.reset();
|
||||
if (dig.getAction() == DiggingAction.FINISHED_DIGGING) {
|
||||
|
||||
IntVector pos = new IntVector(dig.getBlockPosition());
|
||||
Vector3i pos = dig.getBlockPosition();
|
||||
|
||||
if (pos.getX() == -1 && (pos.getY() == 255 || pos.getY() == -1) && pos.getZ() == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateBlock(pos.getX(), pos.getY(), pos.getZ(), airBlockState);
|
||||
currentWorld.get().updateBlock(pos.getX(), pos.getY(), pos.getZ(), airBlockState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,9 +145,9 @@ public class BlockUpdateHandler {
|
||||
|
||||
// Updating block information
|
||||
player.runKeepaliveAction(k -> {
|
||||
IntVector pos = new IntVector(packet.getBlockPosition());
|
||||
Vector3i pos = packet.getBlockPosition();
|
||||
|
||||
updateBlock(pos.getX(), pos.getY(), pos.getZ(), packet.getBlockState());
|
||||
currentWorld.get().updateBlock(pos.getX(), pos.getY(), pos.getZ(), packet.getBlockState());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -341,41 +160,20 @@ public class BlockUpdateHandler {
|
||||
player.runKeepaliveAction(k -> {
|
||||
for (WrapperPlayServerMultiBlockChange.EncodedBlock info : packet.getBlocks()) {
|
||||
|
||||
WrappedBlockState blockState = info.getBlockState(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
||||
WrappedBlockState blockState = info
|
||||
.getBlockState(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
||||
|
||||
updateBlock(info.getX(), info.getY(), info.getZ(), blockState);
|
||||
currentWorld.get().updateBlock(info.getX(), info.getY(), info.getZ(), blockState);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateBlock(int x, int y, int z, WrappedBlockState blockState) {
|
||||
KColumn col = getChunk(x, z);
|
||||
|
||||
int offset = y - minHeight;
|
||||
|
||||
if(offset < 0 || (offset >> 4) > col.chunks().length) {
|
||||
return;
|
||||
}
|
||||
|
||||
BaseChunk chunk = col.chunks()[offset >> 4];
|
||||
|
||||
if(chunk == null) {
|
||||
chunk = create();
|
||||
col.chunks()[offset >> 4] = chunk;
|
||||
|
||||
chunk.set(player.getPlayerVersion(), 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
chunk.set(x & 15, offset & 15, z & 15,
|
||||
blockState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep track of block updates since the Bukkit API will be a bit behind.
|
||||
* @param chunkUpdate Wrapped PacketPlayOutMapChunk
|
||||
*/
|
||||
public void runUpdate(WrapperPlayServerChunkData chunkUpdate) {
|
||||
player.runKeepaliveAction(k -> updateChunk(chunkUpdate.getColumn()));
|
||||
player.runKeepaliveAction(k -> currentWorld.get().updateChunk(chunkUpdate.getColumn()));
|
||||
}
|
||||
|
||||
public void runUpdate(WrapperPlayServerChunkDataBulk chunkBulk) {
|
||||
@@ -386,9 +184,10 @@ public class BlockUpdateHandler {
|
||||
int x = chunkBulk.getX()[index];
|
||||
int z = chunkBulk.getZ()[index];
|
||||
|
||||
Column column = new Column(x, z, true, chunks, new TileEntity[0], chunkBulk.getBiomeData()[index]);
|
||||
Column column = new Column(x, z, true, chunks, new TileEntity[0],
|
||||
chunkBulk.getBiomeData()[index]);
|
||||
|
||||
updateChunk(column);
|
||||
currentWorld.get().updateChunk(column);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -401,8 +200,8 @@ public class BlockUpdateHandler {
|
||||
* @param modZ the z modifier
|
||||
* @return the block relative to the specified location
|
||||
*/
|
||||
public WrappedBlock getRelative(IntVector location, int modX, int modY, int modZ) {
|
||||
return getBlock(location.clone().add(modX, modY, modZ));
|
||||
public WrappedBlock getRelative(Vector3i location, int modX, int modY, int modZ) {
|
||||
return currentWorld.get().getBlock(location.add(modX, modY, modZ));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -412,7 +211,7 @@ public class BlockUpdateHandler {
|
||||
* @param distance the distance
|
||||
* @return the block relative to the specified location
|
||||
*/
|
||||
public WrappedBlock getRelative(IntVector location, BlockFace face, int distance) {
|
||||
public WrappedBlock getRelative(Vector3i location, BlockFace face, int distance) {
|
||||
return getRelative(location,
|
||||
face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance);
|
||||
}
|
||||
@@ -423,8 +222,20 @@ public class BlockUpdateHandler {
|
||||
* @param face the face
|
||||
* @return the block relative to the specified location
|
||||
*/
|
||||
public WrappedBlock getRelative(IntVector location, BlockFace face) {
|
||||
return getBlock(location.clone().add(face.getModX(), face.getModY(), face.getModZ()));
|
||||
public WrappedBlock getRelative(Vector3i location, BlockFace face) {
|
||||
return currentWorld.get().getBlock(location.add(face.getModX(), face.getModY(), face.getModZ()));
|
||||
}
|
||||
|
||||
public WrappedBlock getBlock(int x, int y, int z) {
|
||||
return currentWorld.get().getBlock(x, y, z);
|
||||
}
|
||||
|
||||
public WrappedBlock getBlock(KLocation location) {
|
||||
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
public WrappedBlock getBlock(Vector3i location) {
|
||||
return getBlock(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
public record KColumn(int x, int z, BaseChunk[] chunks) {}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package dev.brighten.ac.handler.block;
|
||||
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@@ -17,7 +19,7 @@ public class Chunk {
|
||||
* @param location - Location of the block
|
||||
* @return Optional of the block at the specified location
|
||||
*/
|
||||
public Optional<WrappedBlock> getBlockAt(IntVector location) {
|
||||
public Optional<WrappedBlock> getBlockAt(Vector3i location) {
|
||||
return getBlockAt(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
@@ -64,7 +66,18 @@ public class Chunk {
|
||||
* @param location - Location of the block
|
||||
* @param block - Block to update to
|
||||
*/
|
||||
public void updateBlock(IntVector location, WrappedBlock block) {
|
||||
public void updateBlock(Vector3i location, WrappedBlock block) {
|
||||
updateBlock(location.getX(), location.getY(), location.getZ(), block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Chunk chunk)) return false;
|
||||
return x == chunk.x && z == chunk.z && Objects.deepEquals(blocks, chunk.blocks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(x, z, Arrays.deepHashCode(blocks));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
package dev.brighten.ac.handler.block;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.BaseChunk;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.Column;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_16.Chunk_v1_9;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_7.Chunk_v1_7;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v1_8.Chunk_v1_8;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.impl.v_1_18.Chunk_v1_18;
|
||||
import com.github.retrooper.packetevents.protocol.world.chunk.palette.PaletteType;
|
||||
import com.github.retrooper.packetevents.protocol.world.dimension.DimensionType;
|
||||
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.Vector3i;
|
||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.LongHash;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import me.hydro.emulator.util.mcp.MathHelper;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Getter
|
||||
public class World {
|
||||
private final String name;
|
||||
private final Long2ObjectOpenHashMap<BlockUpdateHandler.KColumn> chunks = new Long2ObjectOpenHashMap<>(1000);
|
||||
private final Map<Integer, TrackedEntity> trackedEntities = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
public World(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private int minHeight = 0, maxHeight = 256;
|
||||
|
||||
public void setMinHeight(DimensionType type) {
|
||||
minHeight = type.getMinY();
|
||||
maxHeight = minHeight + type.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep track of block diggings since the Bukkit API will be a bit behind
|
||||
* @param x x coordinate
|
||||
* @param z z coordinate
|
||||
* @return the chunk at the specified coordinates
|
||||
*/
|
||||
public BlockUpdateHandler.KColumn getChunk(int x, int z) {
|
||||
synchronized (chunks) {
|
||||
long hash = LongHash.toLong(x >> 4, z >> 4);
|
||||
BlockUpdateHandler.KColumn chunk = chunks.get(hash);
|
||||
|
||||
// If the chunk is null, create a new one
|
||||
if(chunk == null) {
|
||||
return chunks.put(hash, new BlockUpdateHandler.KColumn(x, z, new BaseChunk[maxHeight / 16]));
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
}
|
||||
|
||||
void updateChunk(Column chunk) {
|
||||
synchronized (chunks) {
|
||||
BlockUpdateHandler.KColumn column = new BlockUpdateHandler.KColumn(chunk.getX(), chunk.getZ(), chunk.getChunks());
|
||||
chunks.put(LongHash.toLong(column.x(), column.z()), column);
|
||||
}
|
||||
}
|
||||
|
||||
private static BaseChunk create() {
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_18)) {
|
||||
return new Chunk_v1_18();
|
||||
} else if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
|
||||
return new Chunk_v1_9(0, PaletteType.BIOME.create().paletteType.create());
|
||||
} else if(PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_8)) {
|
||||
return new Chunk_v1_8(false);
|
||||
}
|
||||
return new Chunk_v1_7(false, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a block at the specified coordinates
|
||||
* @param location the location of the block
|
||||
* @return the block at the specified coordinates
|
||||
*/
|
||||
public WrappedBlock getBlock(KLocation location) {
|
||||
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a block at the specified coordinates
|
||||
* @param x x coordinate
|
||||
* @param y y coordinate
|
||||
* @param z z coordinate
|
||||
* @return the block at the specified coordinates
|
||||
*/
|
||||
public WrappedBlock getBlock(int x, int y, int z) {
|
||||
BlockUpdateHandler.KColumn col = getChunk(x, z);
|
||||
|
||||
y -= minHeight;
|
||||
|
||||
if(col == null) {
|
||||
return new WrappedBlock(new Vector3i(x, y, z),
|
||||
StateTypes.AIR,
|
||||
BlockUpdateHandler.airBlockState);
|
||||
}
|
||||
|
||||
BaseChunk chunk = col.chunks().length - 1 < (y >> 4) ? null : col.chunks()[Math.max(0, (y >> 4))];
|
||||
|
||||
if(chunk == null) {
|
||||
//Get Bukkit Block
|
||||
return new WrappedBlock(new Vector3i(x, y, z),
|
||||
StateTypes.AIR,
|
||||
BlockUpdateHandler.airBlockState);
|
||||
}
|
||||
|
||||
WrappedBlockState state = chunk.get(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(),x & 15, y & 15, z & 15);
|
||||
|
||||
return new WrappedBlock(new Vector3i(x, y, z),
|
||||
state.getType(),
|
||||
state);
|
||||
}
|
||||
|
||||
void updateBlock(int x, int y, int z, WrappedBlockState blockState) {
|
||||
BlockUpdateHandler.KColumn col = getChunk(x, z);
|
||||
|
||||
int offset = y - minHeight;
|
||||
|
||||
if(offset < 0 || (offset >> 4) > col.chunks().length) {
|
||||
return;
|
||||
}
|
||||
|
||||
BaseChunk chunk = col.chunks()[offset >> 4];
|
||||
|
||||
if(chunk == null) {
|
||||
chunk = create();
|
||||
col.chunks()[offset >> 4] = chunk;
|
||||
|
||||
chunk.set(null, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
chunk.set(x & 15, offset & 15, z & 15,
|
||||
blockState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a block at the specified coordinates
|
||||
* @param vec the coordinates
|
||||
* @return the block at the specified coordinates
|
||||
*/
|
||||
public WrappedBlock getBlock(Vector3i vec) {
|
||||
return getBlock(vec.getX(), vec.getY(), vec.getZ());
|
||||
}
|
||||
|
||||
public WrappedBlock getBlock(Vector3d vec) {
|
||||
return getBlock(
|
||||
MathHelper.floor_double(vec.getX()),
|
||||
MathHelper.floor_double(vec.getY()),
|
||||
MathHelper.floor_double(vec.getZ())
|
||||
);
|
||||
}
|
||||
|
||||
public Optional<TrackedEntity> getTrackedEntity(int entityId) {
|
||||
TrackedEntity trackedEntity = trackedEntities.get(entityId);
|
||||
|
||||
if(trackedEntity == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(trackedEntity);
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,14 @@ package dev.brighten.ac.handler.block;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class WrappedBlock {
|
||||
private IntVector location;
|
||||
private Vector3i location;
|
||||
private StateType type;
|
||||
private WrappedBlockState blockState;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
package dev.brighten.ac.handler.entity;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||
import dev.brighten.ac.data.obj.Pose;
|
||||
import dev.brighten.ac.handler.ValuedAttribute;
|
||||
import dev.brighten.ac.utils.EntityLocation;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@@ -17,6 +23,8 @@ public class TrackedEntity {
|
||||
private KLocation location;
|
||||
private EntityLocation oldEntityLocation, newEntityLocation;
|
||||
private List<FakeMob> fakeMobs = new ArrayList<>();
|
||||
private Set<ValuedAttribute> attributes = new HashSet<>();
|
||||
private Pose pose = Pose.STANDING;
|
||||
|
||||
public TrackedEntity(int entityId, EntityType entityType, KLocation location) {
|
||||
this.entityId = entityId;
|
||||
@@ -31,4 +39,30 @@ public class TrackedEntity {
|
||||
newEntityLocation.yaw = location.getYaw();
|
||||
newEntityLocation.pitch = location.getPitch();
|
||||
}
|
||||
|
||||
public KLocation getEyeLocation() {
|
||||
return new KLocation(location.getX(), location.getY() + pose.eyeHeight, location.getZ(),
|
||||
location.getYaw(), location.getPitch());
|
||||
}
|
||||
|
||||
public ValuedAttribute getAttribute(Attribute type) {
|
||||
for(ValuedAttribute attribute : attributes) {
|
||||
if(attribute.getAttribute().equals(type)) {
|
||||
return attribute;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void updateAttribute(WrapperPlayServerUpdateAttributes.Property property) {
|
||||
ValuedAttribute attribute = getAttribute(property.getAttribute());
|
||||
|
||||
if(attribute == null) {
|
||||
attribute = new ValuedAttribute(property.getAttribute());
|
||||
}
|
||||
|
||||
attribute.updateAttribute(property);
|
||||
|
||||
attributes.add(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class KeepaliveProcessor {
|
||||
double dh = Math.min(value.getMovement().getDeltaXZ(), 1),
|
||||
dy = Math.min(1, Math.abs(value.getMovement().getDeltaY()));
|
||||
|
||||
value.getInfo().nearbyEntities = value.getEntityLocationHandler().getTrackedEntities().values()
|
||||
value.getInfo().nearbyEntities = value.getWorldTracker().getCurrentWorld().get().getTrackedEntities().values()
|
||||
.stream()
|
||||
.filter(te ->
|
||||
te.getLocation().distance(value.getMovement().getTo().getLoc()) < (2 + (dh + dy) / 2))
|
||||
|
||||
@@ -1,25 +1,8 @@
|
||||
package dev.brighten.ac.handler.protocol;
|
||||
|
||||
import dev.brighten.ac.Anticheat;
|
||||
import dev.brighten.ac.handler.protocol.impl.NoAPI;
|
||||
import dev.brighten.ac.handler.protocol.impl.ProtocolSupport;
|
||||
import dev.brighten.ac.handler.protocol.impl.ViaVersionAPI;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
|
||||
public interface Protocol {
|
||||
int getPlayerVersion(Player player);
|
||||
|
||||
static Protocol getProtocol() {
|
||||
if(Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) {
|
||||
Anticheat.INSTANCE.alog("Using ViaVersion for ProtocolAPI");
|
||||
return new ViaVersionAPI();
|
||||
} else if(Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport")) {
|
||||
Anticheat.INSTANCE.alog("Using ProtocolSupport for ProtocolAPI");
|
||||
return new ProtocolSupport();
|
||||
} else {
|
||||
Anticheat.INSTANCE.alog("Using Vanilla API for ProtocolAPI");
|
||||
return new NoAPI();
|
||||
}
|
||||
}
|
||||
int getPlayerVersion(APlayer player);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package dev.brighten.ac.handler.protocol.impl;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.protocol.Protocol;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class NoAPI implements Protocol {
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(Player player) {
|
||||
return PacketEvents.getAPI().getPlayerManager().getClientVersion(player).getProtocolVersion();
|
||||
public int getPlayerVersion(APlayer player) {
|
||||
return PacketEvents.getAPI().getPlayerManager().getClientVersion(player.getBukkitPlayer()).getProtocolVersion();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package dev.brighten.ac.handler.protocol.impl;
|
||||
|
||||
import dev.brighten.ac.handler.protocol.Protocol;
|
||||
import org.bukkit.entity.Player;
|
||||
import protocolsupport.api.ProtocolSupportAPI;
|
||||
|
||||
public class ProtocolSupport implements Protocol {
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(Player player) {
|
||||
return ProtocolSupportAPI.getProtocolVersion(player).getId();
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,16 @@ package dev.brighten.ac.handler.protocol.impl;
|
||||
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import dev.brighten.ac.Anticheat;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.protocol.Protocol;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ViaVersionAPI implements Protocol {
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(Player player) {
|
||||
Anticheat.INSTANCE.alog("Getting player version for " + player.getName());
|
||||
var toReturn = Via.getAPI().getPlayerVersion(player.getUniqueId());
|
||||
Anticheat.INSTANCE.alog("Player version for " + player.getName() + " is " + toReturn);
|
||||
public int getPlayerVersion(APlayer player) {
|
||||
Anticheat.INSTANCE.alog("Getting player version for " + player.getBukkitPlayer().getName());
|
||||
var toReturn = Via.getAPI().getPlayerVersion(player.getBukkitPlayer().getUniqueId());
|
||||
Anticheat.INSTANCE.alog("Player version for " + player.getBukkitPlayer().getName() + " is " + toReturn);
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.brighten.ac.listener;
|
||||
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import dev.brighten.ac.Anticheat;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
@@ -68,14 +69,15 @@ public class GeneralListener implements Listener {
|
||||
|
||||
Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId())
|
||||
.ifPresent(player -> {
|
||||
player.getBlockUpdateHandler().onWorldChange();
|
||||
|
||||
// Updating bot loc when changing worlds
|
||||
Location origin = event.getTo().clone().add(0, 1.7, 0);
|
||||
Vector mult = origin.getDirection().multiply(-1);
|
||||
|
||||
RayCollision coll = new RayCollision(origin.toVector(), origin.getDirection().multiply(-1));
|
||||
RayCollision coll = new RayCollision(new Vector3d(origin.getX(), origin.getY(), origin.getZ()),
|
||||
new Vector3d(mult.getX(), mult.getY(), mult.getZ()));
|
||||
|
||||
Vector loc1 = coll.collisionPoint(1.2);
|
||||
Vector3d loc1 = coll.collisionPoint(1.2);
|
||||
|
||||
Anticheat.INSTANCE.getRunUtils().taskLater(() -> {
|
||||
player.getMob().despawn();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.brighten.ac.utils;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.world.Direction;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import dev.brighten.ac.utils.world.types.RayCollision;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
import org.bukkit.Location;
|
||||
@@ -211,6 +212,14 @@ public class AxisAlignedBB {
|
||||
return rayTrace(origin, dir);
|
||||
}
|
||||
|
||||
public Vec3D rayTrace(Vector3d vorigin, Vector3d vdirection, double distance) {
|
||||
Vec3D origin = new Vec3D(vorigin.getX(), vorigin.getY(), vorigin.getZ());
|
||||
Vector3d direction = vdirection.multiply(distance);
|
||||
Vec3D dir = origin.clone().add(direction.getX(), direction.getY(), direction.getZ());
|
||||
|
||||
return rayTrace(origin, dir);
|
||||
}
|
||||
|
||||
public Vec3D rayTrace(Vec3D vec3d, Vec3D vec3d1) {
|
||||
Vec3D vec3d2 = vec3d.a(vec3d1, this.minX);
|
||||
Vec3D vec3d3 = vec3d.a(vec3d1, this.maxX);
|
||||
|
||||
@@ -2,19 +2,18 @@ package dev.brighten.ac.utils;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
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.Vector3i;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
@@ -84,20 +83,20 @@ public class BlockUtils {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public static Optional<WrappedBlock> getRelative(APlayer player, IntVector location, int modX, int modY, int modZ) {
|
||||
return Optional.of(player.getBlockUpdateHandler()
|
||||
.getRelative(new IntVector(location.getX(), location.getY(), location.getZ()),
|
||||
public static Optional<WrappedBlock> getRelative(APlayer player, Vector3i location, int modX, int modY, int modZ) {
|
||||
return Optional.of(player.getWorldTracker()
|
||||
.getRelative(new Vector3i(location.getX(), location.getY(), location.getZ()),
|
||||
modX, modY, modZ));
|
||||
}
|
||||
|
||||
public static Optional<WrappedBlock> getRelative(APlayer player, IntVector location,
|
||||
public static Optional<WrappedBlock> getRelative(APlayer player, Vector3i location,
|
||||
com.github.retrooper.packetevents.protocol.world
|
||||
.BlockFace face, int distance) {
|
||||
return getRelative(player, location,
|
||||
face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance);
|
||||
}
|
||||
|
||||
public static Optional<WrappedBlock> getRelative(APlayer player, IntVector vector, BlockFace face) {
|
||||
public static Optional<WrappedBlock> getRelative(APlayer player, Vector3i vector, BlockFace face) {
|
||||
return getRelative(player, vector,
|
||||
face.getModX(), face.getModY(), face.getModZ());
|
||||
}
|
||||
@@ -134,6 +133,12 @@ public class BlockUtils {
|
||||
return isUsable(getXMaterial(material));
|
||||
}
|
||||
|
||||
public static boolean isUsable(ClientVersion version, ItemType type) {
|
||||
return type.hasAttribute(ItemTypes.ItemAttribute.EDIBLE)
|
||||
|| (version.isOlderThan(ClientVersion.V_1_9) && type.hasAttribute(ItemTypes.ItemAttribute.SWORD))
|
||||
|| type.equals(ItemTypes.SHIELD);
|
||||
}
|
||||
|
||||
public static boolean isUsable(XMaterial xmaterial) {
|
||||
if(XEDIBLE.contains(xmaterial)) return true;
|
||||
return switch (xmaterial) {
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package dev.brighten.ac.utils;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.particle.Particle;
|
||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
|
||||
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.Vector3f;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerParticle;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import dev.brighten.ac.utils.world.BlockData;
|
||||
import dev.brighten.ac.utils.world.CollisionBox;
|
||||
import dev.brighten.ac.utils.world.EntityData;
|
||||
@@ -137,8 +136,8 @@ public class Helper {
|
||||
for (int x = x1; x < x2; ++x)
|
||||
for (int y = y1 - 1; y < y2; ++y)
|
||||
for (int z = z1; z < z2; ++z) {
|
||||
IntVector vec = new IntVector(x, y, z);
|
||||
StateType type = player.getBlockUpdateHandler().getBlock(vec).getType();
|
||||
Vector3i vec = new Vector3i(x, y, z);
|
||||
StateType type = player.getWorldTracker().getBlock(vec).getType();
|
||||
|
||||
if (type != StateTypes.AIR && (mask == -100 || Materials.checkFlag(type, mask))) {
|
||||
CollisionBox box = BlockData.getData(type)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package dev.brighten.ac.utils;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionType;
|
||||
|
||||
public record KPotionEffect(PotionType potionType, KProperties properties) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.brighten.ac.utils;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionEffect;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public record KProperties(int amplifier, int duration, boolean ambient, boolean showParticles, boolean showIcon,
|
||||
@Nullable KProperties hiddenEffect) {
|
||||
|
||||
public PotionEffect.Properties toProperties() {
|
||||
return new PotionEffect.Properties(amplifier, duration, ambient, showParticles, showIcon,
|
||||
hiddenEffect == null ? null : hiddenEffect.toProperties());
|
||||
}
|
||||
|
||||
public static KProperties fromBukkit(org.bukkit.potion.PotionEffect potionEffect) {
|
||||
return new KProperties(potionEffect.getAmplifier(), potionEffect.getDuration(), potionEffect.isAmbient(),
|
||||
potionEffect.hasParticles(), false, null);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import org.bukkit.Material;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
//TODO Refactor this system to use just packetevents instead of this class
|
||||
public class Materials {
|
||||
private static final Map<StateType, Integer> MATERIAL_FLAGS = new HashMap<>();
|
||||
|
||||
@@ -31,11 +32,11 @@ public class Materials {
|
||||
int flag = MATERIAL_FLAGS.getOrDefault(mat, 0);
|
||||
|
||||
//We use the one in BlockUtils also since we can't trust Material to include everything.
|
||||
if (mat.isSolid() || mat.getName().contains("COMPARATOR") || mat.getName().contains("DIODE")) {
|
||||
if (mat.isSolid() || mat.getName().contains("COMPARATOR") || mat.getName().contains("DIODE") || mat.isBlocking()) {
|
||||
flag |= SOLID;
|
||||
}
|
||||
|
||||
if(!(BlockData.getData(mat).getDefaultBox() instanceof NoCollisionBox)) {
|
||||
if(!(BlockData.getData(mat).getDefaultBox() instanceof NoCollisionBox) || mat.isBlocking()) {
|
||||
flag |= COLLIDABLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ public class MiscUtils {
|
||||
for(int x = startX ; x < endX ; x++) {
|
||||
for(int y = startY ; y < endY ; y++) {
|
||||
for(int z = startZ ; z < endZ ; z++) {
|
||||
StateType type = player.getBlockUpdateHandler().getBlock(x, y, z).getType();
|
||||
StateType type = player.getWorldTracker().getBlock(x, y, z).getType();
|
||||
|
||||
if(Materials.checkFlag(type, bitmask))
|
||||
return true;
|
||||
|
||||
@@ -19,7 +19,7 @@ public class MovementUtils {
|
||||
public static double getJumpHeight(APlayer data) {
|
||||
float baseHeight = 0.42f;
|
||||
|
||||
baseHeight+= data.getInfo().groundJumpBoost.map(ef -> ef.getAmplifier() + 1)
|
||||
baseHeight+= data.getInfo().groundJumpBoost.map(ef -> ef.properties().amplifier() + 1)
|
||||
.orElse(0) * 0.1f;
|
||||
|
||||
return baseHeight;
|
||||
@@ -38,7 +38,7 @@ public class MovementUtils {
|
||||
int i = MathHelper.floor_double(data.getMovement().getTo().getLoc().getX());
|
||||
int j = MathHelper.floor_double(data.getMovement().getTo().getBox().minY);
|
||||
int k = MathHelper.floor_double(data.getMovement().getTo().getLoc().getZ());
|
||||
WrappedBlock block = data.getBlockUpdateHandler().getBlock(i, j, k);
|
||||
WrappedBlock block = data.getWorldTracker().getBlock(i, j, k);
|
||||
|
||||
return Materials.checkFlag(block.getType(), Materials.LADDER);
|
||||
|
||||
|
||||
@@ -54,6 +54,10 @@ public class IntVector implements Cloneable {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
public Vector3i toVector3i() {
|
||||
return new Vector3i(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + x + ", " + y + ", " + z + "]";
|
||||
|
||||
@@ -2,11 +2,14 @@ package dev.brighten.ac.utils.math;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.MathUtils;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -15,15 +18,15 @@ public class RayTrace {
|
||||
|
||||
//origin = start position
|
||||
//direction = direction in which the raytrace will go
|
||||
Vector origin, direction;
|
||||
Vector3d origin, direction;
|
||||
|
||||
public RayTrace(Vector origin, Vector direction) {
|
||||
public RayTrace(Vector3d origin, Vector3d direction) {
|
||||
this.origin = origin;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
//general intersection detection
|
||||
public static boolean intersects(Vector position, Vector min, Vector max) {
|
||||
public static boolean intersects(Vector3d position, Vector3d min, Vector3d max) {
|
||||
if (position.getX() < min.getX() || position.getX() > max.getX()) {
|
||||
return false;
|
||||
} else if (position.getY() < min.getY() || position.getY() > max.getY()) {
|
||||
@@ -32,27 +35,27 @@ public class RayTrace {
|
||||
}
|
||||
|
||||
//get a point on the raytrace at X blocks away
|
||||
public Vector getPostion(double blocksAway) {
|
||||
return origin.clone().add(direction.clone().multiply(blocksAway));
|
||||
public Vector3d getPostion(double blocksAway) {
|
||||
return origin.add(direction.multiply(blocksAway));
|
||||
}
|
||||
|
||||
//checks if a position is on contained within the position
|
||||
public boolean isOnLine(Vector position) {
|
||||
public boolean isOnLine(Vector3d position) {
|
||||
double t = (position.getX() - origin.getX()) / direction.getX();
|
||||
return position.getBlockY() == origin.getY() + (t * direction.getY()) && position.getBlockZ() == origin.getZ() + (t * direction.getZ());
|
||||
return MathUtils.floor(position.getY()) == origin.getY() + (t * direction.getY()) && MathUtils.floor(position.getZ()) == origin.getZ() + (t * direction.getZ());
|
||||
}
|
||||
|
||||
//get all postions on a raytrace
|
||||
public List<Vector> traverse(double blocksAway, double accuracy) {
|
||||
List<Vector> positions = new ArrayList<>();
|
||||
public List<Vector3d> traverse(double blocksAway, double accuracy) {
|
||||
List<Vector3d> positions = new ArrayList<>();
|
||||
for (double d = 0; d <= blocksAway; d += accuracy) {
|
||||
positions.add(getPostion(d));
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
public List<Vector> traverse(double skip, double blocksAway, double accuracy) {
|
||||
List<Vector> positions = new ArrayList<>();
|
||||
public List<Vector3d> traverse(double skip, double blocksAway, double accuracy) {
|
||||
List<Vector3d> positions = new ArrayList<>();
|
||||
for (double d = skip; d <= blocksAway; d += accuracy) {
|
||||
positions.add(getPostion(d));
|
||||
}
|
||||
@@ -62,14 +65,17 @@ public class RayTrace {
|
||||
public List<Block> getBlocks(World world, double blocksAway, double accuracy) {
|
||||
List<Block> blocks = new ArrayList<>();
|
||||
|
||||
traverse(blocksAway, accuracy).stream().filter(vector -> vector.toLocation(world).getBlock().getType().isSolid()).forEach(vector -> blocks.add(vector.toLocation(world).getBlock()));
|
||||
traverse(blocksAway, accuracy).stream()
|
||||
.map(KLocation::new)
|
||||
.filter(vector -> vector.toLocation(world).getBlock().getType().isSolid())
|
||||
.forEach(vector -> blocks.add(vector.toLocation(world).getBlock()));
|
||||
return blocks;
|
||||
}
|
||||
|
||||
//intersection detection for current raytrace with return
|
||||
public Vector positionOfIntersection(Vector min, Vector max, double blocksAway, double accuracy) {
|
||||
List<Vector> positions = traverse(blocksAway, accuracy);
|
||||
for (Vector position : positions) {
|
||||
public Vector3d positionOfIntersection(Vector3d min, Vector3d max, double blocksAway, double accuracy) {
|
||||
List<Vector3d> positions = traverse(blocksAway, accuracy);
|
||||
for (Vector3d position : positions) {
|
||||
if (intersects(position, min, max)) {
|
||||
return position;
|
||||
}
|
||||
@@ -78,9 +84,9 @@ public class RayTrace {
|
||||
}
|
||||
|
||||
//intersection detection for current raytrace
|
||||
public boolean intersects(Vector min, Vector max, double blocksAway, double accuracy) {
|
||||
List<Vector> positions = traverse(blocksAway, accuracy);
|
||||
for (Vector position : positions) {
|
||||
public boolean intersects(Vector3d min, Vector3d max, double blocksAway, double accuracy) {
|
||||
List<Vector3d> positions = traverse(blocksAway, accuracy);
|
||||
for (Vector3d position : positions) {
|
||||
if (intersects(position, min, max)) {
|
||||
return true;
|
||||
}
|
||||
@@ -89,9 +95,9 @@ public class RayTrace {
|
||||
}
|
||||
|
||||
//bounding blockbox instead of vector
|
||||
public Vector positionOfIntersection(SimpleCollisionBox collisionBox, double blocksAway, double accuracy) {
|
||||
List<Vector> positions = traverse(blocksAway, accuracy);
|
||||
for (Vector position : positions) {
|
||||
public Vector3d positionOfIntersection(SimpleCollisionBox collisionBox, double blocksAway, double accuracy) {
|
||||
List<Vector3d> positions = traverse(blocksAway, accuracy);
|
||||
for (Vector3d position : positions) {
|
||||
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
||||
return position;
|
||||
}
|
||||
@@ -99,9 +105,9 @@ public class RayTrace {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Vector positionOfIntersection(SimpleCollisionBox collisionBox, double skip, double blocksAway, double accuracy) {
|
||||
List<Vector> positions = traverse(skip, blocksAway, accuracy);
|
||||
for (Vector position : positions) {
|
||||
public Vector3d positionOfIntersection(SimpleCollisionBox collisionBox, double skip, double blocksAway, double accuracy) {
|
||||
List<Vector3d> positions = traverse(skip, blocksAway, accuracy);
|
||||
for (Vector3d position : positions) {
|
||||
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
||||
return position;
|
||||
}
|
||||
@@ -111,8 +117,8 @@ public class RayTrace {
|
||||
|
||||
//bounding blockbox instead of vector
|
||||
public boolean intersects(SimpleCollisionBox collisionBox, double blocksAway, double accuracy) {
|
||||
List<Vector> positions = traverse(blocksAway, accuracy);
|
||||
for (Vector position : positions) {
|
||||
List<Vector3d> positions = traverse(blocksAway, accuracy);
|
||||
for (Vector3d position : positions) {
|
||||
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
||||
return true;
|
||||
}
|
||||
@@ -121,8 +127,8 @@ public class RayTrace {
|
||||
}
|
||||
|
||||
public boolean intersects(SimpleCollisionBox collisionBox, double skip, double blocksAway, double accuracy) {
|
||||
List<Vector> positions = traverse(blocksAway, accuracy);
|
||||
for (Vector position : positions) {
|
||||
List<Vector3d> positions = traverse(blocksAway, accuracy);
|
||||
for (Vector3d position : positions) {
|
||||
if (intersects(position, collisionBox.min(), collisionBox.max())) {
|
||||
return true;
|
||||
}
|
||||
@@ -132,8 +138,8 @@ public class RayTrace {
|
||||
|
||||
//debug / effects
|
||||
public void highlight(World world, double blocksAway, double accuracy) {
|
||||
for (Vector position : traverse(blocksAway, accuracy)) {
|
||||
world.playEffect(position.toLocation(world), (PacketEvents.getAPI().getServerManager().getVersion()
|
||||
for (Vector3d position : traverse(blocksAway, accuracy)) {
|
||||
world.playEffect(new Location(world, position.x, position.y, position.z), (PacketEvents.getAPI().getServerManager().getVersion()
|
||||
.isNewerThanOrEquals(ServerVersion.V_1_13) ? Effect.SMOKE : Effect.valueOf("COLOURED_DUST")), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ import com.github.retrooper.packetevents.protocol.world.states.defaulttags.Block
|
||||
import com.github.retrooper.packetevents.protocol.world.states.enums.*;
|
||||
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.Vector3i;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||
import dev.brighten.ac.utils.BlockUtils;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import dev.brighten.ac.utils.world.blocks.*;
|
||||
import dev.brighten.ac.utils.world.types.*;
|
||||
|
||||
@@ -110,12 +110,58 @@ public enum BlockData {
|
||||
|
||||
_DOOR(new DoorHandler(), BlockTags.DOORS.getStates().toArray(new StateType[0])),
|
||||
|
||||
_HOPPER(new HopperBounding(), StateTypes.HOPPER),
|
||||
_HOPPER((version, player, block) -> {
|
||||
if(version.isOlderThan(ClientVersion.V_1_13)) {
|
||||
double thickness = 0.125;
|
||||
return new ComplexCollisionBox(
|
||||
new SimpleCollisionBox(0,0,0,1, 0.125*5,1),
|
||||
new SimpleCollisionBox(0, 0.125*5, 0, thickness, 1, 1),
|
||||
new SimpleCollisionBox(1-thickness, 0.125*5, 0, 1, 1, 1),
|
||||
new SimpleCollisionBox(0, 0.125*5, 0, 1, 1, thickness),
|
||||
new SimpleCollisionBox(0, 0.125*5, 1-thickness, 1, 1, 1)
|
||||
);
|
||||
} else {
|
||||
ComplexCollisionBox hopperBox = new ComplexCollisionBox();
|
||||
|
||||
switch (block.getBlockState().getFacing()) {
|
||||
case DOWN:
|
||||
hopperBox.add(new HexCollisionBox(6.0D, 0.0D, 6.0D, 10.0D, 4.0D, 10.0D));
|
||||
break;
|
||||
case EAST:
|
||||
hopperBox.add(new HexCollisionBox(12.0D, 4.0D, 6.0D, 16.0D, 8.0D, 10.0D));
|
||||
break;
|
||||
case NORTH:
|
||||
hopperBox.add(new HexCollisionBox(6.0D, 4.0D, 0.0D, 10.0D, 8.0D, 4.0D));
|
||||
break;
|
||||
case SOUTH:
|
||||
hopperBox.add(new HexCollisionBox(6.0D, 4.0D, 12.0D, 10.0D, 8.0D, 16.0D));
|
||||
break;
|
||||
case WEST:
|
||||
hopperBox.add(new HexCollisionBox(0.0D, 4.0D, 6.0D, 4.0D, 8.0D, 10.0D));
|
||||
break;
|
||||
}
|
||||
|
||||
hopperBox.add(new SimpleCollisionBox(0, 0.625, 0, 1.0, 0.6875, 1.0));
|
||||
hopperBox.add(new SimpleCollisionBox(0, 0.6875, 0, 0.125, 1, 1));
|
||||
hopperBox.add(new SimpleCollisionBox(0.125, 0.6875, 0, 1, 1, 0.125));
|
||||
hopperBox.add(new SimpleCollisionBox(0.125, 0.6875, 0.875, 1, 1, 1));
|
||||
hopperBox.add(new SimpleCollisionBox(0.25, 0.25, 0.25, 0.75, 0.625, 0.75));
|
||||
hopperBox.add(new SimpleCollisionBox(0.875, 0.6875, 0.125, 1, 1, 0.875));
|
||||
|
||||
return hopperBox;
|
||||
}
|
||||
}, StateTypes.HOPPER),
|
||||
_CAKE((protocol, player, block) -> {
|
||||
double f1 = (1 + block.getBlockState().getBites() * 2) / 16D;
|
||||
|
||||
return new SimpleCollisionBox(f1, 0, 0.0625, 1 - 0.0625, 0.5, 1 - 0.0625);
|
||||
}, StateTypes.CAKE),
|
||||
STONE_CUTTER((version, player, block) -> {
|
||||
if (version.isOlderThanOrEquals(ClientVersion.V_1_13_2))
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1);
|
||||
|
||||
return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D);
|
||||
}, StateTypes.STONECUTTER),
|
||||
_COCOA_BEAN((protocol, player, block) -> {
|
||||
int age = block.getBlockState().getAge();
|
||||
if (protocol.isNewerThanOrEquals(ClientVersion.V_1_9_1) && protocol.isOlderThan(ClientVersion.V_1_11))
|
||||
@@ -282,7 +328,34 @@ public enum BlockData {
|
||||
StateTypes.STRUCTURE_VOID),
|
||||
|
||||
_END_ROD(new DynamicRod(), StateTypes.END_ROD),
|
||||
_CAULDRON(new CouldronBounding(), StateTypes.CAULDRON),
|
||||
_CAULDRON((version, player, block) -> {
|
||||
if(version.isOlderThanOrEquals(ClientVersion.V_1_13_2)) {
|
||||
double thickness = 0.125;
|
||||
|
||||
return new ComplexCollisionBox(new SimpleCollisionBox(0,0,0,1, 0.3125,1),
|
||||
new SimpleCollisionBox(0, 0.3125, 0, thickness, 1, 1),
|
||||
new SimpleCollisionBox(1-thickness, 0.3125, 0, 1, 1, 1),
|
||||
new SimpleCollisionBox(0, 0.3125, 0, 1, 1, thickness),
|
||||
new SimpleCollisionBox(0, 0.3125, 1-thickness, 1, 1, 1));
|
||||
} else {
|
||||
return new ComplexCollisionBox(new SimpleCollisionBox(0.0, 0.0, 0.0, 0.125, 1.0, 0.25),
|
||||
new SimpleCollisionBox(0.0, 0.0, 0.75, 0.125, 1.0, 1.0),
|
||||
new SimpleCollisionBox(0.125, 0.0, 0.0, 0.25, 1.0, 0.125),
|
||||
new SimpleCollisionBox(0.125, 0.0, 0.875, 0.25, 1.0, 1.0),
|
||||
new SimpleCollisionBox(0.75, 0.0, 0.0, 1.0, 1.0, 0.125),
|
||||
new SimpleCollisionBox(0.75, 0.0, 0.875, 1.0, 1.0, 1.0),
|
||||
new SimpleCollisionBox(0.875, 0.0, 0.125, 1.0, 1.0, 0.25),
|
||||
new SimpleCollisionBox(0.875, 0.0, 0.75, 1.0, 1.0, 0.875),
|
||||
new SimpleCollisionBox(0.0, 0.1875, 0.25, 1.0, 0.25, 0.75),
|
||||
new SimpleCollisionBox(0.125, 0.1875, 0.125, 0.875, 0.25, 0.25),
|
||||
new SimpleCollisionBox(0.125, 0.1875, 0.75, 0.875, 0.25, 0.875),
|
||||
new SimpleCollisionBox(0.25, 0.1875, 0.0, 0.75, 1.0, 0.125),
|
||||
new SimpleCollisionBox(0.25, 0.1875, 0.875, 0.75, 1.0, 1.0),
|
||||
new SimpleCollisionBox(0.0, 0.25, 0.25, 0.125, 1.0, 0.75),
|
||||
new SimpleCollisionBox(0.875, 0.25, 0.25, 1.0, 1.0, 0.75)
|
||||
);
|
||||
}
|
||||
}, StateTypes.CAULDRON),
|
||||
_CACTUS(new SimpleCollisionBox(0.0625, 0, 0.0625,
|
||||
1 - 0.0625, 1 - 0.0625, 1 - 0.0625), StateTypes.CACTUS),
|
||||
_PISTON_BASE(new PistonBaseCollision(), StateTypes.PISTON, StateTypes.STICKY_PISTON),
|
||||
@@ -304,6 +377,67 @@ public enum BlockData {
|
||||
}, StateTypes.LECTERN),
|
||||
_POT(new SimpleCollisionBox(0.3125, 0.0, 0.3125, 0.6875, 0.375, 0.6875),
|
||||
StateTypes.FLOWER_POT),
|
||||
KELP(new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D), StateTypes.KELP),
|
||||
// Kelp block is a full block, so it by default is correct
|
||||
|
||||
BELL((version, player, block) -> {
|
||||
if (version.isOlderThanOrEquals(ClientVersion.V_1_13_2))
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1);
|
||||
|
||||
BlockFace direction = block.getBlockState().getFacing();
|
||||
|
||||
if (block.getBlockState().getAttachment() == Attachment.FLOOR) {
|
||||
return direction != BlockFace.NORTH && direction != BlockFace.SOUTH ?
|
||||
new HexCollisionBox(4.0D, 0.0D, 0.0D, 12.0D, 16.0D, 16.0D) :
|
||||
new HexCollisionBox(0.0D, 0.0D, 4.0D, 16.0D, 16.0D, 12.0D);
|
||||
|
||||
}
|
||||
|
||||
ComplexCollisionBox complex = new ComplexCollisionBox(
|
||||
new HexCollisionBox(5.0D, 6.0D, 5.0D, 11.0D, 13.0D, 11.0D),
|
||||
new HexCollisionBox(4.0D, 4.0D, 4.0D, 12.0D, 6.0D, 12.0D));
|
||||
|
||||
if (block.getBlockState().getAttachment() == Attachment.CEILING) {
|
||||
complex.add(new HexCollisionBox(7.0D, 13.0D, 7.0D, 9.0D, 16.0D, 9.0D));
|
||||
} else if (block.getBlockState().getAttachment() == Attachment.DOUBLE_WALL) {
|
||||
if (direction != BlockFace.NORTH && direction != BlockFace.SOUTH) {
|
||||
complex.add(new HexCollisionBox(0.0D, 13.0D, 7.0D, 16.0D, 15.0D, 9.0D));
|
||||
} else {
|
||||
complex.add(new HexCollisionBox(7.0D, 13.0D, 0.0D, 9.0D, 15.0D, 16.0D));
|
||||
}
|
||||
} else if (direction == BlockFace.NORTH) {
|
||||
complex.add(new HexCollisionBox(7.0D, 13.0D, 0.0D, 9.0D, 15.0D, 13.0D));
|
||||
} else if (direction == BlockFace.SOUTH) {
|
||||
complex.add(new HexCollisionBox(7.0D, 13.0D, 3.0D, 9.0D, 15.0D, 16.0D));
|
||||
} else {
|
||||
if (direction == BlockFace.EAST) {
|
||||
complex.add(new HexCollisionBox(3.0D, 13.0D, 7.0D, 16.0D, 15.0D, 9.0D));
|
||||
} else {
|
||||
complex.add(new HexCollisionBox(0.0D, 13.0D, 7.0D, 13.0D, 15.0D, 9.0D));
|
||||
}
|
||||
}
|
||||
|
||||
return complex;
|
||||
|
||||
}, StateTypes.BELL),
|
||||
|
||||
SCAFFOLDING((version, player, block) -> {
|
||||
// ViaVersion replacement block - hay block
|
||||
if (version.isOlderThanOrEquals(ClientVersion.V_1_13_2))
|
||||
return new SimpleCollisionBox(0, 0, 0, 1, 1, 1);
|
||||
|
||||
if (player.getMovement().getFrom().getY() > player.getMovement().getTo().getY() + 1 - 1e-5 && !player.getInfo().sneaking) {
|
||||
return new ComplexCollisionBox(new HexCollisionBox(0.0D, 14.0D, 0.0D, 16.0D, 16.0D, 16.0D),
|
||||
new HexCollisionBox(0.0D, 0.0D, 0.0D, 2.0D, 16.0D, 2.0D),
|
||||
new HexCollisionBox(14.0D, 0.0D, 0.0D, 16.0D, 16.0D, 2.0D),
|
||||
new HexCollisionBox(0.0D, 0.0D, 14.0D, 2.0D, 16.0D, 16.0),
|
||||
new HexCollisionBox(14.0D, 0.0D, 14.0D, 16.0D, 16.0D, 16.0D));
|
||||
}
|
||||
|
||||
return block.getBlockState().getDistance() != 0 && block.getBlockState().isBottom() && player.getMovement().getFrom().getY() > player.getMovement().getTo().getY() - 1e-5 ?
|
||||
new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D) :
|
||||
NoCollisionBox.INSTANCE;
|
||||
}, StateTypes.SCAFFOLDING),
|
||||
|
||||
_NONE(NoCollisionBox.INSTANCE, Stream.of(StateTypes.TORCH, StateTypes.REDSTONE_TORCH,
|
||||
StateTypes.REDSTONE_WIRE, StateTypes.REDSTONE_WALL_TORCH, StateTypes.POWERED_RAIL, StateTypes.WALL_TORCH,
|
||||
@@ -361,10 +495,10 @@ public enum BlockData {
|
||||
return getBox(player, block.getLocation(), version);
|
||||
}
|
||||
|
||||
public CollisionBox getBox(APlayer player, IntVector block, ClientVersion version) {
|
||||
public CollisionBox getBox(APlayer player, Vector3i block, ClientVersion version) {
|
||||
if (this.box != null)
|
||||
return this.box.copy().offset(block.getX(), block.getY(), block.getZ());
|
||||
return new DynamicCollisionBox(dynamic, player, player.getBlockUpdateHandler().getBlock(block), version)
|
||||
return new DynamicCollisionBox(dynamic, player, player.getWorldTracker().getBlock(block), version)
|
||||
.offset(block.getX(), block.getY(), block.getZ());
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.brighten.ac.utils.world;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.world.types.NoCollisionBox;
|
||||
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
|
||||
import org.bukkit.Location;
|
||||
@@ -23,6 +24,10 @@ public class EntityData {
|
||||
return bounds(entity.getEntityType()).offset(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
public static CollisionBox getEntityBox(KLocation location, TrackedEntity entity) {
|
||||
return bounds(entity.getEntityType()).offset(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
public static CollisionBox getEntityBox(Location location, EntityType entity) {
|
||||
return bounds(entity).offset(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@ 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.enums.Half;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.enums.Hinge;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||
import dev.brighten.ac.utils.math.IntVector;
|
||||
import dev.brighten.ac.utils.world.CollisionBox;
|
||||
import dev.brighten.ac.utils.world.types.CollisionFactory;
|
||||
import dev.brighten.ac.utils.world.types.HexCollisionBox;
|
||||
@@ -50,10 +50,10 @@ public class DoorHandler implements CollisionFactory {
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThanOrEquals(ServerVersion.V_1_12_2)
|
||||
|| version.isOlderThanOrEquals(ClientVersion.V_1_12_2)) {
|
||||
if (door.getBlockState().getHalf() == Half.LOWER) {
|
||||
IntVector aboveVec = door.getLocation().clone();
|
||||
Vector3i aboveVec = door.getLocation();
|
||||
|
||||
aboveVec.setY(aboveVec.getY() + 1);
|
||||
WrappedBlockState above = player.getBlockUpdateHandler().getBlock(aboveVec).getBlockState();
|
||||
aboveVec = aboveVec.add(0, aboveVec.getY() + 1, 0);
|
||||
WrappedBlockState above = player.getWorldTracker().getBlock(aboveVec).getBlockState();
|
||||
|
||||
facingDirection = door.getBlockState().getFacing();
|
||||
isClosed = !door.getBlockState().isOpen();
|
||||
@@ -67,10 +67,10 @@ public class DoorHandler implements CollisionFactory {
|
||||
isRightHinge = false;
|
||||
}
|
||||
} else {
|
||||
IntVector belowVec = door.getLocation().clone();
|
||||
Vector3i belowVec = door.getLocation();
|
||||
|
||||
belowVec.setY(belowVec.getY() - 1);
|
||||
WrappedBlockState below = player.getBlockUpdateHandler().getBlock(belowVec).getBlockState();
|
||||
belowVec = belowVec.add(0, belowVec.getY() - 1, 0);
|
||||
WrappedBlockState below = player.getWorldTracker().getBlock(belowVec).getBlockState();
|
||||
|
||||
if (below.getType() == door.getBlockState().getType() && below.getHalf() == Half.LOWER) {
|
||||
isClosed = !below.isOpen();
|
||||
|
||||
@@ -44,7 +44,7 @@ public class DynamicStair implements CollisionFactory {
|
||||
z = originalStairs.getLocation().getZ();
|
||||
WrappedBlock offsetOne = player == null
|
||||
? null
|
||||
: player.getBlockUpdateHandler().getBlock(
|
||||
: player.getWorldTracker().getBlock(
|
||||
x + facing.getModX(),
|
||||
y + facing.getModY(),
|
||||
z + facing.getModZ());
|
||||
@@ -64,7 +64,7 @@ public class DynamicStair implements CollisionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
WrappedBlock offsetTwo = player.getBlockUpdateHandler()
|
||||
WrappedBlock offsetTwo = player.getWorldTracker()
|
||||
.getBlock(x + facing.getOppositeFace().getModX(),
|
||||
y + facing.getOppositeFace().getModY(), z
|
||||
+ facing.getOppositeFace().getModZ());
|
||||
|
||||
@@ -4,18 +4,18 @@ import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.handler.block.WrappedBlock;
|
||||
import dev.brighten.ac.handler.entity.TrackedEntity;
|
||||
import dev.brighten.ac.utils.Helper;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
import dev.brighten.ac.utils.Materials;
|
||||
import dev.brighten.ac.utils.Tuple;
|
||||
import dev.brighten.ac.utils.math.RayTrace;
|
||||
import dev.brighten.ac.utils.world.BlockData;
|
||||
import dev.brighten.ac.utils.world.CollisionBox;
|
||||
import me.hydro.emulator.util.mcp.MathHelper;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -58,15 +58,15 @@ public class RayCollision implements CollisionBox {
|
||||
directionZ = 0;
|
||||
}
|
||||
|
||||
public RayCollision(LivingEntity e) {
|
||||
public RayCollision(TrackedEntity e) {
|
||||
this(e.getEyeLocation());
|
||||
}
|
||||
|
||||
public RayCollision(Location l) {
|
||||
public RayCollision(KLocation l) {
|
||||
this(l.toVector(),l.getDirection());
|
||||
}
|
||||
|
||||
public RayCollision(Vector position, Vector direction) {
|
||||
public RayCollision(Vector3d position, Vector3d direction) {
|
||||
this.originX = position.getX();
|
||||
this.originY = position.getY();
|
||||
this.originZ = position.getZ();
|
||||
@@ -75,17 +75,17 @@ public class RayCollision implements CollisionBox {
|
||||
this.directionZ = direction.getZ();
|
||||
}
|
||||
|
||||
public Vector getOrigin() {
|
||||
return new Vector(originX, originY, originZ);
|
||||
public Vector3d getOrigin() {
|
||||
return new Vector3d(originX, originY, originZ);
|
||||
}
|
||||
|
||||
public Vector getDirection() {
|
||||
return new Vector(directionX, directionY, directionZ);
|
||||
public Vector3d getDirection() {
|
||||
return new Vector3d(directionX, directionY, directionZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollided(CollisionBox other) {
|
||||
if (other instanceof RayCollision) {
|
||||
if (other instanceof RayCollision) {
|
||||
return false; // lol no support
|
||||
} else {
|
||||
List<SimpleCollisionBox> boxes = new ArrayList<>();
|
||||
@@ -141,7 +141,7 @@ public class RayCollision implements CollisionBox {
|
||||
public List<CollisionBox> boxesOnRay(APlayer player, 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.
|
||||
KLocation[] locs = new KLocation[Math.max(2, amount)]; //We do a max to prevent NegativeArraySizeException.
|
||||
List<CollisionBox> boxes = new ArrayList<>();
|
||||
ClientVersion version = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion();
|
||||
|
||||
@@ -152,7 +152,7 @@ public class RayCollision implements CollisionBox {
|
||||
int fy = MathHelper.floor_double(originY + (directionY * ix));
|
||||
int fz = MathHelper.floor_double(originZ + (directionZ * ix));
|
||||
|
||||
WrappedBlock block = player.getBlockUpdateHandler().getBlock(fx, fy, fz);
|
||||
WrappedBlock block = player.getWorldTracker().getBlock(fx, fy, fz);
|
||||
|
||||
if (block == null) continue;
|
||||
|
||||
@@ -173,7 +173,7 @@ public class RayCollision implements CollisionBox {
|
||||
public WrappedBlock getClosestBlockOfType(APlayer player, int bitmask, double distance) {
|
||||
int amount = Math.round((float) (distance / 0.5));
|
||||
|
||||
Location[] locs = new Location[Math.max(2, amount)]; //We do a max
|
||||
KLocation[] locs = new KLocation[Math.max(2, amount)]; //We do a max
|
||||
ClientVersion version = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion();
|
||||
|
||||
for (int i = 0; i < locs.length; i++) {
|
||||
@@ -183,7 +183,7 @@ public class RayCollision implements CollisionBox {
|
||||
int fy = MathHelper.floor_double(originY + (directionY * ix));
|
||||
int fz = MathHelper.floor_double(originZ + (directionZ * ix));
|
||||
|
||||
WrappedBlock block = player.getBlockUpdateHandler().getBlock(fx, fy, fz);
|
||||
WrappedBlock block = player.getWorldTracker().getBlock(fx, fy, fz);
|
||||
|
||||
if(block == null || !Materials.checkFlag(block.getType(), bitmask)) continue;
|
||||
|
||||
@@ -228,7 +228,7 @@ public class RayCollision implements CollisionBox {
|
||||
|
||||
RayTrace trace = new RayTrace(ray.getOrigin(), ray.getDirection());
|
||||
|
||||
Vector point = trace.positionOfIntersection(box, Math.max(0, dist - range), 0.01);
|
||||
Vector3d point = trace.positionOfIntersection(box, Math.max(0, dist - range), 0.01);
|
||||
|
||||
return ray.getOrigin().distance(point);
|
||||
}
|
||||
@@ -347,23 +347,23 @@ public class RayCollision implements CollisionBox {
|
||||
}
|
||||
}
|
||||
|
||||
public Vector collisionPoint(SimpleCollisionBox box) {
|
||||
public Vector3d collisionPoint(SimpleCollisionBox box) {
|
||||
Tuple<Double, Double> p = new Tuple<>();
|
||||
if (box==null||!intersect(this,box,p))
|
||||
return null;
|
||||
Vector vector = new Vector(directionX,directionY,directionZ);
|
||||
Vector3d vector = new Vector3d(directionX,directionY,directionZ);
|
||||
vector.normalize();
|
||||
vector.multiply(p.one);
|
||||
vector.add(new Vector(originX,originY,originZ));
|
||||
vector.add(new Vector3d(originX,originY,originZ));
|
||||
return vector;
|
||||
}
|
||||
|
||||
public Vector collisionPoint(double dist) {
|
||||
Vector vector = new Vector(directionX,directionY,directionZ);
|
||||
public Vector3d collisionPoint(double dist) {
|
||||
Vector3d vector = new Vector3d(directionX,directionY,directionZ);
|
||||
vector.normalize();
|
||||
vector.multiply(dist);
|
||||
vector.add(new Vector(originX,originY,originZ));
|
||||
vector.add(new Vector3d(originX,originY,originZ));
|
||||
return vector;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package dev.brighten.ac.utils.world.types;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import dev.brighten.ac.data.APlayer;
|
||||
import dev.brighten.ac.utils.Helper;
|
||||
import dev.brighten.ac.utils.KLocation;
|
||||
@@ -54,7 +55,7 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
maxZ = width / 2;
|
||||
}
|
||||
|
||||
public SimpleCollisionBox(Vector min, Vector max) {
|
||||
public SimpleCollisionBox(Vector3d min, Vector3d max) {
|
||||
this(min.getX(), min.getY(), min.getZ(), max.getX(), max.getY(), max.getZ());
|
||||
}
|
||||
|
||||
@@ -76,6 +77,13 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
maxY += height;
|
||||
}
|
||||
|
||||
public SimpleCollisionBox(Vector3d vec, double width, double height) {
|
||||
this(vec.getX(), vec.getY(), vec.getZ(), vec.getX(), vec.getY(), vec.getZ());
|
||||
|
||||
expand(width / 2, 0, width / 2);
|
||||
maxY += height;
|
||||
}
|
||||
|
||||
public void sort() {
|
||||
double temp;
|
||||
if (minX >= maxX) {
|
||||
@@ -196,26 +204,26 @@ public class SimpleCollisionBox implements CollisionBox {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector[] corners() {
|
||||
public Vector3d[] corners() {
|
||||
sort();
|
||||
Vector[] vectors = new Vector[8];
|
||||
vectors[0] = new Vector(minX, minY, minZ);
|
||||
vectors[1] = new Vector(minX, minY, maxZ);
|
||||
vectors[2] = new Vector(maxX, minY, minZ);
|
||||
vectors[3] = new Vector(maxX, minY, maxZ);
|
||||
vectors[4] = new Vector(minX, maxY, minZ);
|
||||
vectors[5] = new Vector(minX, maxY, maxZ);
|
||||
vectors[6] = new Vector(maxX, maxY, minZ);
|
||||
vectors[7] = new Vector(maxX, maxY, maxZ);
|
||||
Vector3d[] vectors = new Vector3d[8];
|
||||
vectors[0] = new Vector3d(minX, minY, minZ);
|
||||
vectors[1] = new Vector3d(minX, minY, maxZ);
|
||||
vectors[2] = new Vector3d(maxX, minY, minZ);
|
||||
vectors[3] = new Vector3d(maxX, minY, maxZ);
|
||||
vectors[4] = new Vector3d(minX, maxY, minZ);
|
||||
vectors[5] = new Vector3d(minX, maxY, maxZ);
|
||||
vectors[6] = new Vector3d(maxX, maxY, minZ);
|
||||
vectors[7] = new Vector3d(maxX, maxY, maxZ);
|
||||
return vectors;
|
||||
}
|
||||
|
||||
public Vector min() {
|
||||
return new Vector(minX, minY, minZ);
|
||||
public Vector3d min() {
|
||||
return new Vector3d(minX, minY, minZ);
|
||||
}
|
||||
|
||||
public Vector max() {
|
||||
return new Vector(maxX, maxY, maxZ);
|
||||
public Vector3d max() {
|
||||
return new Vector3d(maxX, maxY, maxZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package dev.brighten.ac.utils;
|
||||
|
||||
import com.github.retrooper.packetevents.util.MathUtil;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import lombok.Data;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.joml.Vector2d;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -41,14 +41,18 @@ public class KLocation implements Cloneable {
|
||||
this.timeStamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public KLocation(Vector vector) {
|
||||
public KLocation(Location location) {
|
||||
this(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
}
|
||||
|
||||
public KLocation(Vector3d vector) {
|
||||
this.x = vector.getX();
|
||||
this.y = vector.getY();
|
||||
this.z = vector.getZ();
|
||||
this.timeStamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public KLocation(Location location) {
|
||||
public KLocation(KLocation location) {
|
||||
this.x = location.getX();
|
||||
this.y = location.getY();
|
||||
this.z = location.getZ();
|
||||
@@ -57,12 +61,12 @@ public class KLocation implements Cloneable {
|
||||
this.timeStamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public Vector toVector() {
|
||||
return new Vector(x, y, z);
|
||||
public Vector3d toVector() {
|
||||
return new Vector3d(x, y, z);
|
||||
}
|
||||
|
||||
public Vector3d toVector3d() {
|
||||
return new Vector3d(x, y, z);
|
||||
public Vector3i toVector3i() {
|
||||
return new Vector3i((int) x, (int) y, (int) z);
|
||||
}
|
||||
|
||||
public Location toLocation(World world) {
|
||||
@@ -112,8 +116,27 @@ public class KLocation implements Cloneable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector getDirection() {
|
||||
return MathUtils.getDirection(this);
|
||||
public Vector3d getDirection() {
|
||||
double rotX = this.getYaw();
|
||||
double rotY = this.getPitch();
|
||||
double x, y, z;
|
||||
y = -Math.sin(Math.toRadians(rotY));
|
||||
double xz = Math.cos(Math.toRadians(rotY));
|
||||
x = -xz * Math.sin(Math.toRadians(rotX));
|
||||
z = xz * Math.cos(Math.toRadians(rotX));
|
||||
return new Vector3d(x, y, z);
|
||||
}
|
||||
|
||||
public int getBlockX() {
|
||||
return MathUtil.floor(x);
|
||||
}
|
||||
|
||||
public int getBlockY() {
|
||||
return MathUtil.floor(y);
|
||||
}
|
||||
|
||||
public int getBlockZ() {
|
||||
return MathUtil.floor(z);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.brighten.ac.utils;
|
||||
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import lombok.val;
|
||||
import me.hydro.emulator.util.mcp.MathHelper;
|
||||
import org.bukkit.Location;
|
||||
@@ -196,10 +197,6 @@ public class MathUtils {
|
||||
return MathUtils.yawTo180D(playerRotation.getX() - expectedRotation.getX());
|
||||
}
|
||||
|
||||
public static double getAngle(KLocation loc1, KLocation loc2) {
|
||||
return getAngle(loc1.toLocation(null), loc2.toLocation(null));
|
||||
}
|
||||
|
||||
public static float distanceBetweenAngles(float a, float b) {
|
||||
final float first = a % 360;
|
||||
final float second = b % 360;
|
||||
@@ -544,16 +541,14 @@ public class MathUtils {
|
||||
return (short) num;
|
||||
}
|
||||
|
||||
/* Stolen from Bukkit */
|
||||
public static Vector getDirection(KLocation loc) {
|
||||
Vector vector = new Vector();
|
||||
public static Vector3d getDirection(KLocation loc) {
|
||||
Vector3d vector = new Vector3d();
|
||||
double rotX = loc.getYaw();
|
||||
double rotY = loc.getPitch();
|
||||
vector.setY(-Math.sin(Math.toRadians(rotY)));
|
||||
double xz = Math.cos(Math.toRadians(rotY));
|
||||
vector.setX(-xz * Math.sin(Math.toRadians(rotX)));
|
||||
vector.setZ(xz * Math.cos(Math.toRadians(rotX)));
|
||||
return vector;
|
||||
return new Vector3d(-xz * Math.sin(Math.toRadians(rotX)),
|
||||
-Math.sin(Math.toRadians(rotY)),
|
||||
xz * Math.cos(Math.toRadians(rotX)));
|
||||
}
|
||||
|
||||
|
||||
@@ -704,12 +699,12 @@ public class MathUtils {
|
||||
return squareRoot;
|
||||
}
|
||||
|
||||
public static Vector getDirection(float yaw, float pitch) {
|
||||
public static Vector3d getDirection(float yaw, float pitch) {
|
||||
float f = MathHelper.cos(MathHelper.FastMathType.VANILLA, -yaw * 0.017453292F - (float)Math.PI);
|
||||
float f1 = MathHelper.sin(MathHelper.FastMathType.VANILLA, -yaw * 0.017453292F - (float)Math.PI);
|
||||
float f2 = -MathHelper.cos(MathHelper.FastMathType.VANILLA, -pitch * 0.017453292F);
|
||||
float f3 = MathHelper.sin(MathHelper.FastMathType.VANILLA, -pitch * 0.017453292F);
|
||||
return new Vector(f1 * f2, f3, f * f2);
|
||||
return new Vector3d(f1 * f2, f3, f * f2);
|
||||
}
|
||||
|
||||
public static float sqrt(float number) {
|
||||
|
||||
+1
-1
Submodule Neo updated: b45b76d09d...feb79131a2
Reference in New Issue
Block a user