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

First version of the SMod menu and command

This commit is contained in:
Shy
2024-06-08 15:22:24 +02:00
parent e2fcf9797c
commit 1f85d65bdd
8 changed files with 238 additions and 4 deletions
@@ -3,6 +3,7 @@ package de.shiewk.smoderation;
import de.shiewk.smoderation.command.BanCommand; import de.shiewk.smoderation.command.BanCommand;
import de.shiewk.smoderation.command.KickCommand; import de.shiewk.smoderation.command.KickCommand;
import de.shiewk.smoderation.command.MuteCommand; import de.shiewk.smoderation.command.MuteCommand;
import de.shiewk.smoderation.command.SModCommand;
import de.shiewk.smoderation.event.CustomInventoryEvents; import de.shiewk.smoderation.event.CustomInventoryEvents;
import de.shiewk.smoderation.listener.PunishmentListener; import de.shiewk.smoderation.listener.PunishmentListener;
import de.shiewk.smoderation.storage.PunishmentContainer; import de.shiewk.smoderation.storage.PunishmentContainer;
@@ -40,6 +41,11 @@ public final class SModeration extends JavaPlugin {
assert kick != null; assert kick != null;
kick.setExecutor(new KickCommand()); kick.setExecutor(new KickCommand());
kick.setTabCompleter(new KickCommand()); kick.setTabCompleter(new KickCommand());
final PluginCommand smod = getCommand("smod");
assert smod != null;
smod.setExecutor(new SModCommand());
smod.setTabCompleter(new SModCommand());
} }
@Override @Override
@@ -0,0 +1,28 @@
package de.shiewk.smoderation.command;
import de.shiewk.smoderation.SModeration;
import de.shiewk.smoderation.inventory.SModMenu;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class SModCommand implements CommandExecutor, TabCompleter {
@Override
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
if (commandSender instanceof Player player){
new SModMenu(player, SModeration.container).open();
}
return true;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, @NotNull String[] strings) {
return List.of();
}
}
@@ -0,0 +1,103 @@
package de.shiewk.smoderation.inventory;
import de.shiewk.smoderation.punishments.Punishment;
import de.shiewk.smoderation.punishments.PunishmentType;
import de.shiewk.smoderation.storage.PunishmentContainer;
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 net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
public class SModMenu extends PageableCustomInventory {
private final Inventory inventory;
private final Player player;
private final ArrayList<Punishment> punishments;
public SModMenu(Player player, PunishmentContainer container) {
this.player = player;
this.inventory = Bukkit.createInventory(this, 54, Component.text("SMod Menu"));
punishments = container.copy();
}
@Override
public int lastPage() {
return Math.max((punishments.size() - 1) / 45, 0);
}
@Override
public void switchPage() {
player.playSound(player, Sound.BLOCK_STONE_HIT, 0.75f, 1f);
}
private ItemStack createPunishmentItem(Punishment punishment){
final NamedTextColor PRIMARY_COLOR = NamedTextColor.AQUA;
final NamedTextColor SECONDARY_COLOR = NamedTextColor.GREEN;
ItemStack stack = new ItemStack(Material.PLAYER_HEAD);
stack.editMeta(meta -> {
if (meta instanceof SkullMeta skullMeta){
skullMeta.setOwningPlayer(Bukkit.getOfflinePlayer(punishment.to));
}
meta.displayName(applyFormatting(Component.text(punishment.type.name).color(NamedTextColor.RED).decorate(TextDecoration.BOLD)));
ArrayList<Component> lore = new ArrayList<>();
lore.add(applyFormatting(Component.text("Player: ").color(SECONDARY_COLOR).append(Component.text(PlayerUtil.offlinePlayerName(punishment.to)).color(PRIMARY_COLOR))));
lore.add(applyFormatting(Component.text("Punished by: ").color(SECONDARY_COLOR).append(Component.text(PlayerUtil.offlinePlayerName(punishment.by)).color(PRIMARY_COLOR))));
lore.add(applyFormatting(Component.text("Timestamp: ").color(SECONDARY_COLOR).append(Component.text(TimeUtil.calendarTimestamp(punishment.time)).color(PRIMARY_COLOR))));
if (punishment.type != PunishmentType.KICK){
lore.add(applyFormatting(Component.text("Duration: ").color(SECONDARY_COLOR).append(Component.text(TimeUtil.formatTimeLong(punishment.until - punishment.time)).color(PRIMARY_COLOR))));
long remainingTime = punishment.until - System.currentTimeMillis();
final String expires;
if (remainingTime > 0){
expires = "in " + TimeUtil.formatTimeLong(remainingTime);
} else {
remainingTime *= -1;
expires = TimeUtil.formatTimeLong(remainingTime) + " ago";
}
lore.add(applyFormatting(Component.text("Expires: ").color(SECONDARY_COLOR).append(Component.text(expires).color(PRIMARY_COLOR))));
}
lore.add(applyFormatting(Component.text("Reason: ").color(SECONDARY_COLOR).append(Component.text(punishment.reason).color(PRIMARY_COLOR))));
meta.lore(lore);
});
return stack;
}
@Override
public void refresh() {
for (int i = 45; i < 54; i++) {
inventory.setItem(i, createEmptyStack());
}
inventory.setItem(45, createPreviousPageStack());
inventory.setItem(53, createNextPageStack());
for (int i = 0; i < 45; i++) {
int ci = i + (getPage() * 45);
if (punishments.size() > ci){
inventory.setItem(i, createPunishmentItem(punishments.get(ci)));
} else {
inventory.setItem(i, new ItemStack(Material.AIR));
}
}
}
@Override
public void open() {
refresh();
player.openInventory(this.inventory);
}
@Override
public @NotNull Inventory getInventory() {
return inventory;
}
}
@@ -46,6 +46,7 @@ public class PunishmentListener implements Listener {
final Punishment duplicate = container.find(p -> p.to.equals(punishment.to) && p.type == punishment.type && p.until >= punishment.time); final Punishment duplicate = container.find(p -> p.to.equals(punishment.to) && p.type == punishment.type && p.until >= punishment.time);
if (duplicate != null){ if (duplicate != null){
container.remove(duplicate); container.remove(duplicate);
container.add(new Punishment(duplicate.type, duplicate.time, System.currentTimeMillis(), duplicate.by, duplicate.to, duplicate.reason));
} }
switch (punishment.type){ switch (punishment.type){
case KICK, BAN -> { case KICK, BAN -> {
@@ -26,7 +26,7 @@ public class Punishment {
public final UUID to; public final UUID to;
public final String reason; public final String reason;
protected Punishment(PunishmentType type, long time, long until, UUID by, UUID to, String reason) { public Punishment(PunishmentType type, long time, long until, UUID by, UUID to, String reason) {
this.type = type; this.type = type;
this.time = time; this.time = time;
this.until = until; this.until = until;
@@ -1,7 +1,13 @@
package de.shiewk.smoderation.punishments; package de.shiewk.smoderation.punishments;
public enum PunishmentType { public enum PunishmentType {
MUTE, MUTE("Mute"),
KICK, KICK("Kick"),
BAN BAN("Ban");
public final String name;
PunishmentType(String name) {
this.name = name;
}
} }
@@ -53,4 +53,8 @@ public class PunishmentContainer {
public @Nullable Punishment findByTimestamp(long timestamp){ public @Nullable Punishment findByTimestamp(long timestamp){
return find(punishment -> punishment.time == timestamp); return find(punishment -> punishment.time == timestamp);
} }
public ArrayList<Punishment> copy() {
return new ArrayList<>(punishments);
}
} }
@@ -1,5 +1,11 @@
package de.shiewk.smoderation.util; package de.shiewk.smoderation.util;
import org.jetbrains.annotations.Range;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public abstract class TimeUtil { public abstract class TimeUtil {
private TimeUtil(){} private TimeUtil(){}
@@ -112,4 +118,84 @@ public abstract class TimeUtil {
return -1; return -1;
} }
} }
public static String calendarTimestamp(long time){
Date date = new Date(time);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
TimeZone zone = calendar.getTimeZone();
int second = calendar.get(Calendar.SECOND);
int minute = calendar.get(Calendar.MINUTE);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int year = calendar.get(Calendar.YEAR);
String day = numberWithSuffix(calendar.get(Calendar.DAY_OF_MONTH));
String month = monthName(calendar.get(Calendar.MONTH));
return "%s %s %s, %s:%s:%s %s".formatted(
month,
day,
year,
hour < 10 ? "0" + hour : hour,
minute < 10 ? "0" + minute : minute,
second < 10 ? "0" + second : second,
zone.getDisplayName(false, TimeZone.SHORT)
);
}
private static String numberWithSuffix(int i){
return i + numberSuffix(i);
}
private static String numberSuffix(int i){
if ((i % 10) == 1 && i != 11){
return "st";
} else if ((i % 10) == 2 && i != 12){
return "nd";
} else if ((i % 10) == 3 && i != 13){
return "rd";
}
return "th";
}
public static String monthName(@Range(from = 0, to = 11) int m){
switch (m){
case 0 -> {
return "January";
}
case 1 -> {
return "February";
}
case 2 -> {
return "March";
}
case 3 -> {
return "April";
}
case 4 -> {
return "May";
}
case 5 -> {
return "June";
}
case 6 -> {
return "July";
}
case 7 -> {
return "August";
}
case 8 -> {
return "September";
}
case 9 -> {
return "October";
}
case 10 -> {
return "November";
}
case 11 -> {
return "December";
}
}
return "Unknown Month";
}
} }