PaperMC/Spigot-Server-Patches/Avoid-Chunk-Lookups-for-Entity-TileEntity-Current-Ch.patch
Aikar 29399ffc02 Numerous fixes to entity related changes
While it wasn't really "broken" before, if plugins use NMS
(which they really should't be) and mess with entity management
themselves, and get it wrong, they could ultimately corrupt our
state expectations.

I've been unable to reproduce any issues locally, but these changes
are the result of me analyzing the code pretty deeply and seeing
about how to make it more durable to abnormal usage.

Any servers seeing oddities, please run with -Ddebug.entities=true
and send me any logs triggered.
2019-04-05 23:08:45 -04:00

77 lines
No EOL
3.8 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 4 Jul 2018 03:39:51 -0400
Subject: [PATCH] Avoid Chunk Lookups for Entity/TileEntity Current Chunk
In many places where we simply want the current chunk the entity
is in, instead of doing a hashmap lookup for it, we now have access
to the object directly on the Entity/TileEntity object we can directly grab.
Use that local value instead to reduce lookups in many hot places.
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index d87b08a49e..c7712d2e71 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
int i = entity.chunkX;
int j = entity.chunkZ;
- if (entity.inChunk && this.isChunkLoaded(i, j, true)) {
- this.getChunkAt(i, j).b(entity);
- }
+ Chunk chunk = entity.getCurrentChunk(); // Paper
+ if (chunk != null) chunk.removeEntity(entity); // Paper
// CraftBukkit start - Decrement loop variable field if we've already ticked this entity
int index = this.entityList.indexOf(entity);
@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
int k = entity.chunkX;
j = entity.chunkZ;
- if (entity.inChunk && this.isChunkLoaded(k, j, true)) {
- this.getChunkAt(k, j).b(entity);
- }
+ Chunk chunk = entity.getCurrentChunk(); // Paper
+ if (chunk != null) chunk.removeEntity(entity); // Paper
//} // Paper - merge
//for (Entity e : this.g) { // Paper - merge
@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
j = entity.chunkX;
int l = entity.chunkZ;
- if (entity.inChunk && this.isChunkLoaded(j, l, true)) {
- this.getChunkAt(j, l).b(entity);
- }
+ // Paper start
+ Chunk chunk = entity.getCurrentChunk();
+ if (chunk != null) chunk.removeEntity(entity);
+ // Paper end
guardEntityList = false; // Spigot
this.entityList.remove(this.tickPosition--); // CraftBukkit - Use field for loop variable
@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
BlockPosition blockposition = tileentity.getPosition();
// Paper start - Skip ticking in chunks scheduled for unload
- net.minecraft.server.Chunk chunk = this.getChunkIfLoaded(blockposition);
+ net.minecraft.server.Chunk chunk = tileentity.getCurrentChunk();
boolean shouldTick = chunk != null;
if(this.paperConfig.skipEntityTickingInChunksScheduledForUnload)
shouldTick = shouldTick && chunk.scheduledForUnload == null;
@@ -0,0 +0,0 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
tilesThisCycle--;
this.tileEntityListTick.remove(tileTickPosition--);
//this.tileEntityList.remove(tileentity); // Paper - remove unused list
- if (this.isLoaded(tileentity.getPosition())) {
- this.getChunkAtWorldCoords(tileentity.getPosition()).d(tileentity.getPosition());
+ // Paper start
+ net.minecraft.server.Chunk chunk = tileentity.getCurrentChunk();
+ if (chunk != null) {
+ chunk.removeTileEntity(tileentity.getPosition());
+ // Paper end
}
}
}
--