diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java index a3ca2a66..b8c53630 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/smartplace/SmartPlaceListener.java @@ -24,10 +24,8 @@ import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.bausystem.BauSystem; import de.steamwar.bausystem.configplayer.Config; import de.steamwar.linkage.Linked; -import org.bukkit.Bukkit; -import org.bukkit.GameMode; -import org.bukkit.Material; -import org.bukkit.World; +import de.steamwar.linkage.api.Plain; +import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; @@ -40,7 +38,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerQuitEvent; import java.util.HashSet; import java.util.List; @@ -48,11 +45,10 @@ import java.util.Set; import java.util.stream.Collectors; @Linked -public class SmartPlaceListener implements Listener { - - // TODO: Sneaking not reset sometimes +public class SmartPlaceListener implements Plain, Listener { private static final Set CONTAINERS = new HashSet<>(); + private static final Set IGNORED = new HashSet<>(); static { World world = Bukkit.getWorlds().get(0); @@ -71,39 +67,43 @@ public class SmartPlaceListener implements Listener { } CONTAINERS.add(Material.GRINDSTONE); state.update(true, false); + + IGNORED.add(Material.TNT); + IGNORED.add(Material.REDSTONE_ORE); } private static final Class useItem = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseItem"); + private static final Class entityPlayer = Reflection.getClass("{nms.server.level}.EntityPlayer"); + private static final Class craftPlayer = Reflection.getClass("{obc}.entity.CraftPlayer"); + private static final Reflection.MethodInvoker getHandle = Reflection.getTypedMethod(craftPlayer, "getHandle", entityPlayer); + private static final Class playerConnectionClazz = Reflection.getClass("{nms.server.network}.PlayerConnection"); + private static final Reflection.FieldAccessor playerConnection = Reflection.getField(entityPlayer, playerConnectionClazz, 0); + private static final Reflection.MethodInvoker packetExecutor = Reflection.getMethod(playerConnectionClazz, null, useItem); + private static final Set SMART_PLACING = new HashSet<>(); public SmartPlaceListener() { TinyProtocol.instance.addFilter(useItem, (player, object) -> { - if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) { - return object; - } + if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) return object; - Block block = player.getTargetBlockExact(6); - if (block != null && (block.getType().isInteractable() || block.getType() == Material.NOTE_BLOCK) && !CONTAINERS.contains(block.getType())) { - return object; - } - - boolean isSneaking = player.isSneaking(); - if (isSneaking) { - SMART_PLACING.add(player); - } - if (!isSneaking) { - player.setSneaking(true); - } Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> { - player.setSneaking(isSneaking); + Block block = player.getTargetBlockExact(6); + boolean shouldSneak = !(block != null && (block.getType().isInteractable() || block.getType() == Material.NOTE_BLOCK) && !CONTAINERS.contains(block.getType()) && !IGNORED.contains(block.getType())); + + boolean sneaking = player.isSneaking(); + if (sneaking) SMART_PLACING.add(player); + player.setSneaking(shouldSneak || sneaking); + packetExecutor.invoke(playerConnection.get(getHandle.invoke(player)), object); SMART_PLACING.remove(player); + player.setSneaking(sneaking); }, 0); - return object; + return null; }); } @EventHandler public void onPlayerInteract(PlayerInteractEvent event) { + if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return; if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) return; if (!event.getPlayer().isSneaking()) return; @@ -120,7 +120,14 @@ public class SmartPlaceListener implements Listener { @EventHandler public void onBlockPlace(BlockPlaceEvent event) { - if (!SMART_PLACING.contains(event.getPlayer())) return; + if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("smartPlace", false)) return; + if (!SMART_PLACING.contains(event.getPlayer())) { + if (CONTAINERS.contains(event.getBlockAgainst().getType())) { + SoundGroup soundGroup = event.getBlockPlaced().getBlockData().getSoundGroup(); + event.getPlayer().playSound(event.getBlockPlaced().getLocation(), soundGroup.getPlaceSound(), soundGroup.getVolume() * 0.8F, soundGroup.getPitch() * 0.8F); + } + return; + } BlockData blockData = event.getBlock().getBlockData(); if (blockData instanceof Bed) { Bed bed = (Bed) blockData; @@ -194,9 +201,4 @@ public class SmartPlaceListener implements Listener { } event.getBlock().setBlockData(blockData, true); } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - SMART_PLACING.remove(event.getPlayer()); - } }