简体   繁体   English

Bukkit插件编码不起作用?

[英]Bukkit Plugin Coding Not Working?

Well to start off, I am new to Java. 好吧,我是Java新手。 This is my first ever bukkit plugin and the only error is this ( Click Here ). 这是我有史以来第一个bukkit插件,唯一的错误是它( 单击此处 )。 The goal of the plugin is that when you right click with the "Bedrock Breaker", it breaks the bedrock. 该插件的目的是当您右键单击“基岩断路器”时,它将破坏基岩。

package me.jrneulight.bedrockbreaker;


import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;

public final class Main extends JavaPlugin implements Listener {
    public static void main(String[] args) {

    }
    @Override
    public void onEnable() {
        getLogger().info("Breakrock Breaker Enabled!");
        getServer().getPluginManager().registerEvents(this, this);
    }
    @Override
    public void onDisable() {
        getLogger().info("Bedrock Breaker Disabled!");
    }
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){
        if(cmd.getName().equalsIgnoreCase("bedrockbreaker")){ 
            Player player = (Player) sender;
            PlayerInventory inventory = player.getInventory();

            ItemStack bedrockbreaker = new ItemStack(Material.DIAMOND_HOE,1);

            ItemMeta im = bedrockbreaker.getItemMeta();

            im.setDisplayName(ChatColor.DARK_AQUA + "Bedrock Breaker");
            bedrockbreaker.setItemMeta(im);
            inventory.addItem(bedrockbreaker);
            return true;
        } 

        return false; 
    }
    @EventHandler(priority=EventPriority.HIGH)
    public void onPlayerUse (org.bukkit.event.player.PlayerInteractEvent evnt) {
        org.bukkit.block.Block block = evnt.getClickedBlock();
        org.bukkit.inventory.ItemStack item = evnt.getItem();
        Player player = evnt.getPlayer();
        org.bukkit.World world = block.getWorld();
        ItemMeta itemmeta = item.getItemMeta();
            if (block.getType() == Material.BEDROCK && item.getType() == Material.DIAMOND_HOE && itemmeta.getDisplayName() == ChatColor.DARK_AQUA + "Bedrock Breaker") {

                BlockBreakEvent breakEvent = new BlockBreakEvent(block, player);
                getServer().getPluginManager().callEvent(breakEvent);
                ItemStack drop = new ItemStack(block.getType());
                drop.setAmount(1);
                drop.setType(Material.BEDROCK);
                block.setType(Material.AIR);

                world.dropItemNaturally(block.getLocation(), drop);
                player.sendMessage("Bedrock Broken!");
            }
    }
}

As seen in your error, here: 如您的错误所示,这里:

Caused by: java.lang.NullPointerException
    at me.jrneulight.bedrockbreaker.Main.onPlayerUse(Main.java:54)

you are getting a NullPointer in your Main file on line 54 . 您在第54行的Main文件中获得了一个NullPointer Meaning the value of something on line 54 is null . 意思是第54行的值是null First, Let me start out by making your code in the beginning of onPlayerUse better. 首先,让我开始onPlayerUse开头的代码。 You don't have to use org.bukkit.block.Block block , you just have to use Block block = evnt.getClickedBlock(); 您不必使用org.bukkit.block.Block block ,而只需使用Block block = evnt.getClickedBlock(); same goes for org.bukkit.inventory.ItemStack , you only need to use ItemStack . org.bukkit.inventory.ItemStack ,您只需要使用ItemStack

The error is being caused by your method trying to get the block clicked, when no block was clicked, or trying to get the item used, when none was used. 该错误是由于您的方法试图单击块而没有单击块,或者试图使块没有被使用而导致的。 Here is the code you should be using instead: 这是您应该使用的代码:

@EventHandler(priority=EventPriority.HIGH)
public void onPlayerUse (PlayerInteractEvent evnt) {
    if(evnt.getAction().equals(Action.LEFT_CLICK_BLOCK){//make sure that they are infact hitting a block
        if(evt.getItem() == new ItemStack(Material.DIAMOND_HOE)){ //make sure they are using a diamond hoe
            Block block = evnt.getClickedBlock();
            //ItemStack item = evnt.getItem();
            //we don't need the above line any more
            Player player = evnt.getPlayer();

            World world = block.getWorld();
            ItemMeta itemmeta = item.getItemMeta();
         }
    }
}

So, for your whole onPlayerUse method, you should be using this code: 因此,对于整个onPlayerUse方法,您应该使用以下代码:

    @EventHandler(priority=EventPriority.HIGH)
    public void onPlayerUse (PlayerInteractEvent evnt) {
        if(evnt.getAction().equals(Action.LEFT_CLICK_BLOCK)){//make sure that they are infact hitting a block
            if(evnt.getItem() == new ItemStack(Material.DIAMOND_HOE)){ //make sure they are using a diamond hoe
               if(evnt.getItem().getItemMeta().getDisplayName().equals(ChatColor.DARK_AQUA + "Bedrock Breaker")){ //make sure the name of the diamond hoe is "Bedrock Breaker" in DARK_AQUA

                Block block = evnt.getClickedBlock();
                World world = block.getWorld();
                Player player = evnt.getPlayer();
                if(block.getType() == Material.BEDROCK){ //make sure the block clicked is bedrock

                    BlockBreakEvent breakEvent = new BlockBreakEvent(block, player);
                    Bukkit.getServer().getPluginManager().callEvent(breakEvent);
                    ItemStack drop = new ItemStack(block.getType());
                    drop.setAmount(1);
                    drop.setType(Material.BEDROCK);
                    block.setType(Material.AIR);

                    world.dropItemNaturally(block.getLocation(), drop);
                    player.sendMessage("Bedrock Broken!");
                }
            }
        }
    }
    }

You're going to want to check for the name with .equals(String) instead of == String . 您将要使用.equals(String)而不是== String来检查名称。 Also, you should check for most of the requirements initially to reduce lag. 另外,您最初应该检查大多数需求以减少延迟。

The reason that you were getting that error was because you weren't making sure that they were hitting a block, so, in your code, when the player did any action (stepping on a pressure plate, right-clicking an item, hitting the air), it called you're code. 出现该错误的原因是,您不确定自己是否碰到了障碍物,因此,在您的代码中,玩家进行任何操作(踩压板,右键单击某个物品,空气),它称您为代码。 That's why you need to make sure that they are left clicking a block, with Action.LEFT_CLICK_BLOCK , then get the block that they are hitting. 因此,您需要使用Action.LEFT_CLICK_BLOCK确保他们单击了一个块,然后获得了它们所击中的块。 Before you would try to get the block they were hitting, even when they pressed a button, or stepped on a pressure plate, so it returned a NullPointerException , because there was no block being hit. 在您尝试获取它们被击中的块之前,即使他们按下了按钮或踩在压板上,因此它返回NullPointerException ,因为没有块被击中。

As a general rule of thumb, before you get something from an event, first check if that something that you are getting exists. 作为一般经验法则,在从事件中获取任何东西之前,请首先检查您所获取的东西是否存在。

You are getting a NullPointerException , which means that one of the values returned didn't exist. 您将收到NullPointerException ,这意味着返回的值之一不存在。

Try adding some if statments to make sure that everything exists first 尝试添加一些if语句,以确保所有内容都首先存在

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM