diff --git a/.gradle/8.5/checksums/checksums.lock b/.gradle/8.5/checksums/checksums.lock index 588ab51..7c1a560 100644 Binary files a/.gradle/8.5/checksums/checksums.lock and b/.gradle/8.5/checksums/checksums.lock differ diff --git a/.gradle/8.5/checksums/md5-checksums.bin b/.gradle/8.5/checksums/md5-checksums.bin index ddf14d4..5268b4d 100644 Binary files a/.gradle/8.5/checksums/md5-checksums.bin and b/.gradle/8.5/checksums/md5-checksums.bin differ diff --git a/.gradle/8.5/checksums/sha1-checksums.bin b/.gradle/8.5/checksums/sha1-checksums.bin index 6c772dc..44d0c1a 100644 Binary files a/.gradle/8.5/checksums/sha1-checksums.bin and b/.gradle/8.5/checksums/sha1-checksums.bin differ diff --git a/.gradle/8.5/executionHistory/executionHistory.bin b/.gradle/8.5/executionHistory/executionHistory.bin index f373e08..070bcd1 100644 Binary files a/.gradle/8.5/executionHistory/executionHistory.bin and b/.gradle/8.5/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.5/executionHistory/executionHistory.lock b/.gradle/8.5/executionHistory/executionHistory.lock index a7c86f1..fdf7eea 100644 Binary files a/.gradle/8.5/executionHistory/executionHistory.lock and b/.gradle/8.5/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.5/fileHashes/fileHashes.bin b/.gradle/8.5/fileHashes/fileHashes.bin index 531c16d..b0bd502 100644 Binary files a/.gradle/8.5/fileHashes/fileHashes.bin and b/.gradle/8.5/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.5/fileHashes/fileHashes.lock b/.gradle/8.5/fileHashes/fileHashes.lock index eabc461..aa5d31e 100644 Binary files a/.gradle/8.5/fileHashes/fileHashes.lock and b/.gradle/8.5/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.5/fileHashes/resourceHashesCache.bin b/.gradle/8.5/fileHashes/resourceHashesCache.bin index 7651bff..b56e646 100644 Binary files a/.gradle/8.5/fileHashes/resourceHashesCache.bin and b/.gradle/8.5/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index a34f41f..4e38d46 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe index 0767e4b..31823eb 100644 Binary files a/.gradle/file-system.probe and b/.gradle/file-system.probe differ diff --git a/src/main/java/me/trouper/sentinel/data/config/NBTConfig.java b/src/main/java/me/trouper/sentinel/data/config/NBTConfig.java index 476e0b5..704e1b6 100644 --- a/src/main/java/me/trouper/sentinel/data/config/NBTConfig.java +++ b/src/main/java/me/trouper/sentinel/data/config/NBTConfig.java @@ -17,6 +17,7 @@ public class NBTConfig implements JsonSerializable { public RateLimit rateLimit = new RateLimit(); public class RateLimit { + public int maxOverhead = 32768; public int rateLimitBytes = 16348; public int byteDecay = 1024; // Every Minute public int rateLimitItems = 10; diff --git a/src/main/java/me/trouper/sentinel/data/storage/NBTStorage.java b/src/main/java/me/trouper/sentinel/data/storage/NBTStorage.java index 415fb8b..2a0e9a4 100644 --- a/src/main/java/me/trouper/sentinel/data/storage/NBTStorage.java +++ b/src/main/java/me/trouper/sentinel/data/storage/NBTStorage.java @@ -1,39 +1,79 @@ package me.trouper.sentinel.data.storage; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import io.github.itzispyder.pdk.utils.misc.config.JsonSerializable; import me.trouper.sentinel.Sentinel; import org.bukkit.inventory.ItemStack; import java.io.*; -import java.util.*; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; public class NBTStorage implements JsonSerializable { - @Override - public File getFile() { - File file = new File(Sentinel.getInstance().getDirector().io.getDataFolder(), "/storage/nbt.json"); - file.getParentFile().mkdirs(); - return file; - } - + + // Mapping from file name to owner UUID (as a String) public Map caughtItems = new HashMap<>(); - public static ItemStack toItem(String serializedString) { - if (serializedString.equals("null")) return null; - byte[] decodedBytes = Base64.getDecoder().decode(serializedString); - String mapString = new String(decodedBytes); - // Remove the curly braces and split by commas to get key-value pairs - String[] keyValuePairs = mapString.substring(1, mapString.length() - 1).split(", "); - Map deserializedMap = new HashMap<>(); - for (String pair : keyValuePairs) { - String[] keyValue = pair.split("="); - deserializedMap.put(keyValue[0], keyValue[1]); + private final File mappingFile; + private final File storageDir; + + public NBTStorage() { + // Create the storage directory: /storage/nbt/ inside the plugin data folder + File dataFolder = Sentinel.getInstance().getDirector().io.getDataFolder(); + storageDir = new File(dataFolder, "storage/nbt"); + if (!storageDir.exists()) { + storageDir.mkdirs(); } - ItemStack item = ItemStack.deserialize(deserializedMap); - return item; + // The mapping file that stores the file-name to owner UUID mapping + mappingFile = new File(dataFolder, "storage/nbt.json"); + mappingFile.getParentFile().mkdirs(); + } + + /** + * Stores an ItemStack's serialized NBT to a unique file + * and maps the generated file name to the owner UUID. + * + * @param item the ItemStack to store + * @param owner the owner's UUID + */ + public void storeItem(ItemStack item, UUID owner) { + // Generate a unique file name with a .nbt extension + String fileName = UUID.randomUUID().toString() + ".nbt"; + File file = new File(storageDir, fileName); + try (FileOutputStream fos = new FileOutputStream(file); + OutputStreamWriter writer = new OutputStreamWriter(fos)) { + + String nbt = serializeItem(item); + writer.write(nbt); + } catch (IOException e) { + e.printStackTrace(); + } + // Add mapping: file name -> owner UUID (as string) + caughtItems.put(fileName, owner.toString()); + save(); + } + + /** + * Placeholder for item serialization. + * Replace this with an actual NBT serialization logic. + * + * @param item the ItemStack to serialize + * @return a String representing the NBT data of the item + */ + private String serializeItem(ItemStack item) { + + return item.toString(); } - public static String toB64(ItemStack itemStack) { - Map serializedMap = itemStack.serialize(); - return Base64.getEncoder().encodeToString(serializedMap.toString().getBytes()); + // Make a deserialize method too. + + + @Override + public File getFile() { + return mappingFile; } + } diff --git a/src/main/java/me/trouper/sentinel/server/events/violations/players/CreativeHotbar.java b/src/main/java/me/trouper/sentinel/server/events/violations/players/CreativeHotbar.java index fd30ad9..303285d 100644 --- a/src/main/java/me/trouper/sentinel/server/events/violations/players/CreativeHotbar.java +++ b/src/main/java/me/trouper/sentinel/server/events/violations/players/CreativeHotbar.java @@ -6,8 +6,8 @@ import me.trouper.sentinel.Sentinel; import me.trouper.sentinel.data.storage.NBTStorage; import me.trouper.sentinel.server.events.violations.AbstractViolation; import me.trouper.sentinel.server.functions.helpers.ActionConfiguration; -import me.trouper.sentinel.server.functions.itemchecks.ItemCheck; -import me.trouper.sentinel.server.functions.itemchecks.RateLimitCheck; +import me.trouper.sentinel.server.functions.hotbar.items.ItemCheck; +import me.trouper.sentinel.server.functions.hotbar.items.RateLimitCheck; import me.trouper.sentinel.server.gui.Items; import me.trouper.sentinel.server.gui.MainGUI; import me.trouper.sentinel.server.gui.config.AntiNukeGUI; @@ -45,7 +45,7 @@ public class CreativeHotbar extends AbstractViolation { if (!new RateLimitCheck().passes(new Pair<>(p,i))) { List punishmentCommands = new ArrayList<>(); for (String punishmentCommand : Sentinel.getInstance().getDirector().io.nbtConfig.rateLimit.punishmentCommands) { - punishmentCommands.add(punishmentCommand.formatted()); + punishmentCommands.add(punishmentCommand.formatted(RateLimitCheck.dataUsed.get(p.getUniqueId()),Sentinel.getInstance().getDirector().io.nbtConfig.rateLimit.rateLimitBytes)); } ServerUtils.verbose("Player flags rate limit, performing action"); @@ -55,7 +55,7 @@ public class CreativeHotbar extends AbstractViolation { .cancel(true) .punish(true) .deop(Sentinel.getInstance().getDirector().io.violationConfig.creativeHotbarAction.deop) - .setPunishmentCommands(); + .setPunishmentCommands(punishmentCommands); runActions( Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.rootNameFormatPlayer.formatted(p.getName(), Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.grab, Sentinel.getInstance().getDirector().io.lang.violations.protections.rootName.nbtItem), diff --git a/src/main/java/me/trouper/sentinel/server/functions/hotbar/AbstractCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/AbstractCheck.java new file mode 100644 index 0000000..4796ad2 --- /dev/null +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/AbstractCheck.java @@ -0,0 +1,9 @@ +package me.trouper.sentinel.server.functions.hotbar; + +import me.trouper.sentinel.Sentinel; +import me.trouper.sentinel.data.config.NBTConfig; + +public abstract class AbstractCheck { + public NBTConfig config = Sentinel.getInstance().getDirector().io.nbtConfig; + public abstract boolean passes(T input); +} diff --git a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/EntityCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/entities/EntityCheck.java similarity index 87% rename from src/main/java/me/trouper/sentinel/server/functions/itemchecks/EntityCheck.java rename to src/main/java/me/trouper/sentinel/server/functions/hotbar/entities/EntityCheck.java index 37ade6a..092dda5 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/EntityCheck.java +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/entities/EntityCheck.java @@ -1,7 +1,9 @@ -package me.trouper.sentinel.server.functions.itemchecks; +package me.trouper.sentinel.server.functions.hotbar.entities; import de.tr7zw.changeme.nbtapi.NBT; -import me.trouper.sentinel.Sentinel; +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; +import me.trouper.sentinel.server.functions.hotbar.misc.InventoryCheck; +import me.trouper.sentinel.server.functions.hotbar.items.ItemCheck; import me.trouper.sentinel.utils.InventoryUtils; import me.trouper.sentinel.utils.ServerUtils; import org.bukkit.entity.Entity; @@ -43,7 +45,7 @@ public class EntityCheck extends AbstractCheck { } } if (!entity.getPassengers().isEmpty()) { - if (!Sentinel.getInstance().getDirector().io.nbtConfig.allowRecursion) { + if (!config.allowRecursion) { ServerUtils.verbose("Entity recursion not allowed."); return false; } @@ -60,7 +62,7 @@ public class EntityCheck extends AbstractCheck { ServerUtils.verbose("Entity death time check failed."); failsTiming.set(true); } - if (nbt.hasTag("Hurttime") && nbt.getInteger("Hurttime") < 1) { + if (nbt.hasTag("HurtTime") && nbt.getInteger("HurtTime") < 1) { ServerUtils.verbose("Entity hurt time check failed."); failsTiming.set(true); } diff --git a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/EntitySnapshotCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/entities/EntitySnapshotCheck.java similarity index 83% rename from src/main/java/me/trouper/sentinel/server/functions/itemchecks/EntitySnapshotCheck.java rename to src/main/java/me/trouper/sentinel/server/functions/hotbar/entities/EntitySnapshotCheck.java index b9e1ce6..f647e52 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/EntitySnapshotCheck.java +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/entities/EntitySnapshotCheck.java @@ -1,5 +1,6 @@ -package me.trouper.sentinel.server.functions.itemchecks; +package me.trouper.sentinel.server.functions.hotbar.entities; +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; import me.trouper.sentinel.utils.ServerUtils; import org.bukkit.Bukkit; import org.bukkit.Location; diff --git a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/EquipmentCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/entities/EquipmentCheck.java similarity index 57% rename from src/main/java/me/trouper/sentinel/server/functions/itemchecks/EquipmentCheck.java rename to src/main/java/me/trouper/sentinel/server/functions/hotbar/entities/EquipmentCheck.java index af83534..023046f 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/EquipmentCheck.java +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/entities/EquipmentCheck.java @@ -1,5 +1,7 @@ -package me.trouper.sentinel.server.functions.itemchecks; +package me.trouper.sentinel.server.functions.hotbar.entities; +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; +import me.trouper.sentinel.server.functions.hotbar.items.ItemCheck; import me.trouper.sentinel.utils.ServerUtils; import org.bukkit.entity.Mob; import org.bukkit.inventory.ItemStack; @@ -11,8 +13,10 @@ public class EquipmentCheck extends AbstractCheck { public boolean passes(Mob mob) { ServerUtils.verbose("Running mob check."); for (EquipmentSlot slot : EquipmentSlot.values()) { + if (mob.getEquipment().getItem(slot).isEmpty()) continue; ItemStack item = mob.getEquipment().getItem(slot); - if (item != null && !new ItemCheck().passes(item)) { + if (!new ItemCheck().passes(item)) { + ServerUtils.verbose("Equipment slot did not pass."); return false; } } diff --git a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/EnchantmentCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/EnchantmentCheck.java similarity index 96% rename from src/main/java/me/trouper/sentinel/server/functions/itemchecks/EnchantmentCheck.java rename to src/main/java/me/trouper/sentinel/server/functions/hotbar/items/EnchantmentCheck.java index 6ad5d4d..bbaaacb 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/EnchantmentCheck.java +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/EnchantmentCheck.java @@ -1,6 +1,7 @@ -package me.trouper.sentinel.server.functions.itemchecks; +package me.trouper.sentinel.server.functions.hotbar.items; import me.trouper.sentinel.Sentinel; +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; import me.trouper.sentinel.utils.ServerUtils; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; @@ -10,7 +11,12 @@ import java.util.Map; import static org.bukkit.enchantments.Enchantment.MENDING; -public class EnchantmentCheck { +public class EnchantmentCheck extends AbstractCheck { + + @Override + public boolean passes(ItemStack input) { + return !hasIllegalEnchants(input); + } public boolean hasIllegalEnchants(ItemStack item) { ServerUtils.verbose("Checking item for illegal enchants: ", item.getType().name()); @@ -119,4 +125,6 @@ public class EnchantmentCheck { return level > maxLevel; } + + } diff --git a/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/ItemCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/ItemCheck.java new file mode 100644 index 0000000..9e0ce9a --- /dev/null +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/ItemCheck.java @@ -0,0 +1,81 @@ +package me.trouper.sentinel.server.functions.hotbar.items; + +import de.tr7zw.changeme.nbtapi.NBT; +import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; +import me.trouper.sentinel.Sentinel; +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; +import me.trouper.sentinel.server.functions.hotbar.misc.BlockStateCheck; +import me.trouper.sentinel.server.functions.hotbar.misc.InventoryCheck; +import me.trouper.sentinel.server.functions.hotbar.nbt.ComponentCheck; +import me.trouper.sentinel.utils.InventoryUtils; +import me.trouper.sentinel.utils.ServerUtils; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; + +public class ItemCheck extends AbstractCheck { + + + @Override + public boolean passes(ItemStack item) { + try { + return scan(item); + } catch (Exception ex) { + Sentinel.getInstance().getLogger().warning("Caught an exception while handling an item check: " + Arrays.toString(ex.getStackTrace())); + return false; + } + } + + + private boolean scan(ItemStack item) { + ServerUtils.verbose("Checking item: " + item.getType().name()); + + // No metadata? Nothing to check. + if (item.getItemMeta() == null) { + ServerUtils.verbose("Item passes because it has no metadata."); + return true; + } + + if (!new MetaCheck().passes(item)) { + ServerUtils.verbose("Item failed metadata check."); + return false; + } + + + // NBT-based checks + ReadWriteNBT nbt = NBT.itemStackToNBT(item); + ReadWriteNBT components = nbt.getCompound("components"); + if (components != null) { + if (!new ComponentCheck().passes(components)) { + ServerUtils.verbose("Components check failed."); + return false; + } + } + + // Spawn egg checks. + if (!new SpawnEggCheck().passes(item)) { + ServerUtils.verbose("Spawn egg check failed."); + return false; + } + + if (!new BlockStateCheck().passes(item)) { + ServerUtils.verbose("Block State check failed."); + return false; + } + + // Check for an inventory inside the item. + Inventory inv = InventoryUtils.getInventory(item); + if (inv != null) { + ServerUtils.verbose("Item contains an inventory: " + inv); + if (!new InventoryCheck().passes(inv)) { + ServerUtils.verbose("Item failed inventory check."); + return false; + } + } + + ServerUtils.verbose("Item passed all checks."); + return true; + } +} diff --git a/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/MetaCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/MetaCheck.java new file mode 100644 index 0000000..0caf5e2 --- /dev/null +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/MetaCheck.java @@ -0,0 +1,65 @@ +package me.trouper.sentinel.server.functions.hotbar.items; + +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; +import me.trouper.sentinel.utils.ServerUtils; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.BundleMeta; +import org.bukkit.inventory.meta.ItemMeta; + +public class MetaCheck extends AbstractCheck { + + @Override + public boolean passes(ItemStack item) { + ItemMeta meta = item.getItemMeta(); + // Name, lore, potion, attribute and enchantment checks. + if (!config.allowName && meta.hasDisplayName()) { + ServerUtils.verbose("Custom names not allowed."); + return false; + } + if (!config.allowLore && meta.hasLore()) { + ServerUtils.verbose("Custom lore not allowed."); + return false; + } + if (!config.allowBooks && meta instanceof BookMeta) { + ServerUtils.verbose("Item failed book check."); + return false; + } + if (!config.allowPotions && + (item.getType().equals(Material.POTION) || + item.getType().equals(Material.SPLASH_POTION) || + item.getType().equals(Material.LINGERING_POTION))) { + ServerUtils.verbose("Potions not allowed."); + return false; + } + if (!config.allowAttributes && meta.hasAttributeModifiers()) { + ServerUtils.verbose("Attribute modifiers not allowed."); + return false; + } + if (config.globalMaxEnchant != 0 && new EnchantmentCheck().hasIllegalEnchants(item)) { + ServerUtils.verbose("Illegal enchantments found."); + return false; + } + // Recursion check for use-remainder items. + if (meta.hasUseRemainder()) { + if (!config.allowRecursion) { + ServerUtils.verbose("Recursion not allowed."); + return false; + } + if (meta.getUseRemainder() != null && !passes(meta.getUseRemainder())) { + ServerUtils.verbose("Use remainder item failed check."); + return false; + } + } + + // Bundle check – recursively check the contained items. + if (item.getType().name().contains("_BUNDLE") && meta instanceof BundleMeta bm) { + for (ItemStack bundleItem : bm.getItems()) { + if (!passes(bundleItem)) return false; + } + } + + return true; + } +} diff --git a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/RateLimitCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/RateLimitCheck.java similarity index 73% rename from src/main/java/me/trouper/sentinel/server/functions/itemchecks/RateLimitCheck.java rename to src/main/java/me/trouper/sentinel/server/functions/hotbar/items/RateLimitCheck.java index afda1cf..f77981a 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/RateLimitCheck.java +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/RateLimitCheck.java @@ -1,16 +1,13 @@ -package me.trouper.sentinel.server.functions.itemchecks; +package me.trouper.sentinel.server.functions.hotbar.items; import de.tr7zw.changeme.nbtapi.NBTItem; import io.github.itzispyder.pdk.utils.misc.Pair; import me.trouper.sentinel.Sentinel; +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; import me.trouper.sentinel.utils.ServerUtils; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitTask; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -36,20 +33,19 @@ public class RateLimitCheck extends AbstractCheck> { ServerUtils.verbose("Current Player used items: " + currentUsed); currentUsed++; itemsUsed.put(uuid,currentUsed); - return currentUsed <= Sentinel.getInstance().getDirector().io.nbtConfig.rateLimit.rateLimitItems; + return currentUsed <= config.rateLimit.rateLimitItems; } private boolean dataLimit(Player player, UUID uuid, ItemStack item) { - int itemData = 0; int currentData = dataUsed.getOrDefault(uuid,0); ServerUtils.verbose("Current Player used data: " + currentData); try { NBTItem nbt = new NBTItem(item); - itemData = nbt.toString().length(); + int itemData = nbt.toString().length(); ServerUtils.verbose("Item data: " + itemData); - currentData += itemData; + if (currentData < config.rateLimit.maxOverhead) currentData += itemData; } catch (Exception e) { Sentinel.getInstance().getLogger().warning("Could not determine size of item. Blocking."); Sentinel.getInstance().getLogger().warning(Arrays.toString(e.getStackTrace())); @@ -60,24 +56,24 @@ public class RateLimitCheck extends AbstractCheck> { ServerUtils.verbose("New Player used data: " + currentData); - return currentData <= Sentinel.getInstance().getDirector().io.nbtConfig.rateLimit.rateLimitBytes; + return currentData <= config.rateLimit.rateLimitBytes; } - public static void decayData() { + public void decayData() { for (UUID uuid : dataUsed.keySet()) { int currentData = dataUsed.get(uuid); if (currentData > 0) { - currentData -= Sentinel.getInstance().getDirector().io.nbtConfig.rateLimit.byteDecay; + currentData -= config.rateLimit.byteDecay; dataUsed.put(uuid, Math.max(0, currentData)); } } } - public static void decayItems() { + public void decayItems() { for (UUID uuid : itemsUsed.keySet()) { int currentItems = itemsUsed.get(uuid); if (currentItems > 0) { - currentItems -= Sentinel.getInstance().getDirector().io.nbtConfig.rateLimit.itemDecay; + currentItems -= config.rateLimit.itemDecay; itemsUsed.put(uuid, Math.max(0, currentItems)); } } diff --git a/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/SpawnEggCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/SpawnEggCheck.java new file mode 100644 index 0000000..ac5e7e3 --- /dev/null +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/items/SpawnEggCheck.java @@ -0,0 +1,50 @@ +package me.trouper.sentinel.server.functions.hotbar.items; + +import de.tr7zw.changeme.nbtapi.NBT; +import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; +import me.trouper.sentinel.server.functions.hotbar.entities.EntitySnapshotCheck; +import me.trouper.sentinel.server.functions.hotbar.nbt.EntityDataCheck; +import me.trouper.sentinel.utils.ServerUtils; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SpawnEggMeta; + +public class SpawnEggCheck extends AbstractCheck { + + @Override + public boolean passes(ItemStack item) { + ServerUtils.verbose("Running spawn egg checks on item: ",item.getType().name()); + if (!item.getType().name().toLowerCase().contains("spawn_egg")) return true; + if (!SpawnEggCheck.entityMatches(item)) { + ServerUtils.verbose("Spawn egg entity doesn't match item type."); + return false; + } + ReadWriteNBT nbt = NBT.itemStackToNBT(item); + ReadWriteNBT components = nbt.getCompound("components"); + if (components != null) { + var entityData = components.getCompound("minecraft:entity_data"); + if (!new EntityDataCheck().passes(entityData)) { + ServerUtils.verbose("Spawn egg entity data check failed."); + return false; + } + } + + if (item.hasItemMeta() && item.getItemMeta() instanceof SpawnEggMeta sem) { + if (sem.getSpawnedEntity() != null && !new EntitySnapshotCheck().passes(sem.getSpawnedEntity())) { + ServerUtils.verbose("Spawn egg entity snapshot check failed."); + return false; + } + } + + return true; + } + + public static boolean entityMatches(ItemStack item) { + if (item.hasItemMeta() && item.getItemMeta() instanceof SpawnEggMeta sem) { + String eggEntityName = item.getType().name().replace("_SPAWN_EGG", ""); + return sem.getSpawnedEntity() != null && + sem.getSpawnedEntity().getEntityType().name().equals(eggEntityName); + } + return false; + } +} diff --git a/src/main/java/me/trouper/sentinel/server/functions/hotbar/misc/BlockStateCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/misc/BlockStateCheck.java new file mode 100644 index 0000000..21009d5 --- /dev/null +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/misc/BlockStateCheck.java @@ -0,0 +1,100 @@ +package me.trouper.sentinel.server.functions.hotbar.misc; + +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; +import me.trouper.sentinel.server.functions.hotbar.entities.EntitySnapshotCheck; +import me.trouper.sentinel.server.functions.hotbar.items.ItemCheck; +import me.trouper.sentinel.utils.ServerUtils; +import org.bukkit.Material; +import org.bukkit.block.*; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BlockStateMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.spawner.TrialSpawnerConfiguration; + +public class BlockStateCheck extends AbstractCheck { + @Override + public boolean passes(ItemStack item) { + ItemMeta meta = item.getItemMeta(); + + if (!(meta instanceof BlockStateMeta blockStateMeta)) { + ServerUtils.verbose("Item passes due to not being a block state meta"); + return true; + } + + if (item.getType().name().contains("CAMPFIRE") ) { + BlockState bs = blockStateMeta.getBlockState(); + if (bs instanceof Campfire campfire) { + for (int slot = 0; slot < 4; slot++) { + org.bukkit.inventory.ItemStack campfireItem = campfire.getItem(slot); + if (campfireItem != null && !new ItemCheck().passes(campfireItem)) { + ServerUtils.verbose("Campfire item failed check."); + return false; + } + } + } + } + + // Lectern and Chiseled Bookshelf check (by validating their inventories). + if (item.getType().equals(Material.LECTERN)) { + BlockState bs = blockStateMeta.getBlockState(); + if (bs instanceof Lectern lectern) { + if (!new InventoryCheck().passes(lectern.getInventory())) { + ServerUtils.verbose("Lectern inventory failed check."); + return false; + } + } + } + if (item.getType().equals(Material.CHISELED_BOOKSHELF)) { + BlockState bs = blockStateMeta.getBlockState(); + if (bs instanceof ChiseledBookshelf bookshelf) { + if (!new InventoryCheck().passes(bookshelf.getInventory())) { + ServerUtils.verbose("Chiseled bookshelf inventory failed check."); + return false; + } + } + } + + // Spawner check. + if (item.getType().equals(Material.SPAWNER)) { + BlockState bs = blockStateMeta.getBlockState(); + if (bs instanceof CreatureSpawner spawner) { + if (spawner.getSpawnedEntity() != null) { + if (spawner.getSpawnedEntity().getEntityType().equals(EntityType.FALLING_BLOCK) || + spawner.getSpawnedEntity().getEntityType().equals(EntityType.COMMAND_BLOCK_MINECART)) { + ServerUtils.verbose("Spawner contains disallowed entity type."); + return false; + } + if (!new EntitySnapshotCheck().passes(spawner.getSpawnedEntity())) { + ServerUtils.verbose("Spawner entity snapshot check failed."); + return false; + } + } + } + } + + // Trial Spawner check. + if (item.getType() == Material.TRIAL_SPAWNER) { + BlockState bs = blockStateMeta.getBlockState(); + if (bs instanceof TrialSpawner spawner) { + ServerUtils.verbose("Running trial spawner check."); + if (spawner.getNormalConfiguration() != null) { + TrialSpawnerConfiguration config = spawner.getNormalConfiguration(); + if (config.getSpawnedEntity() != null && !new EntitySnapshotCheck().passes(config.getSpawnedEntity())) { + ServerUtils.verbose("Trial Spawner failed check: Normal entity snapshot not allowed."); + return false; + } + } + if (spawner.getOminousConfiguration() != null) { + TrialSpawnerConfiguration config = spawner.getOminousConfiguration(); + if (config.getSpawnedEntity() != null && !new EntitySnapshotCheck().passes(config.getSpawnedEntity())) { + ServerUtils.verbose("Trial Spawner failed check: Ominous entity snapshot not allowed."); + return false; + } + } + } + } + + return true; + } +} diff --git a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/InventoryCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/misc/InventoryCheck.java similarity index 56% rename from src/main/java/me/trouper/sentinel/server/functions/itemchecks/InventoryCheck.java rename to src/main/java/me/trouper/sentinel/server/functions/hotbar/misc/InventoryCheck.java index 0d442f2..8f4c6c3 100644 --- a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/InventoryCheck.java +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/misc/InventoryCheck.java @@ -1,8 +1,7 @@ -package me.trouper.sentinel.server.functions.itemchecks; +package me.trouper.sentinel.server.functions.hotbar.misc; -import me.trouper.sentinel.Sentinel; -import me.trouper.sentinel.server.functions.itemchecks.AbstractCheck; -import me.trouper.sentinel.server.functions.itemchecks.ItemCheck; +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; +import me.trouper.sentinel.server.functions.hotbar.items.ItemCheck; import me.trouper.sentinel.utils.InventoryUtils; import me.trouper.sentinel.utils.ServerUtils; import org.bukkit.inventory.Inventory; @@ -11,16 +10,20 @@ import org.bukkit.inventory.ItemStack; public class InventoryCheck extends AbstractCheck { @Override - public boolean passes(Inventory inventory) { + public boolean passes(Inventory inv) { ServerUtils.verbose("Running Inventory Check"); - for (ItemStack item : inventory.getContents()) { - if (item == null || item.getType().isAir()) continue; - if (!new ItemCheck().passes(item)) { + + for (ItemStack i : inv.getContents()) { + if (i == null || i.getType().isAir()) continue; + if (!new ItemCheck().passes(i)) { ServerUtils.verbose("Inventory item failed check."); return false; } - Inventory subInventory = InventoryUtils.getInventory(item); - if (subInventory != null && !Sentinel.getInstance().getDirector().io.nbtConfig.allowRecursion) return false; + Inventory subInventory = InventoryUtils.getInventory(i); + if (subInventory != null && !config.allowRecursion) { + ServerUtils.verbose("Recursion is disabled. Failing check."); + return false; + } if (subInventory != null && !passes(subInventory)) { ServerUtils.verbose("Sub-inventory failed check."); return false; @@ -28,5 +31,5 @@ public class InventoryCheck extends AbstractCheck { } ServerUtils.verbose("Inventory passed all checks."); return true; - } + } } diff --git a/src/main/java/me/trouper/sentinel/server/functions/hotbar/nbt/ComponentCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/nbt/ComponentCheck.java new file mode 100644 index 0000000..cb682b7 --- /dev/null +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/nbt/ComponentCheck.java @@ -0,0 +1,32 @@ +package me.trouper.sentinel.server.functions.hotbar.nbt; + +import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; +import me.trouper.sentinel.utils.ServerUtils; + +public class ComponentCheck extends AbstractCheck { + + @Override + public boolean passes(ReadWriteNBT components) { + ServerUtils.verbose("Checking Consumable & tool"); + if (!config.allowCustomConsumables && components.getCompound("minecraft:consumable") != null) { + ServerUtils.verbose("Item is consumable and not allowed."); + return false; + } + if (!config.allowCustomTools && components.getCompound("minecraft:tool") != null) { + ServerUtils.verbose("Item is custom tool and not allowed."); + return false; + } + + ServerUtils.verbose("Checking Entity data"); + + ReadWriteNBT entityData = components.getCompound("minecraft:entity_data"); + if (!new EntityDataCheck().passes(entityData)) { + ServerUtils.verbose("Entity Data Check Failed."); + return false; + } + + return true; + } + +} diff --git a/src/main/java/me/trouper/sentinel/server/functions/hotbar/nbt/EntityDataCheck.java b/src/main/java/me/trouper/sentinel/server/functions/hotbar/nbt/EntityDataCheck.java new file mode 100644 index 0000000..a2e035a --- /dev/null +++ b/src/main/java/me/trouper/sentinel/server/functions/hotbar/nbt/EntityDataCheck.java @@ -0,0 +1,40 @@ +package me.trouper.sentinel.server.functions.hotbar.nbt; + +import de.tr7zw.changeme.nbtapi.NBT; +import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; +import me.trouper.sentinel.server.functions.hotbar.AbstractCheck; +import me.trouper.sentinel.server.functions.hotbar.items.ItemCheck; +import me.trouper.sentinel.utils.ServerUtils; +import org.bukkit.inventory.ItemStack; + +public class EntityDataCheck extends AbstractCheck { + @Override + public boolean passes(ReadWriteNBT entityData) { + if (entityData == null) { + ServerUtils.verbose("Entity Data check passed. There was no data."); + return true; + } + + ReadWriteNBT itemData = entityData.getCompound("Item"); + if (itemData != null) { + ServerUtils.verbose("Entity data holds an item"); + ItemStack heldItem = NBT.itemStackFromNBT(itemData); + if (heldItem != null && !new ItemCheck().passes(heldItem)) { + ServerUtils.verbose("Item contents failed check."); + return false; + } + } + + if (entityData.hasTag("DeathTime") && entityData.getInteger("DeathTime") < 1) { + ServerUtils.verbose("Death time check failed."); + return false; + } + if (entityData.hasTag("HurtTime") && entityData.getInteger("HurtTime") < 1) { + ServerUtils.verbose("Hurt time check failed."); + return false; + } + + ServerUtils.verbose("Entity Data check passed. There was no flagging."); + return true; + } +} diff --git a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/AbstractCheck.java b/src/main/java/me/trouper/sentinel/server/functions/itemchecks/AbstractCheck.java deleted file mode 100644 index 97f49cc..0000000 --- a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/AbstractCheck.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.trouper.sentinel.server.functions.itemchecks; - -import me.trouper.sentinel.Sentinel; -import me.trouper.sentinel.utils.ServerUtils; - -import java.util.Arrays; - -public abstract class AbstractCheck { - public abstract boolean passes(T input); -} diff --git a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/ItemCheck.java b/src/main/java/me/trouper/sentinel/server/functions/itemchecks/ItemCheck.java deleted file mode 100644 index 9e0e68d..0000000 --- a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/ItemCheck.java +++ /dev/null @@ -1,218 +0,0 @@ -package me.trouper.sentinel.server.functions.itemchecks; - -import de.tr7zw.changeme.nbtapi.NBT; -import me.trouper.sentinel.Sentinel; -import me.trouper.sentinel.data.config.NBTConfig; -import me.trouper.sentinel.utils.InventoryUtils; -import me.trouper.sentinel.utils.ServerUtils; -import org.bukkit.Material; -import org.bukkit.block.*; -import org.bukkit.entity.EntityType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BlockStateMeta; -import org.bukkit.inventory.meta.BundleMeta; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; -import java.util.List; - -public class ItemCheck extends AbstractCheck { - - public List> checks; - - public ItemCheck() { - enchantmentCheck = new EnchantmentCheck(); - } - - @Override - public boolean passes(ItemStack item) { - try { - return scan(item); - } catch (Exception ex) { - Sentinel.getInstance().getLogger().warning("Caught an exception while handling an item check: " + Arrays.toString(ex.getStackTrace())); - return false; - } - } - - private boolean checksPass(ItemStack item) { - - } - - private boolean scan(ItemStack item) { - ServerUtils.verbose("Checking item: " + item.getType().name()); - NBTConfig config = Sentinel.getInstance().getDirector().io.nbtConfig; - - // No metadata? Nothing to check. - if (item.getItemMeta() == null) { - ServerUtils.verbose("Item passes because it has no metadata."); - return true; - } - ItemMeta meta = item.getItemMeta(); - - // Check for an inventory inside the item. - Inventory inv = InventoryUtils.getInventory(item); - if (inv != null) { - ServerUtils.verbose("Item contains an inventory: " + inv); - if (!new InventoryCheck().passes(inv)) { - ServerUtils.verbose("Item failed inventory check."); - return false; - } - } - - // NBT-based checks (e.g. custom consumables/tools). - var nbt = NBT.itemStackToNBT(item); - var components = nbt.getCompound("components"); - if (!config.allowCustomConsumables && components.getCompound("minecraft:consumable") != null) { - ServerUtils.verbose("Item is consumable and not allowed."); - return false; - } - if (!config.allowCustomTools && components.getCompound("minecraft:tool") != null) { - ServerUtils.verbose("Item is custom tool and not allowed."); - return false; - } - var entityData = components.getCompound("minecraft:entity_data"); - if (entityData != null) { - if (item.getType().name().contains("ITEM_FRAME")) { - var itemData = entityData.getCompound("Item"); - ItemStack heldItem = NBT.itemStackFromNBT(itemData); - if (heldItem != null && !new ItemCheck().passes(heldItem)) { - ServerUtils.verbose("Item frame contents failed check."); - return false; - } - } - if (isSpawnEgg(item)) { - if (entityData.hasTag("DeathTime") && entityData.getInteger("DeathTime") < 1) { - ServerUtils.verbose("Egg death time check failed."); - return false; - } - if (entityData.hasTag("Hurttime") && entityData.getInteger("HurtTime") < 1) { - ServerUtils.verbose("Egg hurt time check failed."); - return false; - } - } - } - - // Bundle check – recursively check the contained items. - if (item.getType().name().contains("_BUNDLE") && meta instanceof BundleMeta bm) { - for (ItemStack bundleItem : bm.getItems()) { - if (!passes(bundleItem)) return false; - } - } - - // Campfire check. - if (item.getType().name().contains("CAMPFIRE") && meta instanceof BlockStateMeta blockStateMeta) { - BlockState bs = blockStateMeta.getBlockState(); - if (bs instanceof Campfire campfire) { - for (int slot = 0; slot < 4; slot++) { - ItemStack campfireItem = campfire.getItem(slot); - if (campfireItem != null && !passes(campfireItem)) { - ServerUtils.verbose("Campfire item failed check."); - return false; - } - } - } - } - - // Lectern and Chiseled Bookshelf check (by validating their inventories). - if (item.getType().equals(Material.LECTERN) && meta instanceof BlockStateMeta blockStateMeta) { - BlockState bs = blockStateMeta.getBlockState(); - if (bs instanceof Lectern lectern) { - if (!new InventoryCheck().passes(lectern.getInventory())) { - ServerUtils.verbose("Lectern inventory failed check."); - return false; - } - } - } - if (item.getType().equals(Material.CHISELED_BOOKSHELF) && meta instanceof BlockStateMeta blockStateMeta) { - BlockState bs = blockStateMeta.getBlockState(); - if (bs instanceof ChiseledBookshelf bookshelf) { - if (!new InventoryCheck().passes(bookshelf.getInventory())) { - ServerUtils.verbose("Chiseled bookshelf inventory failed check."); - return false; - } - } - } - - // Spawner check. - if (item.getType().equals(Material.SPAWNER) && meta instanceof BlockStateMeta blockStateMeta) { - BlockState bs = blockStateMeta.getBlockState(); - if (bs instanceof CreatureSpawner spawner) { - if (spawner.getSpawnedEntity() != null) { - if (spawner.getSpawnedEntity().getEntityType().equals(EntityType.FALLING_BLOCK) || - spawner.getSpawnedEntity().getEntityType().equals(EntityType.COMMAND_BLOCK_MINECART)) { - ServerUtils.verbose("Spawner contains disallowed entity type."); - return false; - } - if (!new EntitySnapshotCheck().passes(spawner.getSpawnedEntity())) { - ServerUtils.verbose("Spawner entity snapshot check failed."); - return false; - } - } - } - } - - // Trial Spawner check. - if (item.getType() == Material.TRIAL_SPAWNER && meta instanceof BlockStateMeta blockStateMeta) { - BlockState bs = blockStateMeta.getBlockState(); - if (bs instanceof TrialSpawner trialSpawner) { - if (!new TrialSpawnerCheck().passes(trialSpawner)) return false; - } - } - - // Spawn egg checks. - if (isSpawnEgg(item)) { - if (!SpawnEggCheck.matches(item)) { - ServerUtils.verbose("Spawn egg match check failed."); - return false; - } - if (!new SpawnEggCheck().passes(item)) { - ServerUtils.verbose("Spawn egg check failed."); - return false; - } - } - - // Name, lore, potion, attribute and enchantment checks. - if (!config.allowName && meta.hasDisplayName()) { - ServerUtils.verbose("Custom names not allowed."); - return false; - } - if (!config.allowLore && meta.hasLore()) { - ServerUtils.verbose("Custom lore not allowed."); - return false; - } - if (!config.allowPotions && - (item.getType().equals(Material.POTION) || - item.getType().equals(Material.SPLASH_POTION) || - item.getType().equals(Material.LINGERING_POTION))) { - ServerUtils.verbose("Potions not allowed."); - return false; - } - if (!config.allowAttributes && meta.hasAttributeModifiers()) { - ServerUtils.verbose("Attribute modifiers not allowed."); - return false; - } - if (config.globalMaxEnchant != 0 && new EnchantmentCheck().hasIllegalEnchants(item)) { - ServerUtils.verbose("Illegal enchantments found."); - return false; - } - // Recursion check for use-remainder items. - if (meta.hasUseRemainder()) { - if (!config.allowRecursion) { - ServerUtils.verbose("Recursion not allowed."); - return false; - } - if (meta.getUseRemainder() != null && !passes(meta.getUseRemainder())) { - ServerUtils.verbose("Use remainder item failed check."); - return false; - } - } - - ServerUtils.verbose("Item passed all checks."); - return true; - } - - private boolean isSpawnEgg(ItemStack item) { - return item.getType().name().toLowerCase().contains("spawn_egg"); - } -} diff --git a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/SpawnEggCheck.java b/src/main/java/me/trouper/sentinel/server/functions/itemchecks/SpawnEggCheck.java deleted file mode 100644 index 79d0ad5..0000000 --- a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/SpawnEggCheck.java +++ /dev/null @@ -1,31 +0,0 @@ -package me.trouper.sentinel.server.functions.itemchecks; - -import me.trouper.sentinel.utils.ServerUtils; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SpawnEggMeta; - -public class SpawnEggCheck extends AbstractCheck { - - @Override - public boolean passes(ItemStack item) { - ServerUtils.verbose("Running spawn egg checks on item: ",item.getType().name()); - if (item.hasItemMeta() && item.getItemMeta() instanceof SpawnEggMeta sem) { - if (sem.getSpawnedEntity() != null && !new EntitySnapshotCheck().passes(sem.getSpawnedEntity())) { - return false; - } - } - return true; - } - - public static boolean matches(ItemStack item) { - if (item.hasItemMeta() && item.getItemMeta() instanceof SpawnEggMeta sem) { - String eggEntityName = item.getType().name().replace("_SPAWN_EGG", ""); - return sem.getSpawnedEntity() != null && - sem.getSpawnedEntity().getEntityType().name().equals(eggEntityName); - } - return false; - } -} diff --git a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/TrialSpawnerCheck.java b/src/main/java/me/trouper/sentinel/server/functions/itemchecks/TrialSpawnerCheck.java deleted file mode 100644 index 4b06e98..0000000 --- a/src/main/java/me/trouper/sentinel/server/functions/itemchecks/TrialSpawnerCheck.java +++ /dev/null @@ -1,33 +0,0 @@ -package me.trouper.sentinel.server.functions.itemchecks; - -import me.trouper.sentinel.utils.ServerUtils; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.block.TrialSpawner; -import org.bukkit.block.spawner.SpawnerEntry; -import org.bukkit.entity.Entity; -import org.bukkit.spawner.TrialSpawnerConfiguration; - -public class TrialSpawnerCheck extends AbstractCheck { - - @Override - public boolean passes(TrialSpawner spawner) { - ServerUtils.verbose("Running trial spawner check."); - if (spawner.getNormalConfiguration() != null) { - TrialSpawnerConfiguration config = spawner.getNormalConfiguration(); - if (config.getSpawnedEntity() != null && !new EntitySnapshotCheck().passes(config.getSpawnedEntity())) { - ServerUtils.verbose("Trial Spawner failed check: Normal entity snapshot not allowed."); - return false; - } - } - if (spawner.getOminousConfiguration() != null) { - TrialSpawnerConfiguration config = spawner.getOminousConfiguration(); - if (config.getSpawnedEntity() != null && !new EntitySnapshotCheck().passes(config.getSpawnedEntity())) { - ServerUtils.verbose("Trial Spawner failed check: Ominous entity snapshot not allowed."); - return false; - } - } - return true; - } -} - diff --git a/src/main/java/me/trouper/sentinel/startup/drm/Loader.java b/src/main/java/me/trouper/sentinel/startup/drm/Loader.java index 2500200..832232a 100644 --- a/src/main/java/me/trouper/sentinel/startup/drm/Loader.java +++ b/src/main/java/me/trouper/sentinel/startup/drm/Loader.java @@ -4,7 +4,6 @@ import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.event.PacketListenerPriority; import io.github.itzispyder.pdk.utils.SchedulerUtils; import me.trouper.sentinel.Sentinel; -import me.trouper.sentinel.data.config.MainConfig; import me.trouper.sentinel.server.commands.*; import me.trouper.sentinel.server.events.admin.AntiBanEvents; import me.trouper.sentinel.server.events.admin.BlockDisplayHideEvent; @@ -28,7 +27,7 @@ import me.trouper.sentinel.server.events.violations.entities.CommandMinecartPlac import me.trouper.sentinel.server.events.violations.entities.CommandMinecartUse; import me.trouper.sentinel.server.functions.chatfilter.profanity.ProfanityFilter; import me.trouper.sentinel.server.functions.chatfilter.spam.SpamFilter; -import me.trouper.sentinel.server.functions.itemchecks.RateLimitCheck; +import me.trouper.sentinel.server.functions.hotbar.items.RateLimitCheck; import me.trouper.sentinel.utils.Text; import org.bukkit.Bukkit; @@ -184,8 +183,8 @@ public final class Loader { Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), SpamFilter::decayHeat,0, 20); Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), ProfanityFilter::decayScore,0,1200); Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), WandEvents::handleDisplay,0,1); - Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), RateLimitCheck::decayData,0,1200); - Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), RateLimitCheck::decayItems,0,200); + Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), new RateLimitCheck()::decayData,0,1200); + Bukkit.getScheduler().runTaskTimer(Sentinel.getInstance(), new RateLimitCheck()::decayItems,0,200); if (Sentinel.getInstance().getDirector().io.mainConfig.backdoorDetection.enabled) Sentinel.getInstance().getDirector().backdoorDetection.init();