From 8317d4c79943c31ab28998f6c757849f9c5cea95 Mon Sep 17 00:00:00 2001
From: CraftBukkit/Spigot <noreply+git-craftbukkit@papermc.io>
Date: Sun, 28 Jul 2024 08:54:10 +1000
Subject: [PATCH] SPIGOT-5731: PortalCreateEvent#getEntity returns null for
 nether portals ignited by flint and steel

By: md_5 <git@md-5.net>
---
 .../net/minecraft/world/item/ItemStack.patch  |  2 +-
 .../world/level/block/BlockFireAbstract.patch | 31 ++++++++++++--
 .../world/level/block/state/BlockBase.patch   | 41 ++++++++++++++++++-
 .../world/level/portal/BlockPortalShape.patch | 23 +++++------
 4 files changed, 80 insertions(+), 17 deletions(-)

diff --git a/paper-server/nms-patches/net/minecraft/world/item/ItemStack.patch b/paper-server/nms-patches/net/minecraft/world/item/ItemStack.patch
index c49da51fe6..058997e7ee 100644
--- a/paper-server/nms-patches/net/minecraft/world/item/ItemStack.patch
+++ b/paper-server/nms-patches/net/minecraft/world/item/ItemStack.patch
@@ -218,7 +218,7 @@
 +                        IBlockData block = world.getBlockState(newblockposition);
 +
 +                        if (!(block.getBlock() instanceof BlockTileEntity)) { // Containers get placed automatically
-+                            block.onPlace(world, newblockposition, oldBlock, true);
++                            block.onPlace(world, newblockposition, oldBlock, true, itemactioncontext);
 +                        }
 +
 +                        world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point
diff --git a/paper-server/nms-patches/net/minecraft/world/level/block/BlockFireAbstract.patch b/paper-server/nms-patches/net/minecraft/world/level/block/BlockFireAbstract.patch
index b218c72c2e..7e7020ba83 100644
--- a/paper-server/nms-patches/net/minecraft/world/level/block/BlockFireAbstract.patch
+++ b/paper-server/nms-patches/net/minecraft/world/level/block/BlockFireAbstract.patch
@@ -1,6 +1,17 @@
 --- a/net/minecraft/world/level/block/BlockFireAbstract.java
 +++ b/net/minecraft/world/level/block/BlockFireAbstract.java
-@@ -127,7 +127,14 @@
+@@ -19,6 +19,10 @@
+ import net.minecraft.world.phys.shapes.VoxelShape;
+ import net.minecraft.world.phys.shapes.VoxelShapeCollision;
+ 
++// CraftBukkit start
++import net.minecraft.world.item.context.ItemActionContext;
++// CraftBukkit end
++
+ public abstract class BlockFireAbstract extends Block {
+ 
+     private static final int SECONDS_ON_FIRE = 8;
+@@ -127,7 +131,14 @@
          if (!entity.fireImmune()) {
              entity.setRemainingFireTicks(entity.getRemainingFireTicks() + 1);
              if (entity.getRemainingFireTicks() == 0) {
@@ -16,7 +27,21 @@
              }
          }
  
-@@ -148,14 +155,14 @@
+@@ -136,26 +147,26 @@
+     }
+ 
+     @Override
+-    protected void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) {
++    protected void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag, ItemActionContext context) { // CraftBukkit - context
+         if (!iblockdata1.is(iblockdata.getBlock())) {
+             if (inPortalDimension(world)) {
+                 Optional<BlockPortalShape> optional = BlockPortalShape.findEmptyPortalShape(world, blockposition, EnumDirection.EnumAxis.X);
+ 
+                 if (optional.isPresent()) {
+-                    ((BlockPortalShape) optional.get()).createPortalBlocks();
++                    ((BlockPortalShape) optional.get()).createPortalBlocks((context == null) ? null : context.getPlayer()); // CraftBukkit - player
+                     return;
+                 }
              }
  
              if (!iblockdata.canSurvive(world, blockposition)) {
@@ -33,7 +58,7 @@
      }
  
      @Override
-@@ -203,4 +210,12 @@
+@@ -203,4 +214,12 @@
              }
          }
      }
