088fa6f28b
Upstream has released updates that appear 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: 5b289e69 SPIGOT-5778: Added World.getGameTime method CraftBukkit Changes: d97d91871 SPIGOT-6347: Nether Portals Default to Nether, even in Nether 8aa6a953f SPIGOT-5778: Added World.getGameTime method Spigot Changes: 73fb6094 #107: Add async catching to chunk entity add/remove
163 lines
6.9 KiB
Diff
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 c8ff99ef5c7574292ee66a4aec45d1550eab1624..7c5f79124d2f2c69548263e79752484e07e77d48 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];
|
|
@@ -471,6 +496,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;
|
|
@@ -483,6 +509,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);
|
|
}
|
|
@@ -497,7 +524,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 b8267cf23f795fd7e586b0e567037eae5048d08e..b35ffae9f88cc14aec01482c2a3ed2e2428c2012 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 2770441b13cb993b222c6bf31c11711f001b74c0..db7c4011c8b90b6daca2b48a6d9ec447d31f7197 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
|