Paper/Spigot-Server-Patches/0007-Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch

164 lines
6.9 KiB
Diff
Raw Normal View History

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 4 Jul 2018 02:10:36 -0400
Subject: [PATCH] Store reference to current Chunk for Entity and Block
Entities
This enables us a fast reference to the entities current chunk instead
of having to look it up by hashmap lookups.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 157eccc8e45566db527c7d46d3b3d235c802c8f7..e46ed143a52eab4af15cc76606992c3bf68156c3 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
2020-06-25 11:27:25 +02:00
@@ -56,11 +56,36 @@ public class Chunk implements IChunkAccess {
2019-12-11 01:56:03 +01:00
this(world, chunkcoordintpair, biomestorage, ChunkConverter.a, TickListEmpty.b(), TickListEmpty.b(), 0L, (ChunkSection[]) null, (Consumer) null);
2019-05-14 04:20:58 +02:00
}
2019-04-24 03:00:24 +02:00
+ // Paper start
+ private class TileEntityHashMap extends java.util.HashMap<BlockPosition, TileEntity> {
+ @Override
+ public TileEntity put(BlockPosition key, TileEntity value) {
+ TileEntity replaced = super.put(key, value);
+ if (replaced != null) {
+ replaced.setCurrentChunk(null);
+ }
+ if (value != null) {
+ value.setCurrentChunk(Chunk.this);
+ }
+ return replaced;
+ }
2019-04-24 03:00:24 +02:00
+
+ @Override
+ public TileEntity remove(Object key) {
+ TileEntity removed = super.remove(key);
+ if (removed != null) {
+ removed.setCurrentChunk(null);
+ }
+ return removed;
+ }
+ }
+ // Paper end
2019-04-24 03:00:24 +02:00
+
2019-12-11 01:56:03 +01:00
public Chunk(World world, ChunkCoordIntPair chunkcoordintpair, BiomeStorage biomestorage, ChunkConverter chunkconverter, TickList<Block> ticklist, TickList<FluidType> ticklist1, long i, @Nullable ChunkSection[] achunksection, @Nullable Consumer<Chunk> consumer) {
2019-04-24 03:00:24 +02:00
this.sections = new ChunkSection[16];
this.e = Maps.newHashMap();
2018-10-23 01:16:21 +02:00
this.heightMap = Maps.newEnumMap(HeightMap.Type.class);
- this.tileEntities = Maps.newHashMap();
+ this.tileEntities = new TileEntityHashMap(); // Paper
2019-04-24 03:00:24 +02:00
this.l = Maps.newHashMap();
this.m = Maps.newHashMap();
this.n = new ShortList[16];
@@ -469,6 +494,7 @@ public class Chunk implements IChunkAccess {
}
entity.inChunk = true;
+ entity.setCurrentChunk(this); // Paper
2019-04-24 03:00:24 +02:00
entity.chunkX = this.loc.x;
entity.chunkY = k;
2019-04-24 03:00:24 +02:00
entity.chunkZ = this.loc.z;
@@ -481,6 +507,7 @@ public class Chunk implements IChunkAccess {
((HeightMap) this.heightMap.get(heightmap_type)).a(along);
}
+ public final void removeEntity(Entity entity) { this.b(entity); } // Paper - OBFHELPER
public void b(Entity entity) {
this.a(entity, entity.chunkY);
}
@@ -494,7 +521,12 @@ public class Chunk implements IChunkAccess {
i = this.entitySlices.length - 1;
}
- this.entitySlices[i].remove(entity);
+ // Paper start
+ if (entity.currentChunk != null && entity.currentChunk.get() == this) entity.setCurrentChunk(null);
+ if (!this.entitySlices[i].remove(entity)) {
+ return;
+ }
+ // Paper end
this.entities.remove(entity); // Paper
}
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index f6b97eec33ace01077e6bca58f3c11978422ac47..5e0db989a0f6c7c7041a968550f4068b9a946136 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -176,7 +176,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
public boolean isChunkLoaded() {
2020-06-25 11:27:25 +02:00
- return world.isChunkLoaded((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4);
+ return getCurrentChunk() != null;
}
// CraftBukkit end
@@ -1678,6 +1678,23 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
// Paper start
+ java.lang.ref.WeakReference<Chunk> currentChunk = null;
+
+ public void setCurrentChunk(Chunk chunk) {
+ this.currentChunk = chunk != null ? new java.lang.ref.WeakReference<>(chunk) : null;
+ }
+ /**
+ * Returns the entities current registered chunk. If the entity is not added to a chunk yet, it will return null
+ */
+ public Chunk getCurrentChunk() {
+ final Chunk chunk = currentChunk != null ? currentChunk.get() : null;
2020-06-25 11:27:25 +02:00
+ if (chunk != null && chunk.loaded) {
+ return chunk;
+ }
+
+ return !inChunk ? null : ((WorldServer)world).getChunkProvider().getChunkAtIfLoadedMainThreadNoCache(chunkX, chunkZ);
+ }
+
private MinecraftKey entityKey;
private String entityKeyString;
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
2020-10-17 22:42:18 +02:00
index b8f0653e3e82824a62dfe64348a33ab6432b4e17..b9ffd000c97111678d45fd55dc9c207ebadc140e 100644
--- a/src/main/java/net/minecraft/server/TileEntity.java
+++ b/src/main/java/net/minecraft/server/TileEntity.java
2019-05-14 04:20:58 +02:00
@@ -51,6 +51,15 @@ public abstract class TileEntity implements KeyedObject { // Paper
getMinecraftKey(); // Try to load if it doesn't exists.
return tileEntityKeyString;
}
+
+ private java.lang.ref.WeakReference<Chunk> currentChunk = null;
+ public Chunk getCurrentChunk() {
+ final Chunk chunk = currentChunk != null ? currentChunk.get() : null;
+ return chunk != null && chunk.loaded ? chunk : null;
+ }
+ public void setCurrentChunk(Chunk chunk) {
+ this.currentChunk = chunk != null ? new java.lang.ref.WeakReference<>(chunk) : null;
+ }
// Paper end
@Nullable
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 8c1a66b921c6a63a5446efa24f2e2115010cae41..c20f161eb42159edcfe2c47e3749d88fba9b4747 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -145,6 +145,7 @@ import net.minecraft.server.EntityZombieVillager;
2019-04-24 03:00:24 +02:00
import net.minecraft.server.IChatBaseComponent;
2020-10-17 22:42:18 +02:00
import net.minecraft.server.NBTBase;
2019-04-24 03:00:24 +02:00
import net.minecraft.server.NBTTagCompound;
+import org.bukkit.Chunk; // Paper
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.Server;
@@ -186,6 +187,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
this.entity = entity;
}
+ @Override
+ public Chunk getChunk() {
+ net.minecraft.server.Chunk currentChunk = entity.getCurrentChunk();
+ return currentChunk != null ? currentChunk.bukkitChunk : getLocation().getChunk();
+ }
+
public static CraftEntity getEntity(CraftServer server, Entity entity) {
/*
* Order is *EXTREMELY* important -- keep it right! =D