1
mirror of https://github.com/Shiewk/SModeration.git synced 2026-04-28 05:54:16 +02:00

Add mute command, command usages and smaller improvements

This commit is contained in:
Shy
2024-06-08 11:03:56 +02:00
parent 1bb4c2fc47
commit fe4e87d9b4
8 changed files with 174 additions and 5 deletions
@@ -1,7 +1,9 @@
package de.shiewk.smoderation; package de.shiewk.smoderation;
import de.shiewk.smoderation.command.MuteCommand;
import de.shiewk.smoderation.listener.PunishmentListener; import de.shiewk.smoderation.listener.PunishmentListener;
import de.shiewk.smoderation.storage.PunishmentContainer; import de.shiewk.smoderation.storage.PunishmentContainer;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import static org.bukkit.Bukkit.getPluginManager; import static org.bukkit.Bukkit.getPluginManager;
@@ -19,6 +21,11 @@ public final class SModeration extends JavaPlugin {
@Override @Override
public void onEnable() { public void onEnable() {
getPluginManager().registerEvents(new PunishmentListener(), this); getPluginManager().registerEvents(new PunishmentListener(), this);
final PluginCommand mute = getCommand("mute");
assert mute != null;
mute.setExecutor(new MuteCommand());
mute.setTabCompleter(new MuteCommand());
} }
@Override @Override
@@ -0,0 +1,97 @@
package de.shiewk.smoderation.command;
import de.shiewk.smoderation.SModeration;
import de.shiewk.smoderation.punishments.Punishment;
import de.shiewk.smoderation.util.PlayerUtil;
import de.shiewk.smoderation.util.TimeUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.command.*;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MuteCommand implements CommandExecutor, TabCompleter {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (args.length < 2){
return false;
} else {
UUID senderUUID;
if (sender instanceof ConsoleCommandSender){
senderUUID = PlayerUtil.UUID_CONSOLE;
} else if (sender instanceof Player pl){
senderUUID = pl.getUniqueId();
} else if (sender instanceof BlockCommandSender){
sender.sendMessage(Component.text("Blocks can't execute this command.").color(NamedTextColor.RED));
return true;
} else {
sender.sendMessage(Component.text("Your command sender type is unknown (%s).".formatted(sender.getClass().getName())).color(NamedTextColor.RED));
return true;
}
String playerName = args[0];
UUID uuid = PlayerUtil.offlinePlayerUUIDByName(playerName);
if (senderUUID.equals(uuid)) {
sender.sendMessage(Component.text("You can't mute yourself.").color(NamedTextColor.RED));
return true;
}
if (uuid == null) {
sender.sendMessage(Component.text("This player is either offline or was never on this server.").color(NamedTextColor.RED));
return true;
}
long duration = 0;
for (int i = 1 /* start with index 1 to avoid player name */; i < args.length; i++) {
String arg = args[i];
long parsedDuration = TimeUtil.parseDurationMillisSafely(arg);
if (parsedDuration == -1){
break;
} else {
duration += parsedDuration;
}
}
if (duration == 0){
sender.sendMessage(Component.text("Please provide a valid duration.").color(NamedTextColor.RED));
return false;
}
final Punishment punishment = Punishment.mute(System.currentTimeMillis(), System.currentTimeMillis() + duration, senderUUID, uuid);
Punishment.issue(punishment, SModeration.container);
return true;
}
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (args.length < 2){
String toComplete = args.length > 0 ? args[0] : "";
ArrayList<String> names = new ArrayList<>();
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
names.add(onlinePlayer.getName());
}
ArrayList<String> completions = new ArrayList<>();
StringUtil.copyPartialMatches(toComplete, names, completions);
return completions;
} else {
for (int i = 1; i < args.length; i++) {
if (TimeUtil.parseDurationMillisSafely(args[i]) == -1){
return List.of();
}
}
return List.of(
"100ms",
"15s", // some sample completions for duration
"30min", // you can input your own ones as well
"6h",
"1d",
"2w",
"3mo",
"1y"
);
}
}
}
@@ -2,15 +2,17 @@ package de.shiewk.smoderation.event;
import de.shiewk.smoderation.punishments.Punishment; import de.shiewk.smoderation.punishments.Punishment;
import de.shiewk.smoderation.storage.PunishmentContainer; import de.shiewk.smoderation.storage.PunishmentContainer;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class PunishmentIssueEvent extends Event { public class PunishmentIssueEvent extends Event implements Cancellable {
private static final HandlerList handlerList = new HandlerList(); private static final HandlerList handlerList = new HandlerList();
private final Punishment punishment; private final Punishment punishment;
private final PunishmentContainer container; private final PunishmentContainer container;
private boolean cancelled;
public PunishmentIssueEvent(Punishment punishment, PunishmentContainer container) { public PunishmentIssueEvent(Punishment punishment, PunishmentContainer container) {
this.punishment = punishment; this.punishment = punishment;
@@ -33,4 +35,14 @@ public class PunishmentIssueEvent extends Event {
public static HandlerList getHandlerList() { public static HandlerList getHandlerList() {
return handlerList; return handlerList;
} }
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancelled) {
this.cancelled = cancelled;
}
} }
@@ -38,7 +38,7 @@ public class PunishmentListener implements Listener {
} }
} }
@EventHandler(priority = EventPriority.LOW) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPunishmentIssue(PunishmentIssueEvent event){ public void onPunishmentIssue(PunishmentIssueEvent event){
final Punishment punishment = event.getPunishment(); final Punishment punishment = event.getPunishment();
switch (punishment.type){ switch (punishment.type){
@@ -87,8 +87,11 @@ public class Punishment {
} }
public static void issue(Punishment punishment, PunishmentContainer container){ public static void issue(Punishment punishment, PunishmentContainer container){
container.add(punishment); final PunishmentIssueEvent event = new PunishmentIssueEvent(punishment, container);
Bukkit.getPluginManager().callEvent(new PunishmentIssueEvent(punishment, container)); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()){
container.add(punishment);
}
} }
public Component playerMessage(){ public Component playerMessage(){
@@ -2,15 +2,31 @@ package de.shiewk.smoderation.util;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID; import java.util.UUID;
public abstract class PlayerUtil { public abstract class PlayerUtil {
private PlayerUtil(){} private PlayerUtil(){}
public static String offlinePlayerName(UUID uuid){ public static final UUID UUID_CONSOLE = new UUID(0, 0);
public static @NotNull String offlinePlayerName(UUID uuid){
if (uuid.equals(UUID_CONSOLE)){
return "UUID_CONSOLE";
}
OfflinePlayer player = Bukkit.getOfflinePlayer(uuid); OfflinePlayer player = Bukkit.getOfflinePlayer(uuid);
return player.getName() == null ? uuid.toString() : player.getName(); return player.getName() == null ? uuid.toString() : player.getName();
} }
public static @Nullable UUID offlinePlayerUUIDByName(String name){
final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayerIfCached(name);// getOfflinePlayerIfCached(String) is safer (I have experience with getOfflinePlayer(String) returning wrong UUIDs)
if (offlinePlayer != null) {
return offlinePlayer.getUniqueId();
} else {
return null;
}
}
} }
@@ -77,4 +77,34 @@ public abstract class TimeUtil {
return builder.toString(); return builder.toString();
} }
public static long parseDurationMillisSafely(String in){
try {
return parseDurationMillis(in);
} catch (Throwable e){
return -1;
}
}
public static long parseDurationMillis(String in){
if (in.endsWith("ms")){
return Long.parseLong(in.substring(0, in.length()-2));
} else if (in.endsWith("s")){
return Long.parseLong(in.substring(0, in.length()-1)) * 1000L;
} else if (in.endsWith("min")){
return Long.parseLong(in.substring(0, in.length()-3)) * 60000L;
} else if (in.endsWith("h")){
return Long.parseLong(in.substring(0, in.length()-1)) * 3600000L;
} else if (in.endsWith("d")){
return Long.parseLong(in.substring(0, in.length()-1)) * 86400000L;
} else if (in.endsWith("w")){
return Long.parseLong(in.substring(0, in.length()-1)) * 604800000L;
} else if (in.endsWith("mo")){
return Long.parseLong(in.substring(0, in.length()-2)) * 2592000000L;
} else if (in.endsWith("y")){
return Long.parseLong(in.substring(0, in.length()-1)) * 31536000000L;
} else {
return -1;
}
}
} }
+4
View File
@@ -5,22 +5,26 @@ api-version: '1.20'
load: STARTUP load: STARTUP
commands: commands:
mute: mute:
usage: /mute <player> <duration>
aliases: aliases:
- smodmute - smodmute
permission: smod.mute permission: smod.mute
description: Mutes a player, either temporarily or permanently. description: Mutes a player, either temporarily or permanently.
ban: ban:
usage: /ban <player> <duration>
aliases: aliases:
- smodban - smodban
- tempban - tempban
permission: smod.ban permission: smod.ban
description: Bans a player, either temporarily or permanently. description: Bans a player, either temporarily or permanently.
kick: kick:
usage: /kick <player>
aliases: aliases:
- smodkick - smodkick
permission: smod.kick permission: smod.kick
description: Kicks a player description: Kicks a player
smod: smod:
usage: /smod
aliases: aliases:
- smodmenu - smodmenu
- smoderation - smoderation