diff --git a/.github/workflows/dependency-submission.yml b/.github/workflows/dependency-submission.yml index 499906a7..52595222 100644 --- a/.github/workflows/dependency-submission.yml +++ b/.github/workflows/dependency-submission.yml @@ -17,6 +17,6 @@ jobs: distribution: 'temurin' java-version: 21 - name: Generate and submit dependency graph - uses: gradle/actions/dependency-submission@v3 + uses: gradle/actions/dependency-submission@v4 with: dependency-resolution-task: shadowJar \ No newline at end of file diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml index 26750c71..7c647f47 100644 --- a/.github/workflows/javadoc.yml +++ b/.github/workflows/javadoc.yml @@ -19,7 +19,7 @@ jobs: steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - name: Checkout main branch from GitHub - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Runs a single command using the runners shell - name: Setting up JDK 21 @@ -29,7 +29,7 @@ jobs: java-version: 21 - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/actions/setup-gradle@v4 - name: Execute Gradle build run: | diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f3347566..7e074ce8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,7 +23,7 @@ jobs: distribution: 'temurin' java-version: 21 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Execute Gradle build env: GRGIT_USER: "Angelillo15" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a80143bf..4562eed0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: distribution: 'temurin' java-version: 21 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 - name: Execute Gradle test run: | diff --git a/NookureStaff-API/build.gradle.kts b/NookureStaff-API/build.gradle.kts index 3b7b0231..4e70365f 100644 --- a/NookureStaff-API/build.gradle.kts +++ b/NookureStaff-API/build.gradle.kts @@ -37,6 +37,7 @@ dependencies { compileOnlyApi(rootProject.libs.miniMessage) compileOnlyApi(rootProject.libs.caffeine) compileOnlyApi(rootProject.libs.ebean) + compileOnlyApi(rootProject.libs.placeholderApi) annotationProcessor(rootProject.libs.ebean) compileOnly(libs.auto.service.annotations) diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/config/bukkit/partials/config/PlayerActions.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/config/bukkit/partials/config/PlayerActions.java index 388f4f58..6052f750 100644 --- a/NookureStaff-API/src/main/java/com/nookure/staff/api/config/bukkit/partials/config/PlayerActions.java +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/config/bukkit/partials/config/PlayerActions.java @@ -2,6 +2,7 @@ import org.spongepowered.configurate.objectmapping.ConfigSerializable; import org.spongepowered.configurate.objectmapping.meta.Comment; +import org.spongepowered.configurate.objectmapping.meta.Setting; @ConfigSerializable public class PlayerActions { @@ -9,7 +10,8 @@ public class PlayerActions { If true, the player will be able to inspect a player by shift and right-clicking on them. """) - private final boolean shiftAndRightClickToInspect = true; + @Setting + private boolean shiftAndRightClickToInspect = true; public boolean shiftAndRightClickToInspect() { return shiftAndRightClickToInspect; diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/config/bukkit/partials/messages/FreezeMessagePartial.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/config/bukkit/partials/messages/FreezeMessagePartial.java index 6c2f14dc..67d45f64 100644 --- a/NookureStaff-API/src/main/java/com/nookure/staff/api/config/bukkit/partials/messages/FreezeMessagePartial.java +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/config/bukkit/partials/messages/FreezeMessagePartial.java @@ -82,6 +82,22 @@ public class FreezeMessagePartial { @Comment("Message sent when a player is punished") private String punishMessage = "Freeze » You have punished {player}."; + @Setting + @Comment("Message sent when the timer has been paused for a player") + private String theTimerHasBeenPausedFor = "Freeze » The timer has been paused for {player}."; + + @Setting + @Comment("Message sent when the staff has paused the timer for a player") + private String theStaffHasPausedTheTimer = "Freeze » The staff has paused the timer for you"; + + @Setting + @Comment("Message sent when a player is not frozen.") + private String playerNotFrozen = "Freeze » That player is not frozen."; + + public String playerNotFrozen() { + return playerNotFrozen; + } + public String frozenMessage() { return frozenMessage; } @@ -141,4 +157,12 @@ public String forgiveMessage() { public String punishMessage() { return punishMessage; } + + public String theTimerHasBeenPausedFor() { + return theTimerHasBeenPausedFor; + } + + public String theStaffHasPausedTheTimer() { + return theStaffHasPausedTheTimer; + } } diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/manager/FreezeManager.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/manager/FreezeManager.java index c6d735bb..ea04297c 100644 --- a/NookureStaff-API/src/main/java/com/nookure/staff/api/manager/FreezeManager.java +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/manager/FreezeManager.java @@ -7,6 +7,7 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import java.util.Iterator; import java.util.Optional; import java.util.UUID; import java.util.stream.Stream; @@ -125,6 +126,10 @@ public Stream stream() { return freezeContainers.values().stream(); } + public Iterator iterator() { + return freezeContainers.values().iterator(); + } + public static final class FreezeContainer { private final UUID staff; private final UUID target; diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/util/ServerUtils.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/util/ServerUtils.java index 40ea7fd8..69d1e8da 100644 --- a/NookureStaff-API/src/main/java/com/nookure/staff/api/util/ServerUtils.java +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/util/ServerUtils.java @@ -1,26 +1,16 @@ package com.nookure.staff.api.util; import com.nookure.staff.api.Permissions; +import org.bukkit.Bukkit; import org.jetbrains.annotations.NotNull; import java.util.UUID; +import java.util.logging.Logger; public abstract class ServerUtils { public static final boolean isPaper; - - static { - isPaper = hasClass("com.destroystokyo.paper.PaperConfig") || - hasClass("io.papermc.paper.configuration.Configuration"); - } - - private static boolean hasClass(String className) { - try { - Class.forName(className); - return true; - } catch (ClassNotFoundException e) { - return false; - } - } + public static final MinecraftVersion MINECRAFT_VERSION; + private static final Logger logger = Logger.getLogger("NookureStaff"); /** * Check if a player is online @@ -54,4 +44,64 @@ private static boolean hasClass(String className) { public void broadcastStaffMessage(@NotNull String message) { broadcast(message, Permissions.STAFF_PERMISSION); } + + static { + isPaper = hasClass("com.destroystokyo.paper.PaperConfig") || + hasClass("io.papermc.paper.configuration.Configuration"); + + MINECRAFT_VERSION = getMinecraftVersionOrDefault(); + } + + private static MinecraftVersion getMinecraftVersionOrDefault() { + try { + try { + return getMinecraftVersionByPaper(); + } catch (Exception e) { + return getMinecraftVersionByBukkit(); + } + } catch (Exception e) { + logger.warning("Failed to get the Minecraft version, defaulting to 0.0.0"); + logger.warning("Keep in mind that this may cause issues with the plugin"); + logger.warning("Because of this, it is recommended to use the latest version of the software"); + return new MinecraftVersion(0, 0, 0); + } + } + + private static MinecraftVersion getMinecraftVersionByPaper() { + String[] version = Bukkit.getMinecraftVersion().split("\\."); + return new MinecraftVersion(Integer.parseInt(version[0]), Integer.parseInt(version[1]), Integer.parseInt(version[2])); + } + + private static MinecraftVersion getMinecraftVersionByBukkit() { + String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + String[] versionSplit = version.split("_"); + return new MinecraftVersion(Integer.parseInt(versionSplit[0]), Integer.parseInt(versionSplit[1]), Integer.parseInt(versionSplit[2])); + } + + public record MinecraftVersion(int major, int minor, int patch) { + public boolean isAtLeast(int major, int minor, int patch) { + return this.major > major || (this.major == major && this.minor > minor) || (this.major == major && this.minor == minor && this.patch >= patch); + } + + public boolean isBefore(int major, int minor, int patch) { + return this.major < major || (this.major == major && this.minor < minor) || (this.major == major && this.minor == minor && this.patch < patch); + } + + public boolean isAtLeast(int major, int minor) { + return isAtLeast(major, minor, 0); + } + + public boolean isBefore(int major, int minor) { + return isBefore(major, minor, 0); + } + } + + public static boolean hasClass(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } } diff --git a/NookureStaff-API/src/main/java/com/nookure/staff/api/util/TextUtils.java b/NookureStaff-API/src/main/java/com/nookure/staff/api/util/TextUtils.java index 12c77599..80ae48bd 100644 --- a/NookureStaff-API/src/main/java/com/nookure/staff/api/util/TextUtils.java +++ b/NookureStaff-API/src/main/java/com/nookure/staff/api/util/TextUtils.java @@ -2,11 +2,15 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; +import static com.nookure.staff.api.util.ServerUtils.hasClass; + public abstract class TextUtils { + private static final boolean IS_PAPI_INSTALLED = hasClass("me.clip.placeholderapi.PlaceholderAPI"); private static final long SECOND = 1000; private static final long MINUTE = 60 * SECOND; private static final long HOUR = 60 * MINUTE; @@ -117,4 +121,10 @@ public static String formatTime(long time) { } return buf.toString(); } + + public static String parsePlaceholdersWithPAPI(@NotNull final org.bukkit.entity.Player player, @NotNull final String message) { + if (!IS_PAPI_INSTALLED) return message; + + return me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(player, message); + } } diff --git a/NookureStaff-Paper/build.gradle.kts b/NookureStaff-Paper/build.gradle.kts index 465f3c69..ccc19811 100644 --- a/NookureStaff-Paper/build.gradle.kts +++ b/NookureStaff-Paper/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { compileOnly(libs.configurateYaml) compileOnly(libs.jedis) compileOnly(libs.placeholderApi) + compileOnly(libs.lucko.commodore) compileOnly(libs.nookure.core.inventory) bukkitLibrary(libs.guice) bukkitLibrary(libs.google.guice.assistedinject) diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/PaperPlayerWrapper.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/PaperPlayerWrapper.java index 33cf4822..b4b3c084 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/PaperPlayerWrapper.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/PaperPlayerWrapper.java @@ -13,6 +13,7 @@ import com.nookure.staff.api.util.DefaultFontInfo; import com.nookure.staff.api.util.Scheduler; import com.nookure.staff.api.util.ServerUtils; +import com.nookure.staff.api.util.TextUtils; import io.ebean.Database; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -172,6 +173,7 @@ public void sendMiniMessage(@NotNull String message, String... placeholders) { message = message.replace("{prefix}", nookPlugin.getPrefix()); message = DefaultFontInfo.centerIfContains(message); + message = TextUtils.parsePlaceholdersWithPAPI(player, message); sendMessage(MiniMessage.miniMessage().deserialize(message)); } diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/StaffPaperPlayerWrapper.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/StaffPaperPlayerWrapper.java index 81100516..79ae1614 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/StaffPaperPlayerWrapper.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/StaffPaperPlayerWrapper.java @@ -21,6 +21,7 @@ import com.nookure.staff.api.model.StaffDataModel; import com.nookure.staff.api.state.PlayerState; import com.nookure.staff.api.util.Scheduler; +import com.nookure.staff.api.util.ServerUtils; import com.nookure.staff.paper.data.StaffModeData; import io.ebean.Database; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -402,6 +403,8 @@ public void setStaffChatAsDefault(boolean staffChatAsDefault) { // public void loadPotionEffects() { + if (ServerUtils.MINECRAFT_VERSION.isBefore(1, 20)) return; + if (config.get().staffMode.nightVision()) { if (!player.hasPotionEffect(PotionEffectType.NIGHT_VISION)) toggleNightVision(); } diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/brigadier/BrigadierCommand.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/brigadier/BrigadierCommand.java new file mode 100644 index 00000000..adbd4acf --- /dev/null +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/brigadier/BrigadierCommand.java @@ -0,0 +1,90 @@ +package com.nookure.staff.paper.brigadier; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.tree.LiteralCommandNode; +import com.nookure.staff.api.PlayerWrapper; +import com.nookure.staff.api.command.CommandSender; +import com.nookure.staff.api.manager.PlayerWrapperManager; +import org.bukkit.command.Command; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Optional; + +import static java.util.Objects.requireNonNull; + +public abstract class BrigadierCommand extends Command { + private final CommandSender consoleSender; + private final PlayerWrapperManager playerWrapperManager; + private final CommandDispatcher dispatcher; + + protected BrigadierCommand( + @NotNull final String name, + @NotNull final CommandDispatcher dispatcher, + @NotNull final PlayerWrapperManager playerWrapperManager, + @NotNull final CommandSender consoleSender + ) { + super(name); + requireNonNull(dispatcher, "dispatcher cannot be null"); + requireNonNull(playerWrapperManager, "playerWrapperManager cannot be null"); + requireNonNull(consoleSender, "consoleSender cannot be null"); + this.dispatcher = dispatcher; + this.playerWrapperManager = playerWrapperManager; + this.consoleSender = consoleSender; + } + + protected BrigadierCommand( + @NotNull final String name, + @NotNull final String description, + @NotNull final String usageMessage, + @NotNull final List aliases, + @NotNull final CommandDispatcher dispatcher, + @NotNull final PlayerWrapperManager playerWrapperManager, + @NotNull final CommandSender consoleSender + ) { + super(name, description, usageMessage, aliases); + requireNonNull(dispatcher, "dispatcher cannot be null"); + requireNonNull(playerWrapperManager, "playerWrapperManager cannot be null"); + requireNonNull(consoleSender, "consoleSender cannot be null"); + this.dispatcher = dispatcher; + this.playerWrapperManager = playerWrapperManager; + this.consoleSender = consoleSender; + } + + public void register() { + dispatcher.register(build().createBuilder()); + } + + public abstract LiteralCommandNode build(); + + @Override + public boolean execute(org.bukkit.command.@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) { + if (!(sender instanceof Player player)) { + try { + dispatcher.execute(commandLabel, consoleSender); + } catch (CommandSyntaxException e) { + throw new RuntimeException(e); + } + + return true; + } + + Optional playerWrapperOptional = playerWrapperManager.getPlayerWrapper(player.getUniqueId()); + + if (playerWrapperOptional.isEmpty()) { + return false; + } + + CommandSender commandSender = playerWrapperOptional.get(); + + try { + dispatcher.execute(commandLabel, commandSender); + } catch (CommandSyntaxException e) { + throw new RuntimeException(e); + } + + return false; + } +} diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/command/FreezeCommand.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/command/FreezeCommand.java index a346e3da..ec4092fa 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/command/FreezeCommand.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/command/FreezeCommand.java @@ -120,6 +120,11 @@ protected void onStaffCommand(@NotNull StaffPlayerWrapper sender, @NotNull Strin PlayerWrapper target = optionalTarget.get(); + if (args.size() >= 2 && args.get(1).equalsIgnoreCase("pause")) { + freezeExtension.pauseFreeze(target, sender); + return; + } + if (freezeManager.isFrozen(target.getUniqueId())) { freezeExtension.unfreezePlayer(target); } else { @@ -129,6 +134,15 @@ protected void onStaffCommand(@NotNull StaffPlayerWrapper sender, @NotNull Strin @Override public @NotNull List onTabComplete(@NotNull CommandSender sender, @NotNull String label, @NotNull List args) { - return getSuggestionFilter(Bukkit.getOnlinePlayers().stream().map(Player::getName).toList(), args.getFirst()); + switch (args.size()) { + case 1 -> { + return getSuggestionFilter(Bukkit.getOnlinePlayers().stream().map(Player::getName).toList(), args.getFirst()); + } + case 2 -> { + return List.of("pause"); + } + } + + return super.onTabComplete(sender, label, args); } } diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/FreezePlayerExtension.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/FreezePlayerExtension.java index cadb009d..b241f494 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/FreezePlayerExtension.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/extension/FreezePlayerExtension.java @@ -38,7 +38,13 @@ public FreezePlayerExtension(StaffPlayerWrapper player) { } public void freezePlayer(PlayerWrapper target) { - freezeManager.freeze(target, player, System.currentTimeMillis() + config.get().freeze.freezeTimer()); + final long configTime = config.get().freeze.freezeTimer(); + + if (configTime == -1) { + freezeManager.freeze(target, player, -1); + } else { + freezeManager.freeze(target, player, System.currentTimeMillis() + config.get().freeze.freezeTimer()); + } target.sendMiniMessage(messages.get().freeze.frozenMessage()); @@ -68,6 +74,19 @@ public void executeFreezeCommands(@NotNull PlayerWrapper target, @NotNull String config.get().freeze.commands().forEach(command -> execute(target, command, name)); } + public void pauseFreeze(@NotNull final PlayerWrapper target, @NotNull final PlayerWrapper staff) { + freezeManager.getFreezeContainer(target.getUniqueId()).ifPresentOrElse(container -> { + container.setTimeLeft(-1); + target.sendMiniMessage(messages.get().freeze.theStaffHasPausedTheTimer()); + + eventMessenger.publish(staff, new BroadcastMessage(messages.get().freeze.theTimerHasBeenPausedFor() + .replace("{player}", target.getName()) + .replace("{staff}", staff.getName()), + Permissions.STAFF_FREEZE) + ); + }, () -> target.sendMiniMessage(messages.get().freeze.playerNotOnline())); + } + public void execute(@NotNull PlayerWrapper player, @NotNull String command, @NotNull String name) { requireNonNull(player, "Player cannot be null"); requireNonNull(command, "Command cannot be null"); diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/listener/staff/state/OnOpenChest.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/listener/staff/state/OnOpenChest.java index 4c00ef70..1cfde904 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/listener/staff/state/OnOpenChest.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/listener/staff/state/OnOpenChest.java @@ -4,8 +4,7 @@ import com.nookure.staff.api.StaffPlayerWrapper; import com.nookure.staff.api.manager.PlayerWrapperManager; import org.bukkit.Bukkit; -import org.bukkit.block.Chest; -import org.bukkit.block.Container; +import org.bukkit.block.*; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -24,30 +23,37 @@ public void onPlayerInteract(PlayerInteractEvent event) { return; } - StaffPlayerWrapper playerWrapper = playerWrapperManager.getStaffPlayer(player.getUniqueId()).get(); + StaffPlayerWrapper playerWrapper = playerWrapperManager.getStaffPlayer(player.getUniqueId()).orElseThrow(); if (!playerWrapper.isInStaffMode()) { return; } - if ( - event.getClickedBlock() == null || - event.getClickedBlock().getType().name().contains("CHEST") || - !(event.getClickedBlock().getState() instanceof Container container) - ) { + if (event.getClickedBlock() == null) { return; } - if (!(container instanceof Chest chest)) { + if (event.getClickedBlock().getState() instanceof EnderChest) { + event.setCancelled(true); + player.openInventory(player.getEnderChest()); return; } - Inventory cInv = Bukkit.createInventory(null, chest.getInventory().getSize(), chest.getInventory().getType().defaultTitle()); - cInv.setContents(chest.getInventory().getContents()); + if (!(event.getClickedBlock().getState() instanceof Container container)) { + return; + } - player.openInventory(cInv); + if (container instanceof Chest || container instanceof Barrel || container instanceof ShulkerBox) { + Inventory bInv = Bukkit.createInventory( + null, + container.getInventory().getSize(), + container.getInventory().getType().defaultTitle() + ); - event.setCancelled(true); - } + bInv.setContents(container.getInventory().getContents()); + player.openInventory(bInv); + event.setCancelled(true); + } + } } diff --git a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/task/FreezeSpamMessage.java b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/task/FreezeSpamMessage.java index 7957c794..80d8c820 100644 --- a/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/task/FreezeSpamMessage.java +++ b/NookureStaff-Paper/src/main/java/com/nookure/staff/paper/task/FreezeSpamMessage.java @@ -8,6 +8,8 @@ import com.nookure.staff.api.util.TextUtils; import org.bukkit.entity.Player; +import java.util.Iterator; + public class FreezeSpamMessage implements Runnable { @Inject private FreezeManager freezeManager; @@ -18,8 +20,11 @@ public class FreezeSpamMessage implements Runnable { @Override public void run() { - freezeManager.stream().forEach(container -> { - if (container.hasTalked()) return; + Iterator iterator = freezeManager.iterator(); + + while (iterator.hasNext()) { + FreezeManager.FreezeContainer container = iterator.next(); + if (container.hasTalked()) continue; playerWrapperManager.getPlayerWrapper(container.target()).ifPresent(player -> { player.sendMiniMessage(TextUtils.toMM(messages.get().freeze.chatFrozenMessage() @@ -27,6 +32,6 @@ public void run() { container.timeLeft() == -1 ? "∞" : TextUtils.formatTime(container.timeLeft() - System.currentTimeMillis())) )); }); - }); + } } } diff --git a/NookureStaff-Paper/src/test/java/com/nookure/staff/paper/test/freeze/StaffFreezeAnotherPlayerTest.java b/NookureStaff-Paper/src/test/java/com/nookure/staff/paper/test/freeze/StaffFreezeAnotherPlayerTest.java new file mode 100644 index 00000000..6cffd0b3 --- /dev/null +++ b/NookureStaff-Paper/src/test/java/com/nookure/staff/paper/test/freeze/StaffFreezeAnotherPlayerTest.java @@ -0,0 +1,62 @@ +package com.nookure.staff.paper.test.freeze; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import be.seeseemelk.mockbukkit.entity.PlayerMock; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.TypeLiteral; +import com.nookure.staff.api.PlayerWrapper; +import com.nookure.staff.api.manager.FreezeManager; +import com.nookure.staff.api.manager.PlayerWrapperManager; +import com.nookure.staff.paper.StaffPaperPlayerWrapper; +import com.nookure.staff.paper.bootstrap.StaffBootstrapper; +import com.nookure.staff.paper.extension.FreezePlayerExtension; +import org.bukkit.entity.Player; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.platform.commons.util.Preconditions; + +public class StaffFreezeAnotherPlayerTest { + private ServerMock server; + private Injector injector; + + @BeforeEach + public void setUp() { + server = MockBukkit.mock(); + StaffBootstrapper plugin = MockBukkit.load(StaffBootstrapper.class); + injector = plugin.getInjector(); + } + + @AfterEach + public void tearDown() { + MockBukkit.unmock(); + } + + @Test + @DisplayName("Freeze another player") + public void freezeAnotherPlayer() { + final FreezeManager freezeManager = injector.getInstance(FreezeManager.class); + final PlayerMock staff = new PlayerMock(server, "Staff 1"); + + staff.setOp(true); + + server.addPlayer(staff); + + final PlayerWrapperManager playerWrapperManager = injector.getInstance(Key.get(new TypeLiteral<>() { + })); + + final StaffPaperPlayerWrapper staffPlayerWrapper = (StaffPaperPlayerWrapper) playerWrapperManager.getStaffPlayer(staff.getUniqueId()).orElseThrow(); + + final PlayerMock hacker = new PlayerMock(server, "Hacker"); + server.addPlayer(hacker); + + final PlayerWrapper targetPlayerWrapper = playerWrapperManager.getPlayerWrapper(hacker.getUniqueId()).orElseThrow(); + + staffPlayerWrapper.getExtension(FreezePlayerExtension.class).orElseThrow().freezePlayer(targetPlayerWrapper); + + Preconditions.condition(freezeManager.isFrozen(hacker.getUniqueId()), "The player should be frozen"); + } +} diff --git a/build.gradle.kts b/build.gradle.kts index 08ca0c23..78605957 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,11 +29,16 @@ dependencies { implementation(libs.libbyPaper) implementation(libs.libbyVelocity) implementation(libs.configurateYaml) + implementation(libs.lucko.commodore) } tasks.shadowJar { archiveFileName.set("NookureStaff-${rootProject.version}.jar") + dependencies { + exclude("com/mojang") + } relocate("com.zaxxer", "com.nookure.staff.libs") + relocate("me.lucko.commodore", "com.nookure.staff.libs.commodore") relocate("com.craftmend.storm", "com.nookure.staff.libs.storm") relocate("com.github.benmanes.caffeine", "com.nookure.staff.libs.caffeine") relocate("org.spongepowered.configurate", "com.nookure.staff.libs.configurate") diff --git a/gradle.properties b/gradle.properties index 29cdeae0..ed12e6da 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ major=1 minor=4 -patch=3 \ No newline at end of file +patch=4 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7e672628..08fc765d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,7 +9,7 @@ paperLib = "1.0.7" caffeine = "3.1.8" paper = "1.21-R0.1-SNAPSHOT" vault = "1.7.1" -placeholderApi = "2.11.2" +placeholderApi = "2.11.6" bungeecord = "1.21-R0.1-SNAPSHOT" jedis = "4.4.0-m2" storm = "e1f961b" @@ -19,7 +19,7 @@ velocity = "3.1.1" guice = "7.0.0" configurate = "4.2.0-YAML-COMMENTED-SNAPSHOT" scoreboard = "2.0.1" -shadowJar = "8.1.8" +shadowJar = "8.3.3" pluginYml = "0.6.0" guava = "33.0.0-jre" apacheCommons = "3.14.0" @@ -29,6 +29,8 @@ protoc = "4.27.1" super-vanish = "6.2.18-3" inventory = "1.0.0-ee06bf8" mock-bukkit = "3.9.0" +brigadier = "1.0.18" +commodore = "2.2" [libraries] hikariCP = { group = "com.zaxxer", name = "HikariCP", version.ref = "hikariCP" } @@ -82,13 +84,15 @@ protocol-buffers-lite = { group = "com.google.protobuf", name = "protobuf-javali superVanish = { group = "com.github.LeonMangler", name = "SuperVanish", version.ref = "super-vanish" } nookure-core-inventory = { group = "com.nookure.core", name = "NookCore-Inventory", version.ref = "inventory" } mockBukkit = { group = "com.github.seeseemelk", name = "MockBukkit-v1.20", version.ref = "mock-bukkit" } +mojang-brigadier = { group = "com.mojang", name = "brigadier", version.ref = "brigadier" } +lucko-commodore = { group = "me.lucko", name = "commodore", version.ref = "commodore" } [bundles] invAPI = ["invCore", "invAdvancedSlots", "invPagination", "configurableGui"] scoreboard = ["scoreboard", "scoreboard-implementation", "scoreboard-modern", "scoreboard-packetevents", "scoreboard-8"] [plugins] -shadowJar = { id = "io.github.goooler.shadow", version.ref = "shadowJar" } +shadowJar = { id = "com.gradleup.shadow", version.ref = "shadowJar" } pluginYmlBukkit = { id = "net.minecrell.plugin-yml.bukkit", version.ref = "pluginYml" } pluginYmlBungee = { id = "net.minecrell.plugin-yml.bungee", version.ref = "pluginYml" } pluginYmlPaper = { id = "net.minecrell.plugin-yml.paper", version.ref = "pluginYml" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136..2c352119 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 09523c0e..df97d72b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a42..f5feea6d 100644 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30db..9d21a218 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ##########################################################################