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

@ -0,0 +1,140 @@
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 63b0044a86e6830ccf9d6da8e29989de1402dff4..68da2530db8b0fcdba957ee90c185324a010919f 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -1228,12 +1228,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);
@@ -1391,8 +1394,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
}
}
@@ -1455,8 +1461,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;
@@ -1626,8 +1635,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 999d18610666ec442bb038da5c452e3cd77e7428..5f256c1ac5d49e19cfccf174dd55506313c493e0 100644
--- a/src/main/java/net/minecraft/world/entity/PathfinderMob.java
+++ b/src/main/java/net/minecraft/world/entity/PathfinderMob.java
@@ -49,8 +49,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;
@@ -58,8 +61,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 cf932116a0cafd315e44159fbf7c5d25d43782ff..03bda898a5a263053ecd79f74799d37095bbeb54 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 eda17a60afd6cf03e58e66b2dbfe414b1cfac9d5..5931cf0c05ca22f72a465d096dfb60508d84b859 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

@ -0,0 +1,19 @@
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 d56eb5071ed3ae2b9d5636cafb3aca9b2cd71d15..46a43cd457ee39463e1bd79880e8391f60c06a52 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -891,7 +891,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

@ -0,0 +1,22 @@
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 6166d1ce68742fbcb365c59cd44a611addbe2f8c..f8805dad18a5b9fa37b4f2c214acb17d59167f9d 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1151,6 +1151,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

@ -0,0 +1,35 @@
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 619ce8161deab5b93e2a3c4e652b3249f499fd3b..467e2af08698ca40fbbe1fa7b0bafb9561f4fa65 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
@@ -367,9 +367,23 @@ 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.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(org.bukkit.craftbukkit.block.CraftBlock.at(this.level, eggPosition), 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

@ -0,0 +1,55 @@
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 ad1e731900973deebdc363f34c4cf72058e4363d..6694e0d6d7d8d60f54ea1a2d2dcb5a8894b5b4b9 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1489,6 +1489,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 24ff621292d04d241f432e3a43e9dca92a35be55..bc9bb3f9ea041283a5fa1000f1043db5160f04ba 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -205,6 +205,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 de90fc7af633576a33b0d35715c3cb68bb9f5b21..fbd33490d7e1394c0989ca20fb36f0033a9e1c26 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3222,6 +3222,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

@ -0,0 +1,42 @@
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 1eaea3659dbd99767a045e0f66143bebb604c047..3c5dd72a4c98703602c41f2a04f1c793a6faf2ea 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -702,6 +702,11 @@ public class PaperWorldConfig {
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);
+ }
+
public boolean phantomIgnoreCreative = true;
public boolean phantomOnlyAttackInsomniacs = true;
private void phantomSettings() {
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index bc9bb3f9ea041283a5fa1000f1043db5160f04ba..d09a9886a6fa8a7e180ab0c1c4a5b437b621f236 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1360,6 +1360,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);
@@ -1387,6 +1388,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
+ } // Paper
}
@Override

View file

@ -0,0 +1,55 @@
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 b92377f109c6bc0d497a20b1f92185cb29b57443..6d883db5c04cbcf454952c0f361029ecbfe4f037 100644
--- a/src/main/java/net/minecraft/core/Direction.java
+++ b/src/main/java/net/minecraft/core/Direction.java
@@ -64,6 +64,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;
@@ -73,6 +78,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) {
@@ -357,15 +367,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

@ -0,0 +1,44 @@
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 5931cf0c05ca22f72a465d096dfb60508d84b859..5013a93f9bdc6d2c52239ca0434c7aa40f0572e1 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

@ -0,0 +1,26 @@
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

@ -0,0 +1,60 @@
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 0293d6fd1bb29f75fa1fa1cdfa36b3f679c1bc45..6555db49ff57bba13a7eb3c0bf7ecb66d7828dce 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

@ -0,0 +1,19 @@
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

@ -0,0 +1,19 @@
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..71be1e4f17ded6ea42e36be0a9b534c6a65ec640 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 List.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

@ -0,0 +1,233 @@
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 eaeed610e3f1a622b2ece220d595fbca9c750d20..5e1b87f84ab78952291c16ef468b83c9c5f21112 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.ow2.asm:asm:9.2")
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

@ -0,0 +1,29 @@
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

@ -0,0 +1,88 @@
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/PlayerSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java
index ed1b95ec694b0fe8b647964b18b8c33707fc0b47..0c40e0f8904880e1f01349953f44d1d330a5a696 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((player) -> {
- return entity.closerThan(player, 16.0D);
- }).sorted(Comparator.comparingDouble(entity::distanceToSqr)).collect(Collectors.toList());
+ List<Player> players= new java.util.ArrayList<>(world.players());
+ players.removeIf(player -> !EntitySelector.NO_SPECTATORS.test(player) || !entity.closerThan(player, 16.0D));
+ players.sort(Comparator.comparingDouble(entity::distanceTo));
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
}
}