diff --git a/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch index 71c4fe39ec..3a3653f4cb 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ChunkMap.java.patch @@ -320,11 +320,18 @@ } } -@@ -1215,9 +1291,11 @@ +@@ -1215,9 +1291,18 @@ } public void addEntity(Entity entity) { + org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot ++ // Paper start - ignore and warn about illegal addEntity calls instead of crashing server ++ if (!entity.valid || entity.level() != this.level || this.entityMap.containsKey(entity.getId())) { ++ LOGGER.error("Illegal ChunkMap::addEntity for world " + this.level.getWorld().getName() ++ + ": " + entity + (this.entityMap.containsKey(entity.getId()) ? " ALREADY CONTAINED (This would have crashed your server)" : ""), new Throwable()); ++ return; ++ } ++ // Paper end - ignore and warn about illegal addEntity calls instead of crashing server if (!(entity instanceof EnderDragonPart)) { EntityType entitytypes = entity.getType(); int i = entitytypes.clientTrackingRange() * 16; @@ -332,7 +339,7 @@ if (i != 0) { int j = entitytypes.updateInterval(); -@@ -1250,6 +1328,7 @@ +@@ -1250,6 +1335,7 @@ } protected void removeEntity(Entity entity) { @@ -340,7 +347,7 @@ if (entity instanceof ServerPlayer entityplayer) { this.updatePlayerStatus(entityplayer, false); ObjectIterator objectiterator = this.entityMap.values().iterator(); -@@ -1391,7 +1470,7 @@ +@@ -1391,7 +1477,7 @@ }); } @@ -349,7 +356,7 @@ protected ChunkDistanceManager(final Executor workerExecutor, final Executor mainThreadExecutor) { super(workerExecutor, mainThreadExecutor); -@@ -1424,7 +1503,7 @@ +@@ -1424,7 +1510,7 @@ public final Set seenBy = Sets.newIdentityHashSet(); public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) { @@ -358,7 +365,7 @@ this.entity = entity; this.range = i; this.lastSectionPos = SectionPos.of((EntityAccess) entity); -@@ -1469,6 +1548,7 @@ +@@ -1469,6 +1555,7 @@ } public void removePlayer(ServerPlayer player) { @@ -366,7 +373,7 @@ if (this.seenBy.remove(player.connection)) { this.serverEntity.removePairing(player); } -@@ -1476,6 +1556,7 @@ +@@ -1476,6 +1563,7 @@ } public void updatePlayer(ServerPlayer player) { @@ -374,7 +381,7 @@ if (player != this.entity) { Vec3 vec3d = player.position().subtract(this.entity.position()); int i = ChunkMap.this.getPlayerViewDistance(player); -@@ -1484,6 +1565,11 @@ +@@ -1484,6 +1572,11 @@ double d2 = d0 * d0; boolean flag = d1 <= d2 && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z); @@ -386,7 +393,7 @@ if (flag) { if (this.seenBy.add(player.connection)) { this.serverEntity.addPairing(player); -@@ -1506,6 +1592,7 @@ +@@ -1506,6 +1599,7 @@ while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); int j = entity.getType().clientTrackingRange() * 16; diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index 103da8c231..0aedf79ede 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -79,7 +79,7 @@ + public final LevelStorageSource.LevelStorageAccess convertable; + public final UUID uuid; + public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent -+ + + public LevelChunk getChunkIfLoaded(int x, int z) { + return this.chunkSource.getChunk(x, z, false); + } @@ -129,7 +129,7 @@ + } + int minBlockX = Mth.floor(axisalignedbb.minX - 1.0E-7D) - 3; + int minBlockZ = Mth.floor(axisalignedbb.minZ - 1.0E-7D) - 3; - ++ + int maxBlockX = Mth.floor(axisalignedbb.maxX + 1.0E-7D) + 3; + int maxBlockZ = Mth.floor(axisalignedbb.maxZ + 1.0E-7D) + 3; + @@ -947,20 +947,23 @@ @Override public CrashReportCategory fillReportDetails(CrashReport report) { CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); -@@ -1836,6 +2216,7 @@ +@@ -1836,7 +2216,8 @@ } public void onTrackingStart(Entity entity) { +- ServerLevel.this.getChunkSource().addEntity(entity); + org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot - ServerLevel.this.getChunkSource().addEntity(entity); ++ // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.add(entityplayer); -@@ -1864,9 +2245,52 @@ + ServerLevel.this.updateSleepingPlayerList(); +@@ -1864,9 +2245,53 @@ } entity.updateDynamicGameEventListener(DynamicGameEventListener::add); + entity.inWorld = true; // CraftBukkit - Mark entity as in world + entity.valid = true; // CraftBukkit ++ ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server + // Paper start - Entity origin API + if (entity.getOriginVector() == null) { + entity.setOrigin(entity.getBukkitEntity().getLocation()); @@ -1008,7 +1011,7 @@ ServerLevel.this.getChunkSource().removeEntity(entity); if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.remove(entityplayer); -@@ -1895,6 +2319,15 @@ +@@ -1895,6 +2320,15 @@ } entity.updateDynamicGameEventListener(DynamicGameEventListener::remove);