Fix elytra emulation not working on 1.9.0 servers

This commit is contained in:
FlorianMichael 2024-04-29 13:59:11 +02:00
parent 4d2505d9ee
commit 8db6375a8e
No known key found for this signature in database
GPG Key ID: C2FB87E71C425126
3 changed files with 37 additions and 5 deletions

View File

@ -18,6 +18,9 @@
package com.viaversion.viarewind.legacysupport.feature; package com.viaversion.viarewind.legacysupport.feature;
import com.viaversion.viarewind.legacysupport.BukkitPlugin;
import com.viaversion.viarewind.legacysupport.util.NMSUtil;
import com.viaversion.viarewind.legacysupport.util.ReflectionUtil;
import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -27,9 +30,27 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.lang.reflect.Method;
import java.util.logging.Level;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class ElytraVelocityEmulator implements Listener { public class ElytraVelocityEmulator implements Listener {
private boolean isGliding(final ProtocolVersion version, final Player player) {
if (version.olderThanOrEqualTo(ProtocolVersion.v1_9_1)) {
final Object nmsPlayer = NMSUtil.getNMSPlayer(player);
if (nmsPlayer == null) return false;
try {
final Method getFlag = ReflectionUtil.getMethod(nmsPlayer.getClass(), "getFlag", int.class);
return (boolean) getFlag.invoke(nmsPlayer, 7);
} catch (Exception e) {
BukkitPlugin.getInstance().getLogger().log(Level.SEVERE, "Failed to get player flag", e);
}
}
return player.isGliding();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerMove(PlayerMoveEvent e) { public void onPlayerMove(PlayerMoveEvent e) {
final Player player = e.getPlayer(); final Player player = e.getPlayer();
@ -37,7 +58,10 @@ public class ElytraVelocityEmulator implements Listener {
if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_9)) { if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_9)) {
return; // Only apply for 1.8 and below players return; // Only apply for 1.8 and below players
} }
if (!player.isGliding()) return; // Only apply if the player is gliding final ProtocolVersion serverVersion = BukkitPlugin.getInstance().getServerProtocol();
if (!isGliding(serverVersion, player)) {
return; // Only apply if the player is gliding
}
final Vector direction = player.getLocation().getDirection(); final Vector direction = player.getLocation().getDirection();
final Vector velocity = player.getVelocity(); final Vector velocity = player.getVelocity();

View File

@ -86,12 +86,18 @@ public class NMSUtil {
} }
} }
public static void sendPacket(final Player player, final Object packet) { public static Object getNMSPlayer(final Player player) {
Object nmsPlayer;
try { try {
nmsPlayer = player.getClass().getMethod("getHandle").invoke(player); return player.getClass().getMethod("getHandle").invoke(player);
} catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) { } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
BukkitPlugin.getInstance().getLogger().log(Level.SEVERE, "Failed to get EntityPlayer from player", e); BukkitPlugin.getInstance().getLogger().log(Level.SEVERE, "Failed to get EntityPlayer from player", e);
return null;
}
}
public static void sendPacket(final Player player, final Object packet) {
final Object nmsPlayer = getNMSPlayer(player);
if (nmsPlayer == null) {
return; return;
} }

View File

@ -65,7 +65,9 @@ public class ReflectionUtil {
return clazz.getDeclaredMethod(methodName, parameterTypes); return clazz.getDeclaredMethod(methodName, parameterTypes);
} catch (NoSuchMethodException ex) { } catch (NoSuchMethodException ex) {
final Class<?> superClass = clazz.getSuperclass(); final Class<?> superClass = clazz.getSuperclass();
if (superClass == null) return null; if (superClass == null) {
return null;
}
return getMethod(superClass, methodName, parameterTypes); return getMethod(superClass, methodName, parameterTypes);
} }
} }