even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even even more patches

This commit is contained in:
Jason Penilla 2021-11-24 23:47:39 -08:00 committed by MiniDigger | Martin
parent f04f3321e3
commit b39fa92d5d
50 changed files with 2250 additions and 382 deletions

View File

@ -6,23 +6,29 @@ Subject: [PATCH] Guard against serializing mismatching chunk coordinate
Should help if something dumb happens
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index 992a7d6c4372942711a1381ac08ee13910a62cb0..37855d2183212cb043b30418740c0fd047dbc07f 100644
index 384ee6fbc65baff381d875665fd2462dbc99683e..980c784b8e5365b62cbeef7f32af9f4383cc01e6 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -75,6 +75,12 @@ public class ChunkSerializer {
@@ -75,6 +75,18 @@ public class ChunkSerializer {
public ChunkSerializer() {}
+ // Paper start - guard against serializing mismatching coordinates
+ // TODO Note: This needs to be re-checked each update
+ public static ChunkPos getChunkCoordinate(CompoundTag chunkData) {
+ final int dataVersion = ChunkStorage.getVersion(chunkData);
+ if (dataVersion < 2842) { // Level tag is removed after this version
+ final CompoundTag levelData = chunkData.getCompound("Level");
+ return new ChunkPos(levelData.getInt("xPos"), levelData.getInt("zPos"));
+ } else {
+ return new ChunkPos(chunkData.getInt("xPos"), chunkData.getInt("zPos"));
+ }
+ }
+ // Paper end
// Paper start
public static final class InProgressChunkHolder {
@@ -100,7 +106,7 @@ public class ChunkSerializer {
@@ -100,7 +112,7 @@ public class ChunkSerializer {
public static InProgressChunkHolder loadChunk(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt, boolean distinguish) {
java.util.ArrayDeque<Runnable> tasksToExecuteOnMain = new java.util.ArrayDeque<>();
// Paper end
@ -32,7 +38,7 @@ index 992a7d6c4372942711a1381ac08ee13910a62cb0..37855d2183212cb043b30418740c0fd0
if (!Objects.equals(chunkPos, chunkcoordintpair1)) {
ChunkSerializer.LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", chunkPos, chunkPos, chunkcoordintpair1);
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
index 1fc202caf9051f12192ed479898b01b0a02eebbd..0631a5b1af38ace5ad167d1986271081bd2ee7a6 100644
index 2eba8c2d1e978f677eaedac2e09cd1124f1d03db..a750b40be3ba5ba258ca2540ab0398deac5a6c5e 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
@@ -132,6 +132,13 @@ public class ChunkStorage implements AutoCloseable {

View File

@ -256,10 +256,10 @@ index 81701abd11fbc4671393a76a42973f53835ca234..e8cf0088e94925934acd02ba05b9411b
public String toString() {
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index 0980efbc9ef092f56713c7ef776f78fd89cca818..634e44c3eac516f080b565a3b4c7691e31a3eb38 100644
index 980c784b8e5365b62cbeef7f32af9f4383cc01e6..46beea026eec707c69194da6d1d51dc66b61f54e 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -496,11 +496,11 @@ public class ChunkSerializer {
@@ -502,11 +502,11 @@ public class ChunkSerializer {
}
if (nibblearray != null && !nibblearray.isEmpty()) {

View File

@ -9,10 +9,10 @@ the game, immediately stop the server to prevent data corruption.
You can override this functionality at your own peril.
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index 5c21871c7bdfce191db499860725da769dc9caac..d44ce73ea91abd7199695c417c534b6e4ca34e6a 100644
index 46beea026eec707c69194da6d1d51dc66b61f54e..a5bd7d9a7440887d8997a96efebaf3db155263be 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -103,9 +103,22 @@ public class ChunkSerializer {
@@ -109,9 +109,22 @@ public class ChunkSerializer {
return holder.protoChunk;
}

View File

@ -45,10 +45,10 @@ index ee50ea695585639d0ff184b675f3fb3b205b9f86..0bd800e1aeda87689a6c56ee6fadda38
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 691b110e8a64081b68868456089908fe38fbc1cf..673b5192c32ee1b3c0d15462d3fadb0f31cd6a03 100644
index 691b110e8a64081b68868456089908fe38fbc1cf..3eb5e7f7d449ccd862f42e2e131ebcddbdf79afb 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -421,6 +421,29 @@ public final class CraftMagicNumbers implements UnsafeValues {
@@ -421,6 +421,30 @@ public final class CraftMagicNumbers implements UnsafeValues {
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.of((CompoundTag) converted.getValue()));
}
@ -69,7 +69,8 @@ index 691b110e8a64081b68868456089908fe38fbc1cf..673b5192c32ee1b3c0d15462d3fadb0f
+
+ CompoundTag compound = deserializeNbtFromBytes(data);
+ int dataVersion = compound.getInt("DataVersion");
+ compound = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY, compound, dataVersion, getDataVersion());
+ Dynamic<Tag> converted = DataFixers.getDataFixer().update(References.ENTITY_TREE, new Dynamic<>(NbtOps.INSTANCE, compound), dataVersion, getDataVersion());
+ compound = (CompoundTag) converted.getValue();
+ if (!preserveUUID) compound.remove("UUID"); // Generate a new UUID so we don't have to worry about deserializing the same entity twice
+ return net.minecraft.world.entity.EntityType.create(compound, ((org.bukkit.craftbukkit.CraftWorld) world).getHandle())
+ .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")).getBukkitEntity();

View File

@ -953,7 +953,7 @@ index 5d189257f494eb12b5fd98b12da6dd09ca14f972..913b56361dece6c699ed7fad7e580d40
+ // Paper end
}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index dcfc726ab96dccc05848219e824ad7612dbfbdab..db6c11694e6316c50a3f0a138e09542fdae45718 100644
index 7713f26d4a97df94c27694d28881d298e4c54147..3110f8cbf65ba0fefbf78f90915ee358694d20ca 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -386,6 +386,56 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
@ -1013,7 +1013,7 @@ index dcfc726ab96dccc05848219e824ad7612dbfbdab..db6c11694e6316c50a3f0a138e09542f
public Entity(EntityType<?> type, Level world) {
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
this.passengers = ImmutableList.of();
@@ -2233,11 +2283,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
@@ -2242,11 +2292,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
return InteractionResult.PASS;
}

View File

@ -10,7 +10,7 @@ hoping that at least then we don't swap chunks, and maybe recover
them all.
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
index f58050eaa1354ace7b3558d528ab8effdd1432aa..23b3203d04cf1dd2fc3c42e2c7b287a949c81699 100644
index a5bd7d9a7440887d8997a96efebaf3db155263be..c1f22e3e9b3ab91f05556707ace46e9c627b025e 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
@@ -66,6 +66,12 @@ import org.apache.logging.log4j.LogManager;
@ -26,7 +26,7 @@ index f58050eaa1354ace7b3558d528ab8effdd1432aa..23b3203d04cf1dd2fc3c42e2c7b287a9
public static final Codec<PalettedContainer<BlockState>> BLOCK_STATE_CODEC = PalettedContainer.codec(Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState());
private static final Logger LOGGER = LogManager.getLogger();
@@ -437,7 +443,7 @@ public class ChunkSerializer {
@@ -443,7 +449,7 @@ public class ChunkSerializer {
nbttagcompound.putInt("xPos", chunkcoordintpair.x);
nbttagcompound.putInt("yPos", chunk.getMinSection());
nbttagcompound.putInt("zPos", chunkcoordintpair.z);

View File

@ -123,7 +123,7 @@ index 5d4f20a31ad99b4e808bb9a7aaa2153666af493f..928ac2d5b93b93aa7494374f4f344655
private void tickPassenger(Entity vehicle, Entity passenger) {
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index db6c11694e6316c50a3f0a138e09542fdae45718..62fe626aa198d19ccfb48f47b8f771b6037cff9c 100644
index 3110f8cbf65ba0fefbf78f90915ee358694d20ca..96794dcb87c3606e9d112d4159be8be31ad4329e 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -860,7 +860,42 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
@ -183,7 +183,7 @@ index db6c11694e6316c50a3f0a138e09542fdae45718..62fe626aa198d19ccfb48f47b8f771b6
}
protected boolean isHorizontalCollisionMinor(Vec3 adjustedMovement) {
@@ -3798,7 +3840,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
@@ -3807,7 +3849,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
}
public void setDeltaMovement(Vec3 velocity) {
@ -193,7 +193,7 @@ index db6c11694e6316c50a3f0a138e09542fdae45718..62fe626aa198d19ccfb48f47b8f771b6
}
public void setDeltaMovement(double x, double y, double z) {
@@ -3874,7 +3918,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
@@ -3883,7 +3927,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
}
// Paper end - fix MC-4
if (this.position.x != x || this.position.y != y || this.position.z != z) {

View File

@ -20,7 +20,7 @@ up on this optimisation before he came along.
Locally this patch drops the entity tracker tick by a full 1.5x.
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
index 300cd4d2861c7f155cc6a5bb5a0c47b0b77ff240..7c66d5d51efd3ec55f5170cf828db22e26131517 100644
index 241b086bd096a4bc2175835b2505deda1c143f09..a1aafb037fd340dc93dd2afb758ffc7457d15f84 100644
--- a/src/main/java/net/minecraft/network/Connection.java
+++ b/src/main/java/net/minecraft/network/Connection.java
@@ -49,6 +49,8 @@ import org.apache.logging.log4j.Logger;
@ -32,7 +32,7 @@ index 300cd4d2861c7f155cc6a5bb5a0c47b0b77ff240..7c66d5d51efd3ec55f5170cf828db22e
public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
private static final float AVERAGE_PACKETS_SMOOTHING = 0.75F;
@@ -409,9 +411,19 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
@@ -387,9 +389,19 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
if (this.channel.eventLoop().inEventLoop()) {
this.doSendPacket(packet, callback, enumprotocol, enumprotocol1, flush); // Paper - add flush parameter
} else {

View File

@ -9,13 +9,13 @@ since the penalty of a map lookup could outweigh the benefits of
searching less players (as it basically did in the outside range patch).
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
index 4588ae8037407b81c99135863eb0c4e97c564c24..2a33071c4b69cb7b5a7e296e8fd903e3a528b210 100644
index 7418245d5d08706ca2a1378e769abfb0de1076ed..8a7cc96f563c3fb8807d4a8a3249fc0892710d17 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
@@ -242,6 +242,12 @@ public class ChunkHolder {
long key = net.minecraft.server.MCUtil.getCoordinateKey(this.pos);
this.playersInMobSpawnRange = this.chunkMap.playerMobSpawnMap.getObjectsInRange(key);
this.playersInChunkTickRange = this.chunkMap.playerChunkTickRangeMap.getObjectsInRange(key);
@@ -94,6 +94,12 @@ public class ChunkHolder {
this.setTicketLevel(level);
this.changedBlocksPerSection = new ShortSet[world.getSectionsCount()];
this.chunkMap = (ChunkMap)playersWatchingChunkProvider; // Paper
+ // Paper start - optimise checkDespawn
+ LevelChunk chunk = this.getFullChunkUnchecked();
+ if (chunk != null) {
@ -23,16 +23,16 @@ index 4588ae8037407b81c99135863eb0c4e97c564c24..2a33071c4b69cb7b5a7e296e8fd903e3
+ }
+ // Paper end - optimise checkDespawn
}
// Paper end - optimise isOutsideOfRange
long lastAutoSaveTime; // Paper - incremental autosave
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 6522eb4b72c50be3ff7d1b094066a1cbec88634d..10d1e1f728519ad49379895c7fd3668badcbfd5a 100644
index 925da0baa59f742dbe727c6323cc90b65159f314..3b2db473e5eacbcf55ae8786aff5ac71388a98ee 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -217,6 +217,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerMobSpawnMap; // this map is absent from updateMaps since it's controlled at the start of the chunkproviderserver tick
public final com.destroystokyo.paper.util.misc.PlayerAreaMap playerChunkTickRangeMap;
// Paper end - optimise PlayerChunkMap#isOutsideRange
@@ -190,21 +190,36 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper
// Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
+ // Paper start - optimise checkDespawn
+ public static final int GENERAL_AREA_MAP_SQUARE_RADIUS = 40;
+ public static final double GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE = 16.0 * (GENERAL_AREA_MAP_SQUARE_RADIUS - 1);
@ -42,40 +42,34 @@ index 6522eb4b72c50be3ff7d1b094066a1cbec88634d..10d1e1f728519ad49379895c7fd3668b
void addPlayerToDistanceMaps(ServerPlayer player) {
int chunkX = MCUtil.getChunkCoordinate(player.getX());
@@ -237,6 +243,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.playerChunkTickRangeMap.add(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE);
// Paper end - optimise PlayerChunkMap#isOutsideRange
this.playerChunkManager.addPlayer(player); // Paper - replace chunk loader
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// Note: players need to be explicitly added to distance maps before they can be updated
+ // Paper start - optimise checkDespawn
+ this.playerGeneralAreaMap.add(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS);
+ // Paper end - optimise checkDespawn
}
void removePlayerFromDistanceMaps(ServerPlayer player) {
@@ -250,6 +259,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.playerChunkTickRangeMap.remove(player);
// Paper end - optimise PlayerChunkMap#isOutsideRange
this.playerChunkManager.removePlayer(player); // Paper - replace chunk loader
+ // Paper start - optimise checkDespawn
+ this.playerGeneralAreaMap.remove(player);
+ // Paper end - optimise checkDespawn
}
void updateMaps(ServerPlayer player) {
@@ -268,6 +280,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, DistanceManager.MOB_SPAWN_RANGE);
// Paper end - optimise PlayerChunkMap#isOutsideRange
this.playerChunkManager.updatePlayer(player); // Paper - replace chunk loader
int chunkX = MCUtil.getChunkCoordinate(player.getX());
int chunkZ = MCUtil.getChunkCoordinate(player.getZ());
// Note: players need to be explicitly added to distance maps before they can be updated
+ // Paper start - optimise checkDespawn
+ this.playerGeneralAreaMap.update(player, chunkX, chunkZ, GENERAL_AREA_MAP_SQUARE_RADIUS);
+ // Paper end - optimise checkDespawn
}
// Paper end
// Paper start
@@ -426,6 +441,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
});
// Paper end - optimise PlayerChunkMap#isOutsideRange
@@ -280,6 +295,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
this.regionManagers.add(this.dataRegionManager);
// Paper end
this.playerMobDistanceMap = this.level.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper
+ // Paper start - optimise checkDespawn
+ this.playerGeneralAreaMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets,
+ (ServerPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
@ -95,32 +89,15 @@ index 6522eb4b72c50be3ff7d1b094066a1cbec88634d..10d1e1f728519ad49379895c7fd3668b
+ // Paper end - optimise checkDespawn
}
// Paper start - Chunk Prioritization
@@ -739,7 +771,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} else {
if (holder != null) {
holder.setTicketLevel(level);
- holder.updateRanges(); // Paper - optimise isOutsideOfRange
+ // Paper - move to correct place
}
if (holder != null) {
@@ -754,6 +786,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
holder = (ChunkHolder) this.pendingUnloads.remove(pos);
if (holder != null) {
holder.setTicketLevel(level);
+ holder.updateRanges(); // Paper - optimise isOutsideOfRange // Paper - move to correct place
} else {
holder = new ChunkHolder(new ChunkPos(pos), level, this.level, this.lightEngine, this.queueSorter, this);
// Paper start
protected ChunkGenerator generator() {
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index ed696ed93251e644c2b71e468e2556d24b273933..3afb8b91dceb86e88b848462a5b8dbd5c8365239 100644
index 5935c442a6534ad51d191a72bc8d2043fa25e2ac..8a219ecabe49d8f2564a365968891b214a090f6d 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -392,6 +392,83 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -396,6 +396,83 @@ public class ServerLevel extends Level implements WorldGenLevel {
return this.getServer().getPlayerList().getPlayer(uuid);
}
}
// Paper end - rewrite ticklistserver
// Paper end
+ // Paper start - optimise checkDespawn
+ public final List<ServerPlayer> playersAffectingSpawning = new java.util.ArrayList<>();
+ // Paper end - optimise checkDespawn
@ -201,7 +178,7 @@ index ed696ed93251e644c2b71e468e2556d24b273933..3afb8b91dceb86e88b848462a5b8dbd5
// Add env and gen to constructor, WorldData -> WorldDataServer
public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, ServerLevelData iworlddataserver, ResourceKey<Level> resourcekey, DimensionType dimensionmanager, ChunkProgressListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<CustomSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
@@ -492,6 +569,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -484,6 +561,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
public void tick(BooleanSupplier shouldKeepTicking) {
@ -217,10 +194,10 @@ index ed696ed93251e644c2b71e468e2556d24b273933..3afb8b91dceb86e88b848462a5b8dbd5
this.handlingTick = true;
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 5f4556505d831ea45e576a4c4e10f99e1353684e..55d07e70a67e08bab3a7a66076c980986736e5b8 100644
index 697c2663c4deeb8f2ad603c979ab0884ac027930..0b46066d35d9bb38d98a9d6e5ca8dbdc0ba1dc5a 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -789,7 +789,12 @@ public abstract class Mob extends LivingEntity {
@@ -792,7 +792,12 @@ public abstract class Mob extends LivingEntity {
if (this.level.getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) {
this.discard();
} else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) {
@ -233,12 +210,12 @@ index 5f4556505d831ea45e576a4c4e10f99e1353684e..55d07e70a67e08bab3a7a66076c98098
+ // Paper end - optimise checkDespawn
if (entityhuman != null) {
double d0 = entityhuman.distanceToSqr((Entity) this); // CraftBukkit - decompile error
double d0 = entityhuman.distanceToSqr((Entity) this);
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 64d5e71a8a26116385cee195d86fce1ef1574a8c..f936e9f9a9fa655fa997d6862b5ed54c04169d35 100644
index 6be462975523dae9ff436ba1643b2042ec66e554..929f48675a10fdd64cb351305389d680a16963fb 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -247,6 +247,69 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -243,6 +243,69 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
return ret;
}
// Paper end
@ -306,13 +283,13 @@ index 64d5e71a8a26116385cee195d86fce1ef1574a8c..f936e9f9a9fa655fa997d6862b5ed54c
+ }
+ // Paper end - optimise checkDespawn
protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, final DimensionType dimensionmanager, Supplier<ProfilerFiller> supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) { // Paper - Anti-Xray - Pass executor
protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, final DimensionType dimensionmanager, Supplier<ProfilerFiller> supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env) {
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
index 4d8251a961a9c52456db997506dd9691beaec022..55dd04816886d27a62856ac952d2fc5d15bf40e6 100644
index 63ba93538d990fdd4c9e8c491bb715adc8d57986..e9a37fc6791366ea421f2766a36dc2e014ab7951 100644
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -267,7 +267,7 @@ public final class NaturalSpawner {
@@ -269,7 +269,7 @@ public final class NaturalSpawner {
blockposition_mutableblockposition.set(l, i, i1);
double d0 = (double) l + 0.5D;
double d1 = (double) i1 + 0.5D;
@ -321,7 +298,7 @@ index 4d8251a961a9c52456db997506dd9691beaec022..55dd04816886d27a62856ac952d2fc5d
if (entityhuman != null) {
double d2 = entityhuman.distanceToSqr(d0, (double) i, d1);
@@ -340,7 +340,7 @@ public final class NaturalSpawner {
@@ -342,7 +342,7 @@ public final class NaturalSpawner {
}
private static boolean isRightDistanceToPlayerAndSpawnPoint(ServerLevel world, ChunkAccess chunk, BlockPos.MutableBlockPos pos, double squaredDistance) {
@ -331,10 +308,10 @@ index 4d8251a961a9c52456db997506dd9691beaec022..55dd04816886d27a62856ac952d2fc5d
private static Boolean isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureFeatureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) { // 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 9e75ee7f43722f05dd5df4ef00f7d3e271f4c6e5..86686c24b0b7de4b4bfadbc77419a8872a8e86ee 100644
index b92da719a5d35a60a2e13ccb0f55c41b242f9b50..a9807f9182a4d70e09486612606c7c1d0a6734ac 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -369,6 +369,93 @@ public class LevelChunk implements ChunkAccess {
@@ -231,6 +231,93 @@ public class LevelChunk extends ChunkAccess {
}
}
// Paper end
@ -426,5 +403,5 @@ index 9e75ee7f43722f05dd5df4ef00f7d3e271f4c6e5..86686c24b0b7de4b4bfadbc77419a887
+ }
+ // Paper end - optimise checkDespawn
public LevelChunk(ServerLevel worldserver, ProtoChunk protoChunk, @Nullable Consumer<LevelChunk> consumer) {
this(worldserver, protoChunk.getPos(), protoChunk.getBiomes(), protoChunk.getUpgradeData(), protoChunk.getBlockTicks(), protoChunk.getLiquidTicks(), protoChunk.getInhabitedTime(), protoChunk.getSections(), consumer);
public LevelChunk(ServerLevel world, ProtoChunk protoChunk, @Nullable LevelChunk.PostLoadProcessor chunk_c) {
this(world, protoChunk.getPos(), protoChunk.getUpgradeData(), protoChunk.unpackBlockTicks(), protoChunk.unpackFluidTicks(), protoChunk.getInhabitedTime(), protoChunk.getSections(), chunk_c, protoChunk.getBlendingData());

View File

@ -8,10 +8,10 @@ Instead, only iterate over navigators in the current region that are
eligible for repathing.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index bef7d5b4c8b99d2fbcd975127b16653e0f391338..19a853ceeded1c8803d182d035f0362abfa29933 100644
index 3b2db473e5eacbcf55ae8786aff5ac71388a98ee..6fc7c1cf269466362dce91fa2cf525e67bee6c15 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -290,15 +290,81 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -227,15 +227,81 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public final io.papermc.paper.chunk.SingleThreadChunkRegionManager dataRegionManager;
public static final class DataRegionData implements io.papermc.paper.chunk.SingleThreadChunkRegionManager.RegionData {
@ -93,7 +93,7 @@ index bef7d5b4c8b99d2fbcd975127b16653e0f391338..19a853ceeded1c8803d182d035f0362a
}
@Override
@@ -308,6 +374,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@@ -245,6 +311,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
final DataRegionSectionData sectionData = (DataRegionSectionData)section.sectionData;
final DataRegionData oldRegionData = oldRegion == null ? null : (DataRegionData)oldRegion.regionData;
final DataRegionData newRegionData = (DataRegionData)newRegion.regionData;
@ -110,10 +110,10 @@ index bef7d5b4c8b99d2fbcd975127b16653e0f391338..19a853ceeded1c8803d182d035f0362a
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 89a8138e97ab6a399cfbc69cab0ecaa70bb2fe8d..c01b5611fe6946a24fe21eac6a80e3ddadf9f3c1 100644
index 8a219ecabe49d8f2564a365968891b214a090f6d..8837c9793eb25ad88bdb4b0f6198dc7ae353b9b2 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1079,6 +1079,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -1090,6 +1090,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
public void tickNonPassenger(Entity entity) {
// Paper start - log detailed entity tick information
io.papermc.paper.util.TickThread.ensureTickThread("Cannot tick an entity off-main");
@ -121,7 +121,7 @@ index 89a8138e97ab6a399cfbc69cab0ecaa70bb2fe8d..c01b5611fe6946a24fe21eac6a80e3dd
try {
if (currentlyTickingEntity.get() == null) {
currentlyTickingEntity.lazySet(entity);
@@ -1524,9 +1525,19 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -1504,9 +1505,19 @@ public class ServerLevel extends Level implements WorldGenLevel {
VoxelShape voxelshape1 = newState.getCollisionShape(this, pos);
if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) {
@ -143,7 +143,7 @@ index 89a8138e97ab6a399cfbc69cab0ecaa70bb2fe8d..c01b5611fe6946a24fe21eac6a80e3dd
// CraftBukkit start - fix SPIGOT-6362
Mob entityinsentient;
try {
@@ -1545,6 +1556,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -1525,6 +1536,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
navigationabstract.recomputePath(pos);
}
}
@ -155,7 +155,7 @@ index 89a8138e97ab6a399cfbc69cab0ecaa70bb2fe8d..c01b5611fe6946a24fe21eac6a80e3dd
}
} // Paper
@@ -2324,10 +2340,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -2317,10 +2333,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
public void onTickingStart(Entity entity) {
ServerLevel.this.entityTickList.add(entity);
@ -169,7 +169,7 @@ index 89a8138e97ab6a399cfbc69cab0ecaa70bb2fe8d..c01b5611fe6946a24fe21eac6a80e3dd
public void onTrackingStart(Entity entity) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
index 61080352ef305a1f276dbc297aa680b3175a5da2..10505f32b71b723ed8dbfd9e1348a1691c9f7f18 100644
index 5884fb42f0880585dee843b98a6ea470a1508e46..4651c2e78089ed28220e767654261c735d2c5eb1 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
@@ -27,7 +27,7 @@ import net.minecraft.world.phys.Vec3;
@ -189,8 +189,8 @@ index 61080352ef305a1f276dbc297aa680b3175a5da2..10505f32b71b723ed8dbfd9e1348a169
+ protected boolean hasDelayedRecomputation; protected final boolean needsPathRecalculation() { return this.hasDelayedRecomputation; } // Paper - public accessor
protected long timeLastRecompute;
protected NodeEvaluator nodeEvaluator;
private BlockPos targetPos;
@@ -49,6 +49,13 @@ public abstract class PathNavigation {
@Nullable
@@ -50,6 +50,13 @@ public abstract class PathNavigation {
public final PathFinder pathFinder;
private boolean isStuck;
@ -204,7 +204,7 @@ index 61080352ef305a1f276dbc297aa680b3175a5da2..10505f32b71b723ed8dbfd9e1348a169
public PathNavigation(Mob mob, Level world) {
this.mob = mob;
this.level = world;
@@ -405,7 +412,7 @@ public abstract class PathNavigation {
@@ -415,7 +422,7 @@ public abstract class PathNavigation {
}
public void recomputePath(BlockPos pos) {
@ -214,7 +214,7 @@ index 61080352ef305a1f276dbc297aa680b3175a5da2..10505f32b71b723ed8dbfd9e1348a169
Vec3 vec3 = new Vec3(((double)node.x + this.mob.getX()) / 2.0D, ((double)node.y + this.mob.getY()) / 2.0D, ((double)node.z + this.mob.getZ()) / 2.0D);
if (pos.closerThan(vec3, (double)(this.path.getNodeCount() - this.path.getNextNodeIndex()))) {
diff --git a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
index 976d206a17add01a31ae38b966913368cf386cb1..28c1f144f2cc8675ed61dc814456859309970480 100644
index 1d61807768dd883cb82bda5d529055bc50e4d1a9..d963243431e1a75f95e673e1268faa7c2320c6b6 100644
--- a/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
+++ b/src/main/java/net/minecraft/world/level/entity/PersistentEntitySectionManager.java
@@ -71,6 +71,65 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
@ -283,7 +283,7 @@ index 976d206a17add01a31ae38b966913368cf386cb1..28c1f144f2cc8675ed61dc8144568593
void removeSectionIfEmpty(long sectionPos, EntitySection<T> section) {
if (section.isEmpty()) {
this.sectionStorage.remove(sectionPos);
@@ -462,11 +521,25 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
@@ -451,11 +510,25 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
@Override
public void onMove() {
BlockPos blockposition = this.entity.blockPosition();
@ -311,8 +311,8 @@ index 976d206a17add01a31ae38b966913368cf386cb1..28c1f144f2cc8675ed61dc8144568593
if (!this.currentSection.remove(this.entity)) {
PersistentEntitySectionManager.LOGGER.warn("Entity {} wasn't found in section {} (moving to {})", this.entity, SectionPos.of(this.currentSectionKey), i);
@@ -478,6 +551,11 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
entitysection.add(this.entity); // CraftBukkit - decompile error
@@ -467,6 +540,11 @@ public class PersistentEntitySectionManager<T extends EntityAccess> implements A
entitysection.add(this.entity);
this.currentSection = entitysection;
this.currentSectionKey = i;
+ // Paper start

View File

@ -5,17 +5,17 @@ Subject: [PATCH] Remove streams for villager AI
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
index 09998d160a6d79fdb5a5041a5d572649a1532e6a..84bd9298840ba60abbdb0675cda0458e0d6a534a 100644
index e644bdd3a6f7c09a44149da03587b796674fa568..c67c448e0d8bdd788b94189651304110694c95da 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
@@ -30,11 +30,19 @@ public class GateBehavior<E extends LivingEntity> extends Behavior<E> {
@Override
protected boolean canStillUse(ServerLevel world, E entity, long time) {
- return this.behaviors.stream().filter((behavior) -> {
- return behavior.getStatus() == Behavior.Status.RUNNING;
- }).anyMatch((behavior) -> {
- return behavior.canStillUse(world, entity, time);
- return this.behaviors.stream().filter((task) -> {
- return task.getStatus() == Behavior.Status.RUNNING;
- }).anyMatch((task) -> {
- return task.canStillUse(world, entity, time);
- });
+ // Paper start - remove streams
+ List<ShufflingList.WeightedEntry<Behavior<? super E>>> entries = this.behaviors.entries;
@ -43,10 +43,10 @@ index 09998d160a6d79fdb5a5041a5d572649a1532e6a..84bd9298840ba60abbdb0675cda0458e
@Override
protected void tick(ServerLevel world, E entity, long time) {
- this.behaviors.stream().filter((behavior) -> {
- return behavior.getStatus() == Behavior.Status.RUNNING;
- }).forEach((behavior) -> {
- behavior.tickOrStop(world, entity, time);
- this.behaviors.stream().filter((task) -> {
- return task.getStatus() == Behavior.Status.RUNNING;
- }).forEach((task) -> {
- task.tickOrStop(world, entity, time);
- });
+ // Paper start - remove streams
+ List<ShufflingList.WeightedEntry<Behavior<? super E>>> entries = this.behaviors.entries;
@ -62,10 +62,10 @@ index 09998d160a6d79fdb5a5041a5d572649a1532e6a..84bd9298840ba60abbdb0675cda0458e
@Override
protected void stop(ServerLevel world, E entity, long time) {
- this.behaviors.stream().filter((behavior) -> {
- return behavior.getStatus() == Behavior.Status.RUNNING;
- }).forEach((behavior) -> {
- behavior.doStop(world, entity, time);
- this.behaviors.stream().filter((task) -> {
- return task.getStatus() == Behavior.Status.RUNNING;
- }).forEach((task) -> {
- task.doStop(world, entity, time);
- });
+ // Paper start - remove streams
+ List<ShufflingList.WeightedEntry<Behavior<? super E>>> entries = this.behaviors.entries;
@ -85,10 +85,10 @@ index 09998d160a6d79fdb5a5041a5d572649a1532e6a..84bd9298840ba60abbdb0675cda0458e
RUN_ONE {
@Override
- public <E extends LivingEntity> void apply(Stream<Behavior<? super E>> tasks, ServerLevel world, E entity, long time) {
- tasks.filter((behavior) -> {
- return behavior.getStatus() == Behavior.Status.STOPPED;
- }).filter((behavior) -> {
- return behavior.tryStart(world, entity, time);
- tasks.filter((task) -> {
- return task.getStatus() == Behavior.Status.STOPPED;
- }).filter((task) -> {
- return task.tryStart(world, entity, time);
- }).findFirst();
+ // Paper start - remove streams
+ public <E extends LivingEntity> void apply(List<ShufflingList.WeightedEntry<Behavior<? super E>>> tasks, ServerLevel world, E entity, long time) {
@ -105,10 +105,10 @@ index 09998d160a6d79fdb5a5041a5d572649a1532e6a..84bd9298840ba60abbdb0675cda0458e
TRY_ALL {
@Override
- public <E extends LivingEntity> void apply(Stream<Behavior<? super E>> tasks, ServerLevel world, E entity, long time) {
- tasks.filter((behavior) -> {
- return behavior.getStatus() == Behavior.Status.STOPPED;
- }).forEach((behavior) -> {
- behavior.tryStart(world, entity, time);
- tasks.filter((task) -> {
- return task.getStatus() == Behavior.Status.STOPPED;
- }).forEach((task) -> {
- task.tryStart(world, entity, time);
- });
+ // Paper start - remove streams
+ public <E extends LivingEntity> void apply(List<ShufflingList.WeightedEntry<Behavior<? super E>>> tasks, ServerLevel world, E entity, long time) {
@ -127,64 +127,8 @@ index 09998d160a6d79fdb5a5041a5d572649a1532e6a..84bd9298840ba60abbdb0675cda0458e
+ public abstract <E extends LivingEntity> void apply(List<ShufflingList.WeightedEntry<Behavior<? super E>>> tasks, ServerLevel world, E entity, long time); // Paper - remove streams
}
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/SetLookAndInteract.java b/src/main/java/net/minecraft/world/entity/ai/behavior/SetLookAndInteract.java
index 1f59e790d62f0be8e505e339a6699ca3964aea0d..ee783bb7cbec2f58549cb95fde7cbc4c47efa1cb 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/SetLookAndInteract.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/SetLookAndInteract.java
@@ -34,21 +34,42 @@ public class SetLookAndInteract extends Behavior<LivingEntity> {
@Override
public boolean checkExtraStartConditions(ServerLevel world, LivingEntity entity) {
- return this.selfFilter.test(entity) && this.getVisibleEntities(entity).stream().anyMatch(this::isMatchingTarget);
+ // Paper start - remove streams
+ if (!this.selfFilter.test(entity)) {
+ return false;
+ }
+
+ List<LivingEntity> visibleEntities = this.getVisibleEntities(entity);
+ for (int i = 0; i < visibleEntities.size(); i++) {
+ LivingEntity livingEntity = visibleEntities.get(i);
+ if (this.isMatchingTarget(livingEntity)) {
+ return true;
+ }
+ }
+ return false;
+ // Paper end - remove streams
}
@Override
public void start(ServerLevel world, LivingEntity entity, long time) {
super.start(world, entity, time);
Brain<?> brain = entity.getBrain();
- brain.getMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES).ifPresent((list) -> {
- list.stream().filter((livingEntity2) -> {
- return livingEntity2.distanceToSqr(entity) <= (double)this.interactionRangeSqr;
- }).filter(this::isMatchingTarget).findFirst().ifPresent((livingEntity) -> {
- brain.setMemory(MemoryModuleType.INTERACTION_TARGET, livingEntity);
- brain.setMemory(MemoryModuleType.LOOK_TARGET, new EntityTracker(livingEntity, true));
- });
- });
+ // Paper start - remove streams
+ List<LivingEntity> list = brain.getMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES).orElse(null);
+ if (list != null) {
+ double maxRangeSquared = (double)this.interactionRangeSqr;
+ for (int i = 0; i < list.size(); i++) {
+ LivingEntity livingEntity2 = list.get(i);
+ if (livingEntity2.distanceToSqr(entity) <= maxRangeSquared) {
+ if (this.isMatchingTarget(livingEntity2)) {
+ brain.setMemory(MemoryModuleType.INTERACTION_TARGET, livingEntity2);
+ brain.setMemory(MemoryModuleType.LOOK_TARGET, new EntityTracker(livingEntity2, true));
+ break;
+ }
+ }
+ }
+ }
+ // Paper end - remove streams
}
private boolean isMatchingTarget(LivingEntity entity) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java
index 4fa64b1e2004810906bb0b174436c8e687a75ada..aaff4038867820ab2694f036dcd3c419657be6b8 100644
index 1bc34453933bc7590af45a5559a4fc75eb3e0c5c..204ca4fbd89bdadd902529f1f191df46fce3cace 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java
@@ -12,7 +12,7 @@ import java.util.Random;
@ -225,44 +169,17 @@ index 49f3b25d28072b61f5cc97260df61df892a58714..71f2692c83feafbb31f45427e6c738cb
brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, Optional.ofNullable(nearest));
// Paper end
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
index ffd83db0a419ab589e89feeddd3fb038d6ed5839..c6947aa93b7d2fbc23b0c0e76eed061eb03140c7 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestLivingEntitySensor.java
@@ -18,12 +18,19 @@ public class NearestLivingEntitySensor extends Sensor<LivingEntity> {
List<LivingEntity> list = world.getEntitiesOfClass(LivingEntity.class, aABB, (livingEntity2) -> {
return livingEntity2 != entity && livingEntity2.isAlive();
});
- list.sort(Comparator.comparingDouble(entity::distanceToSqr));
+ // Paper start - remove streams
+ list.sort((e1, e2) -> Double.compare(entity.distanceToSqr(e1), entity.distanceToSqr(e2)));
Brain<?> brain = entity.getBrain();
brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, list);
// Paper start - remove streams in favour of lists
- List<LivingEntity> visibleMobs = new java.util.ArrayList<>(list);
- visibleMobs.removeIf(otherEntityLiving -> !Sensor.isEntityTargetable(entity, otherEntityLiving));
+ List<LivingEntity> visibleMobs = new java.util.ArrayList<>();
+ for (int i = 0, len = list.size(); i < len; i++) {
+ LivingEntity nearby = list.get(i);
+ if (Sensor.isEntityTargetable(entity, nearby)) {
+ visibleMobs.add(nearby);
+ }
+ }
+ // Paper end - remove streams
brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, visibleMobs);
// Paper end
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java
index 457ea75137b8b02dc32bf1769ae8d57c470da470..217c8fd1edf664dc568ee0559a38e0bd2a36696c 100644
index 312775d0430f793720211dc29bb293503e799d11..75d9c4f011b5a97def215784c92bb57bbb35d06b 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java
@@ -21,25 +21,31 @@ public class PlayerSensor extends Sensor<LivingEntity> {
@@ -21,25 +21,30 @@ public class PlayerSensor extends Sensor<LivingEntity> {
@Override
protected void doTick(ServerLevel world, LivingEntity entity) {
- // Paper start - remove streams in favour of lists
- List<Player> players = new java.util.ArrayList<>(world.players());
- players.removeIf(player -> !EntitySelector.NO_SPECTATORS.test(player) || !entity.closerThan(player, 16.0D)); // Paper - removeIf only re-allocates once compared to iterator
- players.removeIf(player -> !EntitySelector.NO_SPECTATORS.test(player) || !entity.closerThan(player, 16.0D));
- players.sort(Comparator.comparingDouble(entity::distanceTo));
+ // Paper start - remove streams
+ List<Player> players = (List)world.getNearbyPlayers(entity, entity.getX(), entity.getY(), entity.getZ(), 16.0D, EntitySelector.NO_SPECTATORS);
+ players.sort((e1, e2) -> Double.compare(entity.distanceToSqr(e1), entity.distanceToSqr(e2)));
@ -296,32 +213,8 @@ index 457ea75137b8b02dc32bf1769ae8d57c470da470..217c8fd1edf664dc568ee0559a38e0bd
- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, nearest);
- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, nearestTargetable);
- // Paper end
+
+ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, firstTargetable);
+ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, Optional.ofNullable(firstAttackable));
+ // Paper end - remove streams
}
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/VillagerBabiesSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/VillagerBabiesSensor.java
index 478010bc291fa3276aab0f66ce6283403af710ec..de39b608856bdf9bef7120a6922c01c5745f3771 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/VillagerBabiesSensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/VillagerBabiesSensor.java
@@ -22,7 +22,17 @@ public class VillagerBabiesSensor extends Sensor<LivingEntity> {
}
private List<LivingEntity> getNearestVillagerBabies(LivingEntity entities) {
- return this.getVisibleEntities(entities).stream().filter(this::isVillagerBaby).collect(Collectors.toList());
+ // Paper start - remove streams
+ List<LivingEntity> list = new java.util.ArrayList<>();
+ List<LivingEntity> visibleEntities = this.getVisibleEntities(entities);
+ for (int i = 0; i < visibleEntities.size(); i++) {
+ LivingEntity livingEntity = visibleEntities.get(i);
+ if (this.isVillagerBaby(livingEntity)) {
+ list.add(livingEntity);
+ }
+ }
+ return list;
+ // Paper end - remove streams
}
private boolean isVillagerBaby(LivingEntity entity) {

View File

@ -29,3 +29,5 @@ check ChunkHolder#updateFutures async catcher
leaf: check mid tick chunk task diff in ServerChunkCache
optimize nearby player lookups - look at patch and updateranges diff in chunkmap (why is it in this patch)
GENERAL_AREA_MAP_ACCEPTABLE_SEARCH_RANGE_SQUARED is unused?