More more more more more more more more more more work

This commit is contained in:
Nassim Jahnke 2021-11-24 10:01:27 +01:00
parent bd2d33ccb1
commit 1f77146c5c
22 changed files with 69 additions and 87 deletions

View File

@ -314,7 +314,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper end // Paper end
+ com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x1, z1); // Paper - sync load info + com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x1, z1); // Paper - sync load info
this.level.timings.syncChunkLoad.startTiming(); // Paper this.level.timings.syncChunkLoad.startTiming(); // Paper
chunkproviderserver_a.managedBlock(completablefuture::isDone); chunkproviderserver_b.managedBlock(completablefuture::isDone);
com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View File

@ -28,8 +28,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
BlockPos blockposition1 = blockposition.below(); BlockPos blockposition1 = blockposition.below();
BlockState iblockdata = world.getBlockState(blockposition1); BlockState iblockdata = world.getBlockState(blockposition1);
- if (!iblockdata.entityCanStandOn((BlockGetter) world, blockposition1, (Entity) this)) { - if (!iblockdata.entityCanStandOn(world, blockposition1, this)) {
+ if (!iblockdata.entityCanStandOn((BlockGetter) world, blockposition1, (Entity) this) && !level.paperConfig.ironGolemsCanSpawnInAir) { // Paper + if (!iblockdata.entityCanStandOn(world, blockposition1, this) && !level.paperConfig.ironGolemsCanSpawnInAir) { // Paper
return false; return false;
} else { } else {
for (int i = 1; i < 3; ++i) { for (int i = 1; i < 3; ++i) {

View File

@ -24,7 +24,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/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, EntityAccess, CommandSource, n @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
public long activatedImmunityTick = Integer.MIN_VALUE; // Paper public long activatedImmunityTick = Integer.MIN_VALUE; // Paper
public boolean isTemporarilyActive = false; // Paper public boolean isTemporarilyActive = false; // Paper
public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected int numCollisions = 0; // Paper protected int numCollisions = 0; // Paper
public void inactiveTick() { } public void inactiveTick() { }
// Spigot end // Spigot end
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
if (spawnedViaMobSpawner) { if (spawnedViaMobSpawner) {
nbt.putBoolean("Paper.FromMobSpawner", true); nbt.putBoolean("Paper.FromMobSpawner", true);
} }
@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper end // Paper end
return nbt; return nbt;
} catch (Throwable throwable) { } catch (Throwable throwable) {
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
} }
spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status

View File

@ -30,7 +30,7 @@ diff --git a/src/main/java/net/minecraft/world/level/entity/EntitySection.java b
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/entity/EntitySection.java --- a/src/main/java/net/minecraft/world/level/entity/EntitySection.java
+++ b/src/main/java/net/minecraft/world/level/entity/EntitySection.java +++ b/src/main/java/net/minecraft/world/level/entity/EntitySection.java
@@ -0,0 +0,0 @@ public class EntitySection<T> { @@ -0,0 +0,0 @@ public class EntitySection<T extends EntityAccess> {
protected static final Logger LOGGER = LogManager.getLogger(); protected static final Logger LOGGER = LogManager.getLogger();
private final ClassInstanceMultiMap<T> storage; private final ClassInstanceMultiMap<T> storage;
private Visibility chunkStatus; private Visibility chunkStatus;
@ -41,53 +41,44 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public EntitySection(Class<T> entityClass, Visibility status) { public EntitySection(Class<T> entityClass, Visibility status) {
this.chunkStatus = status; this.chunkStatus = status;
@@ -0,0 +0,0 @@ public class EntitySection<T> { @@ -0,0 +0,0 @@ public class EntitySection<T extends EntityAccess> {
} }
public void add(T obj) { public void add(T entityAccess) {
+ // Paper start + // Paper start
+ if (obj instanceof net.minecraft.world.entity.item.ItemEntity) { + if (entityAccess instanceof net.minecraft.world.entity.item.ItemEntity) {
+ this.itemCount++; + this.itemCount++;
+ } else if (obj instanceof net.minecraft.world.Container) { + } else if (entityAccess instanceof net.minecraft.world.Container) {
+ this.inventoryEntityCount++; + this.inventoryEntityCount++;
+ } + }
+ // Paper end + // Paper end
this.storage.add(obj); this.storage.add(entityAccess);
} }
public boolean remove(T obj) { public boolean remove(T entityAccess) {
+ // Paper start + // Paper start
+ if (obj instanceof net.minecraft.world.entity.item.ItemEntity) { + if (entityAccess instanceof net.minecraft.world.entity.item.ItemEntity) {
+ this.itemCount--; + this.itemCount--;
+ } else if (obj instanceof net.minecraft.world.Container) { + } else if (entityAccess instanceof net.minecraft.world.Container) {
+ this.inventoryEntityCount--; + this.inventoryEntityCount--;
+ } + }
+ // Paper end + // Paper end
return this.storage.remove(obj); return this.storage.remove(entityAccess);
} }
@@ -0,0 +0,0 @@ public class EntitySection<T> { @@ -0,0 +0,0 @@ public class EntitySection<T extends EntityAccess> {
for(T object : this.storage.find(type.getBaseClass())) { for(T entityAccess : collection) {
U object2 = (U)type.tryCast(object); U entityAccess2 = (U)((EntityAccess)type.tryCast(entityAccess));
if (object2 != null && filter.test(object2)) { if (entityAccess2 != null && entityAccess.getBoundingBox().intersects(aABB)) {
- action.accept((T)object2); - action.accept((T)entityAccess2);
+ action.accept(object2); // Paper - decompile fix + action.accept(entityAccess2); // Paper - decompile fixes
}
} }
}
diff --git a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java diff --git a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java --- a/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java
+++ b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java +++ b/src/main/java/net/minecraft/world/level/entity/EntitySectionStorage.java
@@ -0,0 +0,0 @@ public class EntitySectionStorage<T extends EntityAccess> {
public LongSet getAllChunksWithExistingSections() {
LongSet longSet = new LongOpenHashSet();
- this.sections.keySet().forEach((sectionPos) -> {
+ this.sections.keySet().forEach((java.util.function.LongConsumer) (sectionPos) -> { // Paper - decompile fix
longSet.add(getChunkKeyFromSectionKey(sectionPos));
});
return longSet;
@@ -0,0 +0,0 @@ public class EntitySectionStorage<T extends EntityAccess> { @@ -0,0 +0,0 @@ public class EntitySectionStorage<T extends EntityAccess> {
} }
@ -97,16 +88,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ public void getEntities(AABB box, Consumer<T> action, boolean isContainerSearch) { + public void getEntities(AABB box, Consumer<T> action, boolean isContainerSearch) {
+ // Paper end + // Paper end
this.forEachAccessibleSection(box, (entitySection) -> { this.forEachAccessibleNonEmptySection(box, (entitySection) -> {
+ if (isContainerSearch && entitySection.inventoryEntityCount <= 0) return; // Paper + if (isContainerSearch && entitySection.inventoryEntityCount <= 0) return; // Paper
entitySection.getEntities(createBoundingBoxCheck(box), action); entitySection.getEntities(box, action);
}); });
} }
public <U extends T> void getEntities(EntityTypeTest<T, U> filter, AABB box, Consumer<U> action) { public <U extends T> void getEntities(EntityTypeTest<T, U> filter, AABB box, Consumer<U> action) {
this.forEachAccessibleSection(box, (entitySection) -> { this.forEachAccessibleNonEmptySection(box, (entitySection) -> {
+ if (filter.getBaseClass() == net.minecraft.world.entity.item.ItemEntity.class && entitySection.itemCount <= 0) return; // Paper + if (filter.getBaseClass() == net.minecraft.world.entity.item.ItemEntity.class && entitySection.itemCount <= 0) return; // Paper
entitySection.getEntities(filter, createBoundingBoxCheck(box), action); entitySection.getEntities(filter, box, action);
}); });
} }
diff --git a/src/main/java/net/minecraft/world/level/entity/LevelEntityGetter.java b/src/main/java/net/minecraft/world/level/entity/LevelEntityGetter.java diff --git a/src/main/java/net/minecraft/world/level/entity/LevelEntityGetter.java b/src/main/java/net/minecraft/world/level/entity/LevelEntityGetter.java

View File

@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { @@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
} else if (this.isInLava() && (!this.onGround || d7 > d8)) { } else if (this.isInLava() && (!this.onGround || d7 > d8)) {
this.jumpInLiquid((Tag) FluidTags.LAVA); this.jumpInLiquid(FluidTags.LAVA);
} else if ((this.onGround || flag && d7 <= d8) && this.noJumpDelay == 0) { } else if ((this.onGround || flag && d7 <= d8) && this.noJumpDelay == 0) {
+ if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper + if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper
this.jumpFromGround(); this.jumpFromGround();

View File

@ -16,7 +16,7 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/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, EntityAccess, CommandSource, n @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
BlockPos blockposition1; BlockPos blockposition1;
if (flag1) { if (flag1) {

View File

@ -9,8 +9,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig { @@ -0,0 +0,0 @@ public class PaperWorldConfig {
this.noTickViewDistance = this.getInt("viewdistances.no-tick-view-distance", -1); private void lightQueueSize() {
lightQueueSize = getInt("light-queue-size", lightQueueSize);
} }
-}
+ public boolean altItemDespawnRateEnabled; + public boolean altItemDespawnRateEnabled;
+ public java.util.Map<org.bukkit.Material, Integer> altItemDespawnRateMap; + public java.util.Map<org.bukkit.Material, Integer> altItemDespawnRateMap;
@ -59,10 +61,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ } + }
+ +}
public boolean antiXray;
public EngineMode engineMode;
public int maxBlockHeight;
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java

View File

@ -11,7 +11,7 @@ diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/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 @@ public class LevelChunk implements ChunkAccess { @@ -0,0 +0,0 @@ public class LevelChunk extends ChunkAccess {
} }
public FluidState getFluidState(int x, int y, int z) { public FluidState getFluidState(int x, int y, int z) {
@ -20,19 +20,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- -
- if (l >= 0 && l < this.sections.length) { - if (l >= 0 && l < this.sections.length) {
- LevelChunkSection chunksection = this.sections[l]; - LevelChunkSection chunksection = this.sections[l];
-
- if (!LevelChunkSection.isEmpty(chunksection)) {
- return chunksection.getFluidState(x & 15, y & 15, z & 15);
+ // try { // Paper - remove try catch + // try { // Paper - remove try catch
+ // Paper start - reduce the number of ops in this call + // Paper start - reduce the number of ops in this call
+ int index = this.getSectionIndex(y); + int index = this.getSectionIndex(y);
+ if (index >= 0 && index < this.sections.length) { + if (index >= 0 && index < this.sections.length) {
+ LevelChunkSection chunksection = this.sections[index]; + LevelChunkSection chunksection = this.sections[index];
+
+ if (chunksection != null) { if (!chunksection.hasOnlyAir()) {
- return chunksection.getFluidState(x & 15, y & 15, z & 15);
+ return chunksection.states.get((y & 15) << 8 | (z & 15) << 4 | x & 15).getFluidState(); + return chunksection.states.get((y & 15) << 8 | (z & 15) << 4 | x & 15).getFluidState();
+ // Paper end
} }
+ // Paper end
} }
return Fluids.EMPTY.defaultFluidState(); return Fluids.EMPTY.defaultFluidState();
@ -40,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} catch (Throwable throwable) { } catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting fluid state"); CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting fluid state");
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being got"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being got");
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess { @@ -0,0 +0,0 @@ public class LevelChunk extends ChunkAccess {
}); });
throw new ReportedException(crashreport); throw new ReportedException(crashreport);
} }
@ -56,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
public FluidState getFluidState(int x, int y, int z) { public FluidState getFluidState(int x, int y, int z) {
- return this.states.get(x, y, z).getFluidState(); - return ((BlockState) this.states.get(x, y, z)).getFluidState();
+ return this.states.get(x, y, z).getFluidState(); // Paper - diff on change - we expect this to be effectively just getType(x, y, z).getFluid(). If this changes we need to check other patches that use IBlockData#getFluid. + return this.states.get(x, y, z).getFluidState(); // Paper - diff on change - we expect this to be effectively just getType(x, y, z).getFluid(). If this changes we need to check other patches that use IBlockData#getFluid.
} }

View File

@ -11,7 +11,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/j
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -0,0 +0,0 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
while (iterator.hasNext()) { while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next(); Entity entity = (Entity) iterator.next();
int j = entity.getType().clientTrackingRange() * 16; int j = entity.getType().clientTrackingRange() * 16;
@ -69,7 +69,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return config.miscTrackingRange; return config.miscTrackingRange;
} else } else
{ {
+ if (entity instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon) return ((net.minecraft.server.level.ServerLevel)(entity.getCommandSenderWorld())).getChunkSource().chunkMap.getLoadViewDistance(); // Paper - enderdragon is exempt + if (entity instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon) return ((net.minecraft.server.level.ServerLevel)(entity.getCommandSenderWorld())).getChunkSource().chunkMap.getEffectiveViewDistance(); // Paper - enderdragon is exempt
return config.otherTrackingRange; return config.otherTrackingRange;
} }
} }

View File

@ -29,7 +29,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig { @@ -0,0 +0,0 @@ public class PaperWorldConfig {
Bukkit.getLogger().warning("You have enabled permission-based Anti-Xray checking - depending on your permission plugin, this may cause performance issues"); }
} }
} }
+ +
@ -41,7 +41,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ perPlayerMobSpawns = getBoolean("per-player-mob-spawns", true); + perPlayerMobSpawns = getBoolean("per-player-mob-spawns", true);
+ } + }
} }
diff --git a/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java b/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java diff --git a/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java b/src/main/java/com/destroystokyo/paper/util/PlayerMobDistanceMap.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@ -560,12 +559,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback() // CraftBukkit start - recursion-safe executor for Chunk loadCallback() and unloadCallback()
public final CallbackExecutor callbackExecutor = new CallbackExecutor(); public final CallbackExecutor callbackExecutor = new CallbackExecutor();
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
ChunkMap.this.updateChunkTracking(player, new ChunkPos(rangeX, rangeZ), null, true, false); // unloaded, loaded this.dataRegionManager = new io.papermc.paper.chunk.SingleThreadChunkRegionManager(this.level, 2, (1.0 / 3.0), 1, 6, "Data", DataRegionData::new, DataRegionSectionData::new);
}); this.regionManagers.add(this.dataRegionManager);
// Paper end - no-tick view distance // Paper end
+ this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper + this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper
} }
protected ChunkGenerator generator() {
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
});
}
+ // Paper start + // Paper start
+ public void updatePlayerMobTypeMap(Entity entity) { + public void updatePlayerMobTypeMap(Entity entity) {
+ if (!this.level.paperConfig.perPlayerMobSpawns) { + if (!this.level.paperConfig.perPlayerMobSpawns) {
@ -593,10 +597,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
this.level.getProfiler().push("naturalSpawnCount"); gameprofilerfiller.push("naturalSpawnCount");
this.level.timings.countNaturalMobs.startTiming(); // Paper - timings this.level.timings.countNaturalMobs.startTiming(); // Paper - timings
int l = this.distanceManager.getNaturalSpawnChunkCount(); int l = this.distanceManager.getNaturalSpawnChunkCount();
- NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk); - NaturalSpawner.SpawnState spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap));
+ // Paper start - per player mob spawning + // Paper start - per player mob spawning
+ NaturalSpawner.SpawnState spawnercreature_d; // moved down + NaturalSpawner.SpawnState spawnercreature_d; // moved down
+ if (this.chunkMap.playerMobDistanceMap != null) { + if (this.chunkMap.playerMobDistanceMap != null) {
@ -608,9 +612,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (ServerPlayer player : this.level.players) { + for (ServerPlayer player : this.level.players) {
+ Arrays.fill(player.mobCounts, 0); + Arrays.fill(player.mobCounts, 0);
+ } + }
+ spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, true); + spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap), true);
+ } else { + } else {
+ spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, false); + spawnercreature_d = NaturalSpawner.createState(l, this.level.getAllEntities(), this::getFullChunk, new LocalMobCapCalculator(this.chunkMap), false);
+ } + }
+ // Paper end + // Paper end
this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings this.level.timings.countNaturalMobs.stopTiming(); // Paper - timings
@ -644,24 +648,17 @@ diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/m
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -0,0 +0,0 @@ import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.FluidTags;
import net.minecraft.tags.Tag;
@@ -0,0 +0,0 @@ public final class NaturalSpawner { @@ -0,0 +0,0 @@ public final class NaturalSpawner {
private NaturalSpawner() {} private NaturalSpawner() {}
+ // Paper start - add countMobs parameter + // Paper start - add countMobs parameter
public static NaturalSpawner.SpawnState createState(int spawningChunkCount, Iterable<Entity> entities, NaturalSpawner.ChunkGetter chunkSource) { public static NaturalSpawner.SpawnState createState(int spawningChunkCount, Iterable<Entity> entities, NaturalSpawner.ChunkGetter chunkSource, LocalMobCapCalculator localmobcapcalculator) {
+ return createState(spawningChunkCount, entities, chunkSource, false); + return createState(spawningChunkCount, entities, chunkSource, localmobcapcalculator, false);
+ } + }
+ public static NaturalSpawner.SpawnState createState(int spawningChunkCount, Iterable<Entity> entities, NaturalSpawner.ChunkGetter chunkSource, boolean countMobs) { +
+ // Paper end - add countMobs parameter + public static NaturalSpawner.SpawnState createState(int spawningChunkCount, Iterable<Entity> entities, NaturalSpawner.ChunkGetter chunkSource, LocalMobCapCalculator localmobcapcalculator, boolean countMobs) {
+ // Paper end
PotentialCalculator spawnercreatureprobabilities = new PotentialCalculator(); PotentialCalculator spawnercreatureprobabilities = new PotentialCalculator();
Object2IntOpenHashMap<MobCategory> object2intopenhashmap = new Object2IntOpenHashMap(); Object2IntOpenHashMap<MobCategory> object2intopenhashmap = new Object2IntOpenHashMap();
Iterator iterator = entities.iterator(); Iterator iterator = entities.iterator();
@ -669,11 +666,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
object2intopenhashmap.addTo(enumcreaturetype, 1); object2intopenhashmap.addTo(enumcreaturetype, 1);
+ // Paper start
+ if (countMobs) { + if (countMobs) {
+ chunk.level.getChunkSource().chunkMap.updatePlayerMobTypeMap(entity); + chunk.level.getChunkSource().chunkMap.updatePlayerMobTypeMap(entity);
+ } + }
+ // Paper end
}); });
} }
} }
@ -681,7 +676,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
continue; continue;
} }
- if ((spawnAnimals || !enumcreaturetype.isFriendly()) && (spawnMonsters || enumcreaturetype.isFriendly()) && (rareSpawn || !enumcreaturetype.isPersistent()) && info.canSpawnForCategory(enumcreaturetype, limit)) { - if ((spawnAnimals || !enumcreaturetype.isFriendly()) && (spawnMonsters || enumcreaturetype.isFriendly()) && (rareSpawn || !enumcreaturetype.isPersistent()) && info.canSpawnForCategory(enumcreaturetype, chunk.getPos(), limit)) {
+ // Paper start - only allow spawns upto the limit per chunk and update count afterwards + // Paper start - only allow spawns upto the limit per chunk and update count afterwards
+ int currEntityCount = info.mobCategoryCounts.getInt(enumcreaturetype); + int currEntityCount = info.mobCategoryCounts.getInt(enumcreaturetype);
+ int k1 = limit * info.getSpawnableChunkCount() / NaturalSpawner.MAGIC_NUMBER; + int k1 = limit * info.getSpawnableChunkCount() / NaturalSpawner.MAGIC_NUMBER;
@ -689,25 +684,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ if (world.paperConfig.perPlayerMobSpawns) { + if (world.paperConfig.perPlayerMobSpawns) {
+ int minDiff = Integer.MAX_VALUE; + int minDiff = Integer.MAX_VALUE;
+ for (ServerPlayer entityplayer : world.getChunkSource().chunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) { + for (net.minecraft.server.level.ServerPlayer entityplayer : world.getChunkSource().chunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) {
+ minDiff = Math.min(limit - world.getChunkSource().chunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff); + minDiff = Math.min(limit - world.getChunkSource().chunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff);
+ } + }
+ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff; + difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff;
+ } + }
+ // Paper end
+
+ // Paper start - per player mob spawning
+ if ((spawnAnimals || !enumcreaturetype.isFriendly()) && (spawnMonsters || enumcreaturetype.isFriendly()) && (rareSpawn || !enumcreaturetype.isPersistent()) && difference > 0) { + if ((spawnAnimals || !enumcreaturetype.isFriendly()) && (spawnMonsters || enumcreaturetype.isFriendly()) && (rareSpawn || !enumcreaturetype.isPersistent()) && difference > 0) {
+ // Paper end
// CraftBukkit end // CraftBukkit end
Objects.requireNonNull(info); Objects.requireNonNull(info);
NaturalSpawner.SpawnPredicate spawnercreature_c = info::canSpawn; NaturalSpawner.SpawnPredicate spawnercreature_c = info::canSpawn;
Objects.requireNonNull(info); Objects.requireNonNull(info);
- NaturalSpawner.spawnCategoryForChunk(enumcreaturetype, world, chunk, spawnercreature_c, info::afterSpawn); - NaturalSpawner.spawnCategoryForChunk(enumcreaturetype, world, chunk, spawnercreature_c, info::afterSpawn);
+ // Paper start
+ int spawnCount = NaturalSpawner.spawnCategoryForChunk(enumcreaturetype, world, chunk, spawnercreature_c, info::afterSpawn, + int spawnCount = NaturalSpawner.spawnCategoryForChunk(enumcreaturetype, world, chunk, spawnercreature_c, info::afterSpawn,
+ difference, world.paperConfig.perPlayerMobSpawns ? world.getChunkSource().chunkMap::updatePlayerMobTypeMap : null); + difference, world.paperConfig.perPlayerMobSpawns ? world.getChunkSource().chunkMap::updatePlayerMobTypeMap : null);
+ info.mobCategoryCounts.mergeInt(enumcreaturetype, spawnCount, Integer::sum); + info.mobCategoryCounts.mergeInt(enumcreaturetype, spawnCount, Integer::sum);
+ // Paper end - per player mob spawning + // Paper end
} }
} }
@ -724,10 +718,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
BlockPos blockposition = NaturalSpawner.getRandomPosWithin(world, chunk); BlockPos blockposition = NaturalSpawner.getRandomPosWithin(world, chunk);
if (blockposition.getY() >= world.getMinBuildHeight() + 1) { if (blockposition.getY() >= world.getMinBuildHeight() + 1) {
- NaturalSpawner.spawnCategoryForPosition(group, world, (ChunkAccess) chunk, blockposition, checker, runner); - NaturalSpawner.spawnCategoryForPosition(group, world, chunk, blockposition, checker, runner);
+ return NaturalSpawner.spawnCategoryForPosition(group, world, (ChunkAccess) chunk, blockposition, checker, runner, maxSpawns, trackEntity); // Paper + return NaturalSpawner.spawnCategoryForPosition(group, world, chunk, blockposition, checker, runner, maxSpawns, trackEntity); // Paper
} }
+ return 0; // Paper + return 0; // paper
} }
@VisibleForDebug @VisibleForDebug
@ -750,7 +744,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (iblockdata != null && !iblockdata.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn if (iblockdata != null && !iblockdata.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
- int j = 0; - int j = 0;
+ // Paper - moved up + //int j = 0; // Paper - moved up
int k = 0; int k = 0;
while (k < 3) { while (k < 3) {