diff --git a/src/main/java/net/minecraft/client/Minecraft.java b/src/main/java/net/minecraft/client/Minecraft.java
index 66e343920..ed22306f2 100644
--- a/src/main/java/net/minecraft/client/Minecraft.java
+++ b/src/main/java/net/minecraft/client/Minecraft.java
@@ -29,6 +29,36 @@ import net.minecraft.core.achievement.Achievements;
 import net.minecraft.core.block.BlockLeavesBase;
 import net.minecraft.core.block.entity.TileEntityDispatcher;
 import net.minecraft.core.entity.EntityDispatcher;
+import net.minecraft.core.net.command.CommandManager;
+import net.minecraft.core.net.command.commands.CommandAchievement;
+import net.minecraft.core.net.command.commands.CommandBiome;
+import net.minecraft.core.net.command.commands.CommandChunk;
+import net.minecraft.core.net.command.commands.CommandClear;
+import net.minecraft.core.net.command.commands.CommandClone;
+import net.minecraft.core.net.command.commands.CommandDamage;
+import net.minecraft.core.net.command.commands.CommandFill;
+import net.minecraft.core.net.command.commands.CommandGameMode;
+import net.minecraft.core.net.command.commands.CommandGameRule;
+import net.minecraft.core.net.command.commands.CommandGive;
+import net.minecraft.core.net.command.commands.CommandHeal;
+import net.minecraft.core.net.command.commands.CommandHelp;
+import net.minecraft.core.net.command.commands.CommandKill;
+import net.minecraft.core.net.command.commands.CommandMessage;
+import net.minecraft.core.net.command.commands.CommandMobSpawning;
+import net.minecraft.core.net.command.commands.CommandPlace;
+import net.minecraft.core.net.command.commands.CommandPlaySound;
+import net.minecraft.core.net.command.commands.CommandSay;
+import net.minecraft.core.net.command.commands.CommandSeed;
+import net.minecraft.core.net.command.commands.CommandSetBlock;
+import net.minecraft.core.net.command.commands.CommandSetSpawn;
+import net.minecraft.core.net.command.commands.CommandSpawn;
+import net.minecraft.core.net.command.commands.CommandSpawnParticle;
+import net.minecraft.core.net.command.commands.CommandSummon;
+import net.minecraft.core.net.command.commands.CommandTeleport;
+import net.minecraft.core.net.command.commands.CommandTellRaw;
+import net.minecraft.core.net.command.commands.CommandTestFor;
+import net.minecraft.core.net.command.commands.CommandTime;
+import net.minecraft.core.net.command.commands.CommandWeather;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.util.helper.DyeColor;
 import net.minecraft.core.util.helper.LoggedPrintStream;
@@ -397,6 +427,7 @@ public class Minecraft
         EntityDispatcher.init();
         TileEntityDispatcher.init();
         CommandHelper.init();
+        initCommands();
 
 		gameSettings = new GameSettings(this, mcDataDir);
 
@@ -598,6 +629,38 @@ public class Minecraft
         }
         gameWindow.updateWindowState();
     }
+
+    public void initCommands() {
+        CommandManager.registerCommand(new CommandAchievement());
+        CommandManager.registerCommand(new CommandClear());
+        CommandManager.registerCommand(new CommandKill());
+        CommandManager.registerCommand(new CommandSeed());
+        CommandManager.registerCommand(new CommandSetBlock());
+        CommandManager.registerCommand(new CommandSummon());
+        CommandManager.registerCommand(new CommandTeleport());
+        CommandManager.registerCommand(new CommandMessage());
+        CommandManager.registerCommand(new CommandSetSpawn());
+        CommandManager.registerCommand(new CommandTime());
+        CommandManager.registerCommand(new CommandGameMode());
+        CommandManager.registerCommand(new CommandWeather());
+        CommandManager.registerCommand(new CommandSpawn());
+        CommandManager.registerCommand(new CommandPlace());
+        CommandManager.registerCommand(new CommandHelp());
+        CommandManager.registerCommand(new CommandChunk());
+        CommandManager.registerCommand(new CommandGive());
+        CommandManager.registerCommand(new CommandGameRule());
+        CommandManager.registerCommand(new CommandFill());
+        CommandManager.registerCommand(new CommandClone());
+        CommandManager.registerCommand(new CommandBiome());
+        CommandManager.registerCommand(new CommandSay());
+        CommandManager.registerCommand(new CommandTellRaw());
+        CommandManager.registerCommand(new CommandTestFor());
+        CommandManager.registerCommand(new CommandDamage());
+        CommandManager.registerCommand(new CommandHeal());
+        CommandManager.registerCommand(new CommandMobSpawning());
+        CommandManager.registerCommand(new CommandPlaySound());
+        CommandManager.registerCommand(new CommandSpawnParticle());
+    }
     
     private void printWrongJavaVersionInfo() {
     	String javaVersion = System.getProperty("java.version");
diff --git a/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java b/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java
index 9e1fa0388..5f8093ad6 100644
--- a/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java
+++ b/src/main/java/net/minecraft/client/entity/player/PlayerLocal.java
@@ -37,6 +37,7 @@ import net.minecraft.core.block.entity.TileEntityTrommel;
 import net.minecraft.core.data.gamerule.GameRules;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.entity.vehicle.EntityBoat;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.client.net.command.ClientCommandSource;
@@ -515,4 +516,15 @@ public class PlayerLocal extends Player
 		mc.hudIngame.heldItemTooltipElement.setString(message);
 	}
 
+    @Override
+    public boolean lerpVehicleMotion() {
+        return false;
+    }
+
+    @Override
+    public void handleSpecialVehicleControl() {
+        if (vehicle instanceof EntityBoat) {
+            ((EntityBoat) vehicle).controlBoat(-input.moveForward, -input.moveStrafe);
+        }
+    }
 }
diff --git a/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java b/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
index 4eb0cad3a..cc674e2b1 100644
--- a/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
+++ b/src/main/java/net/minecraft/client/entity/player/PlayerLocalMultiplayer.java
@@ -7,6 +7,8 @@ import net.minecraft.core.achievement.stat.Stat;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityItem;
+import net.minecraft.core.entity.vehicle.EntityBoat;
+import net.minecraft.core.net.packet.BoatControlPacket;
 import net.minecraft.core.net.packet.ChatPacket;
 import net.minecraft.core.net.packet.UpdatePlayerStatePacket;
 import net.minecraft.core.net.packet.MovePlayerPacket;
@@ -274,4 +276,11 @@ public class PlayerLocalMultiplayer extends PlayerLocal
     public void pickBlock(int x, int y, int z) {
     	sendQueue.addToSendQueue(new PlayerActionPacket(PlayerActionPacket.ACTION_PICK_BLOCK, x, y, z, Side.NONE, 0.0, 0.0));
     }
+
+    @Override
+    public void sendSpecialVehiclePacket() {
+        if (vehicle instanceof EntityBoat) {
+            sendQueue.addToSendQueue(new BoatControlPacket((EntityBoat) vehicle));
+        }
+    }
 }
diff --git a/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java b/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java
index 424218f0e..6e3f2e650 100644
--- a/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java
+++ b/src/main/java/net/minecraft/client/net/command/ClientCommandSource.java
@@ -5,6 +5,7 @@ import net.minecraft.client.world.WorldClient;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.helpers.EntitySelector;
+import net.minecraft.core.net.packet.Packet;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.phys.Vec3;
 import net.minecraft.core.world.Dimension;
@@ -14,6 +15,7 @@ import org.jetbrains.annotations.NotNull;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.function.Supplier;
 
 public class ClientCommandSource implements CommandSource {
     private final Minecraft mc;
@@ -93,6 +95,11 @@ public class ClientCommandSource implements CommandSource {
         this.mc.thePlayer.sendChatMessage(message);
     }
 
+    @Override
+    public void sendPacketToAllPlayers(Supplier<Packet> packetSupplier) {
+
+    }
+
     @Override
     public World getWorld() {
         return this.mc.currentWorld;
diff --git a/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java b/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
index e731d560b..bd0ddce0e 100644
--- a/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
+++ b/src/main/java/net/minecraft/client/net/handler/PacketHandlerClient.java
@@ -38,6 +38,7 @@ import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.EntityPainting;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.entity.projectile.Projectile;
+import net.minecraft.core.entity.vehicle.EntityBoat;
 import net.minecraft.core.enums.ArtType;
 import net.minecraft.core.item.ItemMap;
 import net.minecraft.core.item.ItemStack;
@@ -589,6 +590,15 @@ public class PacketHandlerClient extends PacketHandler
         }
     }
 
+    @Override
+    public void handleBoatControl(BoatControlPacket boatControlPacket)
+    {
+        Entity e = worldClientMP.getEntityFromId(boatControlPacket.entityId);
+        if (e instanceof EntityBoat) {
+            ((EntityBoat)e).handleControlDirect(boatControlPacket.targetXD, boatControlPacket.targetZD, boatControlPacket.targetYRot);
+        }
+    }
+
     @Override
     public void handleSleep(SleepPacket sleepPacket)
     {
diff --git a/src/main/java/net/minecraft/core/entity/Entity.java b/src/main/java/net/minecraft/core/entity/Entity.java
index 9a4ebc534..2f436b111 100644
--- a/src/main/java/net/minecraft/core/entity/Entity.java
+++ b/src/main/java/net/minecraft/core/entity/Entity.java
@@ -43,8 +43,8 @@ public abstract class Entity
     public int id = entityCounter++;
     public double viewScale = 1.0D;
     public boolean blocksBuilding = false;
-    public Entity passenger;
-    public IVehicle vehicle;
+    public @Nullable Entity passenger;
+    public @Nullable IVehicle vehicle;
     public World world;
     public double xo;
     public double yo;
@@ -1502,6 +1502,23 @@ public abstract class Entity
         return (float) MathHelper.deltaAngle(xRot, xRotO);
     }
 
