From 69fa242c6a67f137ca892f0629b34283dce033d8 Mon Sep 17 00:00:00 2001 From: Toon Schoenmakers Date: Fri, 23 Oct 2020 15:01:44 +0200 Subject: [PATCH] Avoid error bubbling up when item stack is empty in fishing loot This can realistically only happen if there's custom loot active on fishing which can return 0 items. This would disconnect the player who's fishing. --- .../entity/projectile/FishingHook.java.patch | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch index d6a87cac69..6e4f5b9003 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch @@ -22,10 +22,11 @@ public class FishingHook extends Projectile { private static final Logger LOGGER = LogUtils.getLogger(); -@@ -68,6 +74,18 @@ +@@ -67,6 +73,18 @@ + public FishingHook.FishHookState currentState; private final int luck; private final int lureSpeed; - ++ + // CraftBukkit start - Extra variables to enable modification of fishing wait time, values are minecraft defaults + public int minWaitTime = 100; + public int maxWaitTime = 600; @@ -37,10 +38,9 @@ + public boolean rainInfluenced = true; + public boolean skyInfluenced = true; + // CraftBukkit end -+ + private FishingHook(EntityType type, Level world, int luckBonus, int waitTimeReductionTicks) { super(type, world); - this.syncronizedRandom = RandomSource.create(); @@ -75,13 +93,17 @@ this.currentState = FishingHook.FishHookState.FLYING; this.luck = Math.max(0, luckBonus); @@ -188,12 +188,20 @@ this.pullEntity(this.hookedIn); CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) entityhuman, usedItem, this, Collections.emptyList()); this.level().broadcastEntityEvent(this, (byte) 31); -@@ -467,6 +512,15 @@ +@@ -466,15 +511,38 @@ + while (iterator.hasNext()) { ItemStack itemstack1 = (ItemStack) iterator.next(); - ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack1); +- ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack1); ++ // Paper start - new ItemEntity would throw if for whatever reason (mostly shitty datapacks) the itemstack1 turns out to be empty ++ // if the item stack is empty we instead just have our entityitem as null ++ ItemEntity entityitem = null; ++ if (!itemstack1.isEmpty()) { ++ entityitem = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemstack1); ++ } ++ // Paper end + // CraftBukkit start -+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), entityitem.getBukkitEntity(), (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_FISH); ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) entityhuman.getBukkitEntity(), entityitem != null ? entityitem.getBukkitEntity() : null, (FishHook) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_FISH); // Paper - entityitem may be null + playerFishEvent.setExpToDrop(this.random.nextInt(6) + 1); + this.level().getCraftServer().getPluginManager().callEvent(playerFishEvent); + @@ -204,11 +212,17 @@ double d0 = entityhuman.getX() - this.getX(); double d1 = entityhuman.getY() - this.getY(); double d2 = entityhuman.getZ() - this.getZ(); -@@ -474,7 +528,11 @@ + double d3 = 0.1D; - entityitem.setDeltaMovement(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D); - this.level().addFreshEntity(entityitem); +- entityitem.setDeltaMovement(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D); +- this.level().addFreshEntity(entityitem); - entityhuman.level().addFreshEntity(new ExperienceOrb(entityhuman.level(), entityhuman.getX(), entityhuman.getY() + 0.5D, entityhuman.getZ() + 0.5D, this.random.nextInt(6) + 1)); ++ // Paper start - entity item can be null, so we need to check against this ++ if (entityitem != null) { ++ entityitem.setDeltaMovement(d0 * 0.1D, d1 * 0.1D + Math.sqrt(Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2)) * 0.08D, d2 * 0.1D); ++ this.level().addFreshEntity(entityitem); ++ } ++ // Paper end + // CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop() + if (playerFishEvent.getExpToDrop() > 0) { + entityhuman.level().addFreshEntity(new ExperienceOrb(entityhuman.level(), entityhuman.getX(), entityhuman.getY() + 0.5D, entityhuman.getZ() + 0.5D, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.getPlayerOwner(), this)); // Paper @@ -217,7 +231,7 @@ if (itemstack1.is(ItemTags.FISHES)) { entityhuman.awardStat(Stats.FISH_CAUGHT, 1); } -@@ -484,10 +542,27 @@ +@@ -484,10 +552,27 @@ } if (this.onGround()) { @@ -246,7 +260,7 @@ return i; } else { return 0; -@@ -496,7 +571,7 @@ +@@ -496,7 +581,7 @@ @Override public void handleEntityEvent(byte status) { @@ -255,7 +269,7 @@ this.pullEntity(this.hookedIn); } -@@ -520,8 +595,15 @@ +@@ -520,8 +605,15 @@ @Override public void remove(Entity.RemovalReason reason) { @@ -272,7 +286,7 @@ } @Override -@@ -536,7 +618,7 @@ +@@ -536,7 +628,7 @@ } private void updateOwnerInfo(@Nullable FishingHook fishingBobber) { @@ -281,7 +295,7 @@ if (entityhuman != null) { entityhuman.fishing = fishingBobber; -@@ -545,10 +627,10 @@ +@@ -545,10 +637,10 @@ } @Nullable @@ -294,7 +308,7 @@ } @Nullable -@@ -575,7 +657,7 @@ +@@ -575,7 +667,7 @@ int i = packet.getData(); FishingHook.LOGGER.error("Failed to recreate fishing hook on client. {} (id: {}) is not a valid owner.", this.level().getEntity(i), i);