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 ##########################################################################