位置未保存到 config.yml

Location not being saved to config.yml

我正在尝试在 config.yml 中保存一个位置,当他踏上该位置时,它会引发一个动作。然而,这并没有发生。

很抱歉包含了全部代码,但我认为这对于此类程序来说是必不可少的。

主要class:

public class Turrets extends JavaPlugin{

    ArrayList<String> playersThatShouldPlaceBlock = new ArrayList<String>();

    HashMap<String, String> turretName = new HashMap<String, String>();

    String turretsMsg = ChatColor.RED + "[" + ChatColor.GOLD + "Turrets" + ChatColor.RED + "]" + ChatColor.GOLD + ": ";

    public int waitForPlacement;

    public void loadConfig() {

        this.getConfig().addDefault("Turrets.", null);

        this.saveConfig();

    }

    public void onEnable(){

        new CreateTurretEvent(this);
        loadConfig();

    }

    public void onDisable(){
        loadConfig();
    }

    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){

        final Player p = (Player) sender;

        if (cmd.getName().equalsIgnoreCase("turret")){

            if (args.length < 2){
                p.sendMessage(turretsMsg + ChatColor.RED + "Invalid usage! /turret [create or delete] [name]");
                return true;
            }
            else if (args.length >= 2){
                if (args[0].equalsIgnoreCase("create")){
                    if (args[1] != null){
                        p.sendMessage(turretsMsg + ChatColor.GOLD + "Place a block and YOU will become a turret when you step on it!");

                        playersThatShouldPlaceBlock.add(p.getName());

                        turretName.put(p.getName(), args[1]);

                        waitForPlacement = Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable(){

                            @Override
                            public void run() {

                                p.sendMessage(turretsMsg + ChatColor.RED + "You waited too long so the action was cancelled!");
                                playersThatShouldPlaceBlock.remove(p.getName());

                            }

                        }, 600L);


                        return true;
                    }
                }
            }

        }


        return false;
    }

}

听众class:

package me.mortadelle2.turrets;

import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerMoveEvent;


public class CreateTurretEvent implements Listener{

    Turrets getter;

    public CreateTurretEvent(Turrets plugin){
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
        getter = plugin;
    }

    @EventHandler
    public void playerPlacesBlockToBecomeTurret(BlockPlaceEvent e){

        Player p = e.getPlayer();

        if (getter.playersThatShouldPlaceBlock.contains(p.getName())){
            p.sendMessage(getter.turretsMsg + "That block is now turretified!");
            getter.getServer().getScheduler().cancelTask(getter.waitForPlacement);
            getter.playersThatShouldPlaceBlock.remove(p.getName());

            Location blockLocation = e.getBlock().getLocation();

            getter.getConfig().set("Turrets." + getter.turretName.get(p.getName()), blockLocation);
        }

    }

    @EventHandler
    public void playerStepsOnTurret(PlayerMoveEvent e){

        Player p = e.getPlayer();

            if (getter.getConfig().contains("test")){ //I will add something more specific than test later
                p.sendMessage("This is a test");
            }


    }

}

问题一:拼写错误(此问题已在question revision 3处编辑出题)

您似乎拼错了 onDisbale(){。当插件被禁用时,它将 运行 方法 onDisable() 在你的插件上。在您的情况下,它不是 运行,因为您没有具有该确切签名的方法。

以后如何预防

通过在方法的开头添加 @Override,您表示它必须覆盖在父 class 中找到的现有方法。这可以像这样使用:

@Override
public void onDisable() {

问题 2:PlayerMoveEvent 的实现尚未完成

注意,Whosebug 不是 "we write code for you service"

通过分析您的代码,您正在以下列格式保存您的配置:

playername:
    turretname: (location object)

第一步:更改保存位置

bukkit 配置不能与 Location 对象一起正常工作,您应该将您的位置保存更改为

getter.getConfig().set("Turrets." + getter.turretName.get(p.getName())+ ".world", player.getLocation().getWorld().getName());
getter.getConfig().set("Turrets." + getter.turretName.get(p.getName())+ ".x", player.getLocation().getBlockX());
getter.getConfig().set("Turrets." + getter.turretName.get(p.getName())+ ".y", player.getLocation().getBlockY());
getter.getConfig().set("Turrets." + getter.turretName.get(p.getName())+ ".z", player.getLocation().getBlockZ()); 

这会更改配置以单独存储世界、x、y 和 z

第 2 步:在 PlayerMoveEvent

解析配置

因为我们更改了配置格式,所以在 PlayerMoveEvent 时更容易检测到我们站在哪个炮塔上

我们将使用以下方法检测我们在 PlayerMove 时站在哪个方块上

  1. 检查配置中是否存在炮塔

    ConfigurationSection sec = getter.getConfig().getConfigurationSection("Turrets."+getter.turretName.get(p.getName())); 
    // Todo: check if the player exists inside getter.turretName
    if(sec != null){
        ....
    }
    
  2. 解析配置以检查是否找到位置

    Location loc = event.getPlayer().getLocation();
    if(loc.getBlockX() == sec.getInt("x") && loc.getBlockY() == sec.getInt("y") && loc.getBlockZ() == sec.getInt("z") && loc.getWorld().getName().equals(sec.getString("world"))) {
        event.getPlayer().sendMessage("This is a test");
    }
    

这应该可以解决您遇到的问题。可以做以下改进:

  • 只在玩家改变方块时调用玩家移动代码
  • 使用更具描述性的变量名称,例如 getter 应重命名为 mainplugin