PaperMC/patches/server-remapped/Add-some-Debug-to-Chunk-Entity-slices.patch
MiniDigger | Martin 95d25d98e8 Move patches around
2021-06-11 14:02:28 +02:00

99 lines
5.1 KiB
Diff

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/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
}
}
};
+ public List<Entity> entitySlice = null;
// Paper end
public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -0,0 +0,0 @@ import net.minecraft.ReportedException;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
+import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ChunkHolder;
+import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
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 (Level.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 (Level.DEBUG_ENTITIES) MinecraftServer.LOGGER.warn("Entity is still in another chunk!" + entity, new Throwable());
+ LevelChunk 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;
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
entity.zChunk = this.chunkPos.z;
this.entities.add(entity); // Paper - per chunk entity list
this.entitySlices[k].add(entity);
+ entity.entitySlice = this.entitySlices[k]; // Paper
this.markUnsaved(); // Paper
}
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
// Paper start
if (entity.currentChunk != null && entity.currentChunk.get() == this) entity.setCurrentChunk(null);
+ if (entitySlices[section] == entity.entitySlice) {
+ entity.entitySlice = null;
+ entity.inChunk = false;
+ }
if (!this.entitySlices[section].remove(entity)) {
return;
}
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
// Paper start - neighbour cache
int chunkX = this.chunkPos.x;
int chunkZ = this.chunkPos.z;
- ChunkProviderServer chunkProvider = ((ServerLevel)this.world).getChunkSource();
+ ServerChunkCache chunkProvider = ((ServerLevel)this.world).getChunkSource();
for (int dx = -NEIGHBOUR_CACHE_RADIUS; dx <= NEIGHBOUR_CACHE_RADIUS; ++dx) {
for (int dz = -NEIGHBOUR_CACHE_RADIUS; dz <= NEIGHBOUR_CACHE_RADIUS; ++dz) {
LevelChunk neighbour = chunkProvider.getChunkAtIfLoadedMainThreadNoCache(chunkX + dx, chunkZ + dz);
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
// Paper start - neighbour cache
int chunkX = this.chunkPos.x;
int chunkZ = this.chunkPos.z;
- ChunkProviderServer chunkProvider = ((ServerLevel)this.world).getChunkSource();
+ ServerChunkCache chunkProvider = ((ServerLevel)this.world).getChunkSource();
for (int dx = -NEIGHBOUR_CACHE_RADIUS; dx <= NEIGHBOUR_CACHE_RADIUS; ++dx) {
for (int dz = -NEIGHBOUR_CACHE_RADIUS; dz <= NEIGHBOUR_CACHE_RADIUS; ++dz) {
LevelChunk neighbour = chunkProvider.getChunkAtIfLoadedMainThreadNoCache(chunkX + dx, chunkZ + dz);