diff options
author | Jake Potrebic <[email protected]> | 2021-12-04 20:14:41 -0800 |
---|---|---|
committer | GitHub <[email protected]> | 2021-12-04 20:14:41 -0800 |
commit | 1a83e90c23424e301949b5a525d1bdd4a041b868 (patch) | |
tree | c2a0047daf246a01544a880582e853ccefaec6e0 | |
parent | 005d7b6c758560aefb2b5ecca5aa56a19dc08bc6 (diff) | |
download | Paper-1a83e90c23424e301949b5a525d1bdd4a041b868.tar.gz Paper-1a83e90c23424e301949b5a525d1bdd4a041b868.zip |
Fix possible NPEs with trade events (#7026)
4 files changed, 34 insertions, 55 deletions
diff --git a/patches/server/0401-Async-command-map-building.patch b/patches/server/0401-Async-command-map-building.patch index 96c3da6fb3..a9dc9bf09e 100644 --- a/patches/server/0401-Async-command-map-building.patch +++ b/patches/server/0401-Async-command-map-building.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Async command map building diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 780f46c8fdbaafaca6babfa34ebd97f420d0d612..07c4d909324c8aad3a8c5d27811e2c28fe7a91f3 100644 +index 780f46c8fdbaafaca6babfa34ebd97f420d0d612..1140325637868d60b80394016d936759b1edded1 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java @@ -29,6 +29,7 @@ import net.minecraft.network.chat.MutableComponent; @@ -16,14 +16,12 @@ index 780f46c8fdbaafaca6babfa34ebd97f420d0d612..07c4d909324c8aad3a8c5d27811e2c28 import net.minecraft.server.commands.AdvancementCommands; import net.minecraft.server.commands.AttributeCommand; import net.minecraft.server.commands.BanIpCommands; -@@ -335,6 +336,14 @@ public class Commands { +@@ -335,6 +336,12 @@ public class Commands { if ( org.spigotmc.SpigotConfig.tabComplete < 0 ) return; // Spigot // CraftBukkit start // Register Vanilla commands into builtRoot as before + // Paper start - Async command map building -+ java.util.concurrent.ForkJoinPool.commonPool().execute(() -> { -+ sendAsync(player); -+ }); ++ net.minecraft.server.MCUtil.scheduleAsyncTask(() -> this.sendAsync(player)); + } + + private void sendAsync(ServerPlayer player) { @@ -31,7 +29,7 @@ index 780f46c8fdbaafaca6babfa34ebd97f420d0d612..07c4d909324c8aad3a8c5d27811e2c28 Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues RootCommandNode vanillaRoot = new RootCommandNode(); -@@ -352,7 +361,14 @@ public class Commands { +@@ -352,7 +359,14 @@ public class Commands { for (CommandNode node : rootcommandnode.getChildren()) { bukkit.add(node.getName()); } diff --git a/patches/server/0422-Implement-Brigadier-Mojang-API.patch b/patches/server/0422-Implement-Brigadier-Mojang-API.patch index 61654d81fd..6cce94d466 100644 --- a/patches/server/0422-Implement-Brigadier-Mojang-API.patch +++ b/patches/server/0422-Implement-Brigadier-Mojang-API.patch @@ -10,7 +10,7 @@ Adds CommandRegisteredEvent - Allows manipulating the CommandNode to add more children/metadata for the client diff --git a/build.gradle.kts b/build.gradle.kts -index 24465fa59dd9eeff82ad620731fadcb19910aa4e..053e65679dd44f3d1c669ef560f07554af09086b 100644 +index b91eca079738eb5b48b516915c52511c3bddd831..a482ad74b9a5d06a982ac2a6d9b6c5dc9f664f46 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,6 +16,7 @@ repositories { @@ -61,10 +61,10 @@ index 880fc9fea286384d002518137972935fdf1d2d72..a59d14e61fcbca7861a5593d0717b812 public boolean hasPermission(int level) { // CraftBukkit start diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 07c4d909324c8aad3a8c5d27811e2c28fe7a91f3..96a33f63024c1f72ab018e15904505832430002c 100644 +index 1140325637868d60b80394016d936759b1edded1..341a0fb886daaffd885dfc448b93f084c98f0559 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -362,6 +362,7 @@ public class Commands { +@@ -360,6 +360,7 @@ public class Commands { bukkit.add(node.getName()); } // Paper start - Async command map building @@ -72,7 +72,7 @@ index 07c4d909324c8aad3a8c5d27811e2c28fe7a91f3..96a33f63024c1f72ab018e1590450583 MinecraftServer.getServer().execute(() -> { runSync(player, bukkit, rootcommandnode); }); -@@ -369,6 +370,7 @@ public class Commands { +@@ -367,6 +368,7 @@ public class Commands { private void runSync(ServerPlayer player, Collection<String> bukkit, RootCommandNode<SharedSuggestionProvider> rootcommandnode) { // Paper end - Async command map building @@ -81,7 +81,7 @@ index 07c4d909324c8aad3a8c5d27811e2c28fe7a91f3..96a33f63024c1f72ab018e1590450583 event.getPlayer().getServer().getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 9fc196ada8dc3b9b9a8f3f35ac6b07c949ce2339..3071053aa9c6a9abc2af50b3c370a408cddbac85 100644 +index 34e8007b3e34a946749b3d900fbd8eb2955fac00..9e9edd4b649330c99a41372192e5051732204cc5 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -759,8 +759,12 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser diff --git a/patches/server/0573-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch b/patches/server/0573-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch index db386dbadd..5c3c27cbaa 100644 --- a/patches/server/0573-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch +++ b/patches/server/0573-Add-PlayerTradeEvent-and-PlayerPurchaseEvent.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Add PlayerTradeEvent and PlayerPurchaseEvent Co-authored-by: Alexander <[email protected]> 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 4a7b657265cbbc91ae85409abb3db29cfc555a2c..c75fa3274dedfafa11b94704695a2313f11c22cc 100644 +index 4a7b657265cbbc91ae85409abb3db29cfc555a2c..a44c30370989c8a5ac5ad8e9f0062e76d8c33675 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 4a7b657265cbbc91ae85409abb3db29cfc555a2c..c75fa3274dedfafa11b94704695a2313 + // 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 dc036f6450b2eccdc848c66dac525ed43f70f4e4..549c13180fbbebce73771a8d82eb040f 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..9e65c9535e01b3c858050a7881aff3f99edbeaac 100644 +index 74b28315197b81f80334ae6023113904e4fac4c3..42b4bd526c3a083ae29f913f7f67eb7ee4d61fa7 100644 --- a/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java +++ b/src/main/java/net/minecraft/world/inventory/MerchantResultSlot.java -@@ -47,13 +47,30 @@ public class MerchantResultSlot extends Slot { +@@ -47,13 +47,32 @@ public class MerchantResultSlot extends Slot { @Override public void onTake(Player player, ItemStack stack) { @@ -180,18 +180,20 @@ index 74b28315197b81f80334ae6023113904e4fac4c3..9e65c9535e01b3c858050a7881aff3f9 MerchantOffer merchantOffer = this.slots.getActiveOffer(); + // Paper start + io.papermc.paper.event.player.PlayerPurchaseEvent event = 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 (event != null) { -+ if (!event.callEvent()) { -+ stack.setCount(0); -+ event.getPlayer().updateInventory(); -+ return; ++ if (merchantOffer != null && player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) { ++ if (this.merchant instanceof net.minecraft.world.entity.npc.AbstractVillager villager) { ++ event = new io.papermc.paper.event.player.PlayerTradeEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.AbstractVillager) villager.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()) { ++ stack.setCount(0); ++ event.getPlayer().updateInventory(); ++ return; ++ } ++ merchantOffer = org.bukkit.craftbukkit.inventory.CraftMerchantRecipe.fromBukkit(event.getTrade()).toMinecraft(); + } -+ merchantOffer = org.bukkit.craftbukkit.inventory.CraftMerchantRecipe.fromBukkit(event.getTrade()).toMinecraft(); + } + this.checkTakeAchievements(stack); + // Paper end @@ -205,19 +207,19 @@ index 74b28315197b81f80334ae6023113904e4fac4c3..9e65c9535e01b3c858050a7881aff3f9 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 50dca0d86dbc47f66ba2d2f262e8587853cc6f9e..f11eff88ba4b9a4f8601d70c07907cc12611a1d0 100644 +index 50dca0d86dbc47f66ba2d2f262e8587853cc6f9e..7444800ff6e0807762001399907cfbd361d7f3eb 100644 --- a/src/main/java/net/minecraft/world/item/trading/Merchant.java +++ b/src/main/java/net/minecraft/world/item/trading/Merchant.java @@ -21,6 +21,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 f40d6a0048ad5b3f6e31d83894ee89f5ca64fb3a..22a64092e3b925e852b304376fe0a7c19acf35d0 100644 +index f40d6a0048ad5b3f6e31d83894ee89f5ca64fb3a..eb938890132b9e72204b7f862c4d0a734f7d9924 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 { @@ -226,13 +228,13 @@ index f40d6a0048ad5b3f6e31d83894ee89f5ca64fb3a..22a64092e3b925e852b304376fe0a7c1 + // 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)); + } + } diff --git a/patches/server/0847-fixup-Async-command-map-building.patch b/patches/server/0847-fixup-Async-command-map-building.patch deleted file mode 100644 index a788351feb..0000000000 --- a/patches/server/0847-fixup-Async-command-map-building.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Shane Freeder <[email protected]> -Date: Sat, 4 Dec 2021 03:21:34 +0000 -Subject: [PATCH] fixup! Async command map building - - -diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index b7c24a7ff4dc50d03f74b21a0b353d0ce559b4d4..0766f272068248175bc929a145bafaf9efc8978d 100644 ---- a/src/main/java/net/minecraft/commands/Commands.java -+++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -350,9 +350,7 @@ public class Commands { - // CraftBukkit start - // Register Vanilla commands into builtRoot as before - // Paper start - Async command map building -- java.util.concurrent.ForkJoinPool.commonPool().execute(() -> { -- sendAsync(player); -- }); -+ net.minecraft.server.MCUtil.scheduleAsyncTask(() -> this.sendAsync(player)); - } - - private void sendAsync(ServerPlayer player) { |