diff --git a/patches/server/0046-Do-not-log-invalid-items-in-HoverEvent-and-ItemFrame.patch b/patches/server/0046-Do-not-log-invalid-items-in-HoverEvent-and-ItemFrame.patch new file mode 100644 index 0000000..b6063ad --- /dev/null +++ b/patches/server/0046-Do-not-log-invalid-items-in-HoverEvent-and-ItemFrame.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Telesphoreo +Date: Mon, 15 Apr 2024 22:26:14 -0500 +Subject: [PATCH] Do not log invalid items in HoverEvent and ItemFrame + + +diff --git a/src/main/java/net/minecraft/network/chat/HoverEvent.java b/src/main/java/net/minecraft/network/chat/HoverEvent.java +index 433e586bed53a8c17adec74b3088899c748d4be3..a82b4e39c3160114aded3f33c85fad2e95065b72 100644 +--- a/src/main/java/net/minecraft/network/chat/HoverEvent.java ++++ b/src/main/java/net/minecraft/network/chat/HoverEvent.java +@@ -261,7 +261,7 @@ public class HoverEvent { + CompoundTag compoundTag = TagParser.parseTag(text.getString()); + return DataResult.success(new HoverEvent.ItemStackInfo(ItemStack.of(compoundTag))); + } catch (CommandSyntaxException var2) { +- return DataResult.error(() -> "Failed to parse item tag: " + var2.getMessage()); ++ return null; + } + } + } +diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +index c34701f95580e4cf45fe086115563127432a28c5..fc7547381a5dd7c0aae352c0cae72a980953b98f 100644 +--- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java ++++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java +@@ -436,7 +436,7 @@ public class ItemFrame extends HangingEntity { + ItemStack itemstack = ItemStack.of(nbttagcompound1); + + if (itemstack.isEmpty()) { +- ItemFrame.LOGGER.warn("Unable to load item from: {}", nbttagcompound1); ++ // Scissors - ignore invalid items + } + + ItemStack itemstack1 = this.getItem(); diff --git a/patches/server/0047-Better-handling-of-invalid-JSON-components.patch b/patches/server/0047-Better-handling-of-invalid-JSON-components.patch new file mode 100644 index 0000000..a179fa4 --- /dev/null +++ b/patches/server/0047-Better-handling-of-invalid-JSON-components.patch @@ -0,0 +1,141 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Telesphoreo +Date: Mon, 15 Apr 2024 22:36:13 -0500 +Subject: [PATCH] Better handling of invalid JSON components + + +diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java +index e028353e0261310afc42ca0454b723d9f1ffc131..ed8810319db2ce754245193a62ea7a9a32ac13ec 100644 +--- a/src/main/java/io/papermc/paper/util/MCUtil.java ++++ b/src/main/java/io/papermc/paper/util/MCUtil.java +@@ -675,12 +675,6 @@ public final class MCUtil { + return null; + } + String string = compound.getString(key); +- try { +- return net.minecraft.network.chat.Component.Serializer.fromJson(string); +- } catch (com.google.gson.JsonParseException e) { +- org.bukkit.Bukkit.getLogger().warning("Unable to parse " + key + " from " + compound +": " + e.getMessage()); +- } +- +- return null; ++ return net.minecraft.network.chat.Component.Serializer.fromJsonSafe(string); // Scissors + } + } +diff --git a/src/main/java/net/minecraft/network/chat/Component.java b/src/main/java/net/minecraft/network/chat/Component.java +index e747eddff10e1be2b503cbbf503a21e1de4569ba..df3c03aeaee5c12c5d57584535c9c7aa01be7dd3 100644 +--- a/src/main/java/net/minecraft/network/chat/Component.java ++++ b/src/main/java/net/minecraft/network/chat/Component.java +@@ -378,6 +378,26 @@ public interface Component extends Message, FormattedText, Iterable { + return json == null ? null : Serializer.deserialize(json); + } + ++ // Scissors start ++ @Nullable ++ public static MutableComponent fromJsonSafe(String json) { ++ try { ++ return fromJson(json); ++ } catch (Exception ex) { ++ return Component.empty().append("** Invalid JSON Component **").withStyle(ChatFormatting.RED); ++ } ++ } ++ ++ @Nullable ++ public static MutableComponent fromJsonSafe(JsonElement json) { ++ try { ++ return fromJson(json); ++ } catch (Exception ex) { ++ return Component.empty().append("** Invalid JSON Component **").withStyle(ChatFormatting.RED); ++ } ++ } ++ // Scissors end ++ + @Nullable + public static MutableComponent fromJsonLenient(String json) { + JsonReader jsonreader = new JsonReader(new StringReader(json)); +diff --git a/src/main/java/net/minecraft/network/chat/HoverEvent.java b/src/main/java/net/minecraft/network/chat/HoverEvent.java +index a82b4e39c3160114aded3f33c85fad2e95065b72..e1f15ac481ab598e420ad79bcf289251d9f1c99a 100644 +--- a/src/main/java/net/minecraft/network/chat/HoverEvent.java ++++ b/src/main/java/net/minecraft/network/chat/HoverEvent.java +@@ -147,7 +147,7 @@ public class HoverEvent { + public static DataResult legacyCreate(Component text) { + try { + CompoundTag compoundTag = TagParser.parseTag(text.getString()); +- Component component = Component.Serializer.fromJson(compoundTag.getString("name")); ++ Component component = Component.Serializer.fromJsonSafe(compoundTag.getString("name")); // Scissors - Use safer method for getting Components from JSON + EntityType entityType = BuiltInRegistries.ENTITY_TYPE.get(new ResourceLocation(compoundTag.getString("type"))); + // Scissors start + UUID uUID; +diff --git a/src/main/java/net/minecraft/network/chat/contents/NbtContents.java b/src/main/java/net/minecraft/network/chat/contents/NbtContents.java +index c5673657ca6332147a5cbd2f4107fee13b9b7f47..3fec6f3e0adef6e2094157ef9040c7c6dc41a6c2 100644 +--- a/src/main/java/net/minecraft/network/chat/contents/NbtContents.java ++++ b/src/main/java/net/minecraft/network/chat/contents/NbtContents.java +@@ -124,10 +124,10 @@ public class NbtContents implements ComponentContents { + ); + return stream.flatMap(text -> { + try { +- MutableComponent mutableComponent = Component.Serializer.fromJson(text); ++ MutableComponent mutableComponent = Component.Serializer.fromJsonSafe(text); // Scissors + return Stream.of(ComponentUtils.updateForEntity(source, mutableComponent, sender, depth)); + } catch (Exception var5x) { +- LOGGER.warn("Failed to parse component: {}", text, var5x); ++ // Scissors - don't log + return Stream.of(); + } + }).reduce((accumulator, current) -> accumulator.append(component).append(current)).orElseGet(Component::empty); +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index aec4991e8bd75c0020029008951e4cc2a83ed2b2..36b1a1cc66b9852d3b10c09cbf39262f51996663 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -2545,11 +2545,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S + if (nbt.contains("CustomName", 8)) { + String s = nbt.getString("CustomName"); + +- try { +- this.setCustomName(Component.Serializer.fromJson(s)); +- } catch (Exception exception) { +- Entity.LOGGER.warn("Failed to parse entity custom name {}", s, exception); +- } ++ this.setCustomName(Component.Serializer.fromJsonSafe(s)); // Scissors - Use safer method for getting Components from JSON + } + + this.setCustomNameVisible(nbt.getBoolean("CustomNameVisible")); +diff --git a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java +index 7eb1c28886741bdfe7985d16b6824f3e85ffae50..a6b7ff2e50c9700589428cc7d61b5ef9f9082ea8 100644 +--- a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java ++++ b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java +@@ -41,7 +41,7 @@ public class ScoreboardSaveData extends SavedData { + CompoundTag compoundTag = nbt.getCompound(i); + String string = compoundTag.getString("Name"); + PlayerTeam playerTeam = this.scoreboard.addPlayerTeam(string); +- Component component = Component.Serializer.fromJson(compoundTag.getString("DisplayName")); ++ Component component = Component.Serializer.fromJsonSafe(compoundTag.getString("DisplayName")); // Scissors - Use safer method for getting Components from JSON + if (component != null) { + playerTeam.setDisplayName(component); + } +@@ -59,14 +59,14 @@ public class ScoreboardSaveData extends SavedData { + } + + if (compoundTag.contains("MemberNamePrefix", 8)) { +- Component component2 = Component.Serializer.fromJson(compoundTag.getString("MemberNamePrefix")); ++ Component component2 = Component.Serializer.fromJsonSafe(compoundTag.getString("MemberNamePrefix")); // Scissors - Use safer method for getting Components from JSON + if (component2 != null) { + playerTeam.setPlayerPrefix(component2); + } + } + + if (compoundTag.contains("MemberNameSuffix", 8)) { +- Component component3 = Component.Serializer.fromJson(compoundTag.getString("MemberNameSuffix")); ++ Component component3 = Component.Serializer.fromJsonSafe(compoundTag.getString("MemberNameSuffix")); // Scissors - Use safer method for getting Components from JSON + if (component3 != null) { + playerTeam.setPlayerSuffix(component3); + } +@@ -123,7 +123,7 @@ public class ScoreboardSaveData extends SavedData { + return ObjectiveCriteria.DUMMY; + }); + String string2 = compoundTag.getString("Name"); +- Component component = Component.Serializer.fromJson(compoundTag.getString("DisplayName")); ++ Component component = Component.Serializer.fromJsonSafe(compoundTag.getString("DisplayName")); // Scissors - Use safer method for getting Components from JSON + ObjectiveCriteria.RenderType renderType = ObjectiveCriteria.RenderType.byId(compoundTag.getString("RenderType")); + boolean bl = compoundTag.getBoolean("display_auto_update"); + NumberFormat numberFormat = NumberFormatTypes.CODEC.parse(NbtOps.INSTANCE, compoundTag.get("format")).result().orElse(null); diff --git a/patches/server/0048-Reset-large-tags.patch b/patches/server/0048-Reset-large-tags.patch new file mode 100644 index 0000000..063e14f --- /dev/null +++ b/patches/server/0048-Reset-large-tags.patch @@ -0,0 +1,319 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Telesphoreo +Date: Mon, 15 Apr 2024 22:49:31 -0500 +Subject: [PATCH] Reset large tags + + +diff --git a/src/main/java/net/minecraft/world/ContainerHelper.java b/src/main/java/net/minecraft/world/ContainerHelper.java +index 4105bb71b1f1614b3e91478b40b85add94a9257b..52d2a8fd6e16c8d85f2544ffdb9ed4d18b298e1c 100644 +--- a/src/main/java/net/minecraft/world/ContainerHelper.java ++++ b/src/main/java/net/minecraft/world/ContainerHelper.java +@@ -2,6 +2,8 @@ package net.minecraft.world; + + import java.util.List; + import java.util.function.Predicate; ++ ++import me.totalfreedom.scissors.NbtUtility; // Scissors + import net.minecraft.core.NonNullList; + import net.minecraft.nbt.CompoundTag; + import net.minecraft.nbt.ListTag; +@@ -22,10 +24,12 @@ public class ContainerHelper { + + public static CompoundTag saveAllItems(CompoundTag nbt, NonNullList stacks, boolean setIfEmpty) { + ListTag listTag = new ListTag(); ++ long total = 0; // Scissors + + for (int i = 0; i < stacks.size(); i++) { + ItemStack itemStack = stacks.get(i); + if (!itemStack.isEmpty()) { ++ total += NbtUtility.getTagSize(itemStack.getTag()); // Scissors + CompoundTag compoundTag = new CompoundTag(); + compoundTag.putByte("Slot", (byte)i); + itemStack.save(compoundTag); +@@ -33,7 +37,7 @@ public class ContainerHelper { + } + } + +- if (!listTag.isEmpty() || setIfEmpty) { ++ if ((!listTag.isEmpty() || setIfEmpty) && !(total > NbtUtility.MAXIMUM_SIZE)) { // Scissors + nbt.put("Items", listTag); + } + +@@ -42,11 +46,19 @@ public class ContainerHelper { + + public static void loadAllItems(CompoundTag nbt, NonNullList stacks) { + ListTag listTag = nbt.getList("Items", 10); ++ long total = 0; // Scissors - Account for items inside containers + + for (int i = 0; i < listTag.size(); i++) { + CompoundTag compoundTag = listTag.getCompound(i); + int j = compoundTag.getByte("Slot") & 255; + if (j >= 0 && j < stacks.size()) { ++ // Scissors start ++ total += NbtUtility.getTagSize(compoundTag); ++ if (total >= NbtUtility.MAXIMUM_SIZE) { ++ stacks.clear(); ++ break; ++ } ++ // Scissors end + stacks.set(j, ItemStack.of(compoundTag)); + } + } +diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java +index 1ad126d992d95062a3db08374db7a927f23a0cac..6af963d383293a4a6f8d517e2dc179ab70744b31 100644 +--- a/src/main/java/net/minecraft/world/item/ItemStack.java ++++ b/src/main/java/net/minecraft/world/item/ItemStack.java +@@ -23,6 +23,8 @@ import java.util.function.Predicate; + import java.util.stream.Collectors; + import java.util.stream.Stream; + import javax.annotation.Nullable; ++ ++import me.totalfreedom.scissors.NbtUtility; + import net.minecraft.ChatFormatting; + import net.minecraft.Util; + import net.minecraft.advancements.CriteriaTriggers; +@@ -278,6 +280,12 @@ public final class ItemStack { + + // CraftBukkit - break into own method + private void load(CompoundTag nbttagcompound) { ++ // Scissors start - Reset large tags ++ if (NbtUtility.isTooLarge(nbttagcompound)) { ++ // Reset tag without destroying item ++ nbttagcompound = NbtUtility.Item.removeItemData(nbttagcompound); ++ } ++ // Scissors end + this.item = (Item) BuiltInRegistries.ITEM.get(new ResourceLocation(nbttagcompound.getString("id"))); + this.count = nbttagcompound.getByte("Count"); + if (nbttagcompound.contains("tag", 10)) { +@@ -585,7 +593,11 @@ public final class ItemStack { + nbt.putString("id", minecraftkey == null ? "minecraft:air" : minecraftkey.toString()); + nbt.putByte("Count", (byte) this.count); + if (this.tag != null) { +- nbt.put("tag", this.tag.copy()); ++ // Scissors start - Don't save large tags ++ if (!NbtUtility.isTooLarge(this.tag)) { ++ nbt.put("tag", this.tag.copy()); ++ } ++ // Scissors end + } + + return nbt; +@@ -919,6 +931,7 @@ public final class ItemStack { + // Paper end + + public void setTag(@Nullable CompoundTag nbt) { ++ if (NbtUtility.isTooLarge(nbt)) return; // Scissors - Ignore large tags + this.tag = nbt; + this.processEnchantOrder(this.tag); // Paper + if (this.getItem().canBeDepleted()) { +diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +index 89d06253b00604114e543ebbe12a9993ae95dc41..d0af3a9b956b37126811080d65474eacd76bc083 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +@@ -9,6 +9,8 @@ import java.util.Iterator; + import java.util.List; + import java.util.Map; + import javax.annotation.Nullable; ++ ++import me.totalfreedom.scissors.NbtUtility; + import net.minecraft.SharedConstants; + import net.minecraft.Util; + import net.minecraft.core.BlockPos; +@@ -213,6 +215,17 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit + public List transaction = new java.util.ArrayList(); + + public List getContents() { ++ // Scissors start - Account for items inside containers ++ long total = 0; ++ ++ for (ItemStack item : this.items) { ++ total += NbtUtility.getTagSize(item.getOrCreateTag()); ++ } ++ ++ if (total > NbtUtility.MAXIMUM_SIZE) { ++ this.items.clear(); ++ } ++ // Scissors end + return this.items; + } + +diff --git a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java +index 416aa989ebb18a8741cc9d605a1180ab830f6643..af7ed06c083161212784f746290129a17523575a 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java +@@ -1,5 +1,6 @@ + package net.minecraft.world.level.block.entity; + ++import me.totalfreedom.scissors.NbtUtility; + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; + import net.minecraft.core.NonNullList; +@@ -34,6 +35,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { + + @Override + public List getContents() { ++ // Scissors start - Account for items inside containers ++ long total = 0; ++ ++ for (ItemStack item : this.items) { ++ total += NbtUtility.getTagSize(item.getOrCreateTag()); ++ } ++ ++ if (total > NbtUtility.MAXIMUM_SIZE) { ++ this.items.clear(); ++ } ++ // Scissors end + return this.items; + } + +diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +index 9bb542ce3a8c52e1688bb1f66fc916dd23a5fd10..d8386aa10dc1616c4da87bc8078548d13bff5bdf 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +@@ -3,6 +3,8 @@ package net.minecraft.world.level.block.entity; + import java.util.Arrays; + import java.util.Iterator; + import javax.annotation.Nullable; ++ ++import me.totalfreedom.scissors.NbtUtility; + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; + import net.minecraft.core.NonNullList; +@@ -73,6 +75,17 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements + } + + public List getContents() { ++ // Scissors start - Account for items inside containers ++ long total = 0; ++ ++ for (ItemStack item : this.items) { ++ total += NbtUtility.getTagSize(item.getOrCreateTag()); ++ } ++ ++ if (total > NbtUtility.MAXIMUM_SIZE) { ++ this.items.clear(); ++ } ++ // Scissors end + return this.items; + } + +diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java +index 9b1243d96e0694c62fc9e82e9be540bce0d2b3ad..2cf4a854a40aabbfff2f6ee4fb9e36e8d466afd5 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java +@@ -1,5 +1,6 @@ + package net.minecraft.world.level.block.entity; + ++import me.totalfreedom.scissors.NbtUtility; + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; + import net.minecraft.core.NonNullList; +@@ -40,6 +41,17 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement + private int maxStack = MAX_STACK; + + public List getContents() { ++ // Scissors start - Account for items inside containers ++ long total = 0; ++ ++ for (ItemStack item : this.items) { ++ total += NbtUtility.getTagSize(item.getOrCreateTag()); ++ } ++ ++ if (total > NbtUtility.MAXIMUM_SIZE) { ++ this.items.clear(); ++ } ++ // Scissors end + return this.items; + } + +diff --git a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java +index 881379681c39230a00b3a1f11cd87498984396c7..8e1ef455c1b563844c416021c478b2a34b90c418 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java +@@ -1,5 +1,6 @@ + package net.minecraft.world.level.block.entity; + ++import me.totalfreedom.scissors.NbtUtility; + import net.minecraft.core.BlockPos; + import net.minecraft.core.NonNullList; + import net.minecraft.nbt.CompoundTag; +@@ -28,6 +29,17 @@ public class DispenserBlockEntity extends RandomizableContainerBlockEntity { + private int maxStack = MAX_STACK; + + public List getContents() { ++ // Scissors start - Account for items inside containers ++ long total = 0; ++ ++ for (ItemStack item : this.items) { ++ total += NbtUtility.getTagSize(item.getOrCreateTag()); ++ } ++ ++ if (total > NbtUtility.MAXIMUM_SIZE) { ++ this.items.clear(); ++ } ++ // Scissors end + return this.items; + } + +diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +index cdb739df2a285032d25d84f4464f202a7a3fa578..69845474c207220c0146891be90e3232ac8a3547 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java +@@ -6,6 +6,8 @@ import java.util.function.BooleanSupplier; + import java.util.stream.Collectors; + import java.util.stream.IntStream; + import javax.annotation.Nullable; ++ ++import me.totalfreedom.scissors.NbtUtility; + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; + import net.minecraft.core.NonNullList; +@@ -57,6 +59,17 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + private int maxStack = MAX_STACK; + + public List getContents() { ++ // Scissors start - Account for items inside containers ++ long total = 0; ++ ++ for (ItemStack item : this.items) { ++ total += NbtUtility.getTagSize(item.getOrCreateTag()); ++ } ++ ++ if (total > NbtUtility.MAXIMUM_SIZE) { ++ this.items.clear(); ++ } ++ // Scissors end + return this.items; + } + +diff --git a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java +index 1fa22445a4ecc8c08dbcf0cc6bd39dc5003604c4..c37f0f12283f528d16fd0450075eab1974ba5057 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java +@@ -4,6 +4,8 @@ import java.util.Iterator; + import java.util.List; + import java.util.stream.IntStream; + import javax.annotation.Nullable; ++ ++import me.totalfreedom.scissors.NbtUtility; + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; + import net.minecraft.core.NonNullList; +@@ -61,6 +63,17 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl + public boolean opened; + + public List getContents() { ++ // Scissors start - Account for items inside containers ++ long total = 0; ++ ++ for (ItemStack item : this.itemStacks) { ++ total += NbtUtility.getTagSize(item.getOrCreateTag()); ++ } ++ ++ if (total > NbtUtility.MAXIMUM_SIZE) { ++ this.itemStacks.clear(); ++ } ++ // Scissors end + return this.itemStacks; + } + diff --git a/patches/server/0049-Add-configuration-option-to-disable-chat-signatures.patch b/patches/server/0049-Add-configuration-option-to-disable-chat-signatures.patch new file mode 100644 index 0000000..0b8572b --- /dev/null +++ b/patches/server/0049-Add-configuration-option-to-disable-chat-signatures.patch @@ -0,0 +1,105 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Telesphoreo +Date: Mon, 15 Apr 2024 23:01:26 -0500 +Subject: [PATCH] Add configuration option to disable chat signatures + + +diff --git a/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java b/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java +index c87b708c368713a23a10ad97704575ee4df27891..a650bdccc7f8fe77abe2750c9939f5eb0ccfd57b 100644 +--- a/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java ++++ b/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java +@@ -1,5 +1,6 @@ + package net.minecraft.network.chat; + ++import me.totalfreedom.scissors.ScissorsConfig; + import net.minecraft.server.level.ServerPlayer; + + public interface OutgoingChatMessage { +@@ -46,9 +47,20 @@ public interface OutgoingChatMessage { + // Paper end + PlayerChatMessage playerChatMessage = this.message.filter(filterMaskEnabled); + playerChatMessage = unsigned != null ? playerChatMessage.withUnsignedContent(unsigned) : playerChatMessage; // Paper +- if (!playerChatMessage.isFullyFiltered()) { ++ // Sccissors start ++ if (!playerChatMessage.isFullyFiltered() && ScissorsConfig.chatSignaturesEnabled) { + sender.connection.sendPlayerChatMessage(playerChatMessage, params); ++ return; + } ++ sender.connection.sendPlayerChatMessage(new PlayerChatMessage( ++ SignedMessageLink.unsigned(playerChatMessage.sender()), ++ null, ++ SignedMessageBody.unsigned(playerChatMessage.signedContent()), ++ unsigned, ++ playerChatMessage.filterMask(), ++ playerChatMessage.result() ++ ), params); ++ // Scissors end + } + } + } +diff --git a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java +index 0af9ed92824ccf30814eceb6a2c2e5c12661c991..c92374104b4aed2f952b250c5559ab9cc83532da 100644 +--- a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java ++++ b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java +@@ -5,6 +5,8 @@ import java.time.Instant; + import java.util.UUID; + import java.util.function.BooleanSupplier; + import javax.annotation.Nullable; ++ ++import me.totalfreedom.scissors.ScissorsConfig; + import net.minecraft.util.SignatureValidator; + import net.minecraft.util.Signer; + import net.minecraft.world.entity.player.ProfilePublicKey; +@@ -45,7 +47,7 @@ public class SignedMessageChain { + if (!playerChatMessage.verify(signatureValidator)) { + throw new SignedMessageChain.DecodeException(Component.translatable("multiplayer.disconnect.unsigned_chat"), true, org.bukkit.event.player.PlayerKickEvent.Cause.UNSIGNED_CHAT); // Paper - kick event causes + } else { +- if (playerChatMessage.hasExpiredServer(Instant.now())) { ++ if (playerChatMessage.hasExpiredServer(Instant.now()) && ScissorsConfig.chatSignaturesEnabled) { // Scissors + LOGGER.warn("Received expired chat: '{}'. Is the client/server system time unsynchronized?", body.content()); + } + +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index b2971440e73dcce2beee936313568cbb06d32312..88c98ba7673808819b8f85876f22743bc3a4f471 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -1,5 +1,6 @@ + package net.minecraft.server.network; + ++import me.totalfreedom.scissors.ScissorsConfig; + import me.totalfreedom.scissors.event.player.SpectatorTeleportEvent; // Scissors + import com.google.common.collect.Lists; + import com.google.common.primitives.Floats; +@@ -2243,7 +2244,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + + private void handleMessageDecodeFailure(SignedMessageChain.DecodeException exception) { + ServerGamePacketListenerImpl.LOGGER.warn("Failed to update secure chat state for {}: '{}'", this.player.getGameProfile().getName(), exception.getComponent().getString()); +- if (exception.shouldDisconnect()) { ++ if (exception.shouldDisconnect() && ScissorsConfig.chatSignaturesEnabled) { // Scissors - Do not kick when chat signatures are disabled + this.disconnect(exception.getComponent(), exception.kickCause); // Paper - kick event causes + } else { + this.player.sendSystemMessage(exception.getComponent().copy().withStyle(ChatFormatting.RED)); +@@ -2291,6 +2292,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + Optional optional = this.lastSeenMessages.applyUpdate(acknowledgment); + + if (optional.isEmpty()) { ++ if (!ScissorsConfig.chatSignaturesEnabled) return optional; // Scissors + ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); + this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes + } +@@ -2489,6 +2491,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + + synchronized (this.lastSeenMessages) { + if (!this.lastSeenMessages.applyOffset(packet.offset())) { ++ if (!ScissorsConfig.chatSignaturesEnabled) return; // Scissors + ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString()); + this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes + } +@@ -3460,6 +3463,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl + @Override + public void handleChatSessionUpdate(ServerboundChatSessionUpdatePacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); ++ if (!ScissorsConfig.chatSignaturesEnabled) return; // Scissors + RemoteChatSession.Data remotechatsession_a = packet.chatSession(); + ProfilePublicKey.Data profilepublickey_a = this.chatSession != null ? this.chatSession.profilePublicKey().data() : null; + ProfilePublicKey.Data profilepublickey_a1 = remotechatsession_a.profilePublicKey();