--- a/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
+++ b/net/minecraft/world/entity/ai/behavior/InteractWithDoor.java
@@ -1,7 +1,7 @@
 package net.minecraft.world.entity.ai.behavior;
 
 import com.google.common.collect.Sets;
-import com.mojang.datafixers.kinds.OptionalBox;
+import com.mojang.datafixers.kinds.OptionalBox.Mu;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
@@ -25,55 +25,78 @@
 import org.apache.commons.lang3.mutable.MutableObject;
 
 public class InteractWithDoor {
+
     private static final int COOLDOWN_BEFORE_RERUNNING_IN_SAME_NODE = 20;
     private static final double SKIP_CLOSING_DOOR_IF_FURTHER_AWAY_THAN = 3.0D;
     private static final double MAX_DISTANCE_TO_HOLD_DOOR_OPEN_FOR_OTHER_MOBS = 2.0D;
 
+    public InteractWithDoor() {}
+
     public static BehaviorControl<LivingEntity> create() {
-        MutableObject<Node> mutableObject = new MutableObject<>((Node)null);
-        MutableInt mutableInt = new MutableInt(0);
-        return BehaviorBuilder.create((context) -> {
-            return context.group(context.present(MemoryModuleType.PATH), context.registered(MemoryModuleType.DOORS_TO_CLOSE), context.registered(MemoryModuleType.NEAREST_LIVING_ENTITIES)).apply(context, (path, doorsToClose, mobs) -> {
-                return (world, entity, time) -> {
-                    Path path = context.get(path);
-                    Optional<Set<GlobalPos>> optional = context.tryGet(doorsToClose);
-                    if (!path.notStarted() && !path.isDone()) {
-                        if (Objects.equals(mutableObject.getValue(), path.getNextNode())) {
-                            mutableInt.setValue(20);
-                        } else if (mutableInt.decrementAndGet() > 0) {
+        MutableObject<Node> mutableobject = new MutableObject((Object) null);
+        MutableInt mutableint = new MutableInt(0);
+
+        return BehaviorBuilder.create((behaviorbuilder_b) -> {
+            return behaviorbuilder_b.group(behaviorbuilder_b.present(MemoryModuleType.PATH), behaviorbuilder_b.registered(MemoryModuleType.DOORS_TO_CLOSE), behaviorbuilder_b.registered(MemoryModuleType.NEAREST_LIVING_ENTITIES)).apply(behaviorbuilder_b, (memoryaccessor, memoryaccessor1, memoryaccessor2) -> {
+                return (worldserver, entityliving, i) -> {
+                    Path pathentity = (Path) behaviorbuilder_b.get(memoryaccessor);
+                    Optional<Set<GlobalPos>> optional = behaviorbuilder_b.tryGet(memoryaccessor1);
+
+                    if (!pathentity.notStarted() && !pathentity.isDone()) {
+                        if (Objects.equals(mutableobject.getValue(), pathentity.getNextNode())) {
+                            mutableint.setValue(20);
+                        } else if (mutableint.decrementAndGet() > 0) {
                             return false;
                         }
 
-                        mutableObject.setValue(path.getNextNode());
-                        Node node = path.getPreviousNode();
-                        Node node2 = path.getNextNode();
-                        BlockPos blockPos = node.asBlockPos();
-                        BlockState blockState = world.getBlockState(blockPos);
-                        if (blockState.is(BlockTags.WOODEN_DOORS, (state) -> {
-                            return state.getBlock() instanceof DoorBlock;
+                        mutableobject.setValue(pathentity.getNextNode());
+                        Node pathpoint = pathentity.getPreviousNode();
+                        Node pathpoint1 = pathentity.getNextNode();
+                        BlockPos blockposition = pathpoint.asBlockPos();
+                        BlockState iblockdata = worldserver.getBlockState(blockposition);
+
+                        if (iblockdata.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> {
+                            return blockbase_blockdata.getBlock() instanceof DoorBlock;
                         })) {
-                            DoorBlock doorBlock = (DoorBlock)blockState.getBlock();
-                            if (!doorBlock.isOpen(blockState)) {
-                                doorBlock.setOpen(entity, world, blockState, blockPos, true);
+                            DoorBlock blockdoor = (DoorBlock) iblockdata.getBlock();
+
+                            if (!blockdoor.isOpen(iblockdata)) {
+                                // CraftBukkit start - entities opening doors
+                                org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entityliving.getBukkitEntity(), org.bukkit.craftbukkit.v1_20_R2.block.CraftBlock.at(entityliving.level(), blockposition));
+                                entityliving.level().getCraftServer().getPluginManager().callEvent(event);
+                                if (event.isCancelled()) {
+                                    return false;
+                                }
+                                // CraftBukkit end
+                                blockdoor.setOpen(entityliving, worldserver, iblockdata, blockposition, true);
                             }
 
-                            optional = rememberDoorToClose(doorsToClose, optional, world, blockPos);
+                            optional = InteractWithDoor.rememberDoorToClose(memoryaccessor1, optional, worldserver, blockposition);
                         }
 
-                        BlockPos blockPos2 = node2.asBlockPos();
-                        BlockState blockState2 = world.getBlockState(blockPos2);
-                        if (blockState2.is(BlockTags.WOODEN_DOORS, (state) -> {
-                            return state.getBlock() instanceof DoorBlock;
+                        BlockPos blockposition1 = pathpoint1.asBlockPos();
+                        BlockState iblockdata1 = worldserver.getBlockState(blockposition1);
+
+                        if (iblockdata1.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> {
+                            return blockbase_blockdata.getBlock() instanceof DoorBlock;
                         })) {
-                            DoorBlock doorBlock2 = (DoorBlock)blockState2.getBlock();
-                            if (!doorBlock2.isOpen(blockState2)) {
-                                doorBlock2.setOpen(entity, world, blockState2, blockPos2, true);
-                                optional = rememberDoorToClose(doorsToClose, optional, world, blockPos2);
+                            DoorBlock blockdoor1 = (DoorBlock) iblockdata1.getBlock();
+
+                            if (!blockdoor1.isOpen(iblockdata1)) {
+                                // CraftBukkit start - entities opening doors
+                                org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entityliving.getBukkitEntity(), org.bukkit.craftbukkit.v1_20_R2.block.CraftBlock.at(entityliving.level(), blockposition1));
+                                entityliving.level().getCraftServer().getPluginManager().callEvent(event);
+                                if (event.isCancelled()) {
+                                    return false;
+                                }
+                                // CraftBukkit end
+                                blockdoor1.setOpen(entityliving, worldserver, iblockdata1, blockposition1, true);
+                                optional = InteractWithDoor.rememberDoorToClose(memoryaccessor1, optional, worldserver, blockposition1);
                             }
                         }
 
-                        optional.ifPresent((doors) -> {
-                            closeDoorsThatIHaveOpenedOrPassedThrough(world, entity, node, node2, doors, context.tryGet(mobs));
+                        optional.ifPresent((set) -> {
+                            InteractWithDoor.closeDoorsThatIHaveOpenedOrPassedThrough(worldserver, entityliving, pathpoint, pathpoint1, set, behaviorbuilder_b.tryGet(memoryaccessor2));
                         });
                         return true;
                     } else {
@@ -85,28 +108,31 @@
     }
 
     public static void closeDoorsThatIHaveOpenedOrPassedThrough(ServerLevel world, LivingEntity entity, @Nullable Node lastNode, @Nullable Node currentNode, Set<GlobalPos> doors, Optional<List<LivingEntity>> otherMobs) {
-        Iterator<GlobalPos> iterator = doors.iterator();
+        Iterator iterator = doors.iterator();
 
-        while(iterator.hasNext()) {
-            GlobalPos globalPos = iterator.next();
-            BlockPos blockPos = globalPos.pos();
-            if ((lastNode == null || !lastNode.asBlockPos().equals(blockPos)) && (currentNode == null || !currentNode.asBlockPos().equals(blockPos))) {
-                if (isDoorTooFarAway(world, entity, globalPos)) {
+        while (iterator.hasNext()) {
+            GlobalPos globalpos = (GlobalPos) iterator.next();
+            BlockPos blockposition = globalpos.pos();
+
+            if ((lastNode == null || !lastNode.asBlockPos().equals(blockposition)) && (currentNode == null || !currentNode.asBlockPos().equals(blockposition))) {
+                if (InteractWithDoor.isDoorTooFarAway(world, entity, globalpos)) {
                     iterator.remove();
                 } else {
-                    BlockState blockState = world.getBlockState(blockPos);
-                    if (!blockState.is(BlockTags.WOODEN_DOORS, (state) -> {
-                        return state.getBlock() instanceof DoorBlock;
+                    BlockState iblockdata = world.getBlockState(blockposition);
+
+                    if (!iblockdata.is(BlockTags.WOODEN_DOORS, (blockbase_blockdata) -> {
+                        return blockbase_blockdata.getBlock() instanceof DoorBlock;
                     })) {
                         iterator.remove();
                     } else {
-                        DoorBlock doorBlock = (DoorBlock)blockState.getBlock();
-                        if (!doorBlock.isOpen(blockState)) {
+                        DoorBlock blockdoor = (DoorBlock) iblockdata.getBlock();
+
+                        if (!blockdoor.isOpen(iblockdata)) {
                             iterator.remove();
-                        } else if (areOtherMobsComingThroughDoor(entity, blockPos, otherMobs)) {
+                        } else if (InteractWithDoor.areOtherMobsComingThroughDoor(entity, blockposition, otherMobs)) {
                             iterator.remove();
                         } else {
-                            doorBlock.setOpen(entity, world, blockState, blockPos, false);
+                            blockdoor.setOpen(entity, world, iblockdata, blockposition, false);
                             iterator.remove();
                         }
                     }
@@ -117,12 +143,12 @@
     }
 
     private static boolean areOtherMobsComingThroughDoor(LivingEntity entity, BlockPos pos, Optional<List<LivingEntity>> otherMobs) {
-        return otherMobs.isEmpty() ? false : otherMobs.get().stream().filter((mob) -> {
-            return mob.getType() == entity.getType();
-        }).filter((mob) -> {
-            return pos.closerToCenterThan(mob.position(), 2.0D);
-        }).anyMatch((mob) -> {
-            return isMobComingThroughDoor(mob.getBrain(), pos);
+        return otherMobs.isEmpty() ? false : (otherMobs.get()).stream().filter((entityliving1) -> { // CraftBukkit - decompile error
+            return entityliving1.getType() == entity.getType();
+        }).filter((entityliving1) -> {
+            return pos.closerToCenterThan(entityliving1.position(), 2.0D);
+        }).anyMatch((entityliving1) -> {
+            return InteractWithDoor.isMobComingThroughDoor(entityliving1.getBrain(), pos);
         });
     }
 
@@ -130,16 +156,19 @@
         if (!brain.hasMemoryValue(MemoryModuleType.PATH)) {
             return false;
         } else {
-            Path path = brain.getMemory(MemoryModuleType.PATH).get();
-            if (path.isDone()) {
+            Path pathentity = (Path) brain.getMemory(MemoryModuleType.PATH).get();
+
+            if (pathentity.isDone()) {
                 return false;
             } else {
-                Node node = path.getPreviousNode();
-                if (node == null) {
+                Node pathpoint = pathentity.getPreviousNode();
+
+                if (pathpoint == null) {
                     return false;
                 } else {
-                    Node node2 = path.getNextNode();
-                    return pos.equals(node.asBlockPos()) || pos.equals(node2.asBlockPos());
+                    Node pathpoint1 = pathentity.getNextNode();
+
+                    return pos.equals(pathpoint.asBlockPos()) || pos.equals(pathpoint1.asBlockPos());
                 }
             }
         }
@@ -149,13 +178,15 @@
         return doorPos.dimension() != world.dimension() || !doorPos.pos().closerToCenterThan(entity.position(), 3.0D);
     }
 
-    private static Optional<Set<GlobalPos>> rememberDoorToClose(MemoryAccessor<OptionalBox.Mu, Set<GlobalPos>> queryResult, Optional<Set<GlobalPos>> doors, ServerLevel world, BlockPos pos) {
-        GlobalPos globalPos = GlobalPos.of(world.dimension(), pos);
-        return Optional.of(doors.map((doorSet) -> {
-            doorSet.add(globalPos);
-            return doorSet;
+    private static Optional<Set<GlobalPos>> rememberDoorToClose(MemoryAccessor<Mu, Set<GlobalPos>> queryResult, Optional<Set<GlobalPos>> doors, ServerLevel world, BlockPos pos) {
+        GlobalPos globalpos = GlobalPos.of(world.dimension(), pos);
+
+        return Optional.of((Set) doors.map((set) -> {
+            set.add(globalpos);
+            return set;
         }).orElseGet(() -> {
-            Set<GlobalPos> set = Sets.newHashSet(globalPos);
+            Set<GlobalPos> set = Sets.newHashSet(new GlobalPos[]{globalpos});
+
             queryResult.set(set);
             return set;
         }));
