package eu.mikroskeem.utils.bukkit; import eu.mikroskeem.shuriken.reflect.Reflect; import eu.mikroskeem.shuriken.reflect.wrappers.ClassWrapper; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import java.lang.reflect.InvocationTargetException; import static com.google.common.base.Preconditions.checkNotNull; import static eu.mikroskeem.utils.bukkit.ServerUtils.getNmsVersion; public class PlayerUtils { /** * Return player ping (via NMS reflection) * * Note: I'm bit disappointed, that Bukkit API doesn't expose method to get player's ping * * @param player Player who ping to query * @return Player's ping (-1 if reflection failed) */ @SuppressWarnings("unchecked") public static int getNMSPing(@NotNull Player player){ try { String nmsVer = getNmsVersion(); ClassWrapper craftPlayerClass = (ClassWrapper) checkNotNull(Reflect.getClass( String.format("org.bukkit.craftbukkit.%s.entity.CraftPlayer", nmsVer)).orElse(null)) .setClassInstance(player); ClassWrapper nmsEntityPlayerClass = (ClassWrapper) checkNotNull(Reflect.getClass( String.format("net.minecraft.server.%s.EntityPlayer", nmsVer)).orElse(null)); NMSPlayer nmsPlayer = craftPlayerClass .invokeMethod("getHandle", nmsEntityPlayerClass.getWrappedClass()); nmsEntityPlayerClass.setClassInstance(nmsPlayer); return checkNotNull(nmsEntityPlayerClass.getField("ping", int.class).orElse(null)).read(); } catch (NullPointerException|NoSuchFieldException|NoSuchMethodException| IllegalAccessException|InvocationTargetException ignored){} return -1; } }