Created
September 22, 2016 11:42
-
-
Save TuxCoding/6bdd37937f4538ee5d5dc9cef47cd413 to your computer and use it in GitHub Desktop.
Get the minecraft ping of a Player object in a Bukkit/MCPC server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class MinecraftPing { | |
| //this value updates every 40 Ticks => 2 Seconds. So you proparly want to add a scheduled task for it. | |
| public int getReflectionPing(Player player) { | |
| try { | |
| if (getHandleMethod == null) { | |
| getHandleMethod = player.getClass().getDeclaredMethod("getHandle"); | |
| //disable java security check. This will speed it a little | |
| getHandleMethod.setAccessible(true); | |
| } | |
| Object entityPlayer = getHandleMethod.invoke(player); | |
| if (pingField == null) { | |
| if (isModdedServer()) { | |
| //MCPC has a remapper, but it doesn't work if we get the class dynamic | |
| setMCPCPing(entityPlayer); | |
| } else { | |
| pingField = entityPlayer.getClass().getDeclaredField("ping"); | |
| //disable java security check. This will speed it a little | |
| pingField.setAccessible(true); | |
| } | |
| } | |
| //returns the found int value | |
| return pingField.getInt(entityPlayer); | |
| } catch (Exception ex) { | |
| throw new RuntimeException(ex); | |
| } | |
| } | |
| private boolean isModdedServer() { | |
| //aggressive checking for modded servers | |
| List<String> versionNames = Arrays.asList(Bukkit.getVersion(), Bukkit.getName(), Bukkit.getServer().toString()); | |
| return versionNames.stream().anyMatch((version) -> (version.contains("MCPC") || version.contains("Cauldron"))); | |
| } | |
| private void setMCPCPing(Object entityPlayer) { | |
| //this isn't secure, because it detects the ping variable by the order of the fields | |
| Class<?> lastType = null; | |
| Field lastIntField = null; | |
| for (Field field : entityPlayer.getClass().getDeclaredFields()) { | |
| if (field.getType() == Integer.TYPE | |
| && Modifier.isPublic(field.getModifiers()) | |
| && lastType == Boolean.TYPE) { | |
| lastIntField = field; | |
| continue; | |
| } | |
| if (field.getType() == Boolean.TYPE && lastIntField != null) { | |
| pingField = lastIntField; | |
| //disable java security check. This will speed it a little | |
| pingField.setAccessible(true); | |
| break; | |
| } | |
| lastIntField = null; | |
| lastType = field.getType(); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment