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 new file mode 100644 index 000000000..c90f515c0 --- /dev/null +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/listeners/multiversion/PlayerSneakListener.java @@ -0,0 +1,92 @@ +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 static final float STANDING_HEIGHT = 1.8F; + private static final float HEIGHT_1_14 = 1.5F; + private static final float HEIGHT_1_9 = 1.6F; + private static final float DEFAULT_WIDTH = 0.6F; + + 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, BukkitViaLoader viaLoader, boolean is1_9Fix, boolean is1_14Fix) { + super(plugin, null); + this.is1_9Fix = is1_9Fix; + this.is1_14Fix = is1_14Fix; + try { + getHandle = Class.forName(plugin.getServer().getClass().getPackage().getName() + ".entity.CraftPlayer").getMethod("getHandle"); + setSize = Class.forName(plugin.getServer().getClass().getPackage().getName() + .replace("org.bukkit.craftbukkit", "net.minecraft.server") + ".EntityPlayer").getMethod("setSize", Float.TYPE, Float.TYPE); + } catch (ClassNotFoundException | NoSuchMethodException 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()) { + setHeight(entry.getKey(), entry.getValue() ? HEIGHT_1_14 : HEIGHT_1_9); + } + } + }, 1, 1); + } + } + + @EventHandler(ignoreCancelled = true) + 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()) { + setHeight(player, event.isSneaking() ? HEIGHT_1_14 : STANDING_HEIGHT); + if (!useCache) return; + if (event.isSneaking()) + sneaking.put(player, true); + else + sneaking.remove(player); + } else if (is1_9Fix && protocolVersion >= ProtocolVersion.v1_9.getId()) { + setHeight(player, event.isSneaking() ? HEIGHT_1_9 : STANDING_HEIGHT); + if (!useCache) return; + if (event.isSneaking()) + sneaking.put(player, false); + else + sneaking.remove(player); + } + } + + private void setHeight(Player player, float height) { + try { + setSize.invoke(getHandle.invoke(player), DEFAULT_WIDTH, height); + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } +} diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java index 3ca1df78c..38679a6f7 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitViaConfig.java @@ -254,8 +254,19 @@ public class BukkitViaConfig extends Config implements ViaVersionConfig { public boolean isTruncate1_14Books() { return getBoolean("truncate-1_14-books", false); } - + + @Override public boolean isLeftHandedHandling() { return getBoolean("left-handed-handling", true); } + + @Override + public boolean is1_9HitboxFix() { + return getBoolean("change-1_9-hitbox", false); + } + + @Override + public boolean is1_14HitboxFix() { + return getBoolean("change-1_14-hitbox", false); + } } 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 5d17cc0c0..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 @@ -15,6 +15,7 @@ import us.myles.ViaVersion.api.protocol.ProtocolRegistry; import us.myles.ViaVersion.api.protocol.ProtocolVersion; import us.myles.ViaVersion.bukkit.classgenerator.ClassGenerator; import us.myles.ViaVersion.bukkit.listeners.UpdateListener; +import us.myles.ViaVersion.bukkit.listeners.multiversion.PlayerSneakListener; import us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8.*; import us.myles.ViaVersion.bukkit.providers.BukkitBlockConnectionProvider; import us.myles.ViaVersion.bukkit.providers.BukkitInventoryQuickMoveProvider; @@ -76,6 +77,13 @@ public class BukkitViaLoader implements ViaPlatformLoader { storeListener(new DeathListener(plugin)).register(); storeListener(new BlockListener(plugin)).register(); + 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, this, use1_9Fix, plugin.getConf().is1_14HitboxFix())).register(); + } + } + if ((Bukkit.getVersion().toLowerCase().contains("paper") || Bukkit.getVersion().toLowerCase().contains("taco") || Bukkit.getVersion().toLowerCase().contains("torch")) diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java index def2fd7f1..d77ff934d 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeViaConfig.java @@ -10,7 +10,7 @@ import java.net.URL; import java.util.*; public class BungeeViaConfig extends Config implements ViaVersionConfig { - private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", "blockconnection-method"); + private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", "blockconnection-method", "change-1_9-hitbox", "change-1_14-hitbox"); public BungeeViaConfig(File configFile) { super(new File(configFile, "config.yml")); @@ -307,8 +307,19 @@ public class BungeeViaConfig extends Config implements ViaVersionConfig { public boolean isTruncate1_14Books() { return getBoolean("truncate-1_14-books", false); } - + + @Override public boolean isLeftHandedHandling() { return getBoolean("left-handed-handling", true); } + + @Override + public boolean is1_9HitboxFix() { + return false; + } + + @Override + public boolean is1_14HitboxFix() { + return false; + } } diff --git a/common/src/main/java/us/myles/ViaVersion/api/ViaListener.java b/common/src/main/java/us/myles/ViaVersion/api/ViaListener.java index 243a00212..91212eaee 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/ViaListener.java +++ b/common/src/main/java/us/myles/ViaVersion/api/ViaListener.java @@ -33,7 +33,7 @@ public abstract class ViaListener { protected boolean isOnPipe(UUID uuid) { UserConnection userConnection = getUserConnection(uuid); return userConnection != null && - userConnection.get(ProtocolInfo.class).getPipeline().contains(requiredPipeline); + (requiredPipeline == null || userConnection.get(ProtocolInfo.class).getPipeline().contains(requiredPipeline)); } /** diff --git a/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java b/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java index 9e9e70801..d3b34cac4 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java +++ b/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java @@ -316,11 +316,25 @@ public interface ViaVersionConfig { * @return True if enabled */ boolean isTruncate1_14Books(); - + /** * Handles left handed info by using unused bit 7 on Client Settings packet * * @return True if enabled */ boolean isLeftHandedHandling(); + + /** + * Fixes velocity bugs due to different hitbox for 1.9-1.13 clients on 1.8 servers. + * + * @return True if enabled + */ + boolean is1_9HitboxFix(); + + /** + * Fixes velocity bugs due to different hitbox for 1.14+ clients on sub 1.14 servers. + * + * @return True if enabled + */ + boolean is1_14HitboxFix(); } diff --git a/common/src/main/resources/assets/viaversion/config.yml b/common/src/main/resources/assets/viaversion/config.yml index d56ca095c..61f309a4e 100644 --- a/common/src/main/resources/assets/viaversion/config.yml +++ b/common/src/main/resources/assets/viaversion/config.yml @@ -120,6 +120,12 @@ disable-1_13-auto-complete: false fix-low-snow-collision: false # In 1.14 the client page limit has been upped to 100 (from 50). Some anti-exploit plugins ban when clients go higher than 50. This option cuts edited books to 50 pages. truncate-1_14-books: false +# This prevents clients using 1.9-1.13 on 1.8 servers from receiving no knockback/having velocity bugs whilst sneaking under a block. +change-1_9-hitbox: false +# Similar to the above, but for 1.14+ players on 1.8-1.13 servers. +# WARNING: This gives 1.14+ players the ability to sneak under blocks, that players under that version cannot (sneaking in places that are only 1.5 blocks high)! +# Another thing to remember is that those players might be missed by projectiles and other hits directed at the very top of their head whilst sneaking. +change-1_14-hitbox: false # # Enable serverside block-connections for 1.13+ clients serverside-blockconnections: false diff --git a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java index b2691673c..dc1e1806e 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java +++ b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeViaConfig.java @@ -13,7 +13,7 @@ import java.util.Map; import java.util.Optional; public class SpongeViaConfig extends Config implements ViaVersionConfig { - private static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", "quick-move-action-fix"); + private static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", "quick-move-action-fix", "change-1_9-hitbox", "change-1_14-hitbox"); private final PluginContainer pluginContainer; public SpongeViaConfig(PluginContainer pluginContainer, File configFile) { @@ -260,8 +260,19 @@ public class SpongeViaConfig extends Config implements ViaVersionConfig { public boolean isTruncate1_14Books() { return getBoolean("truncate-1_14-books", false); } - + + @Override public boolean isLeftHandedHandling() { return getBoolean("left-handed-handling", true); } + + @Override + public boolean is1_9HitboxFix() { + return false; + } + + @Override + public boolean is1_14HitboxFix() { + return false; + } } diff --git a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java index 3dbac2ebc..1c86a21a9 100644 --- a/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java +++ b/velocity/src/main/java/us/myles/ViaVersion/velocity/platform/VelocityViaConfig.java @@ -9,7 +9,7 @@ import java.net.URL; import java.util.*; public class VelocityViaConfig extends Config implements ViaVersionConfig { - private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "blockconnection-method"); + private static List UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "bungee-ping-interval", "bungee-ping-save", "bungee-servers", "blockconnection-method", "change-1_9-hitbox", "change-1_14-hitbox"); public VelocityViaConfig(File configFile) { super(new File(configFile, "config.yml")); @@ -312,8 +312,20 @@ public class VelocityViaConfig extends Config implements ViaVersionConfig { public boolean isTruncate1_14Books() { return getBoolean("truncate-1_14-books", false); } - + + @Override public boolean isLeftHandedHandling() { return getBoolean("left-handed-handling", true); } + + + @Override + public boolean is1_9HitboxFix() { + return false; + } + + @Override + public boolean is1_14HitboxFix() { + return false; + } }