More item checks, new item storage.
This commit is contained in:
@@ -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