0%

新手开发Minecraft Bukkit插件日记#1

嗯, 一个新手日记而已

0x01 Asynchronous command dispatch!

报错长这个样子

1
2
3
4
[00:02:34] [Async Chat Thread - #167/ERROR]: Could not pass event AsyncPlayerChatEvent to XXXXXXX v1.6.0
java.lang.IllegalStateException: Asynchronous command dispatch!
at org.spigotmc.AsyncCatcher.catchOp(AsyncCatcher.java:15) ~[patched_1.13.2.jar:git-Paper-655]
at org.bukkit.craftbukkit.v1_13_R2.CraftServer.dispatchCommand(CraftServer.java:709) ~[patched_1.13.2.jar:git-Paper-655]

源码长这个样子

1
2
3
4
5
6
7
plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(),
Objects.requireNonNull(
Objects.requireNonNull(
plugin.getConfig().getString("mute.command")
).replaceAll("%player%", username)
)
);

Bukkit异步线程不能调用BukkitAPI!!!
要运行可以扔到runTask里

1
2
3
4
5
6
7
8
9
10
11
12
new BukkitRunnable() {
@Override
public void run() {
plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(),
Objects.requireNonNull(
Objects.requireNonNull(
plugin.getConfig().getString("mute.command")
).replaceAll("%player%", username)
)
);
}
}.runTask(plugin);

0x02 操作Map java.lang.NullPointerException: null

遍历前一定要检查是否为空

1
2
3
if (map.isEmpty()) {
return null;
}

清空的时候不要直接赋值null, 后面会麻烦很多
用clear就优雅很多

1
data_map.clear();

获取数据用的时候要先检查是不是null

0x03 CommandSender转Player

之前我是这样写的

1
2
3
4
5
6
7
if (commandSender.getName().equalsIgnoreCase("console")) {
commandSender.sendMessage(ChatColor.translateAlternateColorCodes(
'&',"&cConsole can not use this command"
));
return true;
}
Player p = Bukkit.getServer.getPlayer(commandSender.getName());

然而有更高雅的方法

1
2
3
4
if (!(sender instanceof Player)) {
return true;
}
Player p = (Player) commandSender;

0x04 监听玩家执行指令

1
2
3
4
public class CommandPreprocessEvent implements Listener {
public void onCommands(PlayerCommandPreprocessEvent e) {
}
}

0x05 异步监听玩家消息

1
2
3
4
public class ChatEvent implements Listener {
public void onChat(AsyncPlayerChatEvent event) {
}
}

0x06 Bukkit异步任务

1
2
3
4
(new BukkitRunnable() {
public void run() {
}
}).runTaskAsynchronously(plugin);

0x07 Bukkit异步延迟任务

1
2
3
4
5
(new BukkitRunnable() {
public void run() {
}
}).runTaskLaterAsynchronously(plugin, 0L);
// 0L: 延迟0tick

0x08 自增Map

自增Map更优雅做法

1
2
3
4
5
6
7
8
9
10
11
12
// 定义
public Map<String, AtomicInteger> a = new HashMap<>();

// 自增1
AtomicInteger count = a.get(string_data);
if (count == null)
a.put(string_data, new AtomicInteger(1));
else
count.incrementAndGet();

// 读取
a.get(string_data).intValue()