如何使用getConfig()在Main类

时间:2016-03-17 20:59:39

标签: java plugins minecraft bukkit

对于几天没有多少搜索帮助我克服的路径,我一直有一个问题。我最近才开始涉足Bukkit插件开发,所有这些简单的插件当前都设置了join / quit消息和AFK状态。然而,后一部分给了我一些问题。

当玩家加入时,我的Spigot服务器控制台输出无法将事件PlayerJoinEvent传递给ServerBasics ,而当输入/ afk时,插件ServerBasics中的未处理异常执行命令'afk'由一名球员。

逻辑:主类的onEnable()设置AfkCommand的命令执行程序和JoinListener的事件监听器,JoinListener在玩家加入时主要关注监视器。此时,它应该在玩家加入时调用ToggleAFK中的toggle()方法,传递玩家的名字和假布尔值,以便在config.yml中为他们添加条目,并确保他们不是afk,如果他们输入/ afk命令稍后。然后ToggleAFK应该用afk保存配置。[player]等于false。

同时,AfkCommand还应该使用播放器的名称和true / false参数调用ToggleAFK,而ToggleAFK应该以相同的方式处理它。但是,它没有这样做。

我已经通过代码设置了广播消息,以查看它何时失火。当玩家加入服务器时,JoinListener广播 init 加入但不切换,AfkCommand广播 a ,< em> b 和 c 但不是 d ,所以我们知道问题出在ToggleAFK中。 ToggleAFK不会广播 instanced g

问题似乎在于我创建了一个Main类的实例,但是我不知道如何在另一个类中启用getConfig()命令,如果我的所有配置都不是那么整洁.yml编辑在Main处理。我已经读过Main类不应该再次实例化,但是我也找到了一个教程,其中我以ToggleAFK中的方式实现了它,但是我的工作不起作用(虽然看起来很好)我在AfkCommand中这样做。)

我有什么选择?是否有不同的方法来编辑其他类的配置文件?我被迫在Main编辑它们吗?问题是因为ToggleAFK在Main之后被调用了两个类而不是一个吗?任何帮助表示赞赏。

我的主要课程:

package com.timothyreavis.serverbasics;

import org.bukkit.plugin.java.JavaPlugin;

public class Main extends JavaPlugin {

    @Override
    public void onEnable()
    {
        getCommand("afk").setExecutor(new AfkCommand(this));

        getServer().getPluginManager().registerEvents(new JoinListener(null), this);
    }

}

我的JoinListener类(当玩家加入时将afk设置为false。我将稍后对加入消息和内容进行软编码):

package com.timothyreavis.serverbasics;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;

import net.md_5.bungee.api.ChatColor;

public class JoinListener implements Listener
{
    // create ToggleAFK class instance
    ToggleAFK afk;
    public JoinListener(ToggleAFK instance) {
        afk = instance;
    }

    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event)
    {
        Bukkit.broadcastMessage("init");
        // Player joins
        Player player = event.getPlayer();
        Bukkit.broadcastMessage("joined");
        afk.toggle(player, false);
        Bukkit.broadcastMessage("toggled");
        // set player entry as not afk in config.yml
        Bukkit.broadcastMessage("h");

        if (!player.hasPlayedBefore()) {
            // if player is new
            event.setJoinMessage(ChatColor.DARK_PURPLE + "Welcome " + ChatColor.GREEN + event.getPlayer().getName() + ChatColor.DARK_PURPLE + " to the server!");

            // tell player to read rules
            event.getPlayer().sendMessage(ChatColor.YELLOW + "Hi, " + player.getName() + "! " + Bukkit.getServerName() + " is a rather unique server with custom plugins, so please read our rules and commands before getting started.");
        } else {
            // if player isn't new
            event.setJoinMessage(ChatColor.GREEN + "[+] " + event.getPlayer().getName());
        }
    }
    @EventHandler
    public void onPlayerQuit(PlayerQuitEvent event)
    {
        // Player quits
        event.setQuitMessage(ChatColor.RED + "[-] " + event.getPlayer().getName());
    }
}

我的ToggleAFK类(这应该在调用时编辑config.yml文件):

package com.timothyreavis.serverbasics;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

