I've written a rather simple method for my paper/spigot Minecraft server plugin that detects potential lag machines under construction.
The issue I have is that I want to send a single chat message that, when clicked once, will first run a /vanish
command on behalf of the clicker.
Then if (and only if) the vanish was successful, I want to run a teleport command to a location included along with the specific instance of the ClickEvent
.
For reference here is the method that calls notifyOps()
and includes the TextComponent in question, 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));
}
}
Oh and the actual little code of notifyOps
where the TextComponent
is used in a message:
// 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;
}
So I want to have the user click just once, run two commands, the second only if the first succeeds, and would be best if it could be done within the try block the message is sent from.
I could write a custom command for this purpose, and then just run that command, but I rather avoid adding classes for such a small addition if it's actually possible and I just have no idea.
Thanks for any advice or help!
This is impossible because the ClickEvent
and HoverEvent
are entirely client-side. That means that there are no packets sent from the Player
to the server. Therefore, it is impossible to callback the click of the Player
and call a method to perform what you are trying to do.
You may notice that all the ClickEvent.Action
s do not affect the server. OPEN_URL
, OPEN_FILE
, RUN_COMMAND
, SUGGEST_COMMAND
, CHANGE_PAGE
and COPY_TO_CLIPBOARD
are all actions taken on the client-side.
The only way here is to make the client send a command to the server which will trigger a method.