moaaaaar patches

This commit is contained in:
Jake 2021-11-24 11:33:17 -08:00 committed by MiniDigger | Martin
parent e141126891
commit 6f5b43e290
23 changed files with 50 additions and 69 deletions

View file

@ -1,140 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: kennytv <jahnke.nassim@gmail.com>
Date: Fri, 29 Jan 2021 15:13:11 +0100
Subject: [PATCH] Add dropLeash variable to EntityUnleashEvent
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 976dbf40292b10364f9e80bebe96ec9c4dfb657e..c375081e02925da6085a2d433bfc2c3719770f78 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -1213,12 +1213,15 @@ public abstract class Mob extends LivingEntity {
return InteractionResult.PASS;
} else if (this.getLeashHolder() == player) {
// CraftBukkit start - fire PlayerUnleashEntityEvent
- if (CraftEventFactory.callPlayerUnleashEntityEvent(this, player).isCancelled()) {
+ // Paper start - drop leash variable
+ org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(this, player, !player.getAbilities().instabuild);
+ if (event.isCancelled()) {
+ // Paper end
((ServerPlayer) player).connection.send(new ClientboundSetEntityLinkPacket(this, this.getLeashHolder()));
return InteractionResult.PASS;
}
// CraftBukkit end
- this.dropLeash(true, !player.getAbilities().instabuild);
+ this.dropLeash(true, event.isDropLeash()); // Paper - drop leash variable
return InteractionResult.sidedSuccess(this.level.isClientSide);
} else {
InteractionResult enuminteractionresult = this.checkAndHandleImportantInteractions(player, hand);
@@ -1376,8 +1379,11 @@ public abstract class Mob extends LivingEntity {
if (this.leashHolder != null) {
if (!this.isAlive() || !this.leashHolder.isAlive()) {
- this.level.getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), (!this.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE)); // CraftBukkit
- this.dropLeash(true, true);
+ // Paper start - drop leash variable
+ EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), (!this.isAlive()) ? UnleashReason.PLAYER_UNLEASH : UnleashReason.HOLDER_GONE, true);
+ this.level.getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ this.dropLeash(true, event.isDropLeash());
+ // Paper end
}
}
@@ -1440,8 +1446,11 @@ public abstract class Mob extends LivingEntity {
boolean flag1 = super.startRiding(entity, force);
if (flag1 && this.isLeashed()) {
- this.level.getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit
- this.dropLeash(true, true);
+ // Paper start - drop leash variable
+ EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN, true);
+ this.level.getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ this.dropLeash(true, event.isDropLeash());
+ // Paper end
}
return flag1;
@@ -1611,8 +1620,11 @@ public abstract class Mob extends LivingEntity {
@Override
protected void removeAfterChangingDimensions() {
super.removeAfterChangingDimensions();
- this.level.getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit
- this.dropLeash(true, false);
+ // Paper start - drop leash variable
+ EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN, false);
+ this.level.getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ this.dropLeash(true, event.isDropLeash());
+ // Paper end
this.getAllSlots().forEach((itemstack) -> {
if (!itemstack.isEmpty()) itemstack.setCount(0); // CraftBukkit
});
diff --git a/src/main/java/net/minecraft/world/entity/PathfinderMob.java b/src/main/java/net/minecraft/world/entity/PathfinderMob.java
index a884940cc576704951d42c6b0d00f5a319297c29..d16a7bab5495d58ea9e6811d4b507667cfa3d264 100644
--- a/src/main/java/net/minecraft/world/entity/PathfinderMob.java
+++ b/src/main/java/net/minecraft/world/entity/PathfinderMob.java
@@ -47,8 +47,11 @@ public abstract class PathfinderMob extends Mob {
if (this instanceof TamableAnimal && ((TamableAnimal) this).isInSittingPose()) {
if (f > entity.level.paperConfig.maxLeashDistance) { // Paper
- this.level.getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE)); // CraftBukkit
- this.dropLeash(true, true);
+ // Paper start - drop leash variable
+ EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE, true);
+ this.level.getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ this.dropLeash(true, event.isDropLeash());
+ // Paper end
}
return;
@@ -56,8 +59,11 @@ public abstract class PathfinderMob extends Mob {
this.onLeashDistance(f);
if (f > entity.level.paperConfig.maxLeashDistance) { // Paper
- this.level.getCraftServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE)); // CraftBukkit
- this.dropLeash(true, true);
+ // Paper start - drop leash variable
+ EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE, true);
+ this.level.getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ this.dropLeash(true, event.isDropLeash());
+ // Paper end
this.goalSelector.disableControlFlag(Goal.Flag.MOVE);
} else if (f > 6.0F) {
double d0 = (entity.getX() - this.getX()) / (double) f;
diff --git a/src/main/java/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java b/src/main/java/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
index b9b67134f02fd7484ed19905c9ae1f9b8a26ce26..c05f173b7642380900fdd77ce5d2c020468b5fc0 100644
--- a/src/main/java/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
+++ b/src/main/java/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java
@@ -123,11 +123,14 @@ public class LeashFenceKnotEntity extends HangingEntity {
entityinsentient = (Mob) iterator.next();
if (entityinsentient.isLeashed() && entityinsentient.getLeashHolder() == this) {
// CraftBukkit start
- if (CraftEventFactory.callPlayerUnleashEntityEvent(entityinsentient, player).isCancelled()) {
+ // Paper start - drop leash variable
+ org.bukkit.event.player.PlayerUnleashEntityEvent event = CraftEventFactory.callPlayerUnleashEntityEvent(entityinsentient, player, !player.getAbilities().instabuild);
+ if (event.isCancelled()) {
+ // Paper end
die = false;
continue;
}
- entityinsentient.dropLeash(true, !player.getAbilities().instabuild); // false -> survival mode boolean
+ entityinsentient.dropLeash(true, event.isDropLeash()); // false -> survival mode boolean // Paper - drop leash variable
// CraftBukkit end
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index db6b057eb6b0f08f7fcb998f8b646b757a98d3f6..33a8e174c4e3b3b5164157c90c8f5b5f9c6d8263 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -1489,8 +1489,10 @@ public class CraftEventFactory {
return itemInHand;
}
- public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(Mob entity, net.minecraft.world.entity.player.Player player) {
- PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity());
+ // Paper start - drop leash variable
+ public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(Mob entity, net.minecraft.world.entity.player.Player player, boolean dropLeash) {
+ PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity(), dropLeash);
+ // Paper end
entity.level.getCraftServer().getPluginManager().callEvent(event);
return event;
}

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Beech Horn <beechhorn@gmail.com>
Date: Fri, 14 Feb 2020 19:39:59 +0000
Subject: [PATCH] Skip distance map update when spawning disabled.
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 77a6a5883d7e9fba12d0a2c8f3e7f2565d4785b4..6d0c56e4071a990a3b168143e8ac73f8b5ed0379 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -974,7 +974,7 @@ public class ServerChunkCache extends ChunkSource {
int l = this.distanceManager.getNaturalSpawnChunkCount();
// Paper start - per player mob spawning
NaturalSpawner.SpawnState spawnercreature_d; // moved down
- if (this.chunkMap.playerMobDistanceMap != null) {
+ if ((this.spawnFriendlies || this.spawnEnemies) && this.chunkMap.playerMobDistanceMap != null) { // don't update when animals and monsters are disabled
// update distance map
this.level.timings.playerMobDistanceMapUpdate.startTiming();
this.chunkMap.playerMobDistanceMap.update(this.level.players, this.chunkMap.viewDistance);

View file

@ -1,22 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yive <admin@yive.me>
Date: Sun, 24 Jan 2021 08:55:19 -0800
Subject: [PATCH] Reset shield blocking on dimension change
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 8608464c1d229625a10fd459427d8cc5e217789a..e1296bbc1f31f270053a47c21887efbad8718b72 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1142,6 +1142,11 @@ public class ServerPlayer extends Player {
this.level.getCraftServer().getPluginManager().callEvent(changeEvent);
// CraftBukkit end
}
+ // Paper start
+ if (this.isBlocking()) {
+ this.stopUsingItem();
+ }
+ // Paper end
return this;
}

View file

@ -1,36 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Trigary <trigary0@gmail.com>
Date: Mon, 25 Jan 2021 14:53:57 +0100
Subject: [PATCH] add DragonEggFormEvent
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
index f88719dede80c064f6210e078c435ffda32ecc1a..dec99c9d40705a89c395437d0d050f3ab36bc17b 100644
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
@@ -363,9 +363,24 @@ public class EndDragonFight {
this.dragonEvent.setVisible(false);
this.spawnExitPortal(true);
this.spawnNewGateway();
+ // Paper start - DragonEggFormEvent
+ BlockPos eggPosition = this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.END_PODIUM_LOCATION);
+ org.bukkit.craftbukkit.block.CraftBlock eggBlock = org.bukkit.craftbukkit.block.CraftBlock.at(this.level, eggPosition);
+ org.bukkit.craftbukkit.block.CraftBlockState eggState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(this.level, eggPosition);
+ eggState.setData(Blocks.DRAGON_EGG.defaultBlockState());
+ io.papermc.paper.event.block.DragonEggFormEvent eggEvent = new io.papermc.paper.event.block.DragonEggFormEvent(eggBlock, eggState,
+ new org.bukkit.craftbukkit.boss.CraftDragonBattle(this));
+ // Paper end - DragonEggFormEvent
if (this.level.paperConfig.enderDragonsDeathAlwaysPlacesDragonEgg || !this.previouslyKilled) { // Paper - always place dragon egg
- this.level.setBlockAndUpdate(this.level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, EndPodiumFeature.END_PODIUM_LOCATION), Blocks.DRAGON_EGG.defaultBlockState());
+ // Paper start - DragonEggFormEvent
+ //this.world.setTypeUpdate(this.world.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, WorldGenEndTrophy.a), Blocks.DRAGON_EGG.getBlockData());
+ } else {
+ eggEvent.setCancelled(true);
+ }
+ if (eggEvent.callEvent()) {
+ eggEvent.getNewState().update(true);
}
+ // Paper end - DragonEggFormEvent
this.previouslyKilled = true;
this.dragonKilled = true;

View file

@ -1,55 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Tue, 11 Feb 2020 21:56:48 -0600
Subject: [PATCH] EntityMoveEvent
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index d37b14523dd2a0e6412449001c7876bd27bf760e..f3976a53514249e64d91075ec2e620e4c7cef37f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1527,6 +1527,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
while (iterator.hasNext()) {
ServerLevel worldserver = (ServerLevel) iterator.next();
worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
+ worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
this.profiler.push(() -> {
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 073dbf69b5b58c4351110d28491e7feb2e47081c..c58b0de1cf1c51ceb0a0ecc145f4a98929521934 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -197,6 +197,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
public final LevelStorageSource.LevelStorageAccess convertable;
public final UUID uuid;
public boolean hasPhysicsEvent = true; // Paper
+ public boolean hasEntityMoveEvent = false; // Paper
public static Throwable getAddToWorldStackTrace(Entity entity) {
return new Throwable(entity + " Added to world at " + new java.util.Date());
}
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index e3d8557733e20a51bb71d9c968f4f12cc3192624..8ce983822ab44ade6306b52cad352ad95f6d6bad 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3223,6 +3223,20 @@ public abstract class LivingEntity extends Entity {
this.pushEntities();
this.level.getProfiler().pop();
+ // Paper start
+ if (((ServerLevel) this.level).hasEntityMoveEvent && !(this instanceof net.minecraft.world.entity.player.Player)) {
+ if (this.xo != getX() || this.yo != this.getY() || this.zo != this.getZ() || this.yRotO != this.getYRot() || this.xRotO != this.getXRot()) {
+ Location from = new Location(this.level.getWorld(), this.xo, this.yo, this.zo, this.yRotO, this.xRotO);
+ Location to = new Location (this.level.getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
+ io.papermc.paper.event.entity.EntityMoveEvent event = new io.papermc.paper.event.entity.EntityMoveEvent(this.getBukkitLivingEntity(), from, to.clone());
+ if (!event.callEvent()) {
+ absMoveTo(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch());
+ } else if (!to.equals(event.getTo())) {
+ absMoveTo(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ(), event.getTo().getYaw(), event.getTo().getPitch());
+ }
+ }
+ }
+ // Paper end
if (!this.level.isClientSide && this.isSensitiveToWater() && this.isInWaterRainOrBubble()) {
this.hurt(DamageSource.DROWN, 1.0F);
}

View file

@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: lukas81298 <lukas81298@gommehd.net>
Date: Mon, 25 Jan 2021 14:37:57 +0100
Subject: [PATCH] added option to disable pathfinding updates on block changes
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 3e694d8a28524f9ea6ba8f1947061b92bc15b13d..843878bb83dfebca8d3574c159c5e338f15104ac 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -807,5 +807,10 @@ public class PaperWorldConfig {
private void enderDragonsDeathAlwaysPlacesDragonEgg() {
enderDragonsDeathAlwaysPlacesDragonEgg = getBoolean("ender-dragons-death-always-places-dragon-egg", enderDragonsDeathAlwaysPlacesDragonEgg);
}
+
+ public boolean updatePathfindingOnBlockUpdate = true;
+ private void setUpdatePathfindingOnBlockUpdate() {
+ updatePathfindingOnBlockUpdate = getBoolean("update-pathfinding-on-block-update", this.updatePathfindingOnBlockUpdate);
+ }
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 09474f7e973563585e102cc839ab6842a3a10c0c..e0efad2395dd889430554074bbd9769957a72687 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1386,6 +1386,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override
public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) {
this.getChunkSource().blockChanged(pos);
+ if(this.paperConfig.updatePathfindingOnBlockUpdate) { // Paper - option to disable pathfinding updates
VoxelShape voxelshape = oldState.getCollisionShape(this, pos);
VoxelShape voxelshape1 = newState.getCollisionShape(this, pos);
@@ -1413,6 +1414,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
+ } // Paper
}
@Override

View file

@ -1,55 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Mon, 18 Jan 2021 20:45:25 -0500
Subject: [PATCH] Inline shift direction fields
Removes a layer of indirection for EnumDirection.getAdjacent(X|Y|Z)(), which is in the
critical section for much of the server, including the lighting engine.
diff --git a/src/main/java/net/minecraft/core/Direction.java b/src/main/java/net/minecraft/core/Direction.java
index e8e9494f7f337ee91a56fbd299da015dcda4a81b..593d6251c75ec337175d08b85000239ba7da1af2 100644
--- a/src/main/java/net/minecraft/core/Direction.java
+++ b/src/main/java/net/minecraft/core/Direction.java
@@ -62,6 +62,11 @@ public enum Direction implements StringRepresentable {
}, (direction1, direction2) -> {
throw new IllegalArgumentException("Duplicate keys");
}, Long2ObjectOpenHashMap::new));
+ // Paper start
+ private final int adjX;
+ private final int adjY;
+ private final int adjZ;
+ // Paper end
private Direction(int id, int idOpposite, int idHorizontal, String name, Direction.AxisDirection direction, Direction.Axis axis, Vec3i vector) {
this.data3d = id;
@@ -71,6 +76,11 @@ public enum Direction implements StringRepresentable {
this.axis = axis;
this.axisDirection = direction;
this.normal = vector;
+ // Paper start
+ this.adjX = vector.getX();
+ this.adjY = vector.getY();
+ this.adjZ = vector.getZ();
+ // Paper end
}
public static Direction[] orderedByNearest(Entity entity) {
@@ -310,15 +320,15 @@ public enum Direction implements StringRepresentable {
}
public int getStepX() {
- return this.normal.getX();
+ return this.adjX; // Paper
}
public int getStepY() {
- return this.normal.getY();
+ return this.adjY; // Paper
}
public int getStepZ() {
- return this.normal.getZ();
+ return this.adjZ; // Paper
}
public Vector3f step() {

View file

@ -1,44 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <blake.galbreath@gmail.com>
Date: Wed, 20 Jan 2021 14:23:37 -0600
Subject: [PATCH] Allow adding items to BlockDropItemEvent
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 33a8e174c4e3b3b5164157c90c8f5b5f9c6d8263..2b2654ec04e8abca9db09d6257edf11099bb0d9b 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -395,13 +395,30 @@ public class CraftEventFactory {
}
public static void handleBlockDropItemEvent(Block block, BlockState state, ServerPlayer player, List<ItemEntity> items) {
- BlockDropItemEvent event = new BlockDropItemEvent(block, state, player.getBukkitEntity(), Lists.transform(items, (item) -> (org.bukkit.entity.Item) item.getBukkitEntity()));
+ // Paper start
+ List<Item> list = new ArrayList<>();
+ for (ItemEntity item : items) {
+ list.add((Item) item.getBukkitEntity());
+ }
+ BlockDropItemEvent event = new BlockDropItemEvent(block, state, player.getBukkitEntity(), list);
+ // Paper end
Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) {
- for (ItemEntity item : items) {
- item.level.addFreshEntity(item);
+ // Paper start
+ for (Item bukkit : list) {
+ if (!bukkit.isValid()) {
+ Entity item = ((org.bukkit.craftbukkit.entity.CraftItem) bukkit).getHandle();
+ item.level.addFreshEntity(item);
+ }
+ }
+ } else {
+ for (Item bukkit : list) {
+ if (bukkit.isValid()) {
+ bukkit.remove();
+ }
}
+ // Paper end
}
}

View file

@ -1,26 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aleksander Jagiello <themolkapl@gmail.com>
Date: Sun, 24 Jan 2021 22:17:54 +0100
Subject: [PATCH] Add getMainThreadExecutor to BukkitScheduler
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index a423970cf7c927ea8a1bf842aaa236d3cf2d54c2..cdefb2025eedea7e204d70d568adaf1c1ec4c03c 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -655,4 +655,15 @@ public class CraftScheduler implements BukkitScheduler {
public BukkitTask runTaskTimerAsynchronously(Plugin plugin, BukkitRunnable task, long delay, long period) throws IllegalArgumentException {
throw new UnsupportedOperationException("Use BukkitRunnable#runTaskTimerAsynchronously(Plugin, long, long)");
}
+
+ // Paper start - add getMainThreadExecutor
+ @Override
+ public Executor getMainThreadExecutor(Plugin plugin) {
+ Validate.notNull(plugin, "Plugin cannot be null");
+ return command -> {
+ Validate.notNull(command, "Command cannot be null");
+ this.runTask(plugin, command);
+ };
+ }
+ // Paper end
}

View file

@ -1,60 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: ysl3000 <yannicklamprecht@live.de>
Date: Sat, 24 Oct 2020 16:37:44 +0200
Subject: [PATCH] living entity allow attribute registration
diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
index cb9ed449ed96474d2115a3023ff0b7b298548071..9cbfda029782385d1a7987f5be46d450bd8a758e 100644
--- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
@@ -132,4 +132,12 @@ public class AttributeMap {
}
}
+
+ // Paper - start
+ public void registerAttribute(Attribute attributeBase) {
+ AttributeInstance attributeModifiable = new AttributeInstance(attributeBase, AttributeInstance::getAttribute);
+ attributes.put(attributeBase, attributeModifiable);
+ }
+ // Paper - end
+
}
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
index 46c313d581b9af6aa0a48f97ae3cc800a88535f2..07d700382fc356837045c46d320b7b69ad13af68 100644
--- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
@@ -38,6 +38,14 @@ public class CraftAttributeMap implements Attributable {
return (nms == null) ? null : new CraftAttributeInstance(nms, attribute);
}
+ // Paper start
+ @Override
+ public void registerAttribute(Attribute attribute) {
+ Preconditions.checkArgument(attribute != null, "attribute");
+ handle.registerAttribute(CraftAttributeMap.toMinecraft(attribute));
+ }
+ // Paper end
+
public static net.minecraft.world.entity.ai.attributes.Attribute toMinecraft(Attribute attribute) {
return net.minecraft.core.Registry.ATTRIBUTE.get(CraftNamespacedKey.toMinecraft(attribute.getKey()));
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 7c8dba1c7d65b4b91eb5a83c029bc5b31750775f..88c0e80be343614947bfa3a14e08c5400a2d4ccc 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -686,6 +686,13 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
return this.getHandle().craftAttributes.getAttribute(attribute);
}
+ // Paper start
+ @Override
+ public void registerAttribute(Attribute attribute) {
+ getHandle().craftAttributes.registerAttribute(attribute);
+ }
+ // Paper end
+
@Override
public void setAI(boolean ai) {
if (this.getHandle() instanceof Mob) {

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Trigary <trigary0@gmail.com>
Date: Fri, 5 Feb 2021 22:12:13 +0100
Subject: [PATCH] fix dead slime setSize invincibility
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
index 4d401403de2399919043651345eed91c11ac986f..3c5326b1b4b18365e06292eca447778442201176 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
@@ -17,7 +17,7 @@ public class CraftSlime extends CraftMob implements Slime {
@Override
public void setSize(int size) {
- this.getHandle().setSize(size, true);
+ this.getHandle().setSize(size, /* true */ getHandle().isAlive()); // Paper - fix dead slime setSize invincibility
}
@Override

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Wed, 10 Feb 2021 14:53:36 -0800
Subject: [PATCH] Merchant#getRecipes should return an immutable list
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchant.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchant.java
index 425c8de426cecc9919d03dc64325494104d1b294..fcd6574857f77d547fd8101c5ac097bc6306034c 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchant.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchant.java
@@ -24,7 +24,7 @@ public class CraftMerchant implements Merchant {
@Override
public List<MerchantRecipe> getRecipes() {
- return Collections.unmodifiableList(Lists.transform(this.merchant.getOffers(), new Function<net.minecraft.world.item.trading.MerchantOffer, MerchantRecipe>() {
+ return com.google.common.collect.ImmutableList.copyOf(Lists.transform(this.merchant.getOffers(), new Function<net.minecraft.world.item.trading.MerchantOffer, MerchantRecipe>() { // Paper - javadoc says 'an immutable list of trades' - not 'an unmodifiable view of a list of trades'. fixes issue with setRecipes(getRecipes())
@Override
public MerchantRecipe apply(net.minecraft.world.item.trading.MerchantOffer recipe) {
return recipe.asBukkit();

View file

@ -1,233 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Josh Roy <10731363+JRoy@users.noreply.github.com>
Date: Sat, 20 Feb 2021 13:09:59 -0500
Subject: [PATCH] Add support for hex color codes in console
Converts upstream's hex color code legacy format into actual hex color codes in the console.
diff --git a/build.gradle.kts b/build.gradle.kts
index 57edac376bcbd056fb8fc7f0a433e946bce4ff2e..f3db86346c5e7bf446707a746f3094f7f27e09c4 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -34,6 +34,7 @@ dependencies {
Scanning takes about 1-2 seconds so adding this speeds up the server start.
*/
implementation("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - implementation
+ annotationProcessor("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - Needed to generate meta for out hex color converter plugin
// Paper end
implementation("org.apache.logging.log4j:log4j-iostreams:2.14.1") // Paper
implementation("org.apache.logging.log4j:log4j-api:2.14.1") // Paper
diff --git a/src/main/java/io/papermc/paper/console/HexFormattingConverter.java b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..a4315961b7a465fb4872a4d67e7c26d4b4ed1fb9
--- /dev/null
+++ b/src/main/java/io/papermc/paper/console/HexFormattingConverter.java
@@ -0,0 +1,178 @@
+package io.papermc.paper.console;
+
+import net.minecrell.terminalconsole.TerminalConsoleAppender;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.apache.logging.log4j.core.pattern.*;
+import org.apache.logging.log4j.util.PerformanceSensitive;
+import org.apache.logging.log4j.util.PropertiesUtil;
+
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static net.minecrell.terminalconsole.MinecraftFormattingConverter.KEEP_FORMATTING_PROPERTY;
+
+/**
+ * Modified version of <a href="https://github.com/Minecrell/TerminalConsoleAppender/blob/master/src/main/java/net/minecrell/terminalconsole/MinecraftFormattingConverter.java">
+ * TerminalConsoleAppender's MinecraftFormattingConverter</a> to support hex color codes using the md_5 &x&r&r&g&g&b&b format.
+ */
+@Plugin(name = "paperMinecraftFormatting", category = PatternConverter.CATEGORY)
+@ConverterKeys({ "paperMinecraftFormatting" })
+@PerformanceSensitive("allocation")
+public final class HexFormattingConverter extends LogEventPatternConverter {
+
+ private static final boolean KEEP_FORMATTING = PropertiesUtil.getProperties().getBooleanProperty(KEEP_FORMATTING_PROPERTY);
+
+ private static final String ANSI_RESET = "\u001B[m";
+
+ private static final char COLOR_CHAR = '§';
+ private static final String LOOKUP = "0123456789abcdefklmnor";
+
+ private static final String RGB_ANSI = "\u001B[38;2;%d;%d;%dm";
+ private static final Pattern NAMED_PATTERN = Pattern.compile(COLOR_CHAR + "[0-9a-fk-orA-FK-OR]");
+ private static final Pattern RGB_PATTERN = Pattern.compile(COLOR_CHAR + "x(" + COLOR_CHAR + "[0-9a-fA-F]){6}");
+
+ private static final String[] ansiCodes = new String[] {
+ "\u001B[0;30m", // Black §0
+ "\u001B[0;34m", // Dark Blue §1
+ "\u001B[0;32m", // Dark Green §2
+ "\u001B[0;36m", // Dark Aqua §3
+ "\u001B[0;31m", // Dark Red §4
+ "\u001B[0;35m", // Dark Purple §5
+ "\u001B[0;33m", // Gold §6
+ "\u001B[0;37m", // Gray §7
+ "\u001B[0;30;1m", // Dark Gray §8
+ "\u001B[0;34;1m", // Blue §9
+ "\u001B[0;32;1m", // Green §a
+ "\u001B[0;36;1m", // Aqua §b
+ "\u001B[0;31;1m", // Red §c
+ "\u001B[0;35;1m", // Light Purple §d
+ "\u001B[0;33;1m", // Yellow §e
+ "\u001B[0;37;1m", // White §f
+ "\u001B[5m", // Obfuscated §k
+ "\u001B[21m", // Bold §l
+ "\u001B[9m", // Strikethrough §m
+ "\u001B[4m", // Underline §n
+ "\u001B[3m", // Italic §o
+ ANSI_RESET, // Reset §r
+ };
+
+ private final boolean ansi;
+ private final List<PatternFormatter> formatters;
+
+ /**
+ * Construct the converter.
+ *
+ * @param formatters The pattern formatters to generate the text to manipulate
+ * @param strip If true, the converter will strip all formatting codes
+ */
+ protected HexFormattingConverter(List<PatternFormatter> formatters, boolean strip) {
+ super("paperMinecraftFormatting", null);
+ this.formatters = formatters;
+ this.ansi = !strip;
+ }
+
+ @Override
+ public void format(LogEvent event, StringBuilder toAppendTo) {
+ int start = toAppendTo.length();
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0, size = formatters.size(); i < size; i++) {
+ formatters.get(i).format(event, toAppendTo);
+ }
+
+ if (KEEP_FORMATTING || toAppendTo.length() == start) {
+ // Skip replacement if disabled or if the content is empty
+ return;
+ }
+
+ boolean useAnsi = ansi && TerminalConsoleAppender.isAnsiSupported();
+ String content = toAppendTo.substring(start);
+ content = useAnsi ? convertRGBColors(content) : stripRGBColors(content);
+ format(content, toAppendTo, start, useAnsi);
+ }
+
+ private static String convertRGBColors(String input) {
+ Matcher matcher = RGB_PATTERN.matcher(input);
+ StringBuffer buffer = new StringBuffer();
+ while (matcher.find()) {
+ String s = matcher.group().replace(String.valueOf(COLOR_CHAR), "").replace('x', '#');
+ int hex = Integer.decode(s);
+ int red = (hex >> 16) & 0xFF;
+ int green = (hex >> 8) & 0xFF;
+ int blue = hex & 0xFF;
+ String replacement = String.format(RGB_ANSI, red, green, blue);
+ matcher.appendReplacement(buffer, replacement);
+ }
+ matcher.appendTail(buffer);
+ return buffer.toString();
+ }
+
+ private static String stripRGBColors(String input) {
+ Matcher matcher = RGB_PATTERN.matcher(input);
+ StringBuffer buffer = new StringBuffer();
+ while (matcher.find()) {
+ matcher.appendReplacement(buffer, "");
+ }
+ matcher.appendTail(buffer);
+ return buffer.toString();
+ }
+
+ static void format(String content, StringBuilder result, int start, boolean ansi) {
+ int next = content.indexOf(COLOR_CHAR);
+ int last = content.length() - 1;
+ if (next == -1 || next == last) {
+ result.setLength(start);
+ result.append(content);
+ if (ansi) {
+ result.append(ANSI_RESET);
+ }
+ return;
+ }
+
+ Matcher matcher = NAMED_PATTERN.matcher(content);
+ StringBuffer buffer = new StringBuffer();
+ while (matcher.find()) {
+ int format = LOOKUP.indexOf(Character.toLowerCase(matcher.group().charAt(1)));
+ if (format != -1) {
+ matcher.appendReplacement(buffer, ansi ? ansiCodes[format] : "");
+ }
+ }
+ matcher.appendTail(buffer);
+
+ result.setLength(start);
+ result.append(buffer.toString());
+ if (ansi) {
+ result.append(ANSI_RESET);
+ }
+ }
+
+ /**
+ * Gets a new instance of the {@link HexFormattingConverter} with the
+ * specified options.
+ *
+ * @param config The current configuration
+ * @param options The pattern options
+ * @return The new instance
+ *
+ * @see HexFormattingConverter
+ */
+ public static HexFormattingConverter newInstance(Configuration config, String[] options) {
+ if (options.length < 1 || options.length > 2) {
+ LOGGER.error("Incorrect number of options on paperMinecraftFormatting. Expected at least 1, max 2 received " + options.length);
+ return null;
+ }
+ if (options[0] == null) {
+ LOGGER.error("No pattern supplied on paperMinecraftFormatting");
+ return null;
+ }
+
+ PatternParser parser = PatternLayout.createPatternParser(config);
+ List<PatternFormatter> formatters = parser.parse(options[0]);
+ boolean strip = options.length > 1 && "strip".equals(options[1]);
+ return new HexFormattingConverter(formatters, strip);
+ }
+
+}
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index 1a05d23ff886b015fb9396f119822c678a47ec6f..2e421eaac80cf251b32e0bb504dd54a73edf4986 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -6,21 +6,21 @@
</Queue>
<TerminalConsole name="TerminalConsole">
<PatternLayout>
- <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %minecraftFormatting{%msg}%n%xEx{full}}">
+ <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %paperMinecraftFormatting{%msg}%n%xEx{full}}">
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
<!-- Disable prefix for various plugins that bypass the plugin logger -->
<PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
- pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx{full}}" />
+ pattern="%highlightError{[%d{HH:mm:ss} %level]: %paperMinecraftFormatting{%msg}%n%xEx{full}}" />
</LoggerNamePatternSelector>
</PatternLayout>
</TerminalConsole>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout>
- <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %minecraftFormatting{%msg}{strip}%n%xEx{full}">
+ <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %paperMinecraftFormatting{%msg}{strip}%n%xEx{full}">
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
<!-- Disable prefix for various plugins that bypass the plugin logger -->
<PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
- pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n%xEx{full}" />
+ pattern="[%d{HH:mm:ss}] [%t/%level]: %paperMinecraftFormatting{%msg}{strip}%n%xEx{full}" />
</LoggerNamePatternSelector>
</PatternLayout>
<Policies>

View file

@ -1,29 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Tom <cryptite@gmail.com>
Date: Fri, 26 Feb 2021 16:24:25 -0600
Subject: [PATCH] Expose Tracked Players
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 986f045a2e6a040c6e2aab7420c8cb2d4ac3a726..ee50ea695585639d0ff184b675f3fb3b205b9f86 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1263,5 +1263,18 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
public boolean isTicking() {
return getHandle().isTicking();
}
+
+ @Override
+ public Set<org.bukkit.entity.Player> getTrackedPlayers() {
+ if (this.entity.tracker == null) {
+ return java.util.Collections.emptySet();
+ }
+
+ Set<org.bukkit.entity.Player> set = new java.util.HashSet<>(this.entity.tracker.seenBy.size());
+ for (net.minecraft.server.network.ServerPlayerConnection connection : this.entity.tracker.seenBy) {
+ set.add(connection.getPlayer().getBukkitEntity().getPlayer());
+ }
+ return set;
+ }
// Paper end
}

View file

@ -1,107 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bjarne Koll <lynxplay101@gmail.com>
Date: Wed, 3 Mar 2021 12:48:48 +0100
Subject: [PATCH] Remove streams from SensorNearest
The behavioural nearby sensors are validated every tick on the entities
that registered the respective sensors and are therefore a good subject
to performance improvements.
More specifically this commit replaces the Stream#filter usage with
ArrayList#removeIf as the removeIf method on an array list is heavily
optimized towards a single internal array re-allocation without any
further overhead on the removeIf call.
The only negative of this change is the rather agressive diff these
patches introduce as the methods are basically being reimplemented
compared to the previous stream-based implementation.
See: https://nipafx.dev/java-stream-performance/
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
index 7680c269c2fe0cf2a51d0ebeb34624181826d578..49f3b25d28072b61f5cc97260df61df892a58714 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
@@ -28,11 +28,15 @@ public class NearestItemSensor extends Sensor<Mob> {
return true;
});
list.sort(Comparator.comparingDouble(entity::distanceToSqr));
- Optional<ItemEntity> optional = list.stream().filter((itemEntity) -> {
- return entity.wantsToPickUp(itemEntity.getItem());
- }).filter((itemEntity) -> {
- return itemEntity.closerThan(entity, 9.0D);
- }).filter(entity::hasLineOfSight).findFirst();
- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, optional);
+ // Paper start - remove streams in favour of lists
+ ItemEntity nearest = null;
+ for (ItemEntity entityItem : list) {
+ if (entity.wantsToPickUp(entityItem.getItem()) && entityItem.closerThan(entity, 9.0D) && entity.hasLineOfSight(entityItem)) {
+ nearest = entityItem;
+ break;
+ }
+ }
+ 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 66c90013e52170a657b1a5dbdb99748a19fe55e8..ffd83db0a419ab589e89feeddd3fb038d6ed5839 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
@@ -21,9 +21,11 @@ public class NearestLivingEntitySensor extends Sensor<LivingEntity> {
list.sort(Comparator.comparingDouble(entity::distanceToSqr));
Brain<?> brain = entity.getBrain();
brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, list);
- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, list.stream().filter((livingEntity2) -> {
- return isEntityTargetable(entity, livingEntity2);
- }).collect(Collectors.toList()));
+ // Paper start - remove streams in favour of lists
+ List<LivingEntity> visibleMobs = new java.util.ArrayList<>(list);
+ visibleMobs.removeIf(otherEntityLiving -> !Sensor.isEntityTargetable(entity, otherEntityLiving));
+ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, visibleMobs);
+ // Paper end
}
@Override
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 b51574548b370f8a86d27835e9888ce1cd1d18be..457ea75137b8b02dc32bf1769ae8d57c470da470 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,18 +21,25 @@ public class PlayerSensor extends Sensor<LivingEntity> {
@Override
protected void doTick(ServerLevel world, LivingEntity entity) {
- List<Player> list = world.players().stream().filter(EntitySelector.NO_SPECTATORS).filter((serverPlayer) -> {
- return entity.closerThan(serverPlayer, 16.0D);
- }).sorted(Comparator.comparingDouble(entity::distanceToSqr)).collect(Collectors.toList());
+ // 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
Brain<?> brain = entity.getBrain();
- brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, list);
- List<Player> list2 = list.stream().filter((player) -> {
- return isEntityTargetable(entity, player);
- }).collect(Collectors.toList());
- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, list2.isEmpty() ? null : list2.get(0));
- Optional<Player> optional = list2.stream().filter((player) -> {
- return isEntityAttackable(entity, player);
- }).findFirst();
- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, optional);
+
+ brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, players);
+
+ Player nearest = null, nearestTargetable = null;
+ for (Player player : players) {
+ if (Sensor.isEntityTargetable(entity, player)) {
+ if (nearest == null) nearest = player;
+ if (Sensor.isEntityAttackable(entity, player)) {
+ nearestTargetable = player;
+ break; // Both variables are assigned, no reason to loop further
+ }
+ }
+ }
+ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, nearest);
+ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, nearestTargetable);
+ // Paper end
}
}