From 54b0c41c20431f53b22c015aa7dcc9b5cc4a69d5 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sat, 4 Dec 2021 19:39:52 -0800 Subject: [PATCH] further mitigate possible NPEs --- ...erTradeEvent-and-PlayerPurchaseEvent.patch | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/patches/server/0555-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch b/patches/server/0555-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch index 80e0d5adbf..a32b1130cf 100644 --- a/patches/server/0555-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch +++ b/patches/server/0555-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add PlayerTradeEvent and PlayerPurchaseEvent Co-authored-by: Alexander diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java -index 742ffe531bb8f3a9ca34dea99b044123d90cfff9..ce0364b98204b64d43751fed260dcc1d9fe60649 100644 +index 742ffe531bb8f3a9ca34dea99b044123d90cfff9..bd283f71cb05ffbe1fed39afb41ae54dc52ec297 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -138,11 +138,24 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa @@ -15,11 +15,11 @@ index 742ffe531bb8f3a9ca34dea99b044123d90cfff9..ce0364b98204b64d43751fed260dcc1d + // Paper start + @Override -+ public void processTrade(MerchantOffer recipe, io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent -+ if (event.willIncreaseTradeUses()) { ++ public void processTrade(MerchantOffer recipe, @Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent ++ if (event == null || event.willIncreaseTradeUses()) { + recipe.increaseUses(); + } -+ if (event.isRewardingExp()) { ++ if (event == null || event.isRewardingExp()) { + this.rewardTradeXp(recipe); + } + this.notifyTrade(recipe); @@ -168,10 +168,10 @@ index 589527215b10aa848a079b964e748c8c2e6137a1..a6e036165ce1a387195cf3db190a42c5 return itemstack; diff --git a/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java b/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java -index 74b28315197b81f80334ae6023113904e4fac4c3..1fb70ac171788d099e220b83421958976281f127 100644 +index 74b28315197b81f80334ae6023113904e4fac4c3..7acf5ab9339e0134819aab5f270e99e927cc7a62 100644 --- a/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java +++ b/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java -@@ -47,13 +47,35 @@ public class MerchantResultSlot extends Slot { +@@ -47,13 +47,32 @@ public class MerchantResultSlot extends Slot { @Override public void onTake(Player player, ItemStack stack) { @@ -180,11 +180,11 @@ index 74b28315197b81f80334ae6023113904e4fac4c3..1fb70ac171788d099e220b8342195897 MerchantOffer merchantOffer = this.slots.getActiveOffer(); + // Paper start + io.papermc.paper.event.player.PlayerPurchaseEvent event = null; -+ if (merchantOffer != null) { -+ if (this.merchant instanceof net.minecraft.world.entity.npc.AbstractVillager && this.merchant.getTradingPlayer().getBukkitEntity() instanceof org.bukkit.entity.Player) { -+ event = new io.papermc.paper.event.player.PlayerTradeEvent((org.bukkit.entity.Player) this.merchant.getTradingPlayer().getBukkitEntity(), (org.bukkit.entity.AbstractVillager) ((net.minecraft.world.entity.npc.AbstractVillager) this.merchant).getBukkitEntity(), merchantOffer.asBukkit(), true, true); -+ } else if (this.merchant instanceof org.bukkit.craftbukkit.inventory.CraftMerchantCustom.MinecraftMerchant && this.merchant.getTradingPlayer().getBukkitEntity() instanceof org.bukkit.entity.Player) { -+ event = new io.papermc.paper.event.player.PlayerPurchaseEvent((org.bukkit.entity.Player) this.merchant.getTradingPlayer().getBukkitEntity(), merchantOffer.asBukkit(), false, true); ++ if (merchantOffer != null && player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) { ++ if (this.merchant instanceof net.minecraft.world.entity.npc.AbstractVillager abstractVillager) { ++ event = new io.papermc.paper.event.player.PlayerTradeEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.AbstractVillager) abstractVillager.getBukkitEntity(), merchantOffer.asBukkit(), true, true); ++ } else if (this.merchant instanceof org.bukkit.craftbukkit.inventory.CraftMerchantCustom.MinecraftMerchant) { ++ event = new io.papermc.paper.event.player.PlayerPurchaseEvent(serverPlayer.getBukkitEntity(), merchantOffer.asBukkit(), false, true); + } + if (event != null) { + if (!event.callEvent()) { @@ -193,12 +193,9 @@ index 74b28315197b81f80334ae6023113904e4fac4c3..1fb70ac171788d099e220b8342195897 + return; + } + merchantOffer = org.bukkit.craftbukkit.inventory.CraftMerchantRecipe.fromBukkit(event.getTrade()).toMinecraft(); -+ } else { -+ // TODO: Check this, I don't see how this would be hit and the logic below should be fired, warn for missing cases? -+ return; + } -+ this.checkTakeAchievements(stack); + } ++ this.checkTakeAchievements(stack); + // Paper end if (merchantOffer != null) { ItemStack itemStack = this.slots.getItem(0); @@ -210,19 +207,19 @@ index 74b28315197b81f80334ae6023113904e4fac4c3..1fb70ac171788d099e220b8342195897 this.slots.setItem(0, itemStack); this.slots.setItem(1, itemStack2); diff --git a/src/main/java/net/minecraft/world/item/trading/Merchant.java b/src/main/java/net/minecraft/world/item/trading/Merchant.java -index d41f44ed2e497ba3373d170c08488b49e88334c4..5eb54fb8e668e3ae053e33358e5b19e87330a02d 100644 +index d41f44ed2e497ba3373d170c08488b49e88334c4..d3a99ba6f3085ad12b67ddc94cc4ab393ec7ecbe 100644 --- a/src/main/java/net/minecraft/world/item/trading/Merchant.java +++ b/src/main/java/net/minecraft/world/item/trading/Merchant.java @@ -20,6 +20,7 @@ public interface Merchant { void overrideOffers(MerchantOffers offers); -+ default void processTrade(MerchantOffer merchantRecipe, io.papermc.paper.event.player.PlayerPurchaseEvent event) { this.notifyTrade(merchantRecipe); } // Paper ++ default void processTrade(MerchantOffer merchantRecipe, @Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { this.notifyTrade(merchantRecipe); } // Paper void notifyTrade(MerchantOffer offer); void notifyTradeUpdated(ItemStack stack); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java -index 552851cff3678d605428866999951fefd4375d7a..1854d933c90c3ec4b39bdb5c3c177890d9865a1c 100644 +index 552851cff3678d605428866999951fefd4375d7a..9f6ce6c4cba1e6fe83fbac129da990748681ce94 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java @@ -79,10 +79,25 @@ public class CraftMerchantCustom extends CraftMerchant { @@ -231,13 +228,13 @@ index 552851cff3678d605428866999951fefd4375d7a..1854d933c90c3ec4b39bdb5c3c177890 + // Paper start + @Override -+ public void processTrade(MerchantOffer merchantRecipe, io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent ++ public void processTrade(MerchantOffer merchantRecipe, @javax.annotation.Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { // The MerchantRecipe passed in here is the one set by the PlayerPurchaseEvent + /** Based on {@link net.minecraft.world.entity.npc.AbstractVillager#processTrade(MerchantOffer, io.papermc.paper.event.player.PlayerPurchaseEvent)} */ + if (getTradingPlayer() instanceof net.minecraft.server.level.ServerPlayer) { -+ if (event.willIncreaseTradeUses()) { ++ if (event == null || event.willIncreaseTradeUses()) { + merchantRecipe.increaseUses(); + } -+ if (event.isRewardingExp()) { ++ if (event == null || event.isRewardingExp()) { + this.tradingWorld.addFreshEntity(new net.minecraft.world.entity.ExperienceOrb(tradingWorld, tradingPlayer.getX(), tradingPlayer.getY(), tradingPlayer.getZ(), merchantRecipe.getXp(), org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, this.tradingPlayer, null)); + } + }