diff --git a/game/client/src/main/resources/assets/minecraft/models/block/grass_ashy.json b/game/client/src/main/resources/assets/minecraft/models/block/grass_ashy.json
index a6e8e7c46..b1b11fd28 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/grass_ashy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/grass_ashy.json
@@ -1,7 +1,7 @@
 {
   "parent": "minecraft:block/cube_bottom_top",
   "textures": {
-    "top": "minecraft:block/ash",
+    "top": "minecraft:block/block_ash",
     "bottom": "minecraft:block/grass/bottom",
     "side": "minecraft:block/grass/ashy_side"
   }
diff --git a/game/client/src/main/resources/assets/minecraft/models/block/grass_snowy.json b/game/client/src/main/resources/assets/minecraft/models/block/grass_snowy.json
index 8723680c7..7854fae4c 100644
--- a/game/client/src/main/resources/assets/minecraft/models/block/grass_snowy.json
+++ b/game/client/src/main/resources/assets/minecraft/models/block/grass_snowy.json
@@ -1,7 +1,7 @@
 {
   "parent": "minecraft:block/cube_bottom_top",
   "textures": {
-    "top": "minecraft:block/snow",
+    "top": "minecraft:block/block_snow",
     "bottom": "minecraft:block/grass/bottom",
     "side": "minecraft:block/grass/snowy_side"
   }
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java
index 9779a578f..5ea60b1f3 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicActivator.java
@@ -63,15 +63,19 @@ public class BlockLogicActivator
             final double px = direction.offsetX() * 0.6D + 0.5D;
             final double py = direction.offsetY() * 0.6D + 0.5D;
             final double pz = direction.offsetZ() * 0.6D + 0.5D;
+            
+            final var facingPos = tilePos.add(direction, new TilePos());
+            final Block<?> block = world.getBlockType(facingPos);
 
             if (itemStack == null) {
-                final Block<?> block = world.getBlockType(tilePos.add(direction, new TilePos()));
-
                 if (block != Blocks.AIR) {
-                    block.onActivatorInteracted(world, tilePos.add(direction, new TilePos()), activator, direction);
+                    block.onActivatorInteracted(world, facingPos, activator, direction);
                 } else {
                     world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, tilePos.x(), tilePos.y(), tilePos.z(), "tile.activator.click", 1, 1);
                 }
+            } else if (block == Blocks.MESH_GOLD) { // hacky, ik
+                block.onActivatorInteracted(world, facingPos, activator, direction);
+                world.playSoundEffect(null, SoundCategory.WORLD_SOUNDS, tilePos.x(), tilePos.y(), tilePos.z(), "tile.activator.use", 1, 1);
             } else {
                 final @NotNull Item item = itemStack.getItem();
                 item.onUseByActivator(itemStack, world, activator, random, tilePos, direction, px, py, pz);
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMeshGold.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMeshGold.java
index 9cbe60533..5764ab5d4 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicMeshGold.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicMeshGold.java
@@ -1,10 +1,12 @@
 package net.minecraft.core.block;
 
+import net.minecraft.core.block.entity.TileEntityActivator;
 import net.minecraft.core.block.entity.TileEntityMeshGold;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityItem;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.util.helper.Direction;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.pos.TilePosc;
@@ -19,16 +21,26 @@ public class BlockLogicMeshGold extends BlockLogicMesh implements BlockLogic.Mat
 
     @Override
     public boolean onInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Player player, @Nullable Side side, double xHit, double yHit) {
-        if (world.getTileEntity(tilePos) instanceof TileEntityMeshGold meshGold) {
-            ItemStack heldItem = player.getHeldItem();
-            boolean flag = meshGold.setFilterItem(player, heldItem);
-            world.notifyBlocksOfNeighborChange(tilePos, this.block);
-            if(heldItem != null && heldItem.stackSize <= 0) {
-                player.inventory.setItem(player.inventory.getCurrentSlot(), null);
-            }
-            return flag;
+        if (!(world.getTileEntity(tilePos) instanceof TileEntityMeshGold meshGold)) return false;
+        ItemStack heldItem = player.getHeldItem();
+        boolean flag = meshGold.setFilterItem(player, heldItem);
+        world.notifyBlocksOfNeighborChange(tilePos, this.block);
+        if(heldItem != null && heldItem.stackSize <= 0) {
+            player.inventory.setItem(player.inventory.getCurrentSlot(), null);
+        }
+        return flag;
+    }
+    
+    @Override
+    public void onActivatorInteracted(@NotNull World world, @NotNull TilePosc tilePos, @NotNull TileEntityActivator activator, @NotNull Direction direction) {
+        if (!(world.getTileEntity(tilePos) instanceof TileEntityMeshGold meshGold)) return;
+        final int activeSlot = activator.stackSelector;
+        final ItemStack activeItem = activator.getItem(activeSlot);
+        meshGold.setFilterItem(activator, activeItem);
+        world.notifyBlocksOfNeighborChange(tilePos, this.block);
+        if (activeItem != null && activeItem.stackSize <= 0) {
+            activator.setItem(activeSlot, null);
         }
-        return false;
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java
index 1ba79015d..cb08aac13 100644
--- a/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java
+++ b/game/core/src/main/java/net/minecraft/core/block/BlockLogicOreRedstone.java
@@ -85,15 +85,21 @@ public class BlockLogicOreRedstone extends BlockLogic {
 
     @Override
     public void onMoved(@NotNull World world, @NotNull TilePosc sourcePos, @NotNull TilePosc targetPos, @NotNull IMovingBlock block, int indexInLine, @NotNull MovingLine line) {
-        block.setBlockType(this.illuminatedBlock);
-        if (this.block != this.illuminatedBlock) line.updateSignal(indexInLine, LineDirection.BOTH, true);
-        world.scheduleBlockUpdate(targetPos, this.illuminatedBlock, 20 + world.rand.nextInt(9 * 20));
+        if (this.block != this.illuminatedBlock) {
+            block.setBlockType(this.illuminatedBlock);
+            line.updateSignal(indexInLine, LineDirection.BOTH, true);
+        }
+    }
+
+    @Override
+    public void onMoveComplete(@NotNull World world, @NotNull TilePosc tilePos) {
+        if (this.illuminated) world.scheduleBlockUpdate(tilePos, this.illuminatedBlock, this.tickDelay() - 3 + world.rand.nextInt(9 * 20));
     }
 
     private void lightRedstone(@NotNull World world, @NotNull TilePosc tilePos) {
         spawnParticles(world, tilePos);
         if (!this.illuminated) {
-            world.scheduleBlockUpdate(tilePos, this.illuminatedBlock, 20 + world.rand.nextInt(9 * 20));
+            world.scheduleBlockUpdate(tilePos, this.illuminatedBlock, this.tickDelay() + world.rand.nextInt(9 * 20));
             world.setBlockTypeNotify(tilePos, this.illuminatedBlock);
         }
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java
index bf755857a..1680d12e8 100644
--- a/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java
+++ b/game/core/src/main/java/net/minecraft/core/block/entity/TileEntityMeshGold.java
@@ -67,26 +67,33 @@ public class TileEntityMeshGold extends TileEntityMesh {
         }
     }
 
-    public boolean setFilterItem(Player player, @Nullable ItemStack stack){
-        boolean success = false;
-        boolean wasNull = filterItem == null;
-        if (filterItem != null && player.getGamemode().hasBlockConsumption()){
-            player.inventory.insertItem(filterItem, true);
-            if (filterItem.stackSize > 0) {
-                player.dropPlayerItem(filterItem);
-            }
-            success = true;
-        }
-        if (stack != null) {
-            stack.consumeItem(player);
-            filterItem = new ItemStack(stack.getItem(), 1, stack.getMetadata(), stack.getData());
-            setChanged();
-            return true;
+    public boolean setFilterItem(@NotNull Player player, @Nullable ItemStack stack){
+        final boolean hasConsumption = player.getGamemode().hasBlockConsumption();
+        final boolean replacedOld = hasConsumption || this.filterItem != null;
+
+        if (hasConsumption && this.filterItem != null) {
+            player.inventory.insertItem(this.filterItem, true);
+            if (this.filterItem.stackSize > 0) player.dropPlayerItem(this.filterItem);
         }
-        filterItem = null;
-        setChanged();
-        this.updateNeighboringMatchers();
-        return success | !wasNull;
+        
+        final boolean replacedWithNew;
+        this.filterItem = (replacedWithNew = (stack != null && stack.consumeItem(player)))
+            ? new ItemStack(stack.getItem(), 1, stack.getMetadata(), stack.getData())
+            : null;
+
+        this.setChanged();
+        return replacedWithNew || replacedOld;
+    }
+    
+    public void setFilterItem(@NotNull TileEntityActivator activator, @Nullable ItemStack stack) {
+        // if (this.filterItem != null) this.worldObj.dropItem(this.tilePos, this.filterItem);
+        if (this.filterItem != null) this.worldObj.dropItem(activator.tilePos, this.filterItem);
+
+        this.filterItem = (stack != null && stack.consumeItem(null))
+            ? new ItemStack(stack.getItem(), 1, stack.getMetadata(), stack.getData())
+            : null;
+
+        this.setChanged();
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java
index a898d12c1..72597b11c 100644
--- a/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java
+++ b/game/core/src/main/java/net/minecraft/core/block/piston/BlockLogicPistonMoving.java
@@ -61,26 +61,18 @@ public class BlockLogicPistonMoving extends BlockLogic {
         return false;
     }
 
-    @Override
-    public boolean pushesEntities(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Class<? extends Entity> entityClass) {
-        if (!(source.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock moving)) return false;
-        if (!moving.isInFinalTick()) return false;
-        // TODO: purely data-based api
-        return moving.movingBlock.pushesEntities(source, tilePos, entityClass);
-    }
-
     @Override
     public boolean isEmittingSignal(@NotNull WorldSource source, @NotNull TilePosc tilePos, @NotNull Side side) {
+        if (!TileEntityMovingPistonBlock.isFinalizing) return false;
         if (!(source.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock moving)) return false;
-        if (!moving.isInFinalTick()) return false;
         // TODO: purely data-based api
         return moving.movingBlock.isEmittingSignal(source, tilePos, side);
     }
 
     @Override
     public boolean isEmittingDirectSignal(@NotNull World world, @NotNull TilePosc tilePos, @NotNull Side side) {
+        if (!TileEntityMovingPistonBlock.isFinalizing) return false;
         if (!(world.getTileEntity(tilePos) instanceof TileEntityMovingPistonBlock moving)) return false;
-        if (!moving.isInFinalTick()) return false;
         // TODO: purely data-based api
         return moving.movingBlock.isEmittingDirectSignal(world, tilePos, side);
     }
diff --git a/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java b/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java
index e011cab22..8cdf2829e 100644
--- a/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java
+++ b/game/core/src/main/java/net/minecraft/core/block/piston/TileEntityMovingPistonBlock.java
@@ -34,7 +34,7 @@ public class TileEntityMovingPistonBlock extends TileEntity implements IMovingBl
 
     @NotNull Direction direction;
     boolean isExtending, isSourcePiston;
-    int lifetime, latestTick;
+    int lifetime;
     float progressCur = 0F, progressPrev = 0F;
 
     // these would otherwise be reallocated each tick, might as well store them here
@@ -146,7 +146,6 @@ public class TileEntityMovingPistonBlock extends TileEntity implements IMovingBl
 
         if (!this.isCollisionInit) this.initCollision();
 
-        this.latestTick = (int) this.worldObj.getWorldTime(); // using only the lower 32 bit should be enough
         if (this.lifetime ++ >= TICKS_TO_EXTEND) {
             this.finalTick();
         } else {
@@ -179,11 +178,6 @@ public class TileEntityMovingPistonBlock extends TileEntity implements IMovingBl
         return (this.isExtending) ? p - 1.0F : 1.0F - p;
     }
 
-    public boolean isInFinalTick() {
-        if (this.lifetime < TICKS_TO_EXTEND) return false;
-        return this.latestTick + 1 >= (int)this.worldObj.getWorldTime();
-    }
-
     public float xOffset(float partialTick) {
         return this.progressSigned(partialTick) * (float) this.direction.offsetX();
     }
@@ -195,8 +189,13 @@ public class TileEntityMovingPistonBlock extends TileEntity implements IMovingBl
     public float zOffset(float partialTick) {
         return this.progressSigned(partialTick) * (float) this.direction.offsetZ();
     }
+    
+    // workaround for fixing blocks in a line losing neighbor signal after moving due to finalization order :(
+    // ideally moving blocks of the same line should be a single atomic unit. 
+    static boolean isFinalizing = false;
 
     public void finalTick() {
+        isFinalizing = true;
         final var selfPos = new TilePos(this.tilePos);
         assert this.worldObj != null;
 
@@ -217,6 +216,7 @@ public class TileEntityMovingPistonBlock extends TileEntity implements IMovingBl
             : "Piston failed to actually move entity!";
 
         this.worldObj.notifyBlockChange(selfPos, this.movingBlock);
+        isFinalizing = false;
     }
 
     @Override
diff --git a/game/core/src/main/java/net/minecraft/core/util/helper/RestHandler.java b/game/core/src/main/java/net/minecraft/core/util/helper/RestHandler.java
index 7f5f14d29..1bc3005e4 100644
--- a/game/core/src/main/java/net/minecraft/core/util/helper/RestHandler.java
+++ b/game/core/src/main/java/net/minecraft/core/util/helper/RestHandler.java
@@ -11,6 +11,8 @@ public class RestHandler
         {
             URL target = new URL(url);
             HttpURLConnection conn = (HttpURLConnection) target.openConnection();
+            conn.setConnectTimeout(8000);
+            conn.setReadTimeout(8000);
             conn.setRequestMethod("POST");
             conn.connect();
             return conn.getResponseCode();
@@ -20,4 +22,11 @@ public class RestHandler
             return 503;
         }
     }
+
+    public static void postAsync(String url)
+    {
+        Thread thread = new Thread(() -> post(url), "RestHandler async POST");
+        thread.setDaemon(true);
+        thread.start();
+    }
 }
diff --git a/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang b/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang
index b13a636c7..87c96be42 100644
--- a/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang
+++ b/game/core/src/main/resources/assets/minecraft/lang/en_US/tile.lang
@@ -867,17 +867,17 @@ tile.piston.base.name=Piston
 tile.piston.base.desc=Pushes blocks but does not pull them.
 tile.piston.base.sticky.name=Sticky Piston
 tile.piston.base.sticky.desc=Pushes and pulls blocks.
-tile.piston.base.steel.name=Reinforced Piston
+tile.piston.base.steel.name=Steel Piston
 tile.piston.base.steel.desc=Pushes blocks and entities with immense force.
 tile.piston.base.detached.name=Detached Piston
 tile.piston.base.detached.desc=Emotionally unavailable.
 tile.piston.base.sticky.detached.name=Detached Sticky Piston
 tile.piston.base.sticky.detached.desc=Emotionally unavailable and covered in slime.
-tile.piston.base.steel.detached.name=Detached Reinforced Piston
+tile.piston.base.steel.detached.name=Detached Steel Piston
 tile.piston.base.steel.detached.desc=Emotionally unavailable, but made of steel.
 tile.piston.head.name=Piston Head
 tile.piston.head.desc=The pushy part of the piston.
-tile.piston.head.steel.name=Reinforced Piston Head
+tile.piston.head.steel.name=Steel Piston Head
 tile.piston.head.steel.desc=The pushy part of the steel piston.
 tile.piston.moving.name=Piston Mover
 tile.piston.moving.desc=The invisible moving part of the piston.
@@ -1489,7 +1489,7 @@ tile.door.steel.bottom.desc=Steeler, no steeling!
 tile.trapdoor.steel.name=Steel Trapdoor
 tile.trapdoor.steel.desc=Like a door, but flat and made of durable steel.
 
-tile.glass.steel.name=Reinforced Glass
+tile.glass.steel.name=Steel Glass
 tile.glass.steel.desc=Like glass, but without the fragility.
 
 tile.rope.name=Rope
diff --git a/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java b/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
index dbad29c07..120899d98 100644
--- a/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
+++ b/game/server/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
@@ -317,10 +317,9 @@ public class PlayerServer extends Player implements ContainerListener {
                     WorldServer worldserver = mcServer.getDimensionWorld(dimension);
                     loadedChunks.remove(chunkCoord);
                     ChunkPos sentChunkPos = new ChunkPos(chunkCoord.x, chunkCoord.z);
-                    if (worldserver.isChunkLoaded(sentChunkPos)) {
-                        worldserver.getChunkProvider().ensureDecorated(sentChunkPos);
-                        worldserver.getChunk(sentChunkPos, true).sentToClients = true;
-                    }
+                    worldserver.getChunkProvider().prepareChunk(sentChunkPos, true);
+                    worldserver.getChunkProvider().ensureDecorated(sentChunkPos);
+                    worldserver.getChunk(sentChunkPos, true).sentToClients = true;
                     playerNetServerHandler.sendPacket(new PacketBlockRegionUpdate(chunkCoord.x * Chunk.CHUNK_SIZE_X, 0, chunkCoord.z * Chunk.CHUNK_SIZE_Z, Chunk.CHUNK_SIZE_X, Chunk.CHUNK_SECTIONS * ChunkSection.SECTION_SIZE_Y, Chunk.CHUNK_SIZE_Z, worldserver));
                     List<TileEntity> list = worldserver.getBlockEntitiesWithinBounds(chunkCoord.x * Chunk.CHUNK_SIZE_X, 0, chunkCoord.z * Chunk.CHUNK_SIZE_Z, chunkCoord.x * Chunk.CHUNK_SIZE_X + Chunk.CHUNK_SIZE_X, Chunk.CHUNK_SECTIONS * ChunkSection.SECTION_SIZE_Y, chunkCoord.z * Chunk.CHUNK_SIZE_Z + Chunk.CHUNK_SIZE_Z);
                     for (int j = 0; j < list.size(); j++)
diff --git a/game/server/src/main/java/net/minecraft/server/net/NetworkListenThread.java b/game/server/src/main/java/net/minecraft/server/net/NetworkListenThread.java
index ca2ee6863..10ead1fa1 100644
--- a/game/server/src/main/java/net/minecraft/server/net/NetworkListenThread.java
+++ b/game/server/src/main/java/net/minecraft/server/net/NetworkListenThread.java
@@ -63,30 +63,36 @@ public class NetworkListenThread
             throw new IllegalArgumentException("Got null pendingconnection!");
         } else
         {
-            pendingConnections.add(netloginhandler);
+            synchronized(pendingConnections)
+            {
+                pendingConnections.add(netloginhandler);
+            }
             return;
         }
     }
 
     public void handleNetworkListenThread()
     {
-        for(int i = 0; i < pendingConnections.size(); i++)
+        synchronized(pendingConnections)
         {
-            PacketHandlerLogin netloginhandler = pendingConnections.get(i);
-            try
-            {
-                netloginhandler.tryLogin();
-            }
-            catch(Exception exception)
+            for(int i = 0; i < pendingConnections.size(); i++)
             {
-                netloginhandler.kickUser("Internal server error");
-                LOGGER.warn("Failed to handle packet: {}", exception, exception);
-            }
-            if(netloginhandler.finishedProcessing)
-            {
-                pendingConnections.remove(i--);
+                PacketHandlerLogin netloginhandler = pendingConnections.get(i);
+                try
+                {
+                    netloginhandler.tryLogin();
+                }
+                catch(Exception exception)
+                {
+                    netloginhandler.kickUser("Internal server error");
+                    LOGGER.warn("Failed to handle packet: {}", exception, exception);
+                }
+                if(netloginhandler.finishedProcessing)
+                {
+                    pendingConnections.remove(i--);
+                }
+                netloginhandler.netManager.wakeThreads();
             }
-            netloginhandler.netManager.wakeThreads();
         }
 
         for(int j = 0; j < playerList.size(); j++)
diff --git a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java
index 71ce7fd58..630b4fbfd 100644
--- a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java
+++ b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java
@@ -143,7 +143,16 @@ public class PacketHandlerLogin extends PacketHandler
                         bufferedreader.close();
                         if(s1.equals("YES"))
                         {
-                            PacketHandlerLogin.setLoginPacket(this, packetLogin);
+                            // doing this in doLogin (as it used to)
+                            // froze the entire server for the duration of the request on every single login.
+                            UUID mojangUUID = UUIDHelper.getUUIDFromName(packetLogin.username);
+                            if (mojangUUID == null) {
+                                this.kickUser("Cannot authenticate UUID!");
+                            } else if (!mojangUUID.equals(packetLogin.uuid)) {
+                                this.kickUser("UUID mismatch!");
+                            } else {
+                                PacketHandlerLogin.setLoginPacket(this, packetLogin);
+                            }
                         } else
                         {
                             this.kickUser("Failed to verify username!");
@@ -161,17 +170,6 @@ public class PacketHandlerLogin extends PacketHandler
 
     public void doLogin(PacketLogin loginPacket)
     {
-        if (mcServer.onlineMode) {
-            UUID mojangUUID = UUIDHelper.getUUIDFromName(loginPacket.username);
-            if (mojangUUID == null) {
-                kickUser("Cannot authenticate UUID!");
-                return;
-            }
-            if (!mojangUUID.equals(loginPacket.uuid)) {
-                kickUser("UUID mismatch!");
-                return;
-            }
-        }
         PlayerServer player = mcServer.playerList.getPlayerForLogin(this, loginPacket.username, loginPacket.uuid);
         if (player != null)
         {
@@ -234,7 +232,7 @@ public class PacketHandlerLogin extends PacketHandler
             player.setupCraftingInventoryListener();
             if (MinecraftServer.statsStatus)
             {
-                RestHandler.post("https://api.betterthanadventure.net/stats?serverToken=" + MinecraftServer.statsToken + "&count=" + mcServer.playerList.playerEntities.size());
+                RestHandler.postAsync("https://api.betterthanadventure.net/stats?serverToken=" + MinecraftServer.statsToken + "&count=" + mcServer.playerList.playerEntities.size());
             }
             player.playerNetServerHandler.sendPacket(new PacketPhotoMode(mcServer.disablePhotoMode));
             player.playerNetServerHandler.sendPacket(new PacketGameRule(mcServer.getDimensionWorld(0).getLevelData().getGameRules()));
diff --git a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
index 72f6faebd..98061e04c 100644
--- a/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
+++ b/game/server/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
@@ -98,7 +98,7 @@ public class PacketHandlerServer extends PacketHandler
         this.mcServer.playerList.playerLoggedOut(this.playerEntity);
         this.connectionClosed = true;
         if (MinecraftServer.statsStatus) {
-            RestHandler.post("https://api.betterthanadventure.net/stats?serverToken=" + MinecraftServer.statsToken + "&count=" + this.mcServer.playerList.playerEntities.size());
+            RestHandler.postAsync("https://api.betterthanadventure.net/stats?serverToken=" + MinecraftServer.statsToken + "&count=" + this.mcServer.playerList.playerEntities.size());
         }
         PlayerListBox.updateList();
     }
@@ -131,14 +131,17 @@ public class PacketHandlerServer extends PacketHandler
         WorldServer worldserver = this.mcServer.getDimensionWorld(this.playerEntity.dimension);
 
         if (!this.hasMoved) {
-            double dx = packetMovePlayer.x - this.playerEntity.x;
-            double dy = packetMovePlayer.y - this.playerEntity.y;
-            double dz = packetMovePlayer.z - this.playerEntity.z;
-            if (dx * dx > 0.01D || dy * dy > 0.01D || dz * dz > 0.01D) {
-                this.hasMoved = true;
+            // Waiting for the client to acknowledge a teleport
+            if (packetMovePlayer.hasPosition) {
+                double dx = packetMovePlayer.x - this.lastPosX;
+                double dy = packetMovePlayer.y - this.lastPosY;
+                double dz = packetMovePlayer.z - this.lastPosZ;
+                if (dx * dx < 0.01D && dy * dy < 0.01D && dz * dz < 0.01D) {
+                    this.hasMoved = true;
+                }
             }
+            if (!this.hasMoved) return;
         }
-        if (!this.hasMoved) return;
         // Set rotation
         float yRot = this.playerEntity.yRot;
         float xRot = this.playerEntity.xRot;
@@ -462,7 +465,7 @@ public class PacketHandlerServer extends PacketHandler
         this.mcServer.playerList.playerLoggedOut(this.playerEntity);
         this.connectionClosed = true;
         if (MinecraftServer.statsStatus) {
-            RestHandler.post("https://api.betterthanadventure.net/stats?serverToken=" + MinecraftServer.statsToken + "&count=" + this.mcServer.playerList.playerEntities.size());
+            RestHandler.postAsync("https://api.betterthanadventure.net/stats?serverToken=" + MinecraftServer.statsToken + "&count=" + this.mcServer.playerList.playerEntities.size());
         }
         PlayerListBox.updateList();
     }
diff --git a/game/server/src/main/java/net/minecraft/server/player/PlayerManager.java b/game/server/src/main/java/net/minecraft/server/player/PlayerManager.java
index ebdc7e658..61e3ffb85 100644
--- a/game/server/src/main/java/net/minecraft/server/player/PlayerManager.java
+++ b/game/server/src/main/java/net/minecraft/server/player/PlayerManager.java
@@ -223,7 +223,6 @@ public class PlayerManager
             this.chunkX = chunkX;
             this.chunkZ = chunkZ;
             currentChunk = new ChunkCoordinate(chunkX, chunkZ);
-            server.getDimensionWorld(dimension).getChunkProvider().prepareChunk(chunkX, chunkZ);
         }
 
         public void addPlayer(PlayerServer player) {
diff --git a/game/server/src/main/java/net/minecraft/server/world/chunk/provider/ChunkProviderServer.java b/game/server/src/main/java/net/minecraft/server/world/chunk/provider/ChunkProviderServer.java
index 35941efe0..4e505a68a 100644
--- a/game/server/src/main/java/net/minecraft/server/world/chunk/provider/ChunkProviderServer.java
+++ b/game/server/src/main/java/net/minecraft/server/world/chunk/provider/ChunkProviderServer.java
@@ -1,6 +1,8 @@
 package net.minecraft.server.world.chunk.provider;
 
 import com.mojang.logging.LogUtils;
+
+import net.minecraft.core.Global;
 import net.minecraft.core.world.ProgressListener;
 import net.minecraft.core.world.chunk.provider.ChunkProvider;
 import net.minecraft.core.world.pos.ChunkPos;
@@ -47,6 +49,7 @@ public class ChunkProviderServer
     }
 
     public void dropChunk(@NotNull ChunkPos chunkPos) {
+        if (!this.chunkMap.containsKey(chunkPos)) {return;}
         TilePos spawnCoords = this.world.getSpawnPoint();
         int spawnDistanceX = (chunkPos.x * 16 + 8) - spawnCoords.x;
         int spawnDistanceZ = (chunkPos.z * 16 + 8) - spawnCoords.z;
@@ -162,7 +165,7 @@ public class ChunkProviderServer
         Chunk chunk = this.chunkMap.get(chunkPos);
         if (chunk == null) {
             if (this.decorating) {
-                if (!this.warnedRecursiveGeneration) {
+                if (Global.DEBUG_MODE && !this.warnedRecursiveGeneration) {
                     this.warnedRecursiveGeneration = true;
                     LOGGER.warn("Blocked recursive chunk generation at X:{}, Z:{} during decoration!", chunkPos.x(), chunkPos.z(), new Throwable("Stack trace"));
                 }
