From 7d287686630ae0ade924b8d2ba67c441b3c42881 Mon Sep 17 00:00:00 2001 From: SamB440 Date: Thu, 30 May 2024 15:03:12 +0100 Subject: [PATCH] Implement experimental 1.21 update features --- .../impl/velocity/ExplosionHandler.java | 36 +++++++++++++++++-- .../blocks/connecting/DynamicWall.java | 1 - .../utils/latency/CompensatedWorld.java | 14 ++++---- .../grimac/utils/nmsutil/BoundingBoxSize.java | 11 +++++- .../grim/grimac/utils/nmsutil/Materials.java | 3 +- 5 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/main/java/ac/grim/grimac/checks/impl/velocity/ExplosionHandler.java b/src/main/java/ac/grim/grimac/checks/impl/velocity/ExplosionHandler.java index 497eff567f..a8fd77c317 100644 --- a/src/main/java/ac/grim/grimac/checks/impl/velocity/ExplosionHandler.java +++ b/src/main/java/ac/grim/grimac/checks/impl/velocity/ExplosionHandler.java @@ -9,12 +9,18 @@ import ac.grim.grimac.utils.data.VelocityData; import com.github.retrooper.packetevents.event.PacketSendEvent; import com.github.retrooper.packetevents.protocol.packettype.PacketType; +import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; +import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags; +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.protocol.world.states.type.StateValue; import com.github.retrooper.packetevents.util.Vector3f; import com.github.retrooper.packetevents.util.Vector3i; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerExplosion; import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.util.Vector; +import org.jetbrains.annotations.Nullable; import java.util.Deque; import java.util.LinkedList; @@ -43,12 +49,36 @@ public void onPacketSend(final PacketSendEvent event) { Vector3f velocity = explosion.getPlayerMotion(); - if (!explosion.getRecords().isEmpty()) { + final @Nullable WrapperPlayServerExplosion.BlockInteraction blockInteraction = explosion.getBlockInteraction(); + final boolean shouldDestroy = blockInteraction != WrapperPlayServerExplosion.BlockInteraction.KEEP_BLOCKS; + Bukkit.broadcastMessage("should destroy? " + shouldDestroy + ", type: " + blockInteraction); + if (!explosion.getRecords().isEmpty() && shouldDestroy) { player.sendTransaction(); player.latencyUtils.addRealTimeTask(player.lastTransactionSent.get(), () -> { - for (Vector3i records : explosion.getRecords()) { - player.compensatedWorld.updateBlock(records.x, records.y, records.z, 0); + for (Vector3i record : explosion.getRecords()) { + // Null OR not flip redstone blocks, then set to air + if (blockInteraction != WrapperPlayServerExplosion.BlockInteraction.TRIGGER_BLOCKS) { + player.compensatedWorld.updateBlock(record.x, record.y, record.z, 0); + } else { + // We need to flip redstone blocks, or do special things with other blocks + final WrappedBlockState state = player.compensatedWorld.getWrappedBlockStateAt(record); + final StateType type = state.getType(); + if (BlockTags.CANDLES.contains(type) || BlockTags.CANDLE_CAKES.contains(type)) { + state.setLit(false); + continue; + } else if (type == StateTypes.BELL) { + // Does this affect anything? I don't know, I don't see anything that relies on whether a bell is ringing. + continue; + } + + // Otherwise try and flip/open it. + final Object poweredValue = state.getInternalData().get(StateValue.POWERED); + final boolean canFlip = (poweredValue != null && !(Boolean) poweredValue) || type == StateTypes.LEVER; + if (canFlip) { + player.compensatedWorld.tickOpenable(record.x, record.y, record.z); + } + } } }); } diff --git a/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicWall.java b/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicWall.java index 097522b253..75b3ae6263 100644 --- a/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicWall.java +++ b/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicWall.java @@ -14,7 +14,6 @@ import com.github.retrooper.packetevents.protocol.world.states.enums.South; import com.github.retrooper.packetevents.protocol.world.states.enums.West; import com.github.retrooper.packetevents.protocol.world.states.type.StateType; -import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes; public class DynamicWall extends DynamicConnecting implements CollisionFactory { public static final CollisionBox[] BOXES = makeShapes(4.0F, 3.0F, 16.0F, 0.0F, 16.0F, false); diff --git a/src/main/java/ac/grim/grimac/utils/latency/CompensatedWorld.java b/src/main/java/ac/grim/grimac/utils/latency/CompensatedWorld.java index 3c41645e91..c3a8944655 100644 --- a/src/main/java/ac/grim/grimac/utils/latency/CompensatedWorld.java +++ b/src/main/java/ac/grim/grimac/utils/latency/CompensatedWorld.java @@ -20,7 +20,6 @@ import com.github.retrooper.packetevents.netty.channel.ChannelHelper; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; import com.github.retrooper.packetevents.protocol.nbt.NBTCompound; -import com.github.retrooper.packetevents.protocol.nbt.NBTString; import com.github.retrooper.packetevents.protocol.player.ClientVersion; import com.github.retrooper.packetevents.protocol.player.DiggingAction; import com.github.retrooper.packetevents.protocol.player.User; @@ -293,9 +292,9 @@ public void updateBlock(int x, int y, int z, int combinedID) { } public void tickOpenable(int blockX, int blockY, int blockZ) { - WrappedBlockState data = player.compensatedWorld.getWrappedBlockStateAt(blockX, blockY, blockZ); - - if (BlockTags.WOODEN_DOORS.contains(data.getType()) || (player.getClientVersion().isOlderThan(ClientVersion.V_1_8) && data.getType() == StateTypes.IRON_DOOR)) { + final WrappedBlockState data = player.compensatedWorld.getWrappedBlockStateAt(blockX, blockY, blockZ); + final StateType type = data.getType(); + if (BlockTags.WOODEN_DOORS.contains(type) || (player.getClientVersion().isOlderThan(ClientVersion.V_1_8) && type == StateTypes.IRON_DOOR)) { WrappedBlockState otherDoor = player.compensatedWorld.getWrappedBlockStateAt(blockX, blockY + (data.getHalf() == Half.LOWER ? 1 : -1), blockZ); @@ -317,12 +316,13 @@ public void tickOpenable(int blockX, int blockY, int blockZ) { player.compensatedWorld.updateBlock(blockX, blockY - 1, blockZ, otherDoor.getGlobalId()); } } - } else if (BlockTags.WOODEN_TRAPDOORS.contains(data.getType()) || BlockTags.FENCE_GATES.contains(data.getType()) - || (player.getClientVersion().isOlderThan(ClientVersion.V_1_8) && data.getType() == StateTypes.IRON_TRAPDOOR)) { + } else if ((player.getClientVersion().isOlderThan(ClientVersion.V_1_8) || type != StateTypes.IRON_TRAPDOOR) // 1.7 can open iron trapdoors. + && BlockTags.TRAPDOORS.contains(type) + || BlockTags.FENCE_GATES.contains(type)) { // Take 12 most significant bytes -> the material ID. Combine them with the new block magic data. data.setOpen(!data.isOpen()); player.compensatedWorld.updateBlock(blockX, blockY, blockZ, data.getGlobalId()); - } else if (BlockTags.BUTTONS.contains(data.getType())) { + } else if (BlockTags.BUTTONS.contains(type)) { data.setPowered(true); } } diff --git a/src/main/java/ac/grim/grimac/utils/nmsutil/BoundingBoxSize.java b/src/main/java/ac/grim/grimac/utils/nmsutil/BoundingBoxSize.java index 464b3a5745..ed422392de 100644 --- a/src/main/java/ac/grim/grimac/utils/nmsutil/BoundingBoxSize.java +++ b/src/main/java/ac/grim/grimac/utils/nmsutil/BoundingBoxSize.java @@ -18,7 +18,8 @@ * I could PR a ton of classes in order to accomplish it but then no one would use it * (And even if they did they would likely be breaking my license...) */ -public class BoundingBoxSize { +public final class BoundingBoxSize { + public static float getWidth(GrimPlayer player, PacketEntity packetEntity) { // Turtles are the only baby animal that don't follow the * 0.5 rule if (packetEntity.getType() == EntityTypes.TURTLE && packetEntity.isBaby) return 0.36f; @@ -111,6 +112,8 @@ private static float getWidthMinusBaby(GrimPlayer player, PacketEntity packetEnt return 1.9f; } else if (EntityTypes.CAMEL.equals(type)) { return 1.7f; + } else if (EntityTypes.WIND_CHARGE.equals(type)) { + return 0.3125F; } return 0.6f; } @@ -363,6 +366,12 @@ private static float getHeightMinusBaby(GrimPlayer player, PacketEntity packetEn return 1.75f; } else if (EntityTypes.CAMEL.equals(type)) { return 2.375f; + } else if (EntityTypes.BREEZE.equals(type)) { + return 1.77F; + } else if (EntityTypes.BOGGED.equals(type)) { + return 1.99F; + } else if (EntityTypes.WIND_CHARGE.equals(type)) { + return 0.3125F; } return 1.95f; } diff --git a/src/main/java/ac/grim/grimac/utils/nmsutil/Materials.java b/src/main/java/ac/grim/grimac/utils/nmsutil/Materials.java index efdf29a359..f9c000b642 100644 --- a/src/main/java/ac/grim/grimac/utils/nmsutil/Materials.java +++ b/src/main/java/ac/grim/grimac/utils/nmsutil/Materials.java @@ -13,6 +13,7 @@ import java.util.HashSet; import java.util.Set; +import java.util.stream.Collectors; public class Materials { private static final Set NO_PLACE_LIQUIDS = new HashSet<>(); @@ -88,7 +89,7 @@ public class Materials { CLIENT_SIDE.addAll(BlockTags.SHULKER_BOXES.getStates()); CLIENT_SIDE.addAll(BlockTags.SIGNS.getStates()); CLIENT_SIDE.addAll(BlockTags.FLOWER_POTS.getStates()); - CLIENT_SIDE.addAll(BlockTags.WOODEN_TRAPDOORS.getStates()); + CLIENT_SIDE.addAll(BlockTags.TRAPDOORS.getStates().stream().filter(type -> type != StateTypes.IRON_TRAPDOOR).collect(Collectors.toSet())); CLIENT_SIDE.addAll(BlockTags.WOODEN_DOORS.getStates()); PANES.addAll(BlockTags.GLASS_PANES.getStates());