diff --git a/paper-server/nms-patches/net/minecraft/world/level/block/state/BlockBase.patch b/paper-server/nms-patches/net/minecraft/world/level/block/state/BlockBase.patch
index 324b31ff47..9b91c97270 100644
--- a/paper-server/nms-patches/net/minecraft/world/level/block/state/BlockBase.patch
+++ b/paper-server/nms-patches/net/minecraft/world/level/block/state/BlockBase.patch
@@ -1,6 +1,30 @@
 --- a/net/minecraft/world/level/block/state/BlockBase.java
 +++ b/net/minecraft/world/level/block/state/BlockBase.java
-@@ -173,8 +173,10 @@
+@@ -81,6 +81,10 @@
+ import net.minecraft.world.phys.shapes.VoxelShapeCollision;
+ import net.minecraft.world.phys.shapes.VoxelShapes;
+ 
++// CraftBukkit start
++import net.minecraft.world.item.context.ItemActionContext;
++// CraftBukkit end
++
+ public abstract class BlockBase implements FeatureElement {
+ 
+     protected static final EnumDirection[] UPDATE_SHAPE_ORDER = new EnumDirection[]{EnumDirection.WEST, EnumDirection.EAST, EnumDirection.NORTH, EnumDirection.SOUTH, EnumDirection.DOWN, EnumDirection.UP};
+@@ -156,6 +160,12 @@
+ 
+     protected void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) {}
+ 
++    // CraftBukkit start
++    protected void onPlace(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag, @Nullable ItemActionContext context) {
++        this.onPlace(iblockdata, world, blockposition, iblockdata1, flag);
++    }
++    // CraftBukkit end
++
+     protected void onRemove(IBlockData iblockdata, World world, BlockPosition blockposition, IBlockData iblockdata1, boolean flag) {
+         if (iblockdata.hasBlockEntity() && !iblockdata.is(iblockdata1.getBlock())) {
+             world.removeBlockEntity(blockposition);
+@@ -173,8 +183,10 @@
                  TileEntity tileentity = iblockdata.hasBlockEntity() ? world.getBlockEntity(blockposition) : null;
                  LootParams.a lootparams_a = (new LootParams.a(worldserver)).withParameter(LootContextParameters.ORIGIN, Vec3D.atCenterOf(blockposition)).withParameter(LootContextParameters.TOOL, ItemStack.EMPTY).withOptionalParameter(LootContextParameters.BLOCK_ENTITY, tileentity).withOptionalParameter(LootContextParameters.THIS_ENTITY, explosion.getDirectSourceEntity());
  
@@ -13,3 +37,18 @@
                  }
  
                  iblockdata.spawnAfterBreak(worldserver, blockposition, ItemStack.EMPTY, flag);
+@@ -1066,7 +1078,13 @@
+         }
+ 
+         public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) {
+-            this.getBlock().onPlace(this.asState(), world, blockposition, iblockdata, flag);
++            // CraftBukkit start
++            this.onPlace(world, blockposition, iblockdata, flag, null);
++        }
++
++        public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag, @Nullable ItemActionContext context) {
++            this.getBlock().onPlace(this.asState(), world, blockposition, iblockdata, flag, context);
++            // CraftBukkit end
+         }
+ 
+         public void onRemove(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) {
diff --git a/paper-server/nms-patches/net/minecraft/world/level/portal/BlockPortalShape.patch b/paper-server/nms-patches/net/minecraft/world/level/portal/BlockPortalShape.patch
index 9fd436b40f..0a345134dd 100644
--- a/paper-server/nms-patches/net/minecraft/world/level/portal/BlockPortalShape.patch
+++ b/paper-server/nms-patches/net/minecraft/world/level/portal/BlockPortalShape.patch
@@ -1,18 +1,17 @@
 --- a/net/minecraft/world/level/portal/BlockPortalShape.java
 +++ b/net/minecraft/world/level/portal/BlockPortalShape.java
-@@ -21,6 +21,11 @@
+@@ -21,6 +21,10 @@
  import net.minecraft.world.phys.shapes.VoxelShape;
  import net.minecraft.world.phys.shapes.VoxelShapes;
  
 +// CraftBukkit start
-+import org.bukkit.craftbukkit.event.CraftPortalEvent;
 +import org.bukkit.event.world.PortalCreateEvent;
 +// CraftBukkit end
 +
  public class BlockPortalShape {
  
      private static final int MIN_WIDTH = 2;
-@@ -40,6 +45,7 @@
+@@ -40,6 +44,7 @@
      private BlockPosition bottomLeft;
      private int height;
      private final int width;
@@ -20,7 +19,7 @@
  
      public static Optional<BlockPortalShape> findEmptyPortalShape(GeneratorAccess generatoraccess, BlockPosition blockposition, EnumDirection.EnumAxis enumdirection_enumaxis) {
          return findPortalShape(generatoraccess, blockposition, (blockportalshape) -> {
-@@ -60,6 +66,7 @@
+@@ -60,6 +65,7 @@
      }
  
      public BlockPortalShape(GeneratorAccess generatoraccess, BlockPosition blockposition, EnumDirection.EnumAxis enumdirection_enumaxis) {
@@ -28,7 +27,7 @@
          this.level = generatoraccess;
          this.axis = enumdirection_enumaxis;
          this.rightDir = enumdirection_enumaxis == EnumDirection.EnumAxis.X ? EnumDirection.WEST : EnumDirection.SOUTH;
-@@ -104,6 +111,7 @@
+@@ -104,6 +110,7 @@
  
              if (!isEmpty(iblockdata)) {
                  if (BlockPortalShape.FRAME.test(iblockdata, this.level, blockposition_mutableblockposition)) {
@@ -36,7 +35,7 @@
                      return i;
                  }
                  break;
-@@ -114,6 +122,7 @@
+@@ -114,6 +121,7 @@
              if (!BlockPortalShape.FRAME.test(iblockdata1, this.level, blockposition_mutableblockposition)) {
                  break;
              }
@@ -44,7 +43,7 @@
          }
  
          return 0;
-@@ -133,6 +142,7 @@
+@@ -133,6 +141,7 @@
              if (!BlockPortalShape.FRAME.test(this.level.getBlockState(blockposition_mutableblockposition1), this.level, blockposition_mutableblockposition1)) {
                  return false;
              }
@@ -52,7 +51,7 @@
          }
  
          return true;
-@@ -162,6 +172,10 @@
+@@ -162,6 +171,10 @@
                      ++this.numPortalBlocks;
                  }
              }
@@ -63,13 +62,13 @@
          }
  
          return 21;
-@@ -175,12 +189,28 @@
+@@ -175,12 +188,28 @@
          return this.bottomLeft != null && this.width >= 2 && this.width <= 21 && this.height >= 3 && this.height <= 21;
      }
  
 -    public void createPortalBlocks() {
-+    // CraftBukkit start - return boolean
-+    public boolean createPortalBlocks() {
++    // CraftBukkit start - return boolean, add entity
++    public boolean createPortalBlocks(Entity entity) {
 +        org.bukkit.World bworld = this.level.getMinecraftWorld().getWorld();
 +
 +        // Copy below for loop
@@ -79,7 +78,7 @@
 +            blocks.setBlock(blockposition, iblockdata, 18);
 +        });
 +
-+        PortalCreateEvent event = new PortalCreateEvent((java.util.List<org.bukkit.block.BlockState>) (java.util.List) blocks.getList(), bworld, null, PortalCreateEvent.CreateReason.FIRE);
++        PortalCreateEvent event = new PortalCreateEvent((java.util.List<org.bukkit.block.BlockState>) (java.util.List) blocks.getList(), bworld, (entity == null) ? null : entity.getBukkitEntity(), PortalCreateEvent.CreateReason.FIRE);
 +        this.level.getMinecraftWorld().getServer().server.getPluginManager().callEvent(event);
 +
 +        if (event.isCancelled()) {