武吉;如何通过单击单个聊天消息触发多个 ClickEvent RUN_COMMAND 操作
Bukkit; How to trigger multiple ClickEvent RUN_COMMAND actions with a single click on a single chat message
我为我的 paper/spigot Minecraft 服务器插件编写了一个相当简单的方法来检测正在建造的潜在滞后机器。
我遇到的问题是 我想发送一条 单条 聊天消息,点击一次后,首先 运行 一条 /vanish
命令 代表答题器。
然后如果(并且只有 如果)消失成功,我想 运行 一个传送命令 到包含 ClickEvent
.
这两个命令都需要从单个用户单击事件中完成。
此处供参考的是调用 notifyOps()
并包含有问题的 TextComponent msg
的方法
if (LagMats.contains(blockType) || mat.contains("MINECART") || mat.contains("DOOR")) {
int counter = 0;
for (Material thisMat: LagMats) {
if (thisMat != Material.GRAVEL) {
counter += Utilities.blockCounter(block.getChunk(), thisMat);
}
}
TextComponent warn = new TextComponent("WARN "); warn.setBold(true);
warn.setColor(ChatColor.RED);
TextComponent msg = new TextComponent("Potential lag-machine at " +
block.getX() + ", " + block.getY() + ", " + block.getZ() + " in " + dimension +
" by " + placer_name + " with UUID: " + placer.getUniqueId());
String cmd = "/execute in " + env + " run tp @s " +
block.getX() + " " + block.getY() + " " + block.getZ();
msg.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, cmd));
if (counter > 256) {
Utilities.notifyOps(new TextComponent(warn, msg));
}
}
哦,notifyOps
的实际小代码,其中 TextComponent
用于消息中:
// send a message to all online ops and console
public static boolean notifyOps(TextComponent msg) {
if (msg == null) return false;
for (Player thisPlayer: Bukkit.getOnlinePlayers()) {
try {
if (thisPlayer.isOp()) thisPlayer.spigot().sendMessage(msg);
} catch (Exception e) {return false;}
}
System.out.println(msg.getText());
return true;
}
所以我想让用户只点击一次,运行 两个命令,第二个只有在第一个成功时,如果可以在发送消息的 try 块内完成,那将是最好的.
我 可以 为此目的编写自定义命令,然后只 运行 该命令,但我宁愿避免为这么小的文件添加 类如果真的可行,我只是不知道。
感谢您的任何建议或帮助!
如果不编写自定义命令,就无法做到这一点...
这是不可能的,因为 ClickEvent
和 HoverEvent
完全是客户端。这意味着没有数据包从 Player
发送到服务器。因此,无法回调 Player
的点击并调用方法来执行您正在尝试执行的操作。
您可能会注意到所有 ClickEvent.Action
都不会影响服务器。 OPEN_URL
、OPEN_FILE
、RUN_COMMAND
、SUGGEST_COMMAND
、CHANGE_PAGE
和 COPY_TO_CLIPBOARD
都是在客户端执行的操作。
这里唯一的方法是让客户端向服务器发送命令,这将触发一个方法。
我为我的 paper/spigot Minecraft 服务器插件编写了一个相当简单的方法来检测正在建造的潜在滞后机器。
我遇到的问题是 我想发送一条 单条 聊天消息,点击一次后,首先 运行 一条 /vanish
命令 代表答题器。
然后如果(并且只有 如果)消失成功,我想 运行 一个传送命令 到包含 ClickEvent
.
这两个命令都需要从单个用户单击事件中完成。
此处供参考的是调用 notifyOps()
并包含有问题的 TextComponent msg
if (LagMats.contains(blockType) || mat.contains("MINECART") || mat.contains("DOOR")) {
int counter = 0;
for (Material thisMat: LagMats) {
if (thisMat != Material.GRAVEL) {
counter += Utilities.blockCounter(block.getChunk(), thisMat);
}
}
TextComponent warn = new TextComponent("WARN "); warn.setBold(true);
warn.setColor(ChatColor.RED);
TextComponent msg = new TextComponent("Potential lag-machine at " +
block.getX() + ", " + block.getY() + ", " + block.getZ() + " in " + dimension +
" by " + placer_name + " with UUID: " + placer.getUniqueId());
String cmd = "/execute in " + env + " run tp @s " +
block.getX() + " " + block.getY() + " " + block.getZ();
msg.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, cmd));
if (counter > 256) {
Utilities.notifyOps(new TextComponent(warn, msg));
}
}
哦,notifyOps
的实际小代码,其中 TextComponent
用于消息中:
// send a message to all online ops and console
public static boolean notifyOps(TextComponent msg) {
if (msg == null) return false;
for (Player thisPlayer: Bukkit.getOnlinePlayers()) {
try {
if (thisPlayer.isOp()) thisPlayer.spigot().sendMessage(msg);
} catch (Exception e) {return false;}
}
System.out.println(msg.getText());
return true;
}
所以我想让用户只点击一次,运行 两个命令,第二个只有在第一个成功时,如果可以在发送消息的 try 块内完成,那将是最好的.
我 可以 为此目的编写自定义命令,然后只 运行 该命令,但我宁愿避免为这么小的文件添加 类如果真的可行,我只是不知道。
感谢您的任何建议或帮助!
如果不编写自定义命令,就无法做到这一点...
这是不可能的,因为 ClickEvent
和 HoverEvent
完全是客户端。这意味着没有数据包从 Player
发送到服务器。因此,无法回调 Player
的点击并调用方法来执行您正在尝试执行的操作。
您可能会注意到所有 ClickEvent.Action
都不会影响服务器。 OPEN_URL
、OPEN_FILE
、RUN_COMMAND
、SUGGEST_COMMAND
、CHANGE_PAGE
和 COPY_TO_CLIPBOARD
都是在客户端执行的操作。
这里唯一的方法是让客户端向服务器发送命令,这将触发一个方法。