From f6b887b61946da9ef46e4a450360f72f44082449 Mon Sep 17 00:00:00 2001
From: asie <kontakt@asie.pl>
Date: Tue, 11 Dec 2018 17:51:23 +0100
Subject: [PATCH] add entity tracker hooks, fix crash after tweaking
 HandlerList

---
 build.gradle                                  |  2 +-
 .../fabric/block/FabricBlockSettings.java     |  2 +-
 .../fabric/entity/EntityTrackingRegistry.java | 69 +++++++++++++++++++
 .../entity/FabricEntityTypeBuilder.java       | 57 +++++++++++++++
 .../fabric/events/ObjectBuilderEvent.java     |  4 +-
 .../fabric/events/PlayerInteractionEvent.java | 10 +--
 .../fabricmc/fabric/events/ServerEvent.java   |  2 +-
 .../net/fabricmc/fabric/events/TickEvent.java |  4 +-
 .../fabric/events/client/ClientTickEvent.java |  2 +-
 .../fabric/events/client/SpriteEvent.java     |  2 +-
 .../mixin/entity/MixinEntityTracker.java      | 27 ++++++++
 .../mixin/entity/MixinEntityTrackerEntry.java | 26 +++++++
 .../fabric/mixin/registry/MixinBootstrap.java |  8 +--
 .../registry/client/MixinBlockColorMap.java   |  4 +-
 .../registry/client/MixinItemColorMap.java    |  2 +-
 .../BootstrapBiomeRegistryListener.java       |  4 +-
 .../BootstrapBlockRegistryListener.java       |  3 +-
 .../BootstrapFluidRegistryListener.java       |  4 +-
 .../BootstrapItemRegistryListener.java        |  3 +-
 .../{ => impl}/listeners/IdListUpdater.java   |  2 +-
 .../net/fabricmc/fabric/util/HandlerList.java | 11 +--
 .../net.fabricmc.fabric.mixins.common.json    |  2 +
 22 files changed, 213 insertions(+), 37 deletions(-)
 create mode 100644 src/main/java/net/fabricmc/fabric/entity/EntityTrackingRegistry.java
 create mode 100644 src/main/java/net/fabricmc/fabric/entity/FabricEntityTypeBuilder.java
 create mode 100644 src/main/java/net/fabricmc/fabric/mixin/entity/MixinEntityTracker.java
 create mode 100644 src/main/java/net/fabricmc/fabric/mixin/entity/MixinEntityTrackerEntry.java
 rename src/main/java/net/fabricmc/fabric/registry/{ => impl}/listeners/BootstrapBiomeRegistryListener.java (91%)
 rename src/main/java/net/fabricmc/fabric/registry/{ => impl}/listeners/BootstrapBlockRegistryListener.java (93%)
 rename src/main/java/net/fabricmc/fabric/registry/{ => impl}/listeners/BootstrapFluidRegistryListener.java (91%)
 rename src/main/java/net/fabricmc/fabric/registry/{ => impl}/listeners/BootstrapItemRegistryListener.java (92%)
 rename src/main/java/net/fabricmc/fabric/registry/{ => impl}/listeners/IdListUpdater.java (97%)

