diff --git a/src/main/java/dev/brighten/ac/Anticheat.java b/src/main/java/dev/brighten/ac/Anticheat.java index 7bed4d6..ea80c01 100644 --- a/src/main/java/dev/brighten/ac/Anticheat.java +++ b/src/main/java/dev/brighten/ac/Anticheat.java @@ -10,6 +10,7 @@ import dev.brighten.ac.depends.LibraryLoader; import dev.brighten.ac.depends.MavenLibrary; import dev.brighten.ac.depends.Repository; 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.protocolsupport.ProtocolAPI; import dev.brighten.ac.logging.LoggerManager; @@ -60,6 +61,8 @@ public class Anticheat extends LoaderPlugin { private KeepaliveProcessor keepaliveProcessor; private PacketHandler packetHandler; private LoggerManager logManager; + + private FakeEntityTracker fakeTracker; private int currentTick; private Deque onTickEnd = new LinkedList<>(); private ServerInjector injector; @@ -133,6 +136,8 @@ public class Anticheat extends LoaderPlugin { e.printStackTrace(); } + fakeTracker = new FakeEntityTracker(); + Bukkit.getOnlinePlayers().forEach(HandlerAbstract.getHandler()::add); } public void onDisable() { @@ -140,7 +145,7 @@ public class Anticheat extends LoaderPlugin { commandManager.unregisterCommands(); // Unregistering packet listeners for players - HandlerAbstract.shutdown(); + HandlerAbstract.getHandler().shutdown(); HandlerList.unregisterAll(getPluginInstance()); packetProcessor.shutdown(); packetProcessor = null; @@ -153,6 +158,9 @@ public class Anticheat extends LoaderPlugin { ProtocolAPI.INSTANCE = null; tps = null; + fakeTracker.despawnAll(); + fakeTracker = null; + logManager.shutDown(); Bukkit.getScheduler().cancelTasks(getPluginInstance()); diff --git a/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java b/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java index 45415eb..af5e7e9 100644 --- a/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java +++ b/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java @@ -37,8 +37,10 @@ public class Hitbox extends Check { } WAction useEntity = packet -> { + Entity entity = packet.getEntity(player.getBukkitPlayer().getWorld()); + if(entity == null) return; if(packet.getAction() == WPacketPlayInUseEntity.EnumEntityUseAction.ATTACK - && allowedEntityTypes.contains(packet.getEntity(player.getBukkitPlayer().getWorld()).getType())) { + && allowedEntityTypes.contains(entity.getType())) { attacks.add(new Tuple<>(packet.getEntity(player.getBukkitPlayer().getWorld()), player.getMovement().getTo().getLoc().clone())); } }; diff --git a/src/main/java/dev/brighten/ac/check/impl/misc/HealthSpoof.java b/src/main/java/dev/brighten/ac/check/impl/misc/HealthSpoof.java new file mode 100644 index 0000000..cd6abcf --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/impl/misc/HealthSpoof.java @@ -0,0 +1,25 @@ +package dev.brighten.ac.check.impl.misc; + +import dev.brighten.ac.api.check.CheckType; +import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.check.WCancellable; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutEntityMetadata; + +@CheckData(name = "HealthSpoof", checkId = "healthspoof", type = CheckType.EXPLOIT) +public class HealthSpoof extends Check { + + public HealthSpoof(APlayer player) { + super(player); + } + + WCancellable event = packet -> { + if(packet.getEntityId() == player.getBukkitPlayer().getEntityId()) return false; + + packet.getWatchedObjects().forEach(obj -> { + debug("%s: %s", obj.getDataValueId(), obj.getDataWatcherObject()); + }); + return false; + }; +} diff --git a/src/main/java/dev/brighten/ac/check/impl/movement/fly/FlyC.java b/src/main/java/dev/brighten/ac/check/impl/movement/fly/FlyC.java index dabec55..be972e4 100644 --- a/src/main/java/dev/brighten/ac/check/impl/movement/fly/FlyC.java +++ b/src/main/java/dev/brighten/ac/check/impl/movement/fly/FlyC.java @@ -8,7 +8,6 @@ import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; import dev.brighten.ac.utils.MathUtils; import dev.brighten.ac.utils.MovementUtils; -import org.bukkit.potion.PotionEffect; import java.util.ArrayList; import java.util.Comparator; @@ -51,7 +50,8 @@ public class FlyC extends Check { // Adding all possible velocity deltaY. player.getVelocityHandler().getPossibleVectors().forEach(vec -> possibleHeights.add(vec.getY())); - if(player.getInfo().lastHalfBlock.isNotPassed(1)) { + if(player.getInfo().lastHalfBlock.isNotPassed(1) + || player.getInfo().lastFence.isNotPassed(1) || player.getBlockInfo().fenceNear) { possibleHeights.add(0.5); } @@ -61,6 +61,7 @@ public class FlyC extends Check { || player.getInfo().wasOnSlime || player.getBlockInfo().nearSteppableEntity || player.getInfo().lastFence.isNotPassed(1) + || player.getBlockInfo().fenceNear || player.getInfo().lastHalfBlock.isNotPassed(1) || player.getInfo().slimeTimer.isNotPassed(1) || player.getInfo().lastLiquid.isNotPassed(1)) break jumpCheck; diff --git a/src/main/java/dev/brighten/ac/check/impl/movement/fly/FlyD.java b/src/main/java/dev/brighten/ac/check/impl/movement/fly/FlyD.java index c1960a2..623fa9f 100644 --- a/src/main/java/dev/brighten/ac/check/impl/movement/fly/FlyD.java +++ b/src/main/java/dev/brighten/ac/check/impl/movement/fly/FlyD.java @@ -20,7 +20,7 @@ public class FlyD extends Check { WAction flyingPacket = packet -> { if(!packet.isMoved() || player.getMovement().getMoveTicks() <= 2 || player.getBlockInfo().miscNear || player.getBlockInfo().onSlab - || player.getBlockInfo().fenceBelow + || player.getBlockInfo().fenceBelow || player.getBlockInfo().fenceNear || player.getBlockInfo().onStairs || player.getInfo().isGeneralCancel()) return; double deltaY = player.getMovement().getDeltaY(); diff --git a/src/main/java/dev/brighten/ac/command/AnticheatCommand.java b/src/main/java/dev/brighten/ac/command/AnticheatCommand.java index 932cc6e..3ee15fc 100644 --- a/src/main/java/dev/brighten/ac/command/AnticheatCommand.java +++ b/src/main/java/dev/brighten/ac/command/AnticheatCommand.java @@ -8,6 +8,7 @@ import dev.brighten.ac.Anticheat; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.entity.FakeMob; import dev.brighten.ac.messages.Messages; import dev.brighten.ac.packet.handler.HandlerAbstract; import dev.brighten.ac.utils.Color; @@ -207,6 +208,49 @@ public class AnticheatCommand extends BaseCommand { } } + @Subcommand("spawnbot") + @CommandPermission("anticheat.command.spawnbot") + @Description("Spawn test bot") + public void onBot(Player player) { + FakeMob fakePlayer = new FakeMob(player.getLocation().getWorld()); + + fakePlayer.spawn(player.getLocation(), Anticheat.INSTANCE.getPlayerRegistry() + .getPlayer(player.getUniqueId()).orElseThrow(() -> new RuntimeException("shit"))); + + player.sendMessage(Color.Green + "Spawned entity with ID: " + fakePlayer.getEntityId()); + } + + @Subcommand("botinvis") + @Syntax("[id] [boolean]") + @CommandPermission("anticheat.command.botinvis") + @Description("Shit") + public void onInvis(CommandSender sender, int botId, boolean invis) { + FakeMob player = Anticheat.INSTANCE.getFakeTracker().getEntityById(botId); + + if(player == null) { + sender.sendMessage(Color.Red + "Bot with ID " + botId + " does not exist!"); + return; + } + + player.setInvisible(invis); + sender.sendMessage(Color.Green + (invis ? "Made invis" : "Removed invis") + " on bot " + botId); + } + + @Subcommand("despawnbot") + @CommandPermission("anticheat.command.despawnBot") + @Syntax("[botId]") + public void despawnBot(CommandSender sender, int botId) { + FakeMob player = Anticheat.INSTANCE.getFakeTracker().getEntityById(botId); + + if(player == null) { + sender.sendMessage(Color.Red + "Bot with ID " + botId + " does not exist!"); + return; + } + + player.despawn(); + sender.sendMessage(Color.Green + "Despawned bot!"); + } + @Subcommand("logs") @Syntax("[player] [check]") @CommandCompletion("@players @checkIds") diff --git a/src/main/java/dev/brighten/ac/data/APlayer.java b/src/main/java/dev/brighten/ac/data/APlayer.java index 043a561..b3ba4a6 100644 --- a/src/main/java/dev/brighten/ac/data/APlayer.java +++ b/src/main/java/dev/brighten/ac/data/APlayer.java @@ -22,10 +22,7 @@ import dev.brighten.ac.utils.KLocation; import dev.brighten.ac.utils.RunUtils; import dev.brighten.ac.utils.Tuple; import dev.brighten.ac.utils.objects.evicting.EvictingList; -import dev.brighten.ac.utils.reflections.Reflections; import dev.brighten.ac.utils.reflections.impl.MinecraftReflection; -import dev.brighten.ac.utils.reflections.types.WrappedClass; -import dev.brighten.ac.utils.reflections.types.WrappedMethod; import dev.brighten.ac.utils.timer.Timer; import dev.brighten.ac.utils.timer.impl.MillisTimer; import lombok.Getter; @@ -92,17 +89,10 @@ public class APlayer { private final List> onVelocityTasks = new ArrayList<>(); public final EvictingList> pastLocations = new EvictingList<>(20); - - @Setter @Getter private boolean sendingPackets; - static WrappedClass bukkitClass = Reflections.getClass("org.bukkit.Bukkit"); - static WrappedClass pluginManager = Reflections.getClass("org.bukkit.plugin.PluginManager"); - static WrappedMethod method = pluginManager.getMethod("isPluginEnabled", String.class), - method2 = pluginManager.getMethod("getPlugin", String.class), - gpmanager = bukkitClass.getMethod("getPluginManager"); public APlayer(Player player) { this.bukkitPlayer = player; this.uuid = player.getUniqueId(); @@ -204,6 +194,10 @@ public class APlayer { playerTick++; } + public void sendPacket(Object packet) { + HandlerAbstract.getHandler().sendPacket(this, packet); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/dev/brighten/ac/data/PlayerRegistry.java b/src/main/java/dev/brighten/ac/data/PlayerRegistry.java index b208af6..d472275 100644 --- a/src/main/java/dev/brighten/ac/data/PlayerRegistry.java +++ b/src/main/java/dev/brighten/ac/data/PlayerRegistry.java @@ -45,7 +45,6 @@ public class PlayerRegistry { long hash = getHashOfFile(file); if(!acceptableHashes.contains(hash)) { - System.out.println("Bad loader file!"); exit(0); } } diff --git a/src/main/java/dev/brighten/ac/data/info/BlockInformation.java b/src/main/java/dev/brighten/ac/data/info/BlockInformation.java index 8fedf3a..395b9ea 100644 --- a/src/main/java/dev/brighten/ac/data/info/BlockInformation.java +++ b/src/main/java/dev/brighten/ac/data/info/BlockInformation.java @@ -23,12 +23,11 @@ public class BlockInformation { private APlayer player; public boolean onClimbable, onSlab, onStairs, onHalfBlock, inLiquid, inLava, inWater, inWeb, onSlime, onIce, onSoulSand, blocksAbove, collidesVertically, bedNear, collidesHorizontally, blocksNear, inBlock, miscNear, - collidedWithEntity, roseBush, inPortal, blocksBelow, pistonNear, fenceBelow, inScaffolding, inHoney, + collidedWithEntity, roseBush, fenceNear, inPortal, blocksBelow, pistonNear, fenceBelow, inScaffolding, inHoney, nearSteppableEntity; public final List aboveCollisions = Collections.synchronizedList(new ArrayList<>()), belowCollisions = Collections.synchronizedList(new ArrayList<>()); public final List blocks = Collections.synchronizedList(new ArrayList<>()); - private static EnumMap matchMaterial = new EnumMap<>(Material.class); //Caching material private final Material cobweb = XMaterial.COBWEB.parseMaterial(), rosebush = XMaterial.ROSE_BUSH.parseMaterial(), @@ -36,20 +35,14 @@ public class BlockInformation { honey = XMaterial.HONEY_BLOCK.parseMaterial(); public final Map collisionMaterialCount = new HashMap<>(); - static { - for (Material mat : Material.values()) { - matchMaterial.put(mat, XMaterial.matchXMaterial(mat)); - } - } - - public static XMaterial getXMaterial(Material material) { - return matchMaterial.getOrDefault(material, null); - } - public BlockInformation(APlayer objectData) { this.player = objectData; } + private SimpleCollisionBox newBox(double width, double height) { + return new SimpleCollisionBox(player.getMovement().getTo().getLoc(), width, height); + } + public void runCollisionCheck() { if(!Anticheat.INSTANCE.isEnabled()) return; @@ -148,6 +141,7 @@ public class BlockInformation { player.getBlockUpdateHandler().getPossibleMaterials(new IntVector(x, y, z)); BlockUtils.getBlockAsync(new Location(world, x, y, z)).ifPresent(blocks::add); + for (Material type : types) { if (type != Material.AIR) { @@ -177,25 +171,26 @@ public class BlockInformation { } } - if(normalBox.copy().expand(0.1, 0, 0.1).offset(0, -1, 0) + if(normalBox.copy().expand(0.1, 0, 0.1) + .expandMax(0, -0.4, 0).expandMin(0, -0.55, 0) .isCollided(blockBox)) { synchronized (belowCollisions) { blockBox.downCast(belowCollisions); } + } + + if(Materials.checkFlag(type, Materials.SOLID)) { + SimpleCollisionBox groundBox = newBox(0.6, 0.1) + .expandMax(0, -0.5, 0); if(Materials.checkFlag(type, Materials.FENCE) || Materials.checkFlag(type, Materials.WALL)) { fenceBelow = true; } - } - if(Materials.checkFlag(type, Materials.SOLID)) { - SimpleCollisionBox groundBox = normalBox.copy() - .offset(0, -.49, 0).expandMax(0, -1.2, 0); + XMaterial blockMaterial = BlockUtils.getXMaterial(type); - XMaterial blockMaterial = getXMaterial(type); - - if(normalBox.copy().expand(0.4, 0, 0.4).expandMin(0, -1, 0) + if(newBox(1.4, 0).expandMin(0, -1, 0) .isIntersected(blockBox)) blocksBelow = true; @@ -270,8 +265,10 @@ public class BlockInformation { else if(Materials.checkFlag(type, Materials.STAIRS)) onStairs = true; - else - if(blockMaterial != null) + else if(Materials.checkFlag(type, Materials.FENCE) + || Materials.checkFlag(type, Materials.WALL)) { + fenceNear = true; + } else if(blockMaterial != null) switch(blockMaterial) { case CAKE: case BREWING_STAND: @@ -315,7 +312,7 @@ public class BlockInformation { } } } else if(blockBox.isCollided(normalBox)) { - XMaterial blockMaterial = getXMaterial(type); + XMaterial blockMaterial = BlockUtils.getXMaterial(type); if(blockMaterial != null) switch(blockMaterial) { @@ -336,8 +333,6 @@ public class BlockInformation { if(!player.getInfo().isWorldLoaded()) return; - //Bukkit.broadcastMessage("chigga4"); - for (Entity entity : player.getInfo().getNearbyEntities()) { boolean isBlockEntity = !(entity instanceof LivingEntity); diff --git a/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java b/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java index 1a89d33..b304709 100644 --- a/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java +++ b/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java @@ -12,6 +12,7 @@ import dev.brighten.ac.utils.XMaterial; import dev.brighten.ac.utils.math.IntVector; import dev.brighten.ac.utils.world.types.RayCollision; import dev.brighten.ac.utils.wrapper.Wrapper; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.RequiredArgsConstructor; import lombok.val; import org.bukkit.Material; @@ -21,7 +22,7 @@ import java.util.*; @RequiredArgsConstructor public class BlockUpdateHandler { - private final Map> blockInformation = new HashMap<>(); + private final Map> blockInformation = new Object2ObjectOpenHashMap<>(); private final APlayer player; @@ -39,7 +40,7 @@ public class BlockUpdateHandler { IntVector pos = place.getBlockPos().clone(); // Some dumbass shit I have to do because Minecraft with Lilypads - if(place.getItemStack() != null && XMaterial.matchXMaterial(place.getItemStack().getType()).equals(XMaterial.LILY_PAD)) { + if(place.getItemStack() != null && BlockUtils.getXMaterial(place.getItemStack().getType()).equals(XMaterial.LILY_PAD)) { RayCollision rayCollision = new RayCollision(player.getBukkitPlayer().getEyeLocation().toVector(), player.getBukkitPlayer().getLocation().getDirection()); Block block = rayCollision.getClosestBlockOfType(player.getBukkitPlayer().getWorld(), Materials.LIQUID, 5); diff --git a/src/main/java/dev/brighten/ac/handler/entity/FakeEntityTracker.java b/src/main/java/dev/brighten/ac/handler/entity/FakeEntityTracker.java new file mode 100644 index 0000000..480cbaa --- /dev/null +++ b/src/main/java/dev/brighten/ac/handler/entity/FakeEntityTracker.java @@ -0,0 +1,28 @@ +package dev.brighten.ac.handler.entity; + +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import lombok.Getter; + +public class FakeEntityTracker { + @Getter + private final Int2ObjectMap entityMap = Int2ObjectMaps.synchronize(new Int2ObjectOpenHashMap<>()); + + public FakeMob getEntityById(int id) { + return entityMap.get(id); + } + + public void trackEntity(FakeMob player) { + entityMap.put(player.getEntityId(), player); + } + + public void untrackEntity(FakeMob player) { + entityMap.remove(player.getEntityId()); + } + + public void despawnAll() { + entityMap.forEach((id, entity) -> entity.despawn()); + entityMap.clear(); + } +} diff --git a/src/main/java/dev/brighten/ac/handler/entity/FakeMob.java b/src/main/java/dev/brighten/ac/handler/entity/FakeMob.java new file mode 100644 index 0000000..ee8d05e --- /dev/null +++ b/src/main/java/dev/brighten/ac/handler/entity/FakeMob.java @@ -0,0 +1,128 @@ +package dev.brighten.ac.handler.entity; + +import dev.brighten.ac.Anticheat; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutEntity; +import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutEntityEffect; +import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutEntityTeleport; +import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutRemoveEntityEffect; +import lombok.Getter; +import net.minecraft.server.v1_8_R3.EntityZombie; +import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy; +import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.entity.EntityType; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + +@Getter +public class FakeMob { + private int entityId; + private EntityType type; + private EntityZombie zombie; + + private List watching = Collections.emptyList(); + + public FakeMob(World world) { + entityId = ThreadLocalRandom.current().nextInt(15000, 20000); + + zombie = new EntityZombie(((CraftWorld)world).getHandle()); + entityId = zombie.getId(); + } + + public void spawn(Location location, APlayer... players) { + if(watching.size() > 0) { + despawn(); + } + + zombie = new EntityZombie(((CraftWorld)location.getWorld()).getHandle()); + zombie.setInvisible(true); + zombie.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + zombie.setHealth(20f); + + entityId = zombie.getId(); + watching = new ArrayList<>(); + for (APlayer player : players) { + PacketPlayOutSpawnEntityLiving living = new PacketPlayOutSpawnEntityLiving(zombie); + player.sendPacket(living); + watching.add(player); + } + + Anticheat.INSTANCE.getFakeTracker().trackEntity(this); + } + + public void setInvisible(boolean invisible) { + if(invisible) { + WPacketPlayOutEntityEffect packet = WPacketPlayOutEntityEffect.builder().entityId(entityId) + .effectId(PotionEffectType.INVISIBILITY.getId() & 255).amplifier((byte)0).duration(32767).flags((byte)0x02).build(); + + for (APlayer player : watching) { + player.sendPacket(packet); + } + zombie.setInvisible(true); + } else { + WPacketPlayOutRemoveEntityEffect packet = WPacketPlayOutRemoveEntityEffect.builder() + .effectId(PotionEffectType.INVISIBILITY.getId() & 255).entityId(entityId).build(); + + for (APlayer player : watching) { + player.sendPacket(packet); + } + zombie.setInvisible(false); + } + } + + public void despawn() { + for (APlayer aPlayer : watching) { + PacketPlayOutEntityDestroy destroyEntity = new PacketPlayOutEntityDestroy(entityId); + + aPlayer.sendPacket(destroyEntity); + } + watching = Collections.emptyList(); + zombie = null; + + Anticheat.INSTANCE.getFakeTracker().untrackEntity(this); + } + + public void move(double dx, double dy, double dz) { + WPacketPlayOutEntity packet = WPacketPlayOutEntity.builder().x(dx).y(dy).z(dz).moved(true).build(); + + for (APlayer player : watching) { + player.sendPacket(packet); + } + } + + public void move(double dx, double dy, double dz, float dyaw, float dpitch) { + WPacketPlayOutEntity packet = WPacketPlayOutEntity.builder().x(dx).y(dy).z(dz).yaw(dyaw) + .pitch(dpitch).moved(true).looked(true).build(); + + for (APlayer player : watching) { + player.sendPacket(packet); + } + } + + public void move(float dyaw, float dpitch) { + WPacketPlayOutEntity packet = WPacketPlayOutEntity.builder().yaw(dyaw).pitch(dpitch) + .looked(true).build(); + + for (APlayer player : watching) { + player.sendPacket(packet); + } + } + + public void teleport(double x, double y, double z, float yaw, float pitch) { + WPacketPlayOutEntityTeleport packet = WPacketPlayOutEntityTeleport.builder() + .entityId(entityId) + .x(x).y(y).z(z).yaw(yaw).pitch(pitch).onGround(false) + .build(); + + for (APlayer player : watching) { + player.sendPacket(packet); + } + } +} diff --git a/src/main/java/dev/brighten/ac/handler/entity/hit/HitEntityTracker.java b/src/main/java/dev/brighten/ac/handler/entity/hit/HitEntityTracker.java new file mode 100644 index 0000000..dd8dfc0 --- /dev/null +++ b/src/main/java/dev/brighten/ac/handler/entity/hit/HitEntityTracker.java @@ -0,0 +1,4 @@ +package dev.brighten.ac.handler.entity.hit; + +public class HitEntityTracker { +} diff --git a/src/main/java/dev/brighten/ac/listener/JoinListener.java b/src/main/java/dev/brighten/ac/listener/JoinListener.java index ff8956b..28f0df8 100644 --- a/src/main/java/dev/brighten/ac/listener/JoinListener.java +++ b/src/main/java/dev/brighten/ac/listener/JoinListener.java @@ -3,9 +3,8 @@ package dev.brighten.ac.listener; import dev.brighten.ac.Anticheat; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.handler.HandlerAbstract; -import dev.brighten.ac.packet.wrapper.PacketType; -import dev.brighten.ac.utils.annotation.Init; import dev.brighten.ac.utils.RunUtils; +import dev.brighten.ac.utils.annotation.Init; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -43,7 +42,7 @@ public class JoinListener implements Listener { if(player.isSendingPackets()) return; - if(event.getType().equals(PacketType.CLIENT_TRANSACTION)) { + /*if(event.getType().equals(PacketType.CLIENT_TRANSACTION)) { if(player.getPacketQueue().size() > 0) { player.setSendingPackets(true); Object packetToSend = null; @@ -74,7 +73,7 @@ public class JoinListener implements Listener { break; } } - } + }*/ }); } diff --git a/src/main/java/dev/brighten/ac/packet/handler/HandlerAbstract.java b/src/main/java/dev/brighten/ac/packet/handler/HandlerAbstract.java index 5bf7df8..4ad65f7 100644 --- a/src/main/java/dev/brighten/ac/packet/handler/HandlerAbstract.java +++ b/src/main/java/dev/brighten/ac/packet/handler/HandlerAbstract.java @@ -28,11 +28,6 @@ public abstract class HandlerAbstract{ Bukkit.getOnlinePlayers().forEach(handler::add); } - public static void shutdown() { - Bukkit.getOnlinePlayers().forEach(handler::remove); - handler = null; - } - public abstract void add(Player player); public abstract void remove(Player player); @@ -41,5 +36,9 @@ public abstract class HandlerAbstract{ public abstract void sendPacket(APlayer player, Object packet); + public void shutdown() { + Bukkit.getOnlinePlayers().forEach(handler::remove); + handler = null; + } public abstract int getProtocolVersion(Player player); } diff --git a/src/main/java/dev/brighten/ac/packet/handler/ModernHandler.java b/src/main/java/dev/brighten/ac/packet/handler/ModernHandler.java index 2b85887..66f96dc 100644 --- a/src/main/java/dev/brighten/ac/packet/handler/ModernHandler.java +++ b/src/main/java/dev/brighten/ac/packet/handler/ModernHandler.java @@ -135,15 +135,19 @@ public class ModernHandler extends HandlerAbstract { Channel channel = getChannel(player); if(channel != null) { - channel.eventLoop().execute(() -> { - if (channel.pipeline().get(handlerName) != null) { - channel.pipeline().remove(handlerName); - } - }); + uninjectChannel(channel); channelCache.remove(player.getName()); } } + private void uninjectChannel(Channel channel) { + channel.eventLoop().execute(() -> { + if (channel.pipeline().get(handlerName) != null) { + channel.pipeline().remove(handlerName); + } + }); + } + @Override public void sendPacket(Player player, Object packet) { if(packet instanceof WPacket) { @@ -151,6 +155,13 @@ public class ModernHandler extends HandlerAbstract { } else getChannel(player).pipeline().writeAndFlush(packet); } + @Override + public void shutdown() { + serverChannels.forEach(this::uninjectChannel); + serverChannels.clear(); + super.shutdown(); + } + @Override public void sendPacket(APlayer player, Object packet) { this.sendPacket(player.getBukkitPlayer(), packet); diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/PacketConverter.java b/src/main/java/dev/brighten/ac/packet/wrapper/PacketConverter.java index 485320c..6f9929b 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/PacketConverter.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/PacketConverter.java @@ -22,14 +22,20 @@ public interface PacketConverter { WPacketPlayOutEntityEffect processEntityEffect(Object object); + Object processEntityEffect(WPacketPlayOutEntityEffect object); + WPacketPlayOutPosition processServerPosition(Object object); WPacketPlayOutAttachEntity processAttach(Object object); WPacketPlayOutEntity processOutEntity(Object object); + Object processOutEntity(WPacketPlayOutEntity packet); + WPacketPlayOutEntityTeleport processEntityTeleport(Object object); + Object processEntityTeleport(WPacketPlayOutEntityTeleport packet); + WPacketHandshakingInSetProtocol processHandshakingProtocol(Object object); WPacketPlayOutBlockChange processBlockChange(Object object); @@ -53,4 +59,20 @@ public interface PacketConverter { Object processChat(WPacketPlayInChat packet); WPacketPlayOutPlayerInfo processInfo(Object object); + + WPacketPlayOutNamedEntitySpawn processNamedEntitySpawn(Object object); + + Object processNamedEntitySpawn(WPacketPlayOutNamedEntitySpawn packet); + + WPacketPlayOutSpawnEntityLiving processSpawnLiving(Object object); + + Object processSpawnLiving(WPacketPlayOutSpawnEntityLiving packet); + + WPacketPlayOutRemoveEntityEffect processRemoveEffect(Object object); + + Object processRemoveEffect(WPacketPlayOutRemoveEntityEffect packet); + + WPacketPlayOutEntityMetadata processEntityMetadata(Object object); + + Object processEntityMetadata(WPacketPlayOutEntityMetadata packet); } diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/PacketType.java b/src/main/java/dev/brighten/ac/packet/wrapper/PacketType.java index 9eb537c..95d6eb5 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/PacketType.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/PacketType.java @@ -68,6 +68,7 @@ public enum PacketType { STATUS_PING("PacketStatusInPing"), STATUS_START("PacketStatusInStart"), LOGIN_START("PacketLoginInStart"), + REMOVE_EFFECT("PacketPlayOutRemoveEntityEffect"), UNKNOWN(); PacketType(String... packetIds) { @@ -131,6 +132,14 @@ public enum PacketType { return convert.processChat(object); case SERVER_ABILITIES: return convert.processOutAbilities(object); + case WORLD_PARTICLE: + return convert.processParticles(object); + case NAMED_ENTITY_SPAWN: + return convert.processNamedEntitySpawn(object); + case SPAWN_ENTITY_LIVING: + return convert.processSpawnLiving(object); + case REMOVE_EFFECT: + return convert.processRemoveEffect(object); default: return object; } diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/WObject.java b/src/main/java/dev/brighten/ac/packet/wrapper/WObject.java new file mode 100644 index 0000000..aa2d443 --- /dev/null +++ b/src/main/java/dev/brighten/ac/packet/wrapper/WObject.java @@ -0,0 +1,22 @@ +package dev.brighten.ac.packet.wrapper; + +import dev.brighten.ac.utils.reflections.types.WrappedField; +import lombok.Getter; + +public abstract class WObject { + + @Getter + private Object vanillaObject; + public WObject(Object object) { + this.vanillaObject = object; + processVanilla(); + } + + public abstract void processVanilla(); + + public abstract Object toVanillaObject(); + + public T fetch(WrappedField field) { + return field.get(getVanillaObject()); + } +} diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java b/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java index e2b6c02..f2abf68 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java @@ -6,7 +6,10 @@ import dev.brighten.ac.packet.wrapper.login.WPacketHandshakingInSetProtocol; import dev.brighten.ac.packet.wrapper.objects.EnumParticle; import dev.brighten.ac.packet.wrapper.objects.PlayerCapabilities; import dev.brighten.ac.packet.wrapper.objects.WrappedEnumDirection; +import dev.brighten.ac.packet.wrapper.objects.WrappedWatchableObject; import dev.brighten.ac.packet.wrapper.out.*; +import dev.brighten.ac.utils.MathHelper; +import dev.brighten.ac.utils.MiscUtils; import dev.brighten.ac.utils.math.IntVector; import dev.brighten.ac.utils.reflections.types.WrappedClass; import dev.brighten.ac.utils.reflections.types.WrappedField; @@ -15,18 +18,22 @@ import net.minecraft.server.v1_8_R3.*; import org.bukkit.Material; import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_8_R3.util.CraftMagicNumbers; +import org.bukkit.entity.EntityType; import org.bukkit.util.Vector; import java.io.IOException; import java.util.Arrays; +import java.util.List; import java.util.stream.Collectors; public class Processor_18 implements PacketConverter { @Override public WPacketPlayInFlying processFlying(Object object) { PacketPlayInFlying flying = (PacketPlayInFlying) object; - return WPacketPlayInFlying.builder().x(flying.a()).y(flying.b()).z(flying.c()).yaw(flying.d()) + WPacketPlayInFlying f = WPacketPlayInFlying.builder().x(flying.a()).y(flying.b()).z(flying.c()).yaw(flying.d()) .pitch(flying.e()).onGround(flying.f()).moved(flying.g()).looked(flying.h()).build(); + + return f; } private static WrappedClass classUseEntity = new WrappedClass(PacketPlayInUseEntity.class); @@ -35,10 +42,12 @@ public class Processor_18 implements PacketConverter { public WPacketPlayInUseEntity processUseEntity(Object object) { PacketPlayInUseEntity useEntity = (PacketPlayInUseEntity) object; - return WPacketPlayInUseEntity.builder().entityId(fieldEntityId.get(useEntity)) + WPacketPlayInUseEntity ue = WPacketPlayInUseEntity.builder().entityId(fieldEntityId.get(useEntity)) .action(WPacketPlayInUseEntity.EnumEntityUseAction.valueOf(useEntity.a().name())) .vector(useEntity.b() != null ? new Vector(useEntity.b().a, useEntity.b().b, useEntity.b().c) : null) .build(); + + return ue; } private static final WrappedClass classAbilities = new WrappedClass(PacketPlayInAbilities.class), @@ -48,11 +57,12 @@ public class Processor_18 implements PacketConverter { private static final WrappedField outfieldFlySpeed = outClassAbilities.getFieldByType(float.class, 0), outfieldWalkSpeed = outClassAbilities.getFieldByType(float.class, 1); + @Override public WPacketPlayInAbilities processAbilities(Object object) { PacketPlayInAbilities abilities = (PacketPlayInAbilities) object; - return WPacketPlayInAbilities.builder() + WPacketPlayInAbilities a = WPacketPlayInAbilities.builder() .capabilities(PlayerCapabilities.builder() .isInvulnerable(abilities.a()) .isFlying(abilities.isFlying()) @@ -62,12 +72,20 @@ public class Processor_18 implements PacketConverter { .walkSpeed(fieldWalkSpeed.get(abilities)) .build()) .build(); + + + + return a; } @Override public WPacketPlayInArmAnimation processAnimation(Object object) { PacketPlayInArmAnimation packet = (PacketPlayInArmAnimation) object; - return WPacketPlayInArmAnimation.builder().timestamp(packet.timestamp).build(); + WPacketPlayInArmAnimation aa = WPacketPlayInArmAnimation.builder().timestamp(packet.timestamp).build(); + + + + return aa; } @Override @@ -76,10 +94,15 @@ public class Processor_18 implements PacketConverter { BlockPosition pos = packet.a(); - return WPacketPlayInBlockDig.builder().blockPos(new IntVector(pos.getX(), pos.getY(), pos.getZ())) + WPacketPlayInBlockDig bd = WPacketPlayInBlockDig.builder() + .blockPos(new IntVector(pos.getX(), pos.getY(), pos.getZ())) .direction(WrappedEnumDirection.valueOf(packet.b().name())) .digType(WPacketPlayInBlockDig.EnumPlayerDigType.valueOf(packet.c().name())) .build(); + + + + return bd; } @Override @@ -88,11 +111,16 @@ public class Processor_18 implements PacketConverter { BlockPosition pos = packet.a(); - return WPacketPlayInBlockPlace.builder().blockPos(new IntVector(pos.getX(), pos.getY(), pos.getZ())) + WPacketPlayInBlockPlace bp = WPacketPlayInBlockPlace.builder() + .blockPos(new IntVector(pos.getX(), pos.getY(), pos.getZ())) .direction(WrappedEnumDirection.values()[Math.min(packet.getFace(), 5)]) .itemStack(CraftItemStack.asCraftMirror(packet.getItemStack())) .vecX(packet.d()).vecY(packet.e()).vecZ(packet.f()) .build(); + + + + return bp; } @@ -102,15 +130,22 @@ public class Processor_18 implements PacketConverter { public WPacketPlayInCloseWindow processCloseWindow(Object object) { PacketPlayInCloseWindow packet = (PacketPlayInCloseWindow) object; - return WPacketPlayInCloseWindow.builder().id(fieldWindowId.get(packet)).build(); + WPacketPlayInCloseWindow cw = WPacketPlayInCloseWindow.builder().id(fieldWindowId.get(packet)).build(); + + + + return cw; } @Override public WPacketPlayInEntityAction processEntityAction(Object object) { PacketPlayInEntityAction packet = (PacketPlayInEntityAction) object; - return WPacketPlayInEntityAction.builder().action(WPacketPlayInEntityAction.EnumPlayerAction + WPacketPlayInEntityAction ea = WPacketPlayInEntityAction.builder().action(WPacketPlayInEntityAction.EnumPlayerAction .valueOf(packet.b().name())).build(); + + + return ea; } @Override @@ -123,11 +158,35 @@ public class Processor_18 implements PacketConverter { throw new RuntimeException(e); } - return WPacketPlayOutEntityEffect.builder().entityId(serializer.e()) + WPacketPlayOutEntityEffect ee = WPacketPlayOutEntityEffect.builder().entityId(serializer.e()) .effectId(serializer.readByte()) .amplifier(serializer.readByte()) .duration(serializer.e()) .flags(serializer.readByte()).build(); + + + + return ee; + } + + @Override + public Object processEntityEffect(WPacketPlayOutEntityEffect packet) { + PacketPlayOutEntityEffect vanilla = new PacketPlayOutEntityEffect(); + PacketDataSerializer serializer = new PacketDataSerializer(Unpooled.buffer()); + + serializer.b(packet.getEntityId()); + serializer.writeByte(packet.getEffectId()); + serializer.writeByte(packet.getAmplifier()); + serializer.b(packet.getDuration()); + serializer.writeByte(packet.getFlags()); + + try { + vanilla.a(serializer); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return vanilla; } @Override @@ -140,7 +199,7 @@ public class Processor_18 implements PacketConverter { } catch (IOException e) { throw new RuntimeException(e); } - return WPacketPlayOutPosition.builder() + WPacketPlayOutPosition p = WPacketPlayOutPosition.builder() .x(serializer.readDouble()) .y(serializer.readDouble()) .z(serializer.readDouble()) @@ -150,6 +209,10 @@ public class Processor_18 implements PacketConverter { .map(f -> WPacketPlayOutPosition.EnumPlayerTeleportFlags.valueOf(f.name())) .collect(Collectors.toSet())) .build(); + + + + return p; } @Override @@ -164,11 +227,15 @@ public class Processor_18 implements PacketConverter { } - return WPacketPlayOutAttachEntity.builder() + WPacketPlayOutAttachEntity ae = WPacketPlayOutAttachEntity.builder() .attachedEntityId(serial.readInt()) .holdingEntityId(serial.readInt()) .isLeashModifer((int)(serial.readUnsignedByte()) == 1) .build(); + + + + return ae; } @Override @@ -209,11 +276,79 @@ public class Processor_18 implements PacketConverter { looked = true; } - return WPacketPlayOutEntity.builder() + WPacketPlayOutEntity e = WPacketPlayOutEntity.builder() .id(id) .x(x / 32D).y(y / 32D).z(z / 32D).yaw(yaw / 256.0F * 360.0F).pitch(pitch / 256.0F * 360.0F) .onGround(ground).moved(moved).looked(looked) .build(); + + + + return e; + } + + @Override + public Object processOutEntity(WPacketPlayOutEntity packet) { + PacketDataSerializer serial = new PacketDataSerializer(Unpooled.buffer()); + + serial.b(packet.getId()); //No matter what this will always be written + + Object packetToReturn = null; + + if(packet.isLooked() && packet.isMoved()) { // Moved and looked + serial.writeByte(MathHelper.floor_double(packet.getX() * 32.)); + serial.writeByte(MathHelper.floor_double(packet.getY() * 32.)); + serial.writeByte(MathHelper.floor_double(packet.getZ() * 32.)); + serial.writeByte((byte)((int)(packet.getYaw() * 256.F / 360.F))); + serial.writeByte((byte)((int)(packet.getPitch() * 256.F / 360.F))); + serial.writeBoolean(packet.isOnGround()); + + PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook vanilla = new PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook(); + + try { + vanilla.a(serial); + packetToReturn = vanilla; + } catch (IOException e) { + throw new RuntimeException(e); + } + } else if(packet.isLooked()) { // Only looked + serial.writeByte((byte)((int)(packet.getYaw() * 256.F / 360.F))); + serial.writeByte((byte)((int)(packet.getPitch() * 256.F / 360.F))); + serial.writeBoolean(packet.isOnGround()); + + PacketPlayOutEntity.PacketPlayOutEntityLook vanilla = new PacketPlayOutEntity.PacketPlayOutEntityLook(); + + try { + vanilla.a(serial); + packetToReturn = vanilla; + } catch (IOException e) { + throw new RuntimeException(e); + } + } else if(packet.isMoved()) { // Only moved + serial.writeByte(MathHelper.floor_double(packet.getX() * 32.)); + serial.writeByte(MathHelper.floor_double(packet.getY() * 32.)); + serial.writeByte(MathHelper.floor_double(packet.getZ() * 32.)); + serial.writeBoolean(packet.isOnGround()); + + PacketPlayOutEntity.PacketPlayOutRelEntityMove vanilla = new PacketPlayOutEntity.PacketPlayOutRelEntityMove(); + + try { + vanilla.a(serial); + packetToReturn = vanilla; + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + PacketPlayOutEntity vanilla = new PacketPlayOutEntity(); + + try { + vanilla.a(serial); + } catch (IOException e) { + throw new RuntimeException(e); + } + packetToReturn = vanilla; + } + return packetToReturn; } @Override @@ -227,7 +362,7 @@ public class Processor_18 implements PacketConverter { throw new RuntimeException(e); } - return WPacketPlayOutEntityTeleport.builder() + WPacketPlayOutEntityTeleport et = WPacketPlayOutEntityTeleport.builder() .entityId(serial.e()) .x(serial.readInt() / 32D) .y(serial.readInt() / 32D) @@ -236,6 +371,31 @@ public class Processor_18 implements PacketConverter { .pitch(serial.readByte() / 256.0F * 360.0F) .onGround(serial.readBoolean()) .build(); + + + return et; + } + + @Override + public Object processEntityTeleport(WPacketPlayOutEntityTeleport packet) { + PacketDataSerializer serial = new PacketDataSerializer(Unpooled.buffer()); + PacketPlayOutEntityTeleport vanilla = new PacketPlayOutEntityTeleport(); + + serial.b(packet.getEntityId()); + serial.writeInt(MathHelper.floor_double(packet.getX() * 32.)); + serial.writeInt(MathHelper.floor_double(packet.getY() * 32.)); + serial.writeInt(MathHelper.floor_double(packet.getZ() * 32.)); + serial.writeByte((byte)((int)(packet.getYaw() * 256.F / 360.F))); + serial.writeByte((byte)((int)(packet.getPitch() * 256.F / 360.F))); + serial.writeBoolean(packet.isOnGround()); + + try { + vanilla.b(serial); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return vanilla; } @Override @@ -249,12 +409,16 @@ public class Processor_18 implements PacketConverter { throw new RuntimeException(e); } - return WPacketHandshakingInSetProtocol.builder() + WPacketHandshakingInSetProtocol isp = WPacketHandshakingInSetProtocol.builder() .versionNumber(serial.e()) .hostname(serial.c(32767)) .port(serial.readUnsignedShort()) - .protocol(WPacketHandshakingInSetProtocol.EnumProtocol.valueOf(EnumProtocol.a(serial.e()).name())) + .protocol(WPacketHandshakingInSetProtocol.EnumProtocol.valueOf(EnumProtocol.a(serial.e()).toString())) .build(); + + + + return isp; } @Override @@ -266,10 +430,13 @@ public class Processor_18 implements PacketConverter { IntVector vecPos = new IntVector(blockPos.getX(), blockPos.getY(), blockPos.getZ()); Material material = CraftMagicNumbers.getMaterial(packet.block.getBlock()); - return WPacketPlayOutBlockChange.builder() + WPacketPlayOutBlockChange change = WPacketPlayOutBlockChange.builder() .blockLocation(vecPos) .material(material) .build(); + + + return change; } @Override @@ -290,10 +457,14 @@ public class Processor_18 implements PacketConverter { blockChanges[i] = new WPacketPlayOutMultiBlockChange.BlockChange(loc, blockType); } - return WPacketPlayOutMultiBlockChange.builder() + WPacketPlayOutMultiBlockChange change = WPacketPlayOutMultiBlockChange.builder() .chunk(chunkLoc) .changes(blockChanges) .build(); + + + + return change; } @Override @@ -301,18 +472,22 @@ public class Processor_18 implements PacketConverter { PacketPlayOutEntityVelocity packet = (PacketPlayOutEntityVelocity) object; PacketDataSerializer serial = serialize(packet); - return WPacketPlayOutEntityVelocity.builder() + WPacketPlayOutEntityVelocity velocity = WPacketPlayOutEntityVelocity.builder() .entityId(serial.e()) .deltaX(serial.readShort() / 8000D) .deltaY(serial.readShort() / 8000D) .deltaZ(serial.readShort() / 8000D) .build(); + + + + return velocity; } @Override public WPacketPlayOutAbilities processOutAbilities(Object object) { PacketPlayOutAbilities packet = (PacketPlayOutAbilities) object; - return WPacketPlayOutAbilities.builder() + WPacketPlayOutAbilities ab = WPacketPlayOutAbilities.builder() .capabilities(PlayerCapabilities.builder() .isInvulnerable(packet.a()) .isFlying(packet.b()) @@ -322,6 +497,10 @@ public class Processor_18 implements PacketConverter { .walkSpeed(outfieldWalkSpeed.get(packet)) .build()) .build(); + + + + return ab; } @Override @@ -354,7 +533,7 @@ public class Processor_18 implements PacketConverter { int[] data = new int[particle.d()]; - return WPacketPlayOutWorldParticles.builder() + WPacketPlayOutWorldParticles part = WPacketPlayOutWorldParticles.builder() .particle(particle) .longD(serial.readBoolean()) .x(serial.readFloat()) @@ -367,6 +546,10 @@ public class Processor_18 implements PacketConverter { .amount(serial.readInt()) .data(Arrays.stream(data).map(i -> serial.e()).toArray()) .build(); + + + + return part; } @Override @@ -379,9 +562,13 @@ public class Processor_18 implements PacketConverter { @Override public WPacketPlayInChat processChat(Object object) { PacketPlayInChat packet = (PacketPlayInChat) object; - return WPacketPlayInChat.builder() + + WPacketPlayInChat chat = WPacketPlayInChat.builder() .message(packet.a()) .build(); + + + return chat; } @Override @@ -395,7 +582,171 @@ public class Processor_18 implements PacketConverter { return null; } - private PacketDataSerializer serialize(Packet packet) { + private static final WrappedClass wrappedNamedEntitySpawn = new WrappedClass(PacketPlayOutNamedEntitySpawn.class); + private static final WrappedField dataWatcherField = wrappedNamedEntitySpawn.getFieldByType(DataWatcher.class, 0); + @Override + public WPacketPlayOutNamedEntitySpawn processNamedEntitySpawn(Object object) { + PacketPlayOutNamedEntitySpawn packet = (PacketPlayOutNamedEntitySpawn) object; + PacketDataSerializer serial = serialize(packet); + + + WPacketPlayOutNamedEntitySpawn nes = WPacketPlayOutNamedEntitySpawn.builder().entityId(serial.e()).uuid(serial.g()) + .x(serial.readInt() / 32.).y(serial.readInt() / 32.).z(serial.readInt() / 32.) + .yaw(serial.readByte() * 360.F / 256.F).pitch(serial.readByte() * 360.F / 256.F) + .itemInHand(MiscUtils.getById(serial.readShort())) + .build(); + + + + return nes; + } + + @Override + public Object processNamedEntitySpawn(WPacketPlayOutNamedEntitySpawn packet) { + PacketPlayOutNamedEntitySpawn vanilla = new PacketPlayOutNamedEntitySpawn(); + PacketDataSerializer serializer = new PacketDataSerializer(Unpooled.buffer()); + + try { + serializer.b(packet.getEntityId()); + serializer.a(packet.getUuid()); + serializer.writeInt(MathHelper.floor_double(packet.getX() * 32.)); + serializer.writeInt(MathHelper.floor_double(packet.getY() * 32.)); + serializer.writeInt(MathHelper.floor_double(packet.getZ() * 32.)); + serializer.writeByte((byte)((int)(packet.getYaw() * 256.0F / 360.0F))); + serializer.writeByte((byte)((int)(packet.getPitch() * 256.0F / 360.0F))); + serializer.writeShort(packet.getItemInHand() == null ? 0 : packet.getItemInHand().getId()); + dataWatcherField.set(vanilla, new DataWatcher(null)); + new DataWatcher(null).a(serializer); + + vanilla.a(serializer); + } catch (IOException e) { + throw new RuntimeException(e); + } + return vanilla; + } + + @Override + public WPacketPlayOutSpawnEntityLiving processSpawnLiving(Object object) { + PacketPlayOutSpawnEntityLiving packet = (PacketPlayOutSpawnEntityLiving) object; + PacketDataSerializer s = serialize(packet); + + WPacketPlayOutSpawnEntityLiving sel = WPacketPlayOutSpawnEntityLiving.builder().entityId(s.e()) + .type(EntityType.fromId(s.readByte() & 255)).x(s.readInt() / 32.).y(s.readInt() / 32.) + .z(s.readInt()/ 32.).yaw(s.readByte() * 360.F / 256.F).pitch(s.readByte() * 360.F / 256.F) + .headYaw(s.readByte() * 360.F / 256.F).vX(s.readShort() / 8000.).vY(s.readShort() / 8000.) + .vZ(s.readShort() / 8000.).build(); + + + + return sel; + } + + private static WrappedClass classSpawnEntityLiving = new WrappedClass(PacketPlayOutSpawnEntityLiving.class); + private static WrappedField splDataWatcher = classSpawnEntityLiving.getFieldByType(DataWatcher.class, 0); + @Override + public Object processSpawnLiving(WPacketPlayOutSpawnEntityLiving packet) { + PacketPlayOutSpawnEntityLiving vanilla = new PacketPlayOutSpawnEntityLiving(); + PacketDataSerializer serializer = new PacketDataSerializer(Unpooled.buffer()); + + serializer.b(packet.getEntityId()); + serializer.writeByte(packet.getType().getTypeId() & 255); + serializer.writeInt(MathHelper.floor_double(packet.getX() * 32.)); + serializer.writeInt(MathHelper.floor_double(packet.getY() * 32.)); + serializer.writeInt(MathHelper.floor_double(packet.getZ() * 32.)); + serializer.writeByte((byte)((int)(packet.getYaw() * 256.0F / 360.0F))); + serializer.writeByte((byte)((int)(packet.getPitch() * 256.0F / 360.0F))); + serializer.writeByte((byte)((int)(packet.getHeadYaw() * 256.0F / 360.0F))); + serializer.writeShort((int)(packet.getVX() * 8000.)); + serializer.writeShort((int)(packet.getVY() * 8000.)); + serializer.writeShort((int)(packet.getVZ() * 8000.)); + + try { + DataWatcher watcher = new DataWatcher(null); + splDataWatcher.set(vanilla, watcher); + watcher.a(serializer); + vanilla.a(serializer); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return vanilla; + } + + @Override + public WPacketPlayOutRemoveEntityEffect processRemoveEffect(Object object) { + PacketPlayOutRemoveEntityEffect packet = (PacketPlayOutRemoveEntityEffect) object; + + PacketDataSerializer serializer = serialize(packet); + + WPacketPlayOutRemoveEntityEffect ree = WPacketPlayOutRemoveEntityEffect.builder() + .entityId(serializer.e()) + .effectId(serializer.readUnsignedByte()).build(); + + + + return ree; + } + + @Override + public Object processRemoveEffect(WPacketPlayOutRemoveEntityEffect packet) { + PacketPlayOutRemoveEntityEffect vanilla = new PacketPlayOutRemoveEntityEffect(); + + PacketDataSerializer serial = new PacketDataSerializer(Unpooled.buffer()); + + serial.b(packet.getEntityId()); + serial.writeByte(packet.getEffectId()); + + try { + vanilla.b(serial); + } catch (IOException e) { + throw new RuntimeException(e); + } + return vanilla; + } + + @Override + public WPacketPlayOutEntityMetadata processEntityMetadata(Object object) { + PacketPlayOutEntityMetadata packet = (PacketPlayOutEntityMetadata) object; + + PacketDataSerializer serialized = serialize(packet); + + try { + int entityId = serialized.e(); + List watchedObject = DataWatcher.b(serialized); + + WPacketPlayOutEntityMetadata em = WPacketPlayOutEntityMetadata.builder().entityId(entityId) + .watchedObjects(watchedObject.stream().map(WrappedWatchableObject::new) + .collect(Collectors.toList())).build(); + + + return em; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public Object processEntityMetadata(WPacketPlayOutEntityMetadata packet) { + PacketPlayOutEntityMetadata vanilla = new PacketPlayOutEntityMetadata(); + + PacketDataSerializer serialized = new PacketDataSerializer(Unpooled.buffer()); + + serialized.b(packet.getEntityId()); + + List watchedObjects = packet.getWatchedObjects().stream() + .map(w -> (DataWatcher.WatchableObject)w.getVanillaObject()).collect(Collectors.toList()); + + try { + DataWatcher.a(watchedObjects, serialized); + vanilla.a(serialized); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return vanilla; + } + + private PacketDataSerializer serialize(Packet packet) { PacketDataSerializer serial = new PacketDataSerializer(Unpooled.buffer()); try { packet.b(serial); diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/objects/WrappedWatchableObject.java b/src/main/java/dev/brighten/ac/packet/wrapper/objects/WrappedWatchableObject.java new file mode 100644 index 0000000..70e59e4 --- /dev/null +++ b/src/main/java/dev/brighten/ac/packet/wrapper/objects/WrappedWatchableObject.java @@ -0,0 +1,69 @@ +package dev.brighten.ac.packet.wrapper.objects; + +import dev.brighten.ac.packet.ProtocolVersion; +import dev.brighten.ac.packet.wrapper.WObject; +import dev.brighten.ac.utils.reflections.Reflections; +import dev.brighten.ac.utils.reflections.types.WrappedClass; +import dev.brighten.ac.utils.reflections.types.WrappedConstructor; +import dev.brighten.ac.utils.reflections.types.WrappedField; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class WrappedWatchableObject extends WObject { + private static String type = (ProtocolVersion.getGameVersion().isBelow(ProtocolVersion.V1_8_5)) + ? "WatchableObject" : + (ProtocolVersion.getGameVersion().isBelow(ProtocolVersion.V1_9) + ? "DataWatcher$WatchableObject" + : "DataWatcher$Item"); + private static WrappedClass c = Reflections.getNMSClass(type), dwo; + private static WrappedConstructor constructor = c.getConstructor(int.class, int.class, Object.class); + + private static WrappedField firstIntField, dataValueIdField, dataWatcherObjectField, + dataWatcherObjectIdField, dataSerializerField, watchedObjectField, watchedField; + + private int firstInt, dataValueId; + private Object watchedObject, dataWatcherObject, serializer; + private boolean watched; + + public WrappedWatchableObject(Object object) { + super(object); + } + + @Override + public void processVanilla() { + if(ProtocolVersion.getGameVersion().isBelow(ProtocolVersion.V1_9)) { + firstInt = fetch(firstIntField); + dataValueId = fetch(dataValueIdField); + } else { + firstInt = -1; + dataWatcherObject = fetch(dataWatcherObjectField); + dataValueId = dataWatcherObjectIdField.get(dataWatcherObject); + serializer = dataSerializerField.get(dataWatcherObject); + } + watchedObject = fetch(watchedObjectField); + watched = fetch(watchedField); + } + + @Override + public Object toVanillaObject() { + return constructor.newInstance(firstInt, dataValueId, watchedObject); + } + + static { + if(ProtocolVersion.getGameVersion().isBelow(ProtocolVersion.V1_9)) { + firstIntField = c.getFieldByType(int.class, 0); + dataValueIdField = c.getFieldByType(int.class, 1); + watchedObjectField = c.getFieldByType(Object.class, 0); + } else { + dwo = Reflections.getNMSClass("DataWatcherObject"); + dataWatcherObjectIdField = c.getFieldByType(Object.class, 0); + watchedObjectField = c.getFieldByType(Object.class, 1); + + dataWatcherObjectIdField = c.getFieldByType(dwo.getParent(), 0); + dataSerializerField = c.getFieldByType(dwo.getParent(), 1); + } + watchedField = c.getFieldByType(boolean.class, 0); + } +} diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntity.java b/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntity.java index 8cec447..71dfe57 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntity.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntity.java @@ -1,5 +1,6 @@ package dev.brighten.ac.packet.wrapper.out; +import dev.brighten.ac.Anticheat; import dev.brighten.ac.packet.wrapper.PacketType; import dev.brighten.ac.packet.wrapper.WPacket; import lombok.Builder; @@ -21,7 +22,7 @@ public class WPacketPlayOutEntity extends WPacket { @Override public Object getPacket() { - return null; + return Anticheat.INSTANCE.getPacketProcessor().getPacketConverter().processOutEntity(this); } @Override diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntityEffect.java b/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntityEffect.java index e5480d2..e2c6108 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntityEffect.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntityEffect.java @@ -1,5 +1,6 @@ package dev.brighten.ac.packet.wrapper.out; +import dev.brighten.ac.Anticheat; import dev.brighten.ac.packet.wrapper.PacketType; import dev.brighten.ac.packet.wrapper.WPacket; import lombok.Builder; @@ -11,6 +12,11 @@ public class WPacketPlayOutEntityEffect extends WPacket { private int entityId, effectId, duration; private byte amplifier, flags; + /* Flags (source: https://wiki.vg/Protocol#Entity_Effect): + 0x01: Is ambient - was the effect spawned from a beacon? All beacon-generated effects are ambient. Ambient effects use a different icon in the HUD (blue border rather than gray). If all effects on an entity are ambient, the "Is potion effect ambient" living metadata field should be set to true. Usually should not be enabled. + 0x02: Show particles - should all particles from this effect be hidden? Effects with particles hidden are not included in the calculation of the effect color, and are not rendered on the HUD (but are still rendered within the inventory). Usually should be enabled. + 0x04: Show icon - should the icon be displayed on the client? Usually should be enabled. + */ @Override public PacketType getPacketType() { @@ -19,7 +25,7 @@ public class WPacketPlayOutEntityEffect extends WPacket { @Override public Object getPacket() { - return null; + return Anticheat.INSTANCE.getPacketProcessor().getPacketConverter().processEntityEffect(this); } @Override diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntityTeleport.java b/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntityTeleport.java index b24e027..66bac04 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntityTeleport.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutEntityTeleport.java @@ -1,5 +1,6 @@ package dev.brighten.ac.packet.wrapper.out; +import dev.brighten.ac.Anticheat; import dev.brighten.ac.packet.wrapper.PacketType; import dev.brighten.ac.packet.wrapper.WPacket; import lombok.Builder; @@ -21,7 +22,7 @@ public class WPacketPlayOutEntityTeleport extends WPacket { @Override public Object getPacket() { - return null; + return Anticheat.INSTANCE.getPacketProcessor().getPacketConverter().processEntityTeleport(this); } @Override diff --git a/src/main/java/dev/brighten/ac/utils/BlockUtils.java b/src/main/java/dev/brighten/ac/utils/BlockUtils.java index 8581a73..5455775 100644 --- a/src/main/java/dev/brighten/ac/utils/BlockUtils.java +++ b/src/main/java/dev/brighten/ac/utils/BlockUtils.java @@ -11,6 +11,7 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.inventory.ItemStack; +import java.util.EnumMap; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -18,6 +19,17 @@ import java.util.Optional; public class BlockUtils { public static Map collisionBoundingBoxes = new HashMap<>(); + private static final EnumMap matchMaterial = new EnumMap<>(Material.class); + + static { + for (Material mat : Material.values()) { + matchMaterial.put(mat, XMaterial.matchXMaterial(mat)); + } + } + + public static XMaterial getXMaterial(Material material) { + return matchMaterial.get(material); + } @Deprecated public static Block getBlock(Location location) { diff --git a/src/main/java/dev/brighten/ac/utils/Helper.java b/src/main/java/dev/brighten/ac/utils/Helper.java index b42bea1..40a7b76 100644 --- a/src/main/java/dev/brighten/ac/utils/Helper.java +++ b/src/main/java/dev/brighten/ac/utils/Helper.java @@ -217,7 +217,7 @@ public class Helper { for (int y = y1; y <= y2; y++) for (int z = z1; z <= z2; z++) if ((block = getBlockAt(world, x, y, z)) != null - && block.getType()!= XMaterial.AIR.parseMaterial()) + && BlockUtils.getXMaterial(block.getType()) != XMaterial.AIR) if (Materials.checkFlag(block.getType(),mask)) blocks.add(block); return blocks; diff --git a/src/main/java/dev/brighten/ac/utils/ItemBuilder.java b/src/main/java/dev/brighten/ac/utils/ItemBuilder.java index 6e63350..693e2c4 100644 --- a/src/main/java/dev/brighten/ac/utils/ItemBuilder.java +++ b/src/main/java/dev/brighten/ac/utils/ItemBuilder.java @@ -216,10 +216,11 @@ public class ItemBuilder { * @since 1.1 */ public ItemBuilder color(Color color) { - if (is.getType() == XMaterial.LEATHER_BOOTS.parseMaterial() - || is.getType() == XMaterial.LEATHER_CHESTPLATE .parseMaterial() - || is.getType() == XMaterial.LEATHER_HELMET.parseMaterial() - || is.getType() == XMaterial.LEATHER_LEGGINGS.parseMaterial()) { + XMaterial type = BlockUtils.getXMaterial(is.getType()); + if (type == XMaterial.LEATHER_BOOTS + || type == XMaterial.LEATHER_CHESTPLATE + || type == XMaterial.LEATHER_HELMET + || type == XMaterial.LEATHER_LEGGINGS) { LeatherArmorMeta meta = (LeatherArmorMeta) is.getItemMeta(); meta.setColor(color); is.setItemMeta(meta); diff --git a/src/main/java/dev/brighten/ac/utils/MiscUtils.java b/src/main/java/dev/brighten/ac/utils/MiscUtils.java index 3a4506f..7c7582e 100644 --- a/src/main/java/dev/brighten/ac/utils/MiscUtils.java +++ b/src/main/java/dev/brighten/ac/utils/MiscUtils.java @@ -63,7 +63,7 @@ public class MiscUtils { Optional op = BlockUtils.getBlockAsync(loc); if(op.isPresent()) { - if(XMaterial.matchXMaterial(op.get().getType()).equals(xmaterial)) + if(BlockUtils.getXMaterial(op.get().getType()).equals(xmaterial)) return true; } } diff --git a/src/main/java/dev/brighten/ac/utils/MovementUtils.java b/src/main/java/dev/brighten/ac/utils/MovementUtils.java index 71a93e4..fbb0ece 100644 --- a/src/main/java/dev/brighten/ac/utils/MovementUtils.java +++ b/src/main/java/dev/brighten/ac/utils/MovementUtils.java @@ -16,7 +16,6 @@ import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.Optional; public class MovementUtils { @@ -73,10 +72,10 @@ public class MovementUtils { } public static float getFriction(Block block) { - Optional matched = XMaterial.matchXMaterial(block.getType().name()); + XMaterial matched = BlockUtils.getXMaterial(block.getType()); - if(!matched.isPresent()) return 0.6f; - switch(matched.get()) { + if(matched == null) return 0.6f; + switch(matched) { case SLIME_BLOCK: return 0.8f; case ICE: diff --git a/src/main/java/dev/brighten/ac/utils/menu/MenuListener.java b/src/main/java/dev/brighten/ac/utils/menu/MenuListener.java index d683e8f..40bad57 100644 --- a/src/main/java/dev/brighten/ac/utils/menu/MenuListener.java +++ b/src/main/java/dev/brighten/ac/utils/menu/MenuListener.java @@ -2,6 +2,7 @@ package dev.brighten.ac.utils.menu; import dev.brighten.ac.Anticheat; import dev.brighten.ac.packet.ProtocolVersion; +import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.Color; import dev.brighten.ac.utils.annotation.Init; import dev.brighten.ac.utils.XMaterial; @@ -54,7 +55,7 @@ public class MenuListener implements Listener { if (menu != null) { final ItemStack stack = event.getCurrentItem(); - if ((stack == null || stack.getType() == XMaterial.AIR.parseMaterial())) + if ((stack == null || BlockUtils.getXMaterial(stack.getType()) == XMaterial.AIR)) return; int slot = event.getSlot(); diff --git a/src/main/java/dev/brighten/ac/utils/menu/type/impl/ChestMenu.java b/src/main/java/dev/brighten/ac/utils/menu/type/impl/ChestMenu.java index 621d644..ccf7cf4 100644 --- a/src/main/java/dev/brighten/ac/utils/menu/type/impl/ChestMenu.java +++ b/src/main/java/dev/brighten/ac/utils/menu/type/impl/ChestMenu.java @@ -1,5 +1,6 @@ package dev.brighten.ac.utils.menu.type.impl; +import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.XMaterial; import dev.brighten.ac.utils.menu.Menu; import dev.brighten.ac.utils.menu.button.Button; @@ -71,8 +72,8 @@ public class ChestMenu implements Menu { @Override public void fillRange(int startingIndex, int endingIndex, Button button) { IntStream.range(startingIndex, endingIndex) - .filter(i -> contents[i] == null || contents[i].getStack().getType() - .equals(XMaterial.AIR.parseMaterial())) + .filter(i -> contents[i] == null || BlockUtils.getXMaterial(contents[i].getStack().getType()) + .equals(XMaterial.AIR)) .forEach(i -> setItem(i, button)); } diff --git a/src/main/java/dev/brighten/ac/utils/menu/type/impl/PagedMenu.java b/src/main/java/dev/brighten/ac/utils/menu/type/impl/PagedMenu.java index d00ebe7..001ba2c 100644 --- a/src/main/java/dev/brighten/ac/utils/menu/type/impl/PagedMenu.java +++ b/src/main/java/dev/brighten/ac/utils/menu/type/impl/PagedMenu.java @@ -1,5 +1,6 @@ package dev.brighten.ac.utils.menu.type.impl; +import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.ItemBuilder; import dev.brighten.ac.utils.XMaterial; import dev.brighten.ac.utils.menu.Menu; @@ -66,8 +67,8 @@ public class PagedMenu implements Menu { @Override public void fillRange(int startingIndex, int endingIndex, Button button) { IntStream.range(startingIndex, endingIndex) - .filter(i -> contents.get(i) == null || contents.get(i).getStack().getType() - .equals(XMaterial.AIR.parseMaterial())) + .filter(i -> contents.get(i) == null || BlockUtils.getXMaterial(contents.get(i).getStack().getType()) + .equals(XMaterial.AIR)) .forEach(i -> setItem(i, button)); } diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicFence.java b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicFence.java index 6e205e4..5b21c38 100644 --- a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicFence.java +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicFence.java @@ -36,7 +36,7 @@ public class DynamicFence implements CollisionFactory { } static boolean isBlacklisted(Material m) { - XMaterial material = XMaterial.matchXMaterial(m); + XMaterial material = BlockUtils.getXMaterial(m); switch(material) { case BEACON: case STICK: diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicPane.java b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicPane.java index 0554589..b76411d 100644 --- a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicPane.java +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicPane.java @@ -1,6 +1,7 @@ package dev.brighten.ac.utils.world.blocks; import dev.brighten.ac.packet.ProtocolVersion; +import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.Materials; import dev.brighten.ac.utils.XMaterial; import dev.brighten.ac.utils.world.CollisionBox; @@ -56,7 +57,7 @@ public class DynamicPane implements CollisionFactory { } private static boolean isPane(Material m) { - final XMaterial mat = XMaterial.matchXMaterial(m); + XMaterial mat = BlockUtils.getXMaterial(m); return mat == XMaterial.IRON_BARS || mat.name().contains("PANE") || mat.name().contains("THIN");