More item checks, new item storage.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -17,6 +17,7 @@ public class NBTConfig implements JsonSerializable<NBTConfig> {
|
||||
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;
|
||||
|
||||
@@ -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<NBTStorage> {
|
||||
@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<String, String> 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<String, Object> 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<String, Object> serializedMap = itemStack.serialize();
|
||||
return Base64.getEncoder().encodeToString(serializedMap.toString().getBytes());
|
||||
// Make a deserialize method too.
|
||||
|
||||
|
||||
@Override
|
||||
public File getFile() {
|
||||
return mappingFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<String> 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),
|
||||
|
||||
@@ -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<T> {
|
||||
public NBTConfig config = Sentinel.getInstance().getDirector().io.nbtConfig;
|
||||
public abstract boolean passes(T input);
|
||||
}
|
||||
@@ -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<Entity> {
|
||||
}
|
||||
}
|
||||
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<Entity> {
|
||||
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);
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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<Mob> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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<ItemStack> {
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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<ItemStack> {
|
||||
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -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<ItemStack> {
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -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<Pair<Player,ItemStack>> {
|
||||
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<Pair<Player,ItemStack>> {
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -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<ItemStack> {
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -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<ItemStack> {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -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<Inventory> {
|
||||
|
||||
@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<Inventory> {
|
||||
}
|
||||
ServerUtils.verbose("Inventory passed all checks.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<ReadWriteNBT> {
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<ReadWriteNBT> {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -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<T> {
|
||||
public abstract boolean passes(T input);
|
||||
}
|
||||
@@ -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<ItemStack> {
|
||||
|
||||
public List<AbstractCheck<ItemStack>> 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");
|
||||
}
|
||||
}
|
||||
@@ -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<ItemStack> {
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -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<TrialSpawner> {
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user