2020-05-06 09:48:49 +00:00
|
|
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
2018-07-04 07:55:24 +00:00
|
|
|
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
|
2020-08-25 02:22:08 +00:00
|
|
|
index 3b3e94cff2c6def318864bb5b7baefcf9de2cae7..6bd9457ad5c9fb1c0f12ff345b531be0673e866e 100644
|
2018-07-04 07:55:24 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
2020-06-25 09:27:25 +00:00
|
|
|
@@ -56,11 +56,36 @@ public class Chunk implements IChunkAccess {
|
2019-12-11 00:56:03 +00:00
|
|
|
this(world, chunkcoordintpair, biomestorage, ChunkConverter.a, TickListEmpty.b(), TickListEmpty.b(), 0L, (ChunkSection[]) null, (Consumer) null);
|
2019-05-14 02:20:58 +00:00
|
|
|
}
|
2019-04-24 01:00:24 +00:00
|
|
|
|
2018-07-04 07:55:24 +00: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 01:00:24 +00:00
|
|
|
+
|
2018-07-04 07:55:24 +00: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 01:00:24 +00:00
|
|
|
+
|
2019-12-11 00:56:03 +00: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 01:00:24 +00:00
|
|
|
this.sections = new ChunkSection[16];
|
|
|
|
this.e = Maps.newHashMap();
|
2018-10-22 23:16:21 +00:00
|
|
|
this.heightMap = Maps.newEnumMap(HeightMap.Type.class);
|
2018-07-04 07:55:24 +00:00
|
|
|
- this.tileEntities = Maps.newHashMap();
|
|
|
|
+ this.tileEntities = new TileEntityHashMap(); // Paper
|
2019-04-24 01:00:24 +00:00
|
|
|
this.l = Maps.newHashMap();
|
|
|
|
this.m = Maps.newHashMap();
|
|
|
|
this.n = new ShortList[16];
|
2020-06-25 09:27:25 +00:00
|
|
|
@@ -466,6 +491,7 @@ public class Chunk implements IChunkAccess {
|
2019-04-06 03:08:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
entity.inChunk = true;
|
|
|
|
+ entity.setCurrentChunk(this); // Paper
|
2019-04-24 01:00:24 +00:00
|
|
|
entity.chunkX = this.loc.x;
|
2018-12-17 05:18:06 +00:00
|
|
|
entity.chunkY = k;
|
2019-04-24 01:00:24 +00:00
|
|
|
entity.chunkZ = this.loc.z;
|
2020-06-25 09:27:25 +00:00
|
|
|
@@ -478,6 +504,7 @@ public class Chunk implements IChunkAccess {
|
2019-04-06 03:08:45 +00:00
|
|
|
((HeightMap) this.heightMap.get(heightmap_type)).a(along);
|
2018-07-04 07:55:24 +00:00
|
|
|
}
|
|
|
|
|
2020-08-02 05:39:36 +00:00
|
|
|
+ public final void removeEntity(Entity entity) { this.b(entity); } // Paper - OBFHELPER
|
2019-04-06 03:08:45 +00:00
|
|
|
public void b(Entity entity) {
|
|
|
|
this.a(entity, entity.chunkY);
|
|
|
|
}
|
2020-06-25 09:27:25 +00:00
|
|
|
@@ -491,7 +518,12 @@ public class Chunk implements IChunkAccess {
|
2018-07-15 01:53:17 +00:00
|
|
|
i = this.entitySlices.length - 1;
|
2018-07-04 07:55:24 +00:00
|
|
|
}
|
2020-01-31 16:09:56 +00:00
|
|
|
|
2018-07-15 01:53:17 +00:00
|
|
|
- this.entitySlices[i].remove(entity);
|
2018-07-04 07:55:24 +00:00
|
|
|
+ // Paper start
|
2019-04-06 03:08:45 +00:00
|
|
|
+ if (entity.currentChunk != null && entity.currentChunk.get() == this) entity.setCurrentChunk(null);
|
2018-07-15 01:53:17 +00:00
|
|
|
+ if (!this.entitySlices[i].remove(entity)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
2018-07-04 07:55:24 +00:00
|
|
|
+ // Paper end
|
2020-01-31 16:09:56 +00:00
|
|
|
this.entities.remove(entity); // Paper
|
2018-07-04 07:55:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
2020-09-19 11:29:53 +00:00
|
|
|
index 8cd7c8d5d1a20239ffb3b064f8bd0b7a45cfc63f..cd7866f2251f68f24801eacc55800907f184537f 100644
|
2018-07-04 07:55:24 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
2020-09-19 11:29:53 +00:00
|
|
|
@@ -176,7 +176,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
2020-04-02 04:43:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isChunkLoaded() {
|
2020-06-25 09:27:25 +00:00
|
|
|
- return world.isChunkLoaded((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4);
|
2020-04-02 04:43:11 +00:00
|
|
|
+ return getCurrentChunk() != null;
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
|
2020-09-19 11:29:53 +00:00
|
|
|
@@ -1678,6 +1678,23 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
2018-07-04 07:55:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Paper start
|
2019-04-06 03:08:45 +00:00
|
|
|
+ java.lang.ref.WeakReference<Chunk> currentChunk = null;
|
2018-07-14 04:12:42 +00:00
|
|
|
+
|
|
|
|
+ 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
|
|
|
|
+ */
|
2018-07-04 07:55:24 +00:00
|
|
|
+ public Chunk getCurrentChunk() {
|
2018-07-09 02:39:46 +00:00
|
|
|
+ final Chunk chunk = currentChunk != null ? currentChunk.get() : null;
|
2020-06-25 09:27:25 +00:00
|
|
|
+ if (chunk != null && chunk.loaded) {
|
2020-04-02 04:43:11 +00:00
|
|
|
+ return chunk;
|
|
|
|
+ }
|
|
|
|
+
|
2020-08-02 05:39:36 +00:00
|
|
|
+ return !inChunk ? null : ((WorldServer)world).getChunkProvider().getChunkAtIfLoadedMainThreadNoCache(chunkX, chunkZ);
|
2018-07-04 07:55:24 +00:00
|
|
|
+ }
|
2018-07-15 01:53:17 +00:00
|
|
|
+
|
2018-07-27 04:44:53 +00:00
|
|
|
private MinecraftKey entityKey;
|
|
|
|
private String entityKeyString;
|
2018-07-04 07:55:24 +00:00
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
|
2020-08-25 02:22:08 +00:00
|
|
|
index cfbca7cfde3160e888e14c5bb3bc48267f1cb599..67fdd560f8136d83a13f75e265d5f5dd11871375 100644
|
2018-07-04 07:55:24 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/TileEntity.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/TileEntity.java
|
2019-05-14 02:20:58 +00:00
|
|
|
@@ -51,6 +51,15 @@ public abstract class TileEntity implements KeyedObject { // Paper
|
2018-07-27 04:44:53 +00:00
|
|
|
getMinecraftKey(); // Try to load if it doesn't exists.
|
2018-07-15 01:53:17 +00:00
|
|
|
return tileEntityKeyString;
|
2018-07-04 07:55:24 +00:00
|
|
|
}
|
2018-07-15 01:53:17 +00:00
|
|
|
+
|
2018-07-04 07:55:24 +00:00
|
|
|
+ private java.lang.ref.WeakReference<Chunk> currentChunk = null;
|
|
|
|
+ public Chunk getCurrentChunk() {
|
2018-07-27 04:44:53 +00:00
|
|
|
+ final Chunk chunk = currentChunk != null ? currentChunk.get() : null;
|
2020-06-26 06:29:44 +00:00
|
|
|
+ return chunk != null && chunk.loaded ? chunk : null;
|
2018-07-04 07:55:24 +00:00
|
|
|
+ }
|
|
|
|
+ public void setCurrentChunk(Chunk chunk) {
|
|
|
|
+ this.currentChunk = chunk != null ? new java.lang.ref.WeakReference<>(chunk) : null;
|
|
|
|
+ }
|
2018-07-15 01:53:17 +00:00
|
|
|
// Paper end
|
2018-07-04 07:55:24 +00:00
|
|
|
|
2018-07-15 01:53:17 +00:00
|
|
|
@Nullable
|
2018-07-04 07:55:24 +00:00
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
2020-08-25 02:22:08 +00:00
|
|
|
index fc23f2c4dc3ece5fd944de72b62b1a1ede3e7e45..66878c53bfb71392bf07d2c41a2edf1bc8f7af79 100644
|
2018-07-04 07:55:24 +00:00
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
2020-08-25 02:22:08 +00:00
|
|
|
@@ -143,6 +143,7 @@ import net.minecraft.server.EntityZombieHusk;
|
2020-06-02 03:15:47 +00:00
|
|
|
import net.minecraft.server.EntityZombieVillager;
|
2019-04-24 01:00:24 +00:00
|
|
|
import net.minecraft.server.IChatBaseComponent;
|
|
|
|
import net.minecraft.server.NBTTagCompound;
|
|
|
|
+import org.bukkit.Chunk; // Paper
|
2018-07-04 07:55:24 +00:00
|
|
|
import org.bukkit.EntityEffect;
|
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.Server;
|
2020-08-25 02:22:08 +00:00
|
|
|
@@ -184,6 +185,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
2018-07-04 07:55:24 +00:00
|
|
|
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) {
|
2020-04-27 07:34:45 +00:00
|
|
|
/*
|
2018-07-04 07:55:24 +00:00
|
|
|
* Order is *EXTREMELY* important -- keep it right! =D
|