diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/multiversion/PlayerSneakListener.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/multiversion/PlayerSneakListener.java index f33f72c0c..0cc8f72f5 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/multiversion/PlayerSneakListener.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/multiversion/PlayerSneakListener.java @@ -2,22 +2,29 @@ package us.myles.ViaVersion.bukkit.listeners.multiversion; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerToggleSneakEvent; import us.myles.ViaVersion.ViaVersionPlugin; +import us.myles.ViaVersion.api.protocol.ProtocolRegistry; import us.myles.ViaVersion.api.protocol.ProtocolVersion; import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener; +import us.myles.ViaVersion.bukkit.platform.BukkitViaLoader; import us.myles.ViaVersion.protocols.base.ProtocolInfo; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; public class PlayerSneakListener extends ViaBukkitListener { + private Map sneaking; // true = 1.14+, else false private Method getHandle; private Method setSize; private boolean is1_9Fix; private boolean is1_14Fix; + private boolean useCache; - public PlayerSneakListener(ViaVersionPlugin plugin, boolean is1_9Fix, boolean is1_14Fix) { + public PlayerSneakListener(ViaVersionPlugin plugin, BukkitViaLoader viaLoader, boolean is1_9Fix, boolean is1_14Fix) { super(plugin, null); this.is1_9Fix = is1_9Fix; this.is1_14Fix = is1_14Fix; @@ -28,38 +35,45 @@ public class PlayerSneakListener extends ViaBukkitListener { } catch (ClassNotFoundException | NoSuchMethodException e) { e.printStackTrace(); } - - getPlugin().getServer().getScheduler().runTaskTimer(getPlugin(), new Runnable() { - @Override - public void run() { - for (Player onlinePlayer : getPlugin().getServer().getOnlinePlayers()) { - try { - final Object handle = getHandle.invoke(onlinePlayer); - final Class aClass = Class.forName(getPlugin().getServer().getClass().getPackage().getName() - .replace("org.bukkit.craftbukkit", "net.minecraft.server") + ".EntityPlayer"); - System.out.println(aClass.getField("length").get(handle)); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (NoSuchFieldException e) { - e.printStackTrace(); + // From 1.9 upwards the server hitbox is set in every entity tick, so we have to reset it everytime + if (ProtocolRegistry.SERVER_PROTOCOL >= ProtocolVersion.v1_9.getId()) { + sneaking = new HashMap<>(); + useCache = true; + viaLoader.storeListener(new ViaBukkitListener(plugin, null) { + @EventHandler + public void playerQuit(PlayerQuitEvent event) { + sneaking.remove(event.getPlayer()); + } + }).register(); + plugin.getServer().getScheduler().runTaskTimer(plugin, new Runnable() { + @Override + public void run() { + for (Map.Entry entry : sneaking.entrySet()) { + setHight(entry.getKey(), entry.getValue() ? 1.5F : 1.6F); } } - } - }, 1, 1); + }, 1, 1); + } } @EventHandler(ignoreCancelled = true) - public void playerToggleSneak(final PlayerToggleSneakEvent event) { - final Player player = event.getPlayer(); - final int protocolVersion = getUserConnection(player).get(ProtocolInfo.class).getProtocolVersion(); + public void playerToggleSneak(PlayerToggleSneakEvent event) { + Player player = event.getPlayer(); + int protocolVersion = getUserConnection(player).get(ProtocolInfo.class).getProtocolVersion(); if (is1_14Fix && protocolVersion >= ProtocolVersion.v1_14.getId()) { setHight(player, event.isSneaking() ? 1.5F : 1.8F); + if (!useCache) return; + if (event.isSneaking()) + sneaking.put(player, true); + else + sneaking.remove(player); } else if (is1_9Fix && protocolVersion >= ProtocolVersion.v1_9.getId()) { setHight(player, event.isSneaking() ? 1.6F : 1.8F); + if (!useCache) return; + if (event.isSneaking()) + sneaking.put(player, false); + else + sneaking.remove(player); } } diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java index ce4666483..197b2be80 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaLoader.java @@ -80,7 +80,7 @@ public class BukkitViaLoader implements ViaPlatformLoader { if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_14.getId()) { boolean use1_9Fix = plugin.getConf().is1_9HitboxFix() && ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getId(); if (use1_9Fix || plugin.getConf().is1_14HitboxFix()) { - storeListener(new PlayerSneakListener(plugin, use1_9Fix, plugin.getConf().is1_14HitboxFix())).register(); + storeListener(new PlayerSneakListener(plugin, this, use1_9Fix, plugin.getConf().is1_14HitboxFix())).register(); } }