Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified gradlew
100644 → 100755
Empty file.
155 changes: 75 additions & 80 deletions src/main/java/top/modpotato/commands/AntiNetheriteCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ public class AntiNetheriteCommand implements CommandExecutor, TabCompleter {
// Map of user-friendly setting names to actual config paths
private final Map<String, String> SETTINGS_MAP = new HashMap<>();

// Track when the last restore command was used to prevent spam
private long lastRestoreTime = 0;
private static final long RESTORE_COOLDOWN = 10000; // 10 seconds cooldown
// Track when the last restore command was used per sender to prevent spam
private final Map<String, Long> lastRestoreTimes = new HashMap<>();

public AntiNetheriteCommand(Main plugin) {
this.plugin = plugin;
Expand All @@ -50,7 +49,7 @@ public AntiNetheriteCommand(Main plugin) {
SETTINGS_MAP.put("remove-dropped", "anti-netherite.item-handling.remove-dropped");

// Ancient debris settings
SETTINGS_MAP.put("replace-ancient-debris", "anti-netherite.ancient-debris.replace-when-mined");
SETTINGS_MAP.put("replace-when-mined", "anti-netherite.ancient-debris.replace-when-mined");
SETTINGS_MAP.put("replace-on-chunk-load", "anti-netherite.ancient-debris.replace-on-chunk-load");
SETTINGS_MAP.put("only-replace-generated-chunks", "anti-netherite.ancient-debris.only-replace-generated-chunks");
SETTINGS_MAP.put("ensure-chunks-loaded", "anti-netherite.ancient-debris.ensure-chunks-loaded");
Expand Down Expand Up @@ -81,14 +80,22 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
sender.sendMessage(Component.text("AntiNetherite configuration reloaded.").color(NamedTextColor.GREEN));
return true;
case "restore-debris":
// Check for cooldown to prevent command spam
// Get the configured cooldown in milliseconds
int cooldownSeconds = plugin.getConfig().getInt("anti-netherite.advanced.command-cooldown-seconds", 5);
long cooldownMs = cooldownSeconds * 1000L;

// Check for cooldown per sender to prevent command spam
String senderKey = sender.getName();
long currentTime = System.currentTimeMillis();
if (currentTime - lastRestoreTime < RESTORE_COOLDOWN) {
sender.sendMessage(Component.text("Please wait before using this command again.").color(NamedTextColor.RED));
Long lastTime = lastRestoreTimes.get(senderKey);

if (lastTime != null && (currentTime - lastTime) < cooldownMs) {
long remainingSeconds = (cooldownMs - (currentTime - lastTime)) / 1000;
sender.sendMessage(Component.text("Please wait " + remainingSeconds + " seconds before using this command again.").color(NamedTextColor.RED));
return true;
}

lastRestoreTime = currentTime;
lastRestoreTimes.put(senderKey, currentTime);

// Check if replacement features are enabled in config
boolean replaceWhenMined = (boolean) plugin.getConfigValue("anti-netherite.ancient-debris.replace-when-mined");
Expand Down Expand Up @@ -124,20 +131,13 @@ public boolean onCommand(CommandSender sender, Command command, String label, St

sender.sendMessage(Component.text("Restoring " + worldLocations + " Ancient Debris in world " + worldName + "...").color(NamedTextColor.YELLOW));

// Run the restoration asynchronously to prevent lag
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
// Run the restoration on the main thread (delegating Folia handling to DebrisStorage)
Bukkit.getScheduler().runTask(plugin, () -> {
try {
int count = plugin.getDebrisStorage().restoreDebrisInWorld(world);

// Send message on the main thread
Bukkit.getScheduler().runTask(plugin, () -> {
sender.sendMessage(Component.text("Restored " + count + " Ancient Debris blocks in world " + worldName + ".").color(NamedTextColor.GREEN));
});
sender.sendMessage(Component.text("Restored " + count + " Ancient Debris blocks in world " + worldName + ".").color(NamedTextColor.GREEN));
} catch (Exception e) {
// Send error message on the main thread
Bukkit.getScheduler().runTask(plugin, () -> {
sender.sendMessage(Component.text("Error restoring Ancient Debris: " + e.getMessage()).color(NamedTextColor.RED));
});
sender.sendMessage(Component.text("Error restoring Ancient Debris: " + e.getMessage()).color(NamedTextColor.RED));
plugin.getLogger().severe("Error restoring Ancient Debris: " + e.getMessage());
e.printStackTrace();
}
Expand All @@ -153,20 +153,13 @@ public boolean onCommand(CommandSender sender, Command command, String label, St

sender.sendMessage(Component.text("Restoring " + totalLocations + " replaced Ancient Debris...").color(NamedTextColor.YELLOW));

// Run the restoration asynchronously to prevent lag
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
// Run the restoration on the main thread (delegating Folia handling to DebrisStorage)
Bukkit.getScheduler().runTask(plugin, () -> {
try {
int count = plugin.getDebrisStorage().restoreAllDebris();

// Send message on the main thread
Bukkit.getScheduler().runTask(plugin, () -> {
sender.sendMessage(Component.text("Restored " + count + " Ancient Debris blocks.").color(NamedTextColor.GREEN));
});
sender.sendMessage(Component.text("Restored " + count + " Ancient Debris blocks.").color(NamedTextColor.GREEN));
} catch (Exception e) {
// Send error message on the main thread
Bukkit.getScheduler().runTask(plugin, () -> {
sender.sendMessage(Component.text("Error restoring Ancient Debris: " + e.getMessage()).color(NamedTextColor.RED));
});
sender.sendMessage(Component.text("Error restoring Ancient Debris: " + e.getMessage()).color(NamedTextColor.RED));
plugin.getLogger().severe("Error restoring Ancient Debris: " + e.getMessage());
e.printStackTrace();
}
Expand Down Expand Up @@ -212,36 +205,10 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
return true;
}

// Get the actual config path from the user-friendly name
String settingPath = SETTINGS_MAP.get(args[1]);
if (settingPath == null && !args[1].equals("detection.items")) {
sender.sendMessage(Component.text("Unknown setting: " + args[1]).color(NamedTextColor.RED));
return true;
}

String settingValue = args[2];
String settingName = args[1].toLowerCase();

// Handle different setting types
if (args[1].equals("delay") || args[1].equals("multiplier")) {
try {
int intValue = Integer.parseInt(settingValue);
if (intValue < 1) {
sender.sendMessage(Component.text("Value must be at least 1.").color(NamedTextColor.RED));
return true;
}
plugin.updateConfig(settingPath, intValue);
} catch (NumberFormatException e) {
sender.sendMessage(Component.text("Invalid number: " + settingValue).color(NamedTextColor.RED));
return true;
}
} else if (isBooleanSetting(args[1])) {
if (!settingValue.equalsIgnoreCase("true") && !settingValue.equalsIgnoreCase("false")) {
sender.sendMessage(Component.text("Value must be true or false.").color(NamedTextColor.RED));
return true;
}
plugin.updateConfig(settingPath, Boolean.parseBoolean(settingValue));
} else if (args[1].equals("detection.items")) {
// Special handling for adding/removing items
// Special handling for detection.items add/remove
if (settingName.equals("detection.items")) {
if (args.length < 4) {
sender.sendMessage(Component.text("Usage: /antinetherite set detection.items <add|remove> <item>").color(NamedTextColor.RED));
return true;
Expand Down Expand Up @@ -272,36 +239,64 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
sender.sendMessage(Component.text("Invalid action: " + action + ". Use 'add' or 'remove'.").color(NamedTextColor.RED));
}
return true;
} else {
sender.sendMessage(Component.text("Unknown setting: " + args[1]).color(NamedTextColor.RED));
}

// Get the actual config path from the user-friendly name
String settingPath = getConfigPath(settingName);
if (settingPath == null) {
sender.sendMessage(Component.text("Unknown setting: " + settingName).color(NamedTextColor.RED));
return true;
}

String settingValue = args[2];

// Get the current value to determine the type
Object currentValue = plugin.getConfigValue(settingPath);

if (currentValue == null) {
sender.sendMessage(Component.text("Setting not found: " + settingName).color(NamedTextColor.RED));
return true;
}

// Type-aware setting
try {
if (currentValue instanceof Boolean) {
// Boolean setting
if (!settingValue.equalsIgnoreCase("true") && !settingValue.equalsIgnoreCase("false")) {
sender.sendMessage(Component.text("Value must be true or false.").color(NamedTextColor.RED));
return true;
}
plugin.updateConfig(settingPath, Boolean.parseBoolean(settingValue));
} else if (currentValue instanceof Integer) {
// Integer setting
int intValue = Integer.parseInt(settingValue);
if (intValue < 1) {
sender.sendMessage(Component.text("Value must be at least 1.").color(NamedTextColor.RED));
return true;
}
plugin.updateConfig(settingPath, intValue);
} else if (currentValue instanceof List) {
// List setting (should not happen here - detection.items is handled above)
sender.sendMessage(Component.text("This setting is a list and cannot be set directly.").color(NamedTextColor.RED));
return true;
} else {
// Unknown type, try string
plugin.updateConfig(settingPath, settingValue);
}

sender.sendMessage(Component.text("Set " + settingName + " to " + settingValue).color(NamedTextColor.GREEN));
} catch (NumberFormatException e) {
sender.sendMessage(Component.text("Invalid number: " + settingValue).color(NamedTextColor.RED));
return true;
}

sender.sendMessage(Component.text("Set " + args[1] + " to " + settingValue).color(NamedTextColor.GREEN));
return true;
default:
showHelp(sender);
return true;
}
}

private boolean isBooleanSetting(String setting) {
String configPath = SETTINGS_MAP.get(setting);
if (configPath == null) {
return false;
}

// Check if the setting is a boolean type
return configPath.contains("clear") ||
configPath.contains("cancel") ||
configPath.contains("remove") ||
configPath.contains("replace") ||
configPath.contains("use-name-matching") ||
configPath.contains("only-replace-generated-chunks") ||
configPath.contains("ensure-chunks-loaded") ||
configPath.contains("enable-destructive");
}

private void showHelp(CommandSender sender) {
sender.sendMessage(Component.text("AntiNetherite Commands:").color(NamedTextColor.GOLD));
sender.sendMessage(Component.text("/antinetherite reload - Reload the configuration").color(NamedTextColor.YELLOW));
Expand All @@ -325,7 +320,7 @@ private void showHelp(CommandSender sender) {
sender.sendMessage(Component.text(" cancel-pickup, remove-dropped").color(NamedTextColor.GRAY));

sender.sendMessage(Component.text("Ancient debris settings:").color(NamedTextColor.YELLOW));
sender.sendMessage(Component.text(" replace-ancient-debris, replace-on-chunk-load").color(NamedTextColor.GRAY));
sender.sendMessage(Component.text(" replace-when-mined, replace-on-chunk-load").color(NamedTextColor.GRAY));
sender.sendMessage(Component.text(" only-replace-generated-chunks, ensure-chunks-loaded").color(NamedTextColor.GRAY));

sender.sendMessage(Component.text("Detection settings:").color(NamedTextColor.YELLOW));
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/top/modpotato/listeners/AttackListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public void onAttack(EntityDamageByEntityEvent event) {

Player player = (Player) event.getDamager();

// Skip players with bypass permission
if (player.hasPermission("antinetherite.bypass")) {
return;
}

// Skip players in creative or spectator mode if configured to do so
if (config.isIgnoreCreativeSpectator() &&
(player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)) {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/top/modpotato/listeners/CraftListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public void onCraftItem(CraftItemEvent event) {

Player player = (Player) event.getWhoClicked();

// Skip players with bypass permission
if (player.hasPermission("antinetherite.bypass")) {
return;
}

// Skip players in creative or spectator mode if configured to do so
if (config.isIgnoreCreativeSpectator() &&
(player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)) {
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/top/modpotato/listeners/DropListener.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package top.modpotato.listeners;

import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerDropItemEvent;
Expand Down Expand Up @@ -38,6 +39,13 @@ public void onDrop(PlayerDropItemEvent event) {
return;
}

Player player = event.getPlayer();

// Skip players with bypass permission
if (player.hasPermission("antinetherite.bypass")) {
return;
}

ItemStack item = event.getItemDrop().getItemStack();
if (item != null && netheriteDetector.isNetheriteItem(item)) {
if (config.isEnableDestructiveActions()) {
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/top/modpotato/listeners/EquipListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ public void onInventoryClick(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player player)) {
return;
}

// Skip players with bypass permission
if (player.hasPermission("antinetherite.bypass")) {
return;
}

if (shouldIgnore(player)) {
return;
}
Expand Down Expand Up @@ -92,6 +98,12 @@ public void onInventoryDrag(InventoryDragEvent event) {
if (!(event.getWhoClicked() instanceof Player player)) {
return;
}

// Skip players with bypass permission
if (player.hasPermission("antinetherite.bypass")) {
return;
}

if (shouldIgnore(player)) {
return;
}
Expand All @@ -118,6 +130,12 @@ public void onPlayerInteract(PlayerInteractEvent event) {
return;
}
Player player = event.getPlayer();

// Skip players with bypass permission
if (player.hasPermission("antinetherite.bypass")) {
return;
}

if (shouldIgnore(player)) {
return;
}
Expand All @@ -144,6 +162,12 @@ public void onBlockDispenseArmor(BlockDispenseArmorEvent event) {
if (!(event.getTargetEntity() instanceof Player player)) {
return;
}

// Skip players with bypass permission
if (player.hasPermission("antinetherite.bypass")) {
return;
}

if (shouldIgnore(player)) {
return;
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/top/modpotato/listeners/InventoryMoveListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ public void onInventoryClick(InventoryClickEvent event) {

Player player = (Player) event.getWhoClicked();

// Skip players with bypass permission
if (player.hasPermission("antinetherite.bypass")) {
return;
}

// Skip players in creative or spectator mode if configured to do so
if (config.isIgnoreCreativeSpectator() &&
(player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)) {
Expand Down Expand Up @@ -127,6 +132,11 @@ public void onInventoryDrag(InventoryDragEvent event) {

Player player = (Player) event.getWhoClicked();

// Skip players with bypass permission
if (player.hasPermission("antinetherite.bypass")) {
return;
}

// Skip players in creative or spectator mode if configured to do so
if (config.isIgnoreCreativeSpectator() &&
(player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)) {
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/top/modpotato/listeners/MiningListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,14 @@ public void onBlockDamage(BlockDamageEvent event) {
return;
}

// Skip if player is in creative or spectator mode and we're ignoring those modes
Player player = event.getPlayer();

// Skip players with bypass permission
if (player.hasPermission("antinetherite.bypass")) {
return;
}

// Skip if player is in creative or spectator mode and we're ignoring those modes
if (config.isIgnoreCreativeSpectator() &&
(player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)) {
return;
Expand Down
Loading