From aea3ab11ab879a8ba31dd560e42848d328410854 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Sun, 10 Jul 2016 10:45:05 -0500 Subject: [PATCH] Block sketchy head items and blocks --- .../0166-Block-sketchy-heads.patch | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 Spigot-Server-Patches/0166-Block-sketchy-heads.patch diff --git a/Spigot-Server-Patches/0166-Block-sketchy-heads.patch b/Spigot-Server-Patches/0166-Block-sketchy-heads.patch new file mode 100644 index 0000000000..22be90a90f --- /dev/null +++ b/Spigot-Server-Patches/0166-Block-sketchy-heads.patch @@ -0,0 +1,122 @@ +From efa5bad0e1fffbffdea0b131524edb1d2054d6b7 Mon Sep 17 00:00:00 2001 +From: Zach Brown +Date: Sat, 9 Jul 2016 20:00:28 -0500 +Subject: [PATCH] Block sketchy heads + +Checks for, and blocks, sketchy creative mode spawned, heads. +Currently only checks for new data, could be added to check all data if needed. +This is an NMS-port of the work done here: https://github.com/MylesIsCool/SkullExploitPatch by MylesIsCool (_MylesC) + +diff --git a/src/main/java/com/destroystokyo/paper/ItemFilter.java b/src/main/java/com/destroystokyo/paper/ItemFilter.java +new file mode 100644 +index 0000000..9266c19 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/ItemFilter.java +@@ -0,0 +1,84 @@ ++package com.destroystokyo.paper; ++ ++import net.minecraft.server.*; ++ ++import javax.annotation.Nullable; ++ ++public class ItemFilter { ++ ++ /** ++ * Checks if the ItemStack passed could be a sketchy head item or block ++ * @param itemStackIn the ItemStack to check ++ * @return whether the item is safe or sketchy ++ */ ++ public static boolean isHeadSketchy(@Nullable ItemStack itemStackIn) { ++ if (itemStackIn != null && itemStackIn.getTag() != null) { ++ NBTTagCompound itemTag = itemStackIn.getTag(); ++ if (Item.getId(itemStackIn.getItem()) == Item.getId(Items.SKULL) && itemStackIn.getData() == 3) { ++ return isHeadItemSketchy(itemTag); ++ } else if (Item.getId(itemStackIn.getItem()) == Block.getId(Blocks.SKULL)) { ++ return isHeadBlockSketchy(itemTag); ++ } ++ ++ // If we can't figure out which is which just run it through both ++ return isHeadItemSketchy(itemTag) || isHeadBlockSketchy(itemTag); ++ } ++ return false; ++ } ++ ++ /** ++ * Checks the NBTTagCompound for sketchy data, from the perspective of an Item ++ * @param nbtTagCompound NBTTagCompound from an Item ++ * @return whether the data is safe or sketchy ++ */ ++ private static boolean isHeadItemSketchy(NBTTagCompound nbtTagCompound) { ++ if (nbtTagCompound.hasKey("SkullOwner")) { ++ NBTTagCompound skullOwner = nbtTagCompound.getCompound("SkullOwner"); ++ if (skullOwner.hasKey("Properties")) { ++ return isHeadNBTSketchy(skullOwner.getCompound("Properties")); ++ } ++ } ++ return false; ++ } ++ ++ /** ++ * Checks the NBTTagCompound for sketchy data, from the perspective of a Block ++ * @param nbtTagCompound NBTTagCompound from a Block ++ * @return whether the data is safe or sketchy ++ */ ++ private static boolean isHeadBlockSketchy(NBTTagCompound nbtTagCompound) { ++ if (nbtTagCompound.hasKey("Owner")) { ++ NBTTagCompound skullOwner = nbtTagCompound.getCompound("Owner"); ++ if (skullOwner.hasKey("Properties")) { ++ return isHeadNBTSketchy(skullOwner.getCompound("Properties")); ++ } ++ } ++ return false; ++ } ++ ++ /** ++ * Generified checker for use in both Items and Blocks after some semantics ++ * are done above in the calling methods. ++ * @param properties The generified properties compound from a parent-compound ++ * @return whether the data is safe or sketchy ++ */ ++ private static boolean isHeadNBTSketchy(NBTTagCompound properties) { ++ if (properties.hasKey("textures")) { ++ NBTTagList textures = properties.getList("textures", 10); ++ for (NBTBase texture : textures.list) { ++ if (texture instanceof NBTTagCompound) { ++ if (!((NBTTagCompound) texture).hasKey("Signature")) { ++ // Check ++ if (((NBTTagCompound) texture).hasKey("Value")) { ++ if (((NBTTagCompound) texture).getString("Value").trim().length() > 0) { ++ return false; ++ } ++ } ++ return true; ++ } ++ } ++ } ++ } ++ return false; ++ } ++} +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 85c62cd..0b1e089 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -2028,6 +2028,15 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable { + } + } + ++ // Paper start - Block sketchy heads ++ if (itemstack != null && (Item.getId(itemstack.getItem()) == Item.getId(Items.SKULL) && itemstack.getData() == 3 || Item.getId(itemstack.getItem()) == Block.getId(Blocks.SKULL))) { ++ if (com.destroystokyo.paper.ItemFilter.isHeadSketchy(itemstack)) { ++ this.disconnect("Bad creative item!"); ++ return; ++ } ++ } ++ // Paper end ++ + boolean flag1 = packetplayinsetcreativeslot.a() >= 1 && packetplayinsetcreativeslot.a() <= 45; + // CraftBukkit - Add invalidItems check + boolean flag2 = itemstack == null || itemstack.getItem() != null && (!invalidItems.contains(Item.getId(itemstack.getItem())) || !org.spigotmc.SpigotConfig.filterCreativeItems); // Spigot +-- +2.9.0 +