bukkit
NMS
Recherche…
Introduction
NMS, également appelé N et. M inecraft. S serveur est le package qui contient le code de serveur principal de Minecraft. Les classes dans ce paquet ont été faites par Mojang (pas Bukkit) et sont donc pour la plupart obscurcies et non destinées à être utilisées ou modifiées. Cependant, interagir avec le code serveur Minecraft à ce niveau vous permet de modifier presque tous les aspects. Ceci est important car de nombreuses modifications ne sont pas prises en charge par Bukkit.
Remarques
L'API Bukkit est une couche d'encapsulation ou d'abstraction pour NMS qui permet aux développeurs de plug-ins d'interagir avec le serveur sans se soucier des modifications apportées à la base de code interne.
L'utilisation du code NMS est déconseillée car elle se casse souvent entre les modifications de version de Minecraft et ne peut pas être prise en charge par Bukkit ou Spigot car elle ne la crée pas, ne la possède pas ou ne la gère pas.
Accéder à la version actuelle de Minecraft
L'une des parties les plus critiques du traitement du code NMS est la capacité à prendre en charge de nombreuses versions de Minecraft. Il existe de nombreuses façons de procéder, mais une solution simple consiste à utiliser ce code pour stocker la version en tant que champ statique public:
public static final String NMS_VERSION = Bukkit.getServer().getClass().getPackage().getName().substring(23);
Cet extrait de code fonctionne en prenant la classe CraftServer:
org.bukkit.craftbukkit.VERSION.CraftServer.class
Obtenir son paquet:
org.bukkit.craftbukkit.VERSION
Et en prenant la sous-chaîne du nom du paquet commençant à l'index 23 qui sera toujours après «org.bukkit.craftbukkit». (qui a une longueur de 23 caractères). Résultat dans la chaîne VERSION finale:
VERSION
Il y a un certain nombre de raisons pour lesquelles il est si important de pouvoir accéder à la version actuelle de Minecraft. Principalement parce que tout accès à une classe sur un serveur exécutant une version de Minecraft différente de celle utilisée par le plug-in génère une erreur.
Voici un exemple qui montre comment résoudre ce problème en utilisant le champ NMS_VERSION
pour récupérer une instance de CraftPlayer (qui est une classe NMS) sur toute version de Minecraft.
/**
* Invokes the getHandle() method on the player's CraftPlayer instance to
* retrieve the EntityPlayer representation of the player as an Object to
* avoid package version change issues
*
* @param player
* the player to cast
* @return the NMS EnityPlayer representation of the player
*/
public static Object getCraftPlayer(Player player) {
try {
return Class.forName("org.bukkit.craftbukkit." + NMS_VERSION + ".entity.CraftPlayer")
.getMethod("getHandle")
.invoke(player);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | ClassNotFoundException e) {
throw new Error(e);
}
}
L'objet résultant peut ensuite être manipulé en utilisant la réflexion pour effectuer des tâches basées sur NMS sans avoir à se soucier d'essayer d'accéder à la mauvaise version de la classe.
Cependant, même cette méthode n'est pas infaillible, car les noms de champs et de méthodes NMS changent facilement, de sorte que la seule chose que vous garantissez est que votre code ne se cassera pas à chaque mise à jour de Minecraft.
Obtenir un ping du joueur
Une chose très simple à faire avec NMS que Bukkit ne supporte pas est d'obtenir le ping du joueur. Cela peut être fait comme ceci:
/**
* Gets the players ping by using NMS to access the internal 'ping' field in
* EntityPlayer
*
* @param player
* the player whose ping to get
* @return the player's ping
*/
public static int getPing(Player player) {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
return entityPlayer.ping;
}
Si vous utilisez une méthode comme getCraftPlayer (Player) qui renvoie une instance de l'instance CraftPlayer correspondante du Lecteur en tant qu'objet. Vous pouvez accéder aux données sans importer les classes dépendantes de la version en utilisant une réflexion comme celle-ci:
/**
* Gets the player's ping using reflection to avoid breaking on a Minecraft
* update
*
* @param player
* the player whose ping to get
* @return the player's ping
*/
public static int getPing(Player player) {
try {
Object craftPlayer = getCraftPlayer(player);
return (int) craftPlayer.getClass().getField("ping").get(craftPlayer);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
throw new Error(e);
}
}