Bukkit:读出自定义名称字符串/提取整数

Bukkit : Read out Custom Name String / Extract Integer

我目前正在开发一个小的 RPG 插件,目前我正在尝试读取通过以下代码召唤的生物的等级:

public static void summonMob(EntityType entTy, int level, World w, Location loc) {

    Entity en = w.spawnEntity(loc, entTy);
    en.setCustomName(ChatColor.RED + "Experiment One " + ChatColor.DARK_GRAY + "> " + ChatColor.GREEN + level
            + ChatColor.DARK_GRAY + " <");
}

然后调用onEnable()进行测试:

summonMob(EntityType.ZOMBIE, 1, w, new Location(w, 238, 45, 1349));

"test-mob" 是用 1 级召唤的,我正在尝试在以下事件中读出此信息:

@EventHandler
public void onEntityDeath(EntityDeathEvent e) {
    if (e.getEntity().getKiller() instanceof Player) {

        Player p = e.getEntity().getKiller();

        if (e.getEntity().getCustomName() != null) {

            int mobLevel = Integer
                    .parseInt(ChatColor.stripColor(e.getEntity().getCustomName().replaceAll("[^\d.]", "")
                            .replaceAll("[^\p{L}\p{Nd}]+", "").replaceAll("\s+", "")));
            p.sendMessage("You've slain a Level " + mobLevel + " enemie!");
        }
    }

}

问题是,虽然从自定义名称中删除了所有非数字,但最终的整数总是将“8”加两倍,使得 1 中有 818,20 中有 8208。

我可能在这里漏掉了一些简单的东西,如果有人能帮助我就太好了。

虽然在其名称中存储了怪物级别,但在使用时可能会难以提取。更好的解决方案可能是使用 Bukkit 的 Metadatable 系统。

这个系统真的很容易使用,可以通过以下方式完成:

当你生成你的生物时,你可以通过以下方式为生物附加一个值:

en.setMetadata("level", new FixedMetadataValue(level));

当怪物被杀时,您可以通过以下操作轻松提取值:

List<MetadataValue> data = e.getEntity().getMetadata("level");
if(data.isEmpty()) return;
int level = data.get(0).asInt();

这样,您就不需要执行复杂的字符串正则表达式来恢复您的水平。

您可以使用 net.minecraft.server 代码来创建自定义实体,但是在处理 minecraft 更新时这是有问题的,因为函数名称很可能会因混淆而改变。

你可以去反编译你正在使用的 bukkit 版本,看看 bukkit 类 "Entitie" 和那些相关的,搜索它们并试图找出什么他们的意思是 google "bukkit <release> entitie nms",这也可能对您有帮助。

这还可以让您轻松 运行 在您的实体上自定义代码,操纵寻路、行为,让它们对 chat/commands 做出反应,让它们聊天和 运行 命令,<废话>...

我一回到家就会寻找我的 CustomVillager,因为我现在正在忙碌,家里的大存储空间里有所有这些东西,但我会尽快编辑它