diff --git a/build.gradle b/build.gradle
index 0069bdae6..b3b3d6595 100644
--- a/build.gradle
+++ b/build.gradle
@@ -34,7 +34,7 @@ minecraft {
 
 dependencies {
 	minecraft "com.mojang:minecraft:18w49a"
-	mappings "net.fabricmc:yarn:18w49a.6"
+	mappings "net.fabricmc:yarn:18w49a.11"
 	modCompile "net.fabricmc:fabric-loader:0.2.0.62"
 }
 
diff --git a/src/main/java/net/fabricmc/fabric/block/FabricBlockSettings.java b/src/main/java/net/fabricmc/fabric/block/FabricBlockSettings.java
index c9c062760..8e5da693f 100644
--- a/src/main/java/net/fabricmc/fabric/block/FabricBlockSettings.java
+++ b/src/main/java/net/fabricmc/fabric/block/FabricBlockSettings.java
@@ -54,7 +54,7 @@ public class FabricBlockSettings {
 	private final FabricBlockSettings.Delegate castDelegate;
 
 	protected FabricBlockSettings(Material material, MaterialColor color) {
-		this(Block.Settings.create(material, color));
+		this(Block.Settings.of(material, color));
 	}
 
 	protected FabricBlockSettings(Block base) {
diff --git a/src/main/java/net/fabricmc/fabric/entity/EntityTrackingRegistry.java b/src/main/java/net/fabricmc/fabric/entity/EntityTrackingRegistry.java
new file mode 100644
index 000000000..cbf16fb60
--- /dev/null
+++ b/src/main/java/net/fabricmc/fabric/entity/EntityTrackingRegistry.java
@@ -0,0 +1,69 @@
+package net.fabricmc.fabric.entity;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.network.Packet;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+// TODO: javadocs
+public class EntityTrackingRegistry {
+	public static class Entry {
+		private final int trackingDistance;
+		private final int updateIntervalTicks;
+		private final boolean alwaysUpdateVelocity;
+
+		public Entry(int trackingDistance, int updateIntervalTicks, boolean alwaysUpdateVelocity) {
+			this.trackingDistance = trackingDistance;
+			this.updateIntervalTicks = updateIntervalTicks;
+			this.alwaysUpdateVelocity = alwaysUpdateVelocity;
+		}
+
+		public int getTrackingDistance() {
+			return trackingDistance;
+		}
+
+		public int getUpdateIntervalTicks() {
+			return updateIntervalTicks;
+		}
+
+		public boolean alwaysUpdateVelocity() {
+			return alwaysUpdateVelocity;
+		}
+	}
+
+	public static final EntityTrackingRegistry INSTANCE = new EntityTrackingRegistry();
+	private final Map<EntityType, Entry> entries = new HashMap<>();
+	private final Map<EntityType, Function<Entity, Packet>> spawnPacketProviders = new HashMap<>();
+
+	private EntityTrackingRegistry() {
+
+	}
+
+	public Entry get(EntityType type) {
+		return entries.get(type);
+	}
+
+	public Packet createSpawnPacket(Entity entity) {
+		Function<Entity, Packet> packetFunction = spawnPacketProviders.get(entity.getType());
+		if (packetFunction != null) {
+			return packetFunction.apply(entity);
+		} else {
+			return null;
+		}
+	}
+
+	public void register(EntityType type, int trackingDistance, int updateIntervalTicks) {
+		register(type, trackingDistance, updateIntervalTicks, true);
+	}
+
+	public void register(EntityType type, int trackingDistance, int updateIntervalTicks, boolean alwaysUpdateVelocity) {
+		entries.put(type, new Entry(trackingDistance, updateIntervalTicks, alwaysUpdateVelocity));
+	}
+
+	public void registerSpawnPacketProvider(EntityType type, Function<Entity, Packet> packetFunction) {
+		spawnPacketProviders.put(type, packetFunction);
+	}
+}
diff --git a/src/main/java/net/fabricmc/fabric/entity/FabricEntityTypeBuilder.java b/src/main/java/net/fabricmc/fabric/entity/FabricEntityTypeBuilder.java
new file mode 100644
index 000000000..1892ad094
--- /dev/null
+++ b/src/main/java/net/fabricmc/fabric/entity/FabricEntityTypeBuilder.java
@@ -0,0 +1,57 @@
+package net.fabricmc.fabric.entity;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.entity.EntityType.Builder;
+import net.minecraft.world.World;
+
+import java.util.function.Function;
+
+// TODO: javadocs
+public class FabricEntityTypeBuilder<T extends Entity> {
+	protected final EntityType.Builder<T> delegate;
+	private int trackingDistance = -1;
+	private int updateIntervalTicks = -1;
+	private boolean alwaysUpdateVelocity = true;
+
+	protected FabricEntityTypeBuilder(EntityType.Builder<T> delegate) {
+		this.delegate = delegate;
+	}
+
+	public static <T extends Entity> FabricEntityTypeBuilder<T> create(Class<? extends T> entityClass) {
+		return new FabricEntityTypeBuilder<>(EntityType.Builder.create(entityClass));
+	}
+
+	public static <T extends Entity> FabricEntityTypeBuilder<T> create(Class<? extends T> entityClass, Function<? super World, ? extends T> function) {
+		return new FabricEntityTypeBuilder<>(EntityType.Builder.create(entityClass, function));
+	}
+
+	public FabricEntityTypeBuilder<T> disableSummon() {
+		delegate.disableSummon();
+		return this;
+	}
+
+	public FabricEntityTypeBuilder<T> disableSaving() {
+		delegate.disableSaving();
+		return this;
+	}
+
+	public FabricEntityTypeBuilder<T> trackable(int trackingDistance, int updateIntervalTicks) {
+		return trackable(trackingDistance, updateIntervalTicks, true);
+	}
+
+	public FabricEntityTypeBuilder<T> trackable(int trackingDistance, int updateIntervalTicks, boolean alwaysUpdateVelocity) {
+		this.trackingDistance = trackingDistance;
+		this.updateIntervalTicks = updateIntervalTicks;
+		this.alwaysUpdateVelocity = alwaysUpdateVelocity;
+		return this;
+	}
+
+	public EntityType<T> build(String id) {
+		EntityType type = delegate.build(id);
+		if (trackingDistance != -1) {
+			EntityTrackingRegistry.INSTANCE.register(type, trackingDistance, updateIntervalTicks, alwaysUpdateVelocity);
+		}
+		return type;
+	}
+}
diff --git a/src/main/java/net/fabricmc/fabric/events/ObjectBuilderEvent.java b/src/main/java/net/fabricmc/fabric/events/ObjectBuilderEvent.java
index 252b1f634..c3c8dd2fc 100644
--- a/src/main/java/net/fabricmc/fabric/events/ObjectBuilderEvent.java
+++ b/src/main/java/net/fabricmc/fabric/events/ObjectBuilderEvent.java
@@ -29,8 +29,8 @@ import java.util.function.BiConsumer;
  * your own methods and transparently add the resulting information to a Map.
  */
 public final class ObjectBuilderEvent {
-	public static final HandlerRegistry<BiConsumer<Block.Settings, Block>> BLOCK = new HandlerList<>();
-	public static final HandlerRegistry<BiConsumer<Item.Settings, Item>> ITEM = new HandlerList<>();
+	public static final HandlerRegistry<BiConsumer<Block.Settings, Block>> BLOCK = new HandlerList<>(BiConsumer.class);
+	public static final HandlerRegistry<BiConsumer<Item.Settings, Item>> ITEM = new HandlerList<>(BiConsumer.class);
 
 	private ObjectBuilderEvent() {
 
diff --git a/src/main/java/net/fabricmc/fabric/events/PlayerInteractionEvent.java b/src/main/java/net/fabricmc/fabric/events/PlayerInteractionEvent.java
index 59347de33..d7885c629 100644
--- a/src/main/java/net/fabricmc/fabric/events/PlayerInteractionEvent.java
+++ b/src/main/java/net/fabricmc/fabric/events/PlayerInteractionEvent.java
@@ -66,12 +66,12 @@ public final class PlayerInteractionEvent {
 	/**
 	 * Event emitted when a player "attacks" a block.
 	 */
-	public static final HandlerRegistry<Block> ATTACK_BLOCK = new HandlerList<>();
+	public static final HandlerRegistry<Block> ATTACK_BLOCK = new HandlerList<>(Block.class);
 
 	/**
 	 * Event emitted when a player "attacks" an entity.
 	 */
-	public static final HandlerRegistry<Entity> ATTACK_ENTITY = new HandlerList<>();
+	public static final HandlerRegistry<Entity> ATTACK_ENTITY = new HandlerList<>(Entity.class);
 	
 	// TODO: For completeness' sake, but requires us to add a custom packet. Is it worth the complexity?
 	/* public static final HandlerRegistry<Item> ATTACK_ITEM = new HandlerList<>(); */
@@ -79,7 +79,7 @@ public final class PlayerInteractionEvent {
 	/**
 	 * Event emitted when a player interacts with a block.
 	 */
-	public static final HandlerRegistry<BlockPositioned> INTERACT_BLOCK = new HandlerList<>();
+	public static final HandlerRegistry<BlockPositioned> INTERACT_BLOCK = new HandlerList<>(BlockPositioned.class);
 
 	/**
 	 * Event emitted when a player interacts with an entity.
@@ -90,12 +90,12 @@ public final class PlayerInteractionEvent {
 	 * only one event is currently provided, but it is accordingly named in
 	 * the case of a second event being necessary.
 	 */
-	public static final HandlerRegistry<EntityPositioned> INTERACT_ENTITY_POSITIONED = new HandlerList<>();
+	public static final HandlerRegistry<EntityPositioned> INTERACT_ENTITY_POSITIONED = new HandlerList<>(EntityPositioned.class);
 
 	/**
 	 * Event emitted when a player interacts with an item.
 	 */
-	public static final HandlerRegistry<Item> INTERACT_ITEM = new HandlerList<>();
+	public static final HandlerRegistry<Item> INTERACT_ITEM = new HandlerList<>(Item.class);
 
 	/**
 	 * @deprecated Use {@link #ATTACK_BLOCK ATTACK_BLOCK} instead.
diff --git a/src/main/java/net/fabricmc/fabric/events/ServerEvent.java b/src/main/java/net/fabricmc/fabric/events/ServerEvent.java
index 9ff1df663..4f8804cf6 100644
--- a/src/main/java/net/fabricmc/fabric/events/ServerEvent.java
+++ b/src/main/java/net/fabricmc/fabric/events/ServerEvent.java
@@ -25,7 +25,7 @@ import net.minecraft.world.World;
 import java.util.function.Consumer;
 
 public final class ServerEvent {
-	public static final HandlerRegistry<Consumer<MinecraftServer>> START = new HandlerList<>();
+	public static final HandlerRegistry<Consumer<MinecraftServer>> START = new HandlerList<>(Consumer.class);
 
 	private ServerEvent() {
 
diff --git a/src/main/java/net/fabricmc/fabric/events/TickEvent.java b/src/main/java/net/fabricmc/fabric/events/TickEvent.java
index b179aa2f1..5fab90e06 100644
--- a/src/main/java/net/fabricmc/fabric/events/TickEvent.java
+++ b/src/main/java/net/fabricmc/fabric/events/TickEvent.java
@@ -29,8 +29,8 @@ import java.util.function.Consumer;
  * You can use them as endpoints to tick your own, related logic "globally".
  */
 public final class TickEvent {
-	public static final HandlerRegistry<Consumer<MinecraftServer>> SERVER = new HandlerList<>();
-	public static final HandlerRegistry<Consumer<World>> WORLD = new HandlerList<>();
+	public static final HandlerRegistry<Consumer<MinecraftServer>> SERVER = new HandlerList<>(Consumer.class);
+	public static final HandlerRegistry<Consumer<World>> WORLD = new HandlerList<>(Consumer.class);
 
 	private TickEvent() {
 
diff --git a/src/main/java/net/fabricmc/fabric/events/client/ClientTickEvent.java b/src/main/java/net/fabricmc/fabric/events/client/ClientTickEvent.java
index 4264c6674..13f978934 100644
--- a/src/main/java/net/fabricmc/fabric/events/client/ClientTickEvent.java
+++ b/src/main/java/net/fabricmc/fabric/events/client/ClientTickEvent.java
@@ -29,7 +29,7 @@ import java.util.function.Consumer;
  * @see TickEvent
  */
 public final class ClientTickEvent {
-	public static final HandlerRegistry<Consumer<MinecraftClient>> CLIENT = new HandlerList<>();
+	public static final HandlerRegistry<Consumer<MinecraftClient>> CLIENT = new HandlerList<>(Consumer.class);
 
 	private ClientTickEvent() {
 
diff --git a/src/main/java/net/fabricmc/fabric/events/client/SpriteEvent.java b/src/main/java/net/fabricmc/fabric/events/client/SpriteEvent.java
index 004b240e1..8f8aecefb 100644
--- a/src/main/java/net/fabricmc/fabric/events/client/SpriteEvent.java
+++ b/src/main/java/net/fabricmc/fabric/events/client/SpriteEvent.java
@@ -26,5 +26,5 @@ public class SpriteEvent {
 		void registerSprites(SpriteRegistry registry);
 	}
 
-	public static final HandlerRegistry<Provider> PROVIDE = new HandlerList<>();
+	public static final HandlerRegistry<Provider> PROVIDE = new HandlerList<>(Provider.class);
 }
diff --git a/src/main/java/net/fabricmc/fabric/mixin/entity/MixinEntityTracker.java b/src/main/java/net/fabricmc/fabric/mixin/entity/MixinEntityTracker.java
new file mode 100644
index 000000000..01530aa69
--- /dev/null
+++ b/src/main/java/net/fabricmc/fabric/mixin/entity/MixinEntityTracker.java
@@ -0,0 +1,27 @@
+package net.fabricmc.fabric.mixin.entity;
+
+import net.fabricmc.fabric.entity.EntityTrackingRegistry;
+import net.minecraft.entity.Entity;
+import net.minecraft.server.network.EntityTracker;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(EntityTracker.class)
+public abstract class MixinEntityTracker {
+	@Shadow
+	public abstract void add(Entity var1, int var2, int var3, boolean var4);
+
+	@Inject(at = @At("HEAD"), method = "add", cancellable = true)
+	public void add(Entity entity, CallbackInfo info) {
+		if (entity != null) {
+			EntityTrackingRegistry.Entry entry = EntityTrackingRegistry.INSTANCE.get(entity.getType());
+			if (entry != null) {
+				add(entity, entry.getTrackingDistance(), entry.getUpdateIntervalTicks(), entry.alwaysUpdateVelocity());
+				info.cancel();
+			}
+		}
+	}
+}
diff --git a/src/main/java/net/fabricmc/fabric/mixin/entity/MixinEntityTrackerEntry.java b/src/main/java/net/fabricmc/fabric/mixin/entity/MixinEntityTrackerEntry.java
new file mode 100644
index 000000000..9d692b76b
--- /dev/null
+++ b/src/main/java/net/fabricmc/fabric/mixin/entity/MixinEntityTrackerEntry.java
@@ -0,0 +1,26 @@
+package net.fabricmc.fabric.mixin.entity;
+
+import net.fabricmc.fabric.entity.EntityTrackingRegistry;
+import net.minecraft.entity.Entity;
+import net.minecraft.network.Packet;
+import net.minecraft.server.network.EntityTrackerEntry;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+@Mixin(EntityTrackerEntry.class)
+public class MixinEntityTrackerEntry {
+	@Shadow
+	private Entity entity;
+
+	@Inject(at = @At(value = "CONSTANT", args = {"stringValue=Don't know how to add "}), method = "createSpawnPacket", cancellable = true)
+	public void createSpawnPacket(CallbackInfoReturnable<Packet> info) {
+		Packet packet = EntityTrackingRegistry.INSTANCE.createSpawnPacket(entity);
+		if (packet != null) {
+			info.setReturnValue(packet);
+			info.cancel();
+		}
+	}
+}
diff --git a/src/main/java/net/fabricmc/fabric/mixin/registry/MixinBootstrap.java b/src/main/java/net/fabricmc/fabric/mixin/registry/MixinBootstrap.java
index ac62ed672..6966efe9d 100644
--- a/src/main/java/net/fabricmc/fabric/mixin/registry/MixinBootstrap.java
+++ b/src/main/java/net/fabricmc/fabric/mixin/registry/MixinBootstrap.java
@@ -19,10 +19,10 @@ package net.fabricmc.fabric.mixin.registry;
 import net.fabricmc.fabric.networking.CustomPayloadPacketRegistry;
 import net.fabricmc.fabric.registry.ListenableRegistry;
 import net.fabricmc.fabric.registry.RegistrySyncManager;
-import net.fabricmc.fabric.registry.listeners.BootstrapBiomeRegistryListener;
-import net.fabricmc.fabric.registry.listeners.BootstrapBlockRegistryListener;
-import net.fabricmc.fabric.registry.listeners.BootstrapFluidRegistryListener;
-import net.fabricmc.fabric.registry.listeners.BootstrapItemRegistryListener;
+import net.fabricmc.fabric.registry.impl.listeners.BootstrapBiomeRegistryListener;
+import net.fabricmc.fabric.registry.impl.listeners.BootstrapBlockRegistryListener;
+import net.fabricmc.fabric.registry.impl.listeners.BootstrapFluidRegistryListener;
+import net.fabricmc.fabric.registry.impl.listeners.BootstrapItemRegistryListener;
 import net.minecraft.Bootstrap;
 import net.minecraft.block.Block;
 import net.minecraft.block.Blocks;
diff --git a/src/main/java/net/fabricmc/fabric/mixin/registry/client/MixinBlockColorMap.java b/src/main/java/net/fabricmc/fabric/mixin/registry/client/MixinBlockColorMap.java
index 627422670..ef5920086 100644
--- a/src/main/java/net/fabricmc/fabric/mixin/registry/client/MixinBlockColorMap.java
+++ b/src/main/java/net/fabricmc/fabric/mixin/registry/client/MixinBlockColorMap.java
@@ -17,12 +17,10 @@
 package net.fabricmc.fabric.mixin.registry.client;
 
 import net.fabricmc.fabric.registry.ListenableRegistry;
-import net.fabricmc.fabric.registry.listeners.IdListUpdater;
+import net.fabricmc.fabric.registry.impl.listeners.IdListUpdater;
 import net.minecraft.block.Block;
 import net.minecraft.client.render.block.BlockColorMap;
 import net.minecraft.client.render.block.BlockColorMapper;
-import net.minecraft.client.render.item.ItemColorMap;
-import net.minecraft.client.render.item.ItemColorMapper;
 import net.minecraft.util.IdList;
 import net.minecraft.util.registry.Registry;
 import org.spongepowered.asm.mixin.Mixin;
diff --git a/src/main/java/net/fabricmc/fabric/mixin/registry/client/MixinItemColorMap.java b/src/main/java/net/fabricmc/fabric/mixin/registry/client/MixinItemColorMap.java
index b184aee34..2e1eb4344 100644
--- a/src/main/java/net/fabricmc/fabric/mixin/registry/client/MixinItemColorMap.java
+++ b/src/main/java/net/fabricmc/fabric/mixin/registry/client/MixinItemColorMap.java
@@ -17,7 +17,7 @@
 package net.fabricmc.fabric.mixin.registry.client;
 
 import net.fabricmc.fabric.registry.ListenableRegistry;
-import net.fabricmc.fabric.registry.listeners.IdListUpdater;
+import net.fabricmc.fabric.registry.impl.listeners.IdListUpdater;
 import net.minecraft.client.render.block.BlockColorMap;
 import net.minecraft.client.render.item.ItemColorMap;
 import net.minecraft.client.render.item.ItemColorMapper;
diff --git a/src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapBiomeRegistryListener.java b/src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapBiomeRegistryListener.java
similarity index 91%
rename from src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapBiomeRegistryListener.java
rename to src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapBiomeRegistryListener.java
index f6c034251..d136318bd 100644
--- a/src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapBiomeRegistryListener.java
+++ b/src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapBiomeRegistryListener.java
@@ -14,12 +14,10 @@
  * limitations under the License.
  */
 
-package net.fabricmc.fabric.registry.listeners;
+package net.fabricmc.fabric.registry.impl.listeners;
 
 import net.fabricmc.fabric.registry.ExtendedIdList;
 import net.fabricmc.fabric.registry.RegistryListener;
-import net.minecraft.block.Block;
-import net.minecraft.block.BlockState;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.registry.Registry;
 import net.minecraft.world.biome.Biome;
diff --git a/src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapBlockRegistryListener.java b/src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapBlockRegistryListener.java
similarity index 93%
rename from src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapBlockRegistryListener.java
rename to src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapBlockRegistryListener.java
index a634c1948..b27739dfe 100644
--- a/src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapBlockRegistryListener.java
+++ b/src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapBlockRegistryListener.java
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
-package net.fabricmc.fabric.registry.listeners;
+package net.fabricmc.fabric.registry.impl.listeners;
 
-import com.google.common.collect.UnmodifiableIterator;
 import net.fabricmc.fabric.registry.ExtendedIdList;
 import net.fabricmc.fabric.registry.RegistryListener;
 import net.minecraft.block.Block;
diff --git a/src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapFluidRegistryListener.java b/src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapFluidRegistryListener.java
similarity index 91%
rename from src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapFluidRegistryListener.java
rename to src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapFluidRegistryListener.java
index 24ab9295f..e2757fadd 100644
--- a/src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapFluidRegistryListener.java
+++ b/src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapFluidRegistryListener.java
@@ -14,12 +14,10 @@
  * limitations under the License.
  */
 
-package net.fabricmc.fabric.registry.listeners;
+package net.fabricmc.fabric.registry.impl.listeners;
 
 import net.fabricmc.fabric.registry.ExtendedIdList;
 import net.fabricmc.fabric.registry.RegistryListener;
-import net.minecraft.block.Block;
-import net.minecraft.block.BlockState;
 import net.minecraft.fluid.Fluid;
 import net.minecraft.fluid.FluidState;
 import net.minecraft.util.Identifier;
diff --git a/src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapItemRegistryListener.java b/src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapItemRegistryListener.java
similarity index 92%
rename from src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapItemRegistryListener.java
rename to src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapItemRegistryListener.java
index b91825486..e543e050c 100644
--- a/src/main/java/net/fabricmc/fabric/registry/listeners/BootstrapItemRegistryListener.java
+++ b/src/main/java/net/fabricmc/fabric/registry/impl/listeners/BootstrapItemRegistryListener.java
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
-package net.fabricmc.fabric.registry.listeners;
+package net.fabricmc.fabric.registry.impl.listeners;
 
-import net.fabricmc.fabric.registry.ExtendedIdList;
 import net.fabricmc.fabric.registry.RegistryListener;
 import net.minecraft.item.Item;
 import net.minecraft.item.block.BlockItem;
diff --git a/src/main/java/net/fabricmc/fabric/registry/listeners/IdListUpdater.java b/src/main/java/net/fabricmc/fabric/registry/impl/listeners/IdListUpdater.java
similarity index 97%
rename from src/main/java/net/fabricmc/fabric/registry/listeners/IdListUpdater.java
rename to src/main/java/net/fabricmc/fabric/registry/impl/listeners/IdListUpdater.java
index b9472ac57..ee217f3ea 100644
--- a/src/main/java/net/fabricmc/fabric/registry/listeners/IdListUpdater.java
+++ b/src/main/java/net/fabricmc/fabric/registry/impl/listeners/IdListUpdater.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package net.fabricmc.fabric.registry.listeners;
+package net.fabricmc.fabric.registry.impl.listeners;
 
 import net.fabricmc.fabric.registry.ExtendedIdList;
 import net.fabricmc.fabric.registry.RegistryListener;
diff --git a/src/main/java/net/fabricmc/fabric/util/HandlerList.java b/src/main/java/net/fabricmc/fabric/util/HandlerList.java
index fb9b676b6..5be07302d 100644
--- a/src/main/java/net/fabricmc/fabric/util/HandlerList.java
+++ b/src/main/java/net/fabricmc/fabric/util/HandlerList.java
@@ -16,13 +16,16 @@
 
 package net.fabricmc.fabric.util;
 
+import java.lang.reflect.Array;
+
 public class HandlerList<T> implements HandlerRegistry<T> {
-	private static final Object[] EMPTY = new Object[0];
+	private final Class tClass;
 	private T[] array;
 
 	@SuppressWarnings("unchecked")
-	public HandlerList() {
-		this.array = (T[]) EMPTY;
+	public HandlerList(Class theClass) {
+		this.tClass = theClass;
+		this.array = (T[]) Array.newInstance(tClass, 0);
 	}
 
 	@Override
@@ -34,7 +37,7 @@ public class HandlerList<T> implements HandlerRegistry<T> {
 		}
 
 		//noinspection unchecked
-		T[] newArray = (T[]) new Object[array.length + 1];
+		T[] newArray = (T[]) Array.newInstance(tClass, array.length + 1);
 		System.arraycopy(array, 0, newArray, 0, array.length);
 		newArray[array.length] = handler;
 		array = newArray;
diff --git a/src/main/resources/net.fabricmc.fabric.mixins.common.json b/src/main/resources/net.fabricmc.fabric.mixins.common.json
index 0b7b280b5..885df0d6d 100644
--- a/src/main/resources/net.fabricmc.fabric.mixins.common.json
+++ b/src/main/resources/net.fabricmc.fabric.mixins.common.json
@@ -6,6 +6,8 @@
     "block.MixinBlockBuilder",
     "block.entity.MixinBlockEntity",
     "commands.MixinServerCommandManager",
+    "entity.MixinEntityTracker",
+    "entity.MixinEntityTrackerEntry",
     "events.objectbuilder.MixinBlock",
     "events.objectbuilder.MixinItem",
     "events.playerinteraction.MixinServerPlayNetworkHandler",