訪問當前的 Minecraft 版本
處理 NMS 程式碼最關鍵的部分之一是能夠支援多種 Minecraft 版本。有很多方法可以做到這一點,但一個簡單的解決方案是使用此程式碼將版本儲存為公共靜態欄位:
public static final String NMS_VERSION = Bukkit.getServer().getClass().getPackage().getName().substring(23);
此程式碼段通過獲取 CraftServer 類來工作:
org.bukkit.craftbukkit.VERSION.CraftServer.class
獲得它的包裹:
org.bukkit.craftbukkit.VERSION
並從索引 23 開始獲取包名稱的子字串,該索引始終位於’org.bukkit.craftbukkit’之後。 (長度為 23 個字元)。導致最終的 VERSION 字串:
VERSION
有許多原因導致能夠訪問當前的 Minecraft 版本如此重要。主要是因為在執行與外掛編碼的不同的 Minecraft 版本的伺服器上的任何類訪問都將引發錯誤。
下面是一個演示如何通過使用 NMS_VERSION
欄位在任何 Minecraft 版本上檢索 CraftPlayer 例項(這是一個 NMS 類)來解決該問題的示例。
/**
* 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);
}
}
然後,可以使用反射來操作生成的物件,以執行基於 NMS 的任務,而無需擔心嘗試訪問類的錯誤版本。
即使這種方法也不是萬無一失,因為 NMS 欄位和方法名稱很容易改變,所以你唯一要做的就是保證每次 Minecraft 更新時你的程式碼都不會破壞。