mirror of
https://github.com/Shiewk/SModeration.git
synced 2026-04-29 06:34:17 +02:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
041c541356
|
|||
|
dcb52e3e6d
|
|||
|
53df1a908a
|
|||
| 3317e2fffd | |||
| 4b52f74fc5 | |||
| 4ef2700d6b | |||
| 7826c4e75a | |||
| c4953d2acb | |||
| 7e3139126c | |||
| 2be16da939 | |||
| a17086b059 | |||
| 039b40bd53 | |||
| a69c7cb426 | |||
| 8a147eb7cf | |||
| ecdd688a79 | |||
| 26166b5a73 | |||
| 27a1fd8244 | |||
| 66c113bad2 | |||
| d863622168 | |||
| 361f66f645 | |||
| fbaaa6ec89 | |||
| 955ab8791a | |||
| 8128628b12 | |||
| 02570993a7 | |||
| 0d095c40f0 | |||
| 8df1029d42 | |||
| 2f66c6f12c | |||
| 1f9758f3d0 | |||
| c7502fd661 | |||
| 1a9cf76a93 | |||
| b3ec076cae | |||
| 3cb3314f4c | |||
| fb785fb53a | |||
| e44f6489af | |||
| 7e90939b84 | |||
| 4266b7ebb6 |
@@ -14,7 +14,7 @@ SModeration provides a nice user interface that can be used instead of chat comm
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
It has helpful functions like filtering and sorting options.
|
It has helpful functions like filtering, searching and sorting options.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
This plugin has many commands, for a complete list of commands and their usage, please see [the commands list](https://github.com/Shiewk/SModeration/blob/main/docs/commands.md).
|
This plugin has many commands, for a complete list of commands and their usage, please see [the commands list](https://github.com/Shiewk/SModeration/blob/main/docs/commands.md).
|
||||||
|
|||||||
+33
-14
@@ -1,5 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
|
id("xyz.jpenilla.run-paper") version "2.3.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = 'de.shiewk'
|
group = 'de.shiewk'
|
||||||
@@ -11,17 +12,44 @@ repositories {
|
|||||||
name = "papermc-repo"
|
name = "papermc-repo"
|
||||||
url = "https://repo.papermc.io/repository/maven-public/"
|
url = "https://repo.papermc.io/repository/maven-public/"
|
||||||
}
|
}
|
||||||
maven {
|
}
|
||||||
name = "sonatype"
|
|
||||||
url = "https://oss.sonatype.org/content/groups/public/"
|
processResources {
|
||||||
|
def props = [version: version]
|
||||||
|
inputs.properties props
|
||||||
|
filteringCharset 'UTF-8'
|
||||||
|
filesMatching('paper-plugin.yml') {
|
||||||
|
expand props
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runPaper {
|
||||||
|
folia {
|
||||||
|
registerTask()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runServer {
|
||||||
|
minecraftVersion("1.21.10")
|
||||||
|
downloadPlugins {
|
||||||
|
// for testing from other client versions
|
||||||
|
modrinth("ViaVersion", "5.5.1")
|
||||||
|
modrinth("ViaBackwards", "5.5.1")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly "io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT"
|
//compileOnly "io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT"
|
||||||
|
compileOnly 'dev.folia:folia-api:1.21.4-R0.1-SNAPSHOT'
|
||||||
}
|
}
|
||||||
|
|
||||||
def targetJavaVersion = 17
|
jar {
|
||||||
|
archiveBaseName.set('SModeration-Paper')
|
||||||
|
archiveVersion.set(pluginVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def targetJavaVersion = 21
|
||||||
java {
|
java {
|
||||||
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
|
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
|
||||||
sourceCompatibility = javaVersion
|
sourceCompatibility = javaVersion
|
||||||
@@ -38,12 +66,3 @@ tasks.withType(JavaCompile).configureEach {
|
|||||||
options.release.set(targetJavaVersion)
|
options.release.set(targetJavaVersion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
|
||||||
def props = [version: version]
|
|
||||||
inputs.properties props
|
|
||||||
filteringCharset 'UTF-8'
|
|
||||||
filesMatching('plugin.yml') {
|
|
||||||
expand props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-1
@@ -13,6 +13,6 @@
|
|||||||
| /invsee \<player> equipment | Views another player's equipment (armor and offhand). | smod.invsee |
|
| /invsee \<player> equipment | Views another player's equipment (armor and offhand). | smod.invsee |
|
||||||
| /enderchestsee <player> | Views another player's ender chest. | smod.enderchestsee |
|
| /enderchestsee <player> | Views another player's ender chest. | smod.enderchestsee |
|
||||||
| /vanish | Toggles vanish mode so that other players can't see you're online. | smod.vanish |
|
| /vanish | Toggles vanish mode so that other players can't see you're online. | smod.vanish |
|
||||||
| /vanish toggle \<player> | Toggles vanish mode for another player. | smod.vanish |
|
| /vanish toggle \<players> | Toggles vanish mode for other players. | smod.vanish |
|
||||||
| /vanish list | Lists all vanished players. | smod.vanish.see |
|
| /vanish list | Lists all vanished players. | smod.vanish.see |
|
||||||
| /socialspy | Enables SocialSpy mode where you can see other player's private messages. | smod.socialspy |
|
| /socialspy | Enables SocialSpy mode where you can see other player's private messages. | smod.socialspy |
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# SModeration config
|
||||||
|
|
||||||
|
| Key | What it does |
|
||||||
|
|--------------------------|------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| socialspy-commands | The commands that `/socialspy` will listen to. |
|
||||||
|
| force-reason | Whether a reason is required for every punishment. |
|
||||||
|
| muted-forbidden-commands | Commands that players are not allowed to run while they are muted. |
|
||||||
|
| features | Controls which plugin features are enabled. |
|
||||||
|
| features.punishments | Whether the plugin provides punishing features (kick, ban, mute) |
|
||||||
|
| features.smodmenu | If punishments are enabled, controls whether the SMod Menu can be opened. Has no effect when punishments are disabled. |
|
||||||
|
| features.invsee | Whether the plugin provides invsee feature |
|
||||||
|
| features.enderchestsee | Whether the plugin provides enderchestsee feature |
|
||||||
|
| features.offlinetp | Whether the plugin provides the offlinetp feature |
|
||||||
|
| features.socialspy | Whether the plugin provides the SocialSpy feature |
|
||||||
|
| features.vanish | Whether the plugin provides the vanish feature |
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
pluginVersion = 1.4.0
|
pluginVersion = 1.8.2
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
package de.shiewk.smoderation;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.command.*;
|
|
||||||
import de.shiewk.smoderation.config.SModerationConfig;
|
|
||||||
import de.shiewk.smoderation.input.ChatInputListener;
|
|
||||||
import de.shiewk.smoderation.listener.*;
|
|
||||||
import de.shiewk.smoderation.storage.PunishmentContainer;
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
|
||||||
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.PluginCommand;
|
|
||||||
import org.bukkit.command.TabExecutor;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import static de.shiewk.smoderation.command.VanishCommand.isVanished;
|
|
||||||
import static de.shiewk.smoderation.command.VanishCommand.toggleVanish;
|
|
||||||
import static net.kyori.adventure.text.Component.text;
|
|
||||||
import static org.bukkit.Bukkit.getPluginManager;
|
|
||||||
|
|
||||||
public final class SModeration extends JavaPlugin {
|
|
||||||
|
|
||||||
public static final PunishmentContainer container = new PunishmentContainer();
|
|
||||||
public static ComponentLogger LOGGER = null;
|
|
||||||
public static SModeration PLUGIN = null;
|
|
||||||
public static SModerationConfig CONFIG = null;
|
|
||||||
public static File SAVE_FILE = null;
|
|
||||||
|
|
||||||
public static final TextColor PRIMARY_COLOR = TextColor.color(212, 0, 255);
|
|
||||||
public static final TextColor SECONDARY_COLOR = TextColor.color(52, 143, 255);
|
|
||||||
public static final TextColor INACTIVE_COLOR = NamedTextColor.GRAY;
|
|
||||||
public static final TextColor FAIL_COLOR = NamedTextColor.RED;
|
|
||||||
public static final TextComponent CHAT_PREFIX = text("SM \u00BB ").color(PRIMARY_COLOR);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
LOGGER = getComponentLogger();
|
|
||||||
PLUGIN = this;
|
|
||||||
CONFIG = new SModerationConfig(this.getConfig(), this);
|
|
||||||
SAVE_FILE = new File(this.getDataFolder().getAbsolutePath() + "/container.gz");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable() {
|
|
||||||
getPluginManager().registerEvents(new PunishmentListener(), this);
|
|
||||||
getPluginManager().registerEvents(new CustomInventoryListener(), this);
|
|
||||||
getPluginManager().registerEvents(new InvSeeListener(), this);
|
|
||||||
getPluginManager().registerEvents(new EnderchestSeeListener(), this);
|
|
||||||
getPluginManager().registerEvents(new VanishListener(), this);
|
|
||||||
getPluginManager().registerEvents(new ChatInputListener(), this);
|
|
||||||
getPluginManager().registerEvents(new SocialSpyListener(), this);
|
|
||||||
|
|
||||||
registerCommand("mute", new MuteCommand());
|
|
||||||
registerCommand("ban", new BanCommand());
|
|
||||||
registerCommand("kick", new KickCommand());
|
|
||||||
registerCommand("smod", new SModCommand());
|
|
||||||
registerCommand("modlogs", new ModLogsCommand());
|
|
||||||
registerCommand("unmute", new UnmuteCommand());
|
|
||||||
registerCommand("unban", new UnbanCommand());
|
|
||||||
registerCommand("invsee", new InvseeCommand());
|
|
||||||
registerCommand("enderchestsee", new EnderchestSeeCommand());
|
|
||||||
registerCommand("vanish", new VanishCommand());
|
|
||||||
registerCommand("socialspy", new SocialSpyCommand());
|
|
||||||
|
|
||||||
container.load(SAVE_FILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerCommand(String label, TabExecutor executor){
|
|
||||||
final PluginCommand command = getCommand(label);
|
|
||||||
if (command != null) {
|
|
||||||
command.setExecutor(executor);
|
|
||||||
command.setTabCompleter(executor);
|
|
||||||
} else {
|
|
||||||
LOGGER.warn("Command %s failed to register: This command does not exist".formatted(label));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisable() {
|
|
||||||
SModeration.container.save(SModeration.SAVE_FILE);
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
|
||||||
// in case players are still vanished when the server shuts down
|
|
||||||
if (isVanished(player)){
|
|
||||||
toggleVanish(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
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;
|
|
||||||
|
|
||||||
import static net.kyori.adventure.text.Component.text;
|
|
||||||
|
|
||||||
public class BanCommand implements TabExecutor {
|
|
||||||
@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 ban 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;
|
|
||||||
}
|
|
||||||
final Player toPlayer = Bukkit.getPlayer(uuid);
|
|
||||||
if (toPlayer != null && toPlayer.hasPermission("smod.preventban")){
|
|
||||||
sender.sendMessage(text().content("This player can't be banned.").color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
long duration = 0;
|
|
||||||
int p = 1;
|
|
||||||
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){
|
|
||||||
p = i;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
duration += parsedDuration;
|
|
||||||
}
|
|
||||||
if (i == args.length - 1){ p = args.length; }
|
|
||||||
}
|
|
||||||
if (duration == 0){
|
|
||||||
sender.sendMessage(Component.text("Please provide a valid duration.").color(NamedTextColor.RED));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (duration < 0){
|
|
||||||
sender.sendMessage(Component.text("Please provide a duration that's longer than 0ms.").color(NamedTextColor.RED));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
StringBuilder reason = new StringBuilder();
|
|
||||||
for (int i = p; i < args.length; i++) {
|
|
||||||
if (!reason.isEmpty()){
|
|
||||||
reason.append(" ");
|
|
||||||
}
|
|
||||||
reason.append(args[i]);
|
|
||||||
}
|
|
||||||
final Punishment punishment = Punishment.ban(System.currentTimeMillis(), System.currentTimeMillis() + duration, senderUUID, uuid, reason.isEmpty() ? Punishment.DEFAULT_REASON : reason.toString());
|
|
||||||
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){
|
|
||||||
try {
|
|
||||||
Long.parseLong(args[i]);
|
|
||||||
} catch (NumberFormatException ignored){
|
|
||||||
if (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"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package de.shiewk.smoderation.command;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.util.PlayerUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.command.TabExecutor;
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
|
||||||
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 static de.shiewk.smoderation.SModeration.*;
|
|
||||||
|
|
||||||
public class EnderchestSeeCommand implements TabExecutor {
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
if (args.length < 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (sender instanceof HumanEntity human){
|
|
||||||
final Player player = PlayerUtil.findOnlinePlayer(args[0]);
|
|
||||||
if (player != null) {
|
|
||||||
if (human.getUniqueId().equals(player.getUniqueId())){
|
|
||||||
human.sendMessage(Component.text("You can't open your own ender chest.").color(FAIL_COLOR));
|
|
||||||
} else {
|
|
||||||
human.sendMessage(CHAT_PREFIX.append(
|
|
||||||
Component.text("Opening ender chest of ").color(PRIMARY_COLOR)
|
|
||||||
.append(Component.text(player.getName()).color(SECONDARY_COLOR))
|
|
||||||
.append(Component.text("."))
|
|
||||||
));
|
|
||||||
human.openInventory(player.getEnderChest());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
human.sendMessage(Component.text("This player is not online.").color(FAIL_COLOR));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(Component.text("Only an entity that can open inventories can execute this command!").color(FAIL_COLOR));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
if (args.length > 1){
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
List<String> available = new ArrayList<>();
|
|
||||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
|
||||||
available.add(onlinePlayer.getName());
|
|
||||||
}
|
|
||||||
List<String> completions = new ArrayList<>();
|
|
||||||
StringUtil.copyPartialMatches(args.length > 0 ? args[0] : "", available, completions);
|
|
||||||
return completions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
package de.shiewk.smoderation.command;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.inventory.InvSeeEquipmentInventory;
|
|
||||||
import de.shiewk.smoderation.util.PlayerUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.command.TabExecutor;
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
|
||||||
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 static de.shiewk.smoderation.SModeration.*;
|
|
||||||
|
|
||||||
public class InvseeCommand implements TabExecutor {
|
|
||||||
|
|
||||||
private enum InvseeType {
|
|
||||||
INVENTORY,
|
|
||||||
EQUIPMENT
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
if (args.length < 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final InvseeType type;
|
|
||||||
if (args.length > 1){
|
|
||||||
switch (args[1].toLowerCase()){
|
|
||||||
case "armor", "equipment" -> type = InvseeType.EQUIPMENT;
|
|
||||||
default -> type = InvseeType.INVENTORY;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
type = InvseeType.INVENTORY;
|
|
||||||
}
|
|
||||||
if (sender instanceof HumanEntity human){
|
|
||||||
final Player player = PlayerUtil.findOnlinePlayer(args[0]);
|
|
||||||
if (player != null) {
|
|
||||||
if (human.getUniqueId().equals(player.getUniqueId()) && type != InvseeType.EQUIPMENT){
|
|
||||||
human.sendMessage(Component.text("You can't open your own inventory.").color(FAIL_COLOR));
|
|
||||||
} else {
|
|
||||||
human.sendMessage(CHAT_PREFIX.append(
|
|
||||||
Component.text("Opening inventory of ").color(PRIMARY_COLOR)
|
|
||||||
.append(Component.text(player.getName()).color(SECONDARY_COLOR))
|
|
||||||
.append(Component.text("."))
|
|
||||||
));
|
|
||||||
switch (type){
|
|
||||||
case INVENTORY -> human.openInventory(player.getInventory());
|
|
||||||
case EQUIPMENT -> new InvSeeEquipmentInventory(human, player).open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
human.sendMessage(Component.text("This player is not online.").color(FAIL_COLOR));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(Component.text("Only an entity that can open inventories can execute this command!").color(FAIL_COLOR));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
if (args.length > 2){
|
|
||||||
return List.of();
|
|
||||||
} else if (args.length > 1){
|
|
||||||
return List.of("armor", "equipment", "inventory");
|
|
||||||
}
|
|
||||||
List<String> available = new ArrayList<>();
|
|
||||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
|
||||||
available.add(onlinePlayer.getName());
|
|
||||||
}
|
|
||||||
List<String> completions = new ArrayList<>();
|
|
||||||
StringUtil.copyPartialMatches(args.length > 0 ? args[0] : "", available, completions);
|
|
||||||
return completions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package de.shiewk.smoderation.command;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.SModeration;
|
|
||||||
import de.shiewk.smoderation.punishments.Punishment;
|
|
||||||
import de.shiewk.smoderation.util.PlayerUtil;
|
|
||||||
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;
|
|
||||||
|
|
||||||
import static net.kyori.adventure.text.Component.text;
|
|
||||||
|
|
||||||
public class KickCommand implements TabExecutor {
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
if (args.length < 1){
|
|
||||||
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];
|
|
||||||
Player player = Bukkit.getPlayer(playerName);
|
|
||||||
if (player == null) {
|
|
||||||
sender.sendMessage(Component.text("This player is not online.").color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
UUID uuid = player.getUniqueId();
|
|
||||||
if (senderUUID.equals(uuid)) {
|
|
||||||
sender.sendMessage(Component.text("You can't kick yourself.").color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (player.hasPermission("smod.preventkick")){
|
|
||||||
sender.sendMessage(text().content("This player can't be kicked.").color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
StringBuilder reason = new StringBuilder();
|
|
||||||
for (int i = 1; i < args.length; i++) {
|
|
||||||
if (!reason.isEmpty()){
|
|
||||||
reason.append(" ");
|
|
||||||
}
|
|
||||||
reason.append(args[i]);
|
|
||||||
}
|
|
||||||
final Punishment punishment = Punishment.kick(System.currentTimeMillis(), senderUUID, uuid, reason.isEmpty() ? Punishment.DEFAULT_REASON : reason.toString());
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
package de.shiewk.smoderation.command;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.SModeration;
|
|
||||||
import de.shiewk.smoderation.punishments.Punishment;
|
|
||||||
import de.shiewk.smoderation.punishments.PunishmentType;
|
|
||||||
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.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.command.TabExecutor;
|
|
||||||
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;
|
|
||||||
|
|
||||||
import static de.shiewk.smoderation.SModeration.*;
|
|
||||||
|
|
||||||
public class ModLogsCommand implements TabExecutor {
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
if (args.length < 1){
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
String playername = args[0];
|
|
||||||
String name;
|
|
||||||
UUID uuid;
|
|
||||||
try {
|
|
||||||
uuid = UUID.fromString(playername);
|
|
||||||
} catch (IllegalArgumentException ignored){
|
|
||||||
uuid = PlayerUtil.offlinePlayerUUIDByName(playername);
|
|
||||||
}
|
|
||||||
if (uuid == null){
|
|
||||||
sender.sendMessage(Component.text("This player was not found. Try running /%s with an UUID instead.".formatted(label)).color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
name = PlayerUtil.offlinePlayerName(uuid);
|
|
||||||
sender.sendMessage(CHAT_PREFIX.append(Component.text("Player ").color(PRIMARY_COLOR)
|
|
||||||
.append(Component.text(name).color(SECONDARY_COLOR))
|
|
||||||
.append(Component.text(" (%s)".formatted(uuid)).color(INACTIVE_COLOR))));
|
|
||||||
UUID finalUuid = uuid;
|
|
||||||
final List<Punishment> punishments = SModeration.container.findAll(p -> p.to.equals(finalUuid) && p.isActive());
|
|
||||||
for (Punishment punishment : punishments) {
|
|
||||||
sender.sendMessage(Component.text("- is currently ").color(PRIMARY_COLOR)
|
|
||||||
.append(Component.text(punishment.type == PunishmentType.BAN ? "banned" : "muted").color(SECONDARY_COLOR))
|
|
||||||
.append(Component.text(" until ").color(PRIMARY_COLOR))
|
|
||||||
.append(Component.text(TimeUtil.calendarTimestamp(punishment.until)).color(SECONDARY_COLOR))
|
|
||||||
.append(Component.text(" (in %s)".formatted(TimeUtil.formatTimeLong(punishment.until - System.currentTimeMillis()))).color(INACTIVE_COLOR))
|
|
||||||
.append(Component.text(". Reason: ").color(PRIMARY_COLOR))
|
|
||||||
.append(Component.text(punishment.reason).color(SECONDARY_COLOR)));
|
|
||||||
}
|
|
||||||
if (punishments.isEmpty()){
|
|
||||||
sender.sendMessage(Component.text("- has no punishments.").color(PRIMARY_COLOR));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
if (args.length > 1){
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
String search = args.length > 0 ? args[0] : "";
|
|
||||||
List<String> playernames = new ArrayList<>();
|
|
||||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
|
||||||
playernames.add(onlinePlayer.getName());
|
|
||||||
}
|
|
||||||
List<String> completions = new ArrayList<>();
|
|
||||||
StringUtil.copyPartialMatches(search, playernames, completions);
|
|
||||||
return completions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
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.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;
|
|
||||||
|
|
||||||
import static net.kyori.adventure.text.Component.text;
|
|
||||||
|
|
||||||
public class MuteCommand implements TabExecutor {
|
|
||||||
@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(text("Blocks can't execute this command.").color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(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(text("You can't mute yourself.").color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (uuid == null) {
|
|
||||||
sender.sendMessage(text("This player is either offline or was never on this server.").color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
final Player toPlayer = Bukkit.getPlayer(uuid);
|
|
||||||
if (toPlayer != null && toPlayer.hasPermission("smod.preventmute")){
|
|
||||||
sender.sendMessage(text().content("This player can't be muted.").color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
long duration = 0;
|
|
||||||
int p = 1;
|
|
||||||
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){
|
|
||||||
p = i;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
duration += parsedDuration;
|
|
||||||
}
|
|
||||||
if (i == args.length - 1){ p = args.length; }
|
|
||||||
}
|
|
||||||
if (duration == 0){
|
|
||||||
sender.sendMessage(text("Please provide a valid duration.").color(NamedTextColor.RED));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (duration < 0){
|
|
||||||
sender.sendMessage(text("Please provide a duration that's longer than 0ms.").color(NamedTextColor.RED));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
StringBuilder reason = new StringBuilder();
|
|
||||||
for (int i = p; i < args.length; i++) {
|
|
||||||
if (!reason.isEmpty()){
|
|
||||||
reason.append(" ");
|
|
||||||
}
|
|
||||||
reason.append(args[i]);
|
|
||||||
}
|
|
||||||
final Punishment punishment = Punishment.mute(System.currentTimeMillis(), System.currentTimeMillis() + duration, senderUUID, uuid, reason.isEmpty() ? Punishment.DEFAULT_REASON : reason.toString());
|
|
||||||
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){
|
|
||||||
try {
|
|
||||||
Long.parseLong(args[i]);
|
|
||||||
} catch (NumberFormatException ignored){
|
|
||||||
if (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"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
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.CommandSender;
|
|
||||||
import org.bukkit.command.TabExecutor;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SModCommand implements TabExecutor {
|
|
||||||
@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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
package de.shiewk.smoderation.command;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.listener.SocialSpyListener;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.command.TabExecutor;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static de.shiewk.smoderation.SModeration.CHAT_PREFIX;
|
|
||||||
import static net.kyori.adventure.text.Component.text;
|
|
||||||
|
|
||||||
public class SocialSpyCommand implements TabExecutor {
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
final boolean enabled = SocialSpyListener.toggle(sender);
|
|
||||||
sender.sendMessage(CHAT_PREFIX.append(text("SocialSpy ").append(
|
|
||||||
enabled ?
|
|
||||||
text("enabled").color(NamedTextColor.GREEN) :
|
|
||||||
text("disabled").color(NamedTextColor.RED)
|
|
||||||
).append(text("."))));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package de.shiewk.smoderation.command;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.SModeration;
|
|
||||||
import de.shiewk.smoderation.punishments.Punishment;
|
|
||||||
import de.shiewk.smoderation.punishments.PunishmentType;
|
|
||||||
import de.shiewk.smoderation.util.PlayerUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class UnbanCommand implements TabExecutor {
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
if (args.length < 1){
|
|
||||||
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 nameArg = args[0];
|
|
||||||
UUID uuid;
|
|
||||||
try {
|
|
||||||
uuid = UUID.fromString(nameArg);
|
|
||||||
} catch (IllegalArgumentException ignored){
|
|
||||||
uuid = PlayerUtil.offlinePlayerUUIDByName(nameArg);
|
|
||||||
}
|
|
||||||
if (uuid == null){
|
|
||||||
sender.sendMessage(Component.text("This player was not found. Try running /%s with an UUID instead.".formatted(label)).color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
UUID finalUuid = uuid;
|
|
||||||
final Punishment punishment = SModeration.container.find(p -> p.to.equals(finalUuid) && p.isActive() && p.type == PunishmentType.BAN);
|
|
||||||
if (punishment != null) {
|
|
||||||
punishment.undo(senderUUID);
|
|
||||||
punishment.broadcastUndo(SModeration.container);
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(Component.text("This player is not banned.").color(NamedTextColor.RED));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package de.shiewk.smoderation.command;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.SModeration;
|
|
||||||
import de.shiewk.smoderation.punishments.Punishment;
|
|
||||||
import de.shiewk.smoderation.punishments.PunishmentType;
|
|
||||||
import de.shiewk.smoderation.util.PlayerUtil;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import org.bukkit.command.*;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class UnmuteCommand implements TabExecutor {
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
if (args.length < 1){
|
|
||||||
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 nameArg = args[0];
|
|
||||||
UUID uuid;
|
|
||||||
try {
|
|
||||||
uuid = UUID.fromString(nameArg);
|
|
||||||
} catch (IllegalArgumentException ignored){
|
|
||||||
uuid = PlayerUtil.offlinePlayerUUIDByName(nameArg);
|
|
||||||
}
|
|
||||||
if (uuid == null){
|
|
||||||
sender.sendMessage(Component.text("This player was not found. Try running /%s with an UUID instead.".formatted(label)).color(NamedTextColor.RED));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
UUID finalUuid = uuid;
|
|
||||||
final Punishment punishment = SModeration.container.find(p -> p.to.equals(finalUuid) && p.isActive() && p.type == PunishmentType.MUTE);
|
|
||||||
if (punishment != null) {
|
|
||||||
punishment.undo(senderUUID);
|
|
||||||
punishment.broadcastUndo(SModeration.container);
|
|
||||||
} else {
|
|
||||||
sender.sendMessage(Component.text("This player is not muted.").color(NamedTextColor.RED));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||||
package de.shiewk.smoderation.command;
|
|
||||||||
|
|
||||||||
import de.shiewk.smoderation.SModeration;
|
|
||||||||
import de.shiewk.smoderation.util.PlayerUtil;
|
|
||||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
||||||||
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
|
|
||||||||
import net.kyori.adventure.text.Component;
|
|
||||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||||
import org.bukkit.Bukkit;
|
|
||||||||
import org.bukkit.command.Command;
|
|
||||||||
import org.bukkit.command.CommandSender;
|
|
||||||||
import org.bukkit.command.TabExecutor;
|
|
||||||||
import org.bukkit.entity.Player;
|
|
||||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||||
|
|
||||||||
import java.util.List;
|
|
||||||||
|
|
||||||||
import static de.shiewk.smoderation.SModeration.*;
|
|
||||||||
import static net.kyori.adventure.text.Component.text;
|
|
||||||||
|
|
||||||||
public class VanishCommand implements TabExecutor {
|
|
||||||||
|
|
||||||||
@Override
|
|
||||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||||
if (args.length == 0 || args[0].equalsIgnoreCase("toggle")){
|
|
||||||||
Player player = null;
|
|
||||||||
if (args.length > 1){
|
|
||||||||
player = PlayerUtil.findOnlinePlayer(args[1]);
|
|
||||||||
} else if (sender instanceof Player){
|
|
||||||||
player = (Player) sender;
|
|
||||||||
}
|
|
||||||||
if (player != null){
|
|
||||||||
toggleVanish(player);
|
|
||||||||
return true;
|
|
||||||||
} else {
|
|
||||||||
return false;
|
|
||||||||
}
|
|
||||||||
} else if (args[0].equalsIgnoreCase("list")) {
|
|
||||||||
if (sender.hasPermission("smod.vanish.see")){
|
|
||||||||
listVanishedPlayersTo(sender);
|
|
||||||||
} else {
|
|
||||||||
sender.sendMessage(text().color(NamedTextColor.RED).content("You do not have permission to list all vanished players."));
|
|
||||||||
}
|
|
||||||||
return true;
|
|
||||||||
} else {
|
|
||||||||
return false;
|
|
||||||||
}
|
|
||||||||
}
|
|
||||||||
|
|
||||||||
@Override
|
|
||||||||
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
|
||||||||
if (args.length < 2){
|
|
||||||||
return List.of("list", "toggle");
|
|
||||||||
}
|
|
||||||||
if (args.length < 3 && args[0].equalsIgnoreCase("toggle")){
|
|
||||||||
return PlayerUtil.listPlayerNames(args[1]);
|
|
||||||||
}
|
|
||||||||
return List.of();
|
|
||||||||
}
|
|
||||||||
|
|
||||||||
private static final ObjectArrayList<Player> vanishedPlayers = new ObjectArrayList<>();
|
|
||||||||
|
|
||||||||
public static void toggleVanish(Player player){
|
|
||||||||
final boolean newStatus = !isVanished(player);
|
|
||||||||
if (newStatus){
|
|
||||||||
vanishedPlayers.add(player);
|
|
||||||||
for (CommandSender sender : SModeration.container.collectBroadcastTargets()) {
|
|
||||||||
sender.sendMessage(CHAT_PREFIX.append(
|
|
||||||||
player.displayName()
|
|
||||||||
.colorIfAbsent(SECONDARY_COLOR)
|
|
||||||||
).append(
|
|
||||||||
text()
|
|
||||||||
.content(" vanished.")
|
|
||||||||
.color(PRIMARY_COLOR)
|
|
||||||||
));
|
|
||||||||
}
|
|
||||||||
player.sendMessage(CHAT_PREFIX.append(text("You are now vanished.").color(PRIMARY_COLOR)));
|
|
||||||||
player.setVisibleByDefault(false);
|
|
||||||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
|
||||||||
if (onlinePlayer.hasPermission("smod.vanish.see")){
|
|
||||||||
onlinePlayer.showEntity(PLUGIN, player);
|
|
||||||||
}
|
|
||||||||
}
|
|
||||||||
} else {
|
|
||||||||
vanishedPlayers.remove(player);
|
|
||||||||
for (CommandSender sender : container.collectBroadcastTargets()) {
|
|
||||||||
sender.sendMessage(CHAT_PREFIX.append(
|
|
||||||||
player.displayName()
|
|
||||||||
.colorIfAbsent(SECONDARY_COLOR)
|
|
||||||||
).append(
|
|
||||||||
text()
|
|
||||||||
.content(" re-appeared.")
|
|
||||||||
.color(PRIMARY_COLOR)
|
|
||||||||
));
|
|
||||||||
}
|
|
||||||||
player.sendMessage(CHAT_PREFIX.append(text("You are no longer vanished.").color(PRIMARY_COLOR)));
|
|
||||||||
player.setVisibleByDefault(true);
|
|
||||||||
}
|
|
||||||||
}
|
|
||||||||
|
|
||||||||
public static boolean isVanished(Player player){
|
|
||||||||
return vanishedPlayers.contains(player);
|
|
||||||||
}
|
|||||||||
|
}
|
||||||||
|
|
||||||||
|
@Override
|
||||||||
|
public @NotNull ArgumentType<String> getNativeType() {
|
||||||||
|
return StringArgumentType.word();
|
||||||||
|
}
|
||||||||
|
|
||||||||
receiver.sendMessage(CHAT_PREFIX.append(
|
|
||||||||
text().content("No players are currently vanished.").color(PRIMARY_COLOR)
|
|
||||||||
));
|
|
||||||||
} else {
|
|
||||||||
Component vanishList = CHAT_PREFIX.append(
|
|
||||||||
text().content("The following players are currently vanished: ").color(PRIMARY_COLOR)
|
|
||||||||
);
|
|
||||||||
for (ObjectListIterator<Player> iterator = vanishedPlayers.iterator(); iterator.hasNext(); ) {
|
|
||||||||
Player vanishedPlayer = iterator.next();
|
|
||||||||
vanishList = vanishList.append(
|
|
||||||||
vanishedPlayer.displayName().colorIfAbsent(SECONDARY_COLOR)
|
|
||||||||
);
|
|
||||||||
if (iterator.hasNext()){
|
|
||||||||
vanishList = vanishList.append(
|
|
||||||||
text().content(", ").color(PRIMARY_COLOR)
|
|
||||||||
);
|
|
||||||||
}
|
|
||||||||
}
|
|
||||||||
receiver.sendMessage(vanishList);
|
|
||||||||
}
|
|
||||||||
}
|
|
||||||||
}
|
|
||||||||
@@ -1,30 +0,0 @@
|
|||||||
package de.shiewk.smoderation.config;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.SModeration;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SModerationConfig {
|
|
||||||
|
|
||||||
private final FileConfiguration config;
|
|
||||||
private final SModeration plugin;
|
|
||||||
|
|
||||||
public SModerationConfig(FileConfiguration config, SModeration plugin) {
|
|
||||||
this.config = config;
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getSocialSpyCommands(List<String> default_){
|
|
||||||
final String path = "socialspy-commands";
|
|
||||||
if (!config.contains(path)){
|
|
||||||
config.set(path, default_);
|
|
||||||
plugin.saveConfig();
|
|
||||||
}
|
|
||||||
return config.getStringList(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileConfiguration getConfig() {
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,393 +0,0 @@
|
|||||||
package de.shiewk.smoderation.inventory;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.input.ChatInput;
|
|
||||||
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.TextComponent;
|
|
||||||
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.NamespacedKey;
|
|
||||||
import org.bukkit.Sound;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
import org.bukkit.inventory.ItemFlag;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.bukkit.inventory.meta.SkullMeta;
|
|
||||||
import org.bukkit.persistence.PersistentDataContainer;
|
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import static de.shiewk.smoderation.SModeration.*;
|
|
||||||
import static net.kyori.adventure.text.Component.text;
|
|
||||||
|
|
||||||
public class SModMenu extends PageableCustomInventory {
|
|
||||||
|
|
||||||
public enum Filter {
|
|
||||||
ACTIVE("Active punishments", Punishment::isActive),
|
|
||||||
OLD("Old punishments", p -> !p.isActive()),
|
|
||||||
ALL("All punishments", p -> true);
|
|
||||||
|
|
||||||
public static final Material ICON = Material.HOPPER;
|
|
||||||
|
|
||||||
public final String name;
|
|
||||||
public final Predicate<Punishment> filter;
|
|
||||||
Filter(String name, Predicate<Punishment> filter) {
|
|
||||||
this.name = name;
|
|
||||||
this.filter = filter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Sort {
|
|
||||||
EXPIRY("Expiry", Comparator.comparingLong(p -> p.until)),
|
|
||||||
TIME("Date", Comparator.comparingLong(p -> p.time)),
|
|
||||||
PLAYER_NAME("Player name", (p1, p2) -> String.CASE_INSENSITIVE_ORDER.compare(PlayerUtil.offlinePlayerName(p1.to), PlayerUtil.offlinePlayerName(p2.to))),
|
|
||||||
MODERATOR_NAME("Moderator name", (p1, p2) -> String.CASE_INSENSITIVE_ORDER.compare(PlayerUtil.offlinePlayerName(p1.by), PlayerUtil.offlinePlayerName(p2.by)));
|
|
||||||
|
|
||||||
public static final Material ICON = Material.COMPARATOR;
|
|
||||||
|
|
||||||
public final String name;
|
|
||||||
public final Comparator<Punishment> comparator;
|
|
||||||
|
|
||||||
Sort(String name, Comparator<Punishment> comparator) {
|
|
||||||
this.name = name;
|
|
||||||
this.comparator = comparator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static final NamespacedKey PUNISHMENT_STORE_KEY = new NamespacedKey("smod", "punishmentid");
|
|
||||||
|
|
||||||
private final Inventory inventory;
|
|
||||||
private final Player player;
|
|
||||||
private final PunishmentContainer container;
|
|
||||||
private List<Punishment> punishments;
|
|
||||||
private ItemStack sortStack = null;
|
|
||||||
private ItemStack filterStack = null;
|
|
||||||
private ItemStack searchStack = null;
|
|
||||||
private ItemStack typeStack = null;
|
|
||||||
private int sort = 0;
|
|
||||||
private int filter = 0;
|
|
||||||
private int type = -1;
|
|
||||||
private String searchQuery = null;
|
|
||||||
|
|
||||||
public SModMenu(Player player, PunishmentContainer container) {
|
|
||||||
this.player = player;
|
|
||||||
this.container = container;
|
|
||||||
this.inventory = Bukkit.createInventory(this, 54, text("SMod Menu"));
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Sort getSort(){
|
|
||||||
return Sort.values()[sort];
|
|
||||||
}
|
|
||||||
|
|
||||||
public Filter getFilter(){
|
|
||||||
return Filter.values()[filter];
|
|
||||||
}
|
|
||||||
|
|
||||||
public PunishmentType getType(){
|
|
||||||
return type == -1 ? null : PunishmentType.values()[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reload(){
|
|
||||||
this.punishments = container.copy().stream()
|
|
||||||
.filter(getFilter().filter)
|
|
||||||
.filter(p -> getType() == null || p.type == getType())
|
|
||||||
.filter(p -> p.matchesSearchQuery(searchQuery))
|
|
||||||
.sorted(getSort().comparator).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void promptSearchQuery(){
|
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(PLUGIN, player::closeInventory);
|
|
||||||
ChatInput.prompt(player, component -> {
|
|
||||||
if (component instanceof TextComponent text){
|
|
||||||
this.searchQuery = text.content();
|
|
||||||
// chat event is async
|
|
||||||
Bukkit.getScheduler().scheduleSyncDelayedTask(PLUGIN, this::open);
|
|
||||||
}
|
|
||||||
}, text("Enter your search query in chat").color(SECONDARY_COLOR), 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int lastPage() {
|
|
||||||
return Math.max((punishments.size() - 1) / 45, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cycleFilter(boolean backwards){
|
|
||||||
player.playSound(player, Sound.UI_BUTTON_CLICK, 1f, backwards ? 0.8f : 2f);
|
|
||||||
if (backwards){
|
|
||||||
if (filter <= 0){
|
|
||||||
filter = Filter.values().length-1;
|
|
||||||
} else {
|
|
||||||
filter--;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (filter >= Filter.values().length-1){
|
|
||||||
filter = 0;
|
|
||||||
} else {
|
|
||||||
filter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reload();
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cycleSort(boolean backwards){
|
|
||||||
player.playSound(player, Sound.UI_BUTTON_CLICK, 1f, backwards ? 0.8f : 2f);
|
|
||||||
if (backwards){
|
|
||||||
if (sort <= 0){
|
|
||||||
sort = Sort.values().length-1;
|
|
||||||
} else {
|
|
||||||
sort--;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (sort >= Sort.values().length-1){
|
|
||||||
sort = 0;
|
|
||||||
} else {
|
|
||||||
sort++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reload();
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cycleType(boolean backwards){
|
|
||||||
player.playSound(player, Sound.UI_BUTTON_CLICK, 1f, backwards ? 0.8f : 2f);
|
|
||||||
if (backwards){
|
|
||||||
if (type <= -1){
|
|
||||||
type = PunishmentType.values().length-1;
|
|
||||||
} else {
|
|
||||||
type--;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (type >= PunishmentType.values().length-1){
|
|
||||||
type = -1;
|
|
||||||
} else {
|
|
||||||
type++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reload();
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void switchPage() {
|
|
||||||
player.playSound(player, Sound.BLOCK_STONE_HIT, 0.75f, 1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemStack createFilterItem(){
|
|
||||||
final Filter filter = getFilter();
|
|
||||||
final ItemStack stack = new ItemStack(Filter.ICON);
|
|
||||||
stack.editMeta(meta -> {
|
|
||||||
meta.displayName(applyFormatting(text("Filter: " + filter.name).color(PRIMARY_COLOR)));
|
|
||||||
ArrayList<Component> lore = new ArrayList<>();
|
|
||||||
lore.add(Component.empty());
|
|
||||||
for (Filter value : Filter.values()) {
|
|
||||||
final boolean selected = filter == value;
|
|
||||||
Component filterText = applyFormatting(text((selected ? "\u00BB " : "") + value.name).color(selected ? SECONDARY_COLOR : INACTIVE_COLOR));
|
|
||||||
lore.add(filterText);
|
|
||||||
}
|
|
||||||
lore.add(Component.empty());
|
|
||||||
lore.add(applyFormatting(text("\u00BB Click to switch filter").color(NamedTextColor.GOLD)));
|
|
||||||
meta.lore(lore);
|
|
||||||
});
|
|
||||||
filterStack = stack;
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemStack createTypeItem(){
|
|
||||||
final PunishmentType type = getType();
|
|
||||||
final ItemStack stack = new ItemStack(Material.CHEST);
|
|
||||||
stack.editMeta(meta -> {
|
|
||||||
meta.displayName(applyFormatting(text("Type: " + (type == null ? "All" : type.name)).color(PRIMARY_COLOR)));
|
|
||||||
ArrayList<Component> lore = new ArrayList<>();
|
|
||||||
lore.add(Component.empty());
|
|
||||||
final Consumer<PunishmentType> addToLore = value -> {
|
|
||||||
final boolean selected = type == value;
|
|
||||||
Component typeText = applyFormatting(text((selected ? "\u00BB " : "") + (value == null ? "All" : value.name)).color(selected ? SECONDARY_COLOR : INACTIVE_COLOR));
|
|
||||||
lore.add(typeText);
|
|
||||||
};
|
|
||||||
addToLore.accept(null);
|
|
||||||
for (PunishmentType value : PunishmentType.values()) {
|
|
||||||
addToLore.accept(value);
|
|
||||||
}
|
|
||||||
lore.add(Component.empty());
|
|
||||||
lore.add(applyFormatting(text("\u00BB Click to switch type").color(NamedTextColor.GOLD)));
|
|
||||||
meta.lore(lore);
|
|
||||||
});
|
|
||||||
return typeStack = stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemStack createSortItem(){
|
|
||||||
final Sort sort = getSort();
|
|
||||||
final ItemStack stack = new ItemStack(Sort.ICON);
|
|
||||||
stack.editMeta(meta -> {
|
|
||||||
meta.displayName(applyFormatting(text("Sort by: " + sort.name).color(PRIMARY_COLOR)));
|
|
||||||
ArrayList<Component> lore = new ArrayList<>();
|
|
||||||
lore.add(Component.empty());
|
|
||||||
for (Sort value : Sort.values()) {
|
|
||||||
final boolean selected = sort == value;
|
|
||||||
Component sortText = applyFormatting(text((selected ? "\u00BB " : "") + value.name).color(selected ? SECONDARY_COLOR : INACTIVE_COLOR));
|
|
||||||
lore.add(sortText);
|
|
||||||
}
|
|
||||||
lore.add(Component.empty());
|
|
||||||
lore.add(applyFormatting(text("\u00BB Click to switch sorting option").color(NamedTextColor.GOLD)));
|
|
||||||
meta.lore(lore);
|
|
||||||
});
|
|
||||||
sortStack = stack;
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemStack createSearchItem(){
|
|
||||||
final ItemStack stack = new ItemStack(Material.FLOWER_BANNER_PATTERN);
|
|
||||||
stack.editMeta(meta -> {
|
|
||||||
meta.addItemFlags(ItemFlag.HIDE_ITEM_SPECIFICS);
|
|
||||||
meta.displayName(applyFormatting(text("Search").color(PRIMARY_COLOR)));
|
|
||||||
final ArrayList<Component> lore = new ArrayList<>(List.of(
|
|
||||||
Component.empty(),
|
|
||||||
applyFormatting(text("Current search query: %s".formatted(searchQuery == null ? "None" : "\"" + searchQuery + "\"")).color(SECONDARY_COLOR)),
|
|
||||||
Component.empty(),
|
|
||||||
applyFormatting(text("\u00BB Click to enter new search query").color(NamedTextColor.GOLD))
|
|
||||||
));
|
|
||||||
if (searchQuery != null){
|
|
||||||
lore.add(applyFormatting(text("\u00BB Right click to remove search query").color(NamedTextColor.GOLD)));
|
|
||||||
}
|
|
||||||
meta.lore(lore);
|
|
||||||
});
|
|
||||||
return searchStack = stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemStack createPunishmentItem(Punishment punishment){
|
|
||||||
ItemStack stack = new ItemStack(Material.PLAYER_HEAD);
|
|
||||||
stack.editMeta(meta -> {
|
|
||||||
if (meta instanceof SkullMeta skullMeta){
|
|
||||||
try {
|
|
||||||
skullMeta.setOwningPlayer(Bukkit.getOfflinePlayer(punishment.to));
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
LOGGER.warn("Player {} has a punishment but was never on this server!", punishment.to);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
meta.displayName(applyFormatting(text(punishment.type.name).color(NamedTextColor.RED).decorate(TextDecoration.BOLD)));
|
|
||||||
ArrayList<Component> lore = new ArrayList<>();
|
|
||||||
lore.add(applyFormatting(text("Player: ").color(SECONDARY_COLOR).append(text(PlayerUtil.offlinePlayerName(punishment.to)).color(PRIMARY_COLOR))));
|
|
||||||
lore.add(applyFormatting(text("Punished by: ").color(SECONDARY_COLOR).append(text(PlayerUtil.offlinePlayerName(punishment.by)).color(PRIMARY_COLOR))));
|
|
||||||
lore.add(applyFormatting(text("Timestamp: ").color(SECONDARY_COLOR).append(text(TimeUtil.calendarTimestamp(punishment.time)).color(PRIMARY_COLOR))));
|
|
||||||
if (punishment.type != PunishmentType.KICK){
|
|
||||||
lore.add(applyFormatting(text("Duration: ").color(SECONDARY_COLOR).append(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(text("Expires: ").color(SECONDARY_COLOR).append(text(expires).color(PRIMARY_COLOR))));
|
|
||||||
}
|
|
||||||
lore.add(applyFormatting(text("Reason: ").color(SECONDARY_COLOR).append(text(punishment.reason).color(PRIMARY_COLOR))));
|
|
||||||
if (punishment.wasUndone()){
|
|
||||||
lore.add(applyFormatting(text("Undone by: ").color(NamedTextColor.RED).append(text(PlayerUtil.offlinePlayerName(punishment.undoneBy())).color(NamedTextColor.GOLD))));
|
|
||||||
} else if (punishment.isActive()) {
|
|
||||||
if ((punishment.type == PunishmentType.BAN && player.hasPermission("smod.unban")) || (punishment.type == PunishmentType.MUTE && player.hasPermission("smod.unmute"))){
|
|
||||||
lore.add(Component.empty());
|
|
||||||
lore.add(applyFormatting(text("\u00BB Click to undo punishment").color(NamedTextColor.GOLD)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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());
|
|
||||||
inventory.setItem(47, createSearchItem());
|
|
||||||
inventory.setItem(48, createTypeItem());
|
|
||||||
inventory.setItem(50, createFilterItem());
|
|
||||||
inventory.setItem(51, createSortItem());
|
|
||||||
|
|
||||||
for (int i = 0; i < 45; i++) {
|
|
||||||
int ci = i + (getPage() * 45);
|
|
||||||
if (punishments.size() > ci){
|
|
||||||
final Punishment punishment = punishments.get(ci);
|
|
||||||
final ItemStack item = createPunishmentItem(punishment);
|
|
||||||
if (punishment.isActive()){
|
|
||||||
if ((punishment.type == PunishmentType.BAN && player.hasPermission("smod.unban")) || (punishment.type == PunishmentType.MUTE && player.hasPermission("smod.unmute"))) {
|
|
||||||
item.editMeta(meta -> meta.getPersistentDataContainer().set(PUNISHMENT_STORE_KEY, PersistentDataType.LONG, punishment.time));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inventory.setItem(i, item);
|
|
||||||
} else {
|
|
||||||
inventory.setItem(i, new ItemStack(Material.AIR));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void click(ItemStack stack, InventoryClickEvent event) {
|
|
||||||
super.click(stack, event);
|
|
||||||
if (stack != null) {
|
|
||||||
if (stack.equals(filterStack)){
|
|
||||||
cycleFilter(event.isRightClick());
|
|
||||||
} else if (stack.equals(sortStack)){
|
|
||||||
cycleSort(event.isRightClick());
|
|
||||||
} else if (stack.equals(searchStack)){
|
|
||||||
if (event.isRightClick() && searchQuery != null){
|
|
||||||
player.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.8f);
|
|
||||||
searchQuery = null;
|
|
||||||
reload();
|
|
||||||
refresh();
|
|
||||||
} else {
|
|
||||||
player.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 2f);
|
|
||||||
promptSearchQuery();
|
|
||||||
}
|
|
||||||
} else if (stack.equals(typeStack)) {
|
|
||||||
cycleType(event.isRightClick());
|
|
||||||
}
|
|
||||||
final ItemMeta itemMeta = stack.getItemMeta();
|
|
||||||
if (itemMeta != null) {
|
|
||||||
final PersistentDataContainer persistentDataContainer = itemMeta.getPersistentDataContainer();
|
|
||||||
final Long timestamp = persistentDataContainer.get(PUNISHMENT_STORE_KEY, PersistentDataType.LONG);
|
|
||||||
if (timestamp != null) {
|
|
||||||
final Punishment punishment = container.findByTimestamp(timestamp);
|
|
||||||
if (punishment != null) {
|
|
||||||
new ConfirmationInventory(player, "Do you want to undo this punishment?", () -> {
|
|
||||||
punishment.undo(player.getUniqueId());
|
|
||||||
punishment.broadcastUndo(container);
|
|
||||||
player.playSound(player, Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 2f);
|
|
||||||
this.open();
|
|
||||||
}, this::open, false).open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void open() {
|
|
||||||
reload();
|
|
||||||
refresh();
|
|
||||||
player.openInventory(this.inventory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Inventory getInventory() {
|
|
||||||
return inventory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package de.shiewk.smoderation.listener;
|
|
||||||
|
|
||||||
import de.shiewk.smoderation.SModeration;
|
|
||||||
import de.shiewk.smoderation.event.PunishmentIssueEvent;
|
|
||||||
import de.shiewk.smoderation.punishments.Punishment;
|
|
||||||
import de.shiewk.smoderation.punishments.PunishmentType;
|
|
||||||
import de.shiewk.smoderation.storage.PunishmentContainer;
|
|
||||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerLoginEvent;
|
|
||||||
import org.bukkit.event.world.WorldSaveEvent;
|
|
||||||
|
|
||||||
import static de.shiewk.smoderation.SModeration.CHAT_PREFIX;
|
|
||||||
|
|
||||||
public class PunishmentListener implements Listener {
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOW)
|
|
||||||
public void onPlayerLogin(PlayerLoginEvent event){
|
|
||||||
Punishment punishment = SModeration.container.find(p ->
|
|
||||||
p.type == PunishmentType.BAN
|
|
||||||
&& p.to.equals(event.getPlayer().getUniqueId())
|
|
||||||
&& p.isActive());
|
|
||||||
if (punishment != null){
|
|
||||||
event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CHAT_PREFIX.append(punishment.playerMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
||||||
public void onPlayerChat(AsyncChatEvent event){
|
|
||||||
final Player player = event.getPlayer();
|
|
||||||
final Punishment punishment = SModeration.container.find(p ->
|
|
||||||
p.type == PunishmentType.MUTE
|
|
||||||
&& p.
|
|||||||
| faa2eb0a43 | |||||||
| 8c00347ef2 | |||||||
| 8de4382ec4 | |||||||
| 7e90939b84 | |||||||
| 4266b7ebb6 | |||||||