As the title sugests, here you can find how to get player's ping! This is usefull especially for game servers/minigames either to know when a player is lagging or to add the command /ping ingame :- ) Method #1 (version depended but simple and small) This method is more practical to understand how its done than implement it in code. Code: public int getPing(Player who){ //turning player to CraftPlayer, then to EntityPlayer (.getHandle()) and getting field "ping" return ((CraftPlayer)who).getHandle().ping; } Method #2 (Version independed!) now this is the version that is better to use in code even if it is less efficient than Method #1, and the reason is because if your plugin is build on version 1.7.2 and server is on version 1.7.10 it will still work Code: public int pingPlayer(Player who) { try { // Building the version of the server in such a form we can use it // in NMS code. String bukkitversion = Bukkit.getServer().getClass().getPackage() .getName().substring(23); // Getting craftplayer Class<?> craftPlayer = Class.forName("org.bukkit.craftbukkit." + bukkitversion + ".entity.CraftPlayer"); // Invoking method getHandle() for the player Object handle = craftPlayer.getMethod("getHandle").invoke(who); // Getting field "ping" that holds player's ping obviously Integer ping = (Integer) handle.getClass().getDeclaredField("ping") .get(handle); // Returning the ping return ping.intValue(); } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | NoSuchFieldException e) { // Handle exceptions however you like, i chose to return value of // -1; since player's ping can't be -1. return -1; } } Thanks @DJSkepter and @RingOfStorms for their help :- ) Thanks for reading! Hope you like it! PS. if i have any error please mind leaving a reply pointing it out <3 thanks!
@mine-care You used Code: craftPlayer.cast(who); whereas when I had done the same outcome in my ReflectionUtils, I didn't need to cast the player to CraftPlayer
@DJSkepter :O really? how did you obtain ping then? it is not available in player obj :/ it is in EntityPlayer that i need to obtain from craftplayer's handle.... If you want i can add your method of doing this in this thread =) Thanks.
What he means is that you don't need to cast something to something that you already know that it is. You know that "who" is a CraftPlayer, so why do you cast it to one, it is a bunch of wasted lines of code. So in other words, remove the casted part and simply invoke on "who". Here is an example if you want proof of this being real: http://ideone.com/LokkmI Reflection only looks at things as an object anyways, so casting is a pointless operation (unless you plan on returning it and using it outside of reflection), especially when you immediately cast it back to an Object again, doesn't make too much sense. Code: public int pingPlayer(Player who) { try { //Building the version of the server in such a form we can use it in NMS code. String bukkitversion = Bukkit.getServer().getClass().getPackage() .getName().substring(23); //Getting craftplayer to cast later on Class<?> craftPlayer = Class.forName("org.bukkit.craftbukkit." + bukkitversion + ".entity.CraftPlayer"); //Invoking method getHandle() for the craftplayer we build above, and now we have a EntityPlayer Object handle = craftPlayer.getMethod("getHandle").invoke(who); //Getting field "ping" that holds player's ping obviously Integer ping = (Integer) handle.getClass().getDeclaredField("ping").get(handle); //Returning the ping return ping.intValue(); } catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | NoSuchFieldException e) { //Handle exceptions however you like, i chose to return value of -1; since player's ping can't be -1. return -1; } }
@mine-care Nice, but you should keep the version and the field in a fiel (lol) so you don't have to get them every time again, they won't change at runtime.
@mine-care No need for using the Class.forName(), the Player#getClass() will always return CraftPlayer, if it doesn't it's player-made and using the CraftPlayer class won't work then too because it's not an instance of it .