訪問當前的 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 更新時你的程式碼都不會破壞。