diff --git a/src/main/java/de/feelix/sierra/check/impl/creative/impl/BooksProtocol.java b/src/main/java/de/feelix/sierra/check/impl/creative/impl/BooksProtocol.java index 4045618..160079a 100644 --- a/src/main/java/de/feelix/sierra/check/impl/creative/impl/BooksProtocol.java +++ b/src/main/java/de/feelix/sierra/check/impl/creative/impl/BooksProtocol.java @@ -10,8 +10,21 @@ import de.feelix.sierra.utilities.Pair; import de.feelix.sierraapi.violation.PunishType; +/** + * The BooksProtocol class implements the ItemCheck interface, which represents an item check. It handles the check + * for books in the Sierra plugin. + */ public class BooksProtocol implements ItemCheck { + /** + * Handles the check for books in the Sierra plugin. + * + * @param event The PacketReceiveEvent that triggered the check. + * @param clickedStack The ItemStack that was clicked. + * @param nbtCompound The NBTCompound associated with the clickedStack. + * @param playerData The PlayerData of the player who clicked the ItemStack. + * @return A Pair object containing a String message and a PunishType, or null if the check is disabled or no punishment is necessary. + */ @Override public Pair handleCheck(PacketReceiveEvent event, ItemStack clickedStack, NBTCompound nbtCompound, PlayerData playerData) { diff --git a/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeAnvil.java b/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeAnvil.java index 8431eff..3ced004 100644 --- a/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeAnvil.java +++ b/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeAnvil.java @@ -10,10 +10,19 @@ import de.feelix.sierra.utilities.Pair; import de.feelix.sierraapi.violation.PunishType; +/** + * The CreativeAnvil class represents an implementation of the ItemCheck interface that handles checks for anvil items. + */ public class CreativeAnvil implements ItemCheck { - //This prevents the creation of buggy anvils that crash the client when placed - //https://bugs.mojang.com/browse/MC-82677 + /** + * Determines whether the given ItemStack is an invalid anvil item. + * + * @param itemStack The ItemStack to check. + * @return true if the given ItemStack is an invalid anvil item, false otherwise. + */ + // This prevents the creation of buggy anvils that crash the client when placed + // https://bugs.mojang.com/browse/MC-82677 private boolean invalid(ItemStack itemStack) { if (itemStack.getType() == ItemTypes.ANVIL) { return itemStack.getLegacyData() < 0 || itemStack.getLegacyData() > 2; @@ -21,6 +30,15 @@ private boolean invalid(ItemStack itemStack) { return false; } + /** + * Handle the check for an anvil item. + * + * @param event The PacketReceiveEvent that triggered the check. + * @param clickedStack The ItemStack that was clicked. + * @param nbtCompound The NBTCompound of the anvil item. + * @param playerData The PlayerData of the player. + * @return A Pair object containing a String message and a PunishType, or null if the check passed. + */ @Override public Pair handleCheck(PacketReceiveEvent event, ItemStack clickedStack, NBTCompound nbtCompound, PlayerData playerData) { @@ -29,9 +47,15 @@ public Pair handleCheck(PacketReceiveEvent event, ItemStack } if (nbtCompound.getTags().containsKey("id")) { String id = nbtCompound.getStringTagValueOrNull("id"); + + if (id == null) return null; + if (id.contains("anvil")) { if (nbtCompound.getTags().containsKey("Damage")) { NBTNumber damage = nbtCompound.getNumberTagOrNull("Damage"); + + if (damage == null) return null; + if (damage.getAsInt() > 3 || damage.getAsInt() < 0) { return new Pair<>("Invalid damage size", PunishType.BAN); } diff --git a/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeClientBookCrash.java b/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeClientBookCrash.java index 6587c26..cb47f00 100644 --- a/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeClientBookCrash.java +++ b/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeClientBookCrash.java @@ -16,6 +16,10 @@ //Fixes client-side crash books +/** + * The CreativeClientBookCrash class represents a book that can crash the client when opened. + * It is responsible for handling the check for an item and determining if it contains invalid translation keys. + */ //A book with the nbt from below will crash a client when opened //{generation:0,pages:[0:"{translate:translation.test.invalid}",],author:"someone",title:"a",resolved:1b,} //{generation:0,pages:[0:"{translate:translation.test.invalid2}",],author:"someone",title:"a",resolved:1b,} @@ -23,6 +27,15 @@ public class CreativeClientBookCrash implements ItemCheck { private static final Pattern PATTERN = Pattern.compile("\\s"); + /** + * Handles the check for an item and determines if it contains invalid translation keys. + * + * @param event The packet receive event. + * @param clickedStack The clicked item stack. + * @param nbtCompound The NBT compound of the item stack. + * @param playerData The player data. + * @return A Pair containing a String message and a PunishType if the item contains invalid translation keys, null otherwise. + */ @Override public Pair handleCheck(PacketReceiveEvent event, ItemStack clickedStack, NBTCompound nbtCompound, PlayerData playerData) { @@ -40,6 +53,12 @@ public Pair handleCheck(PacketReceiveEvent event, ItemStack return null; } + /** + * Returns a list of pages from the given NBT compound. + * + * @param nbtCompound the NBT compound to retrieve pages from + * @return a List of String representing the pages, or an empty List if there are no pages + */ private List getPages(NBTCompound nbtCompound) { List pageList = new ArrayList<>(); NBTList nbtList = nbtCompound.getStringListTagOrNull("pages"); diff --git a/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeMap.java b/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeMap.java index 3d6a393..95fc2ac 100644 --- a/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeMap.java +++ b/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeMap.java @@ -11,9 +11,39 @@ import de.feelix.sierra.utilities.Pair; import de.feelix.sierraapi.violation.PunishType; +/** + * The CreativeMap class is a class that implements the ItemCheck interface. It is responsible for handling checks + * related to a creative map exploit. + *

+ * It contains a single method, handleCheck, which takes in a PacketReceiveEvent, an ItemStack, an NBTCompound, and a + * PlayerData object. It checks if the NBTCompound contains a key called "Decorations". If it does, it retrieves the + * NBTList of NBTCompounds associated with the "Decorations" key. It then iterates through each NBTCompound in the + * list and checks if it contains a key called "type". If it does, it retrieves the value associated with the "type" + * key as an NBTByte. If the NBTByte is null, it returns a Pair object with a message indicating that the NBT type field + * is invalid and a PunishType of BAN. If the NBTByte is less than 0, it returns a Pair object with a message indicating + * an invalid byte size in the map and a PunishType of BAN. If none of these conditions are met, it returns null. + *

+ * This class is used to mitigate the exploit related to creative maps by checking the NBT data of clicked items in + * order to identify any potential issues and take appropriate actions. + */ //Fixes CrashMap exploit public class CreativeMap implements ItemCheck { + /** + * This method handles the check for the given packet receive event, clicked stack, NBT compound, and player data. + * It checks if the NBT compound contains the key "Decorations", and if so, iterates over the decorations list. + * For each decoration, it checks if it contains the key "type". If the decoration does not have a valid NBT type + * field, it returns a Pair object with an error message and the PunishType set to BAN. If the decoration has a + * negative byte size, it returns a Pair object with an error message and the PunishType set to BAN. If all checks + * pass, it returns null. + * + * @param event The packet receive event + * @param clickedStack The clicked stack + * @param nbtCompound The NBT compound + * @param playerData The player data + * @return A Pair object with an error message and the PunishType set to BAN if invalid NBT type field + * or negative byte size is detected, null otherwise + */ @Override public Pair handleCheck(PacketReceiveEvent event, ItemStack clickedStack, NBTCompound nbtCompound, PlayerData playerData) { diff --git a/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeSkull.java b/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeSkull.java index 172d9a3..b52bd61 100644 --- a/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeSkull.java +++ b/src/main/java/de/feelix/sierra/check/impl/creative/impl/CreativeSkull.java @@ -14,9 +14,22 @@ import java.util.Base64; import java.util.UUID; +/** + * The CreativeSkull class implements the ItemCheck interface and represents a check for a creative skull item. + * This class checks if the skull owner and properties of the clicked skull are valid. + */ //Fixes crash head / glitch head public class CreativeSkull implements ItemCheck { + /** + * This method handles the check for a given packet event, clicked item stack, NBT compound, and player data. + * + * @param event the packet receive event + * @param clickedStack the clicked item stack + * @param nbtCompound the NBT compound + * @param playerData the player data + * @return a pair of string and PunishType or null + */ @Override public Pair handleCheck(PacketReceiveEvent event, ItemStack clickedStack, NBTCompound nbtCompound, PlayerData playerData) { diff --git a/src/main/java/de/feelix/sierra/check/impl/creative/impl/EnchantLimit.java b/src/main/java/de/feelix/sierra/check/impl/creative/impl/EnchantLimit.java index 6065cf5..b64c547 100644 --- a/src/main/java/de/feelix/sierra/check/impl/creative/impl/EnchantLimit.java +++ b/src/main/java/de/feelix/sierra/check/impl/creative/impl/EnchantLimit.java @@ -13,12 +13,26 @@ import de.feelix.sierra.utilities.Pair; import de.feelix.sierraapi.violation.PunishType; +/** + * The EnchantLimit class is responsible for handling the check for valid enchantment levels on a clicked stack. + * It implements the ItemCheck interface. + */ public class EnchantLimit implements ItemCheck { + private static final ClientVersion CLIENT_VERSION = PacketEvents.getAPI() .getServerManager() .getVersion() .toClientVersion(); + /** + * Handles the check for valid enchantment levels on a clicked stack. + * + * @param event The PacketReceiveEvent that triggered the check. + * @param clickedStack The ItemStack that was clicked. + * @param nbtCompound The NBTCompound associated with the clicked stack. + * @param playerData The PlayerData of the player who clicked the stack. + * @return A Pair object containing the error message and the PunishType if the enchantment level is invalid, or null if the enchantment level is valid. + */ @Override public Pair handleCheck(PacketReceiveEvent event, ItemStack clickedStack, NBTCompound nbtCompound, PlayerData playerData) { diff --git a/src/main/java/de/feelix/sierra/check/impl/creative/impl/FireworkSize.java b/src/main/java/de/feelix/sierra/check/impl/creative/impl/FireworkSize.java index 9d7963f..676180b 100644 --- a/src/main/java/de/feelix/sierra/check/impl/creative/impl/FireworkSize.java +++ b/src/main/java/de/feelix/sierra/check/impl/creative/impl/FireworkSize.java @@ -13,9 +13,25 @@ import de.feelix.sierra.utilities.Pair; import de.feelix.sierraapi.violation.PunishType; +/** + * The FireworkSize class is an implementation of the ItemCheck interface. It handles the check for an invalid explosion + * size in a firework. It checks if the explosion size in a firework exceeds the maximum allowed size and returns an + * appropriate result. + */ // PaperMC public class FireworkSize implements ItemCheck { + /** + * This method handles the check for an invalid explosion size in a firework. + * It checks if the explosion size in a firework exceeds the maximum allowed size and returns a Pair. + * + * @param event The PacketReceiveEvent that triggered the check. + * @param clickedStack The ItemStack that was clicked. + * @param nbtCompound The NBTCompound associated with the ItemStack. + * @param playerData The PlayerData of the player. + * @return A Pair which represents the result of the check. If the explosion size is invalid, it returns a Pair with an error message and PunishType.BAN. Otherwise + * , it returns null. + */ @Override public Pair handleCheck(PacketReceiveEvent event, ItemStack clickedStack, NBTCompound nbtCompound, PlayerData playerData) { if (event.getPacketType() == PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT) { @@ -48,6 +64,13 @@ public Pair handleCheck(PacketReceiveEvent event, ItemStack return null; } + /** + * Checks if an ItemStack has an invalid explosion size in a firework. + * It checks if the explosion size exceeds the maximum allowed size. + * + * @param itemStack The ItemStack to check. + * @return {@code true} if the explosion size is invalid, {@code false} otherwise. + */ private boolean invalid(ItemStack itemStack) { if (itemStack.getNBT() != null) { NBTCompound fireworkNBT = itemStack.getNBT().getCompoundTagOrNull("Fireworks"); diff --git a/src/main/java/de/feelix/sierra/check/impl/creative/impl/InvalidPlainNbt.java b/src/main/java/de/feelix/sierra/check/impl/creative/impl/InvalidPlainNbt.java index cc246c4..d304830 100644 --- a/src/main/java/de/feelix/sierra/check/impl/creative/impl/InvalidPlainNbt.java +++ b/src/main/java/de/feelix/sierra/check/impl/creative/impl/InvalidPlainNbt.java @@ -13,8 +13,18 @@ import de.feelix.sierra.utilities.Pair; import de.feelix.sierraapi.violation.PunishType; +/** + * An implementation of the {@link ItemCheck} interface that checks for invalid NBT data in an ItemStack. + */ public class InvalidPlainNbt implements ItemCheck { + /** + * Checks if a given ItemStack has invalid NBT data and returns the corresponding + * punishable property and PunishType. + * + * @param itemStack the ItemStack to check for invalid NBT data + * @return a Pair object representing the punishable property and PunishType, or null if there are no punishable properties + */ private Pair invalidNbt(ItemStack itemStack) { NBTCompound tag = itemStack.getNBT(); @@ -29,6 +39,12 @@ private Pair invalidNbt(ItemStack itemStack) { return null; } + /** + * Checks if a given NBTCompound tag contains a valid map and returns a Pair object representing the punishable property and the PunishType. + * + * @param nbtTag the NBTCompound tag to check + * @return a Pair object representing the punishable property and the PunishType, or null if there are no punishable properties + */ private Pair checkValidMap(NBTCompound nbtTag) { NBTNumber range = nbtTag.getNumberTagOrNull("range"); int maxMapRange = 15; @@ -38,55 +54,68 @@ private Pair checkValidMap(NBTCompound nbtTag) { return null; } + /** + * Checks if a given NBTCompound tag contains punishable properties related to a spawner. + * + * @param tag the NBTCompound tag to check + * @return a Pair object representing the punishable property and the PunishType, or null if there are no punishable properties + */ private Pair checkForSpawner(NBTCompound tag) { + if (isPunishable(tag.getNumberTagOrNull("MaxNearbyEntities"), Byte.MAX_VALUE)) + return makePunishablePair("MaxNearbyEntities", tag.getNumberTagOrNull("MaxNearbyEntities").getAsInt()); - NBTNumber spawnRange = tag.getNumberTagOrNull("SpawnRange"); - NBTNumber requiredPlayerRange = tag.getNumberTagOrNull("RequiredPlayerRange"); - NBTNumber maxNearbyEntities = tag.getNumberTagOrNull("MaxNearbyEntities"); + if (isPunishable(tag.getNumberTagOrNull("Delay"), Short.MAX_VALUE)) + return makePunishablePair("Delay", tag.getNumberTagOrNull("Delay").getAsInt()); - if (maxNearbyEntities != null && (maxNearbyEntities.getAsInt() > Byte.MAX_VALUE || - maxNearbyEntities.getAsInt() < 0)) { - return new Pair<>("MaxNearbyEntities at: " + maxNearbyEntities.getAsInt(), PunishType.BAN); - } - - NBTNumber spawnCount = tag.getNumberTagOrNull("SpawnCount"); - NBTNumber delay = tag.getNumberTagOrNull("Delay"); - - if (delay != null && (delay.getAsInt() > Short.MAX_VALUE || delay.getAsInt() < 0)) { - return new Pair<>("Delay at: " + delay.getAsInt(), PunishType.BAN); - } + if (isPunishable(tag.getNumberTagOrNull("MinSpawnDelay"), Short.MAX_VALUE)) + return makePunishablePair("MinSpawnDelay", tag.getNumberTagOrNull("MinSpawnDelay").getAsInt()); - NBTNumber maxSpawnDelay = tag.getNumberTagOrNull("MaxSpawnDelay"); - NBTNumber minSpawnDelay = tag.getNumberTagOrNull("MinSpawnDelay"); + if (isPunishable(tag.getNumberTagOrNull("SpawnRange"), 20)) + return makePunishablePair("SpawnRange", tag.getNumberTagOrNull("SpawnRange").getAsInt()); - if (minSpawnDelay != null && (minSpawnDelay.getAsInt() > Short.MAX_VALUE || - minSpawnDelay.getAsInt() < 0)) { - return new Pair<>("MinSpawnDelay at: " + minSpawnDelay.getAsInt(), PunishType.BAN); - } + if (isPunishable(tag.getNumberTagOrNull("MaxSpawnDelay"), 1000)) + return makePunishablePair("MaxSpawnDelay", tag.getNumberTagOrNull("MaxSpawnDelay").getAsInt()); - int maxAllowedSpawnRange = 20; - int maxAllowedSpawnDelay = 1000; - int maxAllowedSpawnCount = 30; - int maxAllowedRequiredPlayerRange = 16; + if (isPunishable(tag.getNumberTagOrNull("SpawnCount"), 30)) + return makePunishablePair("SpawnCount", tag.getNumberTagOrNull("SpawnCount").getAsInt()); - if (spawnRange != null && (spawnRange.getAsInt() > maxAllowedSpawnRange || spawnRange.getAsInt() < 0)) - return new Pair<>("SpawnRange at: " + spawnRange.getAsInt(), PunishType.BAN); + if (isPunishable(tag.getNumberTagOrNull("RequiredPlayerRange"), 16)) + return makePunishablePair("RequiredPlayerRange", tag.getNumberTagOrNull("RequiredPlayerRange").getAsInt()); - if (maxSpawnDelay != null && (maxSpawnDelay.getAsInt() > maxAllowedSpawnDelay || - maxSpawnDelay.getAsInt() < 0)) { - return new Pair<>("MaxSpawnDelay at: " + maxSpawnDelay.getAsInt(), PunishType.BAN); - } + return null; + } - if (spawnCount != null && (spawnCount.getAsInt() > maxAllowedSpawnCount || spawnCount.getAsInt() < 0)) - return new Pair<>("SpawnCount at: " + spawnCount.getAsInt(), PunishType.BAN); + /** + * Determines if a given NBTNumber tag is punishable. + * + * @param tag the NBTNumber tag to check + * @param maxValue the maximum allowed value for the tag + * @return true if the tag is punishable, false otherwise + */ + private boolean isPunishable(NBTNumber tag, int maxValue) { + return tag != null && (tag.getAsInt() > maxValue || tag.getAsInt() < 0); + } - if (requiredPlayerRange != null && (requiredPlayerRange.getAsInt() > maxAllowedRequiredPlayerRange || - requiredPlayerRange.getAsInt() < 0)) { - new Pair<>("RequiredPlayerRange at: " + requiredPlayerRange.getAsInt(), PunishType.BAN); - } - return null; + /** + * Creates a Pair object representing a punishable pair. + * + * @param property the property associated with the pair + * @param value the value associated with the pair + * @return a Pair object representing a punishable pair + */ + private Pair makePunishablePair(String property, int value) { + return new Pair<>(property + " at: " + value, PunishType.BAN); } + /** + * Handles the check based on the given event, clicked stack, NBT compound, and player data. + * + * @param event the event representing the received packet + * @param clickedStack the clicked stack item + * @param nbtCompound the NBT compound associated with the item + * @param playerData the player data + * @return a pair of strings and a PunishType if there is an invalid NBT compound, null otherwise + */ @Override public Pair handleCheck(PacketReceiveEvent event, ItemStack clickedStack, NBTCompound nbtCompound, PlayerData playerData) { diff --git a/src/main/java/de/feelix/sierra/check/impl/creative/impl/PotionLimit.java b/src/main/java/de/feelix/sierra/check/impl/creative/impl/PotionLimit.java index 3951997..08ee303 100644 --- a/src/main/java/de/feelix/sierra/check/impl/creative/impl/PotionLimit.java +++ b/src/main/java/de/feelix/sierra/check/impl/creative/impl/PotionLimit.java @@ -10,8 +10,20 @@ import de.feelix.sierra.utilities.Pair; import de.feelix.sierraapi.violation.PunishType; +/** + * The PotionLimit class implements the ItemCheck interface to handle custom potion effects. + */ public class PotionLimit implements ItemCheck { + /** + * Handle the check for custom potion effects. + * + * @param event The packet receive event. + * @param clickedStack The clicked item stack. + * @param nbtCompound The NBT compound. + * @param playerData The player data. + * @return A Pair object containing the error message and the punishment type if a check fails, or null if all checks pass. + */ @Override public Pair handleCheck(PacketReceiveEvent event, ItemStack clickedStack, NBTCompound nbtCompound, PlayerData playerData) { @@ -21,6 +33,8 @@ public Pair handleCheck(PacketReceiveEvent event, ItemStack NBTList potionEffects = nbtCompound.getCompoundListTagOrNull("CustomPotionEffects"); + if (potionEffects == null) return null; + int maxPotionEffects = 5; //Limit how many custom potion effects a potion can have if (potionEffects.size() >= maxPotionEffects) {