Files
Purpur/patches/server/0109-Optimize-Chunk-Ticks.patch
William Blake Galbreath ef94c821f3 Updated Upstream (Paper)
Upstream has released updates that appears to apply and compile correctly

Paper Changes:
23ee0a8a Fix issue with 0,0 chunks causing crash
bc8fafb2 Updated Upstream (CraftBukkit/Spigot)
ebbca5ce Drowned is a RangedEntity (fixes API for Drowned to support Ranged)
83b03eee Don't move existing players to world spawn
3b3e38fd Fix issue with loading chunk during ticking chunks issue
78431dca Update test server startup script
2020-04-10 01:43:21 -05:00

188 lines
11 KiB
Diff

From 5edce62e30b52fab1714882adddf2e49bd67690b Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 2 Apr 2020 00:28:06 -0500
Subject: [PATCH] Optimize Chunk Ticks
---
.../minecraft/server/ChunkProviderServer.java | 70 ++++++-------------
.../minecraft/server/EnumCreatureType.java | 14 ++++
.../net/minecraft/server/PlayerChunkMap.java | 30 ++++----
3 files changed, 51 insertions(+), 63 deletions(-)
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 15450f36a4..276f1adcec 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -632,11 +632,12 @@ public class ChunkProviderServer extends IChunkProvider {
int k = this.world.getGameRules().getInt(GameRules.RANDOM_TICK_SPEED);
BlockPosition blockposition = this.world.getSpawn();
// CraftBukkit start - Other mob type spawn tick rate
- boolean spawnAnimalThisTick = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L;
- boolean spawnMonsterThisTick = world.ticksPerMonsterSpawns != 0L && worlddata.getTime() % world.ticksPerMonsterSpawns == 0L;
- boolean spawnWaterThisTick = world.ticksPerWaterSpawns != 0L && worlddata.getTime() % world.ticksPerWaterSpawns == 0L;
- boolean spawnAmbientThisTick = world.ticksPerAmbientSpawns != 0L && worlddata.getTime() % world.ticksPerAmbientSpawns == 0L;
- boolean flag2 = spawnAnimalThisTick;
+ // Purpur start
+ EnumCreatureType.CREATURE.setLimitThisTick(world.ticksPerAnimalSpawns != 0L && i % world.ticksPerAnimalSpawns == 0L ? world.getWorld().getAnimalSpawnLimit() : -1);
+ EnumCreatureType.MONSTER.setLimitThisTick(world.ticksPerMonsterSpawns != 0L && i % world.ticksPerMonsterSpawns == 0L ? world.getWorld().getMonsterSpawnLimit() : -1);
+ EnumCreatureType.WATER_CREATURE.setLimitThisTick(world.ticksPerWaterSpawns != 0L && i % world.ticksPerWaterSpawns == 0L ? world.getWorld().getWaterAnimalSpawnLimit() : -1);
+ EnumCreatureType.AMBIENT.setLimitThisTick(world.ticksPerAmbientSpawns != 0L && i % world.ticksPerAmbientSpawns == 0L ? world.getWorld().getAmbientSpawnLimit() : -1);
+ // Purpur end
// CraftBukkit end
this.world.getMethodProfiler().enter("naturalSpawnCount");
@@ -662,15 +663,17 @@ public class ChunkProviderServer extends IChunkProvider {
this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings
this.world.getMethodProfiler().exit();
- //Paper start - call player naturally spawn event
- int chunkRange = world.spigotConfig.mobSpawnRange;
- chunkRange = (chunkRange > world.spigotConfig.viewDistance) ? (byte) world.spigotConfig.viewDistance : chunkRange;
- chunkRange = Math.min(chunkRange, 8);
- for (EntityPlayer entityPlayer : this.world.players) {
- entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange);
- entityPlayer.playerNaturallySpawnedEvent.callEvent();
- };
- // Paper end
+ // Purpur start
+ if (com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent.getHandlerList().getRegisteredListeners().length > 0) {
+ // Paper start - call player naturally spawn event
+ byte chunkRange = (byte) Math.min(Math.min(world.spigotConfig.mobSpawnRange, world.spigotConfig.viewDistance), 8);
+ for (EntityPlayer entityPlayer : this.world.players) {
+ entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange);
+ entityPlayer.playerNaturallySpawnedEvent.callEvent();
+ }
+ // Paper end
+ }
+ // Purpur end
final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
Optional<Chunk> optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
@@ -690,40 +693,11 @@ public class ChunkProviderServer extends IChunkProvider {
if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot
this.world.getMethodProfiler().enter("spawner");
this.world.timings.mobSpawn.startTiming(); // Spigot
- EnumCreatureType[] aenumcreaturetype1 = aenumcreaturetype;
- int i1 = aenumcreaturetype.length;
-
- for (int j1 = 0; j1 < i1; ++j1) {
- EnumCreatureType enumcreaturetype = aenumcreaturetype1[j1];
-
- // CraftBukkit start - Use per-world spawn limits
- boolean spawnThisTick = true;
- int limit = enumcreaturetype.b();
- switch (enumcreaturetype) {
- case MONSTER:
- spawnThisTick = spawnMonsterThisTick;
- limit = world.getWorld().getMonsterSpawnLimit();
- break;
- case CREATURE:
- spawnThisTick = spawnAnimalThisTick;
- limit = world.getWorld().getAnimalSpawnLimit();
- break;
- case WATER_CREATURE:
- spawnThisTick = spawnWaterThisTick;
- limit = world.getWorld().getWaterAnimalSpawnLimit();
- break;
- case AMBIENT:
- spawnThisTick = spawnAmbientThisTick;
- limit = world.getWorld().getAmbientSpawnLimit();
- break;
- }
-
- if (!spawnThisTick || limit == 0) {
- continue;
- }
- // CraftBukkit end
-
- if (enumcreaturetype != EnumCreatureType.MISC && (!enumcreaturetype.c() || this.allowAnimals) && (enumcreaturetype.c() || this.allowMonsters) && (!enumcreaturetype.d() || flag2)) {
+ // Purpur start
+ for (EnumCreatureType enumcreaturetype : aenumcreaturetype) {
+ int limit = enumcreaturetype.getLimitThisTick();
+ if (limit > 0 && enumcreaturetype != EnumCreatureType.MISC && (!enumcreaturetype.isFriendly() || this.allowAnimals) && (enumcreaturetype.isFriendly() || this.allowMonsters)) {
+ // Purpur end
int k1 = limit * l / ChunkProviderServer.b; // CraftBukkit - use per-world limits
// Paper start - only allow spawns upto the limit per chunk and update count afterwards
diff --git a/src/main/java/net/minecraft/server/EnumCreatureType.java b/src/main/java/net/minecraft/server/EnumCreatureType.java
index 3ed7fa324f..7f236585db 100644
--- a/src/main/java/net/minecraft/server/EnumCreatureType.java
+++ b/src/main/java/net/minecraft/server/EnumCreatureType.java
@@ -31,11 +31,25 @@ public enum EnumCreatureType {
return this.g;
}
+ public boolean isFriendly() { return c(); } // Purpur - OBFHELPER
public boolean c() {
return this.h;
}
+ public boolean isPersistent() { return d(); } // Purpur - OBFHELPER
public boolean d() {
return this.i;
}
+
+ // Purpur start
+ private int limitThisTick = -1;
+
+ void setLimitThisTick(int cap) {
+ this.limitThisTick = cap;
+ }
+
+ int getLimitThisTick() {
+ return this.limitThisTick;
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 32fed8a39a..488be0c130 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -1358,28 +1358,28 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
boolean isOutsideOfRange(ChunkCoordIntPair chunkcoordintpair, boolean reducedRange) {
- int chunkRange = world.spigotConfig.mobSpawnRange;
- chunkRange = (chunkRange > world.spigotConfig.viewDistance) ? (byte) world.spigotConfig.viewDistance : chunkRange;
- chunkRange = (chunkRange > 8) ? 8 : chunkRange;
-
- final int finalChunkRange = chunkRange; // Paper for lambda below
- //double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; // Paper - use from event
- // Spigot end
+ // Purpur start
long i = chunkcoordintpair.pair();
-
- return !this.chunkDistanceManager.d(i) ? true : this.playerMap.a(i).noneMatch((entityplayer) -> {
- // Paper start -
- com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event;
+ return !this.chunkDistanceManager.d(i) || this.playerMap.a(i).noneMatch((player) -> {
+ // Paper start
double blockRange = 16384.0D;
if (reducedRange) {
- event = entityplayer.playerNaturallySpawnedEvent;
- if (event == null || event.isCancelled()) return false;
- blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4));
+ int radius;
+ if (player.playerNaturallySpawnedEvent != null) {
+ if (player.playerNaturallySpawnedEvent.isCancelled()) {
+ return false;
+ }
+ radius = player.playerNaturallySpawnedEvent.getSpawnRadius();
+ } else {
+ radius = Math.min(Math.min(world.spigotConfig.mobSpawnRange, world.spigotConfig.viewDistance), 8) << 4;
+ }
+ blockRange = radius * radius;
}
- return (!entityplayer.isSpectator() && a(chunkcoordintpair, (Entity) entityplayer) < blockRange); // Spigot
+ return (!player.isSpectator() && a(chunkcoordintpair, player) < blockRange); // Spigot
// Paper end
});
+ // Purpur end
}
private boolean b(EntityPlayer entityplayer) {
--
2.24.0