aboutsummaryrefslogtreecommitdiffhomepage
path: root/Spigot-Server-Patches/0256-Add-some-Debug-to-Chunk-Entity-slices.patch
blob: 0975e2af16ace149488854ef8e0a154d177e5685 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 23 Jul 2018 22:44:23 -0400
Subject: [PATCH] Add some Debug to Chunk Entity slices

If we detect unexpected state, log and try to recover

This should hopefully avoid duplicate entities ever being created
if the entity was to end up in 2 different chunk slices

diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index f0a8142b7477fde211b522e3982e614fc94e20f8..9f369f932ca0a63bde246420cfde7949f3e78ca2 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -509,6 +509,25 @@ public class Chunk implements IChunkAccess {
         if (k >= this.entitySlices.length) {
             k = this.entitySlices.length - 1;
         }
+        // Paper - remove from any old list if its in one
+        List<Entity> nextSlice = this.entitySlices[k]; // the next list to be added to
+        List<Entity> currentSlice = entity.entitySlice;
+        if (nextSlice == currentSlice) {
+            if (World.DEBUG_ENTITIES) MinecraftServer.LOGGER.warn("Entity was already in this chunk!" + entity, new Throwable());
+            return; // ??? silly plugins
+        }
+        if (currentSlice != null && currentSlice.contains(entity)) {
+            // Still in an old chunk...
+            if (World.DEBUG_ENTITIES) MinecraftServer.LOGGER.warn("Entity is still in another chunk!" + entity, new Throwable());
+            Chunk chunk = entity.getCurrentChunk();
+            if (chunk != null) {
+                chunk.removeEntity(entity);
+            } else {
+                removeEntity(entity);
+            }
+            currentSlice.remove(entity); // Just incase the above did not remove from the previous slice
+        }
+        // Paper end
 
         if (!entity.inChunk || entity.getCurrentChunk() != this) entityCounts.increment(entity.getMinecraftKeyString()); // Paper
         entity.inChunk = true;
@@ -518,6 +537,7 @@ public class Chunk implements IChunkAccess {
         entity.chunkZ = this.loc.z;
         this.entities.add(entity); // Paper - per chunk entity list
         this.entitySlices[k].add(entity);
+        entity.entitySlice = this.entitySlices[k]; // Paper
         this.markDirty(); // Paper
     }
 
@@ -542,6 +562,10 @@ public class Chunk implements IChunkAccess {
 
         // Paper start
         if (entity.currentChunk != null && entity.currentChunk.get() == this) entity.setCurrentChunk(null);
+        if (entitySlices[i] == entity.entitySlice) {
+            entity.entitySlice = null;
+            entity.inChunk = false;
+        }
         if (!this.entitySlices[i].remove(entity)) {
             return;
         }
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 653e6d9a1640bedf08aaa5b436ac93e4cb1cb5b7..84d36ea84e25a701af22900af6cd3099adf6cd54 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -71,6 +71,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
             }
         }
     };
+    List<Entity> entitySlice = null;
     // Paper end
 
     public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper