Помогите NullPointerException в плагине

_MCMaster_

Активный участник
Пользователь
Баллы
76
Имя в Minecraft
DragOn4ik
Здравствуйте. Получаю NPE в плагине.
Код плагина ниже. Версия 1.12.2
NPE на 55 строке TrapSet.java
P.S. Еще одна проблема: при активации эвента ничего не происходит(Клик ПКМ с палкой в руке, у который DisplayName "Ловушка".
Код:
package net.darkmine.trap;

import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;

public class Trap extends JavaPlugin{
 
    FileConfiguration config = null;
 
    public void onEnable() {
        getCommand("trapset").setExecutor(new TrapSet());
        Bukkit.getPluginManager().registerEvents(new TrapSet(), this);
        config = getConfig();
        saveDefaultConfig();
        config.options().copyDefaults(true);
    }
 
    public void onDisable() {
        saveConfig();
    }

}
Код:
package net.darkmine.trap;

import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.*********ventory.ItemStack;
import org.*********ventory.meta.ItemMeta;


public class TrapSet implements Listener, CommandExecutor{
    Trap plugin;
 
    public void rightClickTrap(PlayerInteractEvent e) {
        if(!e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) return;
        if(!e.getAction().equals(Action.RIGHT_CLICK_AIR)) return;
        if(!e.getItem().hasItemMeta()) return;
        if(!e.getPlayer().hasPermission("trap.set")) return;
        ItemStack trapItem = new ItemStack(Material.STICK);
        ItemMeta trapMeta = trapItem.getItemMeta();
        trapMeta.setDisplayName(ChatColor.RED + "Ловушка");
        trapItem.setItemMeta(trapMeta);
        if(!e.getItem().isSimilar(trapItem));
        Player p = e.getPlayer();
        Location ploc = p.getLocation();
        Location loc = ploc.subtract(0, 1, 0);
        plugin.getConfig().set("blocks." + locationToDLF(loc) + ".active", true);
        plugin.getConfig().set("blocks." + locationToDLF(loc) + ".player", p.getName());
        plugin.getConfig().set("blocks." + locationToDLF(loc) + ".level", 1);
        plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), "particle cloud " + loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ() + " 1 1 1 1 300");
        plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), "title " + p.getName() + " subtitle [\"\",{\"text\":\"Ловушка установлена\",\"color\":\"aqua\"}]");
        p.sendMessage(ChatColor.AQUA + "Вы установили ловушку [" + loc.getBlockX() + ", " + loc.getBlockY() + ", " + loc.getBlockZ() + "]");
    }
 
    public String locationToDLF(Location loc) {
        return loc.getBlockX() + "_" + loc.getBlockY() + "_" + loc.getBlockZ();
    }

    @SuppressWarnings("deprecation")
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        Player p = (Player)sender;
        if(!p.hasPermission("trap.set.command")) {
            p.sendMessage(ChatColor.RED + "Недостаточно прав!");
            return true;
        }
        Location ploc = p.getLocation();
        Location loc = ploc.subtract(0, 1, 0);
        plugin.getConfig().set("blocks." + locationToDLF(loc) + ".active", true);
        plugin.getConfig().set("blocks." + locationToDLF(loc) + ".player", p.getName());
        plugin.getConfig().set("blocks." + locationToDLF(loc) + ".level", 1);
        plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), "particle cloud " + loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ() + " 1 1 1 1 300");
        plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), "title " + p.getName() + " subtitle [\"\",{\"text\":\"Ловушка установлена\",\"color\":\"aqua\"}]");
        p.sendMessage(ChatColor.AQUA + "Вы установили ловушку [" + loc.getBlockX() + ", " + loc.getBlockY() + ", " + loc.getBlockZ() + "]");
        return true;
    }

}
Код:
main: net.darkmine.trap.Trap
name: Trap
version: '1.0'
description: Trap
author: DragOn4ik
commands:
  trapset:
   description: Set a trap
   permission: trap.set
   usage: /<command>
