diff --git a/patches/api/Clone-mutables-to-prevent-unexpected-issues.patch b/patches/api/Clone-mutables-to-prevent-unexpected-issues.patch
index 172c7dfef5..3b0aedb336 100644
--- a/patches/api/Clone-mutables-to-prevent-unexpected-issues.patch
+++ b/patches/api/Clone-mutables-to-prevent-unexpected-issues.patch
@@ -53,7 +53,7 @@ diff --git a/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java b
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java
 +++ b/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java
-@@ -0,0 +0,0 @@ public class EntityPortalEnterEvent extends EntityEvent {
+@@ -0,0 +0,0 @@ public class EntityPortalEnterEvent extends EntityEvent implements org.bukkit.ev
       */
      @NotNull
      public Location getLocation() {
@@ -61,7 +61,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return location.clone(); // Paper - clone to avoid changes
      }
  
-     @NotNull
+     // Paper start
 diff --git a/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java b/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java
diff --git a/patches/api/Improve-PortalEvents.patch b/patches/api/Improve-PortalEvents.patch
index fd6fea0745..8cc13ef52e 100644
--- a/patches/api/Improve-PortalEvents.patch
+++ b/patches/api/Improve-PortalEvents.patch
@@ -4,6 +4,85 @@ Date: Thu, 15 Dec 2022 10:33:34 -0800
 Subject: [PATCH] Improve PortalEvents
 
 
+diff --git a/src/main/java/org/bukkit/PortalType.java b/src/main/java/org/bukkit/PortalType.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/PortalType.java
++++ b/src/main/java/org/bukkit/PortalType.java
+@@ -0,0 +0,0 @@ public enum PortalType {
+      * This is an Ender portal.
+      */
+     ENDER,
++    // Paper start
++    /**
++     * This is an end gateway
++     */
++    END_GATEWAY,
++    // Paper end
+ 
+     /**
+      * This is a custom Plugin portal.
+diff --git a/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java b/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java
++++ b/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java
+@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
+ 
+ /**
+  * Called when an entity comes into contact with a portal
++ * <p>
++ * Cancelling this event prevents any further processing of the portal for that tick.
++ * @see io.papermc.paper.event.entity.EntityInsideBlockEvent
+  */
+-public class EntityPortalEnterEvent extends EntityEvent {
++public class EntityPortalEnterEvent extends EntityEvent implements org.bukkit.event.Cancellable { // Paper
+     private static final HandlerList handlers = new HandlerList();
+     private final Location location;
+ 
++    @Deprecated(since = "1.21") @io.papermc.paper.annotation.DoNotUse // Paper
+     public EntityPortalEnterEvent(@NotNull final Entity entity, @NotNull final Location location) {
++        // Paper start
++        this(entity, location, org.bukkit.PortalType.CUSTOM);
++    }
++    @org.jetbrains.annotations.ApiStatus.Internal
++    public EntityPortalEnterEvent(@NotNull final Entity entity, @NotNull final Location location, @NotNull final org.bukkit.PortalType portalType) {
++        // Paper end
+         super(entity);
+         this.location = location;
++        this.portalType = portalType; // Paper
+     }
+ 
+     /**
+@@ -0,0 +0,0 @@ public class EntityPortalEnterEvent extends EntityEvent {
+         return location;
+     }
+ 
++    // Paper start
++    private boolean cancelled = false;
++    private final org.bukkit.PortalType portalType;
++
++    /**
++     * Get the portal type.
++     *
++     * @return the portal type
++     */
++    public org.bukkit.@NotNull PortalType getPortalType() {
++        return this.portalType;
++    }
++
++    @Override
++    public boolean isCancelled() {
++        return this.cancelled;
++    }
++
++    @Override
++    public void setCancelled(final boolean cancel) {
++        this.cancelled = cancel;
++    }
++    // Paper end
++
+     @NotNull
+     @Override
+     public HandlerList getHandlers() {
 diff --git a/src/main/java/org/bukkit/event/entity/EntityPortalEvent.java b/src/main/java/org/bukkit/event/entity/EntityPortalEvent.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/event/entity/EntityPortalEvent.java
diff --git a/patches/server/Improve-PortalEvents.patch b/patches/server/Improve-PortalEvents.patch
index 394de3b175..0422306c55 100644
--- a/patches/server/Improve-PortalEvents.patch
+++ b/patches/server/Improve-PortalEvents.patch
@@ -17,6 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        final org.bukkit.PortalType portalType = switch (cause) {
 +            case END_PORTAL -> org.bukkit.PortalType.ENDER;
 +            case NETHER_PORTAL -> org.bukkit.PortalType.NETHER;
++            case END_GATEWAY -> org.bukkit.PortalType.END_GATEWAY; // not actually used yet
 +            default -> org.bukkit.PortalType.CUSTOM;
 +        };
 +        EntityPortalEvent event = new EntityPortalEvent(bukkitEntity, enter, exit, searchRadius, portalType);
@@ -24,3 +25,48 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          event.getEntity().getServer().getPluginManager().callEvent(event);
          if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !entity.isAlive()) {
              return null;
+diff --git a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java
++++ b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java
+@@ -0,0 +0,0 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal {
+     protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+         if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
+         if (entity.canUsePortal(false)) {
++            // Paper start - call EntityPortalEnterEvent
++            org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.END_GATEWAY); // Paper - add portal type
++            if (!event.callEvent()) return;
++            // Paper end - call EntityPortalEnterEvent
+             BlockEntity tileentity = world.getBlockEntity(pos);
+ 
+             if (!world.isClientSide && tileentity instanceof TheEndGatewayBlockEntity) {
+diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
++++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
+@@ -0,0 +0,0 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal {
+         if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
+         if (entity.canUsePortal(false) && Shapes.joinIsNotEmpty(Shapes.create(entity.getBoundingBox().move((double) (-pos.getX()), (double) (-pos.getY()), (double) (-pos.getZ()))), state.getShape(world, pos), BooleanOp.AND)) {
+             // CraftBukkit start - Entity in portal
+-            EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
++            EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.ENDER); // Paper - add portal type
+             world.getCraftServer().getPluginManager().callEvent(event);
++            if (event.isCancelled()) return; // Paper - make cancellable
+             // CraftBukkit end
+             if (!world.isClientSide && world.dimension() == Level.END && entity instanceof ServerPlayer) {
+                 ServerPlayer entityplayer = (ServerPlayer) entity;
+diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
++++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
+@@ -0,0 +0,0 @@ public class NetherPortalBlock extends Block implements Portal {
+         if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
+         if (entity.canUsePortal(false)) {
+             // CraftBukkit start - Entity in portal
+-            EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
++            EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.NETHER); // Paper - add portal type
+             world.getCraftServer().getPluginManager().callEvent(event);
++            if (event.isCancelled()) return; // Paper - make cancellable
+             // CraftBukkit end
+             entity.setAsInsidePortal(this, pos);
+         }