Java 如何使用getConfig()在主类之外的方法中编辑config.yml
几天来,我一直有一个问题,再多的搜索也帮不了我解决。我最近才开始涉足Bukkit插件的开发,目前所有这些简单的插件都是设置加入/退出消息和AFK状态。然而,后一部分给了我一些问题 当玩家加入时,我的插口服务器控制台正在输出无法将event PlayerJoinEvent传递给ServerBasics,当玩家键入/afk时,在插件ServerBasics中执行命令“afk”时,未处理的异常 逻辑:Main类的onEnable()为AfkCommand设置命令执行器,为JoinListener设置事件监听器,当玩家加入时,它的主要焦点是监视。此时,当玩家加入时,应该调用ToggleAFK中的toggle()方法,传递玩家的名称和一个假布尔值,以便在config.yml中为他们添加一个条目,并确保他们稍后键入/afk命令时,不使用afk。然后,ToggleAFK应使用afk保存配置。[player]等于false 同时,AfkCommand还应该使用播放器的名称和true/false参数调用ToggleAFK,并且ToggleAFK应该以相同的方式处理它。然而,它没有做到这一点 我在代码中设置了广播消息,以查看它何时失火。当播放机加入服务器时,JoinListener广播init和joined但不切换,而AfkCommand广播a、b和c但不切换,因此我们知道问题出在ToggleAFK中。TOGGLEFK不广播实例或g 问题似乎在于我创建了一个Main类的实例,但我不知道如何在另一个类中启用getConfig()命令,如果我所有的config.yml编辑都是在Main中处理的,那就一点也不整洁了。我已经读到主类不应该再次实例化,但我也发现了一个教程,其中它是以我在ToggleAFK中的方式实例化的,但是我的类不起作用(尽管在AfkCommand中这样做似乎很好) 我有什么选择?是否有不同于其他类的方式来编辑配置文件?我是否被迫在主目录中编辑它们?这个问题是因为ToggleAFK在Main之后被称为两个类而不是一个类吗?感谢您的帮助 我的主要班级:Java 如何使用getConfig()在主类之外的方法中编辑config.yml,java,plugins,minecraft,bukkit,Java,Plugins,Minecraft,Bukkit,几天来,我一直有一个问题,再多的搜索也帮不了我解决。我最近才开始涉足Bukkit插件的开发,目前所有这些简单的插件都是设置加入/退出消息和AFK状态。然而,后一部分给了我一些问题 当玩家加入时,我的插口服务器控制台正在输出无法将event PlayerJoinEvent传递给ServerBasics,当玩家键入/afk时,在插件ServerBasics中执行命令“afk”时,未处理的异常 逻辑:Main类的onEnable()为AfkCommand设置命令执行器,为JoinListener设置事
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。稍后我将对加入消息和内容进行软编码):
My ToggleAFK类(调用时应编辑config.yml文件):
和我的AfkCommand类(处理/afk并调用ToggleAFK):
据我所知,您的代码正确地将主插件类的引用传递给其他类的构造函数,并且似乎没有创建主插件类的新实例,因此应该没有任何障碍。当我测试代码时,无论是在玩家加入时还是在使用
/afk
命令时,都会抛出NullPointerException
,因为AfkCommand
和JoinListener
类中的afk
字段从未初始化
由于您的JoinListener
类在其构造函数中将ToggleAFK
对象作为参数,而不是像您的代码当前那样使用new JoinListener(null)
初始化它(当到达afk.toggle(player,false)
行时,会产生NullPointerException
),我通过newlistener(newtoggleafk(this))
将一个新的ToggleAFK
对象传递给构造函数
设置afk
字段的AfkCommand
类的替代构造函数似乎从未使用过。您可以在这里初始化afk
字段,方法是再次创建一个新的ToggleAFK
对象,使用AfkCommand类的另一个构造函数(您在onEnable()
方法中使用的)中已经提供的对主插件类的引用,如下所示:
Main plugin;
ToggleAFK afk;
public AfkCommand (Main instance) {
plugin = instance;
afk = new ToggleAFK(plugin);
}
这些更改似乎使代码按照我测试时的预期工作
需要注意的两件事:最好使用播放器的唯一ID(player.getUniqueID()
)将播放器的AFK状态保存在配置文件中,因为现在set
方法正在调用player
对象上的toString()
,这导致条目如下开头:CraftPlayer{name=Steve}
。这不仅看起来很奇怪,而且使用了玩家的名字,这可能会改变。另外,将切换
方法设置为静态并将其放置在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
类,最好是使用Util.initialize(this)
在oneable()方法中进行初始化!非常感谢你。我还将尝试合并您建议的更改。我试图在这里保持最佳实践,但同时我仍在摸索Bukkit插件。Util
类是否可以用来转储我想在插件中的其他类之间引用的方法?很高兴它能工作!是的,我相信用任何经常重复使用的方法填充实用程序类是很常见的,这些方法也不需要从特定的对象/实例调用(因此这些方法是静态的)。
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;
}
}
Main plugin;
ToggleAFK afk;
public AfkCommand (Main instance) {
plugin = instance;
afk = new ToggleAFK(plugin);
}
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);
}
}