From 1863ac217f94f910d83624db067b5e513dbd90dd Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Fri, 23 Feb 2024 14:37:33 +0100 Subject: [PATCH] Updated Upstream (Bukkit/CraftBukkit/Spigot) (#10277) Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 9a80d38c SPIGOT-336, SPIGOT-3366, SPIGOT-5768, SPIGOT-6409, SPIGOT-6861, PR-722: Add EntityRemoveEvent 258086d9 SPIGOT-7417, PR-967: Add Sign#getTargetSide and Sign#getAllowedEditor ffaba051 SPIGOT-7584: Add missing Tag.ITEMS_NON_FLAMMABLE_WOOD CraftBukkit Changes: 98b6c1ac7 SPIGOT-7589 Fix NullPointerException when bans expire a2736ddb0 SPIGOT-336, SPIGOT-3366, SPIGOT-5768, SPIGOT-6409, SPIGOT-6861, PR-1008: Add EntityRemoveEvent 5bf12cb89 SPIGOT-7565: Throw a more descriptive error message when a developer tries to spawn an entity from a CraftBukkit class 76d95fe7e SPIGOT-7417, PR-1343: Add Sign#getTargetSide and Sign#getAllowedEditor Spigot Changes: e9ec5485 Rebuild patches f1b62e0c Rebuild patches --- .../api/Add-Sign-getInteractableSideFor.patch | 5 +-- patches/api/Added-missing-vanilla-tags.patch | 23 ---------- patches/api/Adventure.patch | 2 +- ...Entity-AddTo-RemoveFrom-World-Events.patch | 29 ++++++++++++ .../Ability-to-apply-mending-to-XP-API.patch | 2 +- .../Add-API-for-item-entity-health.patch | 2 +- .../Add-PlayerUseUnknownEntityEvent.patch | 5 +-- ...onfigurable-entity-despawn-distances.patch | 2 +- .../server/Add-drops-to-shear-events.patch | 2 +- .../Add-exception-reporting-event.patch | 2 +- patches/server/Adventure.patch | 4 +- ...urable-Non-Player-Arrow-Despawn-Rate.patch | 2 +- ...ck-and-tnt-entities-at-the-specified.patch | 6 +-- .../Duplicate-UUID-Resolve-Option.patch | 6 +-- patches/server/EnderDragon-Events.patch | 10 ++--- .../server/EntityPickupItemEvent-fixes.patch | 2 +- .../server/Expand-LingeringPotion-API.patch | 2 +- .../server/Expand-PlayerItemMendEvent.patch | 2 +- ...PI-for-Reason-Source-Triggering-play.patch | 2 +- ...-entity-death-event-for-ender-dragon.patch | 2 +- .../server/Fix-a-bunch-of-vanilla-bugs.patch | 4 +- .../server/Fix-potions-splash-events.patch | 4 +- patches/server/Fix-sand-duping.patch | 2 +- .../server/Fix-villager-boat-exploit.patch | 2 +- ...and-additions-to-the-SpawnReason-API.patch | 10 ++--- ...Folia-scheduler-and-owned-region-API.patch | 12 ++--- patches/server/Improve-death-events.patch | 4 +- .../server/Improve-tag-parser-handling.patch | 45 +++++++++++++++++++ ...-maximum-exp-value-when-merging-orbs.patch | 2 +- .../server/Player-affects-spawning-API.patch | 2 +- .../server/PlayerAttemptPickupItemEvent.patch | 4 +- ...PlayerPickupItemEvent-setFlyAtPlayer.patch | 2 +- ...vent-block-entity-and-entity-crashes.patch | 2 +- patches/server/Rewrite-chunk-system.patch | 17 +++---- patches/server/Setup-Gradle-project.patch | 7 +++ patches/server/Test-changes.patch | 2 +- .../Toggle-for-removing-existing-dragon.patch | 2 +- work/Bukkit | 2 +- work/CraftBukkit | 2 +- work/Spigot | 2 +- 40 files changed, 150 insertions(+), 91 deletions(-) delete mode 100644 patches/api/Added-missing-vanilla-tags.patch diff --git a/patches/api/Add-Sign-getInteractableSideFor.patch b/patches/api/Add-Sign-getInteractableSideFor.patch index 12c6fd314d..bf9fd5e4db 100644 --- a/patches/api/Add-Sign-getInteractableSideFor.patch +++ b/patches/api/Add-Sign-getInteractableSideFor.patch @@ -10,9 +10,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/org/bukkit/block/Sign.java @@ -0,0 +0,0 @@ public interface Sign extends TileState, Colorable { */ - @NotNull - public SignSide getSide(@NotNull Side side); -+ + @Nullable + public Player getAllowedEditor(); + // Paper start - get side for player + /** + * Compute the side facing the specified entity. diff --git a/patches/api/Added-missing-vanilla-tags.patch b/patches/api/Added-missing-vanilla-tags.patch deleted file mode 100644 index 9431f51974..0000000000 --- a/patches/api/Added-missing-vanilla-tags.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sun, 3 Jan 2021 20:03:40 -0800 -Subject: [PATCH] Added missing vanilla tags - - -diff --git a/src/main/java/org/bukkit/Tag.java b/src/main/java/org/bukkit/Tag.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/org/bukkit/Tag.java -+++ b/src/main/java/org/bukkit/Tag.java -@@ -0,0 +0,0 @@ public interface Tag extends Keyed { - * Vanilla item tag representing all chest boat items. - */ - Tag ITEMS_CHEST_BOATS = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("chest_boats"), Material.class); -+ // Paper start -+ /** -+ * Vanilla item tag representing all non-flammable wood items. -+ */ -+ Tag ITEMS_NON_FLAMMABLE_WOOD = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("non_flammable_wood"), Material.class); -+ // Paper end - /** - * Vanilla item tag representing all fish items. - */ diff --git a/patches/api/Adventure.patch b/patches/api/Adventure.patch index 670a4a0274..56c19c2a88 100644 --- a/patches/api/Adventure.patch +++ b/patches/api/Adventure.patch @@ -1598,7 +1598,7 @@ diff --git a/src/main/java/org/bukkit/block/Sign.java b/src/main/java/org/bukkit index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/block/Sign.java +++ b/src/main/java/org/bukkit/block/Sign.java -@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull; +@@ -0,0 +0,0 @@ import org.jetbrains.annotations.Nullable; * Represents a captured state of either a SignPost or a WallSign. */ public interface Sign extends TileState, Colorable { diff --git a/patches/api/Entity-AddTo-RemoveFrom-World-Events.patch b/patches/api/Entity-AddTo-RemoveFrom-World-Events.patch index b8d176441e..4b61acb2f1 100644 --- a/patches/api/Entity-AddTo-RemoveFrom-World-Events.patch +++ b/patches/api/Entity-AddTo-RemoveFrom-World-Events.patch @@ -104,3 +104,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return HANDLER_LIST; + } +} +diff --git a/src/main/java/org/bukkit/event/entity/EntityRemoveEvent.java b/src/main/java/org/bukkit/event/entity/EntityRemoveEvent.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/event/entity/EntityRemoveEvent.java ++++ b/src/main/java/org/bukkit/event/entity/EntityRemoveEvent.java +@@ -0,0 +0,0 @@ + package org.bukkit.event.entity; + ++import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent; + import org.bukkit.entity.Entity; + import org.bukkit.event.HandlerList; + import org.jetbrains.annotations.ApiStatus; +@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull; + * This event should only be used for monitoring. The result + * of modifying the entity during or after this event is unspecified. + * This event is not called for a {@link org.bukkit.entity.Player}. ++ * @deprecated use {@link EntityRemoveFromWorldEvent} instead + */ +-@ApiStatus.Experimental ++@Deprecated(forRemoval = true) + public class EntityRemoveEvent extends EntityEvent { + + private static final HandlerList handlers = new HandlerList(); +@@ -0,0 +0,0 @@ public class EntityRemoveEvent extends EntityEvent { + * When the chunk an entity is in gets unloaded. + */ + UNLOAD, ++ DISCARD + } + } diff --git a/patches/server/Ability-to-apply-mending-to-XP-API.patch b/patches/server/Ability-to-apply-mending-to-XP-API.patch index 3d55295d2d..37a9248a1a 100644 --- a/patches/server/Ability-to-apply-mending-to-XP-API.patch +++ b/patches/server/Ability-to-apply-mending-to-XP-API.patch @@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + int i = Math.min(orb.xpToDurability(amount), itemstack.getDamageValue()); + org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, stackEntry.getKey(), i); + i = event.getRepairAmount(); -+ orb.discard(); ++ orb.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); + if (!event.isCancelled()) { + amount -= orb.durabilityToXp(i); + itemstack.setDamageValue(itemstack.getDamageValue() - i); diff --git a/patches/server/Add-API-for-item-entity-health.patch b/patches/server/Add-API-for-item-entity-health.patch index a7f459fcf3..8ebe6a3593 100644 --- a/patches/server/Add-API-for-item-entity-health.patch +++ b/patches/server/Add-API-for-item-entity-health.patch @@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public void setHealth(int health) { + if (health <= 0) { + this.getHandle().getItem().onDestroyed(this.getHandle()); -+ this.getHandle().discard(); ++ this.getHandle().discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PLUGIN); + } else { + this.getHandle().health = health; + } diff --git a/patches/server/Add-PlayerUseUnknownEntityEvent.patch b/patches/server/Add-PlayerUseUnknownEntityEvent.patch index 9f076a43c9..1e8af013c8 100644 --- a/patches/server/Add-PlayerUseUnknownEntityEvent.patch +++ b/patches/server/Add-PlayerUseUnknownEntityEvent.patch @@ -63,10 +63,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -0,0 +0,0 @@ public class CraftEventFactory { - Bukkit.getPluginManager().callEvent(event); - return event; + + Bukkit.getPluginManager().callEvent(new EntityRemoveEvent(entity.getBukkitEntity(), cause)); } -+ + // Paper start - PlayerUseUnknownEntityEvent + public static void callPlayerUseUnknownEntityEvent(net.minecraft.world.entity.player.Player player, net.minecraft.network.protocol.game.ServerboundInteractPacket packet, InteractionHand hand, @Nullable net.minecraft.world.phys.Vec3 vector) { + new com.destroystokyo.paper.event.player.PlayerUseUnknownEntityEvent( diff --git a/patches/server/Add-configurable-entity-despawn-distances.patch b/patches/server/Add-configurable-entity-despawn-distances.patch index ad508a570e..e9bd8df5e8 100644 --- a/patches/server/Add-configurable-entity-despawn-distances.patch +++ b/patches/server/Add-configurable-entity-despawn-distances.patch @@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 int j = i * i; if (d0 > (double) j && this.removeWhenFarAway(d0)) { - this.discard(); + this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } - int k = this.getType().getCategory().getNoDespawnDistance(); diff --git a/patches/server/Add-drops-to-shear-events.patch b/patches/server/Add-drops-to-shear-events.patch index fdcea1765f..6fc6a6c45d 100644 --- a/patches/server/Add-drops-to-shear-events.patch +++ b/patches/server/Add-drops-to-shear-events.patch @@ -93,7 +93,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (!this.level().isClientSide()) { Cow entitycow = (Cow) EntityType.COW.create(this.level()); @@ -0,0 +0,0 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder= ((this instanceof ThrownTrident) ? this.level().spigotConfig.tridentDespawnRate : this.level().spigotConfig.arrowDespawnRate)) { // Spigot + if (this.life >= (pickup == Pickup.CREATIVE_ONLY ? this.level().paperConfig().entities.spawning.creativeArrowDespawnRate.value() : (pickup == Pickup.DISALLOWED ? this.level().paperConfig().entities.spawning.nonPlayerArrowDespawnRate.value() : ((this instanceof ThrownTrident) ? this.level().spigotConfig.tridentDespawnRate : this.level().spigotConfig.arrowDespawnRate)))) { // Spigot // Paper - Configurable non-player arrow despawn rate; TODO: Extract this to init? - this.discard(); + this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } diff --git a/patches/server/Drop-falling-block-and-tnt-entities-at-the-specified.patch b/patches/server/Drop-falling-block-and-tnt-entities-at-the-specified.patch index 56c1288b27..1e5cc99259 100644 --- a/patches/server/Drop-falling-block-and-tnt-entities-at-the-specified.patch +++ b/patches/server/Drop-falling-block-and-tnt-entities-at-the-specified.patch @@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.spawnAtLocation(block); + } + -+ this.discard(); ++ this.discard(EntityRemoveEvent.Cause.OUT_OF_WORLD); + return; + } + // Paper end - Configurable falling blocks height nerf @@ -36,7 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.move(MoverType.SELF, this.getDeltaMovement()); + // Paper start - Configurable TNT height nerf + if (this.level().paperConfig().fixes.tntEntityHeightNerf.test(v -> this.getY() > v)) { -+ this.discard(); ++ this.discard(EntityRemoveEvent.Cause.OUT_OF_WORLD); + return; + } + // Paper end - Configurable TNT height nerf @@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.fuse > 0) { + // Paper start - Configurable TNT height nerf + if (this.level().paperConfig().fixes.tntEntityHeightNerf.test(v -> this.getY() > v)) { -+ this.discard(); ++ this.discard(EntityRemoveEvent.Cause.OUT_OF_WORLD); + return; + } + // Paper end - Configurable TNT height nerf diff --git a/patches/server/Duplicate-UUID-Resolve-Option.patch b/patches/server/Duplicate-UUID-Resolve-Option.patch index d1136adc18..3d1e7352b6 100644 --- a/patches/server/Duplicate-UUID-Resolve-Option.patch +++ b/patches/server/Duplicate-UUID-Resolve-Option.patch @@ -37,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider - entity.discard(); + entity.discard(null); // CraftBukkit - add Bukkit remove cause needsRemoval = true; } + checkDupeUUID(world, entity); // Paper - duplicate uuid resolving @@ -67,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + && Objects.equals(other.getEncodeId(), entity.getEncodeId()) + && entity.getBukkitEntity().getLocation().distance(other.getBukkitEntity().getLocation()) < level.paperConfig().entities.spawning.duplicateUuid.safeRegenDeleteRange + ) { -+ entity.discard(); ++ entity.discard(null); + return true; + } + if (!other.isRemoved()) { @@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + break; + } + case DELETE: { -+ entity.discard(); ++ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); + return true; + } + default: diff --git a/patches/server/EnderDragon-Events.patch b/patches/server/EnderDragon-Events.patch index 489b85c188..42fbf03a57 100644 --- a/patches/server/EnderDragon-Events.patch +++ b/patches/server/EnderDragon-Events.patch @@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 dragonFireball.moveTo(o, p, q, 0.0F, 0.0F); + if (new com.destroystokyo.paper.event.entity.EnderDragonShootFireballEvent((org.bukkit.entity.EnderDragon) dragon.getBukkitEntity(), (org.bukkit.entity.DragonFireball) dragonFireball.getBukkitEntity()).callEvent()) // Paper - EnderDragon Events this.dragon.level().addFreshEntity(dragonFireball); -+ else dragonFireball.discard(); // Paper - EnderDragon Events ++ else dragonFireball.discard(null); // Paper - EnderDragon Events this.fireballCharge = 0; if (this.currentPath != null) { while(!this.currentPath.isDone()) { @@ -44,10 +44,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -+ if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) areaEffectCloud.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events ++ if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) entityareaeffectcloud.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events this.level().levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1); - this.level().addFreshEntity(areaEffectCloud); -+ } else areaEffectCloud.discard(); // Paper - EnderDragon Events - this.discard(); + this.level().addFreshEntity(entityareaeffectcloud); ++ } else entityareaeffectcloud.discard(null); // Paper - EnderDragon Events + this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } diff --git a/patches/server/EntityPickupItemEvent-fixes.patch b/patches/server/EntityPickupItemEvent-fixes.patch index 582b58e1ce..8357452796 100644 --- a/patches/server/EntityPickupItemEvent-fixes.patch +++ b/patches/server/EntityPickupItemEvent-fixes.patch @@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end - EntityPickupItemEvent fixes piglin.take(drop, drop.getItem().getCount()); itemstack = drop.getItem(); - drop.discard(); + drop.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause } else if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, drop, drop.getItem().getCount() - 1, false).isCancelled()) { + piglin.onItemPickup(drop); // Paper - EntityPickupItemEvent fixes; moved from Piglin#pickUpItem - call prior to item entity modification piglin.take(drop, 1); diff --git a/patches/server/Expand-LingeringPotion-API.patch b/patches/server/Expand-LingeringPotion-API.patch index 575da86bd0..60895d9965 100644 --- a/patches/server/Expand-LingeringPotion-API.patch +++ b/patches/server/Expand-LingeringPotion-API.patch @@ -16,4 +16,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (!(event.isCancelled() || entityareaeffectcloud.isRemoved() || (!event.allowsEmptyCreation() && (noEffects && entityareaeffectcloud.effects.isEmpty() && entityareaeffectcloud.getPotion().getEffects().isEmpty())))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling this.level().addFreshEntity(entityareaeffectcloud); } else { - entityareaeffectcloud.discard(); + entityareaeffectcloud.discard(null); // CraftBukkit - add Bukkit remove cause diff --git a/patches/server/Expand-PlayerItemMendEvent.patch b/patches/server/Expand-PlayerItemMendEvent.patch index ae1c525eb9..775dd2275f 100644 --- a/patches/server/Expand-PlayerItemMendEvent.patch +++ b/patches/server/Expand-PlayerItemMendEvent.patch @@ -43,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, stackEntry.getKey(), i); + org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, stackEntry.getKey(), i, orb::durabilityToXp); // Paper - Expand PlayerItemMendEvent i = event.getRepairAmount(); - orb.discard(); + orb.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); if (!event.isCancelled()) { - amount -= orb.durabilityToXp(i); + amount -= event.getDurabilityToXpOperation().applyAsInt(i); // Paper - Expand PlayerItemMendEvent diff --git a/patches/server/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch b/patches/server/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch index 88bba48421..b8d5838c23 100644 --- a/patches/server/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch +++ b/patches/server/ExperienceOrbs-API-for-Reason-Source-Triggering-play.patch @@ -269,7 +269,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - ExperienceOrb.award((ServerLevel) this.level(), this.position(), i); + ExperienceOrb.award((ServerLevel) this.level(), this.position(), i, org.bukkit.entity.ExperienceOrb.SpawnReason.EXP_BOTTLE, this.getOwner(), this); // Paper - this.discard(); + this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java diff --git a/patches/server/Fire-entity-death-event-for-ender-dragon.patch b/patches/server/Fire-entity-death-event-for-ender-dragon.patch index 90c3ad407d..852e793fd2 100644 --- a/patches/server/Fire-entity-death-event-for-ender-dragon.patch +++ b/patches/server/Fire-entity-death-event-for-ender-dragon.patch @@ -21,6 +21,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - Fire entity death event + - this.remove(Entity.RemovalReason.KILLED); + this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause this.gameEvent(GameEvent.ENTITY_DIE); if (this.dragonFight != null) { diff --git a/patches/server/Fix-a-bunch-of-vanilla-bugs.patch b/patches/server/Fix-a-bunch-of-vanilla-bugs.patch index f879fa02e8..0babf43faf 100644 --- a/patches/server/Fix-a-bunch-of-vanilla-bugs.patch +++ b/patches/server/Fix-a-bunch-of-vanilla-bugs.patch @@ -180,11 +180,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 Player player = entity.getBukkitEntity(); PlayerLoginEvent event = new PlayerLoginEvent(player, loginlistener.connection.hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.channel.remoteAddress()).getAddress()); -- if (this.getBans().isBanned(gameprofile) && !this.getBans().get(gameprofile).hasExpired()) { +- if (this.bans.isBanned(gameprofile)) { - UserBanListEntry gameprofilebanentry = (UserBanListEntry) this.bans.get(gameprofile); + // Paper start - Fix MC-158900 + UserBanListEntry gameprofilebanentry; -+ if (getBans().isBanned(gameprofile) && (gameprofilebanentry = getBans().get(gameprofile)) != null) { ++ if (this.bans.isBanned(gameprofile) && (gameprofilebanentry = this.bans.get(gameprofile)) != null) { + // Paper end - Fix MC-158900 ichatmutablecomponent = Component.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason()); diff --git a/patches/server/Fix-potions-splash-events.patch b/patches/server/Fix-potions-splash-events.patch index 5249eb34b5..51b6728d57 100644 --- a/patches/server/Fix-potions-splash-events.patch +++ b/patches/server/Fix-potions-splash-events.patch @@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.level().levelEvent(i, this.blockPosition(), PotionUtils.getColor(itemstack)); + } // Paper - Fix potions splash events - this.discard(); + this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } } @@ -146,7 +146,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (!(event.isCancelled() || entityareaeffectcloud.isRemoved() || (noEffects && entityareaeffectcloud.effects.isEmpty() && entityareaeffectcloud.getPotion().getEffects().isEmpty()))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling this.level().addFreshEntity(entityareaeffectcloud); } else { - entityareaeffectcloud.discard(); + entityareaeffectcloud.discard(null); // CraftBukkit - add Bukkit remove cause } // CraftBukkit end + return !event.isCancelled(); // Paper - Fix potions splash events diff --git a/patches/server/Fix-sand-duping.patch b/patches/server/Fix-sand-duping.patch index 94491dcf48..c912504211 100644 --- a/patches/server/Fix-sand-duping.patch +++ b/patches/server/Fix-sand-duping.patch @@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end - fix sand duping if (this.blockState.isAir()) { - this.discard(); + this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else { @@ -0,0 +0,0 @@ public class FallingBlockEntity extends Entity { } diff --git a/patches/server/Fix-villager-boat-exploit.patch b/patches/server/Fix-villager-boat-exploit.patch index 7029eb21ae..948e84af6f 100644 --- a/patches/server/Fix-villager-boat-exploit.patch +++ b/patches/server/Fix-villager-boat-exploit.patch @@ -20,6 +20,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + // Paper end - Fix villager boat exploit - entity1.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER); + entity1.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, EntityRemoveEvent.Cause.PLAYER_QUIT); // CraftBukkit - add Bukkit remove cause }); } diff --git a/patches/server/Fixes-and-additions-to-the-SpawnReason-API.patch b/patches/server/Fixes-and-additions-to-the-SpawnReason-API.patch index 821ef5fcee..c87efa95aa 100644 --- a/patches/server/Fixes-and-additions-to-the-SpawnReason-API.patch +++ b/patches/server/Fixes-and-additions-to-the-SpawnReason-API.patch @@ -26,12 +26,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java @@ -0,0 +0,0 @@ public class DragonFireball extends AbstractHurtingProjectile { - if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) areaEffectCloud.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events + if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) entityareaeffectcloud.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events this.level().levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1); -- this.level().addFreshEntity(areaEffectCloud); -+ this.level().addFreshEntity(areaEffectCloud, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EXPLOSION); // Paper - use correct spawn reason - } else areaEffectCloud.discard(); // Paper - EnderDragon Events - this.discard(); +- this.level().addFreshEntity(entityareaeffectcloud); ++ this.level().addFreshEntity(entityareaeffectcloud, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EXPLOSION); // Paper - use correct spawn reason + } else entityareaeffectcloud.discard(null); // Paper - EnderDragon Events + this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } diff --git a/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java b/src/main/java/net/minecraft/world/level/block/FrogspawnBlock.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 diff --git a/patches/server/Folia-scheduler-and-owned-region-API.patch b/patches/server/Folia-scheduler-and-owned-region-API.patch index 3bcfd65597..82c9c81d6d 100644 --- a/patches/server/Folia-scheduler-and-owned-region-API.patch +++ b/patches/server/Folia-scheduler-and-owned-region-API.patch @@ -1214,19 +1214,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public CommandSender getBukkitSender(CommandSourceStack wrapper) { return this.getBukkitEntity(); @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S - - @Override - public final void setRemoved(Entity.RemovalReason reason) { + public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { + CraftEventFactory.callEntityRemoveEvent(this, cause); + // CraftBukkit end + final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers if (this.removalReason == null) { - this.removalReason = reason; + this.removalReason = entity_removalreason; } @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.getPassengers().forEach(Entity::stopRiding); - this.levelCallback.onRemove(reason); + this.levelCallback.onRemove(entity_removalreason); + // Paper start - Folia schedulers -+ if (!(this instanceof ServerPlayer) && reason != RemovalReason.CHANGED_DIMENSION && !alreadyRemoved) { ++ if (!(this instanceof ServerPlayer) && entity_removalreason != RemovalReason.CHANGED_DIMENSION && !alreadyRemoved) { + // Players need to be special cased, because they are regularly removed from the world + this.retireScheduler(); + } diff --git a/patches/server/Improve-death-events.patch b/patches/server/Improve-death-events.patch index 8e1d9be85b..95f0b8562c 100644 --- a/patches/server/Improve-death-events.patch +++ b/patches/server/Improve-death-events.patch @@ -367,7 +367,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - this.brokenByPlayer(source); + org.bukkit.event.entity.EntityDeathEvent event = this.brokenByPlayer(source); // Paper this.showBreakingParticles(); -- this.discard(); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event +- this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event + if (!event.isCancelled()) this.kill(false); // Paper - we still need to kill to follow vanilla logic (emit the game event etc...) } @@ -431,7 +431,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, this.drops); // CraftBukkit - call event // Paper - make cancellable + if (event.isCancelled()) return; // Paper - make cancellable + } // Paper - this.remove(Entity.RemovalReason.KILLED); + this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause this.gameEvent(GameEvent.ENTITY_DIE); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java diff --git a/patches/server/Improve-tag-parser-handling.patch b/patches/server/Improve-tag-parser-handling.patch index 3b8988ef75..b86a852b95 100644 --- a/patches/server/Improve-tag-parser-handling.patch +++ b/patches/server/Improve-tag-parser-handling.patch @@ -122,6 +122,51 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } } +diff --git a/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java b/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java ++++ b/src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java +@@ -0,0 +0,0 @@ public class TranslatableContents implements ComponentContents { + + @Override + public Optional visit(FormattedText.ContentConsumer visitor) { ++ // Paper start ++ try { ++ return this.visit(new TranslatableContentConsumer<>(visitor)); ++ } catch (IllegalArgumentException var5) { ++ return Optional.empty(); ++ } ++ } ++ private Optional visit(TranslatableContentConsumer visitor) { ++ // Paper end + this.decompose(); + + for(FormattedText formattedText : this.decomposedParts) { +@@ -0,0 +0,0 @@ public class TranslatableContents implements ComponentContents { + + return Optional.empty(); + } ++ // Paper start ++ private static final class TranslatableContentConsumer implements FormattedText.ContentConsumer { ++ private final FormattedText.ContentConsumer visitor; ++ private int visited; ++ ++ private TranslatableContentConsumer(FormattedText.ContentConsumer visitor) { ++ this.visitor = visitor; ++ } ++ ++ @Override ++ public Optional accept(final String asString) { ++ if (visited++ > 32) { ++ throw new IllegalArgumentException("Too long"); ++ } ++ return this.visitor.accept(asString); ++ } ++ } ++ // Paper end + + @Override + public MutableComponent resolve(@Nullable CommandSourceStack source, @Nullable Entity sender, int depth) throws CommandSyntaxException { diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundCommandSuggestionPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundCommandSuggestionPacket.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ServerboundCommandSuggestionPacket.java diff --git a/patches/server/Option-for-maximum-exp-value-when-merging-orbs.patch b/patches/server/Option-for-maximum-exp-value-when-merging-orbs.patch index e47d59976b..090130c8b9 100644 --- a/patches/server/Option-for-maximum-exp-value-when-merging-orbs.patch +++ b/patches/server/Option-for-maximum-exp-value-when-merging-orbs.patch @@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + xp.value = maxValue; + } else { xp.value += loopItem.value; - loopItem.discard(); + loopItem.discard(null); // Add Bukkit remove cause + } // Paper end - Maximum exp value when merging } } diff --git a/patches/server/Player-affects-spawning-API.patch b/patches/server/Player-affects-spawning-API.patch index 9bca4718ff..3e8f00ef82 100644 --- a/patches/server/Player-affects-spawning-API.patch +++ b/patches/server/Player-affects-spawning-API.patch @@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements Targeting { if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { - this.discard(); + this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { - Player entityhuman = this.level().getNearestPlayer(this, -1.0D); + Player entityhuman = this.level().findNearbyPlayer(this, -1.0D, EntitySelector.PLAYER_AFFECTS_SPAWNING); // Paper - Affects Spawning API diff --git a/patches/server/PlayerAttemptPickupItemEvent.patch b/patches/server/PlayerAttemptPickupItemEvent.patch index 477ca45b54..76cafe7d03 100644 --- a/patches/server/PlayerAttemptPickupItemEvent.patch +++ b/patches/server/PlayerAttemptPickupItemEvent.patch @@ -8,8 +8,8 @@ diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -0,0 +0,0 @@ import org.bukkit.entity.Player; - import org.bukkit.event.entity.EntityPickupItemEvent; +@@ -0,0 +0,0 @@ import org.bukkit.event.entity.EntityPickupItemEvent; + import org.bukkit.event.entity.EntityRemoveEvent; import org.bukkit.event.player.PlayerPickupItemEvent; // CraftBukkit end +import org.bukkit.event.player.PlayerAttemptPickupItemEvent; // Paper diff --git a/patches/server/PlayerPickupItemEvent-setFlyAtPlayer.patch b/patches/server/PlayerPickupItemEvent-setFlyAtPlayer.patch index 6888157f2e..9d79ac980f 100644 --- a/patches/server/PlayerPickupItemEvent-setFlyAtPlayer.patch +++ b/patches/server/PlayerPickupItemEvent-setFlyAtPlayer.patch @@ -38,4 +38,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (flyAtPlayer) // Paper - PlayerPickupItemEvent player.take(this, i); if (itemstack.isEmpty()) { - this.discard(); + this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause diff --git a/patches/server/Prevent-block-entity-and-entity-crashes.patch b/patches/server/Prevent-block-entity-and-entity-crashes.patch index 8695c85b87..ca9144fe45 100644 --- a/patches/server/Prevent-block-entity-and-entity-crashes.patch +++ b/patches/server/Prevent-block-entity-and-entity-crashes.patch @@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper start - Prevent block entity and entity crashes + final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level().getWorld().getName(), entity.getX(), entity.getY(), entity.getZ()); + MinecraftServer.LOGGER.error(msg, throwable); -+ entity.discard(); ++ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); + // Paper end - Prevent block entity and entity crashes } } diff --git a/patches/server/Rewrite-chunk-system.patch b/patches/server/Rewrite-chunk-system.patch index 2789e64499..98a24e6af3 100644 --- a/patches/server/Rewrite-chunk-system.patch +++ b/patches/server/Rewrite-chunk-system.patch @@ -14926,6 +14926,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import java.util.Iterator; +import java.util.List; +import java.util.function.Predicate; ++import org.bukkit.event.entity.EntityRemoveEvent; + +public final class ChunkEntitySlices { + @@ -15021,12 +15022,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + continue; + } + if (entity.shouldBeSaved()) { -+ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK); ++ entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); + if (entity.isVehicle()) { + // we cannot assume that these entities are contained within this chunk, because entities can + // desync - so we need to remove them all + for (final Entity passenger : entity.getIndirectPassengers()) { -+ passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK); ++ passenger.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK, EntityRemoveEvent.Cause.UNLOAD); + } + } + } @@ -19480,7 +19481,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S @Override - public final void setRemoved(Entity.RemovalReason reason) { + public final void setRemoved(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { + // Paper start - rewrite chunk system + io.papermc.paper.util.TickThread.ensureTickThread(this, "Cannot remove entity off-main"); + if (!((ServerLevel)this.level).getEntityLookup().canRemoveEntity(this)) { @@ -19488,18 +19489,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return; + } + // Paper end - rewrite chunk system + CraftEventFactory.callEntityRemoveEvent(this, cause); + // CraftBukkit end final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers - if (this.removalReason == null) { - this.removalReason = reason; @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.stopRiding(); } - this.getPassengers().forEach(Entity::stopRiding); -+ if (reason != RemovalReason.UNLOADED_TO_CHUNK) this.getPassengers().forEach(Entity::stopRiding); // Paper - chunk system - don't adjust passenger state when unloading, it's just not safe (and messes with our logic in entity chunk unload) - this.levelCallback.onRemove(reason); ++ if (entity_removalreason != RemovalReason.UNLOADED_TO_CHUNK) this.getPassengers().forEach(Entity::stopRiding); // Paper - chunk system - don't adjust passenger state when unloading, it's just not safe (and messes with our logic in entity chunk unload) + this.levelCallback.onRemove(entity_removalreason); // Paper start - Folia schedulers - if (!(this instanceof ServerPlayer) && reason != RemovalReason.CHANGED_DIMENSION && !alreadyRemoved) { + if (!(this instanceof ServerPlayer) && entity_removalreason != RemovalReason.CHANGED_DIMENSION && !alreadyRemoved) { @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S @Override diff --git a/patches/server/Setup-Gradle-project.patch b/patches/server/Setup-Gradle-project.patch index 9421a57b44..f07ccb5d76 100644 --- a/patches/server/Setup-Gradle-project.patch +++ b/patches/server/Setup-Gradle-project.patch @@ -58,6 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") + testImplementation("org.hamcrest:hamcrest:2.2") + testImplementation("org.mockito:mockito-core:5.5.0") ++ testImplementation("org.ow2.asm:asm-tree:9.5") +} + +val craftbukkitPackageVersion = "1_20_R3" // Paper @@ -474,6 +475,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - 5.5.0 - test - +- +- org.ow2.asm +- asm-tree +- 9.5 +- test +- - - - diff --git a/patches/server/Test-changes.patch b/patches/server/Test-changes.patch index 305b3e8ec0..a46db529d5 100644 --- a/patches/server/Test-changes.patch +++ b/patches/server/Test-changes.patch @@ -9,9 +9,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -0,0 +0,0 @@ dependencies { - testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") testImplementation("org.hamcrest:hamcrest:2.2") testImplementation("org.mockito:mockito-core:5.5.0") + testImplementation("org.ow2.asm:asm-tree:9.5") + testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") // Paper - CartesianTest } diff --git a/patches/server/Toggle-for-removing-existing-dragon.patch b/patches/server/Toggle-for-removing-existing-dragon.patch index ebe4ea5bd2..78b891bb9b 100644 --- a/patches/server/Toggle-for-removing-existing-dragon.patch +++ b/patches/server/Toggle-for-removing-existing-dragon.patch @@ -15,5 +15,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - if (!flag) { + if (!flag && this.level.paperConfig().entities.behavior.shouldRemoveDragon) { // Paper - Toggle for removing existing dragon EndDragonFight.LOGGER.info("But we didn't have a portal, let's remove it."); - entityenderdragon.discard(); + entityenderdragon.discard(null); // CraftBukkit - add Bukkit remove cause this.dragonUUID = null; diff --git a/work/Bukkit b/work/Bukkit index 58ce1b0f15..9a80d38c00 160000 --- a/work/Bukkit +++ b/work/Bukkit @@ -1 +1 @@ -Subproject commit 58ce1b0f157c419bab3c256659a7e632f91aeb25 +Subproject commit 9a80d38c002509a4849c5e5f735dca9f9b5731e4 diff --git a/work/CraftBukkit b/work/CraftBukkit index 38fd4bd503..98b6c1ac7d 160000 --- a/work/CraftBukkit +++ b/work/CraftBukkit @@ -1 +1 @@ -Subproject commit 38fd4bd5034e9adcc0a3122e43eb8d0273d1bc51 +Subproject commit 98b6c1ac7d4698ded83d96217861b071e519b300 diff --git a/work/Spigot b/work/Spigot index c198da22a8..e9ec54852f 160000 --- a/work/Spigot +++ b/work/Spigot @@ -1 +1 @@ -Subproject commit c198da22a814a0ba9c3128c3a9946286e0839b5a +Subproject commit e9ec54852f825ba470576cd1b5a33b0d76091fbe