PaperMC/Spigot-Server-Patches/0007-Store-reference-to-current-Chunk-for-Entity-and-Bloc.patch
Shane Freeder 56d8811924 Updated Upstream (Bukkit/Spigot)
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
eda400d3 SPIGOT-6213: MinecraftFont.getWidth(" ") returns 2 when it should be 3

Spigot Changes:
aa477927 #100: Allow sending messages from specific UUIDs
2020-11-03 09:14:21 +00:00

163 lines
6.9 KiB
Diff

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
@@ -56,11 +56,36 @@ public class Chunk implements IChunkAccess {
this(world, chunkcoordintpair, biomestorage, ChunkConverter.a, TickListEmpty.b(), TickListEmpty.b(), 0L, (ChunkSection[]) null, (Consumer) null);
}
+ // 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;
+ }
+
+ @Override
+ public TileEntity remove(Object key) {
+ TileEntity removed = super.remove(key);
+ if (removed != null) {
+ removed.setCurrentChunk(null);
+ }
+ return removed;
+ }
+ }
+ // Paper end
+
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) {
this.sections = new ChunkSection[16];
this.e = Maps.newHashMap();
this.heightMap = Maps.newEnumMap(HeightMap.Type.class);
- this.tileEntities = Maps.newHashMap();
+ this.tileEntities = new TileEntityHashMap(); // Paper
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
entity.chunkX = this.loc.x;
entity.chunkY = k;
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() {
- 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;
+ 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
index b8f0653e3e82824a62dfe64348a33ab6432b4e17..b9ffd000c97111678d45fd55dc9c207ebadc140e 100644
--- a/src/main/java/net/minecraft/server/TileEntity.java
+++ b/src/main/java/net/minecraft/server/TileEntity.java
@@ -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;
import net.minecraft.server.IChatBaseComponent;
import net.minecraft.server.NBTBase;
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