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:
@@ -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";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user