*в этом файле ничего нет*
Код:
[17:45:35 ERROR]: null
 org.bukkit.command.CommandException: Unhandled exception executing command 'trapset' in plugin Trap v1.0  
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at org.bukkit.craftbukkit.v1_12_R1.CraftServer.dispatchCommand(CraftServer.java:648) ~[spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at net.minecraft.server.v1_12_R1.PlayerConnection.handleCommand(PlayerConnection.java:1397) [spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]    
at net.minecraft.server.v1_12_R1.PlayerConnection.a(PlayerConnection.java:1232) [spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at net.minecraft.server.v1_12_R1.PacketPlayInChat.a(PacketPlayInChat.java:45) [spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at net.minecraft.server.v1_12_R1.PacketPlayInChat.a(PacketPlayInChat.java:1) [spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at net.minecraft.server.v1_12_R1.PlayerConnectionUtils$1.run(SourceFile:13) [spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_172]  
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_172]  
at net.minecraft.server.v1_12_R1.SystemUtils.a(SourceFile:46) [spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at net.minecraft.server.v1_12_R1.MinecraftServer.D(MinecraftServer.java:748) [spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at net.minecraft.server.v1_12_R1.DedicatedServer.D(DedicatedServer.java:406) [spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at net.minecraft.server.v1_12_R1.MinecraftServer.C(MinecraftServer.java:679) [spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
 at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:577) [spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_172] Caused by: java.lang.NullPointerException  
at net.darkmine.trap.TrapSet.onCommand(TrapSet.java:55) ~[?:?]  
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot-1.12.2.jar:git-Spigot-eb3d921-2b93d83]  
... 15 more
 
Спасибо, все работает.
Ещё один вопрос:
Как с минимальной нагрузкой на сервер проверять, встал ли игрок на блок, который ловушка(в конфиге прописаны координаты). PlayerMoveEvent? Но это же нагрузка большая...
На мой взгляд, все же лучший вариант PlayerMoveEvent. Можно использовать шедулер, но тогда точность заметно уменьшится.
Не уверен, как лучше искать ловушку - сравнивать строки, или всё-же проверять координаты всех ловушек с локацией игрока, так что об этом напишет кто-нибудь другой - я лишь начинающий погромист. Если решать в лоб, то я бы ловушку перенёс в отдельный объект
PHP:
public class TrapThing {
    private UUID player;
    private int level;
    private boolean active;
   
    public TrapThing(UUID player, int level, boolean active) {
        this.player=player;
        this.level=level;
        this.active=active;
    }
    public TrapThing(String coords, ConfigurationSection section) {
        this.player=UUID.fromString(section.getString(coords+".player"));
        this.level=section.getInt(coords+".level");
        this.active=section.getBoolean(coords+".active");
    }
   
    public void setPlayer(UUID player) {
        this.player=player;
    }
   
    public void setLevel(int level) {
        this.level=level;
    }
   
    public void setActive(boolean active) {
        this.active=active;
    }
   
    public UUID getPlayer() {
        return player;
    }
    public int getLevel() {
        return level;
    }
    public boolean isActive() {
        return active;
    }
}
И хранил бы это дело в мапе Координаты,Ловушка
PHP:
    private Map<String,TrapThing> traps;
    private Trap plugin;

    public TrapSet(Trap plugin) {
        this.plugin=plugin;
        loadTraps();
    }

    public void loadTraps() {
        traps=new HashMap<>();
        ConfigurationSection section=plugin.config.get("blocks");
        for (String coord:section.getKeys(false)) {
            traps.put(coord, new TrapThing(coord,section));
        }
    }

    @EventHandler
    public void rightClickTrap(PlayerInteractEvent e) {
        Action act=e.getAction();
        if(!(act==Action.RIGHT_CLICK_AIR||act==Action.RIGHT_CLICK_BLOCK)) return;
        Player pl=e.getPlayer();
        if(!pl.hasPermission("trap.set")) return;
        ItemStack item=e.getItem();
        if(is==null||is.getType()!=Material.STICK) return;
        ItemMeta meta=is.getItemMeta();
        if(!meta.hasDisplayName()||!meta.getDisplayName().equals("§cЛовушка")) return;
        Location loc=pl.getLocation();
        String coord=locationToDLF(loc);
        plugin.config.set("blocks." + coord + ".player", p.getUniqueId());
        plugin.config.set("blocks." + coord + ".level", 1);
        plugin.config.set("blocks." + coord + ".active", true);
        traps.put(coord,new TrapThing(p.getUniqueId(), 1, true));
        p.sendTitle(ChatColor.AQUA + "Ловушка установлена", "", 20, 20, 20);
        p.getWorld().spigot().playEffect(loc, Effect.CLOUD, 0, 0, 0.3f, 0f, 0.3f, 0.5f, 100, 3);
        p.sendMessage(ChatColor.AQUA + "Вы установили ловушку [" + loc.getBlockX() + ", " + loc.getBlockY() + ", " + loc.getBlockZ() + "]");
    }
   
    @EventHandler
    public void onPlayerMove(PlayerMoveEvent e) {
        Location from = e.getFrom();
        Location to = e.getTo();
       
        // Чтобы лишний раз не искать ловушку на одном и том же блоке
        if (to.getBlockX() == from.getBlockX()
                && to.getBlockY() == from.getBlockY()
                && to.getBlockZ() == from.getBlockZ()) return;
   
        TrapThing trap=getTrap(to);
        if(trap!=null&&trap.isActive()&&!trap.getPlayer().equals(e.getPlayer().getUniqueId()){
            // Игрок в ловушке
        }
    }
   
    public String locationToDLF(Location loc) {
        return loc.getBlockX() + "_" + (loc.getBlockY()-1) + "_" + loc.getBlockZ();
    }
   
    public TrapThing getTrap(Location loc) {
        return traps.get(locationToDLF(loc));
    }
Не знаю по поводу работоспособности кода - не проверял, потому, скорее всего, придется править. А ещё не помешала бы проверка на мир игрока.
 
Ну и последний вопрос: как забрать у игрока предмет. Ну т.е., у него в руке палка "Ловушка", он кликает ПКМ, устанавливается ловушка, а палка пропадает
 
Ну и последний вопрос: как забрать у игрока предмет. Ну т.е., у него в руке палка "Ловушка", он кликает ПКМ, устанавливается ловушка, а палка пропадает
Код:
Player player = //Getting your player;
player.getInventory().remove(player.getInventory().getItemInMainHand());
 
Забирает весь стак... Надо чтобы 1 забирало
В подобных простых ситуациях советую покопаться на JavaDoc'ах Spigot'а - там информации достаточно практически для всего, что нужно для базовых плагинов.
PHP:
    if(item.getAmount()==1)
        item==null; else
        item.setAmount(item.getAmount()-1);
    if(e.getHand()==EquipmentSlot.HAND)
        pl.getInventory().setItemInMainHand(item); else
        pl.getInventory().setItemInOffHand(item);
 
Последнее редактирование:
Назад
Верх