2019-04-03 10:51:39 +02:00
|
|
|
From 3da86d2abcd148f2ceed99d9ebafd5ea70e9f9d9 Mon Sep 17 00:00:00 2001
|
2018-07-04 09:55:24 +02: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
|
2019-04-03 10:51:39 +02:00
|
|
|
index 417c015e5..b728a44f5 100644
|
2018-07-04 09:55:24 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
2019-01-01 04:15:55 +01:00
|
|
|
@@ -36,7 +36,7 @@ public class Chunk implements IChunkAccess {
|
2018-08-26 20:11:49 +02:00
|
|
|
private final BiomeBase[] f;
|
|
|
|
private final boolean[] g;
|
|
|
|
private final Map<BlockPosition, NBTTagCompound> h;
|
|
|
|
- private boolean i;
|
|
|
|
+ private boolean i;public boolean isLoaded() { return i; } // Paper - OBFHELPER
|
2018-07-06 00:39:43 +02:00
|
|
|
public final World world;
|
2018-07-15 03:53:17 +02:00
|
|
|
public final Map<HeightMap.Type, HeightMap> heightMap;
|
2018-07-06 00:39:43 +02:00
|
|
|
public final int locX;
|
2019-01-01 04:15:55 +01:00
|
|
|
@@ -66,7 +66,30 @@ public class Chunk implements IChunkAccess {
|
2018-07-15 03:53:17 +02:00
|
|
|
// CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
|
|
|
|
private int neighbors = 0x1 << 12;
|
|
|
|
public long chunkKey;
|
2018-07-04 09:55: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;
|
|
|
|
+ }
|
2018-07-15 03:53:17 +02:00
|
|
|
|
2018-07-04 09:55:24 +02:00
|
|
|
+ @Override
|
|
|
|
+ public TileEntity remove(Object key) {
|
|
|
|
+ TileEntity removed = super.remove(key);
|
|
|
|
+ if (removed != null) {
|
|
|
|
+ removed.setCurrentChunk(null);
|
|
|
|
+ }
|
|
|
|
+ return removed;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
2018-07-15 03:53:17 +02:00
|
|
|
public boolean areNeighborsLoaded(final int radius) {
|
|
|
|
switch (radius) {
|
|
|
|
case 2:
|
2019-01-01 04:15:55 +01:00
|
|
|
@@ -97,7 +120,7 @@ public class Chunk implements IChunkAccess {
|
2018-08-26 20:11:49 +02:00
|
|
|
this.g = new boolean[256];
|
|
|
|
this.h = Maps.newHashMap();
|
2018-10-23 01:16:21 +02:00
|
|
|
this.heightMap = Maps.newEnumMap(HeightMap.Type.class);
|
2018-07-04 09:55:24 +02:00
|
|
|
- this.tileEntities = Maps.newHashMap();
|
|
|
|
+ this.tileEntities = new TileEntityHashMap(); // Paper
|
2018-08-26 20:11:49 +02:00
|
|
|
this.p = Maps.newHashMap();
|
2018-07-15 03:53:17 +02:00
|
|
|
this.q = Maps.newHashMap();
|
2018-08-26 20:11:49 +02:00
|
|
|
this.r = new ShortList[16];
|
2019-01-01 04:15:55 +01:00
|
|
|
@@ -657,6 +680,9 @@ public class Chunk implements IChunkAccess {
|
2018-12-17 06:18:06 +01:00
|
|
|
entity.chunkY = k;
|
|
|
|
entity.chunkZ = this.locZ;
|
2018-07-15 03:53:17 +02:00
|
|
|
this.entitySlices[k].add(entity);
|
2018-07-04 09:55:24 +02:00
|
|
|
+ // Paper start
|
|
|
|
+ entity.setCurrentChunk(this);
|
|
|
|
+ // Paper end
|
|
|
|
}
|
|
|
|
|
2018-07-15 03:53:17 +02:00
|
|
|
public void a(HeightMap.Type heightmap_type, long[] along) {
|
2019-01-01 04:15:55 +01:00
|
|
|
@@ -675,8 +701,12 @@ public class Chunk implements IChunkAccess {
|
2018-07-15 03:53:17 +02:00
|
|
|
if (i >= this.entitySlices.length) {
|
|
|
|
i = this.entitySlices.length - 1;
|
2018-07-04 09:55:24 +02:00
|
|
|
}
|
2018-07-15 03:53:17 +02:00
|
|
|
-
|
|
|
|
- this.entitySlices[i].remove(entity);
|
2018-07-04 09:55:24 +02:00
|
|
|
+ // Paper start
|
2018-07-15 03:53:17 +02:00
|
|
|
+ if (!this.entitySlices[i].remove(entity)) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
2018-07-04 09:55:24 +02:00
|
|
|
+ entity.setCurrentChunk(null);
|
|
|
|
+ // Paper end
|
|
|
|
}
|
|
|
|
|
2018-07-15 03:53:17 +02:00
|
|
|
public boolean c(BlockPosition blockposition) {
|
2019-01-01 04:15:55 +01:00
|
|
|
@@ -885,6 +915,7 @@ public class Chunk implements IChunkAccess {
|
2018-07-30 06:51:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Spigot End
|
|
|
|
+ entity.setCurrentChunk(null); // Paper
|
|
|
|
|
|
|
|
// Do not pass along players, as doing so can get them stuck outside of time.
|
|
|
|
// (which for example disables inventory icon updates and prevents block breaking)
|
2018-07-04 09:55:24 +02:00
|
|
|
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
2019-04-03 10:51:39 +02:00
|
|
|
index d9c9748ce..3b8d09953 100644
|
2018-07-04 09:55:24 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
2019-01-01 04:15:55 +01:00
|
|
|
@@ -132,7 +132,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
2018-07-29 19:12:39 +02:00
|
|
|
private static final DataWatcherObject<Boolean> aF = DataWatcher.a(Entity.class, DataWatcherRegistry.i);
|
|
|
|
private static final DataWatcherObject<Boolean> aG = DataWatcher.a(Entity.class, DataWatcherRegistry.i);
|
|
|
|
private static final DataWatcherObject<Boolean> aH = DataWatcher.a(Entity.class, DataWatcherRegistry.i);
|
|
|
|
- public boolean inChunk;
|
|
|
|
+ public boolean inChunk; public boolean isAddedToChunk() { return inChunk; } // Paper - OBFHELPER
|
2018-12-17 06:18:06 +01:00
|
|
|
public int chunkX; public int getChunkX() { return chunkX; } // Paper - OBFHELPER
|
|
|
|
public int chunkY; public int getChunkY() { return chunkY; } // Paper - OBFHELPER
|
|
|
|
public int chunkZ; public int getChunkZ() { return chunkZ; } // Paper - OBFHELPER
|
2019-01-15 22:12:19 +01:00
|
|
|
@@ -1776,6 +1776,39 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
2018-07-04 09:55:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Paper start
|
|
|
|
+ private java.lang.ref.WeakReference<Chunk> currentChunk = null;
|
2018-07-14 06:12:42 +02: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 09:55:24 +02:00
|
|
|
+ public Chunk getCurrentChunk() {
|
2018-07-09 04:39:46 +02:00
|
|
|
+ final Chunk chunk = currentChunk != null ? currentChunk.get() : null;
|
2018-07-29 18:04:09 +02:00
|
|
|
+ return chunk != null && chunk.isLoaded() ? chunk : (isAddedToChunk() ? world.getChunkIfLoaded(getChunkX(), getChunkZ()) : null);
|
2018-07-04 09:55:24 +02:00
|
|
|
+ }
|
2018-07-14 06:12:42 +02:00
|
|
|
+ /**
|
|
|
|
+ * Returns the chunk at the location, using the entities local cache if avail
|
|
|
|
+ * Will only return null if the location specified is not loaded
|
|
|
|
+ */
|
2018-07-12 22:42:56 +02:00
|
|
|
+ public Chunk getCurrentChunkAt(int x, int z) {
|
|
|
|
+ if (getChunkX() == x && getChunkZ() == z) {
|
2018-07-14 06:12:42 +02:00
|
|
|
+ Chunk chunk = getCurrentChunk();
|
|
|
|
+ if (chunk != null) {
|
|
|
|
+ return chunk;
|
|
|
|
+ }
|
2018-07-12 22:42:56 +02:00
|
|
|
+ }
|
2018-07-14 06:12:42 +02:00
|
|
|
+ return world.getChunkIfLoaded(x, z);
|
2018-07-12 22:42:56 +02:00
|
|
|
+ }
|
2018-07-14 06:12:42 +02:00
|
|
|
+ /**
|
|
|
|
+ * Returns the chunk at the entities current location, using the entities local cache if avail
|
|
|
|
+ * Will only return null if the location specified is not loaded
|
|
|
|
+ */
|
2018-07-12 22:42:56 +02:00
|
|
|
+ public Chunk getChunkAtLocation() {
|
|
|
|
+ return getCurrentChunkAt((int)Math.floor(locX) >> 4, (int)Math.floor(locZ) >> 4);
|
2018-07-04 09:55:24 +02:00
|
|
|
+ }
|
2018-07-15 03:53:17 +02:00
|
|
|
+
|
2018-07-27 06:44:53 +02:00
|
|
|
private MinecraftKey entityKey;
|
|
|
|
private String entityKeyString;
|
2018-07-04 09:55:24 +02:00
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
|
2019-04-03 10:51:39 +02:00
|
|
|
index 7390061bf..c69209497 100644
|
2018-07-04 09:55:24 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/TileEntity.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/TileEntity.java
|
2018-07-27 06:44:53 +02:00
|
|
|
@@ -41,6 +41,15 @@ public abstract class TileEntity implements KeyedObject { // Paper
|
|
|
|
getMinecraftKey(); // Try to load if it doesn't exists.
|
2018-07-15 03:53:17 +02:00
|
|
|
return tileEntityKeyString;
|
2018-07-04 09:55:24 +02:00
|
|
|
}
|
2018-07-15 03:53:17 +02:00
|
|
|
+
|
2018-07-04 09:55:24 +02:00
|
|
|
+ private java.lang.ref.WeakReference<Chunk> currentChunk = null;
|
|
|
|
+ public Chunk getCurrentChunk() {
|
2018-07-27 06:44:53 +02:00
|
|
|
+ final Chunk chunk = currentChunk != null ? currentChunk.get() : null;
|
2018-07-06 00:39:43 +02:00
|
|
|
+ return chunk != null && chunk.isLoaded() ? chunk : null;
|
2018-07-04 09:55:24 +02:00
|
|
|
+ }
|
|
|
|
+ public void setCurrentChunk(Chunk chunk) {
|
|
|
|
+ this.currentChunk = chunk != null ? new java.lang.ref.WeakReference<>(chunk) : null;
|
|
|
|
+ }
|
2018-07-15 03:53:17 +02:00
|
|
|
// Paper end
|
2018-07-04 09:55:24 +02:00
|
|
|
|
2018-07-15 03:53:17 +02:00
|
|
|
@Nullable
|
2018-07-04 09:55:24 +02:00
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
2019-04-03 10:51:39 +02:00
|
|
|
index 9cdd0331f..7edbbb106 100644
|
2018-07-04 09:55:24 +02:00
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
|
|
|
@@ -9,6 +9,7 @@ import java.util.UUID;
|
|
|
|
|
|
|
|
import net.minecraft.server.*;
|
|
|
|
|
|
|
|
+import org.bukkit.Chunk;
|
|
|
|
import org.bukkit.EntityEffect;
|
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.Server;
|
2019-04-03 10:51:39 +02:00
|
|
|
@@ -44,6 +45,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
2018-07-04 09:55:24 +02: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) {
|
|
|
|
/**
|
|
|
|
* Order is *EXTREMELY* important -- keep it right! =D
|
|
|
|
--
|
2019-04-03 10:51:39 +02:00
|
|
|
2.21.0
|
2018-07-04 09:55:24 +02:00
|
|
|
|