From d4747897ada36a01ecda6840c7dc7b91dfe1fe38 Mon Sep 17 00:00:00 2001 From: Dawson <30784509+funkemunky@users.noreply.github.com> Date: Sat, 25 Mar 2023 14:03:06 -0400 Subject: [PATCH] Fixing chunk issues --- .../main/java/dev/brighten/ac/Anticheat.java | 25 +-- .../brighten/ac/handler/BBRevealHandler.java | 37 ++-- .../brighten/ac/handler/PacketHandler.java | 160 +++++++----------- .../ac/handler/block/BlockUpdateHandler.java | 27 ++- .../ac/packet/wrapper/impl/Processor_18.java | 29 +++- .../reflections/impl/CraftReflection.java | 8 + 6 files changed, 146 insertions(+), 140 deletions(-) diff --git a/Anticheat/src/main/java/dev/brighten/ac/Anticheat.java b/Anticheat/src/main/java/dev/brighten/ac/Anticheat.java index 0e60723..09e5ba0 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/Anticheat.java +++ b/Anticheat/src/main/java/dev/brighten/ac/Anticheat.java @@ -5,7 +5,6 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; import dev.brighten.ac.api.AnticheatAPI; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckManager; -import dev.brighten.ac.data.APlayer; import dev.brighten.ac.data.PlayerRegistry; import dev.brighten.ac.depends.LibraryLoader; import dev.brighten.ac.depends.MavenLibrary; @@ -33,9 +32,7 @@ import dev.brighten.loader.LoaderPlugin; import lombok.Getter; import lombok.experimental.PackagePrivate; import org.bukkit.Bukkit; -import org.bukkit.Chunk; import org.bukkit.World; -import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import java.io.File; @@ -169,27 +166,7 @@ public class Anticheat extends LoaderPlugin { logManager = new LoggerManager(); this.actionManager = new ActionManager(); - int chunkDistance = Bukkit.getViewDistance() * 2 + 1; - // Created players on server reload - if(playerRegistry.aplayerMap.size() > 0) { - getLogger().warning("Players are online, resending chunk map to players so anticheat is up to date."); - for (APlayer aplayer : playerRegistry.aplayerMap.values()) { - Player player = aplayer.getBukkitPlayer(); - - getLogger().info("Sending chunks to " + player.getName()); - int chunkX = player.getLocation().getBlockX() >> 4, - chunkZ = player.getLocation().getBlockZ() >> 4; - - for (int x = chunkX - chunkDistance; x <= chunkX + chunkDistance; x++) { - for (int z = chunkZ - chunkDistance; z <= chunkZ + chunkDistance; z++) { - Chunk chunk = player.getWorld().getChunkAt(x, z); - Object mapChunk = packetProcessor.getPacketConverter().createMapChunk(chunk); - - aplayer.sendPacket(mapChunk); - } - } - } - } + Bukkit.getOnlinePlayers().forEach(player -> player.kickPlayer("Server restarting...")); keepaliveProcessor.start(); diff --git a/Anticheat/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java b/Anticheat/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java index 0b80e6c..e4d58b4 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java +++ b/Anticheat/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java @@ -2,18 +2,17 @@ package dev.brighten.ac.handler; import dev.brighten.ac.Anticheat; import dev.brighten.ac.data.APlayer; -import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.wrapper.objects.EnumParticle; 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 net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ComponentBuilder; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -24,14 +23,13 @@ import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; -import java.util.HashSet; -import java.util.Set; +import java.util.*; import java.util.concurrent.TimeUnit; @Init public class BBRevealHandler implements Listener { - private final Set blocksToShow = new HashSet<>(); + private final Map> blocksToShow = new HashMap<>(); private final Set entitiesToShow = new HashSet<>(); public static BBRevealHandler INSTANCE; @@ -53,13 +51,17 @@ public class BBRevealHandler implements Listener { if(event.getAction() == Action.RIGHT_CLICK_BLOCK) { if(Materials.checkFlag(event.getClickedBlock().getType(), Materials.COLLIDABLE)) { - if(blocksToShow.contains(event.getClickedBlock())) { - blocksToShow.remove(event.getClickedBlock()); + IntVector blockLoc = new IntVector(event.getClickedBlock().getX(), + event.getClickedBlock().getY(), event.getClickedBlock().getZ()); + Set blocksToShow = this.blocksToShow + .computeIfAbsent(event.getPlayer().getUniqueId(), k -> new HashSet<>()); + if(blocksToShow.contains(blockLoc)) { + blocksToShow.remove(blockLoc); event.getPlayer().spigot().sendMessage(new ComponentBuilder("No longer showing block: ") .color(ChatColor.RED).append(event.getClickedBlock().getType().name()).color(ChatColor.WHITE) .create()); } else { - blocksToShow.add(event.getClickedBlock()); + blocksToShow.add(blockLoc); event.getPlayer().spigot().sendMessage(new ComponentBuilder("Now showing block: ") .color(ChatColor.GREEN).append(event.getClickedBlock().getType().name()).color(ChatColor.WHITE) .create()); @@ -98,12 +100,21 @@ public class BBRevealHandler implements Listener { private void runShowTask() { Anticheat.INSTANCE.getScheduler().scheduleAtFixedRate(() -> { - blocksToShow.forEach(b -> BlockData.getData(b.getType()).getBox(b, ProtocolVersion.getGameVersion()) - .draw(EnumParticle.FLAME, Bukkit.getOnlinePlayers().toArray(new Player[0]))); - entitiesToShow.forEach(e -> { - EntityData.getEntityBox(e.getLocation(), e) - .draw(EnumParticle.FLAME, Bukkit.getOnlinePlayers().toArray(new Player[0])); + blocksToShow.forEach((uuid, blocks) -> { + Optional player = Anticheat.INSTANCE.getPlayerRegistry().getPlayer(uuid); + if(player.isEmpty()) return; + + blocks.forEach(blockLoc -> { + var block = player.get().getBlockUpdateHandler().getBlock(blockLoc); + + var blockBox = BlockData.getData(block.getType()) + .getBox(player.get(), blockLoc, player.get().getPlayerVersion()); + + blockBox.draw(EnumParticle.FLAME, player.get().getBukkitPlayer()); + }); }); + entitiesToShow.forEach(e -> EntityData.getEntityBox(e.getLocation(), e) + .draw(EnumParticle.FLAME, Bukkit.getOnlinePlayers().toArray(new Player[0]))); }, 3000, 250, TimeUnit.MILLISECONDS); } diff --git a/Anticheat/src/main/java/dev/brighten/ac/handler/PacketHandler.java b/Anticheat/src/main/java/dev/brighten/ac/handler/PacketHandler.java index 0ace308..cc0fd19 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/handler/PacketHandler.java +++ b/Anticheat/src/main/java/dev/brighten/ac/handler/PacketHandler.java @@ -28,11 +28,11 @@ public class PacketHandler { public boolean process(APlayer player, PacketType type, Object packetObject) { long timestamp = System.currentTimeMillis(); switch (type) { - case CLIENT_TRANSACTION: { + case CLIENT_TRANSACTION -> { WPacketPlayInTransaction packet = (WPacketPlayInTransaction) packetObject; - if(packet.getId() == 0) { - if(Anticheat.INSTANCE.getKeepaliveProcessor().keepAlives.getIfPresent(packet.getAction()) != null) { + if (packet.getId() == 0) { + if (Anticheat.INSTANCE.getKeepaliveProcessor().keepAlives.getIfPresent(packet.getAction()) != null) { Anticheat.INSTANCE.getKeepaliveProcessor().addResponse(player, packet.getAction()); val optional = Anticheat.INSTANCE.getKeepaliveProcessor().getResponse(player); @@ -45,29 +45,29 @@ public class PacketHandler { player.getLagInfo().setLastTransPing(player.getLagInfo().getTransPing()); player.getLagInfo().setTransPing(current - ka.start); - if(player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9) + if (player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9) && player.getMovement().getLastFlying().isPassed(1)) { player.getMovement().runPositionHackFix(); } - if(player.instantTransaction.size() > 0) { + if (player.instantTransaction.size() > 0) { synchronized (player.instantTransaction) { Deque toRemove = new LinkedList<>(); player.instantTransaction.forEach((key, tuple) -> { - if((timestamp - tuple.one.getStamp()) + if ((timestamp - tuple.one.getStamp()) > player.getLagInfo().getTransPing() * 52L + 750L) { tuple.two.accept(tuple.one); toRemove.add(key); } }); Short key = null; - while((key = toRemove.poll()) != null) { + while ((key = toRemove.poll()) != null) { player.instantTransaction.remove(key); } } } - if(Math.abs(player.getLagInfo().getLastTransPing() + if (Math.abs(player.getLagInfo().getLastTransPing() - player.getLagInfo().getTransPing()) > 1) { player.getLagInfo().getLastPingDrop().reset(); } @@ -79,7 +79,7 @@ public class PacketHandler { synchronized (player.keepAliveStamps) { List toRemove = new ArrayList<>(); for (NormalAction action : player.keepAliveStamps) { - if(action.stamp > ka.start) continue; + if (action.stamp > ka.start) continue; action.action.accept(ka); toRemove.add(action); @@ -94,26 +94,24 @@ public class PacketHandler { Optional.ofNullable(player.instantTransaction.remove(packet.getAction())) .ifPresent(t -> t.two.accept(t.one)); } - break; } - case SERVER_ABILITIES: { + case SERVER_ABILITIES -> { WPacketPlayOutAbilities packet = (WPacketPlayOutAbilities) packetObject; player.getInfo().getLastAbilities().reset(); player.runInstantAction(ia -> { - if(!ia.isEnd()) { + if (!ia.isEnd()) { player.getInfo().getPossibleCapabilities().add(packet.getCapabilities()); - } else if(player.getInfo().getPossibleCapabilities().size() > 1) { + } else if (player.getInfo().getPossibleCapabilities().size() > 1) { player.getInfo().getPossibleCapabilities().clear(); } }); - break; } - case FLYING: { + case FLYING -> { WPacketPlayInFlying packet = (WPacketPlayInFlying) packetObject; - if(player.getMovement().isExcuseNextFlying()) { + if (player.getMovement().isExcuseNextFlying()) { player.getMovement().setExcuseNextFlying(false); return false; } @@ -126,7 +124,7 @@ public class PacketHandler { player.getEntityLocationHandler().onFlying(); - if(player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_17) + if (player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_17) && packet.isMoved() && packet.isLooked() && MovementUtils.isSameLocation(new KLocation(packet.getX(), packet.getY(), packet.getZ()), player.getMovement().getTo().getLoc())) { @@ -134,33 +132,33 @@ public class PacketHandler { } player.getMovement().process(packet); - break; } - case BLOCK_CHANGE: { + case BLOCK_CHANGE -> { WPacketPlayOutBlockChange packet = (WPacketPlayOutBlockChange) packetObject; player.getBlockUpdateHandler().runUpdate(packet); - break; } - case MULTI_BLOCK_CHANGE: { + case MULTI_BLOCK_CHANGE -> { WPacketPlayOutMultiBlockChange packet = (WPacketPlayOutMultiBlockChange) packetObject; player.getBlockUpdateHandler().runUpdate(packet); - break; } - case MAP_CHUNK: { + case MAP_CHUNK -> { WPacketPlayOutMapChunk packet = (WPacketPlayOutMapChunk) packetObject; player.getBlockUpdateHandler().runUpdate(packet); - break; } - case ENTITY_EFFECT: { + case MAP_CHUNK_BULK -> { + WPacketPlayOutMapChunkBulk packet = (WPacketPlayOutMapChunkBulk) packetObject; + + player.getBlockUpdateHandler().runUpdate(packet); + } + case ENTITY_EFFECT -> { WPacketPlayOutEntityEffect packet = (WPacketPlayOutEntityEffect) packetObject; player.getPotionHandler().onPotionEffect(packet); - break; } - case EXPLOSION: { + case EXPLOSION -> { WPacketPlayOutExplosion packet = (WPacketPlayOutExplosion) packetObject; Vector velocity = packet.getEntityPush().toBukkitVector(); @@ -169,10 +167,10 @@ public class PacketHandler { player.getInfo().setDoingVelocity(true); player.runInstantAction(ka -> { - if(!ka.isEnd()) { + if (!ka.isEnd()) { player.getVelocityHandler().onPre(packet); } else player.getVelocityHandler().onPost(packet); - if(ka.isEnd() && player.getInfo().getVelocityHistory().contains(velocity)) { + if (ka.isEnd() && player.getInfo().getVelocityHistory().contains(velocity)) { player.getInfo().setDoingVelocity(false); player.getInfo().getVelocity().reset(); synchronized (player.getInfo().getVelocityHistory()) { @@ -181,24 +179,23 @@ public class PacketHandler { } }); player.runKeepaliveAction(ka -> { - if(player.getInfo().getVelocityHistory().contains(velocity)) + if (player.getInfo().getVelocityHistory().contains(velocity)) player.getOnVelocityTasks().forEach(task -> task.accept(velocity)); }, 1); - break; } - case VELOCITY: { + case VELOCITY -> { WPacketPlayOutEntityVelocity packet = (WPacketPlayOutEntityVelocity) packetObject; - if(packet.getEntityId() == player.getBukkitPlayer().getEntityId()) { + if (packet.getEntityId() == player.getBukkitPlayer().getEntityId()) { Vector velocity = new Vector(packet.getDeltaX(), packet.getDeltaY(), packet.getDeltaZ()); player.getInfo().getVelocityHistory().add(velocity); player.getInfo().setDoingVelocity(true); player.runInstantAction(ka -> { - if(!ka.isEnd()) { + if (!ka.isEnd()) { player.getVelocityHandler().onPre(packet); } else player.getVelocityHandler().onPost(packet); - if(ka.isEnd() && player.getInfo().getVelocityHistory().contains(velocity)) { + if (ka.isEnd() && player.getInfo().getVelocityHistory().contains(velocity)) { player.getInfo().setDoingVelocity(false); player.getInfo().getVelocity().reset(); synchronized (player.getInfo().getVelocityHistory()) { @@ -207,50 +204,43 @@ public class PacketHandler { } }); player.runKeepaliveAction(ka -> { - if(player.getInfo().getVelocityHistory().contains(velocity)) + if (player.getInfo().getVelocityHistory().contains(velocity)) player.getOnVelocityTasks().forEach(task -> task.accept(velocity)); }, 1); } - break; } - case RESPAWN: { - if(player.getPlayerVersion().isBelow(ProtocolVersion.V1_14)) { + case RESPAWN -> { + if (player.getPlayerVersion().isBelow(ProtocolVersion.V1_14)) { player.runKeepaliveAction(k -> player.getBukkitPlayer().setSprinting(false), 1); } player.runKeepaliveAction(ka -> player.getInfo().lastRespawn.reset()); - break; } - case SERVER_POSITION: { - player.getMovement().addPosition((WPacketPlayOutPosition) packetObject); - break; - } - case ATTACH: { + case SERVER_POSITION -> player.getMovement().addPosition((WPacketPlayOutPosition) packetObject); + case ATTACH -> { WPacketPlayOutAttachEntity packet = (WPacketPlayOutAttachEntity) packetObject; - if(packet.getHoldingEntityId() != -1) { + if (packet.getHoldingEntityId() != -1) { player.getInfo().setInVehicle(true); player.getInfo().getVehicleSwitch().reset(); } else { player.getInfo().setInVehicle(false); player.getInfo().getVehicleSwitch().reset(); } - break; } - case STEER_VEHICLE: { + case STEER_VEHICLE -> { PacketPlayInSteerVehicle packet = (PacketPlayInSteerVehicle) packetObject; // Check for isUnmount() - if(player.getBukkitPlayer().isInsideVehicle() && packet.d()) { + if (player.getBukkitPlayer().isInsideVehicle() && packet.d()) { player.getInfo().getVehicleSwitch().reset(); player.getInfo().setInVehicle(false); } - break; } - case CLIENT_PAYLOAD: { + case CLIENT_PAYLOAD -> { PacketPlayInCustomPayload packet = (PacketPlayInCustomPayload) packetObject; - if(packet.a().equals("Time|Receive")) { + if (packet.a().equals("Time|Receive")) { PacketDataSerializer serial = packet.b(); long serverTime = serial.readLong(); @@ -263,15 +253,13 @@ public class PacketHandler { player.getBukkitPlayer().sendMessage(String.format("total: %sms client-server: %sms server-client: %sms", totalFeedback, clientToServer, serverPing)); } - break; } - case ENTITY_DESTROY: { + case ENTITY_DESTROY -> { WPacketPlayOutEntityDestroy packet = (WPacketPlayOutEntityDestroy) packetObject; player.getEntityLocationHandler().onEntityDestroy(packet); - break; } - case ENTITY_ACTION: { + case ENTITY_ACTION -> { WPacketPlayInEntityAction packet = (WPacketPlayInEntityAction) packetObject; switch (packet.getAction()) { @@ -292,43 +280,37 @@ public class PacketHandler { break; } } - break; } - case ENTITY_TELEPORT: { + case ENTITY_TELEPORT -> { WPacketPlayOutEntityTeleport packet = (WPacketPlayOutEntityTeleport) packetObject; player.getEntityLocationHandler().onTeleportSent(packet); - break; } - case ENTITY: - case ENTITY_MOVE: - case ENTITY_LOOK: - case ENTITY_MOVELOOK: { + case ENTITY, ENTITY_MOVE, ENTITY_LOOK, ENTITY_MOVELOOK -> { WPacketPlayOutEntity packet = (WPacketPlayOutEntity) packetObject; player.getEntityLocationHandler().onRelPosition(packet); - break; } - case USE_ENTITY: { + case USE_ENTITY -> { WPacketPlayInUseEntity packet = (WPacketPlayInUseEntity) packetObject; FakeMob mob = Anticheat.INSTANCE.getFakeTracker().getEntityById(packet.getEntityId()); - if(packet.getAction() == WPacketPlayInUseEntity.EnumEntityUseAction.ATTACK) { - if(mob != null) { + if (packet.getAction() == WPacketPlayInUseEntity.EnumEntityUseAction.ATTACK) { + if (mob != null) { player.getEntityLocationHandler().getTargetOfFakeMob(mob.getEntityId()) .ifPresent(targetId -> { player.getEntityLocationHandler().removeFakeMob(targetId); player.getInfo().lastFakeBotHit.reset(); }); - if(player.getMob().getEntityId() == packet.getEntityId()) { + if (player.getMob().getEntityId() == packet.getEntityId()) { player.getInfo().botAttack.reset(); } } else { Entity target = packet.getEntity(player.getBukkitPlayer().getWorld()); - if(target instanceof LivingEntity) { - if(player.getInfo().lastFakeBotHit.isPassed(400) && Math.random() > 0.9) { + if (target instanceof LivingEntity) { + if (player.getInfo().lastFakeBotHit.isPassed(400) && Math.random() > 0.9) { player.getEntityLocationHandler().canCreateMob.add(target.getEntityId()); } player.getInfo().setTarget((LivingEntity) target); @@ -336,16 +318,14 @@ public class PacketHandler { } player.getInfo().lastAttack.reset(); } - break; } - case ARM_ANIMATION: { + case ARM_ANIMATION -> { long delta = timestamp - player.getInfo().lastArmSwing; player.getInfo().cps.add(1000D / delta, timestamp); player.getInfo().lastArmSwing = timestamp; - break; } - case BLOCK_PLACE: { + case BLOCK_PLACE -> { WPacketPlayInBlockPlace packet = (WPacketPlayInBlockPlace) packetObject; IntVector pos = packet.getBlockPos(); @@ -354,48 +334,36 @@ public class PacketHandler { player.getInfo().getLastBlockPlace().reset(); // Used item - if(pos.getX() == -1 && (pos.getY() == 255 | pos.getY() == -1) && pos.getZ() == -1 + if (pos.getX() == -1 && (pos.getY() == 255 | pos.getY() == -1) && pos.getZ() == -1 && stack != null && BlockUtils.isUsable(stack.getType())) { player.getInfo().getLastUseItem().reset(); } player.getBlockUpdateHandler().onPlace(packet); - break; } - case BLOCK_DIG: { + case BLOCK_DIG -> { WPacketPlayInBlockDig packet = (WPacketPlayInBlockDig) packetObject; player.getInfo().getLastBlockDig().reset(); player.getBlockUpdateHandler().onDig(packet); - break; } - case CLIENT_COMMAND: { + case CLIENT_COMMAND -> { WPacketPlayInClientCommand packet = (WPacketPlayInClientCommand) packetObject; - if(packet.getCommand() == WPacketPlayInClientCommand.WrappedEnumClientCommand + if (packet.getCommand() == WPacketPlayInClientCommand.WrappedEnumClientCommand .OPEN_INVENTORY_ACHIEVEMENT) { player.getInfo().setInventoryOpen(true); player.getInfo().lastInventoryOpen.reset(); return true; } - break; - } - case CLIENT_CLOSE_WINDOW: { - player.getInfo().setInventoryOpen(false); - break; - } - case SERVER_CLOSE_WINDOW: { - player.runKeepaliveAction(ka -> player.getInfo().setInventoryOpen(false)); - break; - } - case SERVER_OPEN_WINDOW: { - player.runKeepaliveAction(ka -> { - player.getInfo().setInventoryOpen(true); - player.getInfo().lastInventoryOpen.reset(); - }); - break; } + case CLIENT_CLOSE_WINDOW -> player.getInfo().setInventoryOpen(false); + case SERVER_CLOSE_WINDOW -> player.runKeepaliveAction(ka -> player.getInfo().setInventoryOpen(false)); + case SERVER_OPEN_WINDOW -> player.runKeepaliveAction(ka -> { + player.getInfo().setInventoryOpen(true); + player.getInfo().lastInventoryOpen.reset(); + }); } if(player.sniffing) { diff --git a/Anticheat/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java b/Anticheat/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java index e4f15e6..dd2c8e0 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java +++ b/Anticheat/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java @@ -5,11 +5,9 @@ import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockDig; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockPlace; import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutBlockChange; import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutMapChunk; +import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutMapChunkBulk; import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutMultiBlockChange; -import dev.brighten.ac.utils.BlockUtils; -import dev.brighten.ac.utils.LongHash; -import dev.brighten.ac.utils.Materials; -import dev.brighten.ac.utils.XMaterial; +import dev.brighten.ac.utils.*; import dev.brighten.ac.utils.math.IntVector; import dev.brighten.ac.utils.world.types.RayCollision; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; @@ -225,6 +223,27 @@ public class BlockUpdateHandler { }); } + public void runUpdate(WPacketPlayOutMapChunkBulk chunkBulk) { + player.runInstantAction(k -> { + RunUtils.task(() -> { + if(!k.isEnd()) { + for (WPacketPlayOutMapChunk.WrappedChunk chunkUpdate : chunkBulk.getChunks()) { + Chunk chunk = getChunk(chunkUpdate.getX(), chunkUpdate.getZ()); + var entrySet = chunkUpdate.getBlocks().entrySet(); + (entrySet.size() > 1000 ? entrySet.parallelStream() : entrySet.stream()).forEach(entry -> { + IntVector vec = entry.getKey(); + WPacketPlayOutMapChunk.MinBlock mblock = entry.getValue(); + WrappedBlock block = new WrappedBlock(vec.toLocation(player.getBukkitPlayer().getWorld()), + mblock.material, mblock.data); + + chunk.updateBlock(vec, block); + }); + } + } + }); + }); + } + /** * Get the block relative to the specified location * @param location the location diff --git a/Anticheat/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java b/Anticheat/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java index ca6cdd6..6f68ddd 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java +++ b/Anticheat/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java @@ -15,6 +15,8 @@ import dev.brighten.ac.utils.reflections.types.WrappedClass; import dev.brighten.ac.utils.reflections.types.WrappedField; import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import lombok.AllArgsConstructor; +import lombok.Getter; import lombok.SneakyThrows; import lombok.val; import me.hydro.emulator.util.mcp.MathHelper; @@ -30,6 +32,7 @@ import org.bukkit.util.Vector; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -769,7 +772,7 @@ public class Processor_18 implements PacketConverter { @Override public Object createMapChunk(Chunk chunk) { - return new PacketPlayOutMapChunk(((CraftChunk)chunk).getHandle(), true, 20); + return new PacketPlayOutMapChunk(((CraftChunk) chunk).getHandle(), true, 20); } @Override @@ -781,24 +784,44 @@ public class Processor_18 implements PacketConverter { int size = serialized.e(); final List chunks = new ArrayList<>(); + final ChunkInfo[] chunkInfos = new ChunkInfo[size]; + for (int i = 0; i < size; ++i) { int chunkX = serialized.readInt(); int chunkZ = serialized.readInt(); + PacketPlayOutMapChunk.ChunkMap chunkMap = new PacketPlayOutMapChunk.ChunkMap(); chunkMap.b = serialized.readShort() & '\uffff'; chunkMap.a = new byte[a(Integer.bitCount(chunkMap.b), groundUp)]; - Map blocks = new Object2ObjectOpenHashMap<>(chunkMap.a.length); + chunkInfos[i] = new ChunkInfo(chunkX, chunkZ, chunkMap); + } + + for (ChunkInfo chunkInfo : chunkInfos) { + serialized.readBytes(chunkInfo.getMap().a); + + var chunkMap = chunkInfo.getMap(); + int chunkX = chunkInfo.getX(); + int chunkZ = chunkInfo.getZ(); + + Map blocks = new HashMap<>(chunkMap.a.length); processChunk(chunkMap.a, chunkMap.b, chunkX, chunkZ, groundUp, blocks); - chunks.add(new WPacketPlayOutMapChunk.WrappedChunk(chunkX, chunkZ, blocks)); } + return new WPacketPlayOutMapChunkBulk(chunks); } + @AllArgsConstructor + @Getter + private static class ChunkInfo { + private int x, z; + private PacketPlayOutMapChunk.ChunkMap map; + } + @Override public WPacketPlayInClientCommand processInClientCommand(Object packet) { PacketPlayInClientCommand clientCommand = (PacketPlayInClientCommand) packet; diff --git a/Compat/src/main/java/dev/brighten/ac/utils/reflections/impl/CraftReflection.java b/Compat/src/main/java/dev/brighten/ac/utils/reflections/impl/CraftReflection.java index 5f3e838..fe0dc50 100644 --- a/Compat/src/main/java/dev/brighten/ac/utils/reflections/impl/CraftReflection.java +++ b/Compat/src/main/java/dev/brighten/ac/utils/reflections/impl/CraftReflection.java @@ -2,6 +2,7 @@ package dev.brighten.ac.utils.reflections.impl; 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.WrappedMethod; import dev.brighten.ac.packet.ProtocolVersion; import org.bukkit.Bukkit; @@ -42,6 +43,9 @@ public class CraftReflection { private static final WrappedMethod methodGetBlockFromMaterial = ProtocolVersion.getGameVersion() .isOrAbove(ProtocolVersion.V1_13) ? craftMagicNumbers.getMethod("getBlock", Material.class) : craftMagicNumbers.getMethod("getBlock", int.class); + + private static final WrappedConstructor getBlockFromChunk = craftBlock + .getConstructor(craftChunk.getParent(), int.class, int.class, int.class); private static WrappedMethod fromComponent; public static T getVanillaItemStack(ItemStack stack) { @@ -97,6 +101,10 @@ public class CraftReflection { return fromComponent.invoke(null, ichatcomp); } + public static Block getBlockFromChunk(Chunk chunk, int x, int y, int z) { + return getBlockFromChunk.newInstance(chunk, x, y, z); + } + static { if(ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_8)) { fromComponent = craftChatMessage.getMethod("fromComponent",