对于几天没有多少搜索帮助我克服的路径,我一直有一个问题。我最近才开始涉足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;
}
}
答案 0 :(得分:0)
据我所知,您的代码正确地将主插件类的引用传递给其他类的构造函数,并且似乎没有创建主插件类的新实例,因此应该没有障碍。当我测试您的代码时,无论是在玩家加入时还是在使用/afk
命令时,都会引发NullPointerException
,因为afk
和AfkCommand
中的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()
方法。