--- a/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/net/minecraft/world/level/block/EndPortalBlock.java
@@ -17,6 +17,7 @@
 import net.minecraft.world.level.block.entity.TheEndPortalBlockEntity;
 import net.minecraft.world.level.block.state.BlockBehaviour;
 import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.dimension.LevelStem;
 import net.minecraft.world.level.levelgen.feature.EndPlatformFeature;
 import net.minecraft.world.level.material.Fluid;
 import net.minecraft.world.level.portal.DimensionTransition;
@@ -25,14 +26,25 @@
 import net.minecraft.world.phys.shapes.CollisionContext;
 import net.minecraft.world.phys.shapes.Shapes;
 import net.minecraft.world.phys.shapes.VoxelShape;
+// CraftBukkit start
+import java.util.List;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.CraftWorld;
+import org.bukkit.craftbukkit.event.CraftPortalEvent;
+import org.bukkit.craftbukkit.util.CraftLocation;
+import org.bukkit.event.entity.EntityPortalEnterEvent;
+import org.bukkit.event.player.PlayerRespawnEvent;
+import org.bukkit.event.player.PlayerTeleportEvent;
+// CraftBukkit end
 
 public class EndPortalBlock extends BaseEntityBlock implements Portal {
+
     public static final MapCodec<EndPortalBlock> CODEC = simpleCodec(EndPortalBlock::new);
-    protected static final VoxelShape SHAPE = Block.box(0.0, 6.0, 0.0, 16.0, 12.0, 16.0);
+    protected static final VoxelShape SHAPE = Block.box(0.0D, 6.0D, 0.0D, 16.0D, 12.0D, 16.0D);
 
     @Override
     public MapCodec<EndPortalBlock> codec() {
-        return CODEC;
+        return EndPortalBlock.CODEC;
     }
 
     protected EndPortalBlock(BlockBehaviour.Properties settings) {
@@ -46,68 +58,79 @@
 
     @Override
     protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
-        return SHAPE;
+        return EndPortalBlock.SHAPE;
     }
 
     @Override
     protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
-        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
-            )) {
-            if (!world.isClientSide && world.dimension() == Level.END && entity instanceof ServerPlayer serverPlayer && !serverPlayer.seenCredits) {
-                serverPlayer.showEndCredits();
-                return;
+        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()));
+            world.getCraftServer().getPluginManager().callEvent(event);
+            // CraftBukkit end
+            if (!world.isClientSide && world.dimension() == Level.END && entity instanceof ServerPlayer) {
+                ServerPlayer entityplayer = (ServerPlayer) entity;
+
+                if (!entityplayer.seenCredits) {
+                    entityplayer.showEndCredits();
+                    return;
+                }
             }
 
             entity.setAsInsidePortal(this, pos);
         }
+
     }
 
     @Override
     public DimensionTransition getPortalDestination(ServerLevel world, Entity entity, BlockPos pos) {
-        ResourceKey<Level> resourceKey = world.dimension() == Level.END ? Level.OVERWORLD : Level.END;
-        ServerLevel serverLevel = world.getServer().getLevel(resourceKey);
-        if (serverLevel == null) {
-            return null;
+        ResourceKey<Level> resourcekey = world.getTypeKey() == LevelStem.END ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends
+        ServerLevel worldserver1 = world.getServer().getLevel(resourcekey);
+
+        if (worldserver1 == null) {
+            return new DimensionTransition(PlayerTeleportEvent.TeleportCause.END_PORTAL); // CraftBukkit- always fire event in case plugins wish to change it
         } else {
-            boolean bl = resourceKey == Level.END;
-            BlockPos blockPos = bl ? ServerLevel.END_SPAWN_POINT : serverLevel.getSharedSpawnPos();
-            Vec3 vec3 = blockPos.getBottomCenter();
+            boolean flag = resourcekey == Level.END;
+            BlockPos blockposition1 = flag ? ServerLevel.END_SPAWN_POINT : worldserver1.getSharedSpawnPos();
+            Vec3 vec3d = blockposition1.getBottomCenter();
             float f = entity.getYRot();
-            if (bl) {
-                EndPlatformFeature.createEndPlatform(serverLevel, BlockPos.containing(vec3).below(), true);
+
+            if (flag) {
+                EndPlatformFeature.createEndPlatform(worldserver1, BlockPos.containing(vec3d).below(), true, entity); // CraftBukkit
                 f = Direction.WEST.toYRot();
                 if (entity instanceof ServerPlayer) {
-                    vec3 = vec3.subtract(0.0, 1.0, 0.0);
+                    vec3d = vec3d.subtract(0.0D, 1.0D, 0.0D);
                 }
             } else {
-                if (entity instanceof ServerPlayer serverPlayer) {
-                    return serverPlayer.findRespawnPositionAndUseSpawnBlock(false, DimensionTransition.DO_NOTHING);
+                if (entity instanceof ServerPlayer) {
+                    ServerPlayer entityplayer = (ServerPlayer) entity;
+
+                    return entityplayer.findRespawnPositionAndUseSpawnBlock(false, DimensionTransition.DO_NOTHING, PlayerRespawnEvent.RespawnReason.END_PORTAL); // CraftBukkit
                 }
 
-                vec3 = entity.adjustSpawnLocation(serverLevel, blockPos).getBottomCenter();
+                vec3d = entity.adjustSpawnLocation(worldserver1, blockposition1).getBottomCenter();
             }
 
-            return new DimensionTransition(
-                serverLevel,
-                vec3,
-                entity.getDeltaMovement(),
-                f,
-                entity.getXRot(),
-                DimensionTransition.PLAY_PORTAL_SOUND.then(DimensionTransition.PLACE_PORTAL_TICKET)
-            );
+            // CraftBukkit start
+            CraftPortalEvent event = entity.callPortalEvent(entity, CraftLocation.toBukkit(vec3d, worldserver1.getWorld(), f, entity.getXRot()), PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0);
+            if (event == null) {
+                return null;
+            }
+            Location to = event.getTo();
+
+            return new DimensionTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), entity.getDeltaMovement(), to.getYaw(), to.getPitch(), DimensionTransition.PLAY_PORTAL_SOUND.then(DimensionTransition.PLACE_PORTAL_TICKET), PlayerTeleportEvent.TeleportCause.END_PORTAL);
+            // CraftBukkit end
         }
     }
 
     @Override
     public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) {
-        double d = (double)pos.getX() + random.nextDouble();
-        double e = (double)pos.getY() + 0.8;
-        double f = (double)pos.getZ() + random.nextDouble();
-        world.addParticle(ParticleTypes.SMOKE, d, e, f, 0.0, 0.0, 0.0);
+        double d0 = (double) pos.getX() + random.nextDouble();
+        double d1 = (double) pos.getY() + 0.8D;
+        double d2 = (double) pos.getZ() + random.nextDouble();
+
+        world.addParticle(ParticleTypes.SMOKE, d0, d1, d2, 0.0D, 0.0D, 0.0D);
     }
 
     @Override
