diff options
author | Jake Potrebic <[email protected]> | 2024-04-23 22:43:09 -0700 |
---|---|---|
committer | Jake Potrebic <[email protected]> | 2024-04-23 22:43:09 -0700 |
commit | 1d7d7e92f213694ddf1155d03a7541671683f4cb (patch) | |
tree | 049b15b20e5405669f75f4fa13fd7c54d68a18e3 /removed-patches-1-20-5 | |
parent | 309ebc13fcbae181ec3b3aa0f670ff3e6ada863e (diff) | |
download | Paper-1d7d7e92f213694ddf1155d03a7541671683f4cb.tar.gz Paper-1d7d7e92f213694ddf1155d03a7541671683f4cb.zip |
301
Diffstat (limited to 'removed-patches-1-20-5')
3 files changed, 751 insertions, 0 deletions
diff --git a/removed-patches-1-20-5/0259-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch b/removed-patches-1-20-5/0259-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch new file mode 100644 index 0000000000..f179b48bd7 --- /dev/null +++ b/removed-patches-1-20-5/0259-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch @@ -0,0 +1,397 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Mark Vainomaa <[email protected]> +Date: Wed, 12 Sep 2018 18:53:55 +0300 +Subject: [PATCH] Add API for CanPlaceOn and CanDestroy NBT values + + +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +index 1920cf7ad846f57cd278cb9a72dce03f3d014fbb..7cf1153ae532a9d53ee85b05f77ed74b94cf5fbc 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +@@ -85,6 +85,12 @@ import org.bukkit.persistence.PersistentDataContainer; + import static org.spigotmc.ValidateUtils.*; + // Spigot end + ++// Paper start ++import com.destroystokyo.paper.Namespaced; ++import com.destroystokyo.paper.NamespacedTag; ++import java.util.Collections; ++// Paper end ++ + /** + * Children must include the following: + * +@@ -273,6 +279,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + @Specific(Specific.To.NBT) + static final ItemMetaKey BLOCK_DATA = new ItemMetaKey("BlockStateTag"); + static final ItemMetaKey BUKKIT_CUSTOM_TAG = new ItemMetaKey("PublicBukkitValues"); ++ // Paper start - Add API for CanPlaceOn and CanDestroy NBT values ++ static final ItemMetaKey CAN_DESTROY = new ItemMetaKey("CanDestroy"); ++ static final ItemMetaKey CAN_PLACE_ON = new ItemMetaKey("CanPlaceOn"); ++ // Paper end - Add API for CanPlaceOn and CanDestroy NBT values + + // We store the raw original JSON representation of all text data. See SPIGOT-5063, SPIGOT-5656, SPIGOT-5304 + private String displayName; +@@ -286,6 +296,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + private int hideFlag; + private boolean unbreakable; + private int damage; ++ // Paper start - Add API for CanPlaceOn and CanDestroy NBT values ++ private Set<Namespaced> placeableKeys = Sets.newHashSet(); ++ private Set<Namespaced> destroyableKeys = Sets.newHashSet(); ++ // Paper end - Add API for CanPlaceOn and CanDestroy NBT values + + private static final Set<String> HANDLED_TAGS = Sets.newHashSet(); + private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); +@@ -323,6 +337,15 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + this.hideFlag = meta.hideFlag; + this.unbreakable = meta.unbreakable; + this.damage = meta.damage; ++ // Paper start - Add API for CanPlaceOn and CanDestroy NBT values ++ if (meta.hasPlaceableKeys()) { ++ this.placeableKeys = new java.util.HashSet<>(meta.placeableKeys); ++ } ++ ++ if (meta.hasDestroyableKeys()) { ++ this.destroyableKeys = new java.util.HashSet<>(meta.destroyableKeys); ++ } ++ // Paper end - Add API for CanPlaceOn and CanDestroy NBT values + this.unhandledTags.putAll(meta.unhandledTags); + this.persistentDataContainer.putAll(meta.persistentDataContainer.getRaw()); + +@@ -386,6 +409,31 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + this.persistentDataContainer.put(key, compound.get(key).copy()); + } + } ++ // Paper start - Add API for CanPlaceOn and CanDestroy NBT values ++ if (tag.contains(CAN_DESTROY.NBT)) { ++ ListTag list = tag.getList(CAN_DESTROY.NBT, CraftMagicNumbers.NBT.TAG_STRING); ++ for (int i = 0; i < list.size(); i++) { ++ Namespaced namespaced = this.blockKeyFromString(list.getString(i)); ++ if (namespaced == null) { ++ continue; ++ } ++ ++ this.destroyableKeys.add(namespaced); ++ } ++ } ++ ++ if (tag.contains(CAN_PLACE_ON.NBT)) { ++ ListTag list = tag.getList(CAN_PLACE_ON.NBT, CraftMagicNumbers.NBT.TAG_STRING); ++ for (int i = 0; i < list.size(); i++) { ++ Namespaced namespaced = this.blockKeyFromString(list.getString(i)); ++ if (namespaced == null) { ++ continue; ++ } ++ ++ this.placeableKeys.add(namespaced); ++ } ++ } ++ // Paper end - Add API for CanPlaceOn and CanDestroy NBT values + + Set<String> keys = tag.getAllKeys(); + for (String key : keys) { +@@ -524,6 +572,34 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + this.setDamage(damage); + } + ++ // Paper start - Add API for CanPlaceOn and CanDestroy NBT values ++ Iterable<?> canPlaceOnSerialized = SerializableMeta.getObject(Iterable.class, map, CAN_PLACE_ON.BUKKIT, true); ++ if (canPlaceOnSerialized != null) { ++ for (Object canPlaceOnElement : canPlaceOnSerialized) { ++ String canPlaceOnRaw = (String) canPlaceOnElement; ++ Namespaced value = this.blockKeyFromString(canPlaceOnRaw); ++ if (value == null) { ++ continue; ++ } ++ ++ this.placeableKeys.add(value); ++ } ++ } ++ ++ Iterable<?> canDestroySerialized = SerializableMeta.getObject(Iterable.class, map, CAN_DESTROY.BUKKIT, true); ++ if (canDestroySerialized != null) { ++ for (Object canDestroyElement : canDestroySerialized) { ++ String canDestroyRaw = (String) canDestroyElement; ++ Namespaced value = this.blockKeyFromString(canDestroyRaw); ++ if (value == null) { ++ continue; ++ } ++ ++ this.destroyableKeys.add(value); ++ } ++ } ++ // Paper end - Add API for CanPlaceOn and CanDestroy NBT values ++ + String internal = SerializableMeta.getString(map, "internal", true); + if (internal != null) { + ByteArrayInputStream buf = new ByteArrayInputStream(Base64.getDecoder().decode(internal)); +@@ -652,6 +728,23 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + if (this.hasDamage()) { + itemTag.putInt(CraftMetaItem.DAMAGE.NBT, this.damage); + } ++ // Paper start - Add API for CanPlaceOn and CanDestroy NBT values ++ if (hasPlaceableKeys()) { ++ List<String> items = this.placeableKeys.stream() ++ .map(this::serializeNamespaced) ++ .collect(java.util.stream.Collectors.toList()); ++ ++ itemTag.put(CAN_PLACE_ON.NBT, createNonComponentStringList(items)); ++ } ++ ++ if (hasDestroyableKeys()) { ++ List<String> items = this.destroyableKeys.stream() ++ .map(this::serializeNamespaced) ++ .collect(java.util.stream.Collectors.toList()); ++ ++ itemTag.put(CAN_DESTROY.NBT, createNonComponentStringList(items)); ++ } ++ // Paper end - Add API for CanPlaceOn and CanDestroy NBT values + + for (Map.Entry<String, Tag> e : this.unhandledTags.entrySet()) { + itemTag.put(e.getKey(), e.getValue()); +@@ -668,6 +761,21 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + } + } + ++ // Paper start - Add API for CanPlaceOn and CanDestroy NBT values ++ static ListTag createNonComponentStringList(List<String> list) { ++ if (list == null || list.isEmpty()) { ++ return null; ++ } ++ ++ ListTag tagList = new ListTag(); ++ for (String value : list) { ++ tagList.add(StringTag.valueOf(value)); // Paper - NBTTagString.of(String str) ++ } ++ ++ return tagList; ++ } ++ // Paper end - Add API for CanPlaceOn and CanDestroy NBT values ++ + ListTag createStringList(List<String> list) { + if (list == null) { + return null; +@@ -751,7 +859,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + + @Overridden + boolean isEmpty() { +- return !(this.hasDisplayName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isUnbreakable() || this.hasDamage() || this.hasAttributeModifiers()); ++ return !(this.hasDisplayName() || this.hasLocalizedName() || this.hasEnchants() || (this.lore != null) || this.hasCustomModelData() || this.hasBlockData() || this.hasRepairCost() || !this.unhandledTags.isEmpty() || !this.persistentDataContainer.isEmpty() || this.hideFlag != 0 || this.isUnbreakable() || this.hasDamage() || this.hasAttributeModifiers() || this.hasPlaceableKeys() || this.hasDestroyableKeys()); // Paper - Implement an API for CanPlaceOn and CanDestroy NBT values + } + + // Paper start +@@ -1223,7 +1331,11 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + && (this.hideFlag == that.hideFlag) + && (this.isUnbreakable() == that.isUnbreakable()) + && (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage()) +- && (this.version == that.version); ++ && (this.version == that.version) ++ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values ++ && (this.hasPlaceableKeys() ? that.hasPlaceableKeys() && this.placeableKeys.equals(that.placeableKeys) : !that.hasPlaceableKeys()) ++ && (this.hasDestroyableKeys() ? that.hasDestroyableKeys() && this.destroyableKeys.equals(that.destroyableKeys) : !that.hasDestroyableKeys()); ++ // Paper end + } + + /** +@@ -1258,6 +1370,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + hash = 61 * hash + (this.hasDamage() ? this.damage : 0); + hash = 61 * hash + (this.hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0); + hash = 61 * hash + this.version; ++ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values ++ hash = 61 * hash + (this.hasPlaceableKeys() ? this.placeableKeys.hashCode() : 0); ++ hash = 61 * hash + (this.hasDestroyableKeys() ? this.destroyableKeys.hashCode() : 0); ++ // Paper end + return hash; + } + +@@ -1282,6 +1398,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + clone.unbreakable = this.unbreakable; + clone.damage = this.damage; + clone.version = this.version; ++ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values ++ if (this.placeableKeys != null) { ++ clone.placeableKeys = Sets.newHashSet(this.placeableKeys); ++ } ++ if (this.destroyableKeys != null) { ++ clone.destroyableKeys = Sets.newHashSet(this.destroyableKeys); ++ } ++ // Paper end + return clone; + } catch (CloneNotSupportedException e) { + throw new Error(e); +@@ -1339,6 +1463,23 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + builder.put(CraftMetaItem.DAMAGE.BUKKIT, this.damage); + } + ++ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values ++ if (this.hasPlaceableKeys()) { ++ List<String> cerealPlaceable = this.placeableKeys.stream() ++ .map(this::serializeNamespaced) ++ .collect(java.util.stream.Collectors.toList()); ++ ++ builder.put(CAN_PLACE_ON.BUKKIT, cerealPlaceable); ++ } ++ ++ if (this.hasDestroyableKeys()) { ++ List<String> cerealDestroyable = this.destroyableKeys.stream() ++ .map(this::serializeNamespaced) ++ .collect(java.util.stream.Collectors.toList()); ++ ++ builder.put(CAN_DESTROY.BUKKIT, cerealDestroyable); ++ } ++ // Paper end + final Map<String, Tag> internalTags = new HashMap<String, Tag>(this.unhandledTags); + this.serializeInternal(internalTags); + if (!internalTags.isEmpty()) { +@@ -1516,6 +1657,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + CraftMetaArmorStand.SHOW_ARMS.NBT, + CraftMetaArmorStand.SMALL.NBT, + CraftMetaArmorStand.MARKER.NBT, ++ CAN_DESTROY.NBT, ++ CAN_PLACE_ON.NBT, + // Paper end + CraftMetaCompass.LODESTONE_DIMENSION.NBT, + CraftMetaCompass.LODESTONE_POS.NBT, +@@ -1545,4 +1688,141 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + } + // Paper end + ++ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values ++ @Override ++ @SuppressWarnings("deprecation") ++ public Set<Material> getCanDestroy() { ++ return !hasDestroyableKeys() ? Collections.emptySet() : legacyGetMatsFromKeys(this.destroyableKeys); ++ } ++ ++ @Override ++ @SuppressWarnings("deprecation") ++ public void setCanDestroy(Set<Material> canDestroy) { ++ Preconditions.checkArgument(canDestroy != null, "Cannot replace with null set!"); ++ legacyClearAndReplaceKeys(this.destroyableKeys, canDestroy); ++ } ++ ++ @Override ++ @SuppressWarnings("deprecation") ++ public Set<Material> getCanPlaceOn() { ++ return !hasPlaceableKeys() ? Collections.emptySet() : legacyGetMatsFromKeys(this.placeableKeys); ++ } ++ ++ @Override ++ @SuppressWarnings("deprecation") ++ public void setCanPlaceOn(Set<Material> canPlaceOn) { ++ Preconditions.checkArgument(canPlaceOn != null, "Cannot replace with null set!"); ++ legacyClearAndReplaceKeys(this.placeableKeys, canPlaceOn); ++ } ++ ++ @Override ++ public Set<Namespaced> getDestroyableKeys() { ++ return !hasDestroyableKeys() ? Collections.emptySet() : Sets.newHashSet(this.destroyableKeys); ++ } ++ ++ @Override ++ public void setDestroyableKeys(Collection<Namespaced> canDestroy) { ++ Preconditions.checkArgument(canDestroy != null, "Cannot replace with null collection!"); ++ Preconditions.checkArgument(ofAcceptableType(canDestroy), "Can only use NamespacedKey or NamespacedTag objects!"); ++ this.destroyableKeys.clear(); ++ this.destroyableKeys.addAll(canDestroy); ++ } ++ ++ @Override ++ public Set<Namespaced> getPlaceableKeys() { ++ return !hasPlaceableKeys() ? Collections.emptySet() : Sets.newHashSet(this.placeableKeys); ++ } ++ ++ @Override ++ public void setPlaceableKeys(Collection<Namespaced> canPlaceOn) { ++ Preconditions.checkArgument(canPlaceOn != null, "Cannot replace with null collection!"); ++ Preconditions.checkArgument(ofAcceptableType(canPlaceOn), "Can only use NamespacedKey or NamespacedTag objects!"); ++ this.placeableKeys.clear(); ++ this.placeableKeys.addAll(canPlaceOn); ++ } ++ ++ @Override ++ public boolean hasPlaceableKeys() { ++ return this.placeableKeys != null && !this.placeableKeys.isEmpty(); ++ } ++ ++ @Override ++ public boolean hasDestroyableKeys() { ++ return this.destroyableKeys != null && !this.destroyableKeys.isEmpty(); ++ } ++ ++ @Deprecated ++ private void legacyClearAndReplaceKeys(Collection<Namespaced> toUpdate, Collection<Material> beingSet) { ++ if (beingSet.stream().anyMatch(Material::isLegacy)) { ++ throw new IllegalArgumentException("Set must not contain any legacy materials!"); ++ } ++ ++ toUpdate.clear(); ++ toUpdate.addAll(beingSet.stream().map(Material::getKey).collect(java.util.stream.Collectors.toSet())); ++ } ++ ++ @Deprecated ++ private Set<Material> legacyGetMatsFromKeys(Collection<Namespaced> names) { ++ Set<Material> mats = Sets.newHashSet(); ++ for (Namespaced key : names) { ++ if (!(key instanceof org.bukkit.NamespacedKey)) { ++ continue; ++ } ++ ++ Material material = Material.matchMaterial(key.toString(), false); ++ if (material != null) { ++ mats.add(material); ++ } ++ } ++ ++ return mats; ++ } ++ ++ private @Nullable Namespaced blockKeyFromString(String raw) { ++ boolean isTag = !raw.isEmpty() && raw.codePointAt(0) == '#'; ++ com.mojang.datafixers.util.Either<net.minecraft.commands.arguments.blocks.BlockStateParser.BlockResult, net.minecraft.commands.arguments.blocks.BlockStateParser.TagResult> result; ++ try { ++ result = net.minecraft.commands.arguments.blocks.BlockStateParser.parseForTesting(net.minecraft.core.registries.BuiltInRegistries.BLOCK.asLookup(), raw, false); ++ } catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) { ++ return null; ++ } ++ ++ net.minecraft.resources.ResourceLocation key = null; ++ if (isTag && result.right().isPresent() && result.right().get().tag() instanceof net.minecraft.core.HolderSet.Named<net.minecraft.world.level.block.Block> namedSet) { ++ key = namedSet.key().location(); ++ } else if (result.left().isPresent()) { ++ key = net.minecraft.core.registries.BuiltInRegistries.BLOCK.getKey(result.left().get().blockState().getBlock()); ++ } ++ ++ if (key == null) { ++ return null; ++ } ++ ++ try { ++ if (isTag) { ++ return new NamespacedTag(key.getNamespace(), key.getPath()); ++ ++ } ++ return CraftNamespacedKey.fromMinecraft(key); ++ } catch (IllegalArgumentException ignored) { ++ return null; ++ } ++ } ++ ++ private @Nonnull String serializeNamespaced(Namespaced resource) { ++ return resource.toString(); ++ } ++ ++ // not a fan of this ++ private boolean ofAcceptableType(Collection<Namespaced> namespacedResources) { ++ ++ for (Namespaced resource : namespacedResources) { ++ if (!(resource instanceof org.bukkit.NamespacedKey || resource instanceof com.destroystokyo.paper.NamespacedTag)) { ++ return false; ++ } ++ } ++ ++ return true; ++ } ++ // Paper end + } diff --git a/removed-patches-1-20-5/0284-Handle-Large-Packets-disconnecting-client.patch b/removed-patches-1-20-5/0284-Handle-Large-Packets-disconnecting-client.patch new file mode 100644 index 0000000000..de32fb8f39 --- /dev/null +++ b/removed-patches-1-20-5/0284-Handle-Large-Packets-disconnecting-client.patch @@ -0,0 +1,134 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar <[email protected]> +Date: Tue, 27 Nov 2018 21:18:06 -0500 +Subject: [PATCH] Handle Large Packets disconnecting client + +If a players inventory is too big to send in a single packet, +split the inventory set into multiple packets instead. + +diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java +index 02b3f5c67b47a098f7fe15ddba0df6cb586a9ae5..157f055df00faf3a7870df8109e84fdb12f55964 100644 +--- a/src/main/java/net/minecraft/network/Connection.java ++++ b/src/main/java/net/minecraft/network/Connection.java +@@ -156,6 +156,22 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> { + } + + public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) { ++ // Paper start - Handle large packets disconnecting client ++ if (throwable instanceof io.netty.handler.codec.EncoderException && throwable.getCause() instanceof PacketEncoder.PacketTooLargeException packetTooLargeException) { ++ final Packet<?> packet = packetTooLargeException.getPacket(); ++ final io.netty.util.Attribute<ConnectionProtocol.CodecData<?>> codecDataAttribute = channelhandlercontext.channel().attr(packetTooLargeException.codecKey); ++ if (packet.packetTooLarge(this)) { ++ ProtocolSwapHandler.swapProtocolIfNeeded(codecDataAttribute, packet); ++ return; ++ } else if (packet.isSkippable()) { ++ Connection.LOGGER.debug("Skipping packet due to errors", throwable.getCause()); ++ ProtocolSwapHandler.swapProtocolIfNeeded(codecDataAttribute, packet); ++ return; ++ } else { ++ throwable = throwable.getCause(); ++ } ++ } ++ // Paper end - Handle large packets disconnecting client + if (throwable instanceof SkipPacketException) { + Connection.LOGGER.debug("Skipping packet due to errors", throwable.getCause()); + } else { +diff --git a/src/main/java/net/minecraft/network/PacketEncoder.java b/src/main/java/net/minecraft/network/PacketEncoder.java +index 0d80fcee1831af59b06c4d00dc713bd4dad947fc..061eada043325142d33a0cec02e9e484d14a7fca 100644 +--- a/src/main/java/net/minecraft/network/PacketEncoder.java ++++ b/src/main/java/net/minecraft/network/PacketEncoder.java +@@ -41,7 +41,7 @@ public class PacketEncoder extends MessageToByteEncoder<Packet<?>> { + int j = friendlyByteBuf.writerIndex(); + packet.write(friendlyByteBuf); + int k = friendlyByteBuf.writerIndex() - j; +- if (k > 8388608) { ++ if (false && k > 8388608) { // Paper - Handle large packets disconnecting client; disable + throw new IllegalArgumentException("Packet too big (is " + k + ", should be less than 8388608): " + packet); + } + +@@ -54,9 +54,34 @@ public class PacketEncoder extends MessageToByteEncoder<Packet<?>> { + + throw var13; + } finally { ++ // Paper start - Handle large packets disconnecting client ++ int packetLength = friendlyByteBuf.readableBytes(); ++ if (packetLength > MAX_PACKET_SIZE) { ++ throw new PacketTooLargeException(packet, this.codecKey, packetLength); ++ } ++ // Paper end - Handle large packets disconnecting client + ProtocolSwapHandler.swapProtocolIfNeeded(attribute, packet); + } + } + } + } ++ ++ // Paper start ++ private static int MAX_PACKET_SIZE = 8388608; ++ ++ public static class PacketTooLargeException extends RuntimeException { ++ private final Packet<?> packet; ++ public final AttributeKey<ConnectionProtocol.CodecData<?>> codecKey; ++ ++ PacketTooLargeException(Packet<?> packet, AttributeKey<ConnectionProtocol.CodecData<?>> codecKey, int packetLength) { ++ super("PacketTooLarge - " + packet.getClass().getSimpleName() + " is " + packetLength + ". Max is " + MAX_PACKET_SIZE); ++ this.packet = packet; ++ this.codecKey = codecKey; ++ } ++ ++ public Packet<?> getPacket() { ++ return this.packet; ++ } ++ } ++ // Paper end + } +diff --git a/src/main/java/net/minecraft/network/protocol/Packet.java b/src/main/java/net/minecraft/network/protocol/Packet.java +index 700418bb0c9fbed3f161611881b1e222248ca4eb..cc658a61065d5c0021a4b88fa58b40211b94f8ec 100644 +--- a/src/main/java/net/minecraft/network/protocol/Packet.java ++++ b/src/main/java/net/minecraft/network/protocol/Packet.java +@@ -10,6 +10,12 @@ public interface Packet<T extends PacketListener> { + + void handle(T listener); + ++ // Paper start ++ default boolean packetTooLarge(net.minecraft.network.Connection manager) { ++ return false; ++ } ++ // Paper end ++ + default boolean isSkippable() { + return false; + } +diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java +index 6206d4d71dfe95b454b22f5b3055623638e145c0..6765175c98d52e5cbc191e88e0d545a05606dfd4 100644 +--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java ++++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java +@@ -31,6 +31,16 @@ public class ClientboundContainerSetContentPacket implements Packet<ClientGamePa + this.carriedItem = buf.readItem(); + } + ++ // Paper start ++ @Override ++ public boolean packetTooLarge(net.minecraft.network.Connection manager) { ++ for (int i = 0 ; i < this.items.size() ; i++) { ++ manager.send(new ClientboundContainerSetSlotPacket(this.containerId, this.stateId, i, this.items.get(i))); ++ } ++ return true; ++ } ++ // Paper end ++ + @Override + public void write(FriendlyByteBuf buf) { + buf.writeByte(this.containerId); +diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java +index dc657312889da4fc3222a6981223a01406b77deb..a44a82d2d5ed4d675dc1a184d5b6b935fda575dd 100644 +--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java ++++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java +@@ -49,7 +49,7 @@ public class ClientboundLevelChunkPacketData { + throw new RuntimeException("Can't read heightmap in packet for [" + x + ", " + z + "]"); + } else { + int i = buf.readVarInt(); +- if (i > 2097152) { ++ if (i > 2097152) { // Paper - diff on change - if this changes, update PacketEncoder + throw new RuntimeException("Chunk Packet trying to allocate too much memory on read."); + } else { + this.buffer = new byte[i]; diff --git a/removed-patches-1-20-5/0310-Configurable-Keep-Spawn-Loaded-range-per-world.patch b/removed-patches-1-20-5/0310-Configurable-Keep-Spawn-Loaded-range-per-world.patch new file mode 100644 index 0000000000..4d9cba2dd0 --- /dev/null +++ b/removed-patches-1-20-5/0310-Configurable-Keep-Spawn-Loaded-range-per-world.patch @@ -0,0 +1,220 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar <[email protected]> +Date: Sat, 13 Sep 2014 23:14:43 -0400 +Subject: [PATCH] Configurable Keep Spawn Loaded range per world + +This lets you disable it for some worlds and lower it for others. + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 176378ddbf21d758694e8e624cc6c555c78e0fab..6342b7a3c4ccad528f026384da64e973e630f030 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -768,30 +768,33 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa + + // CraftBukkit start + public void prepareLevels(ChunkProgressListener worldloadlistener, ServerLevel worldserver) { ++ ServerChunkCache chunkproviderserver = worldserver.getChunkSource(); // Paper - Configurable Keep Spawn Loaded range per world + // WorldServer worldserver = this.overworld(); + this.forceTicks = true; + // CraftBukkit end ++ if (worldserver.getWorld().getKeepSpawnInMemory()) { // Paper - Configurable Keep Spawn Loaded range per world + + MinecraftServer.LOGGER.info("Preparing start region for dimension {}", worldserver.dimension().location()); + BlockPos blockposition = worldserver.getSharedSpawnPos(); + + worldloadlistener.updateSpawnPos(new ChunkPos(blockposition)); +- ServerChunkCache chunkproviderserver = worldserver.getChunkSource(); ++ //ChunkProviderServer chunkproviderserver = worldserver.getChunkProvider(); // Paper - Configurable Keep Spawn Loaded range per world; move up + + this.nextTickTimeNanos = Util.getNanos(); +- // CraftBukkit start +- if (worldserver.getWorld().getKeepSpawnInMemory()) { +- chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(blockposition), 11, Unit.INSTANCE); ++ // Paper start - Configurable Keep Spawn Loaded range per world ++ int radiusBlocks = worldserver.paperConfig().spawn.keepSpawnLoadedRange * 16; ++ int radiusChunks = radiusBlocks / 16 + ((radiusBlocks & 15) != 0 ? 1 : 0); ++ int totalChunks = ((radiusChunks) * 2 + 1); ++ totalChunks *= totalChunks; ++ worldloadlistener.setChunkRadius(radiusBlocks / 16); + +- while (chunkproviderserver.getTickingGenerated() != 441) { +- // this.nextTickTimeNanos = SystemUtils.getNanos() + MinecraftServer.PREPARE_LEVELS_DEFAULT_DELAY_NANOS; +- this.executeModerately(); +- } +- } ++ worldserver.addTicketsForSpawn(radiusBlocks, blockposition); ++ // Paper end - Configurable Keep Spawn Loaded range per world + + // this.nextTickTimeNanos = SystemUtils.getNanos() + MinecraftServer.PREPARE_LEVELS_DEFAULT_DELAY_NANOS; + this.executeModerately(); + // Iterator iterator = this.levels.values().iterator(); ++ } // Paper - Configurable Keep Spawn Loaded range per world + + if (true) { + ServerLevel worldserver1 = worldserver; +@@ -814,7 +817,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa + // this.nextTickTimeNanos = SystemUtils.getNanos() + MinecraftServer.PREPARE_LEVELS_DEFAULT_DELAY_NANOS; + this.executeModerately(); + // CraftBukkit end +- worldloadlistener.stop(); ++ if (worldserver.getWorld().getKeepSpawnInMemory()) worldloadlistener.stop(); // Paper - Configurable Keep Spawn Loaded range per world + // CraftBukkit start + // this.updateMobSpawningFlags(); + worldserver.setSpawnSettings(this.isSpawningMonsters(), this.isSpawningAnimals()); +diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java +index 57f129651778d6c20c695bf7b3a8b4d40c402a20..20de3be232ccc7ec7bbc3c6aee9acf66fd396af1 100644 +--- a/src/main/java/net/minecraft/server/level/ServerLevel.java ++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +@@ -1640,12 +1640,84 @@ public class ServerLevel extends Level implements WorldGenLevel { + return ((MapIndex) this.getServer().overworld().getDataStorage().computeIfAbsent(MapIndex.factory(), "idcounts")).getFreeAuxValueForMap(); + } + ++ // Paper start - Configurable Keep Spawn Loaded range per world ++ public void addTicketsForSpawn(int radiusInBlocks, BlockPos spawn) { ++ // In order to respect vanilla behavior, which is ensuring everything but the spawn border can tick, we add tickets ++ // with level 31 for the non-border spawn chunks ++ ServerChunkCache chunkproviderserver = this.getChunkSource(); ++ int tickRadius = radiusInBlocks - 16; ++ ++ // add ticking chunks ++ for (int x = -tickRadius; x <= tickRadius; x += 16) { ++ for (int z = -tickRadius; z <= tickRadius; z += 16) { ++ // radius of 2 will have the current chunk be level 31 ++ chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, z)), 2, Unit.INSTANCE); ++ } ++ } ++ ++ // add border chunks ++ ++ // add border along x axis (including corner chunks) ++ for (int x = -radiusInBlocks; x <= radiusInBlocks; x += 16) { ++ // top ++ chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, radiusInBlocks)), 1, Unit.INSTANCE); // level 32 ++ // bottom ++ chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, -radiusInBlocks)), 1, Unit.INSTANCE); // level 32 ++ } ++ ++ // add border along z axis (excluding corner chunks) ++ for (int z = -radiusInBlocks + 16; z < radiusInBlocks; z += 16) { ++ // right ++ chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(spawn.offset(radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 ++ // left ++ chunkproviderserver.addRegionTicket(TicketType.START, new ChunkPos(spawn.offset(-radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 ++ } ++ } ++ public void removeTicketsForSpawn(int radiusInBlocks, BlockPos spawn) { ++ // In order to respect vanilla behavior, which is ensuring everything but the spawn border can tick, we added tickets ++ // with level 31 for the non-border spawn chunks ++ ServerChunkCache chunkproviderserver = this.getChunkSource(); ++ int tickRadius = radiusInBlocks - 16; ++ ++ // remove ticking chunks ++ for (int x = -tickRadius; x <= tickRadius; x += 16) { ++ for (int z = -tickRadius; z <= tickRadius; z += 16) { ++ // radius of 2 will have the current chunk be level 31 ++ chunkproviderserver.removeRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, z)), 2, Unit.INSTANCE); ++ } ++ } ++ ++ // remove border chunks ++ ++ // remove border along x axis (including corner chunks) ++ for (int x = -radiusInBlocks; x <= radiusInBlocks; x += 16) { ++ // top ++ chunkproviderserver.removeRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, radiusInBlocks)), 1, Unit.INSTANCE); // level 32 ++ // bottom ++ chunkproviderserver.removeRegionTicket(TicketType.START, new ChunkPos(spawn.offset(x, 0, -radiusInBlocks)), 1, Unit.INSTANCE); // level 32 ++ } ++ ++ // remove border along z axis (excluding corner chunks) ++ for (int z = -radiusInBlocks + 16; z < radiusInBlocks; z += 16) { ++ // right ++ chunkproviderserver.removeRegionTicket(TicketType.START, new ChunkPos(spawn.offset(radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 ++ // left ++ chunkproviderserver.removeRegionTicket(TicketType.START, new ChunkPos(spawn.offset(-radiusInBlocks, 0, z)), 1, Unit.INSTANCE); // level 32 ++ } ++ } ++ // Paper end - Configurable Keep Spawn Loaded range per world ++ + public void setDefaultSpawnPos(BlockPos pos, float angle) { +- ChunkPos chunkcoordintpair = new ChunkPos(new BlockPos(this.levelData.getXSpawn(), 0, this.levelData.getZSpawn())); ++ // Paper start - Configurable Keep Spawn Loaded range per world ++ BlockPos prevSpawn = this.getSharedSpawnPos(); ++ //ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(this.worldData.a(), 0, this.worldData.c())); + + this.levelData.setSpawn(pos, angle); +- this.getChunkSource().removeRegionTicket(TicketType.START, chunkcoordintpair, 11, Unit.INSTANCE); +- this.getChunkSource().addRegionTicket(TicketType.START, new ChunkPos(pos), 11, Unit.INSTANCE); ++ if (this.keepSpawnInMemory) { ++ // if this keepSpawnInMemory is false a plugin has already removed our tickets, do not re-add ++ this.removeTicketsForSpawn(this.paperConfig().spawn.keepSpawnLoadedRange * 16, prevSpawn); ++ this.addTicketsForSpawn(this.paperConfig().spawn.keepSpawnLoadedRange * 16, pos); ++ } + this.getServer().getPlayerList().broadcastAll(new ClientboundSetDefaultSpawnPositionPacket(pos, angle)); + } + +diff --git a/src/main/java/net/minecraft/server/level/progress/ChunkProgressListener.java b/src/main/java/net/minecraft/server/level/progress/ChunkProgressListener.java +index 1b565b2809c2d367e21971c5154f35c9763995e6..4792eaa30464f4c4ca7f2d6cf20f734beed81f23 100644 +--- a/src/main/java/net/minecraft/server/level/progress/ChunkProgressListener.java ++++ b/src/main/java/net/minecraft/server/level/progress/ChunkProgressListener.java +@@ -12,4 +12,6 @@ public interface ChunkProgressListener { + void start(); + + void stop(); ++ ++ void setChunkRadius(int radius); // Paper - Configurable Keep Spawn Loaded range per world + } +diff --git a/src/main/java/net/minecraft/server/level/progress/LoggerChunkProgressListener.java b/src/main/java/net/minecraft/server/level/progress/LoggerChunkProgressListener.java +index c9667df492e5681bf933a7f8878b0fdb324afed3..09d0c702132d4cc52ce36712aed11d30efe89f54 100644 +--- a/src/main/java/net/minecraft/server/level/progress/LoggerChunkProgressListener.java ++++ b/src/main/java/net/minecraft/server/level/progress/LoggerChunkProgressListener.java +@@ -11,12 +11,19 @@ import org.slf4j.Logger; + + public class LoggerChunkProgressListener implements ChunkProgressListener { + private static final Logger LOGGER = LogUtils.getLogger(); +- private final int maxCount; ++ private int maxCount; // Paper - remove final + private int count; + private long startTime; + private long nextTickTime = Long.MAX_VALUE; + + public LoggerChunkProgressListener(int radius) { ++ // Paper start - Configurable Keep Spawn Loaded range per world ++ this.setChunkRadius(radius); // Move to method ++ } ++ ++ @Override ++ public void setChunkRadius(int radius) { ++ // Paper end - Configurable Keep Spawn Loaded range per world + int i = radius * 2 + 1; + this.maxCount = i * i; + } +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 4001a8c13ceed6037174bb81fd06d9758fa0336c..b39721208f8b66c1478e89553a592070cf90fb97 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -1411,15 +1411,21 @@ public class CraftWorld extends CraftRegionAccessor implements World { + + @Override + public void setKeepSpawnInMemory(boolean keepLoaded) { ++ // Paper start - Configurable spawn radius ++ if (keepLoaded == this.world.keepSpawnInMemory) { ++ // do nothing, nothing has changed ++ return; ++ } + this.world.keepSpawnInMemory = keepLoaded; + // Grab the worlds spawn chunk + BlockPos chunkcoordinates = this.world.getSharedSpawnPos(); + if (keepLoaded) { +- this.world.getChunkSource().addRegionTicket(TicketType.START, new ChunkPos(chunkcoordinates), 11, Unit.INSTANCE); ++ this.world.addTicketsForSpawn(this.world.paperConfig().spawn.keepSpawnLoadedRange * 16, chunkcoordinates); + } else { +- // TODO: doesn't work well if spawn changed.... +- this.world.getChunkSource().removeRegionTicket(TicketType.START, new ChunkPos(chunkcoordinates), 11, Unit.INSTANCE); ++ // TODO: doesn't work well if spawn changed.... // Paper - resolved ++ this.world.removeTicketsForSpawn(this.world.paperConfig().spawn.keepSpawnLoadedRange * 16, chunkcoordinates); + } ++ // Paper end + } + + @Override |