--- a/net/minecraft/world/entity/EntitySelector.java
+++ b/net/minecraft/world/entity/EntitySelector.java
@@ -17,6 +_,22 @@
     public static final Predicate<Entity> NO_SPECTATORS = entity -> !entity.isSpectator();
     public static final Predicate<Entity> CAN_BE_COLLIDED_WITH = NO_SPECTATORS.and(entity -> entity.canBeCollidedWith(null));
     public static final Predicate<Entity> CAN_BE_PICKED = NO_SPECTATORS.and(Entity::isPickable);
+    // Paper start - Ability to control player's insomnia and phantoms
+    public static Predicate<Player> IS_INSOMNIAC = (player) -> {
+        int playerInsomniaTicks = player.level().paperConfig().entities.behavior.playerInsomniaStartTicks;
+        if (playerInsomniaTicks <= 0) {
+            return false;
+        }
+
+        net.minecraft.server.level.ServerPlayer serverPlayer = (net.minecraft.server.level.ServerPlayer) player;
+        return net.minecraft.util.Mth.clamp(serverPlayer.getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= playerInsomniaTicks;
+    };
+    // Paper end - Ability to control player's insomnia and phantoms
+    // Paper start - Affects Spawning API
+    public static final Predicate<Entity> PLAYER_AFFECTS_SPAWNING = (entity) -> {
+        return !entity.isSpectator() && entity.isAlive() && entity instanceof Player player && player.affectsSpawning;
+    };
+    // Paper end - Affects Spawning API
 
     private EntitySelector() {
     }
@@ -27,18 +_,24 @@
     }
 
     public static Predicate<Entity> pushableBy(Entity entity) {
+        // Paper start - Climbing should not bypass cramming gamerule
+        return pushable(entity, false);
+    }
+
+    public static Predicate<Entity> pushable(Entity entity, boolean ignoreClimbing) {
+        // Paper end - Climbing should not bypass cramming gamerule
         Team team = entity.getTeam();
         Team.CollisionRule collisionRule = team == null ? Team.CollisionRule.ALWAYS : team.getCollisionRule();
         return (Predicate<Entity>)(collisionRule == Team.CollisionRule.NEVER
             ? Predicates.alwaysFalse()
             : NO_SPECTATORS.and(
-                entity1 -> {
-                    if (!entity1.isPushable()) {
+                entity1 -> { final Entity pushedEntity = entity1; // Paper - OBFHELPER
+                    if (!pushedEntity.isCollidable(ignoreClimbing) || !pushedEntity.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(pushedEntity)) { // CraftBukkit - collidable API // Paper - Climbing should not bypass cramming gamerule
                         return false;
                     } else if (!entity.level().isClientSide || entity1 instanceof Player player && player.isLocalPlayer()) {
                         Team team1 = entity1.getTeam();
                         Team.CollisionRule collisionRule1 = team1 == null ? Team.CollisionRule.ALWAYS : team1.getCollisionRule();
-                        if (collisionRule1 == Team.CollisionRule.NEVER) {
+                        if (collisionRule1 == Team.CollisionRule.NEVER || (pushedEntity instanceof Player && !io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions)) { // Paper - Configurable player collision
                             return false;
                         } else {
                             boolean flag = team != null && team.isAlliedTo(team1);