+    // TODO at some point create a better more generalized method of controlling vehicles
+    public boolean lerpVehicleMotion() {
+        return true;
+    }
+
+    public void handleSpecialVehicleControl() {
+
+    }
+
+    public void sendSpecialVehiclePacket() {
+
+    }
+
+    public boolean deferVehicleBehavior() {
+        return false;
+    }
+
     public static String getNameFromEntity(Entity entity, boolean useNickname){
         I18n translator = I18n.getInstance();
         if (entity instanceof Mob && useNickname){
diff --git a/src/main/java/net/minecraft/core/entity/player/Player.java b/src/main/java/net/minecraft/core/entity/player/Player.java
index f49e0c959..d9638f7a9 100644
--- a/src/main/java/net/minecraft/core/entity/player/Player.java
+++ b/src/main/java/net/minecraft/core/entity/player/Player.java
@@ -69,7 +69,6 @@ import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.world.chunk.provider.IChunkProvider;
 import net.minecraft.core.world.weather.Weathers;
-import net.minecraft.server.entity.player.PlayerServer;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
@@ -494,9 +493,9 @@ public abstract class Player extends Mob
         }
         if (entityKilledBy instanceof ProjectileArrowGolden)
         {
-            if (((ProjectileArrowGolden) entityKilledBy).owner instanceof PlayerServer)
+            if (((ProjectileArrowGolden) entityKilledBy).owner instanceof Player)
             {
-                if (((PlayerServer) ((ProjectileArrowGolden) entityKilledBy).owner).uuid.equals(uuid))
+                if (((Player) ((ProjectileArrowGolden) entityKilledBy).owner).uuid.equals(uuid))
                 {
                     return getDisplayName() + deathMsgColor + " got gold in their eye.";
                 }
@@ -514,9 +513,9 @@ public abstract class Player extends Mob
             {
                 return getDisplayName() + deathMsgColor + " was a victim of aimbot.";
             }
-            else if (((ProjectileArrow) entityKilledBy).owner instanceof PlayerServer)
+            else if (((ProjectileArrow) entityKilledBy).owner instanceof Player)
             {
-                if (((PlayerServer) ((ProjectileArrow) entityKilledBy).owner).uuid.equals(uuid))
+                if (((Player) ((ProjectileArrow) entityKilledBy).owner).uuid.equals(uuid))
                 {
                     return getDisplayName() + deathMsgColor + " lost a game of Russian roulette.";
                 }
@@ -530,9 +529,9 @@ public abstract class Player extends Mob
         }
         if (entityKilledBy instanceof ProjectileCannonball)
         {
-            if (((ProjectileCannonball) entityKilledBy).owner instanceof PlayerServer)
+            if (((ProjectileCannonball) entityKilledBy).owner instanceof Player)
             {
-                if (((PlayerServer) ((ProjectileCannonball) entityKilledBy).owner).uuid.equals(uuid))
+                if (((Player) ((ProjectileCannonball) entityKilledBy).owner).uuid.equals(uuid))
                 {
                     return getDisplayName() + deathMsgColor + " jumped too high.";
                 }
@@ -560,9 +559,9 @@ public abstract class Player extends Mob
         {
             return getDisplayName() + deathMsgColor + " was killed by Popbob.";
         }
-        if (entityKilledBy instanceof PlayerServer)
+        if (entityKilledBy instanceof Player)
         {
-            return getDisplayName() + deathMsgColor + " was backstabbed by " + ((PlayerServer) entityKilledBy).getDisplayName() + deathMsgColor + ".";
+            return getDisplayName() + deathMsgColor + " was backstabbed by " + ((Player) entityKilledBy).getDisplayName() + deathMsgColor + ".";
         }
         if (entityKilledBy instanceof MobPig)
         {
diff --git a/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java b/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java
index 041ef1fde..31e44a513 100644
--- a/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java
+++ b/src/main/java/net/minecraft/core/entity/vehicle/EntityBoat.java
@@ -1,8 +1,6 @@
 package net.minecraft.core.entity.vehicle;
 
 import com.mojang.nbt.CompoundTag;
-import net.minecraft.client.entity.player.PlayerLocalMultiplayer;
-import net.minecraft.client.entity.player.PlayerLocal;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.Blocks;
 import net.minecraft.core.block.entity.TileEntityFlag;
@@ -12,7 +10,6 @@ import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.Items;
 import net.minecraft.core.item.ItemStack;
-import net.minecraft.core.net.packet.BoatControlPacket;
 import net.minecraft.core.player.gamemode.Gamemode;
 import net.minecraft.core.util.helper.BlockParticleHelper;
 import net.minecraft.core.util.helper.DamageType;
@@ -20,7 +17,6 @@ import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.helper.Side;
 import net.minecraft.core.util.phys.AABB;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.player.PlayerServer;
 
 import java.util.List;
 
@@ -207,7 +203,7 @@ public class EntityBoat extends Entity
         boatPitch = xRot;
         lerpTicks = i;
         // Don't interpolate velocity from server when controlling the boat
-        if (passenger instanceof PlayerLocal) return;
+        if (passenger != null && !passenger.lerpVehicleMotion()) return;
         lerpYRot = yRot;
         xd = velocityX;
         yd = velocityY;
@@ -218,7 +214,7 @@ public class EntityBoat extends Entity
 	public void lerpMotion(double xd, double yd, double zd)
     {
         // Don't interpolate velocity from server when controlling the boat
-        if (passenger instanceof PlayerLocal) return;
+        if (passenger != null && !passenger.lerpVehicleMotion()) return;
         velocityX = this.xd = xd;
         velocityY = this.yd = yd;
         velocityZ = this.zd = zd;
@@ -260,7 +256,7 @@ public class EntityBoat extends Entity
                 double lerpY = y + (this.lerpY - y) / (double) lerpTicks;
                 double lerpZ = z + (this.lerpZ - z) / (double) lerpTicks;
                 xRot += (boatPitch - xRot) / lerpTicks;
-                if (!(passenger instanceof PlayerLocalMultiplayer)){
+                if (passenger == null || passenger.lerpVehicleMotion()){
                     float lerpYRot;
                     lerpYRot = MathHelper.normalizeRotation(this.lerpYRot - yRot);
                     yRot += lerpYRot / lerpTicks;
@@ -328,7 +324,7 @@ public class EntityBoat extends Entity
 
         }
 
-        if (!(passenger instanceof PlayerServer)){
+        if (passenger == null || !passenger.deferVehicleBehavior()){
             xd *= 0.99D;
             yd *= 0.95D;
             zd *= 0.99D;
@@ -383,10 +379,8 @@ public class EntityBoat extends Entity
         double xdOff;
         double zdOff;
         currentBoatSpeed = Math.hypot(xd, zd);
-        if(passenger != null && passenger instanceof PlayerLocal)
-        {
-            PlayerLocal sp = (PlayerLocal) passenger;
-            controlBoat(-sp.input.moveForward, -sp.input.moveStrafe);
+        if(passenger != null) {
+            passenger.handleSpecialVehicleControl();
         }
         yRot += pendingYRot;
         pendingYRot = 0;
@@ -406,8 +400,8 @@ public class EntityBoat extends Entity
         xd += xdOff;
         zd += zdOff;
 
-        if (passenger instanceof PlayerLocalMultiplayer){
-            ((PlayerLocalMultiplayer)passenger).sendQueue.addToSendQueue(new BoatControlPacket(this));
+        if(passenger != null) {
+            passenger.sendSpecialVehiclePacket();
         }
 
         // Cap max speed properly
diff --git a/src/main/java/net/minecraft/core/net/command/CommandManager.java b/src/main/java/net/minecraft/core/net/command/CommandManager.java
index 2047e2745..9b6699b7d 100644
--- a/src/main/java/net/minecraft/core/net/command/CommandManager.java
+++ b/src/main/java/net/minecraft/core/net/command/CommandManager.java
@@ -3,8 +3,6 @@ package net.minecraft.core.net.command;
 import com.mojang.brigadier.CommandDispatcher;
 import com.mojang.brigadier.ParseResults;
 import com.mojang.brigadier.exceptions.CommandSyntaxException;
-import net.minecraft.core.net.command.commands.*;
-import net.minecraft.server.net.command.commands.*;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
@@ -23,53 +21,7 @@ public class CommandManager {
     private static final Collection<CommandRegistry> externalServerCommands = new ArrayList<>();
 
     public void init() {
-        CommandAchievement.register(DISPATCHER);
-        CommandClear.register(DISPATCHER);
-        CommandKill.register(DISPATCHER);
-        CommandSeed.register(DISPATCHER);
-        CommandSetBlock.register(DISPATCHER);
-        CommandSummon.register(DISPATCHER);
-        CommandTeleport.register(DISPATCHER);
-        CommandMessage.register(DISPATCHER);
-        CommandSetSpawn.register(DISPATCHER);
-        CommandTime.register(DISPATCHER);
-        CommandGameMode.register(DISPATCHER);
-        CommandWeather.register(DISPATCHER);
-        CommandSpawn.register(DISPATCHER);
-        CommandPlace.register(DISPATCHER);
-        CommandHelp.register(DISPATCHER);
-        CommandChunk.register(DISPATCHER);
-        CommandGive.register(DISPATCHER);
-        CommandGameRule.register(DISPATCHER);
-        CommandFill.register(DISPATCHER);
-        CommandClone.register(DISPATCHER);
-        CommandBiome.register(DISPATCHER);
-        CommandSay.register(DISPATCHER);
-        CommandTellRaw.register(DISPATCHER);
-        CommandTestFor.register(DISPATCHER);
-        CommandDamage.register(DISPATCHER);
-        CommandHeal.register(DISPATCHER);
-        CommandMobSpawning.register(DISPATCHER);
-        CommandPlaySound.register(DISPATCHER);
-        CommandSpawnParticle.register(DISPATCHER);
-
         if (this.isServer) {
-            CommandStop.register(DISPATCHER);
-            CommandOp.register(DISPATCHER);
-            CommandDeop.register(DISPATCHER);
-            CommandList.register(DISPATCHER);
-            CommandDifficulty.register(DISPATCHER);
-            CommandColor.register(DISPATCHER);
-            CommandNickname.register(DISPATCHER);
-            CommandWhoIs.register(DISPATCHER);
-            CommandScore.register(DISPATCHER);
-            CommandMe.register(DISPATCHER);
-            CommandEmotes.register(DISPATCHER);
-            CommandBan.register(DISPATCHER);
-            CommandUnban.register(DISPATCHER);
-            CommandKick.register(DISPATCHER);
-            CommandWhitelist.register(DISPATCHER);
-            CommandSave.register(DISPATCHER);
             for (CommandRegistry registry : externalServerCommands) {
                 registry.register(DISPATCHER);
             }
diff --git a/src/main/java/net/minecraft/core/net/command/CommandSource.java b/src/main/java/net/minecraft/core/net/command/CommandSource.java
index 475eb99fb..32222cbcd 100644
--- a/src/main/java/net/minecraft/core/net/command/CommandSource.java
+++ b/src/main/java/net/minecraft/core/net/command/CommandSource.java
@@ -2,12 +2,14 @@ package net.minecraft.core.net.command;
 
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.packet.Packet;
 import net.minecraft.core.util.phys.Vec3;
 import net.minecraft.core.world.World;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.function.Supplier;
 
 public interface CommandSource {
     Collection<String> getPlayerNames();
@@ -47,6 +49,8 @@ public interface CommandSource {
 
     void sendMessageToAllPlayers(String message);
 
+    void sendPacketToAllPlayers(Supplier<Packet> packetSupplier);
+
     World getWorld();
 
     World getWorld(int dimension);
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandAchievement.java b/src/main/java/net/minecraft/core/net/command/commands/CommandAchievement.java
index 2da4734d6..4d390f75a 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandAchievement.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandAchievement.java
@@ -11,6 +11,7 @@ import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeAchievement;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
@@ -19,10 +20,10 @@ import net.minecraft.core.net.command.helpers.EntitySelector;
 import java.util.ArrayList;
 import java.util.List;
 
-public class CommandAchievement {
+public class CommandAchievement implements CommandManager.CommandRegistry {
     private static final SimpleCommandExceptionType PLAYER_ALREADY_HAS_ACHIEVEMENT = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.achievement.grant.exception_already_has_achievement"));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(((LiteralArgumentBuilder.<CommandSource>literal("achievement"))
             .requires(CommandSource::hasAdmin)
             .then((LiteralArgumentBuilder.<CommandSource>literal("grant"))
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandBiome.java b/src/main/java/net/minecraft/core/net/command/commands/CommandBiome.java
index 1d4f726ad..724ee22fc 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandBiome.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandBiome.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 import net.minecraft.core.data.registry.Registries;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.util.phys.Vec3;
 import net.minecraft.core.world.biome.Biome;
 import net.minecraft.core.net.command.CommandSource;
@@ -15,10 +16,10 @@ import net.minecraft.core.net.command.arguments.ArgumentTypeIntegerCoordinates;
 import net.minecraft.core.net.command.helpers.Coordinates2D;
 import net.minecraft.core.net.command.helpers.IntegerCoordinates;
 
-public class CommandBiome {
+public class CommandBiome implements CommandManager.CommandRegistry {
     private static final DynamicCommandExceptionType FAILURE = new DynamicCommandExceptionType(arg -> () -> I18n.getInstance().translateKeyAndFormat("command.commands.biome.locate.exception_failure", arg));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("biome")
                 .requires(CommandSource::hasAdmin)
                 .then(LiteralArgumentBuilder.<CommandSource>literal("get")
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandChunk.java b/src/main/java/net/minecraft/core/net/command/commands/CommandChunk.java
index ba6971aef..c71febbb6 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandChunk.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandChunk.java
@@ -4,14 +4,15 @@ import com.mojang.brigadier.Command;
 import com.mojang.brigadier.CommandDispatcher;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeChunkCoordinates;
 import net.minecraft.core.net.command.helpers.Coordinates2D;
 import net.minecraft.core.world.LevelListener;
 import net.minecraft.core.world.World;
 
-public class CommandChunk {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandChunk implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("chunk")
             .requires(CommandSource::hasAdmin)
             .then(LiteralArgumentBuilder.<CommandSource>literal("reset")
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandClear.java b/src/main/java/net/minecraft/core/net/command/commands/CommandClear.java
index 8c22343ce..1ef4da227 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandClear.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandClear.java
@@ -11,6 +11,7 @@ import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
 import net.minecraft.core.net.command.arguments.ArgumentTypeItemStack;
@@ -23,12 +24,12 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
-public class CommandClear {
+public class CommandClear implements CommandManager.CommandRegistry {
     private static final Logger LOGGER = LogUtils.getLogger();
 
     private static final SimpleCommandExceptionType FAILURE = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.clear.exception_failure"));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("clear")
             .requires(CommandSource::hasAdmin)
             .executes(c -> {
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandClone.java b/src/main/java/net/minecraft/core/net/command/commands/CommandClone.java
index 8c3138a4e..b46e3ea43 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandClone.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandClone.java
@@ -10,6 +10,7 @@ import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 import com.mojang.nbt.CompoundTag;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.util.phys.AABB;
 import net.minecraft.core.util.phys.Vec3;
@@ -28,13 +29,13 @@ import org.jetbrains.annotations.Nullable;
 import java.util.HashMap;
 import java.util.Map;
 
-public class CommandClone {
+public class CommandClone implements CommandManager.CommandRegistry {
     private static final SimpleCommandExceptionType INSIDE_CLONED_AREA = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.clone.exception_inside_cloned_area"));
     private static final SimpleCommandExceptionType DESTINATION_NOT_LOADED = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.clone.exception_destination_not_loaded"));
     private static final SimpleCommandExceptionType SOURCE_NOT_LOADED = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.clone.exception_source_not_loaded"));
     private static final SimpleCommandExceptionType NOWHERE_LOADED = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.clone.exception_nowhere_loaded"));
 
-    public static void register(CommandDispatcher<CommandSource> commandDispatcher) {
+    public void register(CommandDispatcher<CommandSource> commandDispatcher) {
         commandDispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("clone")
                 .requires(CommandSource::hasAdmin)
                 .then(beginEndDestinationAndModeSuffix(c -> {
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandDamage.java b/src/main/java/net/minecraft/core/net/command/commands/CommandDamage.java
index 2c0c70802..5cc8b2e89 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandDamage.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandDamage.java
@@ -5,6 +5,7 @@ import com.mojang.brigadier.arguments.IntegerArgumentType;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import net.minecraft.core.entity.Entity;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.util.helper.DamageType;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeDamageType;
@@ -13,8 +14,8 @@ import net.minecraft.core.net.command.helpers.EntitySelector;
 
 import java.util.List;
 
-public class CommandDamage {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandDamage implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("damage")
                 .requires(CommandSource::hasAdmin)
                 .then(RequiredArgumentBuilder.<CommandSource, EntitySelector>argument("entities", ArgumentTypeEntity.entities())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandFill.java b/src/main/java/net/minecraft/core/net/command/commands/CommandFill.java
index c61e6c494..eff487e24 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandFill.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandFill.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import com.mojang.nbt.CompoundTag;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.enums.EnumDropCause;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeBlock;
 import net.minecraft.core.net.command.arguments.ArgumentTypeIntegerCoordinates;
@@ -17,8 +18,8 @@ import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.world.World;
 import org.jetbrains.annotations.Nullable;
 
-public class CommandFill {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandFill implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("fill")
             .requires(CommandSource::hasAdmin)
             .then(RequiredArgumentBuilder.<CommandSource, IntegerCoordinates>argument("first", ArgumentTypeIntegerCoordinates.intCoordinates())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandGameMode.java b/src/main/java/net/minecraft/core/net/command/commands/CommandGameMode.java
index 5a2aae16d..36f9f5676 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandGameMode.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandGameMode.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
 import net.minecraft.core.net.command.arguments.ArgumentTypeGameMode;
@@ -17,8 +18,8 @@ import net.minecraft.core.player.gamemode.Gamemode;
 
 import java.util.List;
 
-public class CommandGameMode {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandGameMode implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("gamemode")
             .requires(CommandSource::hasAdmin)
             .then(RequiredArgumentBuilder.<CommandSource, Gamemode>argument("gamemode", ArgumentTypeGameMode.gameMode())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandGameRule.java b/src/main/java/net/minecraft/core/net/command/commands/CommandGameRule.java
index f396d100d..32a9f58f0 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandGameRule.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandGameRule.java
@@ -9,23 +9,21 @@ import com.mojang.brigadier.tree.CommandNode;
 import net.minecraft.core.data.gamerule.GameRule;
 import net.minecraft.core.data.gamerule.GameRuleBoolean;
 import net.minecraft.core.data.registry.Registries;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeGameruleGeneric;
 import net.minecraft.core.net.packet.GameRulePacket;
-import net.minecraft.server.net.command.ServerCommandSource;
 
-public class CommandGameRule {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandGameRule implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         final LiteralArgumentBuilder<CommandSource> argumentBuilder = LiteralArgumentBuilder.<CommandSource>literal("gamerule").requires(CommandSource::hasAdmin);
         for (final GameRule<?> gameRule : Registries.GAME_RULES) {
             RequiredArgumentBuilder<CommandSource, ?> gameRuleValueArgument;
             if (gameRule instanceof GameRuleBoolean) {
                 gameRuleValueArgument = RequiredArgumentBuilder.<CommandSource, Boolean>argument("value", BoolArgumentType.bool())
                         .executes(c -> {
-                            c.getSource().getWorld().getLevelData().getGameRules().setValue((GameRule<? super Object>) gameRule, BoolArgumentType.getBool(c, "value"));
-                            if (c.getSource() instanceof ServerCommandSource) {
-                                ((ServerCommandSource)c.getSource()).server.playerList.sendPacketToAllPlayers(new GameRulePacket(c.getSource().getWorld().getLevelData().getGameRules()));
-                            }
+                            c.getSource().getWorld().getLevelData().getGameRules().setValue((GameRuleBoolean) gameRule, BoolArgumentType.getBool(c, "value"));
+                            c.getSource().sendPacketToAllPlayers(() -> new GameRulePacket(c.getSource().getWorld().getLevelData().getGameRules()));
                             c.getSource().sendTranslatableMessage("command.commands.gamerule.set", gameRule.getKey(), BoolArgumentType.getBool(c, "value"));
                             return Command.SINGLE_SUCCESS;
                         });
@@ -33,10 +31,8 @@ public class CommandGameRule {
                 gameRuleValueArgument = RequiredArgumentBuilder.<CommandSource, Object>argument("value", ArgumentTypeGameruleGeneric.gameRule(gameRule))
                         .executes(c -> {
                             Object o = c.getArgument("value", Object.class);
-                            c.getSource().getWorld().getLevelData().getGameRules().setValue((GameRule<? super Object>) gameRule, o);
-                            if (c.getSource() instanceof ServerCommandSource) {
-                                ((ServerCommandSource)c.getSource()).server.playerList.sendPacketToAllPlayers(new GameRulePacket(c.getSource().getWorld().getLevelData().getGameRules()));
-                            }
+                            c.getSource().getWorld().getLevelData().getGameRules().setValue((GameRule) gameRule, o);
+                            c.getSource().sendPacketToAllPlayers(() -> new GameRulePacket(c.getSource().getWorld().getLevelData().getGameRules()));
                             c.getSource().sendTranslatableMessage("command.commands.gamerule.set", gameRule.getKey(), o);
                             return Command.SINGLE_SUCCESS;
                         });
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandGive.java b/src/main/java/net/minecraft/core/net/command/commands/CommandGive.java
index 36ded5a31..d924ab645 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandGive.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandGive.java
@@ -8,6 +8,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
@@ -16,8 +17,8 @@ import net.minecraft.core.net.command.helpers.EntitySelector;
 
 import java.util.List;
 
-public class CommandGive {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandGive implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("give")
                 .requires(CommandSource::hasAdmin)
                 .then(RequiredArgumentBuilder.<CommandSource, EntitySelector>argument("target", ArgumentTypeEntity.players())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandHeal.java b/src/main/java/net/minecraft/core/net/command/commands/CommandHeal.java
index cbcf96366..917fc4b15 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandHeal.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandHeal.java
@@ -6,6 +6,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.Mob;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
 import net.minecraft.core.net.command.CommandSource;
@@ -15,8 +16,8 @@ import net.minecraft.core.net.command.helpers.EntitySelector;
 import java.lang.reflect.InvocationTargetException;
 import java.util.List;
 
-public class CommandHeal {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandHeal implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("heal")
                 .requires(CommandSource::hasAdmin)
                 .then(RequiredArgumentBuilder.<CommandSource, EntitySelector>argument("entities", ArgumentTypeEntity.entities())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandHelp.java b/src/main/java/net/minecraft/core/net/command/commands/CommandHelp.java
index 57a9aa602..bb5d4c20e 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandHelp.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandHelp.java
@@ -8,15 +8,16 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 import com.mojang.brigadier.tree.CommandNode;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.util.Iterables;
 
 import java.util.Map;
 
-public class CommandHelp {
+public class CommandHelp implements CommandManager.CommandRegistry {
     private static final SimpleCommandExceptionType FAILURE = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.help.exception_failure"));
 
-    public static void register(CommandDispatcher<CommandSource> commandDispatcher) {
+    public void register(CommandDispatcher<CommandSource> commandDispatcher) {
         commandDispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("help")
             .executes(c -> {
                 CommandSource source = c.getSource();
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandKill.java b/src/main/java/net/minecraft/core/net/command/commands/CommandKill.java
index 96c353d82..7b04917c5 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandKill.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandKill.java
@@ -9,6 +9,7 @@ import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
@@ -17,10 +18,10 @@ import net.minecraft.core.net.command.helpers.EntitySelector;
 
 import java.util.concurrent.CopyOnWriteArrayList;
 
-public class CommandKill {
+public class CommandKill implements CommandManager.CommandRegistry {
     private static final SimpleCommandExceptionType FAILURE = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.kill.exception_failure"));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("kill")
                 .requires(CommandSource::hasAdmin)
                 .executes(c -> {
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandMessage.java b/src/main/java/net/minecraft/core/net/command/commands/CommandMessage.java
index 04aaea7c3..c7ce6318d 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandMessage.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandMessage.java
@@ -9,6 +9,7 @@ import com.mojang.brigadier.tree.CommandNode;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
@@ -17,8 +18,8 @@ import net.minecraft.core.util.helper.LoggedPrintStream;
 
 import java.util.List;
 
-public class CommandMessage {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandMessage implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         CommandNode<CommandSource> command = dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("message")
                 .then(RequiredArgumentBuilder.<CommandSource, EntitySelector>argument("targets", ArgumentTypeEntity.players())
                         .then(RequiredArgumentBuilder.<CommandSource, String>argument("message", StringArgumentType.greedyString())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandMobSpawning.java b/src/main/java/net/minecraft/core/net/command/commands/CommandMobSpawning.java
index bed9bfc2b..85fcf50b8 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandMobSpawning.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandMobSpawning.java
@@ -9,6 +9,7 @@ import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityDispatcher;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntitySummon;
 import net.minecraft.core.util.collection.NamespaceID;
@@ -17,11 +18,11 @@ import net.minecraft.core.world.config.spawning.SpawnerConfig;
 
 import java.util.Collection;
 
-public class CommandMobSpawning {
+public class CommandMobSpawning implements CommandManager.CommandRegistry {
     private static final DynamicCommandExceptionType FAILURE =
         new DynamicCommandExceptionType(arg -> () -> I18n.getInstance().translateKeyAndFormat("command.commands.mobspawning.exception_failure", arg));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register
             (
                 LiteralArgumentBuilder.<CommandSource>literal("mobspawning")
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandPlace.java b/src/main/java/net/minecraft/core/net/command/commands/CommandPlace.java
index b2cd4b023..8548bf1b3 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandPlace.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandPlace.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 import com.mojang.brigadier.tree.CommandNode;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.world.LevelListener;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.generate.feature.WorldFeature;
@@ -16,10 +17,10 @@ import net.minecraft.core.net.command.arguments.ArgumentTypeWorldFeature;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 import net.minecraft.core.net.command.helpers.IntegerCoordinates;
 
-public class CommandPlace {
+public class CommandPlace implements CommandManager.CommandRegistry {
     private static final SimpleCommandExceptionType FAILURE = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.place.exception_failure"));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         CommandNode<CommandSource> command = dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("place")
                 .requires(CommandSource::hasAdmin)
                 .then(RequiredArgumentBuilder.<CommandSource, WorldFeature>argument("feature", ArgumentTypeWorldFeature.worldFeature())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandPlaySound.java b/src/main/java/net/minecraft/core/net/command/commands/CommandPlaySound.java
index 4b75031bd..8b79636a6 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandPlaySound.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandPlaySound.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
 import net.minecraft.core.net.command.arguments.ArgumentTypeSoundCategory;
@@ -20,8 +21,8 @@ import net.minecraft.core.world.World;
 
 import java.util.List;
 
-public class CommandPlaySound {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandPlaySound implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register
             (
                 LiteralArgumentBuilder.<CommandSource>literal("playsound")
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandSay.java b/src/main/java/net/minecraft/core/net/command/commands/CommandSay.java
index 43be12bb8..0a24af6dd 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandSay.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandSay.java
@@ -5,10 +5,11 @@ import com.mojang.brigadier.CommandDispatcher;
 import com.mojang.brigadier.arguments.StringArgumentType;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 
-public class CommandSay {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandSay implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("say")
                 .requires(CommandSource::hasAdmin)
                 .then(RequiredArgumentBuilder.<CommandSource, String>argument("message", StringArgumentType.greedyString())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandSeed.java b/src/main/java/net/minecraft/core/net/command/commands/CommandSeed.java
index ee350fbf6..518c295f1 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandSeed.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandSeed.java
@@ -3,10 +3,11 @@ package net.minecraft.core.net.command.commands;
 import com.mojang.brigadier.Command;
 import com.mojang.brigadier.CommandDispatcher;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 
-public class CommandSeed {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandSeed implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("seed")
                 .requires(CommandSource::hasAdmin)
                 .executes(c -> {
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandSetBlock.java b/src/main/java/net/minecraft/core/net/command/commands/CommandSetBlock.java
index 82bdd8af0..45323a052 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandSetBlock.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandSetBlock.java
@@ -6,6 +6,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.world.World;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.net.command.CommandSource;
@@ -13,10 +14,10 @@ import net.minecraft.core.net.command.arguments.*;
 import net.minecraft.core.net.command.helpers.BlockInput;
 import net.minecraft.core.net.command.helpers.IntegerCoordinates;
 
-public class CommandSetBlock {
+public class CommandSetBlock implements CommandManager.CommandRegistry {
     private static final SimpleCommandExceptionType FAILURE = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.setblock.exception_failure"));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("setblock")
                 .requires(CommandSource::hasAdmin)
                 .then(RequiredArgumentBuilder.<CommandSource, IntegerCoordinates>argument("position", ArgumentTypeIntegerCoordinates.intCoordinates())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandSetSpawn.java b/src/main/java/net/minecraft/core/net/command/commands/CommandSetSpawn.java
index f23f98ea5..7bdb6cf02 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandSetSpawn.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandSetSpawn.java
@@ -5,13 +5,14 @@ import com.mojang.brigadier.CommandDispatcher;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.tree.CommandNode;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeIntegerCoordinates;
 import net.minecraft.core.net.command.helpers.IntegerCoordinates;
 
-public class CommandSetSpawn {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandSetSpawn implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         CommandNode<CommandSource> command = dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("setworldspawn")
                 .requires(CommandSource::hasAdmin)
                 .then(RequiredArgumentBuilder.<CommandSource, IntegerCoordinates>argument("position", ArgumentTypeIntegerCoordinates.intCoordinates())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandSpawn.java b/src/main/java/net/minecraft/core/net/command/commands/CommandSpawn.java
index e89488580..76b0d2754 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandSpawn.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandSpawn.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
@@ -17,8 +18,8 @@ import net.minecraft.core.net.command.helpers.EntitySelector;
 
 import java.util.List;
 
-public class CommandSpawn {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandSpawn implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("spawn")
                 .requires(CommandSource::hasAdmin)
                 .executes(c -> {
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandSpawnParticle.java b/src/main/java/net/minecraft/core/net/command/commands/CommandSpawnParticle.java
index 6010c839b..49f5ca96a 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandSpawnParticle.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandSpawnParticle.java
@@ -8,6 +8,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
 import net.minecraft.core.net.command.arguments.ArgumentTypeParticleId;
@@ -18,8 +19,8 @@ import org.jetbrains.annotations.Nullable;
 
 import java.util.List;
 
-public class CommandSpawnParticle {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandSpawnParticle implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register
             (
                 LiteralArgumentBuilder.<CommandSource>literal("spawnparticle")
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandSummon.java b/src/main/java/net/minecraft/core/net/command/commands/CommandSummon.java
index a2bfccb53..3c8607b28 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandSummon.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandSummon.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.context.CommandContext;
 import net.minecraft.core.entity.Entity;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.util.phys.Vec3;
 import net.minecraft.core.world.World;
 import net.minecraft.core.net.command.util.CommandHelper;
@@ -16,8 +17,8 @@ import net.minecraft.core.net.command.arguments.ArgumentTypeVec3;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 import net.minecraft.core.net.command.helpers.DoubleCoordinates;
 
-public class CommandSummon {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandSummon implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("summon")
                 .requires(CommandSource::hasAdmin)
                 .then(RequiredArgumentBuilder.<CommandSource, Class<? extends Entity>>argument("entity", ArgumentTypeEntitySummon.entity())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandTeleport.java b/src/main/java/net/minecraft/core/net/command/commands/CommandTeleport.java
index 6105e7c01..4d9198b55 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandTeleport.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandTeleport.java
@@ -6,6 +6,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.tree.CommandNode;
 import net.minecraft.core.entity.Entity;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
@@ -16,8 +17,8 @@ import net.minecraft.core.net.command.helpers.EntitySelector;
 
 import java.util.List;
 
-public class CommandTeleport {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandTeleport implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         CommandNode<CommandSource> command = dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("teleport")
                 .requires(CommandSource::hasAdmin)
                 .then(RequiredArgumentBuilder.<CommandSource, DoubleCoordinates>argument("position", ArgumentTypeVec3.vec3d())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandTellRaw.java b/src/main/java/net/minecraft/core/net/command/commands/CommandTellRaw.java
index a1c6e7c1e..008050db4 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandTellRaw.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandTellRaw.java
@@ -7,14 +7,15 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
 import net.minecraft.core.net.command.helpers.EntitySelector;
 
 import java.util.List;
 
-public class CommandTellRaw {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandTellRaw implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("tellraw")
                 .requires(CommandSource::hasAdmin)
                 .then(RequiredArgumentBuilder.<CommandSource, EntitySelector>argument("targets", ArgumentTypeEntity.players())
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandTest.java b/src/main/java/net/minecraft/core/net/command/commands/CommandTest.java
deleted file mode 100644
index 452973f3f..000000000
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.minecraft.core.net.command.commands;
-
-import com.mojang.brigadier.Command;
-import com.mojang.brigadier.CommandDispatcher;
-import com.mojang.brigadier.builder.LiteralArgumentBuilder;
-import com.mojang.brigadier.builder.RequiredArgumentBuilder;
-import net.minecraft.core.net.command.CommandSource;
-import net.minecraft.core.net.command.arguments.ArgumentTypeAchievement;
-
-@SuppressWarnings("unchecked")
-public class CommandTest {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
-        dispatcher.register((LiteralArgumentBuilder)(((LiteralArgumentBuilder)LiteralArgumentBuilder.literal("test"))
-                .then(((LiteralArgumentBuilder)LiteralArgumentBuilder.<CommandSource>literal("grant")
-                ).then(RequiredArgumentBuilder.argument("achievement", ArgumentTypeAchievement.achievement())
-                        .then(RequiredArgumentBuilder.argument("achievement1", ArgumentTypeAchievement.achievement())
-                                .then(RequiredArgumentBuilder.argument("achievement2", ArgumentTypeAchievement.achievement())
-                                        .then(RequiredArgumentBuilder.argument("achievement3", ArgumentTypeAchievement.achievement())
-                                                .then(RequiredArgumentBuilder.argument("achievement4", ArgumentTypeAchievement.achievement())
-                                                        .then(RequiredArgumentBuilder.argument("achievement5", ArgumentTypeAchievement.achievement())
-                                                                .executes(c -> {
-                                                                    ((CommandSource)c.getSource()).getSender().sendMessage("Command run!");
-                                                                    return Command.SINGLE_SUCCESS;
-                                                                }))))))))));
-    }
-}
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandTestFor.java b/src/main/java/net/minecraft/core/net/command/commands/CommandTestFor.java
index caf9cc437..3dc79c20d 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandTestFor.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandTestFor.java
@@ -8,6 +8,7 @@ import com.mojang.nbt.CompoundTag;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.block.entity.TileEntity;
 import net.minecraft.core.entity.Entity;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeBlock;
@@ -17,8 +18,8 @@ import net.minecraft.core.net.command.helpers.*;
 
 import java.util.List;
 
-public class CommandTestFor {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandTestFor implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("testfor")
                 .requires(CommandSource::hasAdmin)
                 .then(LiteralArgumentBuilder.<CommandSource>literal("entity")
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandTime.java b/src/main/java/net/minecraft/core/net/command/commands/CommandTime.java
index e90207fd4..739e7e1c3 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandTime.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandTime.java
@@ -6,6 +6,7 @@ import com.mojang.brigadier.arguments.IntegerArgumentType;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import net.minecraft.core.Global;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.arguments.ArgumentTypeSeason;
 import net.minecraft.core.world.LevelListener;
 import net.minecraft.core.world.World;
@@ -15,8 +16,8 @@ import net.minecraft.core.world.season.Season;
 import net.minecraft.core.world.season.SeasonManagerCycle;
 import net.minecraft.core.world.season.Seasons;
 
-public class CommandTime {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandTime implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("time")
             .requires(CommandSource::hasAdmin)
             .then(LiteralArgumentBuilder.<CommandSource>literal("query")
diff --git a/src/main/java/net/minecraft/core/net/command/commands/CommandWeather.java b/src/main/java/net/minecraft/core/net/command/commands/CommandWeather.java
index 7c9717e24..8cb4e8ce2 100644
--- a/src/main/java/net/minecraft/core/net/command/commands/CommandWeather.java
+++ b/src/main/java/net/minecraft/core/net/command/commands/CommandWeather.java
@@ -6,6 +6,7 @@ import com.mojang.brigadier.arguments.FloatArgumentType;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.tree.CommandNode;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.world.World;
 import net.minecraft.core.world.weather.Weather;
 import net.minecraft.core.net.command.CommandSource;
@@ -13,8 +14,8 @@ import net.minecraft.core.net.command.arguments.ArgumentTypeTime;
 import net.minecraft.core.net.command.arguments.ArgumentTypeWeather;
 import net.minecraft.core.world.weather.Weathers;
 
-public class CommandWeather {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandWeather implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         CommandNode<CommandSource> command = dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("weather")
                 .requires(CommandSource::hasAdmin)
                 .then(LiteralArgumentBuilder.<CommandSource>literal("clear")
diff --git a/src/main/java/net/minecraft/core/net/entity/EntityTracker.java b/src/main/java/net/minecraft/core/net/entity/EntityTracker.java
new file mode 100644
index 000000000..7fd97ecad
--- /dev/null
+++ b/src/main/java/net/minecraft/core/net/entity/EntityTracker.java
@@ -0,0 +1,25 @@
+package net.minecraft.core.net.entity;
+
+import net.minecraft.core.entity.Entity;
+import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.net.packet.Packet;
+
+import java.util.Set;
+
+public interface EntityTracker {
+    void trackEntity(Entity entity);
+
+    EntityTrackerEntry trackEntity(Entity entity, int trackingDistance, int packetDelay, boolean shouldSendMotionUpdates);
+
+    void untrackEntity(Entity entity);
+
+    void tick();
+
+    void sendPacketToTrackedPlayers(Entity entity, Packet packet);
+
+    void sendPacketToTrackedPlayersAndTrackedEntity(Entity entity, Packet packet);
+
+    void removeTrackedPlayerSymmetric(Player player);
+
+    Set<? extends EntityTrackerEntry> getTrackedEntries();
+}
diff --git a/src/main/java/net/minecraft/core/net/entity/EntityTrackerEntry.java b/src/main/java/net/minecraft/core/net/entity/EntityTrackerEntry.java
new file mode 100644
index 000000000..5d6db1b59
--- /dev/null
+++ b/src/main/java/net/minecraft/core/net/entity/EntityTrackerEntry.java
@@ -0,0 +1,27 @@
+package net.minecraft.core.net.entity;
+
+import net.minecraft.core.entity.Entity;
+import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.net.packet.Packet;
+
+import java.util.List;
+
+public interface EntityTrackerEntry {
+
+    void tick(List<Player> list);
+
+    void sendPacketToTrackedPlayers(Packet packet);
+
+    void sendPacketToTrackedPlayersAndTrackedEntity(Packet packet);
+
+    void sendDestroyEntityPacketToTrackedPlayers();
+
+    void removeFromTrackedPlayers(Player player);
+
+    void updatePlayerEntity(Player player);
+
+    void updatePlayerEntities(List<Player> list);
+    void removeTrackedPlayerSymmetric(Player playerServer);
+
+    Entity getTrackedEntity();
+}
diff --git a/src/main/java/net/minecraft/core/net/entity/IPacketEntry.java b/src/main/java/net/minecraft/core/net/entity/IPacketEntry.java
index 71870482e..08c0645b0 100644
--- a/src/main/java/net/minecraft/core/net/entity/IPacketEntry.java
+++ b/src/main/java/net/minecraft/core/net/entity/IPacketEntry.java
@@ -1,7 +1,6 @@
 package net.minecraft.core.net.entity;
 
 import net.minecraft.core.net.packet.Packet;
-import net.minecraft.server.entity.EntityTrackerEntry;
 
 public interface IPacketEntry<T> extends INetworkEntry<T> {
     Packet getSpawnPacket(EntityTrackerEntry tracker, T trackedObject);
diff --git a/src/main/java/net/minecraft/core/net/entity/ITrackedEntry.java b/src/main/java/net/minecraft/core/net/entity/ITrackedEntry.java
index 31786c2ec..974bbc7bd 100644
--- a/src/main/java/net/minecraft/core/net/entity/ITrackedEntry.java
+++ b/src/main/java/net/minecraft/core/net/entity/ITrackedEntry.java
@@ -1,8 +1,5 @@
 package net.minecraft.core.net.entity;
 
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
-
 public interface ITrackedEntry<T> extends INetworkEntry<T> {
     int getTrackingDistance();
     int getPacketDelay();
diff --git a/src/main/java/net/minecraft/core/net/entity/IVehicleEntry.java b/src/main/java/net/minecraft/core/net/entity/IVehicleEntry.java
index f2aa675a9..cd2233e27 100644
--- a/src/main/java/net/minecraft/core/net/entity/IVehicleEntry.java
+++ b/src/main/java/net/minecraft/core/net/entity/IVehicleEntry.java
@@ -3,7 +3,6 @@ package net.minecraft.core.net.entity;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTrackerEntry;
 
 public interface IVehicleEntry<T> extends IPacketEntry<T> {
     Entity getEntity(World world, double x, double y, double z, int metadata, boolean hasVelocity, double xd, double yd, double zd, Entity owner);
diff --git a/src/main/java/net/minecraft/core/net/entity/NetEntityHandler.java b/src/main/java/net/minecraft/core/net/entity/NetEntityHandler.java
index d087fd79f..de6868f89 100644
--- a/src/main/java/net/minecraft/core/net/entity/NetEntityHandler.java
+++ b/src/main/java/net/minecraft/core/net/entity/NetEntityHandler.java
@@ -18,7 +18,6 @@ import net.minecraft.core.net.entity.entries.NetEntrySnowball;
 import net.minecraft.core.net.entity.entries.NetEntrySquid;
 import net.minecraft.core.net.entity.entries.NetEntryPrimedTNT;
 import net.minecraft.core.net.packet.Packet;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
@@ -81,17 +80,17 @@ public class NetEntityHandler {
             sortEntries();
         }
         for (IPacketEntry netEnt : packetEntries){
-            if (netEnt.getAppliedClass().isAssignableFrom(trackerEntry.trackedEntity.getClass())){
+            if (netEnt.getAppliedClass().isAssignableFrom(trackerEntry.getTrackedEntity().getClass())){
                 Packet packet;
                 if (netEnt instanceof IVehicleEntry){
-                    packet = ((IVehicleEntry)netEnt).getSpawnPacket(trackerEntry, trackerEntry.trackedEntity).setType(providerToTypeMap.get(netEnt));
+                    packet = ((IVehicleEntry)netEnt).getSpawnPacket(trackerEntry, trackerEntry.getTrackedEntity()).setType(providerToTypeMap.get(netEnt));
                 } else {
-                    packet = netEnt.getSpawnPacket(trackerEntry, trackerEntry.trackedEntity);
+                    packet = netEnt.getSpawnPacket(trackerEntry, trackerEntry.getTrackedEntity());
                 }
                 return packet;
             }
         }
-        throw new IllegalArgumentException("Don't know how to add " + trackerEntry.trackedEntity.getClass() + "!");
+        throw new IllegalArgumentException("Don't know how to add " + trackerEntry.getTrackedEntity().getClass() + "!");
     }
     @SuppressWarnings("unchecked")
     public static <T> ITrackedEntry<T> getTrackedEntry(T entity){
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryAnimal.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryAnimal.java
index 06ec1769f..1c064a456 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryAnimal.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryAnimal.java
@@ -2,12 +2,12 @@ package net.minecraft.core.net.entity.entries;
 
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.animal.Creature;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.IPacketEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.packet.Packet;
 import net.minecraft.core.net.packet.AddMobPacket;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryAnimal<T extends Creature> implements IPacketEntry<T>, ITrackedEntry<T> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryArrow.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryArrow.java
index 3cc67a47d..0041b8f0a 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryArrow.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryArrow.java
@@ -5,12 +5,12 @@ import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.projectile.ProjectileArrow;
 import net.minecraft.core.entity.projectile.ProjectileArrowGolden;
 import net.minecraft.core.entity.projectile.ProjectileArrowPurple;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryArrow implements IVehicleEntry<ProjectileArrow>, ITrackedEntry<ProjectileArrow> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryBoat.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryBoat.java
index a26eb2cab..3d0d78d16 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryBoat.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryBoat.java
@@ -2,12 +2,12 @@ package net.minecraft.core.net.entity.entries;
 
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.vehicle.EntityBoat;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryBoat implements IVehicleEntry<EntityBoat>, ITrackedEntry<EntityBoat> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryBobber.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryBobber.java
index 753663735..66e5cb57f 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryBobber.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryBobber.java
@@ -3,12 +3,12 @@ package net.minecraft.core.net.entity.entries;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityFishingBobber;
 import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryBobber implements IVehicleEntry<EntityFishingBobber>, ITrackedEntry<EntityFishingBobber> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryCannonball.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryCannonball.java
index fa46e44e6..7332554d1 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryCannonball.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryCannonball.java
@@ -3,12 +3,12 @@ package net.minecraft.core.net.entity.entries;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.projectile.ProjectileCannonball;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryCannonball implements IVehicleEntry<ProjectileCannonball>, ITrackedEntry<ProjectileCannonball> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryEgg.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryEgg.java
index 27a5459b9..4ad2a3e4f 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryEgg.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryEgg.java
@@ -2,12 +2,12 @@ package net.minecraft.core.net.entity.entries;
 
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.projectile.ProjectileEgg;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryEgg implements IVehicleEntry<ProjectileEgg>, ITrackedEntry<ProjectileEgg> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFallingBlock.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFallingBlock.java
index c6daabc21..eb23a029b 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFallingBlock.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFallingBlock.java
@@ -3,13 +3,13 @@ package net.minecraft.core.net.entity.entries;
 import net.minecraft.core.block.Block;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityFallingBlock;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryFallingBlock implements IVehicleEntry<EntityFallingBlock>, ITrackedEntry<EntityFallingBlock> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFireball.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFireball.java
index 990bd5f29..6d241ab3e 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFireball.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryFireball.java
@@ -2,12 +2,12 @@ package net.minecraft.core.net.entity.entries;
 
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.projectile.ProjectileFireball;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryFireball implements IVehicleEntry<ProjectileFireball>, ITrackedEntry<ProjectileFireball> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryItem.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryItem.java
index 3ad04539e..55ed09609 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryItem.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryItem.java
@@ -1,12 +1,12 @@
 package net.minecraft.core.net.entity.entries;
 
 import net.minecraft.core.entity.EntityItem;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.IPacketEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.packet.Packet;
 import net.minecraft.core.net.packet.AddItemEntityPacket;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryItem implements IPacketEntry<EntityItem>, ITrackedEntry<EntityItem> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryMinecart.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryMinecart.java
index a0039d333..a7bd12f50 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryMinecart.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryMinecart.java
@@ -2,12 +2,12 @@ package net.minecraft.core.net.entity.entries;
 
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.vehicle.MinecartEntity;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryMinecart implements IVehicleEntry<MinecartEntity>, ITrackedEntry<MinecartEntity> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPainting.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPainting.java
index 20eb2ecc4..6ff6b30c3 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPainting.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPainting.java
@@ -1,12 +1,12 @@
 package net.minecraft.core.net.entity.entries;
 
 import net.minecraft.core.entity.EntityPainting;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.IPacketEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.packet.Packet;
 import net.minecraft.core.net.packet.AddPaintingPacket;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryPainting implements IPacketEntry<EntityPainting>, ITrackedEntry<EntityPainting> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPebble.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPebble.java
index fee3e9af7..902023ef9 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPebble.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPebble.java
@@ -2,12 +2,12 @@ package net.minecraft.core.net.entity.entries;
 
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.projectile.ProjectilePebble;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryPebble implements IVehicleEntry<ProjectilePebble>, ITrackedEntry<ProjectilePebble> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPlayerServer.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPlayerServer.java
index a70ef0599..694fd51da 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPlayerServer.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPlayerServer.java
@@ -1,18 +1,18 @@
 package net.minecraft.core.net.entity.entries;
 
+import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.IPacketEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.packet.Packet;
 import net.minecraft.core.net.packet.AddPlayerPacket;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
-import net.minecraft.server.entity.player.PlayerServer;
 import org.jetbrains.annotations.NotNull;
 
-public class NetEntryPlayerServer implements IPacketEntry<PlayerServer>, ITrackedEntry<PlayerServer> {
+public class NetEntryPlayerServer implements IPacketEntry<Player>, ITrackedEntry<Player> {
     @Override
-    public @NotNull Class<PlayerServer> getAppliedClass() {
-        return PlayerServer.class;
+    public @NotNull Class<Player> getAppliedClass() {
+        return Player.class;
     }
 
     @Override
@@ -31,16 +31,16 @@ public class NetEntryPlayerServer implements IPacketEntry<PlayerServer>, ITracke
     }
 
     @Override
-    public void onEntityTracked(EntityTracker tracker, EntityTrackerEntry trackerEntry, PlayerServer trackedObject) {
-        for (EntityTrackerEntry entitytrackerentry : tracker.trackedEntitySet) {
-            if (entitytrackerentry.trackedEntity != trackedObject) {
-                entitytrackerentry.updatePlayerEntity(trackedObject);
+    public void onEntityTracked(EntityTracker tracker, EntityTrackerEntry trackerEntry, Player trackedObject) {
+        for (EntityTrackerEntry entry : tracker.getTrackedEntries()) {
+            if (entry.getTrackedEntity() != trackedObject) {
+                entry.updatePlayerEntity(trackedObject);
             }
         }
     }
 
     @Override
-    public Packet getSpawnPacket(EntityTrackerEntry tracker, PlayerServer trackedObject) {
+    public Packet getSpawnPacket(EntityTrackerEntry tracker, Player trackedObject) {
         return new AddPlayerPacket(trackedObject);
     }
 }
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPrimedTNT.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPrimedTNT.java
index 44819874a..3e28ff4b4 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPrimedTNT.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntryPrimedTNT.java
@@ -2,12 +2,12 @@ package net.minecraft.core.net.entity.entries;
 
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.EntityPrimedTNT;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntryPrimedTNT implements IVehicleEntry<EntityPrimedTNT>, ITrackedEntry<EntityPrimedTNT> {
diff --git a/src/main/java/net/minecraft/core/net/entity/entries/NetEntrySnowball.java b/src/main/java/net/minecraft/core/net/entity/entries/NetEntrySnowball.java
index a67678fed..1d00cba52 100644
--- a/src/main/java/net/minecraft/core/net/entity/entries/NetEntrySnowball.java
+++ b/src/main/java/net/minecraft/core/net/entity/entries/NetEntrySnowball.java
@@ -2,12 +2,12 @@ package net.minecraft.core.net.entity.entries;
 
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.projectile.ProjectileSnowball;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.ITrackedEntry;
 import net.minecraft.core.net.entity.IVehicleEntry;
 import net.minecraft.core.net.packet.AddEntityPacket;
 import net.minecraft.core.world.World;
-import net.minecraft.server.entity.EntityTracker;
-import net.minecraft.server.entity.EntityTrackerEntry;
 import org.jetbrains.annotations.NotNull;
 
 public class NetEntrySnowball implements IVehicleEntry<ProjectileSnowball>, ITrackedEntry<ProjectileSnowball> {
diff --git a/src/main/java/net/minecraft/core/net/packet/UpdatePlayerProfilePacket.java b/src/main/java/net/minecraft/core/net/packet/UpdatePlayerProfilePacket.java
index b5f05fccb..e79e77365 100644
--- a/src/main/java/net/minecraft/core/net/packet/UpdatePlayerProfilePacket.java
+++ b/src/main/java/net/minecraft/core/net/packet/UpdatePlayerProfilePacket.java
@@ -1,7 +1,6 @@
 package net.minecraft.core.net.packet;
 
 import net.minecraft.core.net.handler.PacketHandler;
-import net.minecraft.server.util.helper.PlayerList;
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
@@ -24,7 +23,6 @@ public class UpdatePlayerProfilePacket extends Packet
         this.chatColor = chatColor;
         this.isOnline = isOnline;
         this.isOperator = isOperator;
-        PlayerList.updateList();
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/core/world/type/WorldType.java b/src/main/java/net/minecraft/core/world/type/WorldType.java
index 34013e664..6f3add051 100644
--- a/src/main/java/net/minecraft/core/world/type/WorldType.java
+++ b/src/main/java/net/minecraft/core/world/type/WorldType.java
@@ -13,6 +13,8 @@ import net.minecraft.core.world.weather.Weathers;
 import net.minecraft.core.world.wind.WindProvider;
 import net.minecraft.core.world.wind.WindProviderGeneric;
 
+import java.util.Random;
+
 public abstract class WorldType {
     private final String languageKey;
     private final Weather defaultWeather;
@@ -138,6 +140,7 @@ public abstract class WorldType {
         int x = 0;
         int y = 0;
         int z = 0;
+        Random random = new Random(world.getRandomSeed());
         int attemptsRemaining = 10000;
         spawnLoop:  while (true) {
             if (attemptsRemaining <= 0) {
@@ -146,8 +149,8 @@ public abstract class WorldType {
                 y = world.getHeightValue(x, z);
                 break spawnLoop;
             }
-            x += world.rand.nextInt(64) - world.rand.nextInt(64);
-            z += world.rand.nextInt(64) - world.rand.nextInt(64);
+            x += random.nextInt(64) - random.nextInt(64);
+            z += random.nextInt(64) - random.nextInt(64);
             for (y = getMaxY(); y >= getMinY(); y--) {
                 if (world.getBlockId(x, y + 1, z) == 0 && isValidSpawn(world, x, y, z)) {
                     break spawnLoop;
diff --git a/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java b/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java
index e04ce0c60..99834d2de 100644
--- a/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java
+++ b/src/main/java/net/minecraft/core/world/type/overworld/WorldTypeOverworldIndev.java
@@ -11,6 +11,8 @@ import net.minecraft.core.world.generate.chunk.indev.IndevWorldTheme;
 import net.minecraft.core.world.generate.chunk.indev.IndevWorldType;
 import net.minecraft.core.world.generate.chunk.indev.LevelGenerator;
 
+import java.util.Random;
+
 public class WorldTypeOverworldIndev
         extends WorldTypeOverworld {
     public WorldTypeOverworldIndev(Properties properties) {
@@ -27,10 +29,11 @@ public class WorldTypeOverworldIndev
         int x = 0;
         int y = 0;
         int z = 0;
+        Random random = new Random(world.getRandomSeed());
         spawnLoop:
         while (true) {
-            x = world.rand.nextInt(256);
-            z = world.rand.nextInt(256);
+            x = random.nextInt(256);
+            z = random.nextInt(256);
             for (y = getMaxY(); y >= getMinY(); y--) {
                 if (world.getBlockId(x, y + 1, z) == 0 && isValidSpawn(world, x, y, z)) {
                     break spawnLoop;
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 9ec06012b..7a314abed 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -20,6 +20,36 @@ import net.minecraft.core.net.IUpdatePlayerListBox;
 import net.minecraft.core.net.NetworkManager;
 import net.minecraft.core.net.PropertyManager;
 import net.minecraft.core.net.ServerCommandEntry;
+import net.minecraft.core.net.command.CommandManager;
+import net.minecraft.core.net.command.commands.CommandAchievement;
+import net.minecraft.core.net.command.commands.CommandBiome;
+import net.minecraft.core.net.command.commands.CommandChunk;
+import net.minecraft.core.net.command.commands.CommandClear;
+import net.minecraft.core.net.command.commands.CommandClone;
+import net.minecraft.core.net.command.commands.CommandDamage;
+import net.minecraft.core.net.command.commands.CommandFill;
+import net.minecraft.core.net.command.commands.CommandGameMode;
+import net.minecraft.core.net.command.commands.CommandGameRule;
+import net.minecraft.core.net.command.commands.CommandGive;
+import net.minecraft.core.net.command.commands.CommandHeal;
+import net.minecraft.core.net.command.commands.CommandHelp;
+import net.minecraft.core.net.command.commands.CommandKill;
+import net.minecraft.core.net.command.commands.CommandMessage;
+import net.minecraft.core.net.command.commands.CommandMobSpawning;
+import net.minecraft.core.net.command.commands.CommandPlace;
+import net.minecraft.core.net.command.commands.CommandPlaySound;
+import net.minecraft.core.net.command.commands.CommandSay;
+import net.minecraft.core.net.command.commands.CommandSeed;
+import net.minecraft.core.net.command.commands.CommandSetBlock;
+import net.minecraft.core.net.command.commands.CommandSetSpawn;
+import net.minecraft.core.net.command.commands.CommandSpawn;
+import net.minecraft.core.net.command.commands.CommandSpawnParticle;
+import net.minecraft.core.net.command.commands.CommandSummon;
+import net.minecraft.core.net.command.commands.CommandTeleport;
+import net.minecraft.core.net.command.commands.CommandTellRaw;
+import net.minecraft.core.net.command.commands.CommandTestFor;
+import net.minecraft.core.net.command.commands.CommandTime;
+import net.minecraft.core.net.command.commands.CommandWeather;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.server.entity.player.PlayerServer;
 import net.minecraft.server.net.command.ConsoleCommandSource;
@@ -46,11 +76,27 @@ import net.minecraft.core.world.save.SaveHandlerServer;
 import net.minecraft.core.world.save.mcregion.SaveFormat19134;
 import net.minecraft.core.world.type.WorldType;
 import net.minecraft.core.world.type.WorldTypes;
-import net.minecraft.server.entity.EntityTracker;
+import net.minecraft.server.entity.EntityTrackerImpl;
 import net.minecraft.server.entity.ServerSkinVariantList;
 import net.minecraft.server.gui.ServerGui;
 import net.minecraft.server.net.NetworkListenThread;
 import net.minecraft.server.net.PlayerList;
+import net.minecraft.server.net.command.commands.CommandBan;
+import net.minecraft.server.net.command.commands.CommandColor;
+import net.minecraft.server.net.command.commands.CommandDeop;
+import net.minecraft.server.net.command.commands.CommandDifficulty;
+import net.minecraft.server.net.command.commands.CommandEmotes;
+import net.minecraft.server.net.command.commands.CommandKick;
+import net.minecraft.server.net.command.commands.CommandList;
+import net.minecraft.server.net.command.commands.CommandMe;
+import net.minecraft.server.net.command.commands.CommandNickname;
+import net.minecraft.server.net.command.commands.CommandOp;
+import net.minecraft.server.net.command.commands.CommandSave;
+import net.minecraft.server.net.command.commands.CommandScore;
+import net.minecraft.server.net.command.commands.CommandStop;
+import net.minecraft.server.net.command.commands.CommandUnban;
+import net.minecraft.server.net.command.commands.CommandWhitelist;
+import net.minecraft.server.net.command.commands.CommandWhoIs;
 import net.minecraft.server.world.ConvertProgressUpdater;
 import net.minecraft.server.world.WorldManager;
 import net.minecraft.server.world.WorldServer;
@@ -92,7 +138,7 @@ public class MinecraftServer
     public int percentDone;
     private final List<IUpdatePlayerListBox> playerListBoxes;
     private final List<ServerCommandEntry> commands;
-    public Map<Integer, EntityTracker> entityTrackerMap;
+    public Map<Integer, EntityTrackerImpl> entityTrackerMap;
     public boolean onlineMode;
     public boolean pvpOn;
     public boolean allowFlight;
@@ -174,6 +220,7 @@ public class MinecraftServer
         EntityDispatcher.init();
         TileEntityDispatcher.init();
         CommandHelper.init();
+        initCommands();
 
         LOGGER.info("Loading properties");
         propertyManager = new PropertyManager(new File("server.properties"));
@@ -308,9 +355,9 @@ public class MinecraftServer
             LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file.");
         }
         playerList = new PlayerList(this);
-        for (Integer id : Dimension.getDimensionList().keySet())
+        for (Map.Entry<Integer, Dimension> entry : Dimension.getDimensionList().entrySet())
         {
-            entityTrackerMap.put(id, new EntityTracker(this, id));
+            entityTrackerMap.put(entry.getKey(), new EntityTrackerImpl(this, entry.getValue()));
         }
         long time = System.nanoTime();
         String lName = propertyManager.getStringProperty("level-name", "world");
@@ -342,6 +389,55 @@ public class MinecraftServer
         return true;
     }
 
+    public void initCommands() {
+        CommandManager.registerCommand(new CommandAchievement());
+        CommandManager.registerCommand(new CommandClear());
+        CommandManager.registerCommand(new CommandKill());
+        CommandManager.registerCommand(new CommandSeed());
+        CommandManager.registerCommand(new CommandSetBlock());
+        CommandManager.registerCommand(new CommandSummon());
+        CommandManager.registerCommand(new CommandTeleport());
+        CommandManager.registerCommand(new CommandMessage());
+        CommandManager.registerCommand(new CommandSetSpawn());
+        CommandManager.registerCommand(new CommandTime());
+        CommandManager.registerCommand(new CommandGameMode());
+        CommandManager.registerCommand(new CommandWeather());
+        CommandManager.registerCommand(new CommandSpawn());
+        CommandManager.registerCommand(new CommandPlace());
+        CommandManager.registerCommand(new CommandHelp());
+        CommandManager.registerCommand(new CommandChunk());
+        CommandManager.registerCommand(new CommandGive());
+        CommandManager.registerCommand(new CommandGameRule());
+        CommandManager.registerCommand(new CommandFill());
+        CommandManager.registerCommand(new CommandClone());
+        CommandManager.registerCommand(new CommandBiome());
+        CommandManager.registerCommand(new CommandSay());
+        CommandManager.registerCommand(new CommandTellRaw());
+        CommandManager.registerCommand(new CommandTestFor());
+        CommandManager.registerCommand(new CommandDamage());
+        CommandManager.registerCommand(new CommandHeal());
+        CommandManager.registerCommand(new CommandMobSpawning());
+        CommandManager.registerCommand(new CommandPlaySound());
+        CommandManager.registerCommand(new CommandSpawnParticle());
+
+        CommandManager.registerServerCommand(new CommandStop());
+        CommandManager.registerServerCommand(new CommandOp());
+        CommandManager.registerServerCommand(new CommandDeop());
+        CommandManager.registerServerCommand(new CommandList());
+        CommandManager.registerServerCommand(new CommandDifficulty());
+        CommandManager.registerServerCommand(new CommandColor());
+        CommandManager.registerServerCommand(new CommandNickname());
+        CommandManager.registerServerCommand(new CommandWhoIs());
+        CommandManager.registerServerCommand(new CommandScore());
+        CommandManager.registerServerCommand(new CommandMe());
+        CommandManager.registerServerCommand(new CommandEmotes());
+        CommandManager.registerServerCommand(new CommandBan());
+        CommandManager.registerServerCommand(new CommandUnban());
+        CommandManager.registerServerCommand(new CommandKick());
+        CommandManager.registerServerCommand(new CommandWhitelist());
+        CommandManager.registerServerCommand(new CommandSave());
+    }
+
     private void convertWorld(ISaveFormat saveFormat, String worldDirName)
     {
         int worldSaveVersion = 0;
@@ -679,7 +775,7 @@ public class MinecraftServer
 
         networkServer.handleNetworkListenThread();
         playerList.onTick();
-        for (EntityTracker tracker : entityTrackerMap.values())
+        for (EntityTrackerImpl tracker : entityTrackerMap.values())
         {
             tracker.tick();
         }
@@ -780,7 +876,7 @@ public class MinecraftServer
         return dimensionWorlds.get(dimId);
     }
 
-    public EntityTracker getEntityTracker(int dimId)
+    public EntityTrackerImpl getEntityTracker(int dimId)
     {
         return entityTrackerMap.get(dimId);
     }
diff --git a/src/main/java/net/minecraft/server/entity/EntityTracker.java b/src/main/java/net/minecraft/server/entity/EntityTracker.java
deleted file mode 100644
index dcd609924..000000000
--- a/src/main/java/net/minecraft/server/entity/EntityTracker.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package net.minecraft.server.entity;
-
-import net.minecraft.core.entity.Entity;
-import net.minecraft.core.net.entity.ITrackedEntry;
-import net.minecraft.core.net.entity.NetEntityHandler;
-import net.minecraft.core.net.packet.Packet;
-import net.minecraft.core.util.collection.IntHashMap;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.entity.player.PlayerServer;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-public class EntityTracker {
-    public final Set<EntityTrackerEntry> trackedEntitySet;
-    public final IntHashMap<EntityTrackerEntry> trackedEntityHashTable;
-    public final MinecraftServer mcServer;
-    public final int maxTrackingDistanceThreshold;
-    public final int dimension;
-
-    public EntityTracker(MinecraftServer minecraftserver, int dimId) {
-        trackedEntitySet = new HashSet<>();
-        trackedEntityHashTable = new IntHashMap<>();
-        mcServer = minecraftserver;
-        dimension = dimId;
-        maxTrackingDistanceThreshold = minecraftserver.playerList.getMaxTrackingDistance();
-    }
-
-    public void trackEntity(Entity entity) {
-        ITrackedEntry<Entity> trackedConfig = NetEntityHandler.getTrackedEntry(entity);
-        if (trackedConfig != null){
-            EntityTrackerEntry trackerEntry = trackEntity(entity, trackedConfig.getTrackingDistance(), trackedConfig.getPacketDelay(), trackedConfig.sendMotionUpdates());
-            trackedConfig.onEntityTracked(this, trackerEntry, entity);
-        }
-    }
-
-    public EntityTrackerEntry trackEntity(Entity entity, int trackingDistance, int packetDelay, boolean shouldSendMotionUpdates)
-    {
-        if(trackingDistance > maxTrackingDistanceThreshold) {
-            trackingDistance = maxTrackingDistanceThreshold;
-        }
-        if(trackedEntityHashTable.containsValue(entity.id)) {
-            throw new IllegalStateException("Entity is already tracked!");
-        }
-        EntityTrackerEntry trackerEntry = new EntityTrackerEntry(entity, trackingDistance, packetDelay, shouldSendMotionUpdates);
-        trackedEntitySet.add(trackerEntry);
-        trackedEntityHashTable.put(entity.id, trackerEntry);
-        trackerEntry.updatePlayerEntities(mcServer.getDimensionWorld(dimension).players);
-        return trackerEntry;
-    }
-
-    public void untrackEntity(Entity entity)
-    {
-        if(entity instanceof PlayerServer)
-        {
-            PlayerServer entityplayermp = (PlayerServer)entity;
-            EntityTrackerEntry entitytrackerentry1;
-            for(Iterator<EntityTrackerEntry> iterator = trackedEntitySet.iterator(); iterator.hasNext(); entitytrackerentry1.removeFromTrackedPlayers(entityplayermp))
-            {
-                entitytrackerentry1 = iterator.next();
-            }
-
-        }
-        EntityTrackerEntry entitytrackerentry = trackedEntityHashTable.remove(entity.id);
-        if(entitytrackerentry != null)
-        {
-            trackedEntitySet.remove(entitytrackerentry);
-            entitytrackerentry.sendDestroyEntityPacketToTrackedPlayers();
-        }
-    }
-
-    public void tick()
-    {
-        ArrayList<Entity> arraylist = new ArrayList<>();
-        for (EntityTrackerEntry entitytrackerentry : trackedEntitySet) {
-            entitytrackerentry.tick(mcServer.getDimensionWorld(dimension).players);
-            if (entitytrackerentry.playerEntitiesUpdated && (entitytrackerentry.trackedEntity instanceof PlayerServer)) {
-                arraylist.add(entitytrackerentry.trackedEntity);
-            }
-        }
-label0:
-        for(int i = 0; i < arraylist.size(); i++)
-        {
-            PlayerServer entityplayermp = (PlayerServer)arraylist.get(i);
-            Iterator<EntityTrackerEntry> iterator1 = trackedEntitySet.iterator();
-            do
-            {
-                if(!iterator1.hasNext())
-                {
-                    continue label0;
-                }
-                EntityTrackerEntry entitytrackerentry1 = iterator1.next();
-                if(entitytrackerentry1.trackedEntity != entityplayermp)
-                {
-                    entitytrackerentry1.updatePlayerEntity(entityplayermp);
-                }
-            } while(true);
-        }
-
-    }
-
-    public void sendPacketToTrackedPlayers(Entity entity, Packet packet)
-    {
-        EntityTrackerEntry entitytrackerentry = trackedEntityHashTable.get(entity.id);
-        if(entitytrackerentry != null)
-        {
-            entitytrackerentry.sendPacketToTrackedPlayers(packet);
-        }
-    }
-
-    public void sendPacketToTrackedPlayersAndTrackedEntity(Entity entity, Packet packet)
-    {
-        EntityTrackerEntry entitytrackerentry = trackedEntityHashTable.get(entity.id);
-        if(entitytrackerentry != null)
-        {
-            entitytrackerentry.sendPacketToTrackedPlayersAndTrackedEntity(packet);
-        }
-    }
-
-    public void removeTrackedPlayerSymmetric(PlayerServer entityplayermp)
-    {
-        EntityTrackerEntry entitytrackerentry;
-        for(Iterator<EntityTrackerEntry> iterator = trackedEntitySet.iterator(); iterator.hasNext(); entitytrackerentry.removeTrackedPlayerSymmetric(entityplayermp))
-        {
-            entitytrackerentry = iterator.next();
-        }
-
-    }
-}
diff --git a/src/main/java/net/minecraft/server/entity/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/entity/EntityTrackerEntryImpl.java
similarity index 76%
rename from src/main/java/net/minecraft/server/entity/EntityTrackerEntry.java
rename to src/main/java/net/minecraft/server/entity/EntityTrackerEntryImpl.java
index e2ceb9bb4..476ad3ab7 100644
--- a/src/main/java/net/minecraft/server/entity/EntityTrackerEntry.java
+++ b/src/main/java/net/minecraft/server/entity/EntityTrackerEntryImpl.java
@@ -4,6 +4,7 @@ import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.Mob;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.item.ItemStack;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
 import net.minecraft.core.net.entity.NetEntityHandler;
 import net.minecraft.core.net.packet.MoveEntityPacket;
 import net.minecraft.core.net.packet.Packet;
@@ -23,7 +24,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-public class EntityTrackerEntry {
+public class EntityTrackerEntryImpl implements EntityTrackerEntry {
     public Entity trackedEntity;
     public int trackingDistance;
     public int packetDelay;
@@ -44,7 +45,7 @@ public class EntityTrackerEntry {
     private int ticksSinceLastTeleport;
     public boolean playerEntitiesUpdated;
     public Set<PlayerServer> trackedPlayers;
-    public EntityTrackerEntry(Entity entity, int trackingDistance, int packetDelay, boolean shouldSendMotionUpdates) {
+    public EntityTrackerEntryImpl(Entity entity, int trackingDistance, int packetDelay, boolean shouldSendMotionUpdates) {
         updateCounter = 0;
         ticksSinceLastTeleport = 0;
         firstUpdateDone = false;
@@ -63,8 +64,8 @@ public class EntityTrackerEntry {
 
     @Override
 	public boolean equals(Object obj) {
-        if (!(obj instanceof EntityTrackerEntry)) return false;
-        return ((EntityTrackerEntry)obj).trackedEntity.id == trackedEntity.id;
+        if (!(obj instanceof EntityTrackerEntryImpl)) return false;
+        return ((EntityTrackerEntryImpl)obj).trackedEntity.id == trackedEntity.id;
     }
 
     @Override
@@ -166,43 +167,45 @@ public class EntityTrackerEntry {
         sendPacketToTrackedPlayers(new RemoveEntityPacket(trackedEntity.id));
     }
 
-    public void removeFromTrackedPlayers(PlayerServer playerMP) {
-        trackedPlayers.remove(playerMP);
+    public void removeFromTrackedPlayers(Player player) {
+        trackedPlayers.remove(player);
     }
 
-    public void updatePlayerEntity(PlayerServer entityplayermp) {
-        if(entityplayermp == trackedEntity) {
+    public void updatePlayerEntity(Player player) {
+        assert player instanceof PlayerServer : "Player must be a instance of player server!";
+        PlayerServer playerServer = (PlayerServer) player;
+        if(playerServer == trackedEntity) {
             return;
         }
-        double dx = entityplayermp.x - (double)(encodedPosX / 32);
-        double dz = entityplayermp.z - (double)(encodedPosZ / 32);
+        double dx = playerServer.x - (double)(encodedPosX / 32);
+        double dz = playerServer.z - (double)(encodedPosZ / 32);
         if(dx >= (double)(-trackingDistance) && dx <= (double)trackingDistance && dz >= (double)(-trackingDistance) && dz <= (double)trackingDistance) {
-            if(!trackedPlayers.contains(entityplayermp)) {
-                trackedPlayers.add(entityplayermp);
-                entityplayermp.playerNetServerHandler.sendPacket(NetEntityHandler.getSpawnPacket(this));
+            if(!trackedPlayers.contains(playerServer)) {
+                trackedPlayers.add(playerServer);
+                playerServer.playerNetServerHandler.sendPacket(NetEntityHandler.getSpawnPacket(this));
                 if (trackedEntity.sendAdditionalData) {
-                    entityplayermp.playerNetServerHandler.sendPacket(new EntityTagDataPacket(trackedEntity));
+                    playerServer.playerNetServerHandler.sendPacket(new EntityTagDataPacket(trackedEntity));
                 }
                 if(shouldSendMotionUpdates) {
-                    entityplayermp.playerNetServerHandler.sendPacket(new SetEntityMotionPacket(trackedEntity.id, trackedEntity.xd, trackedEntity.yd, trackedEntity.zd));
+                    playerServer.playerNetServerHandler.sendPacket(new SetEntityMotionPacket(trackedEntity.id, trackedEntity.xd, trackedEntity.yd, trackedEntity.zd));
                 }
                 ItemStack[] aitemstack = trackedEntity.getInventory();
                 if(aitemstack != null) {
                     for(int i = 0; i < aitemstack.length; i++) {
-                        entityplayermp.playerNetServerHandler.sendPacket(new SetEquippedItemPacket(trackedEntity.id, i, aitemstack[i]));
+                        playerServer.playerNetServerHandler.sendPacket(new SetEquippedItemPacket(trackedEntity.id, i, aitemstack[i]));
                     }
                 }
-                if(trackedEntity instanceof Player) {
-                    Player entityplayer = (Player)trackedEntity;
-                    if(entityplayer.isPlayerSleeping())
+                if(trackedEntity instanceof PlayerServer) {
+                    PlayerServer trackedPlayerServer = (PlayerServer) trackedEntity;
+                    if(trackedPlayerServer.isPlayerSleeping())
                     {
-                        entityplayermp.playerNetServerHandler.sendPacket(new SleepPacket(trackedEntity, 0, MathHelper.floor(trackedEntity.x), MathHelper.floor(trackedEntity.y), MathHelper.floor(trackedEntity.z)));
+                        playerServer.playerNetServerHandler.sendPacket(new SleepPacket(trackedEntity, 0, MathHelper.floor(trackedEntity.x), MathHelper.floor(trackedEntity.y), MathHelper.floor(trackedEntity.z)));
                     }
                 }
             }
-        } else if(trackedPlayers.contains(entityplayermp)) {
-            trackedPlayers.remove(entityplayermp);
-            entityplayermp.playerNetServerHandler.sendPacket(new RemoveEntityPacket(trackedEntity.id));
+        } else if(trackedPlayers.contains(playerServer)) {
+            trackedPlayers.remove(playerServer);
+            playerServer.playerNetServerHandler.sendPacket(new RemoveEntityPacket(trackedEntity.id));
         }
     }
 
@@ -211,10 +214,18 @@ public class EntityTrackerEntry {
             updatePlayerEntity((PlayerServer) player);
         }
     }
-    public void removeTrackedPlayerSymmetric(PlayerServer playerMP) {
-        if(trackedPlayers.contains(playerMP)) {
-            trackedPlayers.remove(playerMP);
-            playerMP.playerNetServerHandler.sendPacket(new RemoveEntityPacket(trackedEntity.id));
+    public void removeTrackedPlayerSymmetric(Player player) {
+        if (player instanceof PlayerServer) {
+            PlayerServer playerServer = (PlayerServer) player;
+            if(trackedPlayers.contains(playerServer)) {
+                trackedPlayers.remove(playerServer);
+                playerServer.playerNetServerHandler.sendPacket(new RemoveEntityPacket(trackedEntity.id));
+            }
         }
     }
+
+    @Override
+    public Entity getTrackedEntity() {
+        return trackedEntity;
+    }
 }
diff --git a/src/main/java/net/minecraft/server/entity/EntityTrackerImpl.java b/src/main/java/net/minecraft/server/entity/EntityTrackerImpl.java
new file mode 100644
index 000000000..9be2e54b8
--- /dev/null
+++ b/src/main/java/net/minecraft/server/entity/EntityTrackerImpl.java
@@ -0,0 +1,146 @@
+package net.minecraft.server.entity;
+
+import net.minecraft.core.entity.Entity;
+import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.net.entity.EntityTracker;
+import net.minecraft.core.net.entity.EntityTrackerEntry;
+import net.minecraft.core.net.entity.ITrackedEntry;
+import net.minecraft.core.net.entity.NetEntityHandler;
+import net.minecraft.core.net.packet.Packet;
+import net.minecraft.core.util.collection.IntHashMap;
+import net.minecraft.core.world.Dimension;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.entity.player.PlayerServer;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class EntityTrackerImpl implements EntityTracker {
+    public final Set<EntityTrackerEntryImpl> trackedEntitySet;
+    public final IntHashMap<EntityTrackerEntryImpl> trackedEntityHashTable;
+    public final MinecraftServer mcServer;
+    public final int maxTrackingDistanceThreshold;
+    public final Dimension dimension;
+
+    public EntityTrackerImpl(MinecraftServer minecraftserver, Dimension dimensions) {
+        trackedEntitySet = new HashSet<>();
+        trackedEntityHashTable = new IntHashMap<>();
+        mcServer = minecraftserver;
+        dimension = dimensions;
+        maxTrackingDistanceThreshold = minecraftserver.playerList.getMaxTrackingDistance();
+    }
+
+    @Override
+    public void trackEntity(Entity entity) {
+        ITrackedEntry<Entity> trackedConfig = NetEntityHandler.getTrackedEntry(entity);
+        if (trackedConfig != null){
+            EntityTrackerEntryImpl trackerEntry = trackEntity(entity, trackedConfig.getTrackingDistance(), trackedConfig.getPacketDelay(), trackedConfig.sendMotionUpdates());
+            trackedConfig.onEntityTracked(this, trackerEntry, entity);
+        }
+    }
+
+    @Override
+    public EntityTrackerEntryImpl trackEntity(Entity entity, int trackingDistance, int packetDelay, boolean shouldSendMotionUpdates)
+    {
+        if(trackingDistance > maxTrackingDistanceThreshold) {
+            trackingDistance = maxTrackingDistanceThreshold;
+        }
+        if(trackedEntityHashTable.containsValue(entity.id)) {
+            throw new IllegalStateException("Entity is already tracked!");
+        }
+        EntityTrackerEntryImpl trackerEntry = new EntityTrackerEntryImpl(entity, trackingDistance, packetDelay, shouldSendMotionUpdates);
+        trackedEntitySet.add(trackerEntry);
+        trackedEntityHashTable.put(entity.id, trackerEntry);
+        trackerEntry.updatePlayerEntities(mcServer.getDimensionWorld(dimension.id).players);
+        return trackerEntry;
+    }
+
+    @Override
+    public void untrackEntity(Entity entity)
+    {
+        if(entity instanceof PlayerServer)
+        {
+            PlayerServer playerServer = (PlayerServer)entity;
+            EntityTrackerEntryImpl entitytrackerentry1;
+            for(Iterator<EntityTrackerEntryImpl> iterator = trackedEntitySet.iterator(); iterator.hasNext(); entitytrackerentry1.removeFromTrackedPlayers(playerServer))
+            {
+                entitytrackerentry1 = iterator.next();
+            }
+
+        }
+        EntityTrackerEntryImpl entityTrackerEntry = trackedEntityHashTable.remove(entity.id);
+        if(entityTrackerEntry != null)
+        {
+            trackedEntitySet.remove(entityTrackerEntry);
+            entityTrackerEntry.sendDestroyEntityPacketToTrackedPlayers();
+        }
+    }
+
+    @Override
+    public void tick()
+    {
+        ArrayList<Entity> arraylist = new ArrayList<>();
+        for (EntityTrackerEntryImpl entityTrackerEntry : trackedEntitySet) {
+            entityTrackerEntry.tick(mcServer.getDimensionWorld(dimension.id).players);
+            if (entityTrackerEntry.playerEntitiesUpdated && (entityTrackerEntry.trackedEntity instanceof PlayerServer)) {
+                arraylist.add(entityTrackerEntry.trackedEntity);
+            }
+        }
+label0:
+        for(int i = 0; i < arraylist.size(); i++)
+        {
+            PlayerServer entityplayermp = (PlayerServer)arraylist.get(i);
+            Iterator<EntityTrackerEntryImpl> iterator1 = trackedEntitySet.iterator();
+            do
+            {
+                if(!iterator1.hasNext())
+                {
+                    continue label0;
+                }
+                EntityTrackerEntryImpl entitytrackerentry1 = iterator1.next();
+                if(entitytrackerentry1.trackedEntity != entityplayermp)
+                {
+                    entitytrackerentry1.updatePlayerEntity(entityplayermp);
+                }
+            } while(true);
+        }
+
+    }
+
+    @Override
+    public void sendPacketToTrackedPlayers(Entity entity, Packet packet)
+    {
+        EntityTrackerEntryImpl entityTrackerEntry = trackedEntityHashTable.get(entity.id);
+        if(entityTrackerEntry != null)
+        {
+            entityTrackerEntry.sendPacketToTrackedPlayers(packet);
+        }
+    }
+
+    @Override
+    public void sendPacketToTrackedPlayersAndTrackedEntity(Entity entity, Packet packet)
+    {
+        EntityTrackerEntryImpl entityTrackerEntry = trackedEntityHashTable.get(entity.id);
+        if(entityTrackerEntry != null)
+        {
+            entityTrackerEntry.sendPacketToTrackedPlayersAndTrackedEntity(packet);
+        }
+    }
+
+    @Override
+    public void removeTrackedPlayerSymmetric(Player player)
+    {
+        EntityTrackerEntryImpl entitytrackerentry;
+        for(Iterator<EntityTrackerEntryImpl> iterator = trackedEntitySet.iterator(); iterator.hasNext(); entitytrackerentry.removeTrackedPlayerSymmetric(player))
+        {
+            entitytrackerentry = iterator.next();
+        }
+    }
+
+    @Override
+    public Set<? extends EntityTrackerEntry> getTrackedEntries() {
+        return trackedEntitySet;
+    }
+}
diff --git a/src/main/java/net/minecraft/server/entity/player/PlayerServer.java b/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
index eca2e4066..9d69846bb 100644
--- a/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
+++ b/src/main/java/net/minecraft/server/entity/player/PlayerServer.java
@@ -22,7 +22,7 @@ import net.minecraft.core.world.ICarriable;
 import net.minecraft.core.world.IVehicle;
 import net.minecraft.core.world.chunk.Chunk;
 import net.minecraft.core.world.chunk.ChunkSection;
-import net.minecraft.server.entity.EntityTracker;
+import net.minecraft.server.entity.EntityTrackerImpl;
 import net.minecraft.server.net.handler.PacketHandlerServer;
 import net.minecraft.core.net.packet.*;
 import net.minecraft.server.world.ServerPlayerController;
@@ -130,7 +130,7 @@ public class PlayerServer extends Player implements ContainerListener {
 	public void awardKillScore(Entity entity, int i)
     {
         super.awardKillScore(entity, i);
-        mcServer.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(username, nickname, uuid, score, chatColor, true, isOperator()));
+        mcServer.playerList.updatePlayerProfile(username, nickname, uuid, score, chatColor, true, isOperator());
     }
 
     public boolean isOperator()
@@ -356,7 +356,7 @@ public class PlayerServer extends Player implements ContainerListener {
         }
         if (score != lastScore)
         {
-            playerNetServerHandler.sendPacket(new UpdatePlayerProfilePacket(username, nickname, uuid, score, chatColor, true, isOperator()));
+            mcServer.playerList.updatePlayerProfile(username, nickname, uuid, score, chatColor, true, isOperator());
             lastScore = score;
         }
     }
@@ -410,7 +410,7 @@ public class PlayerServer extends Player implements ContainerListener {
     {
         if (!entity.removed)
         {
-            EntityTracker entitytracker = mcServer.getEntityTracker(dimension);
+            EntityTrackerImpl entitytracker = mcServer.getEntityTracker(dimension);
             if (entity instanceof EntityItem)
             {
                 entitytracker.sendPacketToTrackedPlayers(entity, new TakeItemEntityPacket(entity.id, id));
@@ -431,7 +431,7 @@ public class PlayerServer extends Player implements ContainerListener {
         {
             swingProgressInt = -1;
             isSwinging = true;
-            EntityTracker entitytracker = mcServer.getEntityTracker(dimension);
+            EntityTrackerImpl entitytracker = mcServer.getEntityTracker(dimension);
             entitytracker.sendPacketToTrackedPlayers(this, new AnimatePacket(this, 1));
         }
     }
@@ -446,7 +446,7 @@ public class PlayerServer extends Player implements ContainerListener {
         EnumSleepStatus status = super.sleepInBedAt(x, y, z);
         if (status == EnumSleepStatus.OK)
         {
-            EntityTracker entitytracker = mcServer.getEntityTracker(dimension);
+            EntityTrackerImpl entitytracker = mcServer.getEntityTracker(dimension);
             SleepPacket sleepPacket = new SleepPacket(this, 0, x, y, z);
             entitytracker.sendPacketToTrackedPlayers(this, sleepPacket);
             playerNetServerHandler.teleportAndRotate(this.x, this.y, this.z, yRot, xRot);
@@ -460,7 +460,7 @@ public class PlayerServer extends Player implements ContainerListener {
     {
         if (isPlayerSleeping())
         {
-            EntityTracker entitytracker = mcServer.getEntityTracker(dimension);
+            EntityTrackerImpl entitytracker = mcServer.getEntityTracker(dimension);
             entitytracker.sendPacketToTrackedPlayersAndTrackedEntity(this, new AnimatePacket(this, 3));
             super.wakeUpPlayer(flag, flag1);
         }
@@ -767,6 +767,10 @@ public class PlayerServer extends Player implements ContainerListener {
         playerNetServerHandler.teleportAndRotate(x, y, z, xr, yr);
     }
 
+    @Override
+    public boolean deferVehicleBehavior() {
+        return true;
+    }
 
     public PacketHandlerServer playerNetServerHandler;
     public MinecraftServer mcServer;
diff --git a/src/main/java/net/minecraft/server/net/PlayerList.java b/src/main/java/net/minecraft/server/net/PlayerList.java
index e90b83e9c..8956e75ba 100644
--- a/src/main/java/net/minecraft/server/net/PlayerList.java
+++ b/src/main/java/net/minecraft/server/net/PlayerList.java
@@ -11,6 +11,7 @@ import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.server.entity.player.PlayerServer;
 import net.minecraft.server.net.handler.PacketHandlerLogin;
 import net.minecraft.core.net.packet.*;
+import net.minecraft.server.player.PlayerListBox;
 import net.minecraft.server.player.PlayerManager;
 import net.minecraft.server.world.ServerPlayerController;
 import net.minecraft.core.util.helper.AES;
@@ -322,6 +323,11 @@ public class PlayerList
 
     }
 
+    public void updatePlayerProfile(String username, String nickname, UUID uuid, int score, byte chatColor, boolean isOnline, boolean isOperator) {
+        sendPacketToAllPlayers(new UpdatePlayerProfilePacket(username, nickname, uuid, score, chatColor, isOnline, isOperator));
+        PlayerListBox.updateList();
+    }
+
     public void sendEncryptedChatToAllPlayers(String message)
     {
         for (PlayerServer player : playerEntities) {
diff --git a/src/main/java/net/minecraft/server/net/command/ConsoleCommandSource.java b/src/main/java/net/minecraft/server/net/command/ConsoleCommandSource.java
index e914ac39c..578a9d2e9 100644
--- a/src/main/java/net/minecraft/server/net/command/ConsoleCommandSource.java
+++ b/src/main/java/net/minecraft/server/net/command/ConsoleCommandSource.java
@@ -4,6 +4,7 @@ import com.mojang.logging.LogUtils;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.packet.ChatPacket;
+import net.minecraft.core.net.packet.Packet;
 import net.minecraft.core.util.helper.AES;
 import net.minecraft.core.util.helper.LoggedPrintStream;
 import net.minecraft.core.util.phys.Vec3;
@@ -16,6 +17,7 @@ import org.slf4j.Logger;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.function.Supplier;
 
 public class ConsoleCommandSource implements CommandSource, IServerCommandSource {
     private static final Logger LOGGER = LogUtils.getLogger();
@@ -85,6 +87,11 @@ public class ConsoleCommandSource implements CommandSource, IServerCommandSource
         this.getServer().playerList.sendPacketToAllPlayers(new ChatPacket(message));
     }
 
+    @Override
+    public void sendPacketToAllPlayers(Supplier<Packet> packetSupplier) {
+        this.getServer().playerList.sendPacketToAllPlayers(packetSupplier.get());
+    }
+
     @Override
     public World getWorld() {
         return this.server.getDimensionWorld(0);
diff --git a/src/main/java/net/minecraft/server/net/command/ServerCommandSource.java b/src/main/java/net/minecraft/server/net/command/ServerCommandSource.java
index 256483608..901049ae8 100644
--- a/src/main/java/net/minecraft/server/net/command/ServerCommandSource.java
+++ b/src/main/java/net/minecraft/server/net/command/ServerCommandSource.java
@@ -3,6 +3,7 @@ package net.minecraft.server.net.command;
 import net.minecraft.core.entity.player.Player;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.packet.ChatPacket;
+import net.minecraft.core.net.packet.Packet;
 import net.minecraft.core.util.helper.AES;
 import net.minecraft.core.util.helper.MathHelper;
 import net.minecraft.core.util.phys.Vec3;
@@ -14,6 +15,7 @@ import org.jetbrains.annotations.NotNull;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.function.Supplier;
 
 public class ServerCommandSource implements CommandSource, IServerCommandSource {
     public final MinecraftServer server;
@@ -86,6 +88,11 @@ public class ServerCommandSource implements CommandSource, IServerCommandSource
         this.getServer().playerList.sendPacketToAllPlayers(new ChatPacket(message));
     }
 
+    @Override
+    public void sendPacketToAllPlayers(Supplier<Packet> packetSupplier) {
+        this.getServer().playerList.sendPacketToAllPlayers(packetSupplier.get());
+    }
+
     @Override
     public World getWorld() {
         return this.player == null ? this.server.getDimensionWorld(0) : this.player.world;
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandBan.java b/src/main/java/net/minecraft/server/net/command/commands/CommandBan.java
index a34ac08b1..bb32380bf 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandBan.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandBan.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 import net.minecraft.core.util.helper.UUIDHelper;
@@ -14,11 +15,11 @@ import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.entity.player.PlayerServer;
 import net.minecraft.server.net.command.IServerCommandSource;
 
-public class CommandBan {
+public class CommandBan implements CommandManager.CommandRegistry {
     private static final DynamicCommandExceptionType FAILURE =
         new DynamicCommandExceptionType(arg -> () -> I18n.getInstance().translateKeyAndFormat("command.commands.ban.exception_failure", arg));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register
         (
             LiteralArgumentBuilder.<CommandSource>literal("ban")
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandColor.java b/src/main/java/net/minecraft/server/net/command/commands/CommandColor.java
index 7b1c5c093..c90675bb9 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandColor.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandColor.java
@@ -8,6 +8,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import com.mojang.brigadier.tree.CommandNode;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.server.entity.player.PlayerServer;
@@ -19,8 +20,8 @@ import net.minecraft.core.net.command.util.CommandHelper;
 
 import java.util.List;
 
-public class CommandColor {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandColor implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         CommandNode<CommandSource> command = dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("color")
             .then(LiteralArgumentBuilder.<CommandSource>literal("get")
                 .executes(c -> {
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandDeop.java b/src/main/java/net/minecraft/server/net/command/commands/CommandDeop.java
index 44e96a566..8c2f30377 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandDeop.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandDeop.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.server.entity.player.PlayerServer;
 import net.minecraft.server.net.command.IServerCommandSource;
@@ -18,10 +19,10 @@ import net.minecraft.server.MinecraftServer;
 
 import java.util.List;
 
-public class CommandDeop {
+public class CommandDeop implements CommandManager.CommandRegistry {
     private static final SimpleCommandExceptionType FAILURE = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.deop.exception_failure"));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("deop")
             .requires(CommandSource::hasAdmin)
             .then(RequiredArgumentBuilder.<CommandSource, EntitySelector>argument("target", ArgumentTypeEntity.players())
@@ -44,7 +45,7 @@ public class CommandDeop {
                             source.sendTranslatableMessage("command.commands.deop.success", player.username);
                             source.sendTranslatableMessage(player, "command.commands.deop.success_receiver");
                         }
-                        server.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator()));
+                        server.playerList.updatePlayerProfile(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator());
                     }
                     if (!deoppedSomeone) {
                         throw FAILURE.create();
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandDifficulty.java b/src/main/java/net/minecraft/server/net/command/commands/CommandDifficulty.java
index 16a0b2eb9..4d8c4610f 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandDifficulty.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandDifficulty.java
@@ -5,6 +5,7 @@ import com.mojang.brigadier.CommandDispatcher;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.world.World;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.core.net.command.CommandSource;
@@ -14,8 +15,8 @@ import net.minecraft.core.net.command.exceptions.CommandExceptions;
 import java.util.Arrays;
 import java.util.List;
 
-public class CommandDifficulty {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandDifficulty implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("difficulty")
                 .requires(CommandSource::hasAdmin)
                 .executes(c -> {
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandEmotes.java b/src/main/java/net/minecraft/server/net/command/commands/CommandEmotes.java
index b1adb5fb2..42c2b9043 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandEmotes.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandEmotes.java
@@ -3,14 +3,15 @@ package net.minecraft.server.net.command.commands;
 import com.mojang.brigadier.CommandDispatcher;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import net.minecraft.core.net.ChatEmotes;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.net.command.CommandSource;
 
 import java.util.ArrayList;
 import java.util.Map;
 
-public class CommandEmotes {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandEmotes implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("emotes")
             .executes(c -> {
                 CommandSource source = c.getSource();
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandKick.java b/src/main/java/net/minecraft/server/net/command/commands/CommandKick.java
index a0e1cd6bf..ea6b0d048 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandKick.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandKick.java
@@ -6,6 +6,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
@@ -13,11 +14,11 @@ import net.minecraft.core.net.command.helpers.EntitySelector;
 import net.minecraft.server.entity.player.PlayerServer;
 import net.minecraft.server.net.command.IServerCommandSource;
 
-public class CommandKick {
+public class CommandKick implements CommandManager.CommandRegistry {
     private static final DynamicCommandExceptionType FAILURE =
         new DynamicCommandExceptionType(arg -> () -> I18n.getInstance().translateKeyAndFormat("command.commands.kick.exception_failure", arg));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register
             (
                 LiteralArgumentBuilder.<CommandSource>literal("kick")
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandList.java b/src/main/java/net/minecraft/server/net/command/commands/CommandList.java
index 324a49007..56e822fbb 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandList.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandList.java
@@ -5,16 +5,17 @@ import com.mojang.brigadier.CommandDispatcher;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.server.net.command.IServerCommandSource;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 
-public class CommandList {
+public class CommandList implements CommandManager.CommandRegistry {
     private static final SimpleCommandExceptionType FAILURE = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.list.exception_failure"));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("list")
                 .executes(c -> {
                     CommandSource source = c.getSource();
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandMe.java b/src/main/java/net/minecraft/server/net/command/commands/CommandMe.java
index bec59aa25..3d8e8daa0 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandMe.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandMe.java
@@ -6,13 +6,14 @@ import com.mojang.brigadier.arguments.BoolArgumentType;
 import com.mojang.brigadier.arguments.StringArgumentType;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.server.net.command.IServerCommandSource;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 import net.minecraft.core.net.packet.ChatPacket;
 
-public class CommandMe {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandMe implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("me")
             .then(RequiredArgumentBuilder.<CommandSource, Boolean>argument("asterisk", BoolArgumentType.bool())
                 .then(RequiredArgumentBuilder.<CommandSource, String>argument("message", StringArgumentType.greedyString())
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandNickname.java b/src/main/java/net/minecraft/server/net/command/commands/CommandNickname.java
index f5b45f507..bb529211a 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandNickname.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandNickname.java
@@ -9,6 +9,7 @@ import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 import com.mojang.brigadier.tree.CommandNode;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
@@ -18,11 +19,11 @@ import net.minecraft.server.entity.player.PlayerServer;
 
 import java.util.List;
 
-public class CommandNickname {
+public class CommandNickname implements CommandManager.CommandRegistry {
     private static final SimpleCommandExceptionType NICKNAME_TOO_LARGE = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.nickname.exception_too_large"));
     private static final SimpleCommandExceptionType NICKNAME_TOO_SMALL = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.nickname.exception_too_small"));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         CommandNode<CommandSource> command = dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("nickname")
             .then(LiteralArgumentBuilder.<CommandSource>literal("set")
                 .then(RequiredArgumentBuilder.<CommandSource, EntitySelector>argument("target", ArgumentTypeEntity.player())
@@ -40,7 +41,7 @@ public class CommandNickname {
 
                             player.nickname = nickname;
                             player.hadNicknameSet = true;
-                            player.mcServer.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator()));
+                            player.mcServer.playerList.updatePlayerProfile(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator());
                             if (source.getSender() == player) {
                                 source.sendTranslatableMessage("command.commands.nickname.set.success", nickname);
                             } else {
@@ -62,7 +63,7 @@ public class CommandNickname {
 
                         player.nickname = nickname;
                         player.hadNicknameSet = true;
-                        player.mcServer.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator()));
+                        player.mcServer.playerList.updatePlayerProfile(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator());
 
                         source.sendTranslatableMessage("command.commands.nickname.set.success", nickname);
 
@@ -91,7 +92,7 @@ public class CommandNickname {
 
                         player.nickname = "";
                         player.hadNicknameSet = false;
-                        player.mcServer.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator()));
+                        player.mcServer.playerList.updatePlayerProfile(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator());
                         if (source.getSender() == player) {
                             source.sendTranslatableMessage("command.commands.nickname.reset.success");
                         } else {
@@ -109,7 +110,7 @@ public class CommandNickname {
 
                     player.nickname = "";
                     player.hadNicknameSet = false;
-                    player.mcServer.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator()));
+                    player.mcServer.playerList.updatePlayerProfile(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator());
 
                     source.sendTranslatableMessage("command.commands.nickname.reset.success", player.username);
 
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandOp.java b/src/main/java/net/minecraft/server/net/command/commands/CommandOp.java
index b9de58b1e..237f7afe4 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandOp.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandOp.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.server.entity.player.PlayerServer;
 import net.minecraft.server.net.command.IServerCommandSource;
@@ -18,10 +19,10 @@ import net.minecraft.server.MinecraftServer;
 
 import java.util.List;
 
-public class CommandOp {
+public class CommandOp implements CommandManager.CommandRegistry {
     private static final SimpleCommandExceptionType FAILURE = new SimpleCommandExceptionType(() -> I18n.getInstance().translateKey("command.commands.op.exception_failure"));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("op")
             .requires(CommandSource::hasAdmin)
             .then(RequiredArgumentBuilder.<CommandSource, EntitySelector>argument("target", ArgumentTypeEntity.players())
@@ -44,7 +45,7 @@ public class CommandOp {
                             source.sendTranslatableMessage("command.commands.op.success", player.username);
                             source.sendTranslatableMessage(player, "command.commands.op.success_receiver");
                         }
-                        server.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator()));
+                        server.playerList.updatePlayerProfile(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator());
                     }
                     if (!oppedSomeone) {
                         throw FAILURE.create();
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandSave.java b/src/main/java/net/minecraft/server/net/command/commands/CommandSave.java
index 087044399..720d1d1d4 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandSave.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandSave.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 import net.minecraft.core.world.Dimension;
@@ -14,11 +15,11 @@ import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.net.command.IServerCommandSource;
 import net.minecraft.server.world.WorldServer;
 
-public class CommandSave {
+public class CommandSave implements CommandManager.CommandRegistry {
     private static final DynamicCommandExceptionType FAILURE =
         new DynamicCommandExceptionType(arg -> () -> I18n.getInstance().translateKeyAndFormat("command.commands.save.exception_failure", arg));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register
             (
                 LiteralArgumentBuilder.<CommandSource>literal("save")
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandScore.java b/src/main/java/net/minecraft/server/net/command/commands/CommandScore.java
index 498479034..ed8daa8d8 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandScore.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandScore.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import net.minecraft.core.entity.Entity;
 import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.server.entity.player.PlayerServer;
 import net.minecraft.server.net.command.IServerCommandSource;
@@ -19,8 +20,8 @@ import net.minecraft.server.MinecraftServer;
 
 import java.util.List;
 
-public class CommandScore {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandScore implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("score")
             .then(LiteralArgumentBuilder.<CommandSource>literal("get")
                 .executes(c -> {
@@ -77,7 +78,7 @@ public class CommandScore {
         if (!(source instanceof IServerCommandSource)) throw CommandExceptions.multiplayerWorldOnly().create();
         MinecraftServer server = ((IServerCommandSource) source).getServer();
         player.score = score;
-        server.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator()));
+        server.playerList.updatePlayerProfile(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator());
         if (player == source.getSender()) {
             source.sendTranslatableMessage("command.commands.score.set.success", score);
         } else {
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandStop.java b/src/main/java/net/minecraft/server/net/command/commands/CommandStop.java
index 2c9eedbe0..79cdd1cc2 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandStop.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandStop.java
@@ -3,14 +3,15 @@ package net.minecraft.server.net.command.commands;
 import com.mojang.brigadier.Command;
 import com.mojang.brigadier.CommandDispatcher;
 import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.world.World;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.server.net.command.IServerCommandSource;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 
-public class CommandStop {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandStop implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("stop")
                 .requires(CommandSource::hasAdmin)
                 .executes(c -> {
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandUnban.java b/src/main/java/net/minecraft/server/net/command/commands/CommandUnban.java
index 7af0aa6c0..9b28d8edd 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandUnban.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandUnban.java
@@ -7,17 +7,18 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 import net.minecraft.core.util.helper.UUIDHelper;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.net.command.IServerCommandSource;
 
-public class CommandUnban {
+public class CommandUnban implements CommandManager.CommandRegistry {
     private static final DynamicCommandExceptionType FAILURE =
         new DynamicCommandExceptionType(arg -> () -> I18n.getInstance().translateKeyAndFormat("command.commands.unban.exception_failure", arg));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register
             (
                 LiteralArgumentBuilder.<CommandSource>literal("unban")
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandWhitelist.java b/src/main/java/net/minecraft/server/net/command/commands/CommandWhitelist.java
index bbaeae680..066175427 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandWhitelist.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandWhitelist.java
@@ -7,6 +7,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 import net.minecraft.core.lang.I18n;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.exceptions.CommandExceptions;
 import net.minecraft.core.util.helper.UUIDHelper;
@@ -17,11 +18,11 @@ import net.minecraft.server.net.command.IServerCommandSource;
 import java.util.Set;
 import java.util.UUID;
 
-public class CommandWhitelist {
+public class CommandWhitelist implements CommandManager.CommandRegistry {
     private static final DynamicCommandExceptionType FAILURE =
         new DynamicCommandExceptionType(arg -> () -> I18n.getInstance().translateKeyAndFormat("command.commands.whitelist.exception_failure", arg));
 
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         dispatcher.register
             (
                 LiteralArgumentBuilder.<CommandSource>literal("whitelist")
diff --git a/src/main/java/net/minecraft/server/net/command/commands/CommandWhoIs.java b/src/main/java/net/minecraft/server/net/command/commands/CommandWhoIs.java
index ba2f5f9c8..d8dcc8dbc 100644
--- a/src/main/java/net/minecraft/server/net/command/commands/CommandWhoIs.java
+++ b/src/main/java/net/minecraft/server/net/command/commands/CommandWhoIs.java
@@ -6,13 +6,14 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.builder.RequiredArgumentBuilder;
 import com.mojang.brigadier.tree.CommandNode;
 import net.minecraft.core.entity.player.Player;
+import net.minecraft.core.net.command.CommandManager;
 import net.minecraft.core.net.command.util.CommandHelper;
 import net.minecraft.core.net.command.CommandSource;
 import net.minecraft.core.net.command.arguments.ArgumentTypeEntity;
 import net.minecraft.core.net.command.helpers.EntitySelector;
 
-public class CommandWhoIs {
-    public static void register(CommandDispatcher<CommandSource> dispatcher) {
+public class CommandWhoIs implements CommandManager.CommandRegistry {
+    public void register(CommandDispatcher<CommandSource> dispatcher) {
         CommandNode<CommandSource> command = dispatcher.register(LiteralArgumentBuilder.<CommandSource>literal("whois")
                 .then(RequiredArgumentBuilder.<CommandSource, EntitySelector>argument("target", ArgumentTypeEntity.player())
                         .executes(c -> {
diff --git a/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java b/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java
index 636d9d959..64b46d22b 100644
--- a/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java
+++ b/src/main/java/net/minecraft/server/net/handler/PacketHandlerLogin.java
@@ -201,7 +201,7 @@ public class PacketHandlerLogin extends PacketHandler
             packetHandler.sendPacket(new SetSpawnPositionPacket(chunkcoordinates.x, chunkcoordinates.y, chunkcoordinates.z));
             mcServer.playerList.setTime(player, worldserver);
             mcServer.playerList.sendPacketToAllPlayers(new ChatPacket(TextFormatting.YELLOW + player.getDisplayName() + TextFormatting.YELLOW + " joined the game."));
-            mcServer.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator()));
+            mcServer.playerList.updatePlayerProfile(player.username, player.nickname, player.uuid, player.score, player.chatColor, true, player.isOperator());
 
             if (mcServer.joinMessage != null && !mcServer.joinMessage.isEmpty())
             {
diff --git a/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java b/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
index f7dc7e0e7..75cc53024 100644
--- a/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
+++ b/src/main/java/net/minecraft/server/net/handler/PacketHandlerServer.java
@@ -21,6 +21,7 @@ import net.minecraft.core.net.command.TextFormatting;
 import net.minecraft.core.player.inventory.container.ContainerInventory;
 import net.minecraft.core.util.collection.NamespaceID;
 import net.minecraft.core.world.World;
+import net.minecraft.server.net.PlayerList;
 import net.minecraft.server.net.command.ServerCommandSource;
 import net.minecraft.core.net.handler.PacketHandler;
 import net.minecraft.core.net.packet.*;
@@ -39,7 +40,7 @@ import net.minecraft.core.util.phys.Vec3;
 import net.minecraft.core.world.chunk.ChunkCoordinates;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.entity.player.PlayerServer;
-import net.minecraft.server.util.helper.PlayerList;
+import net.minecraft.server.player.PlayerListBox;
 import net.minecraft.server.world.WorldServer;
 import org.slf4j.Logger;
 
@@ -83,14 +84,14 @@ public class PacketHandlerServer extends PacketHandler
         sendPacket(new DisconnectPacket(s));
         netManager.serverShutdown();
         mcServer.playerList.sendPacketToAllPlayers(new ChatPacket(playerEntity.getDisplayName() + TextFormatting.YELLOW + " was kicked from the game."));
-        mcServer.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(playerEntity.username, playerEntity.nickname, playerEntity.uuid, playerEntity.score, playerEntity.chatColor, false, playerEntity.isOperator()));
+        mcServer.playerList.updatePlayerProfile(playerEntity.username, playerEntity.nickname, playerEntity.uuid, playerEntity.score, playerEntity.chatColor, false, playerEntity.isOperator());
         mcServer.playerList.playerLoggedOut(playerEntity);
         connectionClosed = true;
         if (MinecraftServer.statsStatus)
         {
             RestHandler.post("https://api.betterthanadventure.net/stats?serverToken=" + MinecraftServer.statsToken + "&count=" + mcServer.playerList.playerEntities.size());
         }
-        PlayerList.updateList();
+        PlayerListBox.updateList();
     }
 
     @Override
@@ -366,6 +367,7 @@ public class PacketHandlerServer extends PacketHandler
         {
             sendPacket(new UpdatePlayerProfilePacket(playerServer.username, playerServer.nickname, playerServer.uuid, playerServer.score, playerServer.chatColor, true, playerServer.isOperator()));
         }
+        PlayerListBox.updateList();
     }
 
     @Override
@@ -433,14 +435,14 @@ public class PacketHandlerServer extends PacketHandler
     {
         LOGGER.info(playerEntity.username + " lost connection: " + message);
         mcServer.playerList.sendPacketToAllPlayers(new ChatPacket(playerEntity.getDisplayName() + TextFormatting.YELLOW + " left the game."));
-        mcServer.playerList.sendPacketToAllPlayers(new UpdatePlayerProfilePacket(playerEntity.username, playerEntity.nickname, playerEntity.uuid, playerEntity.score, playerEntity.chatColor, false, playerEntity.isOperator()));
+        mcServer.playerList.updatePlayerProfile(playerEntity.username, playerEntity.nickname, playerEntity.uuid, playerEntity.score, playerEntity.chatColor, false, playerEntity.isOperator());
         mcServer.playerList.playerLoggedOut(playerEntity);
         connectionClosed = true;
         if (MinecraftServer.statsStatus)
         {
             RestHandler.post("https://api.betterthanadventure.net/stats?serverToken=" + MinecraftServer.statsToken + "&count=" + mcServer.playerList.playerEntities.size());
         }
-        PlayerList.updateList();
+        PlayerListBox.updateList();
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/server/player/PlayerListBox.java b/src/main/java/net/minecraft/server/player/PlayerListBox.java
index 1b6dbbd76..ace904e31 100644
--- a/src/main/java/net/minecraft/server/player/PlayerListBox.java
+++ b/src/main/java/net/minecraft/server/player/PlayerListBox.java
@@ -3,8 +3,10 @@ package net.minecraft.server.player;
 import java.util.Vector;
 import javax.swing.JList;
 
+import net.minecraft.core.net.packet.PlayerListPacket;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.core.net.IUpdatePlayerListBox;
+import net.minecraft.server.entity.player.PlayerServer;
 
 public class PlayerListBox extends JList<String>
     implements IUpdatePlayerListBox
@@ -33,4 +35,22 @@ public class PlayerListBox extends JList<String>
             setListData(vector);
         }
     }
+
+    public static void updateList() {
+        MinecraftServer server = MinecraftServer.getInstance();
+
+        int playerCount = server.playerList.playerEntities.size();
+
+        String[] players = new String[playerCount];
+        String[] scores = new String[playerCount];
+
+        for(int i=0; i < playerCount; i++) {
+            PlayerServer player = server.playerList.playerEntities.get(i);
+
+            players[i] = player.getDisplayName();
+            scores[i] = String.valueOf(player.getScore());
+        }
+
+        server.playerList.sendPacketToAllPlayers(new PlayerListPacket(playerCount, players, scores));
+    }
 }
diff --git a/src/main/java/net/minecraft/server/util/helper/PlayerList.java b/src/main/java/net/minecraft/server/util/helper/PlayerList.java
deleted file mode 100644
index 6186336f3..000000000
--- a/src/main/java/net/minecraft/server/util/helper/PlayerList.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.minecraft.server.util.helper;
-
-import net.minecraft.core.net.packet.PlayerListPacket;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.entity.player.PlayerServer;
-
-public class PlayerList {
-	
-	public static void updateList() {
-		MinecraftServer server = MinecraftServer.getInstance();
-		
-    	int playerCount = server.playerList.playerEntities.size();
-    	
-    	String[] players = new String[playerCount];
-		String[] scores = new String[playerCount];
-    	
-    	for(int i=0; i < playerCount; i++) {
-    		PlayerServer player = server.playerList.playerEntities.get(i);
-    		
-    		players[i] = player.getDisplayName();
-    		scores[i] = String.valueOf(player.getScore());
-    	}
-        
-        server.playerList.sendPacketToAllPlayers(new PlayerListPacket(playerCount, players, scores));
-    }
-}