import net.md_5.bungee.api.ChatColor;

public class ToggleAFK {
    // create Main class instance
    Main plugin;
    public ToggleAFK(Main instance) {
        plugin = instance;
        Bukkit.broadcastMessage("instanced");
    }

    public Boolean toggle(Player player, Boolean status) {
        Bukkit.broadcastMessage("g");
        plugin.getConfig().set("afk." + player, status);
        plugin.saveConfig();
        if (status) {
            Bukkit.broadcastMessage(ChatColor.DARK_PURPLE + player.getName() + " is now AFK.");
        } else {
            Bukkit.broadcastMessage(ChatColor.DARK_PURPLE + player.getName() + " is no longer AFK.");
        }
        return true;
    }
}

我的AfkCommand类(处理/ afk并调用ToggleAFK):

package com.timothyreavis.serverbasics;

import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
//import org.bukkit.event.player.PlayerMoveEvent;

public class AfkCommand implements CommandExecutor {
    // create Main class instance
    Main plugin;
    public AfkCommand (Main instance) {
        plugin = instance;
    }
    // create ToggleAFK class instance
    ToggleAFK afk;
    public AfkCommand (ToggleAFK instance) {
        afk = instance;
    }

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        Bukkit.broadcastMessage("a");
        if (sender instanceof Player) {
            Player player = (Player) sender;
            Bukkit.broadcastMessage("b");
            if (plugin.getConfig().getBoolean("afk."+sender) == false) {
                Bukkit.broadcastMessage("c");
                afk.toggle(player, true);
                Bukkit.broadcastMessage("d");
            } else {
                afk.toggle(player, false);
                Bukkit.broadcastMessage("d");
            }
        } else {
            Bukkit.broadcastMessage("e");
            return false;
        }
        // if command is used correctly, return true
        Bukkit.broadcastMessage("f");
        return true;
    }

}

1 个答案:

答案 0 :(得分:0)

据我所知,您的代码正确地将主插件类的引用传递给其他类的构造函数,并且似乎没有创建主插件类的新实例,因此应该没有障碍。当我测试您的代码时,无论是在玩家加入时还是在使用/afk命令时,都会引发NullPointerException,因为afkAfkCommand中的JoinListener字段} class永远不会被初始化。

由于您的JoinListener类在其构造函数中将ToggleAFK对象作为参数,而不是像您当前的代码那样使用new JoinListener(null)初始化它(生成NullPointerException当到达行afk.toggle(player, false)时,我将一个新的ToggleAFK对象传递给了new Listener(new ToggleAFK(this))的构造函数。

设置AfkCommand字段的afk类的备用构造函数似乎永远不会被使用。您可以通过再次创建一个新的afk对象来初始化ToggleAFK字段,这次使用AfkCommand类的另一个构造函数(您正在使用的那个)中提供的主插件类的引用。 onEnable()方法),如下所示:

Main plugin;
ToggleAFK afk;
public AfkCommand (Main instance) {
    plugin = instance;
    afk = new ToggleAFK(plugin);
}

这些更改似乎使代码在我测试时按预期工作。

有两点需要注意:最好使用其唯一ID(player.getUniqueID())将播放器的AFK状态保存在配置文件中,因为现在set方法正在调用{{1}在toString()对象上导致条目如下所示:Player。这不仅看起来很奇怪,而且使用了玩家的名字,这可能会改变。此外,可能更容易使CraftPlayer{name=Steve}方法静态并将其放在toggle类中,这样您就不必创建Util类的所有实例来访问它方法。这样的事可能适合你:

ToggleAFK

对于此特定示例,您需要“初始化”import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; public class Util { private static Main plugin; public static void initialize(Main instance) { plugin = instance; } public static void toggleAFK(Player player, boolean isAFK) { if (plugin == null) { throw new IllegalStateException("This class has not been initialized yet!"); } plugin.getConfig().set("AFK." + player.getUniqueId(), isAFK); plugin.saveConfig(); String message = ChatColor.DARK_PURPLE + player.getName(); message += (isAFK) ? " is now AFK." : " is no longer AFK."; Bukkit.broadcastMessage(message); } } 类,最好使用Util onEnable()方法。