QoL/src/main/java/xyz/etztech/qol/listeners/CommandPreprocessListener.java

193 lines
7.1 KiB
Java

package xyz.etztech.qol.listeners;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.apache.commons.lang.StringUtils;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent;
import org.dynmap.DynmapAPI;
import xyz.etztech.core.web.Http;
import xyz.etztech.qol.QoL;
import xyz.etztech.qol.other.LinkCommand;
import java.util.*;
public class CommandPreprocessListener implements Listener {
QoL plugin;
private Map<UUID, String> confirmMap = new HashMap<>();
private Map<UUID, Boolean> dynmapVisibleStatusMap = new HashMap<>();
public CommandPreprocessListener(QoL plugin) {
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onServerCommand(ServerCommandEvent event) {
if (plugin.getConfig().getBoolean("audit.enabled")) {
String command = event.getCommand();
if (commandIsAuditable(command)) {
sendAuditWebhook("Console", null, command);
}
}
}
@EventHandler
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
String command = event.getMessage();
String base = command.split(" ")[0].substring(1).toLowerCase(); // Strip the slash
Player sender = event.getPlayer();
DynmapAPI dynmap = plugin.getDynmap();
// Spec dynmap hide
if (base.equals("spec") && sender.hasPermission("SafeSpectate.spectate") && dynmap != null) {
String message;
boolean visibleStatus;
if (sender.getGameMode() != GameMode.SPECTATOR){
dynmapVisibleStatusMap.put(sender.getUniqueId(), dynmap.getPlayerVisbility(sender.getName()));
visibleStatus = false;
message = "You are now being hidden on Dynmap.";
}
else if (dynmapVisibleStatusMap.containsKey(sender.getUniqueId())){
visibleStatus = dynmapVisibleStatusMap.remove(sender.getUniqueId());
String status = ((visibleStatus) ? "shown" : "hidden");
message = "Your " + status + " status has been restored on Dynmap.";
}
else {
message = "You are now visible on the Dynmap.";
visibleStatus = true;
}
TextComponent textComponent = new TextComponent(message);
textComponent.setColor(ChatColor.GREEN);
sender.spigot().sendMessage(textComponent);
dynmap.setPlayerVisiblity(sender.getName(), visibleStatus);
}
// Spec confirmation
List<String> specConfirm = plugin.getConfig().getStringList("spec-confirm");
if (sender.hasPermission("qol.specconfirm")) {
boolean confirm = false;
for (String confirmable : specConfirm) {
// If the player command either starts with a confirmable command and space (meaning confirmation is needed regardless of arguments)
// Or the player command is a full match to the confirmable command
if (noSlash(command).toLowerCase().startsWith(confirmable.toLowerCase() + " ") || noSlash(command).toLowerCase().equals(confirmable.toLowerCase())) {
confirm = true;
}
}
//check if the command is a spec confirm command
if (confirm) {
//If the user is in the confirm map, remove them and let the command run
if (command.equals(confirmMap.get(sender.getUniqueId()))) {
confirmMap.remove(sender.getUniqueId());
}
//If the user is running the command for the first time outside of spec
else if (sender.getGameMode() != GameMode.SPECTATOR) {
//Cancel the command
event.setCancelled(true);
//Add the user to the spec confirm map
confirmMap.put(sender.getUniqueId(), command);
TextComponent message = new TextComponent("You are running this command out of spec, run again to confirm.");
message.setColor(ChatColor.GREEN);
sender.spigot().sendMessage(message);
}
}
}
// Command Auditing
if (sender.hasPermission("qol.auditable") && plugin.getConfig().getBoolean("audit.enabled")) {
if (sender.hasPermission("qol.auditor") && targetIsAuditable(command)) {
return;
} else {
if (commandIsAuditable(command)) {
sendAuditWebhook(sender.getName(), sender.getGameMode(), command);
}
}
}
// Links
for (LinkCommand linkCommand : QoL.getLinks()) {
if (base.equalsIgnoreCase(linkCommand.getCommand())) {
event.setCancelled(true);
TextComponent link = new TextComponent(linkCommand.getMessage());
link.setColor(ChatColor.GREEN);
link.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, linkCommand.getUrl()));
sender.spigot().sendMessage(link);
return;
}
}
}
public boolean commandIsAuditable(String command) {
for (String audit : QoL.getAudits()) {
if (noSlash(command).startsWith(noSlash(audit))) {
return true;
}
}
return false;
}
public void sendAuditWebhook(String commandSource, GameMode gamemode, String command) {
String content = "";
if (gamemode != null) {
content += "[" + StringUtils.capitalize(gamemode.name().toLowerCase()) + "] ";
}
content += commandSource + " executed command: " + command;
sendWebhook("QoL Auditor", content);
}
public void sendWebhook(String username, String content) {
String webhook = plugin.getConfig().getString("audit.webhook");
if (StringUtils.isNotEmpty(webhook)) {
Map<String, String> post = new HashMap<>();
post.put("username", username);
post.put("content", content);
Http.asyncPost(plugin, webhook, post);
}
}
public boolean targetIsAuditable(String command) {
String[] commandSplit = command.split(" ");
Collection<? extends Player> players = plugin.getServer().getOnlinePlayers();
for (String param : commandSplit) {
String lowerCaseParam = param.toLowerCase();
for (Player p : players) {
if (p.getName().toLowerCase().equals(lowerCaseParam)) {
return p.hasPermission("qol.auditable");
}
}
}
return false;
}
public String noSlash(String command) {
return command.startsWith("/") ? command.substring(1) : command;
}
}