--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -666,7 +_,7 @@
 
     @Override
     public void kickPlayer(String message) {
-        org.spigotmc.AsyncCatcher.catchOp("player kick"); // Spigot
+        //org.spigotmc.AsyncCatcher.catchOp("player kick"); // Spigot // Folia - thread-safe now, as it will simply delay the kick
         this.getHandle().transferCookieConnection.kickPlayer(CraftChatMessage.fromStringOrEmpty(message, true), org.bukkit.event.player.PlayerKickEvent.Cause.PLUGIN); // Paper - kick event cause
     }
 
@@ -684,7 +_,7 @@
 
     @Override
     public void kick(net.kyori.adventure.text.Component message, org.bukkit.event.player.PlayerKickEvent.Cause cause) {
-        org.spigotmc.AsyncCatcher.catchOp("player kick");
+        //org.spigotmc.AsyncCatcher.catchOp("player kick"); // Folia - region threading - no longer needed
         final ServerGamePacketListenerImpl connection = this.getHandle().connection;
         if (connection != null) {
             connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message, cause);
@@ -1403,6 +_,11 @@
 
     @Override
     public boolean teleport(Location location, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) {
+        // Folia start - region threading
+        if (true) {
+            throw new UnsupportedOperationException("Must use teleportAsync while in region threading");
+        }
+        // Folia end - region threading
         Set<io.papermc.paper.entity.TeleportFlag.Relative> relativeArguments;
         Set<io.papermc.paper.entity.TeleportFlag> allFlags;
         if (flags.length == 0) {
@@ -2067,7 +_,7 @@
     private void unregisterEntity(Entity other) {
         // Paper end
         ChunkMap tracker = ((ServerLevel) this.getHandle().level()).getChunkSource().chunkMap;
-        ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId());
+        ChunkMap.TrackedEntity entry = other.moonrise$getTrackedEntity(); // Folia - region threading
         if (entry != null) {
             entry.removePlayer(this.getHandle());
         }
@@ -2164,7 +_,7 @@
             if (original != null) otherPlayer.setUUID(original); // Paper - uuid override
         }
 
-        ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId());
+        ChunkMap.TrackedEntity entry = other.moonrise$getTrackedEntity(); // Folia - region threading
         if (entry != null && !entry.seenBy.contains(this.getHandle().connection)) {
             entry.updatePlayer(this.getHandle());
         }
@@ -2313,9 +_,16 @@
         return this;
     }
 
+    // Folia start - region threading
+    @Override
+    public ServerPlayer getHandleRaw() {
+        return (ServerPlayer)this.entity;
+    }
+    // Folia end - region threading
+
     @Override
     public ServerPlayer getHandle() {
-        return (ServerPlayer) this.entity;
+        return (ServerPlayer) this.entity; // Folia - region threading - no checks for players, as it's a total mess
     }
 
     public void setHandle(final ServerPlayer entity) {
@@ -3345,7 +_,7 @@
         {
             if ( CraftPlayer.this.getHealth() <= 0 && CraftPlayer.this.isOnline() )
             {
-                CraftPlayer.this.server.getServer().getPlayerList().respawn( CraftPlayer.this.getHandle(), false, Entity.RemovalReason.KILLED, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.PLUGIN );
+                CraftPlayer.this.getHandle().respawn(null, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.PLUGIN); // Folia - region threading
             }
         }
 
